• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/api.h"
6 
7 #include <string.h>  // For memcpy, strlen.
8 #ifdef V8_USE_ADDRESS_SANITIZER
9 #include <sanitizer/asan_interface.h>
10 #endif  // V8_USE_ADDRESS_SANITIZER
11 #include <cmath>  // For isnan.
12 #include <limits>
13 #include <vector>
14 #include "include/v8-debug.h"
15 #include "include/v8-experimental.h"
16 #include "include/v8-profiler.h"
17 #include "include/v8-testing.h"
18 #include "include/v8-util.h"
19 #include "src/accessors.h"
20 #include "src/api-experimental.h"
21 #include "src/api-natives.h"
22 #include "src/assert-scope.h"
23 #include "src/background-parsing-task.h"
24 #include "src/base/functional.h"
25 #include "src/base/platform/platform.h"
26 #include "src/base/platform/time.h"
27 #include "src/base/safe_conversions.h"
28 #include "src/base/utils/random-number-generator.h"
29 #include "src/bootstrapper.h"
30 #include "src/char-predicates-inl.h"
31 #include "src/code-stubs.h"
32 #include "src/compiler-dispatcher/compiler-dispatcher.h"
33 #include "src/compiler.h"
34 #include "src/context-measure.h"
35 #include "src/contexts.h"
36 #include "src/conversions-inl.h"
37 #include "src/counters.h"
38 #include "src/debug/debug-coverage.h"
39 #include "src/debug/debug.h"
40 #include "src/deoptimizer.h"
41 #include "src/execution.h"
42 #include "src/frames-inl.h"
43 #include "src/gdb-jit.h"
44 #include "src/global-handles.h"
45 #include "src/globals.h"
46 #include "src/icu_util.h"
47 #include "src/isolate-inl.h"
48 #include "src/json-parser.h"
49 #include "src/json-stringifier.h"
50 #include "src/messages.h"
51 #include "src/objects-inl.h"
52 #include "src/parsing/parser.h"
53 #include "src/parsing/scanner-character-streams.h"
54 #include "src/pending-compilation-error-handler.h"
55 #include "src/profiler/cpu-profiler.h"
56 #include "src/profiler/heap-profiler.h"
57 #include "src/profiler/heap-snapshot-generator-inl.h"
58 #include "src/profiler/profile-generator-inl.h"
59 #include "src/profiler/tick-sample.h"
60 #include "src/property-descriptor.h"
61 #include "src/property-details.h"
62 #include "src/property.h"
63 #include "src/prototype.h"
64 #include "src/runtime-profiler.h"
65 #include "src/runtime/runtime.h"
66 #include "src/simulator.h"
67 #include "src/snapshot/code-serializer.h"
68 #include "src/snapshot/natives.h"
69 #include "src/snapshot/snapshot.h"
70 #include "src/startup-data-util.h"
71 #include "src/tracing/trace-event.h"
72 #include "src/unicode-inl.h"
73 #include "src/v8.h"
74 #include "src/v8threads.h"
75 #include "src/value-serializer.h"
76 #include "src/version.h"
77 #include "src/vm-state-inl.h"
78 #include "src/wasm/wasm-module.h"
79 #include "src/wasm/wasm-objects.h"
80 #include "src/wasm/wasm-result.h"
81 
82 namespace v8 {
83 
84 #define LOG_API(isolate, class_name, function_name)                       \
85   i::RuntimeCallTimerScope _runtime_timer(                                \
86       isolate, &i::RuntimeCallStats::API_##class_name##_##function_name); \
87   LOG(isolate, ApiEntryCall("v8::" #class_name "::" #function_name))
88 
89 #define ENTER_V8(isolate) i::VMState<v8::OTHER> __state__((isolate))
90 
91 #define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, class_name,  \
92                                       function_name, bailout_value,  \
93                                       HandleScopeClass, do_callback) \
94   if (IsExecutionTerminatingCheck(isolate)) {                        \
95     return bailout_value;                                            \
96   }                                                                  \
97   HandleScopeClass handle_scope(isolate);                            \
98   CallDepthScope<do_callback> call_depth_scope(isolate, context);    \
99   LOG_API(isolate, class_name, function_name);                       \
100   ENTER_V8(isolate);                                                 \
101   bool has_pending_exception = false
102 
103 #define PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, T)       \
104   if (IsExecutionTerminatingCheck(isolate)) {                                \
105     return MaybeLocal<T>();                                                  \
106   }                                                                          \
107   InternalEscapableScope handle_scope(isolate);                              \
108   CallDepthScope<false> call_depth_scope(isolate, v8::Local<v8::Context>()); \
109   ENTER_V8(isolate);                                                         \
110   bool has_pending_exception = false
111 
112 #define PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
113                                            bailout_value, HandleScopeClass,    \
114                                            do_callback)                        \
115   auto isolate = context.IsEmpty()                                             \
116                      ? i::Isolate::Current()                                   \
117                      : reinterpret_cast<i::Isolate*>(context->GetIsolate());   \
118   PREPARE_FOR_EXECUTION_GENERIC(isolate, context, class_name, function_name,   \
119                                 bailout_value, HandleScopeClass, do_callback);
120 
121 #define PREPARE_FOR_EXECUTION_WITH_CONTEXT_IN_RUNTIME_CALL_STATS_SCOPE(      \
122     category, name, context, class_name, function_name, bailout_value,       \
123     HandleScopeClass, do_callback)                                           \
124   auto isolate = context.IsEmpty()                                           \
125                      ? i::Isolate::Current()                                 \
126                      : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \
127   TRACE_EVENT_CALL_STATS_SCOPED(isolate, category, name);                    \
128   PREPARE_FOR_EXECUTION_GENERIC(isolate, context, class_name, function_name, \
129                                 bailout_value, HandleScopeClass, do_callback);
130 
131 #define PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, class_name, function_name, \
132                                            T)                                  \
133   PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), class_name,         \
134                                 function_name, MaybeLocal<T>(),                \
135                                 InternalEscapableScope, false);
136 
137 #define PREPARE_FOR_EXECUTION(context, class_name, function_name, T)          \
138   PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name,      \
139                                      MaybeLocal<T>(), InternalEscapableScope, \
140                                      false)
141 
142 #define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, class_name,              \
143                                             function_name, T)                 \
144   PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name,      \
145                                      MaybeLocal<T>(), InternalEscapableScope, \
146                                      true)
147 
148 #define PREPARE_FOR_EXECUTION_PRIMITIVE(context, class_name, function_name, T) \
149   PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name,       \
150                                      Nothing<T>(), i::HandleScope, false)
151 
152 #define PREPARE_FOR_EXECUTION_BOOL(context, class_name, function_name)   \
153   PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
154                                      false, i::HandleScope, false)
155 
156 #ifdef DEBUG
157 #define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate)                    \
158   i::VMState<v8::OTHER> __state__((isolate));                       \
159   i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)); \
160   i::DisallowExceptions __no_exceptions__((isolate))
161 
162 #define ENTER_V8_FOR_NEW_CONTEXT(isolate)     \
163   i::VMState<v8::OTHER> __state__((isolate)); \
164   i::DisallowExceptions __no_exceptions__((isolate))
165 #else
166 #define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \
167   i::VMState<v8::OTHER> __state__((isolate));
168 
169 #define ENTER_V8_FOR_NEW_CONTEXT(isolate) \
170   i::VMState<v8::OTHER> __state__((isolate));
171 #endif  // DEBUG
172 
173 #define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value) \
174   do {                                                 \
175     if (has_pending_exception) {                       \
176       call_depth_scope.Escape();                       \
177       return value;                                    \
178     }                                                  \
179   } while (false)
180 
181 
182 #define RETURN_ON_FAILED_EXECUTION(T) \
183   EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, MaybeLocal<T>())
184 
185 
186 #define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \
187   EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, Nothing<T>())
188 
189 #define RETURN_ON_FAILED_EXECUTION_BOOL() \
190   EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false)
191 
192 #define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \
193   return maybe_local.FromMaybe(Local<T>());
194 
195 
196 #define RETURN_ESCAPED(value) return handle_scope.Escape(value);
197 
198 
199 namespace {
200 
ContextFromHeapObject(i::Handle<i::Object> obj)201 Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) {
202   return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate())
203       ->GetCurrentContext();
204 }
205 
206 class InternalEscapableScope : public v8::EscapableHandleScope {
207  public:
InternalEscapableScope(i::Isolate * isolate)208   explicit inline InternalEscapableScope(i::Isolate* isolate)
209       : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {}
210 };
211 
212 
213 #ifdef DEBUG
CheckMicrotasksScopesConsistency(i::Isolate * isolate)214 void CheckMicrotasksScopesConsistency(i::Isolate* isolate) {
215   auto handle_scope_implementer = isolate->handle_scope_implementer();
216   if (handle_scope_implementer->microtasks_policy() ==
217       v8::MicrotasksPolicy::kScoped) {
218     DCHECK(handle_scope_implementer->GetMicrotasksScopeDepth() ||
219            !handle_scope_implementer->DebugMicrotasksScopeDepthIsZero());
220   }
221 }
222 #endif
223 
224 template <bool do_callback>
225 class CallDepthScope {
226  public:
CallDepthScope(i::Isolate * isolate,Local<Context> context)227   explicit CallDepthScope(i::Isolate* isolate, Local<Context> context)
228       : isolate_(isolate), context_(context), escaped_(false) {
229     // TODO(dcarney): remove this when blink stops crashing.
230     DCHECK(!isolate_->external_caught_exception());
231     isolate_->handle_scope_implementer()->IncrementCallDepth();
232     if (!context.IsEmpty()) {
233       i::Handle<i::Context> env = Utils::OpenHandle(*context);
234       i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
235       if (isolate->context() != nullptr &&
236           isolate->context()->native_context() == env->native_context() &&
237           impl->LastEnteredContextWas(env)) {
238         context_ = Local<Context>();
239       } else {
240         context_->Enter();
241       }
242     }
243     if (do_callback) isolate_->FireBeforeCallEnteredCallback();
244   }
~CallDepthScope()245   ~CallDepthScope() {
246     if (!context_.IsEmpty()) context_->Exit();
247     if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
248     if (do_callback) isolate_->FireCallCompletedCallback();
249 #ifdef DEBUG
250     if (do_callback) CheckMicrotasksScopesConsistency(isolate_);
251 #endif
252   }
253 
Escape()254   void Escape() {
255     DCHECK(!escaped_);
256     escaped_ = true;
257     auto handle_scope_implementer = isolate_->handle_scope_implementer();
258     handle_scope_implementer->DecrementCallDepth();
259     bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();
260     isolate_->OptionalRescheduleException(call_depth_is_zero);
261   }
262 
263  private:
264   i::Isolate* const isolate_;
265   Local<Context> context_;
266   bool escaped_;
267   bool do_callback_;
268 };
269 
270 }  // namespace
271 
272 
GetScriptOriginForScript(i::Isolate * isolate,i::Handle<i::Script> script)273 static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
274                                              i::Handle<i::Script> script) {
275   i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
276   i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
277   v8::Isolate* v8_isolate =
278       reinterpret_cast<v8::Isolate*>(script->GetIsolate());
279   ScriptOriginOptions options(script->origin_options());
280   v8::ScriptOrigin origin(
281       Utils::ToLocal(scriptName),
282       v8::Integer::New(v8_isolate, script->line_offset()),
283       v8::Integer::New(v8_isolate, script->column_offset()),
284       v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()),
285       v8::Integer::New(v8_isolate, script->id()),
286       Utils::ToLocal(source_map_url),
287       v8::Boolean::New(v8_isolate, options.IsOpaque()),
288       v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM),
289       v8::Boolean::New(v8_isolate, options.IsModule()));
290   return origin;
291 }
292 
293 
294 // --- E x c e p t i o n   B e h a v i o r ---
295 
296 
FatalProcessOutOfMemory(const char * location)297 void i::FatalProcessOutOfMemory(const char* location) {
298   i::V8::FatalProcessOutOfMemory(location, false);
299 }
300 
301 // When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
302 // OOM error handler is called and execution is stopped.
FatalProcessOutOfMemory(const char * location,bool is_heap_oom)303 void i::V8::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
304   i::Isolate* isolate = i::Isolate::Current();
305   char last_few_messages[Heap::kTraceRingBufferSize + 1];
306   char js_stacktrace[Heap::kStacktraceBufferSize + 1];
307   i::HeapStats heap_stats;
308 
309   if (isolate == nullptr) {
310     // On a background thread -> we cannot retrieve memory information from the
311     // Isolate. Write easy-to-recognize values on the stack.
312     memset(last_few_messages, 0x0badc0de, Heap::kTraceRingBufferSize + 1);
313     memset(js_stacktrace, 0x0badc0de, Heap::kStacktraceBufferSize + 1);
314     memset(&heap_stats, 0xbadc0de, sizeof(heap_stats));
315     // Note that the embedder's oom handler won't be called in this case. We
316     // just crash.
317     FATAL("API fatal error handler returned after process out of memory");
318     return;
319   }
320 
321   memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
322   memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
323 
324   intptr_t start_marker;
325   heap_stats.start_marker = &start_marker;
326   size_t new_space_size;
327   heap_stats.new_space_size = &new_space_size;
328   size_t new_space_capacity;
329   heap_stats.new_space_capacity = &new_space_capacity;
330   size_t old_space_size;
331   heap_stats.old_space_size = &old_space_size;
332   size_t old_space_capacity;
333   heap_stats.old_space_capacity = &old_space_capacity;
334   size_t code_space_size;
335   heap_stats.code_space_size = &code_space_size;
336   size_t code_space_capacity;
337   heap_stats.code_space_capacity = &code_space_capacity;
338   size_t map_space_size;
339   heap_stats.map_space_size = &map_space_size;
340   size_t map_space_capacity;
341   heap_stats.map_space_capacity = &map_space_capacity;
342   size_t lo_space_size;
343   heap_stats.lo_space_size = &lo_space_size;
344   size_t global_handle_count;
345   heap_stats.global_handle_count = &global_handle_count;
346   size_t weak_global_handle_count;
347   heap_stats.weak_global_handle_count = &weak_global_handle_count;
348   size_t pending_global_handle_count;
349   heap_stats.pending_global_handle_count = &pending_global_handle_count;
350   size_t near_death_global_handle_count;
351   heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
352   size_t free_global_handle_count;
353   heap_stats.free_global_handle_count = &free_global_handle_count;
354   size_t memory_allocator_size;
355   heap_stats.memory_allocator_size = &memory_allocator_size;
356   size_t memory_allocator_capacity;
357   heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
358   size_t malloced_memory;
359   heap_stats.malloced_memory = &malloced_memory;
360   size_t malloced_peak_memory;
361   heap_stats.malloced_peak_memory = &malloced_peak_memory;
362   size_t objects_per_type[LAST_TYPE + 1] = {0};
363   heap_stats.objects_per_type = objects_per_type;
364   size_t size_per_type[LAST_TYPE + 1] = {0};
365   heap_stats.size_per_type = size_per_type;
366   int os_error;
367   heap_stats.os_error = &os_error;
368   heap_stats.last_few_messages = last_few_messages;
369   heap_stats.js_stacktrace = js_stacktrace;
370   intptr_t end_marker;
371   heap_stats.end_marker = &end_marker;
372   if (isolate->heap()->HasBeenSetUp()) {
373     // BUG(1718): Don't use the take_snapshot since we don't support
374     // HeapIterator here without doing a special GC.
375     isolate->heap()->RecordStats(&heap_stats, false);
376     char* first_newline = strchr(last_few_messages, '\n');
377     if (first_newline == NULL || first_newline[1] == '\0')
378       first_newline = last_few_messages;
379     PrintF("\n<--- Last few GCs --->\n%s\n", first_newline);
380     PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
381   }
382   Utils::ReportOOMFailure(location, is_heap_oom);
383   // If the fatal error handler returns, we stop execution.
384   FATAL("API fatal error handler returned after process out of memory");
385 }
386 
387 
ReportApiFailure(const char * location,const char * message)388 void Utils::ReportApiFailure(const char* location, const char* message) {
389   i::Isolate* isolate = i::Isolate::Current();
390   FatalErrorCallback callback = isolate->exception_behavior();
391   if (callback == nullptr) {
392     base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
393                          message);
394     base::OS::Abort();
395   } else {
396     callback(location, message);
397   }
398   isolate->SignalFatalError();
399 }
400 
ReportOOMFailure(const char * location,bool is_heap_oom)401 void Utils::ReportOOMFailure(const char* location, bool is_heap_oom) {
402   i::Isolate* isolate = i::Isolate::Current();
403   OOMErrorCallback oom_callback = isolate->oom_behavior();
404   if (oom_callback == nullptr) {
405     // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
406     // crbug.com/614440.
407     FatalErrorCallback fatal_callback = isolate->exception_behavior();
408     if (fatal_callback == nullptr) {
409       base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
410                            is_heap_oom ? "javascript" : "process", location);
411       base::OS::Abort();
412     } else {
413       fatal_callback(location,
414                      is_heap_oom
415                          ? "Allocation failed - JavaScript heap out of memory"
416                          : "Allocation failed - process out of memory");
417     }
418   } else {
419     oom_callback(location, is_heap_oom);
420   }
421   isolate->SignalFatalError();
422 }
423 
IsExecutionTerminatingCheck(i::Isolate * isolate)424 static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
425   if (isolate->has_scheduled_exception()) {
426     return isolate->scheduled_exception() ==
427         isolate->heap()->termination_exception();
428   }
429   return false;
430 }
431 
432 
SetNativesDataBlob(StartupData * natives_blob)433 void V8::SetNativesDataBlob(StartupData* natives_blob) {
434   i::V8::SetNativesBlob(natives_blob);
435 }
436 
437 
SetSnapshotDataBlob(StartupData * snapshot_blob)438 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
439   i::V8::SetSnapshotBlob(snapshot_blob);
440 }
441 
442 namespace {
443 
444 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
445  public:
Allocate(size_t length)446   virtual void* Allocate(size_t length) {
447     void* data = AllocateUninitialized(length);
448     return data == NULL ? data : memset(data, 0, length);
449   }
AllocateUninitialized(size_t length)450   virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
Free(void * data,size_t)451   virtual void Free(void* data, size_t) { free(data); }
452 };
453 
RunExtraCode(Isolate * isolate,Local<Context> context,const char * utf8_source,const char * name)454 bool RunExtraCode(Isolate* isolate, Local<Context> context,
455                   const char* utf8_source, const char* name) {
456   base::ElapsedTimer timer;
457   timer.Start();
458   Context::Scope context_scope(context);
459   TryCatch try_catch(isolate);
460   Local<String> source_string;
461   if (!String::NewFromUtf8(isolate, utf8_source, NewStringType::kNormal)
462            .ToLocal(&source_string)) {
463     return false;
464   }
465   Local<String> resource_name =
466       String::NewFromUtf8(isolate, name, NewStringType::kNormal)
467           .ToLocalChecked();
468   ScriptOrigin origin(resource_name);
469   ScriptCompiler::Source source(source_string, origin);
470   Local<Script> script;
471   if (!ScriptCompiler::Compile(context, &source).ToLocal(&script)) return false;
472   if (script->Run(context).IsEmpty()) return false;
473   if (i::FLAG_profile_deserialization) {
474     i::PrintF("Executing custom snapshot script %s took %0.3f ms\n", name,
475               timer.Elapsed().InMillisecondsF());
476   }
477   timer.Stop();
478   CHECK(!try_catch.HasCaught());
479   return true;
480 }
481 
482 struct SnapshotCreatorData {
SnapshotCreatorDatav8::__anon50f97c120211::SnapshotCreatorData483   explicit SnapshotCreatorData(Isolate* isolate)
484       : isolate_(isolate),
485         default_context_(),
486         contexts_(isolate),
487         templates_(isolate),
488         created_(false) {}
489 
castv8::__anon50f97c120211::SnapshotCreatorData490   static SnapshotCreatorData* cast(void* data) {
491     return reinterpret_cast<SnapshotCreatorData*>(data);
492   }
493 
494   ArrayBufferAllocator allocator_;
495   Isolate* isolate_;
496   Persistent<Context> default_context_;
497   PersistentValueVector<Context> contexts_;
498   PersistentValueVector<Template> templates_;
499   std::vector<SerializeInternalFieldsCallback> internal_fields_serializers_;
500   bool created_;
501 };
502 
503 }  // namespace
504 
SnapshotCreator(intptr_t * external_references,StartupData * existing_snapshot)505 SnapshotCreator::SnapshotCreator(intptr_t* external_references,
506                                  StartupData* existing_snapshot) {
507   i::Isolate* internal_isolate = new i::Isolate(true);
508   Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
509   SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
510   data->isolate_ = isolate;
511   internal_isolate->set_array_buffer_allocator(&data->allocator_);
512   internal_isolate->set_api_external_references(external_references);
513   isolate->Enter();
514   if (existing_snapshot) {
515     internal_isolate->set_snapshot_blob(existing_snapshot);
516     i::Snapshot::Initialize(internal_isolate);
517   } else {
518     internal_isolate->Init(nullptr);
519   }
520   data_ = data;
521 }
522 
~SnapshotCreator()523 SnapshotCreator::~SnapshotCreator() {
524   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
525   DCHECK(data->created_);
526   Isolate* isolate = data->isolate_;
527   isolate->Exit();
528   isolate->Dispose();
529   delete data;
530 }
531 
GetIsolate()532 Isolate* SnapshotCreator::GetIsolate() {
533   return SnapshotCreatorData::cast(data_)->isolate_;
534 }
535 
SetDefaultContext(Local<Context> context)536 void SnapshotCreator::SetDefaultContext(Local<Context> context) {
537   DCHECK(!context.IsEmpty());
538   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
539   DCHECK(!data->created_);
540   DCHECK(data->default_context_.IsEmpty());
541   Isolate* isolate = data->isolate_;
542   CHECK_EQ(isolate, context->GetIsolate());
543   data->default_context_.Reset(isolate, context);
544 }
545 
AddContext(Local<Context> context,SerializeInternalFieldsCallback callback)546 size_t SnapshotCreator::AddContext(Local<Context> context,
547                                    SerializeInternalFieldsCallback callback) {
548   DCHECK(!context.IsEmpty());
549   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
550   DCHECK(!data->created_);
551   Isolate* isolate = data->isolate_;
552   CHECK_EQ(isolate, context->GetIsolate());
553   size_t index = static_cast<int>(data->contexts_.Size());
554   data->contexts_.Append(context);
555   data->internal_fields_serializers_.push_back(callback);
556   return index;
557 }
558 
AddTemplate(Local<Template> template_obj)559 size_t SnapshotCreator::AddTemplate(Local<Template> template_obj) {
560   DCHECK(!template_obj.IsEmpty());
561   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
562   DCHECK(!data->created_);
563   DCHECK_EQ(reinterpret_cast<i::Isolate*>(data->isolate_),
564             Utils::OpenHandle(*template_obj)->GetIsolate());
565   size_t index = static_cast<int>(data->templates_.Size());
566   data->templates_.Append(template_obj);
567   return index;
568 }
569 
CreateBlob(SnapshotCreator::FunctionCodeHandling function_code_handling)570 StartupData SnapshotCreator::CreateBlob(
571     SnapshotCreator::FunctionCodeHandling function_code_handling) {
572   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
573   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
574   DCHECK(!data->created_);
575   DCHECK(!data->default_context_.IsEmpty());
576 
577   int num_additional_contexts = static_cast<int>(data->contexts_.Size());
578 
579   {
580     int num_templates = static_cast<int>(data->templates_.Size());
581     i::HandleScope scope(isolate);
582     i::Handle<i::FixedArray> templates =
583         isolate->factory()->NewFixedArray(num_templates, i::TENURED);
584     for (int i = 0; i < num_templates; i++) {
585       templates->set(i, *v8::Utils::OpenHandle(*data->templates_.Get(i)));
586     }
587     isolate->heap()->SetSerializedTemplates(*templates);
588     data->templates_.Clear();
589 
590     // We need to store the global proxy size upfront in case we need the
591     // bootstrapper to create a global proxy before we deserialize the context.
592     i::Handle<i::FixedArray> global_proxy_sizes =
593         isolate->factory()->NewFixedArray(num_additional_contexts, i::TENURED);
594     for (int i = 0; i < num_additional_contexts; i++) {
595       i::Handle<i::Context> context =
596           v8::Utils::OpenHandle(*data->contexts_.Get(i));
597       global_proxy_sizes->set(i,
598                               i::Smi::FromInt(context->global_proxy()->Size()));
599     }
600     isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
601   }
602 
603   // If we don't do this then we end up with a stray root pointing at the
604   // context even after we have disposed of the context.
605   isolate->heap()->CollectAllAvailableGarbage(
606       i::GarbageCollectionReason::kSnapshotCreator);
607   isolate->heap()->CompactWeakFixedArrays();
608 
609   i::DisallowHeapAllocation no_gc_from_here_on;
610 
611   i::List<i::Object*> contexts(num_additional_contexts);
612   i::Object* default_context;
613   {
614     i::HandleScope scope(isolate);
615     default_context =
616         *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_));
617     data->default_context_.Reset();
618     for (int i = 0; i < num_additional_contexts; i++) {
619       i::Handle<i::Context> context =
620           v8::Utils::OpenHandle(*data->contexts_.Get(i));
621       contexts.Add(*context);
622     }
623     data->contexts_.Clear();
624   }
625 
626 #ifdef DEBUG
627   i::ExternalReferenceTable::instance(isolate)->ResetCount();
628 #endif  // DEBUG
629 
630   i::StartupSerializer startup_serializer(isolate, function_code_handling);
631   startup_serializer.SerializeStrongReferences();
632 
633   // Serialize each context with a new partial serializer.
634   i::List<i::SnapshotData*> context_snapshots(num_additional_contexts + 1);
635 
636   {
637     // The default snapshot does not support internal fields.
638     i::PartialSerializer partial_serializer(
639         isolate, &startup_serializer, v8::SerializeInternalFieldsCallback());
640     partial_serializer.Serialize(&default_context, false);
641     context_snapshots.Add(new i::SnapshotData(&partial_serializer));
642   }
643 
644   for (int i = 0; i < num_additional_contexts; i++) {
645     i::PartialSerializer partial_serializer(
646         isolate, &startup_serializer, data->internal_fields_serializers_[i]);
647     partial_serializer.Serialize(&contexts[i], true);
648     context_snapshots.Add(new i::SnapshotData(&partial_serializer));
649   }
650 
651   startup_serializer.SerializeWeakReferencesAndDeferred();
652 
653 #ifdef DEBUG
654   if (i::FLAG_external_reference_stats) {
655     i::ExternalReferenceTable::instance(isolate)->PrintCount();
656   }
657 #endif  // DEBUG
658 
659   i::SnapshotData startup_snapshot(&startup_serializer);
660   StartupData result =
661       i::Snapshot::CreateSnapshotBlob(&startup_snapshot, &context_snapshots);
662 
663   // Delete heap-allocated context snapshot instances.
664   for (const auto& context_snapshot : context_snapshots) {
665     delete context_snapshot;
666   }
667   data->created_ = true;
668   return result;
669 }
670 
CreateSnapshotDataBlob(const char * embedded_source)671 StartupData V8::CreateSnapshotDataBlob(const char* embedded_source) {
672   // Create a new isolate and a new context from scratch, optionally run
673   // a script to embed, and serialize to create a snapshot blob.
674   StartupData result = {nullptr, 0};
675   base::ElapsedTimer timer;
676   timer.Start();
677   {
678     SnapshotCreator snapshot_creator;
679     Isolate* isolate = snapshot_creator.GetIsolate();
680     {
681       HandleScope scope(isolate);
682       Local<Context> context = Context::New(isolate);
683       if (embedded_source != NULL &&
684           !RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
685         return result;
686       }
687       snapshot_creator.SetDefaultContext(context);
688     }
689     result = snapshot_creator.CreateBlob(
690         SnapshotCreator::FunctionCodeHandling::kClear);
691   }
692 
693   if (i::FLAG_profile_deserialization) {
694     i::PrintF("Creating snapshot took %0.3f ms\n",
695               timer.Elapsed().InMillisecondsF());
696   }
697   timer.Stop();
698   return result;
699 }
700 
WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob,const char * warmup_source)701 StartupData V8::WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob,
702                                        const char* warmup_source) {
703   CHECK(cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != NULL);
704   CHECK(warmup_source != NULL);
705   // Use following steps to create a warmed up snapshot blob from a cold one:
706   //  - Create a new isolate from the cold snapshot.
707   //  - Create a new context to run the warmup script. This will trigger
708   //    compilation of executed functions.
709   //  - Create a new context. This context will be unpolluted.
710   //  - Serialize the isolate and the second context into a new snapshot blob.
711   StartupData result = {nullptr, 0};
712   base::ElapsedTimer timer;
713   timer.Start();
714   {
715     SnapshotCreator snapshot_creator(nullptr, &cold_snapshot_blob);
716     Isolate* isolate = snapshot_creator.GetIsolate();
717     {
718       HandleScope scope(isolate);
719       Local<Context> context = Context::New(isolate);
720       if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) {
721         return result;
722       }
723     }
724     {
725       HandleScope handle_scope(isolate);
726       isolate->ContextDisposedNotification(false);
727       Local<Context> context = Context::New(isolate);
728       snapshot_creator.SetDefaultContext(context);
729     }
730     result = snapshot_creator.CreateBlob(
731         SnapshotCreator::FunctionCodeHandling::kKeep);
732   }
733 
734   if (i::FLAG_profile_deserialization) {
735     i::PrintF("Warming up snapshot took %0.3f ms\n",
736               timer.Elapsed().InMillisecondsF());
737   }
738   timer.Stop();
739   return result;
740 }
741 
742 
SetFlagsFromString(const char * str,int length)743 void V8::SetFlagsFromString(const char* str, int length) {
744   i::FlagList::SetFlagsFromString(str, length);
745   i::FlagList::EnforceFlagImplications();
746 }
747 
748 
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)749 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
750   i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
751 }
752 
753 
754 RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
755 
756 
RegisteredExtension(Extension * extension)757 RegisteredExtension::RegisteredExtension(Extension* extension)
758     : extension_(extension) { }
759 
760 
Register(RegisteredExtension * that)761 void RegisteredExtension::Register(RegisteredExtension* that) {
762   that->next_ = first_extension_;
763   first_extension_ = that;
764 }
765 
766 
UnregisterAll()767 void RegisteredExtension::UnregisterAll() {
768   RegisteredExtension* re = first_extension_;
769   while (re != NULL) {
770     RegisteredExtension* next = re->next();
771     delete re;
772     re = next;
773   }
774   first_extension_ = NULL;
775 }
776 
777 
RegisterExtension(Extension * that)778 void RegisterExtension(Extension* that) {
779   RegisteredExtension* extension = new RegisteredExtension(that);
780   RegisteredExtension::Register(extension);
781 }
782 
783 
Extension(const char * name,const char * source,int dep_count,const char ** deps,int source_length)784 Extension::Extension(const char* name,
785                      const char* source,
786                      int dep_count,
787                      const char** deps,
788                      int source_length)
789     : name_(name),
790       source_length_(source_length >= 0 ?
791                      source_length :
792                      (source ? static_cast<int>(strlen(source)) : 0)),
793       source_(source, source_length_),
794       dep_count_(dep_count),
795       deps_(deps),
796       auto_enable_(false) {
797   CHECK(source != NULL || source_length_ == 0);
798 }
799 
ResourceConstraints()800 ResourceConstraints::ResourceConstraints()
801     : max_semi_space_size_(0),
802       max_old_space_size_(0),
803       max_executable_size_(0),
804       stack_limit_(NULL),
805       code_range_size_(0),
806       max_zone_pool_size_(0) {}
807 
ConfigureDefaults(uint64_t physical_memory,uint64_t virtual_memory_limit)808 void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
809                                             uint64_t virtual_memory_limit) {
810 #if V8_OS_ANDROID
811   // Android has higher physical memory requirements before raising the maximum
812   // heap size limits since it has no swap space.
813   const uint64_t low_limit = 512ul * i::MB;
814   const uint64_t medium_limit = 1ul * i::GB;
815   const uint64_t high_limit = 2ul * i::GB;
816 #else
817   const uint64_t low_limit = 512ul * i::MB;
818   const uint64_t medium_limit = 768ul * i::MB;
819   const uint64_t high_limit = 1ul  * i::GB;
820 #endif
821 
822   if (physical_memory <= low_limit) {
823     set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice);
824     set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
825     set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
826     set_max_zone_pool_size(i::AccountingAllocator::kMaxPoolSizeLowMemoryDevice);
827   } else if (physical_memory <= medium_limit) {
828     set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice);
829     set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
830     set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
831     set_max_zone_pool_size(
832         i::AccountingAllocator::kMaxPoolSizeMediumMemoryDevice);
833   } else if (physical_memory <= high_limit) {
834     set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice);
835     set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
836     set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
837     set_max_zone_pool_size(
838         i::AccountingAllocator::kMaxPoolSizeHighMemoryDevice);
839   } else {
840     set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice);
841     set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
842     set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
843     set_max_zone_pool_size(
844         i::AccountingAllocator::kMaxPoolSizeHugeMemoryDevice);
845   }
846 
847   if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
848     // Reserve no more than 1/8 of the memory for the code range, but at most
849     // kMaximalCodeRangeSize.
850     set_code_range_size(
851         i::Min(i::kMaximalCodeRangeSize / i::MB,
852                static_cast<size_t>((virtual_memory_limit >> 3) / i::MB)));
853   }
854 }
855 
856 
SetResourceConstraints(i::Isolate * isolate,const ResourceConstraints & constraints)857 void SetResourceConstraints(i::Isolate* isolate,
858                             const ResourceConstraints& constraints) {
859   int semi_space_size = constraints.max_semi_space_size();
860   int old_space_size = constraints.max_old_space_size();
861   int max_executable_size = constraints.max_executable_size();
862   size_t code_range_size = constraints.code_range_size();
863   size_t max_pool_size = constraints.max_zone_pool_size();
864   if (semi_space_size != 0 || old_space_size != 0 ||
865       max_executable_size != 0 || code_range_size != 0) {
866     isolate->heap()->ConfigureHeap(semi_space_size, old_space_size,
867                                    max_executable_size, code_range_size);
868   }
869   isolate->allocator()->ConfigureSegmentPool(max_pool_size);
870 
871   if (constraints.stack_limit() != NULL) {
872     uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
873     isolate->stack_guard()->SetStackLimit(limit);
874   }
875 }
876 
877 
GlobalizeReference(i::Isolate * isolate,i::Object ** obj)878 i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
879   LOG_API(isolate, Persistent, New);
880   i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
881 #ifdef VERIFY_HEAP
882   if (i::FLAG_verify_heap) {
883     (*obj)->ObjectVerify();
884   }
885 #endif  // VERIFY_HEAP
886   return result.location();
887 }
888 
889 
CopyPersistent(i::Object ** obj)890 i::Object** V8::CopyPersistent(i::Object** obj) {
891   i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
892 #ifdef VERIFY_HEAP
893   if (i::FLAG_verify_heap) {
894     (*obj)->ObjectVerify();
895   }
896 #endif  // VERIFY_HEAP
897   return result.location();
898 }
899 
RegisterExternallyReferencedObject(i::Object ** object,i::Isolate * isolate)900 void V8::RegisterExternallyReferencedObject(i::Object** object,
901                                             i::Isolate* isolate) {
902   isolate->heap()->RegisterExternallyReferencedObject(object);
903 }
904 
MakeWeak(i::Object ** location,void * parameter,int internal_field_index1,int internal_field_index2,WeakCallbackInfo<void>::Callback weak_callback)905 void V8::MakeWeak(i::Object** location, void* parameter,
906                   int internal_field_index1, int internal_field_index2,
907                   WeakCallbackInfo<void>::Callback weak_callback) {
908   WeakCallbackType type = WeakCallbackType::kParameter;
909   if (internal_field_index1 == 0) {
910     if (internal_field_index2 == 1) {
911       type = WeakCallbackType::kInternalFields;
912     } else {
913       DCHECK_EQ(internal_field_index2, -1);
914       type = WeakCallbackType::kInternalFields;
915     }
916   } else {
917     DCHECK_EQ(internal_field_index1, -1);
918     DCHECK_EQ(internal_field_index2, -1);
919   }
920   i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
921 }
922 
MakeWeak(i::Object ** location,void * parameter,WeakCallbackInfo<void>::Callback weak_callback,WeakCallbackType type)923 void V8::MakeWeak(i::Object** location, void* parameter,
924                   WeakCallbackInfo<void>::Callback weak_callback,
925                   WeakCallbackType type) {
926   i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
927 }
928 
MakeWeak(i::Object *** location_addr)929 void V8::MakeWeak(i::Object*** location_addr) {
930   i::GlobalHandles::MakeWeak(location_addr);
931 }
932 
ClearWeak(i::Object ** location)933 void* V8::ClearWeak(i::Object** location) {
934   return i::GlobalHandles::ClearWeakness(location);
935 }
936 
DisposeGlobal(i::Object ** location)937 void V8::DisposeGlobal(i::Object** location) {
938   i::GlobalHandles::Destroy(location);
939 }
940 
941 
Eternalize(Isolate * v8_isolate,Value * value,int * index)942 void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
943   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
944   i::Object* object = *Utils::OpenHandle(value);
945   isolate->eternal_handles()->Create(isolate, object, index);
946 }
947 
948 
GetEternal(Isolate * v8_isolate,int index)949 Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
950   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
951   return Utils::ToLocal(isolate->eternal_handles()->Get(index));
952 }
953 
954 
FromJustIsNothing()955 void V8::FromJustIsNothing() {
956   Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
957 }
958 
959 
ToLocalEmpty()960 void V8::ToLocalEmpty() {
961   Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
962 }
963 
964 
InternalFieldOutOfBounds(int index)965 void V8::InternalFieldOutOfBounds(int index) {
966   Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
967                   "WeakCallbackInfo::GetInternalField",
968                   "Internal field out of bounds.");
969 }
970 
971 
972 // --- H a n d l e s ---
973 
974 
HandleScope(Isolate * isolate)975 HandleScope::HandleScope(Isolate* isolate) {
976   Initialize(isolate);
977 }
978 
979 
Initialize(Isolate * isolate)980 void HandleScope::Initialize(Isolate* isolate) {
981   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
982   // We do not want to check the correct usage of the Locker class all over the
983   // place, so we do it only here: Without a HandleScope, an embedder can do
984   // almost nothing, so it is enough to check in this central place.
985   // We make an exception if the serializer is enabled, which means that the
986   // Isolate is exclusively used to create a snapshot.
987   Utils::ApiCheck(
988       !v8::Locker::IsActive() ||
989           internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
990           internal_isolate->serializer_enabled(),
991       "HandleScope::HandleScope",
992       "Entering the V8 API without proper locking in place");
993   i::HandleScopeData* current = internal_isolate->handle_scope_data();
994   isolate_ = internal_isolate;
995   prev_next_ = current->next;
996   prev_limit_ = current->limit;
997   current->level++;
998 }
999 
1000 
~HandleScope()1001 HandleScope::~HandleScope() {
1002   i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
1003 }
1004 
operator new(size_t)1005 V8_NORETURN void* HandleScope::operator new(size_t) {
1006   base::OS::Abort();
1007   abort();
1008 }
1009 
operator delete(void *,size_t)1010 void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
1011 
NumberOfHandles(Isolate * isolate)1012 int HandleScope::NumberOfHandles(Isolate* isolate) {
1013   return i::HandleScope::NumberOfHandles(
1014       reinterpret_cast<i::Isolate*>(isolate));
1015 }
1016 
1017 
CreateHandle(i::Isolate * isolate,i::Object * value)1018 i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
1019   return i::HandleScope::CreateHandle(isolate, value);
1020 }
1021 
1022 
CreateHandle(i::HeapObject * heap_object,i::Object * value)1023 i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
1024                                       i::Object* value) {
1025   DCHECK(heap_object->IsHeapObject());
1026   return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
1027 }
1028 
1029 
EscapableHandleScope(Isolate * v8_isolate)1030 EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
1031   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1032   escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
1033   Initialize(v8_isolate);
1034 }
1035 
1036 
Escape(i::Object ** escape_value)1037 i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
1038   i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
1039   Utils::ApiCheck((*escape_slot_)->IsTheHole(heap->isolate()),
1040                   "EscapableHandleScope::Escape", "Escape value set twice");
1041   if (escape_value == NULL) {
1042     *escape_slot_ = heap->undefined_value();
1043     return NULL;
1044   }
1045   *escape_slot_ = *escape_value;
1046   return escape_slot_;
1047 }
1048 
operator new(size_t)1049 V8_NORETURN void* EscapableHandleScope::operator new(size_t) {
1050   base::OS::Abort();
1051   abort();
1052 }
1053 
operator delete(void *,size_t)1054 void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
1055 
SealHandleScope(Isolate * isolate)1056 SealHandleScope::SealHandleScope(Isolate* isolate)
1057     : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
1058   i::HandleScopeData* current = isolate_->handle_scope_data();
1059   prev_limit_ = current->limit;
1060   current->limit = current->next;
1061   prev_sealed_level_ = current->sealed_level;
1062   current->sealed_level = current->level;
1063 }
1064 
1065 
~SealHandleScope()1066 SealHandleScope::~SealHandleScope() {
1067   i::HandleScopeData* current = isolate_->handle_scope_data();
1068   DCHECK_EQ(current->next, current->limit);
1069   current->limit = prev_limit_;
1070   DCHECK_EQ(current->level, current->sealed_level);
1071   current->sealed_level = prev_sealed_level_;
1072 }
1073 
operator new(size_t)1074 V8_NORETURN void* SealHandleScope::operator new(size_t) {
1075   base::OS::Abort();
1076   abort();
1077 }
1078 
operator delete(void *,size_t)1079 void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
1080 
Enter()1081 void Context::Enter() {
1082   i::Handle<i::Context> env = Utils::OpenHandle(this);
1083   i::Isolate* isolate = env->GetIsolate();
1084   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1085   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1086   impl->EnterContext(env);
1087   impl->SaveContext(isolate->context());
1088   isolate->set_context(*env);
1089 }
1090 
1091 
Exit()1092 void Context::Exit() {
1093   i::Handle<i::Context> env = Utils::OpenHandle(this);
1094   i::Isolate* isolate = env->GetIsolate();
1095   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1096   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1097   if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
1098                        "v8::Context::Exit()",
1099                        "Cannot exit non-entered context")) {
1100     return;
1101   }
1102   impl->LeaveContext();
1103   isolate->set_context(impl->RestoreContext());
1104 }
1105 
1106 
DecodeSmiToAligned(i::Object * value,const char * location)1107 static void* DecodeSmiToAligned(i::Object* value, const char* location) {
1108   Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
1109   return reinterpret_cast<void*>(value);
1110 }
1111 
1112 
EncodeAlignedAsSmi(void * value,const char * location)1113 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
1114   i::Smi* smi = reinterpret_cast<i::Smi*>(value);
1115   Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
1116   return smi;
1117 }
1118 
1119 
EmbedderDataFor(Context * context,int index,bool can_grow,const char * location)1120 static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
1121                                                 int index,
1122                                                 bool can_grow,
1123                                                 const char* location) {
1124   i::Handle<i::Context> env = Utils::OpenHandle(context);
1125   i::Isolate* isolate = env->GetIsolate();
1126   bool ok =
1127       Utils::ApiCheck(env->IsNativeContext(),
1128                       location,
1129                       "Not a native context") &&
1130       Utils::ApiCheck(index >= 0, location, "Negative index");
1131   if (!ok) return i::Handle<i::FixedArray>();
1132   i::Handle<i::FixedArray> data(env->embedder_data());
1133   if (index < data->length()) return data;
1134   if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
1135     return i::Handle<i::FixedArray>();
1136   }
1137   int new_size = i::Max(index, data->length() << 1) + 1;
1138   int grow_by = new_size - data->length();
1139   data = isolate->factory()->CopyFixedArrayAndGrow(data, grow_by);
1140   env->set_embedder_data(*data);
1141   return data;
1142 }
1143 
1144 
SlowGetEmbedderData(int index)1145 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1146   const char* location = "v8::Context::GetEmbedderData()";
1147   i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
1148   if (data.is_null()) return Local<Value>();
1149   i::Handle<i::Object> result(data->get(index), data->GetIsolate());
1150   return Utils::ToLocal(result);
1151 }
1152 
1153 
SetEmbedderData(int index,v8::Local<Value> value)1154 void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1155   const char* location = "v8::Context::SetEmbedderData()";
1156   i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
1157   if (data.is_null()) return;
1158   i::Handle<i::Object> val = Utils::OpenHandle(*value);
1159   data->set(index, *val);
1160   DCHECK_EQ(*Utils::OpenHandle(*value),
1161             *Utils::OpenHandle(*GetEmbedderData(index)));
1162 }
1163 
1164 
SlowGetAlignedPointerFromEmbedderData(int index)1165 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1166   const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1167   i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
1168   if (data.is_null()) return NULL;
1169   return DecodeSmiToAligned(data->get(index), location);
1170 }
1171 
1172 
SetAlignedPointerInEmbedderData(int index,void * value)1173 void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1174   const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1175   i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
1176   data->set(index, EncodeAlignedAsSmi(value, location));
1177   DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1178 }
1179 
1180 
1181 // --- T e m p l a t e ---
1182 
1183 
InitializeTemplate(i::Handle<i::TemplateInfo> that,int type)1184 static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
1185   that->set_number_of_properties(0);
1186   that->set_tag(i::Smi::FromInt(type));
1187 }
1188 
1189 
Set(v8::Local<Name> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1190 void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1191                    v8::PropertyAttribute attribute) {
1192   auto templ = Utils::OpenHandle(this);
1193   i::Isolate* isolate = templ->GetIsolate();
1194   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1195   i::HandleScope scope(isolate);
1196   auto value_obj = Utils::OpenHandle(*value);
1197   CHECK(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo());
1198   if (value_obj->IsObjectTemplateInfo()) {
1199     templ->set_serial_number(i::Smi::kZero);
1200     if (templ->IsFunctionTemplateInfo()) {
1201       i::Handle<i::FunctionTemplateInfo>::cast(templ)->set_do_not_cache(true);
1202     }
1203   }
1204   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1205                                  value_obj,
1206                                  static_cast<i::PropertyAttributes>(attribute));
1207 }
1208 
SetPrivate(v8::Local<Private> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1209 void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1210                           v8::PropertyAttribute attribute) {
1211   Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1212       attribute);
1213 }
1214 
SetAccessorProperty(v8::Local<v8::Name> name,v8::Local<FunctionTemplate> getter,v8::Local<FunctionTemplate> setter,v8::PropertyAttribute attribute,v8::AccessControl access_control)1215 void Template::SetAccessorProperty(
1216     v8::Local<v8::Name> name,
1217     v8::Local<FunctionTemplate> getter,
1218     v8::Local<FunctionTemplate> setter,
1219     v8::PropertyAttribute attribute,
1220     v8::AccessControl access_control) {
1221   // TODO(verwaest): Remove |access_control|.
1222   DCHECK_EQ(v8::DEFAULT, access_control);
1223   auto templ = Utils::OpenHandle(this);
1224   auto isolate = templ->GetIsolate();
1225   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1226   DCHECK(!name.IsEmpty());
1227   DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1228   i::HandleScope scope(isolate);
1229   i::ApiNatives::AddAccessorProperty(
1230       isolate, templ, Utils::OpenHandle(*name),
1231       Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1232       static_cast<i::PropertyAttributes>(attribute));
1233 }
1234 
1235 
1236 // --- F u n c t i o n   T e m p l a t e ---
InitializeFunctionTemplate(i::Handle<i::FunctionTemplateInfo> info)1237 static void InitializeFunctionTemplate(
1238     i::Handle<i::FunctionTemplateInfo> info) {
1239   InitializeTemplate(info, Consts::FUNCTION_TEMPLATE);
1240   info->set_flag(0);
1241 }
1242 
1243 static Local<ObjectTemplate> ObjectTemplateNew(
1244     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1245     bool do_not_cache);
1246 
PrototypeTemplate()1247 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1248   i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
1249   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1250   i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
1251                               i_isolate);
1252   if (result->IsUndefined(i_isolate)) {
1253     // Do not cache prototype objects.
1254     result = Utils::OpenHandle(
1255         *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1256     Utils::OpenHandle(this)->set_prototype_template(*result);
1257   }
1258   return ToApiHandle<ObjectTemplate>(result);
1259 }
1260 
SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider)1261 void FunctionTemplate::SetPrototypeProviderTemplate(
1262     Local<FunctionTemplate> prototype_provider) {
1263   i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
1264   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1265   i::Handle<i::Object> result = Utils::OpenHandle(*prototype_provider);
1266   auto info = Utils::OpenHandle(this);
1267   CHECK(info->prototype_template()->IsUndefined(i_isolate));
1268   CHECK(info->parent_template()->IsUndefined(i_isolate));
1269   info->set_prototype_provider_template(*result);
1270 }
1271 
EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,const char * func)1272 static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,
1273                                   const char* func) {
1274   Utils::ApiCheck(!info->instantiated(), func,
1275                   "FunctionTemplate already instantiated");
1276 }
1277 
1278 
Inherit(v8::Local<FunctionTemplate> value)1279 void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1280   auto info = Utils::OpenHandle(this);
1281   EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit");
1282   i::Isolate* i_isolate = info->GetIsolate();
1283   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1284   CHECK(info->prototype_provider_template()->IsUndefined(i_isolate));
1285   info->set_parent_template(*Utils::OpenHandle(*value));
1286 }
1287 
FunctionTemplateNew(i::Isolate * isolate,FunctionCallback callback,experimental::FastAccessorBuilder * fast_handler,v8::Local<Value> data,v8::Local<Signature> signature,int length,bool do_not_cache,v8::Local<Private> cached_property_name=v8::Local<Private> ())1288 static Local<FunctionTemplate> FunctionTemplateNew(
1289     i::Isolate* isolate, FunctionCallback callback,
1290     experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
1291     v8::Local<Signature> signature, int length, bool do_not_cache,
1292     v8::Local<Private> cached_property_name = v8::Local<Private>()) {
1293   i::Handle<i::Struct> struct_obj =
1294       isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
1295   i::Handle<i::FunctionTemplateInfo> obj =
1296       i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1297   InitializeFunctionTemplate(obj);
1298   obj->set_do_not_cache(do_not_cache);
1299   int next_serial_number = i::FunctionTemplateInfo::kInvalidSerialNumber;
1300   if (!do_not_cache) {
1301     next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
1302   }
1303   obj->set_serial_number(i::Smi::FromInt(next_serial_number));
1304   if (callback != 0) {
1305     if (data.IsEmpty()) {
1306       data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1307     }
1308     Utils::ToLocal(obj)->SetCallHandler(callback, data, fast_handler);
1309   }
1310   obj->set_length(length);
1311   obj->set_undetectable(false);
1312   obj->set_needs_access_check(false);
1313   obj->set_accept_any_receiver(true);
1314   if (!signature.IsEmpty())
1315     obj->set_signature(*Utils::OpenHandle(*signature));
1316   obj->set_cached_property_name(
1317       cached_property_name.IsEmpty()
1318           ? isolate->heap()->the_hole_value()
1319           : *Utils::OpenHandle(*cached_property_name));
1320   return Utils::ToLocal(obj);
1321 }
1322 
New(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior)1323 Local<FunctionTemplate> FunctionTemplate::New(
1324     Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1325     v8::Local<Signature> signature, int length, ConstructorBehavior behavior) {
1326   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1327   // Changes to the environment cannot be captured in the snapshot. Expect no
1328   // function templates when the isolate is created for serialization.
1329   LOG_API(i_isolate, FunctionTemplate, New);
1330   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1331   auto templ = FunctionTemplateNew(i_isolate, callback, nullptr, data,
1332                                    signature, length, false);
1333   if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
1334   return templ;
1335 }
1336 
FromSnapshot(Isolate * isolate,size_t index)1337 MaybeLocal<FunctionTemplate> FunctionTemplate::FromSnapshot(Isolate* isolate,
1338                                                             size_t index) {
1339   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1340   i::FixedArray* templates = i_isolate->heap()->serialized_templates();
1341   int int_index = static_cast<int>(index);
1342   if (int_index < templates->length()) {
1343     i::Object* info = templates->get(int_index);
1344     if (info->IsFunctionTemplateInfo()) {
1345       return Utils::ToLocal(i::Handle<i::FunctionTemplateInfo>(
1346           i::FunctionTemplateInfo::cast(info)));
1347     }
1348   }
1349   return Local<FunctionTemplate>();
1350 }
1351 
NewWithFastHandler(Isolate * isolate,FunctionCallback callback,experimental::FastAccessorBuilder * fast_handler,v8::Local<Value> data,v8::Local<Signature> signature,int length)1352 Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
1353     Isolate* isolate, FunctionCallback callback,
1354     experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
1355     v8::Local<Signature> signature, int length) {
1356   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1357   LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler);
1358   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1359   return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature,
1360                              length, false);
1361 }
1362 
NewWithCache(Isolate * isolate,FunctionCallback callback,Local<Private> cache_property,Local<Value> data,Local<Signature> signature,int length)1363 Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1364     Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1365     Local<Value> data, Local<Signature> signature, int length) {
1366   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1367   LOG_API(i_isolate, FunctionTemplate, NewWithCache);
1368   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1369   return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature,
1370                              length, false, cache_property);
1371 }
1372 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1373 Local<Signature> Signature::New(Isolate* isolate,
1374                                 Local<FunctionTemplate> receiver) {
1375   return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1376 }
1377 
1378 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1379 Local<AccessorSignature> AccessorSignature::New(
1380     Isolate* isolate, Local<FunctionTemplate> receiver) {
1381   return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1382 }
1383 
1384 
1385 #define SET_FIELD_WRAPPED(obj, setter, cdata) do {                      \
1386     i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
1387     (obj)->setter(*foreign);                                            \
1388   } while (false)
1389 
1390 
SetCallHandler(FunctionCallback callback,v8::Local<Value> data,experimental::FastAccessorBuilder * fast_handler)1391 void FunctionTemplate::SetCallHandler(
1392     FunctionCallback callback, v8::Local<Value> data,
1393     experimental::FastAccessorBuilder* fast_handler) {
1394   auto info = Utils::OpenHandle(this);
1395   EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler");
1396   i::Isolate* isolate = info->GetIsolate();
1397   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1398   i::HandleScope scope(isolate);
1399   i::Handle<i::Struct> struct_obj =
1400       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1401   i::Handle<i::CallHandlerInfo> obj =
1402       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1403   SET_FIELD_WRAPPED(obj, set_callback, callback);
1404   i::MaybeHandle<i::Code> code =
1405       i::experimental::BuildCodeFromFastAccessorBuilder(fast_handler);
1406   if (!code.is_null()) {
1407     obj->set_fast_handler(*code.ToHandleChecked());
1408   }
1409   if (data.IsEmpty()) {
1410     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1411   }
1412   obj->set_data(*Utils::OpenHandle(*data));
1413   info->set_call_code(*obj);
1414 }
1415 
1416 
SetAccessorInfoProperties(i::Handle<i::AccessorInfo> obj,v8::Local<Name> name,v8::AccessControl settings,v8::PropertyAttribute attributes,v8::Local<AccessorSignature> signature)1417 static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1418     i::Handle<i::AccessorInfo> obj, v8::Local<Name> name,
1419     v8::AccessControl settings, v8::PropertyAttribute attributes,
1420     v8::Local<AccessorSignature> signature) {
1421   obj->set_name(*Utils::OpenHandle(*name));
1422   if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1423   if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1424   obj->set_property_attributes(static_cast<i::PropertyAttributes>(attributes));
1425   if (!signature.IsEmpty()) {
1426     obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1427   }
1428   return obj;
1429 }
1430 
1431 namespace {
1432 
1433 template <typename Getter, typename Setter>
MakeAccessorInfo(v8::Local<Name> name,Getter getter,Setter setter,v8::Local<Value> data,v8::AccessControl settings,v8::PropertyAttribute attributes,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access)1434 i::Handle<i::AccessorInfo> MakeAccessorInfo(
1435     v8::Local<Name> name, Getter getter, Setter setter, v8::Local<Value> data,
1436     v8::AccessControl settings, v8::PropertyAttribute attributes,
1437     v8::Local<AccessorSignature> signature, bool is_special_data_property,
1438     bool replace_on_access) {
1439   i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1440   i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1441   SET_FIELD_WRAPPED(obj, set_getter, getter);
1442   DCHECK_IMPLIES(replace_on_access,
1443                  is_special_data_property && setter == nullptr);
1444   if (is_special_data_property && setter == nullptr) {
1445     setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1446   }
1447   SET_FIELD_WRAPPED(obj, set_setter, setter);
1448   i::Address redirected = obj->redirected_getter();
1449   if (redirected != nullptr) SET_FIELD_WRAPPED(obj, set_js_getter, redirected);
1450   if (data.IsEmpty()) {
1451     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1452   }
1453   obj->set_data(*Utils::OpenHandle(*data));
1454   obj->set_is_special_data_property(is_special_data_property);
1455   obj->set_replace_on_access(replace_on_access);
1456   return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1457 }
1458 
1459 }  // namespace
1460 
InstanceTemplate()1461 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1462   i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1463   if (!Utils::ApiCheck(!handle.is_null(),
1464                        "v8::FunctionTemplate::InstanceTemplate()",
1465                        "Reading from empty handle")) {
1466     return Local<ObjectTemplate>();
1467   }
1468   i::Isolate* isolate = handle->GetIsolate();
1469   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1470   if (handle->instance_template()->IsUndefined(isolate)) {
1471     Local<ObjectTemplate> templ =
1472         ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1473     handle->set_instance_template(*Utils::OpenHandle(*templ));
1474   }
1475   i::Handle<i::ObjectTemplateInfo> result(
1476       i::ObjectTemplateInfo::cast(handle->instance_template()));
1477   return Utils::ToLocal(result);
1478 }
1479 
1480 
SetLength(int length)1481 void FunctionTemplate::SetLength(int length) {
1482   auto info = Utils::OpenHandle(this);
1483   EnsureNotInstantiated(info, "v8::FunctionTemplate::SetLength");
1484   auto isolate = info->GetIsolate();
1485   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1486   info->set_length(length);
1487 }
1488 
1489 
SetClassName(Local<String> name)1490 void FunctionTemplate::SetClassName(Local<String> name) {
1491   auto info = Utils::OpenHandle(this);
1492   EnsureNotInstantiated(info, "v8::FunctionTemplate::SetClassName");
1493   auto isolate = info->GetIsolate();
1494   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1495   info->set_class_name(*Utils::OpenHandle(*name));
1496 }
1497 
1498 
SetAcceptAnyReceiver(bool value)1499 void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1500   auto info = Utils::OpenHandle(this);
1501   EnsureNotInstantiated(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1502   auto isolate = info->GetIsolate();
1503   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1504   info->set_accept_any_receiver(value);
1505 }
1506 
1507 
SetHiddenPrototype(bool value)1508 void FunctionTemplate::SetHiddenPrototype(bool value) {
1509   auto info = Utils::OpenHandle(this);
1510   EnsureNotInstantiated(info, "v8::FunctionTemplate::SetHiddenPrototype");
1511   auto isolate = info->GetIsolate();
1512   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1513   info->set_hidden_prototype(value);
1514 }
1515 
1516 
ReadOnlyPrototype()1517 void FunctionTemplate::ReadOnlyPrototype() {
1518   auto info = Utils::OpenHandle(this);
1519   EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1520   auto isolate = info->GetIsolate();
1521   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1522   info->set_read_only_prototype(true);
1523 }
1524 
1525 
RemovePrototype()1526 void FunctionTemplate::RemovePrototype() {
1527   auto info = Utils::OpenHandle(this);
1528   EnsureNotInstantiated(info, "v8::FunctionTemplate::RemovePrototype");
1529   auto isolate = info->GetIsolate();
1530   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1531   info->set_remove_prototype(true);
1532 }
1533 
1534 
1535 // --- O b j e c t T e m p l a t e ---
1536 
1537 
New(Isolate * isolate,v8::Local<FunctionTemplate> constructor)1538 Local<ObjectTemplate> ObjectTemplate::New(
1539     Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1540   return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1541 }
1542 
1543 
New()1544 Local<ObjectTemplate> ObjectTemplate::New() {
1545   return New(i::Isolate::Current(), Local<FunctionTemplate>());
1546 }
1547 
ObjectTemplateNew(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor,bool do_not_cache)1548 static Local<ObjectTemplate> ObjectTemplateNew(
1549     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1550     bool do_not_cache) {
1551   LOG_API(isolate, ObjectTemplate, New);
1552   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1553   i::Handle<i::Struct> struct_obj =
1554       isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
1555   i::Handle<i::ObjectTemplateInfo> obj =
1556       i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1557   InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1558   int next_serial_number = 0;
1559   if (!do_not_cache) {
1560     next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
1561   }
1562   obj->set_serial_number(i::Smi::FromInt(next_serial_number));
1563   if (!constructor.IsEmpty())
1564     obj->set_constructor(*Utils::OpenHandle(*constructor));
1565   obj->set_data(i::Smi::kZero);
1566   return Utils::ToLocal(obj);
1567 }
1568 
New(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor)1569 Local<ObjectTemplate> ObjectTemplate::New(
1570     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1571   return ObjectTemplateNew(isolate, constructor, false);
1572 }
1573 
FromSnapshot(Isolate * isolate,size_t index)1574 MaybeLocal<ObjectTemplate> ObjectTemplate::FromSnapshot(Isolate* isolate,
1575                                                         size_t index) {
1576   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1577   i::FixedArray* templates = i_isolate->heap()->serialized_templates();
1578   int int_index = static_cast<int>(index);
1579   if (int_index < templates->length()) {
1580     i::Object* info = templates->get(int_index);
1581     if (info->IsObjectTemplateInfo()) {
1582       return Utils::ToLocal(
1583           i::Handle<i::ObjectTemplateInfo>(i::ObjectTemplateInfo::cast(info)));
1584     }
1585   }
1586   return Local<ObjectTemplate>();
1587 }
1588 
1589 // Ensure that the object template has a constructor.  If no
1590 // constructor is available we create one.
EnsureConstructor(i::Isolate * isolate,ObjectTemplate * object_template)1591 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1592     i::Isolate* isolate,
1593     ObjectTemplate* object_template) {
1594   i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1595   if (!obj->IsUndefined(isolate)) {
1596     i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1597     return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1598   }
1599   Local<FunctionTemplate> templ =
1600       FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1601   i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1602   constructor->set_instance_template(*Utils::OpenHandle(object_template));
1603   Utils::OpenHandle(object_template)->set_constructor(*constructor);
1604   return constructor;
1605 }
1606 
1607 template <typename Getter, typename Setter, typename Data, typename Template>
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)1608 static bool TemplateSetAccessor(Template* template_obj, v8::Local<Name> name,
1609                                 Getter getter, Setter setter, Data data,
1610                                 AccessControl settings,
1611                                 PropertyAttribute attribute,
1612                                 v8::Local<AccessorSignature> signature,
1613                                 bool is_special_data_property,
1614                                 bool replace_on_access) {
1615   auto info = Utils::OpenHandle(template_obj);
1616   auto isolate = info->GetIsolate();
1617   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1618   i::HandleScope scope(isolate);
1619   auto obj =
1620       MakeAccessorInfo(name, getter, setter, data, settings, attribute,
1621                        signature, is_special_data_property, replace_on_access);
1622   if (obj.is_null()) return false;
1623   i::ApiNatives::AddNativeDataProperty(isolate, info, obj);
1624   return true;
1625 }
1626 
1627 
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings)1628 void Template::SetNativeDataProperty(v8::Local<String> name,
1629                                      AccessorGetterCallback getter,
1630                                      AccessorSetterCallback setter,
1631                                      v8::Local<Value> data,
1632                                      PropertyAttribute attribute,
1633                                      v8::Local<AccessorSignature> signature,
1634                                      AccessControl settings) {
1635   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1636                       signature, true, false);
1637 }
1638 
1639 
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings)1640 void Template::SetNativeDataProperty(v8::Local<Name> name,
1641                                      AccessorNameGetterCallback getter,
1642                                      AccessorNameSetterCallback setter,
1643                                      v8::Local<Value> data,
1644                                      PropertyAttribute attribute,
1645                                      v8::Local<AccessorSignature> signature,
1646                                      AccessControl settings) {
1647   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1648                       signature, true, false);
1649 }
1650 
SetLazyDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attribute)1651 void Template::SetLazyDataProperty(v8::Local<Name> name,
1652                                    AccessorNameGetterCallback getter,
1653                                    v8::Local<Value> data,
1654                                    PropertyAttribute attribute) {
1655   TemplateSetAccessor(
1656       this, name, getter, static_cast<AccessorNameSetterCallback>(nullptr),
1657       data, DEFAULT, attribute, Local<AccessorSignature>(), true, true);
1658 }
1659 
SetIntrinsicDataProperty(Local<Name> name,Intrinsic intrinsic,PropertyAttribute attribute)1660 void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1661                                         PropertyAttribute attribute) {
1662   auto templ = Utils::OpenHandle(this);
1663   i::Isolate* isolate = templ->GetIsolate();
1664   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1665   i::HandleScope scope(isolate);
1666   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1667                                  intrinsic,
1668                                  static_cast<i::PropertyAttributes>(attribute));
1669 }
1670 
1671 
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature)1672 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1673                                  AccessorGetterCallback getter,
1674                                  AccessorSetterCallback setter,
1675                                  v8::Local<Value> data, AccessControl settings,
1676                                  PropertyAttribute attribute,
1677                                  v8::Local<AccessorSignature> signature) {
1678   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1679                       signature, i::FLAG_disable_old_api_accessors, false);
1680 }
1681 
1682 
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature)1683 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1684                                  AccessorNameGetterCallback getter,
1685                                  AccessorNameSetterCallback setter,
1686                                  v8::Local<Value> data, AccessControl settings,
1687                                  PropertyAttribute attribute,
1688                                  v8::Local<AccessorSignature> signature) {
1689   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1690                       signature, i::FLAG_disable_old_api_accessors, false);
1691 }
1692 
1693 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1694           typename Deleter, typename Enumerator, typename Definer>
CreateInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1695 static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1696     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1697     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1698     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1699   DCHECK(query == nullptr ||
1700          descriptor == nullptr);  // Either intercept attributes or descriptor.
1701   DCHECK(query == nullptr ||
1702          definer ==
1703              nullptr);  // Only use descriptor callback with definer callback.
1704   auto obj = i::Handle<i::InterceptorInfo>::cast(
1705       isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
1706   obj->set_flags(0);
1707 
1708   if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1709   if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1710   if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1711   if (descriptor != 0) SET_FIELD_WRAPPED(obj, set_descriptor, descriptor);
1712   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1713   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1714   if (definer != 0) SET_FIELD_WRAPPED(obj, set_definer, definer);
1715   obj->set_can_intercept_symbols(
1716       !(static_cast<int>(flags) &
1717         static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1718   obj->set_all_can_read(static_cast<int>(flags) &
1719                         static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1720   obj->set_non_masking(static_cast<int>(flags) &
1721                        static_cast<int>(PropertyHandlerFlags::kNonMasking));
1722 
1723   if (data.IsEmpty()) {
1724     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1725   }
1726   obj->set_data(*Utils::OpenHandle(*data));
1727   return obj;
1728 }
1729 
1730 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1731           typename Deleter, typename Enumerator, typename Definer>
ObjectTemplateSetNamedPropertyHandler(ObjectTemplate * templ,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1732 static void ObjectTemplateSetNamedPropertyHandler(
1733     ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1734     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1735     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1736   i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1737   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1738   i::HandleScope scope(isolate);
1739   auto cons = EnsureConstructor(isolate, templ);
1740   EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
1741   auto obj = CreateInterceptorInfo(isolate, getter, setter, query, descriptor,
1742                                    remover, enumerator, definer, data, flags);
1743   cons->set_named_property_handler(*obj);
1744 }
1745 
SetNamedPropertyHandler(NamedPropertyGetterCallback getter,NamedPropertySetterCallback setter,NamedPropertyQueryCallback query,NamedPropertyDeleterCallback remover,NamedPropertyEnumeratorCallback enumerator,Local<Value> data)1746 void ObjectTemplate::SetNamedPropertyHandler(
1747     NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
1748     NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
1749     NamedPropertyEnumeratorCallback enumerator, Local<Value> data) {
1750   ObjectTemplateSetNamedPropertyHandler(
1751       this, getter, setter, query, nullptr, remover, enumerator, nullptr, data,
1752       PropertyHandlerFlags::kOnlyInterceptStrings);
1753 }
1754 
SetHandler(const NamedPropertyHandlerConfiguration & config)1755 void ObjectTemplate::SetHandler(
1756     const NamedPropertyHandlerConfiguration& config) {
1757   ObjectTemplateSetNamedPropertyHandler(
1758       this, config.getter, config.setter, config.query, config.descriptor,
1759       config.deleter, config.enumerator, config.definer, config.data,
1760       config.flags);
1761 }
1762 
1763 
MarkAsUndetectable()1764 void ObjectTemplate::MarkAsUndetectable() {
1765   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1766   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1767   i::HandleScope scope(isolate);
1768   auto cons = EnsureConstructor(isolate, this);
1769   EnsureNotInstantiated(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1770   cons->set_undetectable(true);
1771 }
1772 
1773 
SetAccessCheckCallback(AccessCheckCallback callback,Local<Value> data)1774 void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1775                                             Local<Value> data) {
1776   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1777   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1778   i::HandleScope scope(isolate);
1779   auto cons = EnsureConstructor(isolate, this);
1780   EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1781 
1782   i::Handle<i::Struct> struct_info =
1783       isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
1784   i::Handle<i::AccessCheckInfo> info =
1785       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1786 
1787   SET_FIELD_WRAPPED(info, set_callback, callback);
1788   info->set_named_interceptor(nullptr);
1789   info->set_indexed_interceptor(nullptr);
1790 
1791   if (data.IsEmpty()) {
1792     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1793   }
1794   info->set_data(*Utils::OpenHandle(*data));
1795 
1796   cons->set_access_check_info(*info);
1797   cons->set_needs_access_check(true);
1798 }
1799 
SetAccessCheckCallbackAndHandler(AccessCheckCallback callback,const NamedPropertyHandlerConfiguration & named_handler,const IndexedPropertyHandlerConfiguration & indexed_handler,Local<Value> data)1800 void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1801     AccessCheckCallback callback,
1802     const NamedPropertyHandlerConfiguration& named_handler,
1803     const IndexedPropertyHandlerConfiguration& indexed_handler,
1804     Local<Value> data) {
1805   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1806   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1807   i::HandleScope scope(isolate);
1808   auto cons = EnsureConstructor(isolate, this);
1809   EnsureNotInstantiated(
1810       cons, "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1811 
1812   i::Handle<i::Struct> struct_info =
1813       isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
1814   i::Handle<i::AccessCheckInfo> info =
1815       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1816 
1817   SET_FIELD_WRAPPED(info, set_callback, callback);
1818   auto named_interceptor = CreateInterceptorInfo(
1819       isolate, named_handler.getter, named_handler.setter, named_handler.query,
1820       named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1821       named_handler.definer, named_handler.data, named_handler.flags);
1822   info->set_named_interceptor(*named_interceptor);
1823   auto indexed_interceptor = CreateInterceptorInfo(
1824       isolate, indexed_handler.getter, indexed_handler.setter,
1825       indexed_handler.query, indexed_handler.descriptor,
1826       indexed_handler.deleter, indexed_handler.enumerator,
1827       indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1828   info->set_indexed_interceptor(*indexed_interceptor);
1829 
1830   if (data.IsEmpty()) {
1831     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1832   }
1833   info->set_data(*Utils::OpenHandle(*data));
1834 
1835   cons->set_access_check_info(*info);
1836   cons->set_needs_access_check(true);
1837 }
1838 
SetHandler(const IndexedPropertyHandlerConfiguration & config)1839 void ObjectTemplate::SetHandler(
1840     const IndexedPropertyHandlerConfiguration& config) {
1841   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1842   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1843   i::HandleScope scope(isolate);
1844   auto cons = EnsureConstructor(isolate, this);
1845   EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler");
1846   auto obj = CreateInterceptorInfo(isolate, config.getter, config.setter,
1847                                    config.query, config.descriptor,
1848                                    config.deleter, config.enumerator,
1849                                    config.definer, config.data, config.flags);
1850   cons->set_indexed_property_handler(*obj);
1851 }
1852 
1853 
SetCallAsFunctionHandler(FunctionCallback callback,Local<Value> data)1854 void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1855                                               Local<Value> data) {
1856   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1857   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1858   i::HandleScope scope(isolate);
1859   auto cons = EnsureConstructor(isolate, this);
1860   EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1861   i::Handle<i::Struct> struct_obj =
1862       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1863   i::Handle<i::CallHandlerInfo> obj =
1864       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1865   SET_FIELD_WRAPPED(obj, set_callback, callback);
1866   if (data.IsEmpty()) {
1867     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1868   }
1869   obj->set_data(*Utils::OpenHandle(*data));
1870   cons->set_instance_call_handler(*obj);
1871 }
1872 
1873 
InternalFieldCount()1874 int ObjectTemplate::InternalFieldCount() {
1875   return Utils::OpenHandle(this)->internal_field_count();
1876 }
1877 
1878 
SetInternalFieldCount(int value)1879 void ObjectTemplate::SetInternalFieldCount(int value) {
1880   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1881   if (!Utils::ApiCheck(i::Smi::IsValid(value),
1882                        "v8::ObjectTemplate::SetInternalFieldCount()",
1883                        "Invalid internal field count")) {
1884     return;
1885   }
1886   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1887   if (value > 0) {
1888     // The internal field count is set by the constructor function's
1889     // construct code, so we ensure that there is a constructor
1890     // function to do the setting.
1891     EnsureConstructor(isolate, this);
1892   }
1893   Utils::OpenHandle(this)->set_internal_field_count(value);
1894 }
1895 
IsImmutableProto()1896 bool ObjectTemplate::IsImmutableProto() {
1897   return Utils::OpenHandle(this)->immutable_proto();
1898 }
1899 
SetImmutableProto()1900 void ObjectTemplate::SetImmutableProto() {
1901   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1902   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1903   Utils::OpenHandle(this)->set_immutable_proto(true);
1904 }
1905 
1906 // --- S c r i p t s ---
1907 
1908 
1909 // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1910 // JSFunction.
1911 
CachedData(const uint8_t * data_,int length_,BufferPolicy buffer_policy_)1912 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1913                                        BufferPolicy buffer_policy_)
1914     : data(data_),
1915       length(length_),
1916       rejected(false),
1917       buffer_policy(buffer_policy_) {}
1918 
1919 
~CachedData()1920 ScriptCompiler::CachedData::~CachedData() {
1921   if (buffer_policy == BufferOwned) {
1922     delete[] data;
1923   }
1924 }
1925 
1926 
SetBookmark()1927 bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; }
1928 
1929 
ResetToBookmark()1930 void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); }
1931 
1932 
StreamedSource(ExternalSourceStream * stream,Encoding encoding)1933 ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
1934                                                Encoding encoding)
1935     : impl_(new i::StreamedSource(stream, encoding)) {}
1936 
1937 
~StreamedSource()1938 ScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; }
1939 
1940 
1941 const ScriptCompiler::CachedData*
GetCachedData() const1942 ScriptCompiler::StreamedSource::GetCachedData() const {
1943   return impl_->cached_data.get();
1944 }
1945 
1946 
BindToCurrentContext()1947 Local<Script> UnboundScript::BindToCurrentContext() {
1948   i::Handle<i::HeapObject> obj =
1949       i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1950   i::Isolate* isolate = obj->GetIsolate();
1951   i::Handle<i::SharedFunctionInfo> function_info(
1952       i::SharedFunctionInfo::cast(*obj), isolate);
1953   i::Handle<i::JSFunction> function =
1954       isolate->factory()->NewFunctionFromSharedFunctionInfo(
1955           function_info, isolate->native_context());
1956   return ToApiHandle<Script>(function);
1957 }
1958 
1959 
GetId()1960 int UnboundScript::GetId() {
1961   i::Handle<i::HeapObject> obj =
1962       i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1963   i::Isolate* isolate = obj->GetIsolate();
1964   LOG_API(isolate, UnboundScript, GetId);
1965   i::HandleScope scope(isolate);
1966   i::Handle<i::SharedFunctionInfo> function_info(
1967       i::SharedFunctionInfo::cast(*obj));
1968   i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1969   return script->id();
1970 }
1971 
1972 
GetLineNumber(int code_pos)1973 int UnboundScript::GetLineNumber(int code_pos) {
1974   i::Handle<i::SharedFunctionInfo> obj =
1975       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1976   i::Isolate* isolate = obj->GetIsolate();
1977   LOG_API(isolate, UnboundScript, GetLineNumber);
1978   if (obj->script()->IsScript()) {
1979     i::Handle<i::Script> script(i::Script::cast(obj->script()));
1980     return i::Script::GetLineNumber(script, code_pos);
1981   } else {
1982     return -1;
1983   }
1984 }
1985 
1986 
GetScriptName()1987 Local<Value> UnboundScript::GetScriptName() {
1988   i::Handle<i::SharedFunctionInfo> obj =
1989       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1990   i::Isolate* isolate = obj->GetIsolate();
1991   LOG_API(isolate, UnboundScript, GetName);
1992   if (obj->script()->IsScript()) {
1993     i::Object* name = i::Script::cast(obj->script())->name();
1994     return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1995   } else {
1996     return Local<String>();
1997   }
1998 }
1999 
2000 
GetSourceURL()2001 Local<Value> UnboundScript::GetSourceURL() {
2002   i::Handle<i::SharedFunctionInfo> obj =
2003       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2004   i::Isolate* isolate = obj->GetIsolate();
2005   LOG_API(isolate, UnboundScript, GetSourceURL);
2006   if (obj->script()->IsScript()) {
2007     i::Object* url = i::Script::cast(obj->script())->source_url();
2008     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2009   } else {
2010     return Local<String>();
2011   }
2012 }
2013 
2014 
GetSourceMappingURL()2015 Local<Value> UnboundScript::GetSourceMappingURL() {
2016   i::Handle<i::SharedFunctionInfo> obj =
2017       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2018   i::Isolate* isolate = obj->GetIsolate();
2019   LOG_API(isolate, UnboundScript, GetSourceMappingURL);
2020   if (obj->script()->IsScript()) {
2021     i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
2022     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2023   } else {
2024     return Local<String>();
2025   }
2026 }
2027 
2028 
Run(Local<Context> context)2029 MaybeLocal<Value> Script::Run(Local<Context> context) {
2030   PREPARE_FOR_EXECUTION_WITH_CONTEXT_IN_RUNTIME_CALL_STATS_SCOPE(
2031       "v8", "V8.Execute", context, Script, Run, MaybeLocal<Value>(),
2032       InternalEscapableScope, true);
2033   i::HistogramTimerScope execute_timer(isolate->counters()->execute(), true);
2034   i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2035   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2036   auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2037 
2038   i::Handle<i::Object> receiver = isolate->global_proxy();
2039   Local<Value> result;
2040   has_pending_exception = !ToLocal<Value>(
2041       i::Execution::Call(isolate, fun, receiver, 0, nullptr), &result);
2042 
2043   RETURN_ON_FAILED_EXECUTION(Value);
2044   RETURN_ESCAPED(result);
2045 }
2046 
2047 
Run()2048 Local<Value> Script::Run() {
2049   auto self = Utils::OpenHandle(this, true);
2050   // If execution is terminating, Compile(..)->Run() requires this
2051   // check.
2052   if (self.is_null()) return Local<Value>();
2053   auto context = ContextFromHeapObject(self);
2054   RETURN_TO_LOCAL_UNCHECKED(Run(context), Value);
2055 }
2056 
2057 
GetUnboundScript()2058 Local<UnboundScript> Script::GetUnboundScript() {
2059   i::Handle<i::Object> obj = Utils::OpenHandle(this);
2060   return ToApiHandle<UnboundScript>(
2061       i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
2062 }
2063 
GetModuleRequestsLength() const2064 int Module::GetModuleRequestsLength() const {
2065   i::Handle<i::Module> self = Utils::OpenHandle(this);
2066   return self->info()->module_requests()->length();
2067 }
2068 
GetModuleRequest(int i) const2069 Local<String> Module::GetModuleRequest(int i) const {
2070   CHECK_GE(i, 0);
2071   i::Handle<i::Module> self = Utils::OpenHandle(this);
2072   i::Isolate* isolate = self->GetIsolate();
2073   i::Handle<i::FixedArray> module_requests(self->info()->module_requests(),
2074                                            isolate);
2075   CHECK_LT(i, module_requests->length());
2076   return ToApiHandle<String>(i::handle(module_requests->get(i), isolate));
2077 }
2078 
GetIdentityHash() const2079 int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2080 
Instantiate(Local<Context> context,Module::ResolveCallback callback)2081 bool Module::Instantiate(Local<Context> context,
2082                          Module::ResolveCallback callback) {
2083   PREPARE_FOR_EXECUTION_BOOL(context, Module, Instantiate);
2084   has_pending_exception =
2085       !i::Module::Instantiate(Utils::OpenHandle(this), context, callback);
2086   RETURN_ON_FAILED_EXECUTION_BOOL();
2087   return true;
2088 }
2089 
Evaluate(Local<Context> context)2090 MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2091   PREPARE_FOR_EXECUTION_WITH_CONTEXT_IN_RUNTIME_CALL_STATS_SCOPE(
2092       "v8", "V8.Execute", context, Module, Evaluate, MaybeLocal<Value>(),
2093       InternalEscapableScope, true);
2094   i::HistogramTimerScope execute_timer(isolate->counters()->execute(), true);
2095   i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2096   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2097 
2098   i::Handle<i::Module> self = Utils::OpenHandle(this);
2099   // It's an API error to call Evaluate before Instantiate.
2100   CHECK(self->instantiated());
2101 
2102   Local<Value> result;
2103   has_pending_exception = !ToLocal(i::Module::Evaluate(self), &result);
2104   RETURN_ON_FAILED_EXECUTION(Value);
2105   RETURN_ESCAPED(result);
2106 }
2107 
CompileUnboundInternal(Isolate * v8_isolate,Source * source,CompileOptions options)2108 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2109     Isolate* v8_isolate, Source* source, CompileOptions options) {
2110   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2111   PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, ScriptCompiler, CompileUnbound,
2112                                      UnboundScript);
2113   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2114 
2115   // Don't try to produce any kind of cache when the debugger is loaded.
2116   if (isolate->debug()->is_loaded() &&
2117       (options == kProduceParserCache || options == kProduceCodeCache)) {
2118     options = kNoCompileOptions;
2119   }
2120 
2121   i::ScriptData* script_data = NULL;
2122   if (options == kConsumeParserCache || options == kConsumeCodeCache) {
2123     DCHECK(source->cached_data);
2124     // ScriptData takes care of pointer-aligning the data.
2125     script_data = new i::ScriptData(source->cached_data->data,
2126                                     source->cached_data->length);
2127   }
2128 
2129   i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2130   i::Handle<i::SharedFunctionInfo> result;
2131   {
2132     i::HistogramTimerScope total(isolate->counters()->compile_script(), true);
2133     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2134     i::Handle<i::Object> name_obj;
2135     i::Handle<i::Object> source_map_url;
2136     int line_offset = 0;
2137     int column_offset = 0;
2138     if (!source->resource_name.IsEmpty()) {
2139       name_obj = Utils::OpenHandle(*(source->resource_name));
2140     }
2141     if (!source->resource_line_offset.IsEmpty()) {
2142       line_offset = static_cast<int>(source->resource_line_offset->Value());
2143     }
2144     if (!source->resource_column_offset.IsEmpty()) {
2145       column_offset =
2146           static_cast<int>(source->resource_column_offset->Value());
2147     }
2148     if (!source->source_map_url.IsEmpty()) {
2149       source_map_url = Utils::OpenHandle(*(source->source_map_url));
2150     }
2151     result = i::Compiler::GetSharedFunctionInfoForScript(
2152         str, name_obj, line_offset, column_offset, source->resource_options,
2153         source_map_url, isolate->native_context(), NULL, &script_data, options,
2154         i::NOT_NATIVES_CODE);
2155     has_pending_exception = result.is_null();
2156     if (has_pending_exception && script_data != NULL) {
2157       // This case won't happen during normal operation; we have compiled
2158       // successfully and produced cached data, and but the second compilation
2159       // of the same source code fails.
2160       delete script_data;
2161       script_data = NULL;
2162     }
2163     RETURN_ON_FAILED_EXECUTION(UnboundScript);
2164 
2165     if ((options == kProduceParserCache || options == kProduceCodeCache) &&
2166         script_data != NULL) {
2167       // script_data now contains the data that was generated. source will
2168       // take the ownership.
2169       source->cached_data = new CachedData(
2170           script_data->data(), script_data->length(), CachedData::BufferOwned);
2171       script_data->ReleaseDataOwnership();
2172     } else if (options == kConsumeParserCache || options == kConsumeCodeCache) {
2173       source->cached_data->rejected = script_data->rejected();
2174     }
2175     delete script_data;
2176   }
2177   RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2178 }
2179 
2180 
CompileUnboundScript(Isolate * v8_isolate,Source * source,CompileOptions options)2181 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2182     Isolate* v8_isolate, Source* source, CompileOptions options) {
2183   Utils::ApiCheck(
2184       !source->GetResourceOptions().IsModule(),
2185       "v8::ScriptCompiler::CompileUnboundScript",
2186       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2187   return CompileUnboundInternal(v8_isolate, source, options);
2188 }
2189 
2190 
CompileUnbound(Isolate * v8_isolate,Source * source,CompileOptions options)2191 Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate,
2192                                                     Source* source,
2193                                                     CompileOptions options) {
2194   Utils::ApiCheck(
2195       !source->GetResourceOptions().IsModule(),
2196       "v8::ScriptCompiler::CompileUnbound",
2197       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2198   RETURN_TO_LOCAL_UNCHECKED(CompileUnboundInternal(v8_isolate, source, options),
2199                             UnboundScript);
2200 }
2201 
2202 
Compile(Local<Context> context,Source * source,CompileOptions options)2203 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2204                                            Source* source,
2205                                            CompileOptions options) {
2206   Utils::ApiCheck(
2207       !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2208       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2209   auto isolate = context->GetIsolate();
2210   auto maybe = CompileUnboundInternal(isolate, source, options);
2211   Local<UnboundScript> result;
2212   if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2213   v8::Context::Scope scope(context);
2214   return result->BindToCurrentContext();
2215 }
2216 
2217 
Compile(Isolate * v8_isolate,Source * source,CompileOptions options)2218 Local<Script> ScriptCompiler::Compile(
2219     Isolate* v8_isolate,
2220     Source* source,
2221     CompileOptions options) {
2222   auto context = v8_isolate->GetCurrentContext();
2223   RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, options), Script);
2224 }
2225 
CompileModule(Isolate * isolate,Source * source)2226 MaybeLocal<Module> ScriptCompiler::CompileModule(Isolate* isolate,
2227                                                  Source* source) {
2228   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2229 
2230   Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2231                   "v8::ScriptCompiler::CompileModule",
2232                   "Invalid ScriptOrigin: is_module must be true");
2233   auto maybe = CompileUnboundInternal(isolate, source, kNoCompileOptions);
2234   Local<UnboundScript> unbound;
2235   if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2236 
2237   i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2238   return ToApiHandle<Module>(i_isolate->factory()->NewModule(shared));
2239 }
2240 
2241 
2242 class IsIdentifierHelper {
2243  public:
IsIdentifierHelper()2244   IsIdentifierHelper() : is_identifier_(false), first_char_(true) {}
2245 
Check(i::String * string)2246   bool Check(i::String* string) {
2247     i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
2248     if (cons_string == NULL) return is_identifier_;
2249     // We don't support cons strings here.
2250     return false;
2251   }
VisitOneByteString(const uint8_t * chars,int length)2252   void VisitOneByteString(const uint8_t* chars, int length) {
2253     for (int i = 0; i < length; ++i) {
2254       if (first_char_) {
2255         first_char_ = false;
2256         is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
2257       } else {
2258         is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
2259       }
2260     }
2261   }
VisitTwoByteString(const uint16_t * chars,int length)2262   void VisitTwoByteString(const uint16_t* chars, int length) {
2263     for (int i = 0; i < length; ++i) {
2264       if (first_char_) {
2265         first_char_ = false;
2266         is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
2267       } else {
2268         is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
2269       }
2270     }
2271   }
2272 
2273  private:
2274   bool is_identifier_;
2275   bool first_char_;
2276   i::UnicodeCache unicode_cache_;
2277   DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper);
2278 };
2279 
2280 
CompileFunctionInContext(Local<Context> v8_context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[])2281 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2282     Local<Context> v8_context, Source* source, size_t arguments_count,
2283     Local<String> arguments[], size_t context_extension_count,
2284     Local<Object> context_extensions[]) {
2285   PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
2286                         Function);
2287   TRACE_EVENT0("v8", "V8.ScriptCompiler");
2288   i::Handle<i::String> source_string;
2289   int parameters_end_pos = i::kNoSourcePosition;
2290   auto factory = isolate->factory();
2291   if (arguments_count) {
2292     if (i::FLAG_harmony_function_tostring) {
2293       source_string = factory->NewStringFromStaticChars("(function anonymous(");
2294     } else {
2295       source_string = factory->NewStringFromStaticChars("(function(");
2296     }
2297     for (size_t i = 0; i < arguments_count; ++i) {
2298       IsIdentifierHelper helper;
2299       if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) {
2300         return Local<Function>();
2301       }
2302       has_pending_exception =
2303           !factory->NewConsString(source_string,
2304                                   Utils::OpenHandle(*arguments[i]))
2305                .ToHandle(&source_string);
2306       RETURN_ON_FAILED_EXECUTION(Function);
2307       if (i + 1 == arguments_count) continue;
2308       has_pending_exception =
2309           !factory->NewConsString(source_string,
2310                                   factory->LookupSingleCharacterStringFromCode(
2311                                       ',')).ToHandle(&source_string);
2312       RETURN_ON_FAILED_EXECUTION(Function);
2313     }
2314     i::Handle<i::String> brackets;
2315     if (i::FLAG_harmony_function_tostring) {
2316       brackets = factory->NewStringFromStaticChars("\n) {");
2317       parameters_end_pos = source_string->length() - 3;
2318     } else {
2319       brackets = factory->NewStringFromStaticChars("){");
2320     }
2321     has_pending_exception = !factory->NewConsString(source_string, brackets)
2322                                  .ToHandle(&source_string);
2323     RETURN_ON_FAILED_EXECUTION(Function);
2324   } else {
2325     if (i::FLAG_harmony_function_tostring) {
2326       source_string =
2327           factory->NewStringFromStaticChars("(function anonymous(\n) {");
2328       parameters_end_pos = source_string->length() - 3;
2329     } else {
2330       source_string = factory->NewStringFromStaticChars("(function(){");
2331     }
2332   }
2333 
2334   int scope_position = source_string->length();
2335   has_pending_exception =
2336       !factory->NewConsString(source_string,
2337                               Utils::OpenHandle(*source->source_string))
2338            .ToHandle(&source_string);
2339   RETURN_ON_FAILED_EXECUTION(Function);
2340   // Include \n in case the source contains a line end comment.
2341   auto brackets = factory->NewStringFromStaticChars("\n})");
2342   has_pending_exception =
2343       !factory->NewConsString(source_string, brackets).ToHandle(&source_string);
2344   RETURN_ON_FAILED_EXECUTION(Function);
2345 
2346   i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2347   i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(),
2348                                               isolate);
2349   for (size_t i = 0; i < context_extension_count; ++i) {
2350     i::Handle<i::JSReceiver> extension =
2351         Utils::OpenHandle(*context_extensions[i]);
2352     if (!extension->IsJSObject()) return Local<Function>();
2353     i::Handle<i::JSFunction> closure(context->closure(), isolate);
2354     context = factory->NewWithContext(
2355         closure, context,
2356         i::ScopeInfo::CreateForWithScope(
2357             isolate, context->IsNativeContext()
2358                          ? i::Handle<i::ScopeInfo>::null()
2359                          : i::Handle<i::ScopeInfo>(context->scope_info())),
2360         extension);
2361   }
2362 
2363   i::Handle<i::Object> name_obj;
2364   int eval_scope_position = 0;
2365   int eval_position = i::kNoSourcePosition;
2366   int line_offset = 0;
2367   int column_offset = 0;
2368   if (!source->resource_name.IsEmpty()) {
2369     name_obj = Utils::OpenHandle(*(source->resource_name));
2370   }
2371   if (!source->resource_line_offset.IsEmpty()) {
2372     line_offset = static_cast<int>(source->resource_line_offset->Value());
2373   }
2374   if (!source->resource_column_offset.IsEmpty()) {
2375     column_offset = static_cast<int>(source->resource_column_offset->Value());
2376   }
2377   i::Handle<i::JSFunction> fun;
2378   has_pending_exception =
2379       !i::Compiler::GetFunctionFromEval(
2380            source_string, outer_info, context, i::SLOPPY,
2381            i::ONLY_SINGLE_FUNCTION_LITERAL, parameters_end_pos,
2382            eval_scope_position, eval_position, line_offset,
2383            column_offset - scope_position, name_obj, source->resource_options)
2384            .ToHandle(&fun);
2385   if (has_pending_exception) {
2386     isolate->ReportPendingMessages();
2387   }
2388   RETURN_ON_FAILED_EXECUTION(Function);
2389 
2390   i::Handle<i::Object> result;
2391   has_pending_exception =
2392       !i::Execution::Call(isolate, fun,
2393                           Utils::OpenHandle(*v8_context->Global()), 0,
2394                           nullptr).ToHandle(&result);
2395   RETURN_ON_FAILED_EXECUTION(Function);
2396   RETURN_ESCAPED(
2397       Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(result)));
2398 }
2399 
2400 
CompileFunctionInContext(Isolate * v8_isolate,Source * source,Local<Context> v8_context,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[])2401 Local<Function> ScriptCompiler::CompileFunctionInContext(
2402     Isolate* v8_isolate, Source* source, Local<Context> v8_context,
2403     size_t arguments_count, Local<String> arguments[],
2404     size_t context_extension_count, Local<Object> context_extensions[]) {
2405   RETURN_TO_LOCAL_UNCHECKED(
2406       CompileFunctionInContext(v8_context, source, arguments_count, arguments,
2407                                context_extension_count, context_extensions),
2408       Function);
2409 }
2410 
2411 
StartStreamingScript(Isolate * v8_isolate,StreamedSource * source,CompileOptions options)2412 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
2413     Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
2414   if (!i::FLAG_script_streaming) {
2415     return nullptr;
2416   }
2417   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2418   return new i::BackgroundParsingTask(source->impl(), options,
2419                                       i::FLAG_stack_size, isolate);
2420 }
2421 
2422 
Compile(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2423 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2424                                            StreamedSource* v8_source,
2425                                            Local<String> full_source_string,
2426                                            const ScriptOrigin& origin) {
2427   PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2428   TRACE_EVENT0("v8", "V8.ScriptCompiler");
2429   i::StreamedSource* source = v8_source->impl();
2430   i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2431   i::Handle<i::Script> script = isolate->factory()->NewScript(str);
2432   if (!origin.ResourceName().IsEmpty()) {
2433     script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
2434   }
2435   if (!origin.ResourceLineOffset().IsEmpty()) {
2436     script->set_line_offset(
2437         static_cast<int>(origin.ResourceLineOffset()->Value()));
2438   }
2439   if (!origin.ResourceColumnOffset().IsEmpty()) {
2440     script->set_column_offset(
2441         static_cast<int>(origin.ResourceColumnOffset()->Value()));
2442   }
2443   script->set_origin_options(origin.Options());
2444   if (!origin.SourceMapUrl().IsEmpty()) {
2445     script->set_source_mapping_url(
2446         *Utils::OpenHandle(*(origin.SourceMapUrl())));
2447   }
2448 
2449   source->info->set_script(script);
2450   if (source->info->literal() == nullptr) {
2451     source->parser->ReportErrors(isolate, script);
2452   }
2453   source->parser->UpdateStatistics(isolate, script);
2454 
2455   i::DeferredHandleScope deferred_handle_scope(isolate);
2456   {
2457     // Internalize AST values on the main thread.
2458     source->info->ReopenHandlesInNewHandleScope();
2459     source->info->ast_value_factory()->Internalize(isolate);
2460     source->parser->HandleSourceURLComments(isolate, script);
2461   }
2462   source->info->set_deferred_handles(deferred_handle_scope.Detach());
2463 
2464   i::Handle<i::SharedFunctionInfo> result;
2465   if (source->info->literal() != nullptr) {
2466     // Parsing has succeeded.
2467     result = i::Compiler::GetSharedFunctionInfoForStreamedScript(
2468         script, source->info.get(), str->length());
2469   }
2470   has_pending_exception = result.is_null();
2471   if (has_pending_exception) isolate->ReportPendingMessages();
2472 
2473   source->Release();
2474 
2475   RETURN_ON_FAILED_EXECUTION(Script);
2476 
2477   Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
2478   if (generic.IsEmpty()) return Local<Script>();
2479   Local<Script> bound = generic->BindToCurrentContext();
2480   if (bound.IsEmpty()) return Local<Script>();
2481   RETURN_ESCAPED(bound);
2482 }
2483 
2484 
Compile(Isolate * v8_isolate,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2485 Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
2486                                       StreamedSource* v8_source,
2487                                       Local<String> full_source_string,
2488                                       const ScriptOrigin& origin) {
2489   auto context = v8_isolate->GetCurrentContext();
2490   RETURN_TO_LOCAL_UNCHECKED(
2491       Compile(context, v8_source, full_source_string, origin), Script);
2492 }
2493 
2494 
CachedDataVersionTag()2495 uint32_t ScriptCompiler::CachedDataVersionTag() {
2496   return static_cast<uint32_t>(base::hash_combine(
2497       internal::Version::Hash(), internal::FlagList::Hash(),
2498       static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2499 }
2500 
2501 
Compile(Local<Context> context,Local<String> source,ScriptOrigin * origin)2502 MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2503                                    ScriptOrigin* origin) {
2504   if (origin) {
2505     ScriptCompiler::Source script_source(source, *origin);
2506     return ScriptCompiler::Compile(context, &script_source);
2507   }
2508   ScriptCompiler::Source script_source(source);
2509   return ScriptCompiler::Compile(context, &script_source);
2510 }
2511 
2512 
Compile(v8::Local<String> source,v8::ScriptOrigin * origin)2513 Local<Script> Script::Compile(v8::Local<String> source,
2514                               v8::ScriptOrigin* origin) {
2515   auto str = Utils::OpenHandle(*source);
2516   auto context = ContextFromHeapObject(str);
2517   RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script);
2518 }
2519 
2520 
Compile(v8::Local<String> source,v8::Local<String> file_name)2521 Local<Script> Script::Compile(v8::Local<String> source,
2522                               v8::Local<String> file_name) {
2523   auto str = Utils::OpenHandle(*source);
2524   auto context = ContextFromHeapObject(str);
2525   ScriptOrigin origin(file_name);
2526   return Compile(context, source, &origin).FromMaybe(Local<Script>());
2527 }
2528 
2529 
2530 // --- E x c e p t i o n s ---
2531 
2532 
TryCatch()2533 v8::TryCatch::TryCatch()
2534     : isolate_(i::Isolate::Current()),
2535       next_(isolate_->try_catch_handler()),
2536       is_verbose_(false),
2537       can_continue_(true),
2538       capture_message_(true),
2539       rethrow_(false),
2540       has_terminated_(false) {
2541   ResetInternal();
2542   // Special handling for simulators which have a separate JS stack.
2543   js_stack_comparable_address_ =
2544       reinterpret_cast<void*>(i::SimulatorStack::RegisterCTryCatch(
2545           isolate_, i::GetCurrentStackPosition()));
2546   isolate_->RegisterTryCatchHandler(this);
2547 }
2548 
2549 
TryCatch(v8::Isolate * isolate)2550 v8::TryCatch::TryCatch(v8::Isolate* isolate)
2551     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2552       next_(isolate_->try_catch_handler()),
2553       is_verbose_(false),
2554       can_continue_(true),
2555       capture_message_(true),
2556       rethrow_(false),
2557       has_terminated_(false) {
2558   ResetInternal();
2559   // Special handling for simulators which have a separate JS stack.
2560   js_stack_comparable_address_ =
2561       reinterpret_cast<void*>(i::SimulatorStack::RegisterCTryCatch(
2562           isolate_, i::GetCurrentStackPosition()));
2563   isolate_->RegisterTryCatchHandler(this);
2564 }
2565 
2566 
~TryCatch()2567 v8::TryCatch::~TryCatch() {
2568   if (rethrow_) {
2569     v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2570     v8::HandleScope scope(isolate);
2571     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2572     if (HasCaught() && capture_message_) {
2573       // If an exception was caught and rethrow_ is indicated, the saved
2574       // message, script, and location need to be restored to Isolate TLS
2575       // for reuse.  capture_message_ needs to be disabled so that Throw()
2576       // does not create a new message.
2577       isolate_->thread_local_top()->rethrowing_message_ = true;
2578       isolate_->RestorePendingMessageFromTryCatch(this);
2579     }
2580     isolate_->UnregisterTryCatchHandler(this);
2581     i::SimulatorStack::UnregisterCTryCatch(isolate_);
2582     reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2583     DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2584   } else {
2585     if (HasCaught() && isolate_->has_scheduled_exception()) {
2586       // If an exception was caught but is still scheduled because no API call
2587       // promoted it, then it is canceled to prevent it from being propagated.
2588       // Note that this will not cancel termination exceptions.
2589       isolate_->CancelScheduledExceptionFromTryCatch(this);
2590     }
2591     isolate_->UnregisterTryCatchHandler(this);
2592     i::SimulatorStack::UnregisterCTryCatch(isolate_);
2593   }
2594 }
2595 
operator new(size_t)2596 V8_NORETURN void* v8::TryCatch::operator new(size_t) {
2597   base::OS::Abort();
2598   abort();
2599 }
2600 
operator delete(void *,size_t)2601 void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
2602 
HasCaught() const2603 bool v8::TryCatch::HasCaught() const {
2604   return !reinterpret_cast<i::Object*>(exception_)->IsTheHole(isolate_);
2605 }
2606 
2607 
CanContinue() const2608 bool v8::TryCatch::CanContinue() const {
2609   return can_continue_;
2610 }
2611 
2612 
HasTerminated() const2613 bool v8::TryCatch::HasTerminated() const {
2614   return has_terminated_;
2615 }
2616 
2617 
ReThrow()2618 v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2619   if (!HasCaught()) return v8::Local<v8::Value>();
2620   rethrow_ = true;
2621   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2622 }
2623 
2624 
Exception() const2625 v8::Local<Value> v8::TryCatch::Exception() const {
2626   if (HasCaught()) {
2627     // Check for out of memory exception.
2628     i::Object* exception = reinterpret_cast<i::Object*>(exception_);
2629     return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2630   } else {
2631     return v8::Local<Value>();
2632   }
2633 }
2634 
2635 
StackTrace(Local<Context> context) const2636 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2637   if (!HasCaught()) return v8::Local<Value>();
2638   i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
2639   if (!raw_obj->IsJSObject()) return v8::Local<Value>();
2640   PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2641   i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
2642   i::Handle<i::String> name = isolate->factory()->stack_string();
2643   Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
2644   has_pending_exception = !maybe.IsJust();
2645   RETURN_ON_FAILED_EXECUTION(Value);
2646   if (!maybe.FromJust()) return v8::Local<Value>();
2647   Local<Value> result;
2648   has_pending_exception =
2649       !ToLocal<Value>(i::JSReceiver::GetProperty(obj, name), &result);
2650   RETURN_ON_FAILED_EXECUTION(Value);
2651   RETURN_ESCAPED(result);
2652 }
2653 
2654 
StackTrace() const2655 v8::Local<Value> v8::TryCatch::StackTrace() const {
2656   auto context = reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext();
2657   RETURN_TO_LOCAL_UNCHECKED(StackTrace(context), Value);
2658 }
2659 
2660 
Message() const2661 v8::Local<v8::Message> v8::TryCatch::Message() const {
2662   i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2663   DCHECK(message->IsJSMessageObject() || message->IsTheHole(isolate_));
2664   if (HasCaught() && !message->IsTheHole(isolate_)) {
2665     return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2666   } else {
2667     return v8::Local<v8::Message>();
2668   }
2669 }
2670 
2671 
Reset()2672 void v8::TryCatch::Reset() {
2673   if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2674     // If an exception was caught but is still scheduled because no API call
2675     // promoted it, then it is canceled to prevent it from being propagated.
2676     // Note that this will not cancel termination exceptions.
2677     isolate_->CancelScheduledExceptionFromTryCatch(this);
2678   }
2679   ResetInternal();
2680 }
2681 
2682 
ResetInternal()2683 void v8::TryCatch::ResetInternal() {
2684   i::Object* the_hole = isolate_->heap()->the_hole_value();
2685   exception_ = the_hole;
2686   message_obj_ = the_hole;
2687 }
2688 
2689 
SetVerbose(bool value)2690 void v8::TryCatch::SetVerbose(bool value) {
2691   is_verbose_ = value;
2692 }
2693 
2694 
SetCaptureMessage(bool value)2695 void v8::TryCatch::SetCaptureMessage(bool value) {
2696   capture_message_ = value;
2697 }
2698 
2699 
2700 // --- M e s s a g e ---
2701 
2702 
Get() const2703 Local<String> Message::Get() const {
2704   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2705   ENTER_V8(isolate);
2706   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2707   i::Handle<i::Object> obj = Utils::OpenHandle(this);
2708   i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
2709   Local<String> result = Utils::ToLocal(raw_result);
2710   return scope.Escape(result);
2711 }
2712 
2713 
GetScriptOrigin() const2714 ScriptOrigin Message::GetScriptOrigin() const {
2715   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2716   auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2717   auto script_wraper = i::Handle<i::Object>(message->script(), isolate);
2718   auto script_value = i::Handle<i::JSValue>::cast(script_wraper);
2719   i::Handle<i::Script> script(i::Script::cast(script_value->value()));
2720   return GetScriptOriginForScript(isolate, script);
2721 }
2722 
2723 
GetScriptResourceName() const2724 v8::Local<Value> Message::GetScriptResourceName() const {
2725   return GetScriptOrigin().ResourceName();
2726 }
2727 
2728 
GetStackTrace() const2729 v8::Local<v8::StackTrace> Message::GetStackTrace() const {
2730   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2731   ENTER_V8(isolate);
2732   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2733   auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2734   i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
2735   if (!stackFramesObj->IsJSArray()) return v8::Local<v8::StackTrace>();
2736   auto stackTrace = i::Handle<i::JSArray>::cast(stackFramesObj);
2737   return scope.Escape(Utils::StackTraceToLocal(stackTrace));
2738 }
2739 
2740 
GetLineNumber(Local<Context> context) const2741 Maybe<int> Message::GetLineNumber(Local<Context> context) const {
2742   auto self = Utils::OpenHandle(this);
2743   i::Isolate* isolate = self->GetIsolate();
2744   ENTER_V8(isolate);
2745   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2746   auto msg = i::Handle<i::JSMessageObject>::cast(self);
2747   return Just(msg->GetLineNumber());
2748 }
2749 
2750 
GetLineNumber() const2751 int Message::GetLineNumber() const {
2752   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2753   return GetLineNumber(context).FromMaybe(0);
2754 }
2755 
2756 
GetStartPosition() const2757 int Message::GetStartPosition() const {
2758   auto self = Utils::OpenHandle(this);
2759   return self->start_position();
2760 }
2761 
2762 
GetEndPosition() const2763 int Message::GetEndPosition() const {
2764   auto self = Utils::OpenHandle(this);
2765   return self->end_position();
2766 }
2767 
ErrorLevel() const2768 int Message::ErrorLevel() const {
2769   auto self = Utils::OpenHandle(this);
2770   return self->error_level();
2771 }
2772 
GetStartColumn(Local<Context> context) const2773 Maybe<int> Message::GetStartColumn(Local<Context> context) const {
2774   auto self = Utils::OpenHandle(this);
2775   i::Isolate* isolate = self->GetIsolate();
2776   ENTER_V8(isolate);
2777   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2778   auto msg = i::Handle<i::JSMessageObject>::cast(self);
2779   return Just(msg->GetColumnNumber());
2780 }
2781 
2782 
GetStartColumn() const2783 int Message::GetStartColumn() const {
2784   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2785   const int default_value = kNoColumnInfo;
2786   return GetStartColumn(context).FromMaybe(default_value);
2787 }
2788 
2789 
GetEndColumn(Local<Context> context) const2790 Maybe<int> Message::GetEndColumn(Local<Context> context) const {
2791   auto self = Utils::OpenHandle(this);
2792   i::Isolate* isolate = self->GetIsolate();
2793   ENTER_V8(isolate);
2794   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2795   auto msg = i::Handle<i::JSMessageObject>::cast(self);
2796   const int column_number = msg->GetColumnNumber();
2797   if (column_number == -1) return Just(-1);
2798   const int start = self->start_position();
2799   const int end = self->end_position();
2800   return Just(column_number + (end - start));
2801 }
2802 
2803 
GetEndColumn() const2804 int Message::GetEndColumn() const {
2805   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2806   const int default_value = kNoColumnInfo;
2807   return GetEndColumn(context).FromMaybe(default_value);
2808 }
2809 
2810 
IsSharedCrossOrigin() const2811 bool Message::IsSharedCrossOrigin() const {
2812   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2813   ENTER_V8(isolate);
2814   auto self = Utils::OpenHandle(this);
2815   auto script = i::Handle<i::JSValue>::cast(
2816       i::Handle<i::Object>(self->script(), isolate));
2817   return i::Script::cast(script->value())
2818       ->origin_options()
2819       .IsSharedCrossOrigin();
2820 }
2821 
IsOpaque() const2822 bool Message::IsOpaque() const {
2823   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2824   ENTER_V8(isolate);
2825   auto self = Utils::OpenHandle(this);
2826   auto script = i::Handle<i::JSValue>::cast(
2827       i::Handle<i::Object>(self->script(), isolate));
2828   return i::Script::cast(script->value())->origin_options().IsOpaque();
2829 }
2830 
2831 
GetSourceLine(Local<Context> context) const2832 MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
2833   auto self = Utils::OpenHandle(this);
2834   i::Isolate* isolate = self->GetIsolate();
2835   ENTER_V8(isolate);
2836   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2837   auto msg = i::Handle<i::JSMessageObject>::cast(self);
2838   RETURN_ESCAPED(Utils::ToLocal(msg->GetSourceLine()));
2839 }
2840 
2841 
GetSourceLine() const2842 Local<String> Message::GetSourceLine() const {
2843   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2844   RETURN_TO_LOCAL_UNCHECKED(GetSourceLine(context), String)
2845 }
2846 
2847 
PrintCurrentStackTrace(Isolate * isolate,FILE * out)2848 void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
2849   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2850   ENTER_V8(i_isolate);
2851   i_isolate->PrintCurrentStackTrace(out);
2852 }
2853 
2854 
2855 // --- S t a c k T r a c e ---
2856 
GetFrame(uint32_t index) const2857 Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
2858   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2859   ENTER_V8(isolate);
2860   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2861   auto self = Utils::OpenHandle(this);
2862   auto obj = i::JSReceiver::GetElement(isolate, self, index).ToHandleChecked();
2863   auto jsobj = i::Handle<i::JSObject>::cast(obj);
2864   return scope.Escape(Utils::StackFrameToLocal(jsobj));
2865 }
2866 
2867 
GetFrameCount() const2868 int StackTrace::GetFrameCount() const {
2869   return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2870 }
2871 
2872 
AsArray()2873 Local<Array> StackTrace::AsArray() {
2874   return Utils::ToLocal(Utils::OpenHandle(this));
2875 }
2876 
2877 
CurrentStackTrace(Isolate * isolate,int frame_limit,StackTraceOptions options)2878 Local<StackTrace> StackTrace::CurrentStackTrace(
2879     Isolate* isolate,
2880     int frame_limit,
2881     StackTraceOptions options) {
2882   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2883   ENTER_V8(i_isolate);
2884   // TODO(dcarney): remove when ScriptDebugServer is fixed.
2885   options = static_cast<StackTraceOptions>(
2886       static_cast<int>(options) | kExposeFramesAcrossSecurityOrigins);
2887   i::Handle<i::JSArray> stackTrace =
2888       i_isolate->CaptureCurrentStackTrace(frame_limit, options);
2889   return Utils::StackTraceToLocal(stackTrace);
2890 }
2891 
2892 
2893 // --- S t a c k F r a m e ---
2894 
getIntProperty(const StackFrame * f,const char * propertyName,int defaultValue)2895 static int getIntProperty(const StackFrame* f, const char* propertyName,
2896                           int defaultValue) {
2897   i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
2898   ENTER_V8(isolate);
2899   i::HandleScope scope(isolate);
2900   i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2901   i::Handle<i::Object> obj =
2902       i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
2903   return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue;
2904 }
2905 
2906 
GetLineNumber() const2907 int StackFrame::GetLineNumber() const {
2908   return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo);
2909 }
2910 
2911 
GetColumn() const2912 int StackFrame::GetColumn() const {
2913   return getIntProperty(this, "column", Message::kNoColumnInfo);
2914 }
2915 
2916 
GetScriptId() const2917 int StackFrame::GetScriptId() const {
2918   return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo);
2919 }
2920 
2921 
getStringProperty(const StackFrame * f,const char * propertyName)2922 static Local<String> getStringProperty(const StackFrame* f,
2923                                        const char* propertyName) {
2924   i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
2925   ENTER_V8(isolate);
2926   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2927   i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2928   i::Handle<i::Object> obj =
2929       i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
2930   return obj->IsString()
2931              ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
2932              : Local<String>();
2933 }
2934 
2935 
GetScriptName() const2936 Local<String> StackFrame::GetScriptName() const {
2937   return getStringProperty(this, "scriptName");
2938 }
2939 
2940 
GetScriptNameOrSourceURL() const2941 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
2942   return getStringProperty(this, "scriptNameOrSourceURL");
2943 }
2944 
2945 
GetFunctionName() const2946 Local<String> StackFrame::GetFunctionName() const {
2947   return getStringProperty(this, "functionName");
2948 }
2949 
2950 
getBoolProperty(const StackFrame * f,const char * propertyName)2951 static bool getBoolProperty(const StackFrame* f, const char* propertyName) {
2952   i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
2953   ENTER_V8(isolate);
2954   i::HandleScope scope(isolate);
2955   i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2956   i::Handle<i::Object> obj =
2957       i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
2958   return obj->IsTrue(isolate);
2959 }
2960 
IsEval() const2961 bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
2962 
2963 
IsConstructor() const2964 bool StackFrame::IsConstructor() const {
2965   return getBoolProperty(this, "isConstructor");
2966 }
2967 
2968 
2969 // --- N a t i v e W e a k M a p ---
2970 
New(Isolate * v8_isolate)2971 Local<NativeWeakMap> NativeWeakMap::New(Isolate* v8_isolate) {
2972   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2973   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2974   i::Handle<i::JSWeakMap> weakmap = isolate->factory()->NewJSWeakMap();
2975   i::JSWeakCollection::Initialize(weakmap, isolate);
2976   return Utils::NativeWeakMapToLocal(weakmap);
2977 }
2978 
2979 
Set(Local<Value> v8_key,Local<Value> v8_value)2980 void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) {
2981   i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2982   i::Isolate* isolate = weak_collection->GetIsolate();
2983   ENTER_V8(isolate);
2984   i::HandleScope scope(isolate);
2985   i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2986   i::Handle<i::Object> value = Utils::OpenHandle(*v8_value);
2987   if (!key->IsJSReceiver() && !key->IsSymbol()) {
2988     DCHECK(false);
2989     return;
2990   }
2991   i::Handle<i::ObjectHashTable> table(
2992       i::ObjectHashTable::cast(weak_collection->table()));
2993   if (!table->IsKey(isolate, *key)) {
2994     DCHECK(false);
2995     return;
2996   }
2997   int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
2998   i::JSWeakCollection::Set(weak_collection, key, value, hash);
2999 }
3000 
3001 
Get(Local<Value> v8_key)3002 Local<Value> NativeWeakMap::Get(Local<Value> v8_key) {
3003   i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
3004   i::Isolate* isolate = weak_collection->GetIsolate();
3005   ENTER_V8(isolate);
3006   i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
3007   if (!key->IsJSReceiver() && !key->IsSymbol()) {
3008     DCHECK(false);
3009     return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3010   }
3011   i::Handle<i::ObjectHashTable> table(
3012       i::ObjectHashTable::cast(weak_collection->table()));
3013   if (!table->IsKey(isolate, *key)) {
3014     DCHECK(false);
3015     return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3016   }
3017   i::Handle<i::Object> lookup(table->Lookup(key), isolate);
3018   if (lookup->IsTheHole(isolate))
3019     return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3020   return Utils::ToLocal(lookup);
3021 }
3022 
3023 
Has(Local<Value> v8_key)3024 bool NativeWeakMap::Has(Local<Value> v8_key) {
3025   i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
3026   i::Isolate* isolate = weak_collection->GetIsolate();
3027   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3028   i::HandleScope scope(isolate);
3029   i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
3030   if (!key->IsJSReceiver() && !key->IsSymbol()) {
3031     DCHECK(false);
3032     return false;
3033   }
3034   i::Handle<i::ObjectHashTable> table(
3035       i::ObjectHashTable::cast(weak_collection->table()));
3036   if (!table->IsKey(isolate, *key)) {
3037     DCHECK(false);
3038     return false;
3039   }
3040   i::Handle<i::Object> lookup(table->Lookup(key), isolate);
3041   return !lookup->IsTheHole(isolate);
3042 }
3043 
3044 
Delete(Local<Value> v8_key)3045 bool NativeWeakMap::Delete(Local<Value> v8_key) {
3046   i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
3047   i::Isolate* isolate = weak_collection->GetIsolate();
3048   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3049   i::HandleScope scope(isolate);
3050   i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
3051   if (!key->IsJSReceiver() && !key->IsSymbol()) {
3052     DCHECK(false);
3053     return false;
3054   }
3055   i::Handle<i::ObjectHashTable> table(
3056       i::ObjectHashTable::cast(weak_collection->table()));
3057   if (!table->IsKey(isolate, *key)) {
3058     DCHECK(false);
3059     return false;
3060   }
3061   int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
3062   return i::JSWeakCollection::Delete(weak_collection, key, hash);
3063 }
3064 
3065 
3066 // --- J S O N ---
3067 
Parse(Isolate * v8_isolate,Local<String> json_string)3068 MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
3069   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3070   PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, JSON, Parse, Value);
3071   i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3072   i::Handle<i::String> source = i::String::Flatten(string);
3073   i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3074   auto maybe = source->IsSeqOneByteString()
3075                    ? i::JsonParser<true>::Parse(isolate, source, undefined)
3076                    : i::JsonParser<false>::Parse(isolate, source, undefined);
3077   Local<Value> result;
3078   has_pending_exception = !ToLocal<Value>(maybe, &result);
3079   RETURN_ON_FAILED_EXECUTION(Value);
3080   RETURN_ESCAPED(result);
3081 }
3082 
Parse(Local<Context> context,Local<String> json_string)3083 MaybeLocal<Value> JSON::Parse(Local<Context> context,
3084                               Local<String> json_string) {
3085   PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3086   i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3087   i::Handle<i::String> source = i::String::Flatten(string);
3088   i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3089   auto maybe = source->IsSeqOneByteString()
3090                    ? i::JsonParser<true>::Parse(isolate, source, undefined)
3091                    : i::JsonParser<false>::Parse(isolate, source, undefined);
3092   Local<Value> result;
3093   has_pending_exception = !ToLocal<Value>(maybe, &result);
3094   RETURN_ON_FAILED_EXECUTION(Value);
3095   RETURN_ESCAPED(result);
3096 }
3097 
Parse(Local<String> json_string)3098 Local<Value> JSON::Parse(Local<String> json_string) {
3099   RETURN_TO_LOCAL_UNCHECKED(Parse(Local<Context>(), json_string), Value);
3100 }
3101 
Stringify(Local<Context> context,Local<Object> json_object,Local<String> gap)3102 MaybeLocal<String> JSON::Stringify(Local<Context> context,
3103                                    Local<Object> json_object,
3104                                    Local<String> gap) {
3105   PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3106   i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3107   i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3108   i::Handle<i::String> gap_string = gap.IsEmpty()
3109                                         ? isolate->factory()->empty_string()
3110                                         : Utils::OpenHandle(*gap);
3111   i::Handle<i::Object> maybe;
3112   has_pending_exception = !i::JsonStringifier(isolate)
3113                                .Stringify(object, replacer, gap_string)
3114                                .ToHandle(&maybe);
3115   RETURN_ON_FAILED_EXECUTION(String);
3116   Local<String> result;
3117   has_pending_exception =
3118       !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3119   RETURN_ON_FAILED_EXECUTION(String);
3120   RETURN_ESCAPED(result);
3121 }
3122 
3123 // --- V a l u e   S e r i a l i z a t i o n ---
3124 
WriteHostObject(Isolate * v8_isolate,Local<Object> object)3125 Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3126                                                        Local<Object> object) {
3127   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3128   isolate->ScheduleThrow(*isolate->factory()->NewError(
3129       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3130       Utils::OpenHandle(*object)));
3131   return Nothing<bool>();
3132 }
3133 
GetSharedArrayBufferId(Isolate * v8_isolate,Local<SharedArrayBuffer> shared_array_buffer)3134 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3135     Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3136   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3137   isolate->ScheduleThrow(*isolate->factory()->NewError(
3138       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3139       Utils::OpenHandle(*shared_array_buffer)));
3140   return Nothing<uint32_t>();
3141 }
3142 
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)3143 void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3144                                                         size_t size,
3145                                                         size_t* actual_size) {
3146   *actual_size = size;
3147   return realloc(old_buffer, size);
3148 }
3149 
FreeBufferMemory(void * buffer)3150 void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3151   return free(buffer);
3152 }
3153 
3154 struct ValueSerializer::PrivateData {
PrivateDatav8::ValueSerializer::PrivateData3155   explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3156       : isolate(i), serializer(i, delegate) {}
3157   i::Isolate* isolate;
3158   i::ValueSerializer serializer;
3159 };
3160 
ValueSerializer(Isolate * isolate)3161 ValueSerializer::ValueSerializer(Isolate* isolate)
3162     : ValueSerializer(isolate, nullptr) {}
3163 
ValueSerializer(Isolate * isolate,Delegate * delegate)3164 ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3165     : private_(
3166           new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3167 
~ValueSerializer()3168 ValueSerializer::~ValueSerializer() { delete private_; }
3169 
WriteHeader()3170 void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3171 
SetTreatArrayBufferViewsAsHostObjects(bool mode)3172 void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3173   private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3174 }
3175 
WriteValue(Local<Context> context,Local<Value> value)3176 Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3177                                         Local<Value> value) {
3178   PREPARE_FOR_EXECUTION_PRIMITIVE(context, ValueSerializer, WriteValue, bool);
3179   i::Handle<i::Object> object = Utils::OpenHandle(*value);
3180   Maybe<bool> result = private_->serializer.WriteObject(object);
3181   has_pending_exception = result.IsNothing();
3182   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3183   return result;
3184 }
3185 
ReleaseBuffer()3186 std::vector<uint8_t> ValueSerializer::ReleaseBuffer() {
3187   return private_->serializer.ReleaseBuffer();
3188 }
3189 
Release()3190 std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3191   return private_->serializer.Release();
3192 }
3193 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3194 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3195                                           Local<ArrayBuffer> array_buffer) {
3196   private_->serializer.TransferArrayBuffer(transfer_id,
3197                                            Utils::OpenHandle(*array_buffer));
3198 }
3199 
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3200 void ValueSerializer::TransferSharedArrayBuffer(
3201     uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3202   private_->serializer.TransferArrayBuffer(
3203       transfer_id, Utils::OpenHandle(*shared_array_buffer));
3204 }
3205 
WriteUint32(uint32_t value)3206 void ValueSerializer::WriteUint32(uint32_t value) {
3207   private_->serializer.WriteUint32(value);
3208 }
3209 
WriteUint64(uint64_t value)3210 void ValueSerializer::WriteUint64(uint64_t value) {
3211   private_->serializer.WriteUint64(value);
3212 }
3213 
WriteDouble(double value)3214 void ValueSerializer::WriteDouble(double value) {
3215   private_->serializer.WriteDouble(value);
3216 }
3217 
WriteRawBytes(const void * source,size_t length)3218 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3219   private_->serializer.WriteRawBytes(source, length);
3220 }
3221 
ReadHostObject(Isolate * v8_isolate)3222 MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3223     Isolate* v8_isolate) {
3224   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3225   isolate->ScheduleThrow(*isolate->factory()->NewError(
3226       isolate->error_function(),
3227       i::MessageTemplate::kDataCloneDeserializationError));
3228   return MaybeLocal<Object>();
3229 }
3230 
3231 struct ValueDeserializer::PrivateData {
PrivateDatav8::ValueDeserializer::PrivateData3232   PrivateData(i::Isolate* i, i::Vector<const uint8_t> data, Delegate* delegate)
3233       : isolate(i), deserializer(i, data, delegate) {}
3234   i::Isolate* isolate;
3235   i::ValueDeserializer deserializer;
3236   bool has_aborted = false;
3237   bool supports_legacy_wire_format = false;
3238 };
3239 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size)3240 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3241                                      size_t size)
3242     : ValueDeserializer(isolate, data, size, nullptr) {}
3243 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size,Delegate * delegate)3244 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3245                                      size_t size, Delegate* delegate) {
3246   if (base::IsValueInRangeForNumericType<int>(size)) {
3247     private_ = new PrivateData(
3248         reinterpret_cast<i::Isolate*>(isolate),
3249         i::Vector<const uint8_t>(data, static_cast<int>(size)), delegate);
3250   } else {
3251     private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3252                                i::Vector<const uint8_t>(nullptr, 0), nullptr);
3253     private_->has_aborted = true;
3254   }
3255 }
3256 
~ValueDeserializer()3257 ValueDeserializer::~ValueDeserializer() { delete private_; }
3258 
ReadHeader(Local<Context> context)3259 Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3260   PREPARE_FOR_EXECUTION_PRIMITIVE(context, ValueDeserializer, ReadHeader, bool);
3261 
3262   // We could have aborted during the constructor.
3263   // If so, ReadHeader is where we report it.
3264   if (private_->has_aborted) {
3265     isolate->Throw(*isolate->factory()->NewError(
3266         i::MessageTemplate::kDataCloneDeserializationError));
3267     has_pending_exception = true;
3268     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3269   }
3270 
3271   bool read_header = false;
3272   has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3273   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3274   DCHECK(read_header);
3275 
3276   // TODO(jbroman): Today, all wire formats are "legacy". When a more supported
3277   // format is added, compare the version of the internal serializer to the
3278   // minimum non-legacy version number.
3279   if (!private_->supports_legacy_wire_format) {
3280     isolate->Throw(*isolate->factory()->NewError(
3281         i::MessageTemplate::kDataCloneDeserializationVersionError));
3282     has_pending_exception = true;
3283     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3284   }
3285 
3286   return Just(true);
3287 }
3288 
SetSupportsLegacyWireFormat(bool supports_legacy_wire_format)3289 void ValueDeserializer::SetSupportsLegacyWireFormat(
3290     bool supports_legacy_wire_format) {
3291   private_->supports_legacy_wire_format = supports_legacy_wire_format;
3292 }
3293 
GetWireFormatVersion() const3294 uint32_t ValueDeserializer::GetWireFormatVersion() const {
3295   CHECK(!private_->has_aborted);
3296   return private_->deserializer.GetWireFormatVersion();
3297 }
3298 
ReadValue(Local<Context> context)3299 MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3300   CHECK(!private_->has_aborted);
3301   PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3302   i::MaybeHandle<i::Object> result;
3303   if (GetWireFormatVersion() > 0) {
3304     result = private_->deserializer.ReadObject();
3305   } else {
3306     result =
3307         private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3308   }
3309   Local<Value> value;
3310   has_pending_exception = !ToLocal(result, &value);
3311   RETURN_ON_FAILED_EXECUTION(Value);
3312   RETURN_ESCAPED(value);
3313 }
3314 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3315 void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3316                                             Local<ArrayBuffer> array_buffer) {
3317   CHECK(!private_->has_aborted);
3318   private_->deserializer.TransferArrayBuffer(transfer_id,
3319                                              Utils::OpenHandle(*array_buffer));
3320 }
3321 
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3322 void ValueDeserializer::TransferSharedArrayBuffer(
3323     uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3324   CHECK(!private_->has_aborted);
3325   private_->deserializer.TransferArrayBuffer(
3326       transfer_id, Utils::OpenHandle(*shared_array_buffer));
3327 }
3328 
ReadUint32(uint32_t * value)3329 bool ValueDeserializer::ReadUint32(uint32_t* value) {
3330   return private_->deserializer.ReadUint32(value);
3331 }
3332 
ReadUint64(uint64_t * value)3333 bool ValueDeserializer::ReadUint64(uint64_t* value) {
3334   return private_->deserializer.ReadUint64(value);
3335 }
3336 
ReadDouble(double * value)3337 bool ValueDeserializer::ReadDouble(double* value) {
3338   return private_->deserializer.ReadDouble(value);
3339 }
3340 
ReadRawBytes(size_t length,const void ** data)3341 bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3342   return private_->deserializer.ReadRawBytes(length, data);
3343 }
3344 
3345 // --- D a t a ---
3346 
FullIsUndefined() const3347 bool Value::FullIsUndefined() const {
3348   i::Handle<i::Object> object = Utils::OpenHandle(this);
3349   bool result = false;
3350   if (!object->IsSmi()) {
3351     result = object->IsUndefined(i::HeapObject::cast(*object)->GetIsolate());
3352   }
3353   DCHECK_EQ(result, QuickIsUndefined());
3354   return result;
3355 }
3356 
3357 
FullIsNull() const3358 bool Value::FullIsNull() const {
3359   i::Handle<i::Object> object = Utils::OpenHandle(this);
3360   bool result = false;
3361   if (!object->IsSmi()) {
3362     result = object->IsNull(i::HeapObject::cast(*object)->GetIsolate());
3363   }
3364   DCHECK_EQ(result, QuickIsNull());
3365   return result;
3366 }
3367 
3368 
IsTrue() const3369 bool Value::IsTrue() const {
3370   i::Handle<i::Object> object = Utils::OpenHandle(this);
3371   if (object->IsSmi()) return false;
3372   return object->IsTrue(i::HeapObject::cast(*object)->GetIsolate());
3373 }
3374 
3375 
IsFalse() const3376 bool Value::IsFalse() const {
3377   i::Handle<i::Object> object = Utils::OpenHandle(this);
3378   if (object->IsSmi()) return false;
3379   return object->IsFalse(i::HeapObject::cast(*object)->GetIsolate());
3380 }
3381 
3382 
IsFunction() const3383 bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3384 
3385 
IsName() const3386 bool Value::IsName() const {
3387   return Utils::OpenHandle(this)->IsName();
3388 }
3389 
3390 
FullIsString() const3391 bool Value::FullIsString() const {
3392   bool result = Utils::OpenHandle(this)->IsString();
3393   DCHECK_EQ(result, QuickIsString());
3394   return result;
3395 }
3396 
3397 
IsSymbol() const3398 bool Value::IsSymbol() const {
3399   return Utils::OpenHandle(this)->IsSymbol();
3400 }
3401 
3402 
IsArray() const3403 bool Value::IsArray() const {
3404   return Utils::OpenHandle(this)->IsJSArray();
3405 }
3406 
3407 
IsArrayBuffer() const3408 bool Value::IsArrayBuffer() const {
3409   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3410   return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared();
3411 }
3412 
3413 
IsArrayBufferView() const3414 bool Value::IsArrayBufferView() const {
3415   return Utils::OpenHandle(this)->IsJSArrayBufferView();
3416 }
3417 
3418 
IsTypedArray() const3419 bool Value::IsTypedArray() const {
3420   return Utils::OpenHandle(this)->IsJSTypedArray();
3421 }
3422 
3423 
3424 #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size)              \
3425   bool Value::Is##Type##Array() const {                                      \
3426     i::Handle<i::Object> obj = Utils::OpenHandle(this);                      \
3427     return obj->IsJSTypedArray() &&                                          \
3428            i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array; \
3429   }
3430 
3431 
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)3432 TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3433 
3434 #undef VALUE_IS_TYPED_ARRAY
3435 
3436 
3437 bool Value::IsDataView() const {
3438   return Utils::OpenHandle(this)->IsJSDataView();
3439 }
3440 
3441 
IsSharedArrayBuffer() const3442 bool Value::IsSharedArrayBuffer() const {
3443   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3444   return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared();
3445 }
3446 
3447 
IsObject() const3448 bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3449 
3450 
IsNumber() const3451 bool Value::IsNumber() const {
3452   return Utils::OpenHandle(this)->IsNumber();
3453 }
3454 
3455 
IsProxy() const3456 bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3457 
IsWebAssemblyCompiledModule() const3458 bool Value::IsWebAssemblyCompiledModule() const {
3459   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3460   if (!obj->IsJSObject()) return false;
3461   i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
3462   return js_obj->GetIsolate()->native_context()->wasm_module_constructor() ==
3463          js_obj->map()->GetConstructor();
3464 }
3465 
3466 #define VALUE_IS_SPECIFIC_TYPE(Type, Class)                            \
3467   bool Value::Is##Type() const {                                       \
3468     i::Handle<i::Object> obj = Utils::OpenHandle(this);                \
3469     if (!obj->IsHeapObject()) return false;                            \
3470     i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();     \
3471     return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
3472   }
3473 
VALUE_IS_SPECIFIC_TYPE(ArgumentsObject,Arguments)3474 VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
3475 VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
3476 VALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
3477 VALUE_IS_SPECIFIC_TYPE(StringObject, String)
3478 VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
3479 VALUE_IS_SPECIFIC_TYPE(Date, Date)
3480 VALUE_IS_SPECIFIC_TYPE(Map, Map)
3481 VALUE_IS_SPECIFIC_TYPE(Set, Set)
3482 VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
3483 VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
3484 
3485 #undef VALUE_IS_SPECIFIC_TYPE
3486 
3487 
3488 bool Value::IsBoolean() const {
3489   return Utils::OpenHandle(this)->IsBoolean();
3490 }
3491 
3492 
IsExternal() const3493 bool Value::IsExternal() const {
3494   return Utils::OpenHandle(this)->IsExternal();
3495 }
3496 
3497 
IsInt32() const3498 bool Value::IsInt32() const {
3499   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3500   if (obj->IsSmi()) return true;
3501   if (obj->IsNumber()) {
3502     return i::IsInt32Double(obj->Number());
3503   }
3504   return false;
3505 }
3506 
3507 
IsUint32() const3508 bool Value::IsUint32() const {
3509   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3510   if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
3511   if (obj->IsNumber()) {
3512     double value = obj->Number();
3513     return !i::IsMinusZero(value) &&
3514         value >= 0 &&
3515         value <= i::kMaxUInt32 &&
3516         value == i::FastUI2D(i::FastD2UI(value));
3517   }
3518   return false;
3519 }
3520 
3521 
IsNativeError() const3522 bool Value::IsNativeError() const {
3523   return Utils::OpenHandle(this)->IsJSError();
3524 }
3525 
3526 
IsRegExp() const3527 bool Value::IsRegExp() const {
3528   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3529   return obj->IsJSRegExp();
3530 }
3531 
IsAsyncFunction() const3532 bool Value::IsAsyncFunction() const {
3533   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3534   if (!obj->IsJSFunction()) return false;
3535   i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
3536   return i::IsAsyncFunction(func->shared()->kind());
3537 }
3538 
IsGeneratorFunction() const3539 bool Value::IsGeneratorFunction() const {
3540   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3541   if (!obj->IsJSFunction()) return false;
3542   i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
3543   return i::IsGeneratorFunction(func->shared()->kind());
3544 }
3545 
3546 
IsGeneratorObject() const3547 bool Value::IsGeneratorObject() const {
3548   return Utils::OpenHandle(this)->IsJSGeneratorObject();
3549 }
3550 
3551 
IsMapIterator() const3552 bool Value::IsMapIterator() const {
3553   return Utils::OpenHandle(this)->IsJSMapIterator();
3554 }
3555 
3556 
IsSetIterator() const3557 bool Value::IsSetIterator() const {
3558   return Utils::OpenHandle(this)->IsJSSetIterator();
3559 }
3560 
IsPromise() const3561 bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3562 
ToString(Local<Context> context) const3563 MaybeLocal<String> Value::ToString(Local<Context> context) const {
3564   auto obj = Utils::OpenHandle(this);
3565   if (obj->IsString()) return ToApiHandle<String>(obj);
3566   PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3567   Local<String> result;
3568   has_pending_exception =
3569       !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3570   RETURN_ON_FAILED_EXECUTION(String);
3571   RETURN_ESCAPED(result);
3572 }
3573 
3574 
ToString(Isolate * isolate) const3575 Local<String> Value::ToString(Isolate* isolate) const {
3576   RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String);
3577 }
3578 
3579 
ToDetailString(Local<Context> context) const3580 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3581   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3582   if (obj->IsString()) return ToApiHandle<String>(obj);
3583   PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3584   Local<String> result =
3585       Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3586   RETURN_ON_FAILED_EXECUTION(String);
3587   RETURN_ESCAPED(result);
3588 }
3589 
3590 
ToDetailString(Isolate * isolate) const3591 Local<String> Value::ToDetailString(Isolate* isolate) const {
3592   RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()),
3593                             String);
3594 }
3595 
3596 
ToObject(Local<Context> context) const3597 MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3598   auto obj = Utils::OpenHandle(this);
3599   if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3600   PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3601   Local<Object> result;
3602   has_pending_exception =
3603       !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3604   RETURN_ON_FAILED_EXECUTION(Object);
3605   RETURN_ESCAPED(result);
3606 }
3607 
3608 
ToObject(Isolate * isolate) const3609 Local<v8::Object> Value::ToObject(Isolate* isolate) const {
3610   RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object);
3611 }
3612 
3613 
ToBoolean(Local<Context> context) const3614 MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const {
3615   auto obj = Utils::OpenHandle(this);
3616   if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj);
3617   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3618   auto val = isolate->factory()->ToBoolean(obj->BooleanValue());
3619   return ToApiHandle<Boolean>(val);
3620 }
3621 
3622 
ToBoolean(Isolate * v8_isolate) const3623 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3624   return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked();
3625 }
3626 
3627 
ToNumber(Local<Context> context) const3628 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3629   auto obj = Utils::OpenHandle(this);
3630   if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3631   PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3632   Local<Number> result;
3633   has_pending_exception = !ToLocal<Number>(i::Object::ToNumber(obj), &result);
3634   RETURN_ON_FAILED_EXECUTION(Number);
3635   RETURN_ESCAPED(result);
3636 }
3637 
3638 
ToNumber(Isolate * isolate) const3639 Local<Number> Value::ToNumber(Isolate* isolate) const {
3640   RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number);
3641 }
3642 
3643 
ToInteger(Local<Context> context) const3644 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3645   auto obj = Utils::OpenHandle(this);
3646   if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3647   PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3648   Local<Integer> result;
3649   has_pending_exception =
3650       !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3651   RETURN_ON_FAILED_EXECUTION(Integer);
3652   RETURN_ESCAPED(result);
3653 }
3654 
3655 
ToInteger(Isolate * isolate) const3656 Local<Integer> Value::ToInteger(Isolate* isolate) const {
3657   RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer);
3658 }
3659 
3660 
ToInt32(Local<Context> context) const3661 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3662   auto obj = Utils::OpenHandle(this);
3663   if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3664   Local<Int32> result;
3665   PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3666   has_pending_exception =
3667       !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3668   RETURN_ON_FAILED_EXECUTION(Int32);
3669   RETURN_ESCAPED(result);
3670 }
3671 
3672 
ToInt32(Isolate * isolate) const3673 Local<Int32> Value::ToInt32(Isolate* isolate) const {
3674   RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32);
3675 }
3676 
3677 
ToUint32(Local<Context> context) const3678 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3679   auto obj = Utils::OpenHandle(this);
3680   if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3681   Local<Uint32> result;
3682   PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3683   has_pending_exception =
3684       !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3685   RETURN_ON_FAILED_EXECUTION(Uint32);
3686   RETURN_ESCAPED(result);
3687 }
3688 
3689 
ToUint32(Isolate * isolate) const3690 Local<Uint32> Value::ToUint32(Isolate* isolate) const {
3691   RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32);
3692 }
3693 
3694 
CheckInitializedImpl(v8::Isolate * external_isolate)3695 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3696   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3697   Utils::ApiCheck(isolate != NULL && !isolate->IsDead(),
3698                   "v8::internal::Internals::CheckInitialized",
3699                   "Isolate is not initialized or V8 has died");
3700 }
3701 
3702 
CheckCast(v8::Value * that)3703 void External::CheckCast(v8::Value* that) {
3704   Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(), "v8::External::Cast",
3705                   "Could not convert to external");
3706 }
3707 
3708 
CheckCast(Value * that)3709 void v8::Object::CheckCast(Value* that) {
3710   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3711   Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3712                   "Could not convert to object");
3713 }
3714 
3715 
CheckCast(Value * that)3716 void v8::Function::CheckCast(Value* that) {
3717   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3718   Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3719                   "Could not convert to function");
3720 }
3721 
3722 
CheckCast(v8::Value * that)3723 void v8::Boolean::CheckCast(v8::Value* that) {
3724   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3725   Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3726                   "Could not convert to boolean");
3727 }
3728 
3729 
CheckCast(v8::Value * that)3730 void v8::Name::CheckCast(v8::Value* that) {
3731   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3732   Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Could not convert to name");
3733 }
3734 
3735 
CheckCast(v8::Value * that)3736 void v8::String::CheckCast(v8::Value* that) {
3737   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3738   Utils::ApiCheck(obj->IsString(), "v8::String::Cast",
3739                   "Could not convert to string");
3740 }
3741 
3742 
CheckCast(v8::Value * that)3743 void v8::Symbol::CheckCast(v8::Value* that) {
3744   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3745   Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast",
3746                   "Could not convert to symbol");
3747 }
3748 
3749 
CheckCast(v8::Value * that)3750 void v8::Number::CheckCast(v8::Value* that) {
3751   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3752   Utils::ApiCheck(obj->IsNumber(),
3753                   "v8::Number::Cast()",
3754                   "Could not convert to number");
3755 }
3756 
3757 
CheckCast(v8::Value * that)3758 void v8::Integer::CheckCast(v8::Value* that) {
3759   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3760   Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3761                   "Could not convert to number");
3762 }
3763 
3764 
CheckCast(v8::Value * that)3765 void v8::Int32::CheckCast(v8::Value* that) {
3766   Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast",
3767                   "Could not convert to 32-bit signed integer");
3768 }
3769 
3770 
CheckCast(v8::Value * that)3771 void v8::Uint32::CheckCast(v8::Value* that) {
3772   Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast",
3773                   "Could not convert to 32-bit unsigned integer");
3774 }
3775 
3776 
CheckCast(Value * that)3777 void v8::Array::CheckCast(Value* that) {
3778   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3779   Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast",
3780                   "Could not convert to array");
3781 }
3782 
3783 
CheckCast(Value * that)3784 void v8::Map::CheckCast(Value* that) {
3785   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3786   Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Could not convert to Map");
3787 }
3788 
3789 
CheckCast(Value * that)3790 void v8::Set::CheckCast(Value* that) {
3791   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3792   Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Could not convert to Set");
3793 }
3794 
3795 
CheckCast(Value * that)3796 void v8::Promise::CheckCast(Value* that) {
3797   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3798                   "Could not convert to promise");
3799 }
3800 
3801 
CheckCast(Value * that)3802 void v8::Promise::Resolver::CheckCast(Value* that) {
3803   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3804                   "Could not convert to promise resolver");
3805 }
3806 
3807 
CheckCast(Value * that)3808 void v8::Proxy::CheckCast(Value* that) {
3809   Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast",
3810                   "Could not convert to proxy");
3811 }
3812 
CheckCast(Value * that)3813 void v8::WasmCompiledModule::CheckCast(Value* that) {
3814   Utils::ApiCheck(that->IsWebAssemblyCompiledModule(),
3815                   "v8::WasmCompiledModule::Cast",
3816                   "Could not convert to wasm compiled module");
3817 }
3818 
CheckCast(Value * that)3819 void v8::ArrayBuffer::CheckCast(Value* that) {
3820   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3821   Utils::ApiCheck(
3822       obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared(),
3823       "v8::ArrayBuffer::Cast()", "Could not convert to ArrayBuffer");
3824 }
3825 
3826 
CheckCast(Value * that)3827 void v8::ArrayBufferView::CheckCast(Value* that) {
3828   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3829   Utils::ApiCheck(obj->IsJSArrayBufferView(),
3830                   "v8::ArrayBufferView::Cast()",
3831                   "Could not convert to ArrayBufferView");
3832 }
3833 
3834 
CheckCast(Value * that)3835 void v8::TypedArray::CheckCast(Value* that) {
3836   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3837   Utils::ApiCheck(obj->IsJSTypedArray(),
3838                   "v8::TypedArray::Cast()",
3839                   "Could not convert to TypedArray");
3840 }
3841 
3842 
3843 #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size)             \
3844   void v8::Type##Array::CheckCast(Value* that) {                              \
3845     i::Handle<i::Object> obj = Utils::OpenHandle(that);                       \
3846     Utils::ApiCheck(                                                          \
3847         obj->IsJSTypedArray() &&                                              \
3848             i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array, \
3849         "v8::" #Type "Array::Cast()", "Could not convert to " #Type "Array"); \
3850   }
3851 
3852 
TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)3853 TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
3854 
3855 #undef CHECK_TYPED_ARRAY_CAST
3856 
3857 
3858 void v8::DataView::CheckCast(Value* that) {
3859   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3860   Utils::ApiCheck(obj->IsJSDataView(),
3861                   "v8::DataView::Cast()",
3862                   "Could not convert to DataView");
3863 }
3864 
3865 
CheckCast(Value * that)3866 void v8::SharedArrayBuffer::CheckCast(Value* that) {
3867   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3868   Utils::ApiCheck(
3869       obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared(),
3870       "v8::SharedArrayBuffer::Cast()",
3871       "Could not convert to SharedArrayBuffer");
3872 }
3873 
3874 
CheckCast(v8::Value * that)3875 void v8::Date::CheckCast(v8::Value* that) {
3876   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3877   i::Isolate* isolate = NULL;
3878   if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3879   Utils::ApiCheck(isolate != NULL &&
3880                   obj->HasSpecificClassOf(isolate->heap()->Date_string()),
3881                   "v8::Date::Cast()",
3882                   "Could not convert to date");
3883 }
3884 
3885 
CheckCast(v8::Value * that)3886 void v8::StringObject::CheckCast(v8::Value* that) {
3887   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3888   i::Isolate* isolate = NULL;
3889   if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3890   Utils::ApiCheck(isolate != NULL &&
3891                   obj->HasSpecificClassOf(isolate->heap()->String_string()),
3892                   "v8::StringObject::Cast()",
3893                   "Could not convert to StringObject");
3894 }
3895 
3896 
CheckCast(v8::Value * that)3897 void v8::SymbolObject::CheckCast(v8::Value* that) {
3898   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3899   i::Isolate* isolate = NULL;
3900   if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3901   Utils::ApiCheck(isolate != NULL &&
3902                   obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
3903                   "v8::SymbolObject::Cast()",
3904                   "Could not convert to SymbolObject");
3905 }
3906 
3907 
CheckCast(v8::Value * that)3908 void v8::NumberObject::CheckCast(v8::Value* that) {
3909   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3910   i::Isolate* isolate = NULL;
3911   if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3912   Utils::ApiCheck(isolate != NULL &&
3913                   obj->HasSpecificClassOf(isolate->heap()->Number_string()),
3914                   "v8::NumberObject::Cast()",
3915                   "Could not convert to NumberObject");
3916 }
3917 
3918 
CheckCast(v8::Value * that)3919 void v8::BooleanObject::CheckCast(v8::Value* that) {
3920   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3921   i::Isolate* isolate = NULL;
3922   if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3923   Utils::ApiCheck(isolate != NULL &&
3924                   obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
3925                   "v8::BooleanObject::Cast()",
3926                   "Could not convert to BooleanObject");
3927 }
3928 
3929 
CheckCast(v8::Value * that)3930 void v8::RegExp::CheckCast(v8::Value* that) {
3931   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3932   Utils::ApiCheck(obj->IsJSRegExp(),
3933                   "v8::RegExp::Cast()",
3934                   "Could not convert to regular expression");
3935 }
3936 
3937 
BooleanValue(Local<Context> context) const3938 Maybe<bool> Value::BooleanValue(Local<Context> context) const {
3939   return Just(Utils::OpenHandle(this)->BooleanValue());
3940 }
3941 
3942 
BooleanValue() const3943 bool Value::BooleanValue() const {
3944   return Utils::OpenHandle(this)->BooleanValue();
3945 }
3946 
3947 
NumberValue(Local<Context> context) const3948 Maybe<double> Value::NumberValue(Local<Context> context) const {
3949   auto obj = Utils::OpenHandle(this);
3950   if (obj->IsNumber()) return Just(obj->Number());
3951   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, NumberValue, double);
3952   i::Handle<i::Object> num;
3953   has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num);
3954   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
3955   return Just(num->Number());
3956 }
3957 
3958 
NumberValue() const3959 double Value::NumberValue() const {
3960   auto obj = Utils::OpenHandle(this);
3961   if (obj->IsNumber()) return obj->Number();
3962   return NumberValue(ContextFromHeapObject(obj))
3963       .FromMaybe(std::numeric_limits<double>::quiet_NaN());
3964 }
3965 
3966 
IntegerValue(Local<Context> context) const3967 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
3968   auto obj = Utils::OpenHandle(this);
3969   if (obj->IsNumber()) {
3970     return Just(NumberToInt64(*obj));
3971   }
3972   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, IntegerValue, int64_t);
3973   i::Handle<i::Object> num;
3974   has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
3975   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
3976   return Just(NumberToInt64(*num));
3977 }
3978 
3979 
IntegerValue() const3980 int64_t Value::IntegerValue() const {
3981   auto obj = Utils::OpenHandle(this);
3982   if (obj->IsNumber()) {
3983     if (obj->IsSmi()) {
3984       return i::Smi::cast(*obj)->value();
3985     } else {
3986       return static_cast<int64_t>(obj->Number());
3987     }
3988   }
3989   return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0);
3990 }
3991 
3992 
Int32Value(Local<Context> context) const3993 Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
3994   auto obj = Utils::OpenHandle(this);
3995   if (obj->IsNumber()) return Just(NumberToInt32(*obj));
3996   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Int32Value, int32_t);
3997   i::Handle<i::Object> num;
3998   has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
3999   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
4000   return Just(num->IsSmi() ? i::Smi::cast(*num)->value()
4001                            : static_cast<int32_t>(num->Number()));
4002 }
4003 
4004 
Int32Value() const4005 int32_t Value::Int32Value() const {
4006   auto obj = Utils::OpenHandle(this);
4007   if (obj->IsNumber()) return NumberToInt32(*obj);
4008   return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0);
4009 }
4010 
4011 
Uint32Value(Local<Context> context) const4012 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
4013   auto obj = Utils::OpenHandle(this);
4014   if (obj->IsNumber()) return Just(NumberToUint32(*obj));
4015   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Uint32Value, uint32_t);
4016   i::Handle<i::Object> num;
4017   has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4018   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4019   return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value())
4020                            : static_cast<uint32_t>(num->Number()));
4021 }
4022 
4023 
Uint32Value() const4024 uint32_t Value::Uint32Value() const {
4025   auto obj = Utils::OpenHandle(this);
4026   if (obj->IsNumber()) return NumberToUint32(*obj);
4027   return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0);
4028 }
4029 
4030 
ToArrayIndex(Local<Context> context) const4031 MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4032   auto self = Utils::OpenHandle(this);
4033   if (self->IsSmi()) {
4034     if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
4035     return Local<Uint32>();
4036   }
4037   PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4038   i::Handle<i::Object> string_obj;
4039   has_pending_exception =
4040       !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4041   RETURN_ON_FAILED_EXECUTION(Uint32);
4042   i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4043   uint32_t index;
4044   if (str->AsArrayIndex(&index)) {
4045     i::Handle<i::Object> value;
4046     if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4047       value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4048     } else {
4049       value = isolate->factory()->NewNumber(index);
4050     }
4051     RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4052   }
4053   return Local<Uint32>();
4054 }
4055 
4056 
ToArrayIndex() const4057 Local<Uint32> Value::ToArrayIndex() const {
4058   auto self = Utils::OpenHandle(this);
4059   if (self->IsSmi()) {
4060     if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
4061     return Local<Uint32>();
4062   }
4063   auto context = ContextFromHeapObject(self);
4064   RETURN_TO_LOCAL_UNCHECKED(ToArrayIndex(context), Uint32);
4065 }
4066 
4067 
Equals(Local<Context> context,Local<Value> that) const4068 Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4069   auto self = Utils::OpenHandle(this);
4070   auto other = Utils::OpenHandle(*that);
4071   return i::Object::Equals(self, other);
4072 }
4073 
4074 
Equals(Local<Value> that) const4075 bool Value::Equals(Local<Value> that) const {
4076   auto self = Utils::OpenHandle(this);
4077   auto other = Utils::OpenHandle(*that);
4078   if (self->IsSmi() && other->IsSmi()) {
4079     return self->Number() == other->Number();
4080   }
4081   if (self->IsJSObject() && other->IsJSObject()) {
4082     return *self == *other;
4083   }
4084   auto heap_object = self->IsSmi() ? other : self;
4085   auto context = ContextFromHeapObject(heap_object);
4086   return Equals(context, that).FromMaybe(false);
4087 }
4088 
4089 
StrictEquals(Local<Value> that) const4090 bool Value::StrictEquals(Local<Value> that) const {
4091   auto self = Utils::OpenHandle(this);
4092   auto other = Utils::OpenHandle(*that);
4093   return self->StrictEquals(*other);
4094 }
4095 
4096 
SameValue(Local<Value> that) const4097 bool Value::SameValue(Local<Value> that) const {
4098   auto self = Utils::OpenHandle(this);
4099   auto other = Utils::OpenHandle(*that);
4100   return self->SameValue(*other);
4101 }
4102 
TypeOf(v8::Isolate * external_isolate)4103 Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4104   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4105   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4106   LOG_API(isolate, Value, TypeOf);
4107   return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4108 }
4109 
Set(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value)4110 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4111                             v8::Local<Value> key, v8::Local<Value> value) {
4112   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Set, bool);
4113   auto self = Utils::OpenHandle(this);
4114   auto key_obj = Utils::OpenHandle(*key);
4115   auto value_obj = Utils::OpenHandle(*value);
4116   has_pending_exception =
4117       i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4118                                     i::SLOPPY).is_null();
4119   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4120   return Just(true);
4121 }
4122 
4123 
Set(v8::Local<Value> key,v8::Local<Value> value)4124 bool v8::Object::Set(v8::Local<Value> key, v8::Local<Value> value) {
4125   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4126   return Set(context, key, value).FromMaybe(false);
4127 }
4128 
4129 
Set(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4130 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4131                             v8::Local<Value> value) {
4132   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Set, bool);
4133   auto self = Utils::OpenHandle(this);
4134   auto value_obj = Utils::OpenHandle(*value);
4135   has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4136                                                 i::SLOPPY).is_null();
4137   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4138   return Just(true);
4139 }
4140 
4141 
Set(uint32_t index,v8::Local<Value> value)4142 bool v8::Object::Set(uint32_t index, v8::Local<Value> value) {
4143   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4144   return Set(context, index, value).FromMaybe(false);
4145 }
4146 
4147 
CreateDataProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value)4148 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4149                                            v8::Local<Name> key,
4150                                            v8::Local<Value> value) {
4151   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, CreateDataProperty, bool);
4152   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4153   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4154   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4155 
4156   i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4157       isolate, self, key_obj, self, i::LookupIterator::OWN);
4158   Maybe<bool> result =
4159       i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
4160   has_pending_exception = result.IsNothing();
4161   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4162   return result;
4163 }
4164 
4165 
CreateDataProperty(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4166 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4167                                            uint32_t index,
4168                                            v8::Local<Value> value) {
4169   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, CreateDataProperty, bool);
4170   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4171   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4172 
4173   i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4174   Maybe<bool> result =
4175       i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
4176   has_pending_exception = result.IsNothing();
4177   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4178   return result;
4179 }
4180 
4181 struct v8::PropertyDescriptor::PrivateData {
PrivateDatav8::v8::PropertyDescriptor::PrivateData4182   PrivateData() : desc() {}
4183   i::PropertyDescriptor desc;
4184 };
4185 
PropertyDescriptor()4186 v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4187 
4188 // DataDescriptor
PropertyDescriptor(v8::Local<v8::Value> value)4189 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4190     : private_(new PrivateData()) {
4191   private_->desc.set_value(Utils::OpenHandle(*value, true));
4192 }
4193 
4194 // DataDescriptor with writable field
PropertyDescriptor(v8::Local<v8::Value> value,bool writable)4195 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4196                                            bool writable)
4197     : private_(new PrivateData()) {
4198   private_->desc.set_value(Utils::OpenHandle(*value, true));
4199   private_->desc.set_writable(writable);
4200 }
4201 
4202 // AccessorDescriptor
PropertyDescriptor(v8::Local<v8::Value> get,v8::Local<v8::Value> set)4203 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4204                                            v8::Local<v8::Value> set)
4205     : private_(new PrivateData()) {
4206   DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4207   DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4208   private_->desc.set_get(Utils::OpenHandle(*get, true));
4209   private_->desc.set_set(Utils::OpenHandle(*set, true));
4210 }
4211 
~PropertyDescriptor()4212 v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4213 
value() const4214 v8::Local<Value> v8::PropertyDescriptor::value() const {
4215   DCHECK(private_->desc.has_value());
4216   return Utils::ToLocal(private_->desc.value());
4217 }
4218 
get() const4219 v8::Local<Value> v8::PropertyDescriptor::get() const {
4220   DCHECK(private_->desc.has_get());
4221   return Utils::ToLocal(private_->desc.get());
4222 }
4223 
set() const4224 v8::Local<Value> v8::PropertyDescriptor::set() const {
4225   DCHECK(private_->desc.has_set());
4226   return Utils::ToLocal(private_->desc.set());
4227 }
4228 
has_value() const4229 bool v8::PropertyDescriptor::has_value() const {
4230   return private_->desc.has_value();
4231 }
has_get() const4232 bool v8::PropertyDescriptor::has_get() const {
4233   return private_->desc.has_get();
4234 }
has_set() const4235 bool v8::PropertyDescriptor::has_set() const {
4236   return private_->desc.has_set();
4237 }
4238 
writable() const4239 bool v8::PropertyDescriptor::writable() const {
4240   DCHECK(private_->desc.has_writable());
4241   return private_->desc.writable();
4242 }
4243 
has_writable() const4244 bool v8::PropertyDescriptor::has_writable() const {
4245   return private_->desc.has_writable();
4246 }
4247 
set_enumerable(bool enumerable)4248 void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4249   private_->desc.set_enumerable(enumerable);
4250 }
4251 
enumerable() const4252 bool v8::PropertyDescriptor::enumerable() const {
4253   DCHECK(private_->desc.has_enumerable());
4254   return private_->desc.enumerable();
4255 }
4256 
has_enumerable() const4257 bool v8::PropertyDescriptor::has_enumerable() const {
4258   return private_->desc.has_enumerable();
4259 }
4260 
set_configurable(bool configurable)4261 void v8::PropertyDescriptor::set_configurable(bool configurable) {
4262   private_->desc.set_configurable(configurable);
4263 }
4264 
configurable() const4265 bool v8::PropertyDescriptor::configurable() const {
4266   DCHECK(private_->desc.has_configurable());
4267   return private_->desc.configurable();
4268 }
4269 
has_configurable() const4270 bool v8::PropertyDescriptor::has_configurable() const {
4271   return private_->desc.has_configurable();
4272 }
4273 
DefineOwnProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value,v8::PropertyAttribute attributes)4274 Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4275                                           v8::Local<Name> key,
4276                                           v8::Local<Value> value,
4277                                           v8::PropertyAttribute attributes) {
4278   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, DefineOwnProperty, bool);
4279   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4280   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4281   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4282 
4283   i::PropertyDescriptor desc;
4284   desc.set_writable(!(attributes & v8::ReadOnly));
4285   desc.set_enumerable(!(attributes & v8::DontEnum));
4286   desc.set_configurable(!(attributes & v8::DontDelete));
4287   desc.set_value(value_obj);
4288   Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4289       isolate, self, key_obj, &desc, i::Object::DONT_THROW);
4290   // Even though we said DONT_THROW, there might be accessors that do throw.
4291   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4292   return success;
4293 }
4294 
DefineProperty(v8::Local<v8::Context> context,v8::Local<Name> key,PropertyDescriptor & descriptor)4295 Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4296                                        v8::Local<Name> key,
4297                                        PropertyDescriptor& descriptor) {
4298   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, DefineProperty, bool);
4299   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4300   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4301 
4302   Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4303       isolate, self, key_obj, &descriptor.get_private()->desc,
4304       i::Object::DONT_THROW);
4305   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4306   return success;
4307 }
4308 
4309 MUST_USE_RESULT
DefineObjectProperty(i::Handle<i::JSObject> js_object,i::Handle<i::Object> key,i::Handle<i::Object> value,i::PropertyAttributes attrs)4310 static i::MaybeHandle<i::Object> DefineObjectProperty(
4311     i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
4312     i::Handle<i::Object> value, i::PropertyAttributes attrs) {
4313   i::Isolate* isolate = js_object->GetIsolate();
4314   bool success = false;
4315   i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4316       isolate, js_object, key, &success, i::LookupIterator::OWN);
4317   if (!success) return i::MaybeHandle<i::Object>();
4318 
4319   return i::JSObject::DefineOwnPropertyIgnoreAttributes(
4320       &it, value, attrs, i::JSObject::FORCE_FIELD);
4321 }
4322 
4323 
ForceSet(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value,v8::PropertyAttribute attribs)4324 Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
4325                                  v8::Local<Value> key, v8::Local<Value> value,
4326                                  v8::PropertyAttribute attribs) {
4327   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, ForceSet, bool);
4328   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4329   auto key_obj = Utils::OpenHandle(*key);
4330   auto value_obj = Utils::OpenHandle(*value);
4331   has_pending_exception =
4332       DefineObjectProperty(self, key_obj, value_obj,
4333                            static_cast<i::PropertyAttributes>(attribs))
4334           .is_null();
4335   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4336   return Just(true);
4337 }
4338 
4339 
ForceSet(v8::Local<Value> key,v8::Local<Value> value,v8::PropertyAttribute attribs)4340 bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value,
4341                           v8::PropertyAttribute attribs) {
4342   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4343   PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), Object, ForceSet,
4344                                 false, i::HandleScope, false);
4345   i::Handle<i::JSObject> self =
4346       i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4347   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
4348   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4349   has_pending_exception =
4350       DefineObjectProperty(self, key_obj, value_obj,
4351                            static_cast<i::PropertyAttributes>(attribs))
4352           .is_null();
4353   EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false);
4354   return true;
4355 }
4356 
4357 
SetPrivate(Local<Context> context,Local<Private> key,Local<Value> value)4358 Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4359                                    Local<Value> value) {
4360   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetPrivate, bool);
4361   auto self = Utils::OpenHandle(this);
4362   auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4363   auto value_obj = Utils::OpenHandle(*value);
4364   if (self->IsJSProxy()) {
4365     i::PropertyDescriptor desc;
4366     desc.set_writable(true);
4367     desc.set_enumerable(false);
4368     desc.set_configurable(true);
4369     desc.set_value(value_obj);
4370     return i::JSProxy::SetPrivateProperty(
4371         isolate, i::Handle<i::JSProxy>::cast(self),
4372         i::Handle<i::Symbol>::cast(key_obj), &desc, i::Object::DONT_THROW);
4373   }
4374   auto js_object = i::Handle<i::JSObject>::cast(self);
4375   i::LookupIterator it(js_object, key_obj, js_object);
4376   has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4377                               &it, value_obj, i::DONT_ENUM)
4378                               .is_null();
4379   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4380   return Just(true);
4381 }
4382 
4383 
Get(Local<v8::Context> context,Local<Value> key)4384 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4385                                   Local<Value> key) {
4386   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4387   auto self = Utils::OpenHandle(this);
4388   auto key_obj = Utils::OpenHandle(*key);
4389   i::Handle<i::Object> result;
4390   has_pending_exception =
4391       !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4392   RETURN_ON_FAILED_EXECUTION(Value);
4393   RETURN_ESCAPED(Utils::ToLocal(result));
4394 }
4395 
4396 
Get(v8::Local<Value> key)4397 Local<Value> v8::Object::Get(v8::Local<Value> key) {
4398   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4399   RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value);
4400 }
4401 
4402 
Get(Local<Context> context,uint32_t index)4403 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4404   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4405   auto self = Utils::OpenHandle(this);
4406   i::Handle<i::Object> result;
4407   has_pending_exception =
4408       !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4409   RETURN_ON_FAILED_EXECUTION(Value);
4410   RETURN_ESCAPED(Utils::ToLocal(result));
4411 }
4412 
4413 
Get(uint32_t index)4414 Local<Value> v8::Object::Get(uint32_t index) {
4415   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4416   RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value);
4417 }
4418 
4419 
GetPrivate(Local<Context> context,Local<Private> key)4420 MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4421                                          Local<Private> key) {
4422   return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4423 }
4424 
4425 
GetPropertyAttributes(Local<Context> context,Local<Value> key)4426 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4427     Local<Context> context, Local<Value> key) {
4428   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, GetPropertyAttributes,
4429                                   PropertyAttribute);
4430   auto self = Utils::OpenHandle(this);
4431   auto key_obj = Utils::OpenHandle(*key);
4432   if (!key_obj->IsName()) {
4433     has_pending_exception =
4434         !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4435     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4436   }
4437   auto key_name = i::Handle<i::Name>::cast(key_obj);
4438   auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4439   has_pending_exception = result.IsNothing();
4440   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4441   if (result.FromJust() == i::ABSENT) {
4442     return Just(static_cast<PropertyAttribute>(i::NONE));
4443   }
4444   return Just(static_cast<PropertyAttribute>(result.FromJust()));
4445 }
4446 
4447 
GetPropertyAttributes(v8::Local<Value> key)4448 PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) {
4449   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4450   return GetPropertyAttributes(context, key)
4451       .FromMaybe(static_cast<PropertyAttribute>(i::NONE));
4452 }
4453 
4454 
GetOwnPropertyDescriptor(Local<Context> context,Local<String> key)4455 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4456                                                        Local<String> key) {
4457   PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4458   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4459   i::Handle<i::String> key_name = Utils::OpenHandle(*key);
4460 
4461   i::PropertyDescriptor desc;
4462   Maybe<bool> found =
4463       i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4464   has_pending_exception = found.IsNothing();
4465   RETURN_ON_FAILED_EXECUTION(Value);
4466   if (!found.FromJust()) {
4467     return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4468   }
4469   RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4470 }
4471 
4472 
GetOwnPropertyDescriptor(Local<String> key)4473 Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) {
4474   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4475   RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyDescriptor(context, key), Value);
4476 }
4477 
4478 
GetPrototype()4479 Local<Value> v8::Object::GetPrototype() {
4480   auto isolate = Utils::OpenHandle(this)->GetIsolate();
4481   auto self = Utils::OpenHandle(this);
4482   i::PrototypeIterator iter(isolate, self);
4483   return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4484 }
4485 
4486 
SetPrototype(Local<Context> context,Local<Value> value)4487 Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4488                                      Local<Value> value) {
4489   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetPrototype, bool);
4490   auto self = Utils::OpenHandle(this);
4491   auto value_obj = Utils::OpenHandle(*value);
4492   // We do not allow exceptions thrown while setting the prototype
4493   // to propagate outside.
4494   TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4495   auto result = i::JSReceiver::SetPrototype(self, value_obj, false,
4496                                             i::Object::THROW_ON_ERROR);
4497   has_pending_exception = result.IsNothing();
4498   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4499   return Just(true);
4500 }
4501 
4502 
SetPrototype(Local<Value> value)4503 bool v8::Object::SetPrototype(Local<Value> value) {
4504   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4505   return SetPrototype(context, value).FromMaybe(false);
4506 }
4507 
FindInstanceInPrototypeChain(v8::Local<FunctionTemplate> tmpl)4508 Local<Object> v8::Object::FindInstanceInPrototypeChain(
4509     v8::Local<FunctionTemplate> tmpl) {
4510   auto self = Utils::OpenHandle(this);
4511   auto isolate = self->GetIsolate();
4512   i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4513   auto tmpl_info = *Utils::OpenHandle(*tmpl);
4514   while (!tmpl_info->IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4515     iter.Advance();
4516     if (iter.IsAtEnd()) return Local<Object>();
4517     if (!iter.GetCurrent()->IsJSObject()) return Local<Object>();
4518   }
4519   // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4520   return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4521 }
4522 
GetPropertyNames(Local<Context> context)4523 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4524   return GetPropertyNames(
4525       context, v8::KeyCollectionMode::kIncludePrototypes,
4526       static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4527       v8::IndexFilter::kIncludeIndices);
4528 }
4529 
GetPropertyNames(Local<Context> context,KeyCollectionMode mode,PropertyFilter property_filter,IndexFilter index_filter)4530 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context,
4531                                                KeyCollectionMode mode,
4532                                                PropertyFilter property_filter,
4533                                                IndexFilter index_filter) {
4534   PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4535   auto self = Utils::OpenHandle(this);
4536   i::Handle<i::FixedArray> value;
4537   i::KeyAccumulator accumulator(
4538       isolate, static_cast<i::KeyCollectionMode>(mode),
4539       static_cast<i::PropertyFilter>(property_filter));
4540   accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4541   has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4542   RETURN_ON_FAILED_EXECUTION(Array);
4543   value = accumulator.GetKeys(i::GetKeysConversion::kKeepNumbers);
4544   DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
4545          self->map()->EnumLength() == 0 ||
4546          self->map()->instance_descriptors()->GetEnumCache() != *value);
4547   auto result = isolate->factory()->NewJSArrayWithElements(value);
4548   RETURN_ESCAPED(Utils::ToLocal(result));
4549 }
4550 
4551 
GetPropertyNames()4552 Local<Array> v8::Object::GetPropertyNames() {
4553   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4554   RETURN_TO_LOCAL_UNCHECKED(GetPropertyNames(context), Array);
4555 }
4556 
GetOwnPropertyNames(Local<Context> context)4557 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4558   return GetOwnPropertyNames(
4559       context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4560 }
4561 
GetOwnPropertyNames()4562 Local<Array> v8::Object::GetOwnPropertyNames() {
4563   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4564   RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyNames(context), Array);
4565 }
4566 
GetOwnPropertyNames(Local<Context> context,PropertyFilter filter)4567 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context,
4568                                                   PropertyFilter filter) {
4569   return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4570                           v8::IndexFilter::kIncludeIndices);
4571 }
4572 
ObjectProtoToString(Local<Context> context)4573 MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4574   PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4575   auto self = Utils::OpenHandle(this);
4576   Local<Value> result;
4577   has_pending_exception =
4578       !ToLocal<Value>(i::Execution::Call(isolate, isolate->object_to_string(),
4579                                          self, 0, nullptr),
4580                       &result);
4581   RETURN_ON_FAILED_EXECUTION(String);
4582   RETURN_ESCAPED(Local<String>::Cast(result));
4583 }
4584 
4585 
ObjectProtoToString()4586 Local<String> v8::Object::ObjectProtoToString() {
4587   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4588   RETURN_TO_LOCAL_UNCHECKED(ObjectProtoToString(context), String);
4589 }
4590 
4591 
GetConstructorName()4592 Local<String> v8::Object::GetConstructorName() {
4593   auto self = Utils::OpenHandle(this);
4594   i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
4595   return Utils::ToLocal(name);
4596 }
4597 
SetIntegrityLevel(Local<Context> context,IntegrityLevel level)4598 Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4599                                           IntegrityLevel level) {
4600   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetIntegrityLevel, bool);
4601   auto self = Utils::OpenHandle(this);
4602   i::JSReceiver::IntegrityLevel i_level =
4603       level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4604   Maybe<bool> result =
4605       i::JSReceiver::SetIntegrityLevel(self, i_level, i::Object::DONT_THROW);
4606   has_pending_exception = result.IsNothing();
4607   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4608   return result;
4609 }
4610 
Delete(Local<Context> context,Local<Value> key)4611 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4612   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Delete, bool);
4613   auto self = Utils::OpenHandle(this);
4614   auto key_obj = Utils::OpenHandle(*key);
4615   Maybe<bool> result =
4616       i::Runtime::DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY);
4617   has_pending_exception = result.IsNothing();
4618   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4619   return result;
4620 }
4621 
4622 
Delete(v8::Local<Value> key)4623 bool v8::Object::Delete(v8::Local<Value> key) {
4624   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4625   return Delete(context, key).FromMaybe(false);
4626 }
4627 
4628 
DeletePrivate(Local<Context> context,Local<Private> key)4629 Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4630                                       Local<Private> key) {
4631   return Delete(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4632 }
4633 
4634 
Has(Local<Context> context,Local<Value> key)4635 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4636   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Get, bool);
4637   auto self = Utils::OpenHandle(this);
4638   auto key_obj = Utils::OpenHandle(*key);
4639   Maybe<bool> maybe = Nothing<bool>();
4640   // Check if the given key is an array index.
4641   uint32_t index = 0;
4642   if (key_obj->ToArrayIndex(&index)) {
4643     maybe = i::JSReceiver::HasElement(self, index);
4644   } else {
4645     // Convert the key to a name - possibly by calling back into JavaScript.
4646     i::Handle<i::Name> name;
4647     if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4648       maybe = i::JSReceiver::HasProperty(self, name);
4649     }
4650   }
4651   has_pending_exception = maybe.IsNothing();
4652   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4653   return maybe;
4654 }
4655 
4656 
Has(v8::Local<Value> key)4657 bool v8::Object::Has(v8::Local<Value> key) {
4658   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4659   return Has(context, key).FromMaybe(false);
4660 }
4661 
4662 
HasPrivate(Local<Context> context,Local<Private> key)4663 Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4664   return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4665 }
4666 
4667 
Delete(Local<Context> context,uint32_t index)4668 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4669   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, DeleteProperty, bool);
4670   auto self = Utils::OpenHandle(this);
4671   Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4672   has_pending_exception = result.IsNothing();
4673   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4674   return result;
4675 }
4676 
4677 
Delete(uint32_t index)4678 bool v8::Object::Delete(uint32_t index) {
4679   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4680   return Delete(context, index).FromMaybe(false);
4681 }
4682 
4683 
Has(Local<Context> context,uint32_t index)4684 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4685   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Get, bool);
4686   auto self = Utils::OpenHandle(this);
4687   auto maybe = i::JSReceiver::HasElement(self, index);
4688   has_pending_exception = maybe.IsNothing();
4689   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4690   return maybe;
4691 }
4692 
4693 
Has(uint32_t index)4694 bool v8::Object::Has(uint32_t index) {
4695   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4696   return Has(context, index).FromMaybe(false);
4697 }
4698 
4699 
4700 template <typename Getter, typename Setter, typename Data>
ObjectSetAccessor(Local<Context> context,Object * self,Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attributes)4701 static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
4702                                      Local<Name> name, Getter getter,
4703                                      Setter setter, Data data,
4704                                      AccessControl settings,
4705                                      PropertyAttribute attributes) {
4706   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetAccessor, bool);
4707   if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4708   i::Handle<i::JSObject> obj =
4709       i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4710   v8::Local<AccessorSignature> signature;
4711   auto info =
4712       MakeAccessorInfo(name, getter, setter, data, settings, attributes,
4713                        signature, i::FLAG_disable_old_api_accessors, false);
4714   if (info.is_null()) return Nothing<bool>();
4715   bool fast = obj->HasFastProperties();
4716   i::Handle<i::Object> result;
4717   has_pending_exception =
4718       !i::JSObject::SetAccessor(obj, info).ToHandle(&result);
4719   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4720   if (result->IsUndefined(obj->GetIsolate())) return Just(false);
4721   if (fast) {
4722     i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4723   }
4724   return Just(true);
4725 }
4726 
4727 
SetAccessor(Local<Context> context,Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,MaybeLocal<Value> data,AccessControl settings,PropertyAttribute attribute)4728 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4729                                 AccessorNameGetterCallback getter,
4730                                 AccessorNameSetterCallback setter,
4731                                 MaybeLocal<Value> data, AccessControl settings,
4732                                 PropertyAttribute attribute) {
4733   return ObjectSetAccessor(context, this, name, getter, setter,
4734                            data.FromMaybe(Local<Value>()), settings, attribute);
4735 }
4736 
4737 
SetAccessor(Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attributes)4738 bool Object::SetAccessor(Local<String> name, AccessorGetterCallback getter,
4739                          AccessorSetterCallback setter, v8::Local<Value> data,
4740                          AccessControl settings, PropertyAttribute attributes) {
4741   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4742   return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
4743                            attributes).FromMaybe(false);
4744 }
4745 
4746 
SetAccessor(Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attributes)4747 bool Object::SetAccessor(Local<Name> name, AccessorNameGetterCallback getter,
4748                          AccessorNameSetterCallback setter,
4749                          v8::Local<Value> data, AccessControl settings,
4750                          PropertyAttribute attributes) {
4751   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4752   return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
4753                            attributes).FromMaybe(false);
4754 }
4755 
4756 
SetAccessorProperty(Local<Name> name,Local<Function> getter,Local<Function> setter,PropertyAttribute attribute,AccessControl settings)4757 void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4758                                  Local<Function> setter,
4759                                  PropertyAttribute attribute,
4760                                  AccessControl settings) {
4761   // TODO(verwaest): Remove |settings|.
4762   DCHECK_EQ(v8::DEFAULT, settings);
4763   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4764   ENTER_V8(isolate);
4765   i::HandleScope scope(isolate);
4766   auto self = Utils::OpenHandle(this);
4767   if (!self->IsJSObject()) return;
4768   i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4769   i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4770   if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
4771   i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4772                               v8::Utils::OpenHandle(*name), getter_i, setter_i,
4773                               static_cast<i::PropertyAttributes>(attribute));
4774 }
4775 
4776 
HasOwnProperty(Local<Context> context,Local<Name> key)4777 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4778                                        Local<Name> key) {
4779   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasOwnProperty, bool);
4780   auto self = Utils::OpenHandle(this);
4781   auto key_val = Utils::OpenHandle(*key);
4782   auto result = i::JSReceiver::HasOwnProperty(self, key_val);
4783   has_pending_exception = result.IsNothing();
4784   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4785   return result;
4786 }
4787 
HasOwnProperty(Local<Context> context,uint32_t index)4788 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
4789   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasOwnProperty, bool);
4790   auto self = Utils::OpenHandle(this);
4791   auto result = i::JSReceiver::HasOwnProperty(self, index);
4792   has_pending_exception = result.IsNothing();
4793   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4794   return result;
4795 }
4796 
HasOwnProperty(Local<String> key)4797 bool v8::Object::HasOwnProperty(Local<String> key) {
4798   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4799   return HasOwnProperty(context, key).FromMaybe(false);
4800 }
4801 
4802 
HasRealNamedProperty(Local<Context> context,Local<Name> key)4803 Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4804                                              Local<Name> key) {
4805   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasRealNamedProperty, bool);
4806   auto self = Utils::OpenHandle(this);
4807   if (!self->IsJSObject()) return Just(false);
4808   auto key_val = Utils::OpenHandle(*key);
4809   auto result = i::JSObject::HasRealNamedProperty(
4810       i::Handle<i::JSObject>::cast(self), key_val);
4811   has_pending_exception = result.IsNothing();
4812   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4813   return result;
4814 }
4815 
4816 
HasRealNamedProperty(Local<String> key)4817 bool v8::Object::HasRealNamedProperty(Local<String> key) {
4818   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4819   return HasRealNamedProperty(context, key).FromMaybe(false);
4820 }
4821 
4822 
HasRealIndexedProperty(Local<Context> context,uint32_t index)4823 Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4824                                                uint32_t index) {
4825   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasRealIndexedProperty,
4826                                   bool);
4827   auto self = Utils::OpenHandle(this);
4828   if (!self->IsJSObject()) return Just(false);
4829   auto result = i::JSObject::HasRealElementProperty(
4830       i::Handle<i::JSObject>::cast(self), index);
4831   has_pending_exception = result.IsNothing();
4832   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4833   return result;
4834 }
4835 
4836 
HasRealIndexedProperty(uint32_t index)4837 bool v8::Object::HasRealIndexedProperty(uint32_t index) {
4838   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4839   return HasRealIndexedProperty(context, index).FromMaybe(false);
4840 }
4841 
4842 
HasRealNamedCallbackProperty(Local<Context> context,Local<Name> key)4843 Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4844                                                      Local<Name> key) {
4845   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, HasRealNamedCallbackProperty,
4846                                   bool);
4847   auto self = Utils::OpenHandle(this);
4848   if (!self->IsJSObject()) return Just(false);
4849   auto key_val = Utils::OpenHandle(*key);
4850   auto result = i::JSObject::HasRealNamedCallbackProperty(
4851       i::Handle<i::JSObject>::cast(self), key_val);
4852   has_pending_exception = result.IsNothing();
4853   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4854   return result;
4855 }
4856 
4857 
HasRealNamedCallbackProperty(Local<String> key)4858 bool v8::Object::HasRealNamedCallbackProperty(Local<String> key) {
4859   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4860   return HasRealNamedCallbackProperty(context, key).FromMaybe(false);
4861 }
4862 
4863 
HasNamedLookupInterceptor()4864 bool v8::Object::HasNamedLookupInterceptor() {
4865   auto self = Utils::OpenHandle(this);
4866   return self->IsJSObject() &&
4867          i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor();
4868 }
4869 
4870 
HasIndexedLookupInterceptor()4871 bool v8::Object::HasIndexedLookupInterceptor() {
4872   auto self = Utils::OpenHandle(this);
4873   return self->IsJSObject() &&
4874          i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor();
4875 }
4876 
4877 
GetRealNamedPropertyInPrototypeChain(Local<Context> context,Local<Name> key)4878 MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4879     Local<Context> context, Local<Name> key) {
4880   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
4881                         Value);
4882   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4883   if (!self->IsJSObject()) return MaybeLocal<Value>();
4884   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4885   i::PrototypeIterator iter(isolate, self);
4886   if (iter.IsAtEnd()) return MaybeLocal<Value>();
4887   i::Handle<i::JSReceiver> proto =
4888       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4889   i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4890       isolate, self, key_obj, proto,
4891       i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4892   Local<Value> result;
4893   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4894   RETURN_ON_FAILED_EXECUTION(Value);
4895   if (!it.IsFound()) return MaybeLocal<Value>();
4896   RETURN_ESCAPED(result);
4897 }
4898 
4899 
GetRealNamedPropertyInPrototypeChain(Local<String> key)4900 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4901     Local<String> key) {
4902   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4903   RETURN_TO_LOCAL_UNCHECKED(GetRealNamedPropertyInPrototypeChain(context, key),
4904                             Value);
4905 }
4906 
4907 
4908 Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,Local<Name> key)4909 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
4910     Local<Context> context, Local<Name> key) {
4911   PREPARE_FOR_EXECUTION_PRIMITIVE(
4912       context, Object, GetRealNamedPropertyAttributesInPrototypeChain,
4913       PropertyAttribute);
4914   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4915   if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
4916   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4917   i::PrototypeIterator iter(isolate, self);
4918   if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
4919   i::Handle<i::JSReceiver> proto =
4920       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4921   i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4922       isolate, self, key_obj, proto,
4923       i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4924   Maybe<i::PropertyAttributes> result =
4925       i::JSReceiver::GetPropertyAttributes(&it);
4926   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4927   if (!it.IsFound()) return Nothing<PropertyAttribute>();
4928   if (result.FromJust() == i::ABSENT) return Just(None);
4929   return Just(static_cast<PropertyAttribute>(result.FromJust()));
4930 }
4931 
4932 
4933 Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key)4934 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key) {
4935   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4936   return GetRealNamedPropertyAttributesInPrototypeChain(context, key);
4937 }
4938 
4939 
GetRealNamedProperty(Local<Context> context,Local<Name> key)4940 MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
4941                                                    Local<Name> key) {
4942   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
4943   auto self = Utils::OpenHandle(this);
4944   auto key_obj = Utils::OpenHandle(*key);
4945   i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4946       isolate, self, key_obj, self,
4947       i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4948   Local<Value> result;
4949   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4950   RETURN_ON_FAILED_EXECUTION(Value);
4951   if (!it.IsFound()) return MaybeLocal<Value>();
4952   RETURN_ESCAPED(result);
4953 }
4954 
4955 
GetRealNamedProperty(Local<String> key)4956 Local<Value> v8::Object::GetRealNamedProperty(Local<String> key) {
4957   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4958   RETURN_TO_LOCAL_UNCHECKED(GetRealNamedProperty(context, key), Value);
4959 }
4960 
4961 
GetRealNamedPropertyAttributes(Local<Context> context,Local<Name> key)4962 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4963     Local<Context> context, Local<Name> key) {
4964   PREPARE_FOR_EXECUTION_PRIMITIVE(
4965       context, Object, GetRealNamedPropertyAttributes, PropertyAttribute);
4966   auto self = Utils::OpenHandle(this);
4967   auto key_obj = Utils::OpenHandle(*key);
4968   i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4969       isolate, self, key_obj, self,
4970       i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4971   auto result = i::JSReceiver::GetPropertyAttributes(&it);
4972   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4973   if (!it.IsFound()) return Nothing<PropertyAttribute>();
4974   if (result.FromJust() == i::ABSENT) {
4975     return Just(static_cast<PropertyAttribute>(i::NONE));
4976   }
4977   return Just<PropertyAttribute>(
4978       static_cast<PropertyAttribute>(result.FromJust()));
4979 }
4980 
4981 
GetRealNamedPropertyAttributes(Local<String> key)4982 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4983     Local<String> key) {
4984   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4985   return GetRealNamedPropertyAttributes(context, key);
4986 }
4987 
4988 
Clone()4989 Local<v8::Object> v8::Object::Clone() {
4990   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4991   auto isolate = self->GetIsolate();
4992   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4993   auto result = isolate->factory()->CopyJSObject(self);
4994   CHECK(!result.is_null());
4995   return Utils::ToLocal(result);
4996 }
4997 
4998 
CreationContext()4999 Local<v8::Context> v8::Object::CreationContext() {
5000   auto self = Utils::OpenHandle(this);
5001   return Utils::ToLocal(self->GetCreationContext());
5002 }
5003 
5004 
GetIdentityHash()5005 int v8::Object::GetIdentityHash() {
5006   auto isolate = Utils::OpenHandle(this)->GetIsolate();
5007   i::HandleScope scope(isolate);
5008   auto self = Utils::OpenHandle(this);
5009   return i::JSReceiver::GetOrCreateIdentityHash(isolate, self)->value();
5010 }
5011 
5012 
IsCallable()5013 bool v8::Object::IsCallable() {
5014   auto self = Utils::OpenHandle(this);
5015   return self->IsCallable();
5016 }
5017 
IsConstructor()5018 bool v8::Object::IsConstructor() {
5019   auto self = Utils::OpenHandle(this);
5020   return self->IsConstructor();
5021 }
5022 
CallAsFunction(Local<Context> context,Local<Value> recv,int argc,Local<Value> argv[])5023 MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
5024                                          Local<Value> recv, int argc,
5025                                          Local<Value> argv[]) {
5026   PREPARE_FOR_EXECUTION_WITH_CONTEXT_IN_RUNTIME_CALL_STATS_SCOPE(
5027       "v8", "V8.Execute", context, Object, CallAsFunction, MaybeLocal<Value>(),
5028       InternalEscapableScope, true);
5029   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5030   auto self = Utils::OpenHandle(this);
5031   auto recv_obj = Utils::OpenHandle(*recv);
5032   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5033   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5034   Local<Value> result;
5035   has_pending_exception = !ToLocal<Value>(
5036       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5037   RETURN_ON_FAILED_EXECUTION(Value);
5038   RETURN_ESCAPED(result);
5039 }
5040 
5041 
CallAsFunction(v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5042 Local<v8::Value> Object::CallAsFunction(v8::Local<v8::Value> recv, int argc,
5043                                         v8::Local<v8::Value> argv[]) {
5044   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5045   Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
5046   RETURN_TO_LOCAL_UNCHECKED(CallAsFunction(context, recv, argc, argv_cast),
5047                             Value);
5048 }
5049 
5050 
CallAsConstructor(Local<Context> context,int argc,Local<Value> argv[])5051 MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
5052                                             Local<Value> argv[]) {
5053   PREPARE_FOR_EXECUTION_WITH_CONTEXT_IN_RUNTIME_CALL_STATS_SCOPE(
5054       "v8", "V8.Execute", context, Object, CallAsConstructor,
5055       MaybeLocal<Value>(), InternalEscapableScope, true);
5056   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5057   auto self = Utils::OpenHandle(this);
5058   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5059   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5060   Local<Value> result;
5061   has_pending_exception = !ToLocal<Value>(
5062       i::Execution::New(isolate, self, self, argc, args), &result);
5063   RETURN_ON_FAILED_EXECUTION(Value);
5064   RETURN_ESCAPED(result);
5065 }
5066 
5067 
CallAsConstructor(int argc,v8::Local<v8::Value> argv[])5068 Local<v8::Value> Object::CallAsConstructor(int argc,
5069                                            v8::Local<v8::Value> argv[]) {
5070   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5071   Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
5072   RETURN_TO_LOCAL_UNCHECKED(CallAsConstructor(context, argc, argv_cast), Value);
5073 }
5074 
New(Local<Context> context,FunctionCallback callback,Local<Value> data,int length,ConstructorBehavior behavior)5075 MaybeLocal<Function> Function::New(Local<Context> context,
5076                                    FunctionCallback callback, Local<Value> data,
5077                                    int length, ConstructorBehavior behavior) {
5078   i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
5079   LOG_API(isolate, Function, New);
5080   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5081   auto templ = FunctionTemplateNew(isolate, callback, nullptr, data,
5082                                    Local<Signature>(), length, true);
5083   if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
5084   return templ->GetFunction(context);
5085 }
5086 
5087 
New(Isolate * v8_isolate,FunctionCallback callback,Local<Value> data,int length)5088 Local<Function> Function::New(Isolate* v8_isolate, FunctionCallback callback,
5089                               Local<Value> data, int length) {
5090   return Function::New(v8_isolate->GetCurrentContext(), callback, data, length,
5091                        ConstructorBehavior::kAllow)
5092       .FromMaybe(Local<Function>());
5093 }
5094 
5095 
NewInstance() const5096 Local<v8::Object> Function::NewInstance() const {
5097   return NewInstance(Isolate::GetCurrent()->GetCurrentContext(), 0, NULL)
5098       .FromMaybe(Local<Object>());
5099 }
5100 
5101 
NewInstance(Local<Context> context,int argc,v8::Local<v8::Value> argv[]) const5102 MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
5103                                          v8::Local<v8::Value> argv[]) const {
5104   PREPARE_FOR_EXECUTION_WITH_CONTEXT_IN_RUNTIME_CALL_STATS_SCOPE(
5105       "v8", "V8.Execute", context, Function, NewInstance, MaybeLocal<Object>(),
5106       InternalEscapableScope, true);
5107   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5108   auto self = Utils::OpenHandle(this);
5109   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5110   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5111   Local<Object> result;
5112   has_pending_exception = !ToLocal<Object>(
5113       i::Execution::New(isolate, self, self, argc, args), &result);
5114   RETURN_ON_FAILED_EXECUTION(Object);
5115   RETURN_ESCAPED(result);
5116 }
5117 
5118 
NewInstance(int argc,v8::Local<v8::Value> argv[]) const5119 Local<v8::Object> Function::NewInstance(int argc,
5120                                         v8::Local<v8::Value> argv[]) const {
5121   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5122   RETURN_TO_LOCAL_UNCHECKED(NewInstance(context, argc, argv), Object);
5123 }
5124 
5125 
Call(Local<Context> context,v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5126 MaybeLocal<v8::Value> Function::Call(Local<Context> context,
5127                                      v8::Local<v8::Value> recv, int argc,
5128                                      v8::Local<v8::Value> argv[]) {
5129   PREPARE_FOR_EXECUTION_WITH_CONTEXT_IN_RUNTIME_CALL_STATS_SCOPE(
5130       "v8", "V8.Execute", context, Function, Call, MaybeLocal<Value>(),
5131       InternalEscapableScope, true);
5132   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5133   auto self = Utils::OpenHandle(this);
5134   i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
5135   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5136   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5137   Local<Value> result;
5138   has_pending_exception = !ToLocal<Value>(
5139       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5140   RETURN_ON_FAILED_EXECUTION(Value);
5141   RETURN_ESCAPED(result);
5142 }
5143 
5144 
Call(v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5145 Local<v8::Value> Function::Call(v8::Local<v8::Value> recv, int argc,
5146                                 v8::Local<v8::Value> argv[]) {
5147   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5148   RETURN_TO_LOCAL_UNCHECKED(Call(context, recv, argc, argv), Value);
5149 }
5150 
5151 
SetName(v8::Local<v8::String> name)5152 void Function::SetName(v8::Local<v8::String> name) {
5153   auto self = Utils::OpenHandle(this);
5154   if (!self->IsJSFunction()) return;
5155   auto func = i::Handle<i::JSFunction>::cast(self);
5156   func->shared()->set_name(*Utils::OpenHandle(*name));
5157 }
5158 
5159 
GetName() const5160 Local<Value> Function::GetName() const {
5161   auto self = Utils::OpenHandle(this);
5162   i::Isolate* isolate = self->GetIsolate();
5163   if (self->IsJSBoundFunction()) {
5164     auto func = i::Handle<i::JSBoundFunction>::cast(self);
5165     i::Handle<i::Object> name;
5166     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5167                                      i::JSBoundFunction::GetName(isolate, func),
5168                                      Local<Value>());
5169     return Utils::ToLocal(name);
5170   }
5171   if (self->IsJSFunction()) {
5172     auto func = i::Handle<i::JSFunction>::cast(self);
5173     return Utils::ToLocal(handle(func->shared()->name(), isolate));
5174   }
5175   return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5176 }
5177 
5178 
GetInferredName() const5179 Local<Value> Function::GetInferredName() const {
5180   auto self = Utils::OpenHandle(this);
5181   if (!self->IsJSFunction()) {
5182     return ToApiHandle<Primitive>(
5183         self->GetIsolate()->factory()->undefined_value());
5184   }
5185   auto func = i::Handle<i::JSFunction>::cast(self);
5186   return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
5187                                              func->GetIsolate()));
5188 }
5189 
5190 
GetDebugName() const5191 Local<Value> Function::GetDebugName() const {
5192   auto self = Utils::OpenHandle(this);
5193   if (!self->IsJSFunction()) {
5194     return ToApiHandle<Primitive>(
5195         self->GetIsolate()->factory()->undefined_value());
5196   }
5197   auto func = i::Handle<i::JSFunction>::cast(self);
5198   i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5199   return Utils::ToLocal(i::Handle<i::Object>(*name, name->GetIsolate()));
5200 }
5201 
5202 
GetDisplayName() const5203 Local<Value> Function::GetDisplayName() const {
5204   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
5205   ENTER_V8(isolate);
5206   auto self = Utils::OpenHandle(this);
5207   if (!self->IsJSFunction()) {
5208     return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5209   }
5210   auto func = i::Handle<i::JSFunction>::cast(self);
5211   i::Handle<i::String> property_name =
5212       isolate->factory()->NewStringFromStaticChars("displayName");
5213   i::Handle<i::Object> value =
5214       i::JSReceiver::GetDataProperty(func, property_name);
5215   if (value->IsString()) {
5216     i::Handle<i::String> name = i::Handle<i::String>::cast(value);
5217     if (name->length() > 0) return Utils::ToLocal(name);
5218   }
5219   return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5220 }
5221 
5222 
GetScriptOrigin() const5223 ScriptOrigin Function::GetScriptOrigin() const {
5224   auto self = Utils::OpenHandle(this);
5225   if (!self->IsJSFunction()) {
5226     return v8::ScriptOrigin(Local<Value>());
5227   }
5228   auto func = i::Handle<i::JSFunction>::cast(self);
5229   if (func->shared()->script()->IsScript()) {
5230     i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5231     return GetScriptOriginForScript(func->GetIsolate(), script);
5232   }
5233   return v8::ScriptOrigin(Local<Value>());
5234 }
5235 
5236 
5237 const int Function::kLineOffsetNotFound = -1;
5238 
5239 
GetScriptLineNumber() const5240 int Function::GetScriptLineNumber() const {
5241   auto self = Utils::OpenHandle(this);
5242   if (!self->IsJSFunction()) {
5243     return kLineOffsetNotFound;
5244   }
5245   auto func = i::Handle<i::JSFunction>::cast(self);
5246   if (func->shared()->script()->IsScript()) {
5247     i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5248     return i::Script::GetLineNumber(script, func->shared()->start_position());
5249   }
5250   return kLineOffsetNotFound;
5251 }
5252 
5253 
GetScriptColumnNumber() const5254 int Function::GetScriptColumnNumber() const {
5255   auto self = Utils::OpenHandle(this);
5256   if (!self->IsJSFunction()) {
5257     return kLineOffsetNotFound;
5258   }
5259   auto func = i::Handle<i::JSFunction>::cast(self);
5260   if (func->shared()->script()->IsScript()) {
5261     i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5262     return i::Script::GetColumnNumber(script, func->shared()->start_position());
5263   }
5264   return kLineOffsetNotFound;
5265 }
5266 
5267 
IsBuiltin() const5268 bool Function::IsBuiltin() const {
5269   auto self = Utils::OpenHandle(this);
5270   if (!self->IsJSFunction()) {
5271     return false;
5272   }
5273   auto func = i::Handle<i::JSFunction>::cast(self);
5274   return !func->shared()->IsUserJavaScript();
5275 }
5276 
5277 
ScriptId() const5278 int Function::ScriptId() const {
5279   auto self = Utils::OpenHandle(this);
5280   if (!self->IsJSFunction()) {
5281     return v8::UnboundScript::kNoScriptId;
5282   }
5283   auto func = i::Handle<i::JSFunction>::cast(self);
5284   if (!func->shared()->script()->IsScript()) {
5285     return v8::UnboundScript::kNoScriptId;
5286   }
5287   i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5288   return script->id();
5289 }
5290 
5291 
GetBoundFunction() const5292 Local<v8::Value> Function::GetBoundFunction() const {
5293   auto self = Utils::OpenHandle(this);
5294   if (self->IsJSBoundFunction()) {
5295     auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5296     auto bound_target_function = i::handle(
5297         bound_function->bound_target_function(), bound_function->GetIsolate());
5298     return Utils::CallableToLocal(bound_target_function);
5299   }
5300   return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5301 }
5302 
5303 
GetIdentityHash()5304 int Name::GetIdentityHash() {
5305   auto self = Utils::OpenHandle(this);
5306   return static_cast<int>(self->Hash());
5307 }
5308 
5309 
Length() const5310 int String::Length() const {
5311   i::Handle<i::String> str = Utils::OpenHandle(this);
5312   return str->length();
5313 }
5314 
5315 
IsOneByte() const5316 bool String::IsOneByte() const {
5317   i::Handle<i::String> str = Utils::OpenHandle(this);
5318   return str->HasOnlyOneByteChars();
5319 }
5320 
5321 
5322 // Helpers for ContainsOnlyOneByteHelper
5323 template<size_t size> struct OneByteMask;
5324 template<> struct OneByteMask<4> {
5325   static const uint32_t value = 0xFF00FF00;
5326 };
5327 template<> struct OneByteMask<8> {
5328   static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
5329 };
5330 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5331 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
Unaligned(const uint16_t * chars)5332 static inline bool Unaligned(const uint16_t* chars) {
5333   return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5334 }
5335 
5336 
Align(const uint16_t * chars)5337 static inline const uint16_t* Align(const uint16_t* chars) {
5338   return reinterpret_cast<uint16_t*>(
5339       reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
5340 }
5341 
5342 class ContainsOnlyOneByteHelper {
5343  public:
ContainsOnlyOneByteHelper()5344   ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
Check(i::String * string)5345   bool Check(i::String* string) {
5346     i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
5347     if (cons_string == NULL) return is_one_byte_;
5348     return CheckCons(cons_string);
5349   }
VisitOneByteString(const uint8_t * chars,int length)5350   void VisitOneByteString(const uint8_t* chars, int length) {
5351     // Nothing to do.
5352   }
VisitTwoByteString(const uint16_t * chars,int length)5353   void VisitTwoByteString(const uint16_t* chars, int length) {
5354     // Accumulated bits.
5355     uintptr_t acc = 0;
5356     // Align to uintptr_t.
5357     const uint16_t* end = chars + length;
5358     while (Unaligned(chars) && chars != end) {
5359       acc |= *chars++;
5360     }
5361     // Read word aligned in blocks,
5362     // checking the return value at the end of each block.
5363     const uint16_t* aligned_end = Align(end);
5364     const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
5365     const int inner_loops = 16;
5366     while (chars + inner_loops*increment < aligned_end) {
5367       for (int i = 0; i < inner_loops; i++) {
5368         acc |= *reinterpret_cast<const uintptr_t*>(chars);
5369         chars += increment;
5370       }
5371       // Check for early return.
5372       if ((acc & kOneByteMask) != 0) {
5373         is_one_byte_ = false;
5374         return;
5375       }
5376     }
5377     // Read the rest.
5378     while (chars != end) {
5379       acc |= *chars++;
5380     }
5381     // Check result.
5382     if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5383   }
5384 
5385  private:
CheckCons(i::ConsString * cons_string)5386   bool CheckCons(i::ConsString* cons_string) {
5387     while (true) {
5388       // Check left side if flat.
5389       i::String* left = cons_string->first();
5390       i::ConsString* left_as_cons =
5391           i::String::VisitFlat(this, left, 0);
5392       if (!is_one_byte_) return false;
5393       // Check right side if flat.
5394       i::String* right = cons_string->second();
5395       i::ConsString* right_as_cons =
5396           i::String::VisitFlat(this, right, 0);
5397       if (!is_one_byte_) return false;
5398       // Standard recurse/iterate trick.
5399       if (left_as_cons != NULL && right_as_cons != NULL) {
5400         if (left->length() < right->length()) {
5401           CheckCons(left_as_cons);
5402           cons_string = right_as_cons;
5403         } else {
5404           CheckCons(right_as_cons);
5405           cons_string = left_as_cons;
5406         }
5407         // Check fast return.
5408         if (!is_one_byte_) return false;
5409         continue;
5410       }
5411       // Descend left in place.
5412       if (left_as_cons != NULL) {
5413         cons_string = left_as_cons;
5414         continue;
5415       }
5416       // Descend right in place.
5417       if (right_as_cons != NULL) {
5418         cons_string = right_as_cons;
5419         continue;
5420       }
5421       // Terminate.
5422       break;
5423     }
5424     return is_one_byte_;
5425   }
5426   bool is_one_byte_;
5427   DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
5428 };
5429 
5430 
ContainsOnlyOneByte() const5431 bool String::ContainsOnlyOneByte() const {
5432   i::Handle<i::String> str = Utils::OpenHandle(this);
5433   if (str->HasOnlyOneByteChars()) return true;
5434   ContainsOnlyOneByteHelper helper;
5435   return helper.Check(*str);
5436 }
5437 
5438 
5439 class Utf8LengthHelper : public i::AllStatic {
5440  public:
5441   enum State {
5442     kEndsWithLeadingSurrogate = 1 << 0,
5443     kStartsWithTrailingSurrogate = 1 << 1,
5444     kLeftmostEdgeIsCalculated = 1 << 2,
5445     kRightmostEdgeIsCalculated = 1 << 3,
5446     kLeftmostEdgeIsSurrogate = 1 << 4,
5447     kRightmostEdgeIsSurrogate = 1 << 5
5448   };
5449 
5450   static const uint8_t kInitialState = 0;
5451 
EndsWithSurrogate(uint8_t state)5452   static inline bool EndsWithSurrogate(uint8_t state) {
5453     return state & kEndsWithLeadingSurrogate;
5454   }
5455 
StartsWithSurrogate(uint8_t state)5456   static inline bool StartsWithSurrogate(uint8_t state) {
5457     return state & kStartsWithTrailingSurrogate;
5458   }
5459 
5460   class Visitor {
5461    public:
Visitor()5462     Visitor() : utf8_length_(0), state_(kInitialState) {}
5463 
VisitOneByteString(const uint8_t * chars,int length)5464     void VisitOneByteString(const uint8_t* chars, int length) {
5465       int utf8_length = 0;
5466       // Add in length 1 for each non-Latin1 character.
5467       for (int i = 0; i < length; i++) {
5468         utf8_length += *chars++ >> 7;
5469       }
5470       // Add in length 1 for each character.
5471       utf8_length_ = utf8_length + length;
5472       state_ = kInitialState;
5473     }
5474 
VisitTwoByteString(const uint16_t * chars,int length)5475     void VisitTwoByteString(const uint16_t* chars, int length) {
5476       int utf8_length = 0;
5477       int last_character = unibrow::Utf16::kNoPreviousCharacter;
5478       for (int i = 0; i < length; i++) {
5479         uint16_t c = chars[i];
5480         utf8_length += unibrow::Utf8::Length(c, last_character);
5481         last_character = c;
5482       }
5483       utf8_length_ = utf8_length;
5484       uint8_t state = 0;
5485       if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
5486         state |= kStartsWithTrailingSurrogate;
5487       }
5488       if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
5489         state |= kEndsWithLeadingSurrogate;
5490       }
5491       state_ = state;
5492     }
5493 
VisitFlat(i::String * string,int * length,uint8_t * state)5494     static i::ConsString* VisitFlat(i::String* string,
5495                                     int* length,
5496                                     uint8_t* state) {
5497       Visitor visitor;
5498       i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
5499       *length = visitor.utf8_length_;
5500       *state = visitor.state_;
5501       return cons_string;
5502     }
5503 
5504    private:
5505     int utf8_length_;
5506     uint8_t state_;
5507     DISALLOW_COPY_AND_ASSIGN(Visitor);
5508   };
5509 
MergeLeafLeft(int * length,uint8_t * state,uint8_t leaf_state)5510   static inline void MergeLeafLeft(int* length,
5511                                    uint8_t* state,
5512                                    uint8_t leaf_state) {
5513     bool edge_surrogate = StartsWithSurrogate(leaf_state);
5514     if (!(*state & kLeftmostEdgeIsCalculated)) {
5515       DCHECK(!(*state & kLeftmostEdgeIsSurrogate));
5516       *state |= kLeftmostEdgeIsCalculated
5517           | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
5518     } else if (EndsWithSurrogate(*state) && edge_surrogate) {
5519       *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
5520     }
5521     if (EndsWithSurrogate(leaf_state)) {
5522       *state |= kEndsWithLeadingSurrogate;
5523     } else {
5524       *state &= ~kEndsWithLeadingSurrogate;
5525     }
5526   }
5527 
MergeLeafRight(int * length,uint8_t * state,uint8_t leaf_state)5528   static inline void MergeLeafRight(int* length,
5529                                     uint8_t* state,
5530                                     uint8_t leaf_state) {
5531     bool edge_surrogate = EndsWithSurrogate(leaf_state);
5532     if (!(*state & kRightmostEdgeIsCalculated)) {
5533       DCHECK(!(*state & kRightmostEdgeIsSurrogate));
5534       *state |= (kRightmostEdgeIsCalculated
5535                  | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
5536     } else if (edge_surrogate && StartsWithSurrogate(*state)) {
5537       *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
5538     }
5539     if (StartsWithSurrogate(leaf_state)) {
5540       *state |= kStartsWithTrailingSurrogate;
5541     } else {
5542       *state &= ~kStartsWithTrailingSurrogate;
5543     }
5544   }
5545 
MergeTerminal(int * length,uint8_t state,uint8_t * state_out)5546   static inline void MergeTerminal(int* length,
5547                                    uint8_t state,
5548                                    uint8_t* state_out) {
5549     DCHECK((state & kLeftmostEdgeIsCalculated) &&
5550            (state & kRightmostEdgeIsCalculated));
5551     if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
5552       *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
5553     }
5554     *state_out = kInitialState |
5555         (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
5556         (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
5557   }
5558 
Calculate(i::ConsString * current,uint8_t * state_out)5559   static int Calculate(i::ConsString* current, uint8_t* state_out) {
5560     using internal::ConsString;
5561     int total_length = 0;
5562     uint8_t state = kInitialState;
5563     while (true) {
5564       i::String* left = current->first();
5565       i::String* right = current->second();
5566       uint8_t right_leaf_state;
5567       uint8_t left_leaf_state;
5568       int leaf_length;
5569       ConsString* left_as_cons =
5570           Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
5571       if (left_as_cons == NULL) {
5572         total_length += leaf_length;
5573         MergeLeafLeft(&total_length, &state, left_leaf_state);
5574       }
5575       ConsString* right_as_cons =
5576           Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
5577       if (right_as_cons == NULL) {
5578         total_length += leaf_length;
5579         MergeLeafRight(&total_length, &state, right_leaf_state);
5580         if (left_as_cons != NULL) {
5581           // 1 Leaf node. Descend in place.
5582           current = left_as_cons;
5583           continue;
5584         } else {
5585           // Terminal node.
5586           MergeTerminal(&total_length, state, state_out);
5587           return total_length;
5588         }
5589       } else if (left_as_cons == NULL) {
5590         // 1 Leaf node. Descend in place.
5591         current = right_as_cons;
5592         continue;
5593       }
5594       // Both strings are ConsStrings.
5595       // Recurse on smallest.
5596       if (left->length() < right->length()) {
5597         total_length += Calculate(left_as_cons, &left_leaf_state);
5598         MergeLeafLeft(&total_length, &state, left_leaf_state);
5599         current = right_as_cons;
5600       } else {
5601         total_length += Calculate(right_as_cons, &right_leaf_state);
5602         MergeLeafRight(&total_length, &state, right_leaf_state);
5603         current = left_as_cons;
5604       }
5605     }
5606     UNREACHABLE();
5607     return 0;
5608   }
5609 
Calculate(i::ConsString * current)5610   static inline int Calculate(i::ConsString* current) {
5611     uint8_t state = kInitialState;
5612     return Calculate(current, &state);
5613   }
5614 
5615  private:
5616   DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
5617 };
5618 
5619 
Utf8Length(i::String * str,i::Isolate * isolate)5620 static int Utf8Length(i::String* str, i::Isolate* isolate) {
5621   int length = str->length();
5622   if (length == 0) return 0;
5623   uint8_t state;
5624   i::ConsString* cons_string =
5625       Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
5626   if (cons_string == NULL) return length;
5627   return Utf8LengthHelper::Calculate(cons_string);
5628 }
5629 
5630 
Utf8Length() const5631 int String::Utf8Length() const {
5632   i::Handle<i::String> str = Utils::OpenHandle(this);
5633   i::Isolate* isolate = str->GetIsolate();
5634   return v8::Utf8Length(*str, isolate);
5635 }
5636 
5637 
5638 class Utf8WriterVisitor {
5639  public:
Utf8WriterVisitor(char * buffer,int capacity,bool skip_capacity_check,bool replace_invalid_utf8)5640   Utf8WriterVisitor(
5641       char* buffer,
5642       int capacity,
5643       bool skip_capacity_check,
5644       bool replace_invalid_utf8)
5645     : early_termination_(false),
5646       last_character_(unibrow::Utf16::kNoPreviousCharacter),
5647       buffer_(buffer),
5648       start_(buffer),
5649       capacity_(capacity),
5650       skip_capacity_check_(capacity == -1 || skip_capacity_check),
5651       replace_invalid_utf8_(replace_invalid_utf8),
5652       utf16_chars_read_(0) {
5653   }
5654 
WriteEndCharacter(uint16_t character,int last_character,int remaining,char * const buffer,bool replace_invalid_utf8)5655   static int WriteEndCharacter(uint16_t character,
5656                                int last_character,
5657                                int remaining,
5658                                char* const buffer,
5659                                bool replace_invalid_utf8) {
5660     DCHECK_GT(remaining, 0);
5661     // We can't use a local buffer here because Encode needs to modify
5662     // previous characters in the stream.  We know, however, that
5663     // exactly one character will be advanced.
5664     if (unibrow::Utf16::IsSurrogatePair(last_character, character)) {
5665       int written = unibrow::Utf8::Encode(buffer, character, last_character,
5666                                           replace_invalid_utf8);
5667       DCHECK_EQ(written, 1);
5668       return written;
5669     }
5670     // Use a scratch buffer to check the required characters.
5671     char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5672     // Can't encode using last_character as gcc has array bounds issues.
5673     int written = unibrow::Utf8::Encode(temp_buffer, character,
5674                                         unibrow::Utf16::kNoPreviousCharacter,
5675                                         replace_invalid_utf8);
5676     // Won't fit.
5677     if (written > remaining) return 0;
5678     // Copy over the character from temp_buffer.
5679     for (int j = 0; j < written; j++) {
5680       buffer[j] = temp_buffer[j];
5681     }
5682     return written;
5683   }
5684 
5685   // Visit writes out a group of code units (chars) of a v8::String to the
5686   // internal buffer_. This is done in two phases. The first phase calculates a
5687   // pesimistic estimate (writable_length) on how many code units can be safely
5688   // written without exceeding the buffer capacity and without writing the last
5689   // code unit (it could be a lead surrogate). The estimated number of code
5690   // units is then written out in one go, and the reported byte usage is used
5691   // to correct the estimate. This is repeated until the estimate becomes <= 0
5692   // or all code units have been written out. The second phase writes out code
5693   // units until the buffer capacity is reached, would be exceeded by the next
5694   // unit, or all units have been written out.
5695   template<typename Char>
Visit(const Char * chars,const int length)5696   void Visit(const Char* chars, const int length) {
5697     DCHECK(!early_termination_);
5698     if (length == 0) return;
5699     // Copy state to stack.
5700     char* buffer = buffer_;
5701     int last_character = sizeof(Char) == 1
5702                              ? unibrow::Utf16::kNoPreviousCharacter
5703                              : last_character_;
5704     int i = 0;
5705     // Do a fast loop where there is no exit capacity check.
5706     while (true) {
5707       int fast_length;
5708       if (skip_capacity_check_) {
5709         fast_length = length;
5710       } else {
5711         int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
5712         // Need enough space to write everything but one character.
5713         STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit ==
5714                       3);
5715         int max_size_per_char =  sizeof(Char) == 1 ? 2 : 3;
5716         int writable_length =
5717             (remaining_capacity - max_size_per_char)/max_size_per_char;
5718         // Need to drop into slow loop.
5719         if (writable_length <= 0) break;
5720         fast_length = i + writable_length;
5721         if (fast_length > length) fast_length = length;
5722       }
5723       // Write the characters to the stream.
5724       if (sizeof(Char) == 1) {
5725         for (; i < fast_length; i++) {
5726           buffer += unibrow::Utf8::EncodeOneByte(
5727               buffer, static_cast<uint8_t>(*chars++));
5728           DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
5729         }
5730       } else {
5731         for (; i < fast_length; i++) {
5732           uint16_t character = *chars++;
5733           buffer += unibrow::Utf8::Encode(buffer, character, last_character,
5734                                           replace_invalid_utf8_);
5735           last_character = character;
5736           DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
5737         }
5738       }
5739       // Array is fully written. Exit.
5740       if (fast_length == length) {
5741         // Write state back out to object.
5742         last_character_ = last_character;
5743         buffer_ = buffer;
5744         utf16_chars_read_ += length;
5745         return;
5746       }
5747     }
5748     DCHECK(!skip_capacity_check_);
5749     // Slow loop. Must check capacity on each iteration.
5750     int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
5751     DCHECK_GE(remaining_capacity, 0);
5752     for (; i < length && remaining_capacity > 0; i++) {
5753       uint16_t character = *chars++;
5754       // remaining_capacity is <= 3 bytes at this point, so we do not write out
5755       // an umatched lead surrogate.
5756       if (replace_invalid_utf8_ && unibrow::Utf16::IsLeadSurrogate(character)) {
5757         early_termination_ = true;
5758         break;
5759       }
5760       int written = WriteEndCharacter(character,
5761                                       last_character,
5762                                       remaining_capacity,
5763                                       buffer,
5764                                       replace_invalid_utf8_);
5765       if (written == 0) {
5766         early_termination_ = true;
5767         break;
5768       }
5769       buffer += written;
5770       remaining_capacity -= written;
5771       last_character = character;
5772     }
5773     // Write state back out to object.
5774     last_character_ = last_character;
5775     buffer_ = buffer;
5776     utf16_chars_read_ += i;
5777   }
5778 
IsDone()5779   inline bool IsDone() {
5780     return early_termination_;
5781   }
5782 
VisitOneByteString(const uint8_t * chars,int length)5783   inline void VisitOneByteString(const uint8_t* chars, int length) {
5784     Visit(chars, length);
5785   }
5786 
VisitTwoByteString(const uint16_t * chars,int length)5787   inline void VisitTwoByteString(const uint16_t* chars, int length) {
5788     Visit(chars, length);
5789   }
5790 
CompleteWrite(bool write_null,int * utf16_chars_read_out)5791   int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
5792     // Write out number of utf16 characters written to the stream.
5793     if (utf16_chars_read_out != NULL) {
5794       *utf16_chars_read_out = utf16_chars_read_;
5795     }
5796     // Only null terminate if all of the string was written and there's space.
5797     if (write_null &&
5798         !early_termination_ &&
5799         (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
5800       *buffer_++ = '\0';
5801     }
5802     return static_cast<int>(buffer_ - start_);
5803   }
5804 
5805  private:
5806   bool early_termination_;
5807   int last_character_;
5808   char* buffer_;
5809   char* const start_;
5810   int capacity_;
5811   bool const skip_capacity_check_;
5812   bool const replace_invalid_utf8_;
5813   int utf16_chars_read_;
5814   DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
5815 };
5816 
5817 
RecursivelySerializeToUtf8(i::String * current,Utf8WriterVisitor * writer,int recursion_budget)5818 static bool RecursivelySerializeToUtf8(i::String* current,
5819                                        Utf8WriterVisitor* writer,
5820                                        int recursion_budget) {
5821   while (!writer->IsDone()) {
5822     i::ConsString* cons_string = i::String::VisitFlat(writer, current);
5823     if (cons_string == NULL) return true;  // Leaf node.
5824     if (recursion_budget <= 0) return false;
5825     // Must write the left branch first.
5826     i::String* first = cons_string->first();
5827     bool success = RecursivelySerializeToUtf8(first,
5828                                               writer,
5829                                               recursion_budget - 1);
5830     if (!success) return false;
5831     // Inline tail recurse for right branch.
5832     current = cons_string->second();
5833   }
5834   return true;
5835 }
5836 
5837 
WriteUtf8(char * buffer,int capacity,int * nchars_ref,int options) const5838 int String::WriteUtf8(char* buffer,
5839                       int capacity,
5840                       int* nchars_ref,
5841                       int options) const {
5842   i::Handle<i::String> str = Utils::OpenHandle(this);
5843   i::Isolate* isolate = str->GetIsolate();
5844   LOG_API(isolate, String, WriteUtf8);
5845   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5846   if (options & HINT_MANY_WRITES_EXPECTED) {
5847     str = i::String::Flatten(str);  // Flatten the string for efficiency.
5848   }
5849   const int string_length = str->length();
5850   bool write_null = !(options & NO_NULL_TERMINATION);
5851   bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
5852   int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
5853   // First check if we can just write the string without checking capacity.
5854   if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
5855     Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
5856     const int kMaxRecursion = 100;
5857     bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
5858     if (success) return writer.CompleteWrite(write_null, nchars_ref);
5859   } else if (capacity >= string_length) {
5860     // First check that the buffer is large enough.
5861     int utf8_bytes = v8::Utf8Length(*str, isolate);
5862     if (utf8_bytes <= capacity) {
5863       // one-byte fast path.
5864       if (utf8_bytes == string_length) {
5865         WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
5866         if (nchars_ref != NULL) *nchars_ref = string_length;
5867         if (write_null && (utf8_bytes+1 <= capacity)) {
5868           return string_length + 1;
5869         }
5870         return string_length;
5871       }
5872       if (write_null && (utf8_bytes+1 > capacity)) {
5873         options |= NO_NULL_TERMINATION;
5874       }
5875       // Recurse once without a capacity limit.
5876       // This will get into the first branch above.
5877       // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
5878       return WriteUtf8(buffer, -1, nchars_ref, options);
5879     }
5880   }
5881   // Recursive slow path can potentially be unreasonable slow. Flatten.
5882   str = i::String::Flatten(str);
5883   Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
5884   i::String::VisitFlat(&writer, *str);
5885   return writer.CompleteWrite(write_null, nchars_ref);
5886 }
5887 
5888 
5889 template<typename CharType>
WriteHelper(const String * string,CharType * buffer,int start,int length,int options)5890 static inline int WriteHelper(const String* string,
5891                               CharType* buffer,
5892                               int start,
5893                               int length,
5894                               int options) {
5895   i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
5896   LOG_API(isolate, String, Write);
5897   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5898   DCHECK(start >= 0 && length >= -1);
5899   i::Handle<i::String> str = Utils::OpenHandle(string);
5900   if (options & String::HINT_MANY_WRITES_EXPECTED) {
5901     // Flatten the string for efficiency.  This applies whether we are
5902     // using StringCharacterStream or Get(i) to access the characters.
5903     str = i::String::Flatten(str);
5904   }
5905   int end = start + length;
5906   if ((length == -1) || (length > str->length() - start) )
5907     end = str->length();
5908   if (end < 0) return 0;
5909   i::String::WriteToFlat(*str, buffer, start, end);
5910   if (!(options & String::NO_NULL_TERMINATION) &&
5911       (length == -1 || end - start < length)) {
5912     buffer[end - start] = '\0';
5913   }
5914   return end - start;
5915 }
5916 
5917 
WriteOneByte(uint8_t * buffer,int start,int length,int options) const5918 int String::WriteOneByte(uint8_t* buffer,
5919                          int start,
5920                          int length,
5921                          int options) const {
5922   return WriteHelper(this, buffer, start, length, options);
5923 }
5924 
5925 
Write(uint16_t * buffer,int start,int length,int options) const5926 int String::Write(uint16_t* buffer,
5927                   int start,
5928                   int length,
5929                   int options) const {
5930   return WriteHelper(this, buffer, start, length, options);
5931 }
5932 
5933 
IsExternal() const5934 bool v8::String::IsExternal() const {
5935   i::Handle<i::String> str = Utils::OpenHandle(this);
5936   return i::StringShape(*str).IsExternalTwoByte();
5937 }
5938 
5939 
IsExternalOneByte() const5940 bool v8::String::IsExternalOneByte() const {
5941   i::Handle<i::String> str = Utils::OpenHandle(this);
5942   return i::StringShape(*str).IsExternalOneByte();
5943 }
5944 
5945 
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const5946 void v8::String::VerifyExternalStringResource(
5947     v8::String::ExternalStringResource* value) const {
5948   i::Handle<i::String> str = Utils::OpenHandle(this);
5949   const v8::String::ExternalStringResource* expected;
5950   if (i::StringShape(*str).IsExternalTwoByte()) {
5951     const void* resource =
5952         i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
5953     expected = reinterpret_cast<const ExternalStringResource*>(resource);
5954   } else {
5955     expected = NULL;
5956   }
5957   CHECK_EQ(expected, value);
5958 }
5959 
VerifyExternalStringResourceBase(v8::String::ExternalStringResourceBase * value,Encoding encoding) const5960 void v8::String::VerifyExternalStringResourceBase(
5961     v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5962   i::Handle<i::String> str = Utils::OpenHandle(this);
5963   const v8::String::ExternalStringResourceBase* expected;
5964   Encoding expectedEncoding;
5965   if (i::StringShape(*str).IsExternalOneByte()) {
5966     const void* resource =
5967         i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5968     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5969     expectedEncoding = ONE_BYTE_ENCODING;
5970   } else if (i::StringShape(*str).IsExternalTwoByte()) {
5971     const void* resource =
5972         i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
5973     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5974     expectedEncoding = TWO_BYTE_ENCODING;
5975   } else {
5976     expected = NULL;
5977     expectedEncoding =
5978         str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5979   }
5980   CHECK_EQ(expected, value);
5981   CHECK_EQ(expectedEncoding, encoding);
5982 }
5983 
5984 const v8::String::ExternalOneByteStringResource*
GetExternalOneByteStringResource() const5985 v8::String::GetExternalOneByteStringResource() const {
5986   i::Handle<i::String> str = Utils::OpenHandle(this);
5987   if (i::StringShape(*str).IsExternalOneByte()) {
5988     const void* resource =
5989         i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5990     return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
5991   } else {
5992     return NULL;
5993   }
5994 }
5995 
5996 
Name() const5997 Local<Value> Symbol::Name() const {
5998   i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5999   i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
6000   return Utils::ToLocal(name);
6001 }
6002 
6003 
Name() const6004 Local<Value> Private::Name() const {
6005   return reinterpret_cast<const Symbol*>(this)->Name();
6006 }
6007 
6008 
Value() const6009 double Number::Value() const {
6010   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6011   return obj->Number();
6012 }
6013 
6014 
Value() const6015 bool Boolean::Value() const {
6016   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6017   return obj->IsTrue(i::HeapObject::cast(*obj)->GetIsolate());
6018 }
6019 
6020 
Value() const6021 int64_t Integer::Value() const {
6022   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6023   if (obj->IsSmi()) {
6024     return i::Smi::cast(*obj)->value();
6025   } else {
6026     return static_cast<int64_t>(obj->Number());
6027   }
6028 }
6029 
6030 
Value() const6031 int32_t Int32::Value() const {
6032   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6033   if (obj->IsSmi()) {
6034     return i::Smi::cast(*obj)->value();
6035   } else {
6036     return static_cast<int32_t>(obj->Number());
6037   }
6038 }
6039 
6040 
Value() const6041 uint32_t Uint32::Value() const {
6042   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6043   if (obj->IsSmi()) {
6044     return i::Smi::cast(*obj)->value();
6045   } else {
6046     return static_cast<uint32_t>(obj->Number());
6047   }
6048 }
6049 
6050 
InternalFieldCount()6051 int v8::Object::InternalFieldCount() {
6052   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
6053   if (!self->IsJSObject()) return 0;
6054   return i::Handle<i::JSObject>::cast(self)->GetInternalFieldCount();
6055 }
6056 
6057 
InternalFieldOK(i::Handle<i::JSReceiver> obj,int index,const char * location)6058 static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
6059                             const char* location) {
6060   return Utils::ApiCheck(
6061       obj->IsJSObject() &&
6062           (index < i::Handle<i::JSObject>::cast(obj)->GetInternalFieldCount()),
6063       location, "Internal field out of bounds");
6064 }
6065 
6066 
SlowGetInternalField(int index)6067 Local<Value> v8::Object::SlowGetInternalField(int index) {
6068   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6069   const char* location = "v8::Object::GetInternalField()";
6070   if (!InternalFieldOK(obj, index, location)) return Local<Value>();
6071   i::Handle<i::Object> value(
6072       i::Handle<i::JSObject>::cast(obj)->GetInternalField(index),
6073       obj->GetIsolate());
6074   return Utils::ToLocal(value);
6075 }
6076 
6077 
SetInternalField(int index,v8::Local<Value> value)6078 void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
6079   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6080   const char* location = "v8::Object::SetInternalField()";
6081   if (!InternalFieldOK(obj, index, location)) return;
6082   i::Handle<i::Object> val = Utils::OpenHandle(*value);
6083   i::Handle<i::JSObject>::cast(obj)->SetInternalField(index, *val);
6084 }
6085 
6086 
SlowGetAlignedPointerFromInternalField(int index)6087 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
6088   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6089   const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
6090   if (!InternalFieldOK(obj, index, location)) return NULL;
6091   return DecodeSmiToAligned(
6092       i::Handle<i::JSObject>::cast(obj)->GetInternalField(index), location);
6093 }
6094 
SetAlignedPointerInInternalField(int index,void * value)6095 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
6096   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6097   const char* location = "v8::Object::SetAlignedPointerInInternalField()";
6098   if (!InternalFieldOK(obj, index, location)) return;
6099   i::Handle<i::JSObject>::cast(obj)
6100       ->SetInternalField(index, EncodeAlignedAsSmi(value, location));
6101   DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6102 }
6103 
SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])6104 void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
6105                                                    void* values[]) {
6106   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6107   const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
6108   i::DisallowHeapAllocation no_gc;
6109   i::JSObject* object = i::JSObject::cast(*obj);
6110   int nof_internal_fields = object->GetInternalFieldCount();
6111   for (int i = 0; i < argc; i++) {
6112     int index = indices[i];
6113     if (!Utils::ApiCheck(index < nof_internal_fields, location,
6114                          "Internal field out of bounds")) {
6115       return;
6116     }
6117     void* value = values[i];
6118     object->SetInternalField(index, EncodeAlignedAsSmi(value, location));
6119     DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6120   }
6121 }
6122 
ExternalValue(i::Object * obj)6123 static void* ExternalValue(i::Object* obj) {
6124   // Obscure semantics for undefined, but somehow checked in our unit tests...
6125   if (!obj->IsSmi() &&
6126       obj->IsUndefined(i::HeapObject::cast(obj)->GetIsolate())) {
6127     return NULL;
6128   }
6129   i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
6130   return i::Foreign::cast(foreign)->foreign_address();
6131 }
6132 
6133 
6134 // --- E n v i r o n m e n t ---
6135 
6136 
InitializePlatform(Platform * platform)6137 void v8::V8::InitializePlatform(Platform* platform) {
6138   i::V8::InitializePlatform(platform);
6139 }
6140 
6141 
ShutdownPlatform()6142 void v8::V8::ShutdownPlatform() {
6143   i::V8::ShutdownPlatform();
6144 }
6145 
6146 
Initialize()6147 bool v8::V8::Initialize() {
6148   i::V8::Initialize();
6149 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
6150   i::ReadNatives();
6151 #endif
6152   return true;
6153 }
6154 
6155 
SetEntropySource(EntropySource entropy_source)6156 void v8::V8::SetEntropySource(EntropySource entropy_source) {
6157   base::RandomNumberGenerator::SetEntropySource(entropy_source);
6158 }
6159 
6160 
SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)6161 void v8::V8::SetReturnAddressLocationResolver(
6162     ReturnAddressLocationResolver return_address_resolver) {
6163   i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6164 }
6165 
6166 
Dispose()6167 bool v8::V8::Dispose() {
6168   i::V8::TearDown();
6169 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
6170   i::DisposeNatives();
6171 #endif
6172   return true;
6173 }
6174 
HeapStatistics()6175 HeapStatistics::HeapStatistics()
6176     : total_heap_size_(0),
6177       total_heap_size_executable_(0),
6178       total_physical_size_(0),
6179       total_available_size_(0),
6180       used_heap_size_(0),
6181       heap_size_limit_(0),
6182       malloced_memory_(0),
6183       peak_malloced_memory_(0),
6184       does_zap_garbage_(0) {}
6185 
HeapSpaceStatistics()6186 HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
6187                                             space_size_(0),
6188                                             space_used_size_(0),
6189                                             space_available_size_(0),
6190                                             physical_space_size_(0) { }
6191 
6192 
HeapObjectStatistics()6193 HeapObjectStatistics::HeapObjectStatistics()
6194     : object_type_(nullptr),
6195       object_sub_type_(nullptr),
6196       object_count_(0),
6197       object_size_(0) {}
6198 
HeapCodeStatistics()6199 HeapCodeStatistics::HeapCodeStatistics()
6200     : code_and_metadata_size_(0), bytecode_and_metadata_size_(0) {}
6201 
InitializeICU(const char * icu_data_file)6202 bool v8::V8::InitializeICU(const char* icu_data_file) {
6203   return i::InitializeICU(icu_data_file);
6204 }
6205 
InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)6206 bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6207                                           const char* icu_data_file) {
6208   return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6209 }
6210 
InitializeExternalStartupData(const char * directory_path)6211 void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6212   i::InitializeExternalStartupData(directory_path);
6213 }
6214 
6215 
InitializeExternalStartupData(const char * natives_blob,const char * snapshot_blob)6216 void v8::V8::InitializeExternalStartupData(const char* natives_blob,
6217                                            const char* snapshot_blob) {
6218   i::InitializeExternalStartupData(natives_blob, snapshot_blob);
6219 }
6220 
6221 
GetVersion()6222 const char* v8::V8::GetVersion() {
6223   return i::Version::GetVersion();
6224 }
6225 
6226 template <typename ObjectType>
6227 struct InvokeBootstrapper;
6228 
6229 template <>
6230 struct InvokeBootstrapper<i::Context> {
Invokev8::InvokeBootstrapper6231   i::Handle<i::Context> Invoke(
6232       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6233       v8::Local<v8::ObjectTemplate> global_object_template,
6234       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6235       v8::DeserializeInternalFieldsCallback internal_fields_deserializer) {
6236     return isolate->bootstrapper()->CreateEnvironment(
6237         maybe_global_proxy, global_object_template, extensions,
6238         context_snapshot_index, internal_fields_deserializer);
6239   }
6240 };
6241 
6242 template <>
6243 struct InvokeBootstrapper<i::JSGlobalProxy> {
Invokev8::InvokeBootstrapper6244   i::Handle<i::JSGlobalProxy> Invoke(
6245       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6246       v8::Local<v8::ObjectTemplate> global_object_template,
6247       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6248       v8::DeserializeInternalFieldsCallback internal_fields_deserializer) {
6249     USE(extensions);
6250     USE(context_snapshot_index);
6251     return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
6252                                                      global_object_template);
6253   }
6254 };
6255 
6256 template <typename ObjectType>
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 internal_fields_deserializer)6257 static i::Handle<ObjectType> CreateEnvironment(
6258     i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
6259     v8::MaybeLocal<ObjectTemplate> maybe_global_template,
6260     v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
6261     v8::DeserializeInternalFieldsCallback internal_fields_deserializer) {
6262   i::Handle<ObjectType> result;
6263 
6264   {
6265     ENTER_V8_FOR_NEW_CONTEXT(isolate);
6266     v8::Local<ObjectTemplate> proxy_template;
6267     i::Handle<i::FunctionTemplateInfo> proxy_constructor;
6268     i::Handle<i::FunctionTemplateInfo> global_constructor;
6269     i::Handle<i::Object> named_interceptor(
6270         isolate->factory()->undefined_value());
6271     i::Handle<i::Object> indexed_interceptor(
6272         isolate->factory()->undefined_value());
6273 
6274     if (!maybe_global_template.IsEmpty()) {
6275       v8::Local<v8::ObjectTemplate> global_template =
6276           maybe_global_template.ToLocalChecked();
6277       // Make sure that the global_template has a constructor.
6278       global_constructor = EnsureConstructor(isolate, *global_template);
6279 
6280       // Create a fresh template for the global proxy object.
6281       proxy_template = ObjectTemplate::New(
6282           reinterpret_cast<v8::Isolate*>(isolate));
6283       proxy_constructor = EnsureConstructor(isolate, *proxy_template);
6284 
6285       // Set the global template to be the prototype template of
6286       // global proxy template.
6287       proxy_constructor->set_prototype_template(
6288           *Utils::OpenHandle(*global_template));
6289 
6290       proxy_template->SetInternalFieldCount(
6291           global_template->InternalFieldCount());
6292 
6293       // Migrate security handlers from global_template to
6294       // proxy_template.  Temporarily removing access check
6295       // information from the global template.
6296       if (!global_constructor->access_check_info()->IsUndefined(isolate)) {
6297         proxy_constructor->set_access_check_info(
6298             global_constructor->access_check_info());
6299         proxy_constructor->set_needs_access_check(
6300             global_constructor->needs_access_check());
6301         global_constructor->set_needs_access_check(false);
6302         global_constructor->set_access_check_info(
6303             isolate->heap()->undefined_value());
6304       }
6305 
6306       // Same for other interceptors. If the global constructor has
6307       // interceptors, we need to replace them temporarily with noop
6308       // interceptors, so the map is correctly marked as having interceptors,
6309       // but we don't invoke any.
6310       if (!global_constructor->named_property_handler()->IsUndefined(isolate)) {
6311         named_interceptor =
6312             handle(global_constructor->named_property_handler(), isolate);
6313         global_constructor->set_named_property_handler(
6314             isolate->heap()->noop_interceptor_info());
6315       }
6316       if (!global_constructor->indexed_property_handler()->IsUndefined(
6317               isolate)) {
6318         indexed_interceptor =
6319             handle(global_constructor->indexed_property_handler(), isolate);
6320         global_constructor->set_indexed_property_handler(
6321             isolate->heap()->noop_interceptor_info());
6322       }
6323     }
6324 
6325     i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6326     if (!maybe_global_proxy.IsEmpty()) {
6327       maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6328           Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6329     }
6330     // Create the environment.
6331     InvokeBootstrapper<ObjectType> invoke;
6332     result =
6333         invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6334                       context_snapshot_index, internal_fields_deserializer);
6335 
6336     // Restore the access check info and interceptors on the global template.
6337     if (!maybe_global_template.IsEmpty()) {
6338       DCHECK(!global_constructor.is_null());
6339       DCHECK(!proxy_constructor.is_null());
6340       global_constructor->set_access_check_info(
6341           proxy_constructor->access_check_info());
6342       global_constructor->set_needs_access_check(
6343           proxy_constructor->needs_access_check());
6344       global_constructor->set_named_property_handler(*named_interceptor);
6345       global_constructor->set_indexed_property_handler(*indexed_interceptor);
6346     }
6347   }
6348   // Leave V8.
6349 
6350   return result;
6351 }
6352 
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 internal_fields_deserializer)6353 Local<Context> NewContext(
6354     v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6355     v8::MaybeLocal<ObjectTemplate> global_template,
6356     v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6357     v8::DeserializeInternalFieldsCallback internal_fields_deserializer) {
6358   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6359   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6360   LOG_API(isolate, Context, New);
6361   i::HandleScope scope(isolate);
6362   ExtensionConfiguration no_extensions;
6363   if (extensions == NULL) extensions = &no_extensions;
6364   i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6365       isolate, extensions, global_template, global_object,
6366       context_snapshot_index, internal_fields_deserializer);
6367   if (env.is_null()) {
6368     if (isolate->has_pending_exception()) {
6369       isolate->OptionalRescheduleException(true);
6370     }
6371     return Local<Context>();
6372   }
6373   return Utils::ToLocal(scope.CloseAndEscape(env));
6374 }
6375 
New(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object)6376 Local<Context> v8::Context::New(v8::Isolate* external_isolate,
6377                                 v8::ExtensionConfiguration* extensions,
6378                                 v8::MaybeLocal<ObjectTemplate> global_template,
6379                                 v8::MaybeLocal<Value> global_object) {
6380   return NewContext(external_isolate, extensions, global_template,
6381                     global_object, 0, DeserializeInternalFieldsCallback());
6382 }
6383 
FromSnapshot(v8::Isolate * external_isolate,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback internal_fields_deserializer,v8::ExtensionConfiguration * extensions,MaybeLocal<Value> global_object)6384 MaybeLocal<Context> v8::Context::FromSnapshot(
6385     v8::Isolate* external_isolate, size_t context_snapshot_index,
6386     v8::DeserializeInternalFieldsCallback internal_fields_deserializer,
6387     v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object) {
6388   size_t index_including_default_context = context_snapshot_index + 1;
6389   if (!i::Snapshot::HasContextSnapshot(
6390           reinterpret_cast<i::Isolate*>(external_isolate),
6391           index_including_default_context)) {
6392     return MaybeLocal<Context>();
6393   }
6394   return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6395                     global_object, index_including_default_context,
6396                     internal_fields_deserializer);
6397 }
6398 
NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6399 MaybeLocal<Object> v8::Context::NewRemoteContext(
6400     v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6401     v8::MaybeLocal<v8::Value> global_object) {
6402   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6403   LOG_API(isolate, Context, NewRemoteContext);
6404   i::HandleScope scope(isolate);
6405   i::Handle<i::FunctionTemplateInfo> global_constructor =
6406       EnsureConstructor(isolate, *global_template);
6407   Utils::ApiCheck(global_constructor->needs_access_check(),
6408                   "v8::Context::NewRemoteContext",
6409                   "Global template needs to have access checks enabled.");
6410   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6411       i::AccessCheckInfo::cast(global_constructor->access_check_info()),
6412       isolate);
6413   Utils::ApiCheck(access_check_info->named_interceptor() != nullptr,
6414                   "v8::Context::NewRemoteContext",
6415                   "Global template needs to have access check handlers.");
6416   i::Handle<i::JSGlobalProxy> global_proxy =
6417       CreateEnvironment<i::JSGlobalProxy>(isolate, nullptr, global_template,
6418                                           global_object, 0,
6419                                           DeserializeInternalFieldsCallback());
6420   if (global_proxy.is_null()) {
6421     if (isolate->has_pending_exception()) {
6422       isolate->OptionalRescheduleException(true);
6423     }
6424     return MaybeLocal<Object>();
6425   }
6426   return Utils::ToLocal(
6427       scope.CloseAndEscape(i::Handle<i::JSObject>::cast(global_proxy)));
6428 }
6429 
SetSecurityToken(Local<Value> token)6430 void v8::Context::SetSecurityToken(Local<Value> token) {
6431   i::Handle<i::Context> env = Utils::OpenHandle(this);
6432   i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6433   env->set_security_token(*token_handle);
6434 }
6435 
6436 
UseDefaultSecurityToken()6437 void v8::Context::UseDefaultSecurityToken() {
6438   i::Handle<i::Context> env = Utils::OpenHandle(this);
6439   env->set_security_token(env->global_object());
6440 }
6441 
6442 
GetSecurityToken()6443 Local<Value> v8::Context::GetSecurityToken() {
6444   i::Handle<i::Context> env = Utils::OpenHandle(this);
6445   i::Isolate* isolate = env->GetIsolate();
6446   i::Object* security_token = env->security_token();
6447   i::Handle<i::Object> token_handle(security_token, isolate);
6448   return Utils::ToLocal(token_handle);
6449 }
6450 
6451 
GetIsolate()6452 v8::Isolate* Context::GetIsolate() {
6453   i::Handle<i::Context> env = Utils::OpenHandle(this);
6454   return reinterpret_cast<Isolate*>(env->GetIsolate());
6455 }
6456 
Global()6457 v8::Local<v8::Object> Context::Global() {
6458   i::Handle<i::Context> context = Utils::OpenHandle(this);
6459   i::Isolate* isolate = context->GetIsolate();
6460   i::Handle<i::Object> global(context->global_proxy(), isolate);
6461   // TODO(dcarney): This should always return the global proxy
6462   // but can't presently as calls to GetProtoype will return the wrong result.
6463   if (i::Handle<i::JSGlobalProxy>::cast(
6464           global)->IsDetachedFrom(context->global_object())) {
6465     global = i::Handle<i::Object>(context->global_object(), isolate);
6466   }
6467   return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6468 }
6469 
6470 
DetachGlobal()6471 void Context::DetachGlobal() {
6472   i::Handle<i::Context> context = Utils::OpenHandle(this);
6473   i::Isolate* isolate = context->GetIsolate();
6474   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6475   isolate->bootstrapper()->DetachGlobal(context);
6476 }
6477 
6478 
GetExtrasBindingObject()6479 Local<v8::Object> Context::GetExtrasBindingObject() {
6480   i::Handle<i::Context> context = Utils::OpenHandle(this);
6481   i::Isolate* isolate = context->GetIsolate();
6482   i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6483   return Utils::ToLocal(binding);
6484 }
6485 
6486 
AllowCodeGenerationFromStrings(bool allow)6487 void Context::AllowCodeGenerationFromStrings(bool allow) {
6488   i::Handle<i::Context> context = Utils::OpenHandle(this);
6489   i::Isolate* isolate = context->GetIsolate();
6490   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6491   context->set_allow_code_gen_from_strings(
6492       allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
6493 }
6494 
6495 
IsCodeGenerationFromStringsAllowed()6496 bool Context::IsCodeGenerationFromStringsAllowed() {
6497   i::Handle<i::Context> context = Utils::OpenHandle(this);
6498   return !context->allow_code_gen_from_strings()->IsFalse(
6499       context->GetIsolate());
6500 }
6501 
6502 
SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6503 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6504   i::Handle<i::Context> context = Utils::OpenHandle(this);
6505   i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6506   context->set_error_message_for_code_gen_from_strings(*error_handle);
6507 }
6508 
6509 
EstimatedSize()6510 size_t Context::EstimatedSize() {
6511   return static_cast<size_t>(
6512       i::ContextMeasure(*Utils::OpenHandle(this)).Size());
6513 }
6514 
6515 
NewInstance(Local<Context> context)6516 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6517   PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6518   auto self = Utils::OpenHandle(this);
6519   Local<Object> result;
6520   has_pending_exception =
6521       !ToLocal<Object>(i::ApiNatives::InstantiateObject(self), &result);
6522   RETURN_ON_FAILED_EXECUTION(Object);
6523   RETURN_ESCAPED(result);
6524 }
6525 
6526 
NewInstance()6527 Local<v8::Object> ObjectTemplate::NewInstance() {
6528   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6529   RETURN_TO_LOCAL_UNCHECKED(NewInstance(context), Object);
6530 }
6531 
6532 
GetFunction(Local<Context> context)6533 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6534   PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6535   auto self = Utils::OpenHandle(this);
6536   Local<Function> result;
6537   has_pending_exception =
6538       !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6539   RETURN_ON_FAILED_EXECUTION(Function);
6540   RETURN_ESCAPED(result);
6541 }
6542 
6543 
GetFunction()6544 Local<v8::Function> FunctionTemplate::GetFunction() {
6545   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6546   RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function);
6547 }
6548 
NewRemoteInstance()6549 MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6550   auto self = Utils::OpenHandle(this);
6551   i::Isolate* isolate = self->GetIsolate();
6552   LOG_API(isolate, FunctionTemplate, NewRemoteInstance);
6553   i::HandleScope scope(isolate);
6554   i::Handle<i::FunctionTemplateInfo> constructor =
6555       EnsureConstructor(isolate, *InstanceTemplate());
6556   Utils::ApiCheck(constructor->needs_access_check(),
6557                   "v8::FunctionTemplate::NewRemoteInstance",
6558                   "InstanceTemplate needs to have access checks enabled.");
6559   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6560       i::AccessCheckInfo::cast(constructor->access_check_info()), isolate);
6561   Utils::ApiCheck(access_check_info->named_interceptor() != nullptr,
6562                   "v8::FunctionTemplate::NewRemoteInstance",
6563                   "InstanceTemplate needs to have access check handlers.");
6564   i::Handle<i::JSObject> object;
6565   if (!i::ApiNatives::InstantiateRemoteObject(
6566            Utils::OpenHandle(*InstanceTemplate()))
6567            .ToHandle(&object)) {
6568     if (isolate->has_pending_exception()) {
6569       isolate->OptionalRescheduleException(true);
6570     }
6571     return MaybeLocal<Object>();
6572   }
6573   return Utils::ToLocal(scope.CloseAndEscape(object));
6574 }
6575 
HasInstance(v8::Local<v8::Value> value)6576 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6577   auto self = Utils::OpenHandle(this);
6578   auto obj = Utils::OpenHandle(*value);
6579   if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6580     return true;
6581   }
6582   if (obj->IsJSGlobalProxy()) {
6583     // If it's a global proxy, then test with the global object. Note that the
6584     // inner global object may not necessarily be a JSGlobalObject.
6585     i::PrototypeIterator iter(i::JSObject::cast(*obj)->map());
6586     // The global proxy should always have a prototype, as it is a bug to call
6587     // this on a detached JSGlobalProxy.
6588     DCHECK(!iter.IsAtEnd());
6589     return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6590   }
6591   return false;
6592 }
6593 
6594 
New(Isolate * isolate,void * value)6595 Local<External> v8::External::New(Isolate* isolate, void* value) {
6596   STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6597   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6598   LOG_API(i_isolate, External, New);
6599   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6600   i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6601   return Utils::ExternalToLocal(external);
6602 }
6603 
6604 
Value() const6605 void* External::Value() const {
6606   return ExternalValue(*Utils::OpenHandle(this));
6607 }
6608 
6609 
6610 // anonymous namespace for string creation helper functions
6611 namespace {
6612 
StringLength(const char * string)6613 inline int StringLength(const char* string) {
6614   return i::StrLength(string);
6615 }
6616 
6617 
StringLength(const uint8_t * string)6618 inline int StringLength(const uint8_t* string) {
6619   return i::StrLength(reinterpret_cast<const char*>(string));
6620 }
6621 
6622 
StringLength(const uint16_t * string)6623 inline int StringLength(const uint16_t* string) {
6624   int length = 0;
6625   while (string[length] != '\0')
6626     length++;
6627   return length;
6628 }
6629 
6630 
6631 MUST_USE_RESULT
NewString(i::Factory * factory,v8::NewStringType type,i::Vector<const char> string)6632 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6633                                            v8::NewStringType type,
6634                                            i::Vector<const char> string) {
6635   if (type == v8::NewStringType::kInternalized) {
6636     return factory->InternalizeUtf8String(string);
6637   }
6638   return factory->NewStringFromUtf8(string);
6639 }
6640 
6641 
6642 MUST_USE_RESULT
NewString(i::Factory * factory,v8::NewStringType type,i::Vector<const uint8_t> string)6643 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6644                                            v8::NewStringType type,
6645                                            i::Vector<const uint8_t> string) {
6646   if (type == v8::NewStringType::kInternalized) {
6647     return factory->InternalizeOneByteString(string);
6648   }
6649   return factory->NewStringFromOneByte(string);
6650 }
6651 
6652 
6653 MUST_USE_RESULT
NewString(i::Factory * factory,v8::NewStringType type,i::Vector<const uint16_t> string)6654 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6655                                            v8::NewStringType type,
6656                                            i::Vector<const uint16_t> string) {
6657   if (type == v8::NewStringType::kInternalized) {
6658     return factory->InternalizeTwoByteString(string);
6659   }
6660   return factory->NewStringFromTwoByte(string);
6661 }
6662 
6663 
6664 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6665 
6666 }  // anonymous namespace
6667 
6668 // TODO(dcarney): throw a context free exception.
6669 #define NEW_STRING(isolate, class_name, function_name, Char, data, type,   \
6670                    length)                                                 \
6671   MaybeLocal<String> result;                                               \
6672   if (length == 0) {                                                       \
6673     result = String::Empty(isolate);                                       \
6674   } else if (length > i::String::kMaxLength) {                             \
6675     result = MaybeLocal<String>();                                         \
6676   } else {                                                                 \
6677     i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6678     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);                            \
6679     LOG_API(i_isolate, class_name, function_name);                         \
6680     if (length < 0) length = StringLength(data);                           \
6681     i::Handle<i::String> handle_result =                                   \
6682         NewString(i_isolate->factory(), type,                              \
6683                   i::Vector<const Char>(data, length))                     \
6684             .ToHandleChecked();                                            \
6685     result = Utils::ToLocal(handle_result);                                \
6686   }
6687 
NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6688 Local<String> String::NewFromUtf8(Isolate* isolate,
6689                                   const char* data,
6690                                   NewStringType type,
6691                                   int length) {
6692   NEW_STRING(isolate, String, NewFromUtf8, char, data,
6693              static_cast<v8::NewStringType>(type), length);
6694   RETURN_TO_LOCAL_UNCHECKED(result, String);
6695 }
6696 
6697 
NewFromUtf8(Isolate * isolate,const char * data,v8::NewStringType type,int length)6698 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
6699                                        v8::NewStringType type, int length) {
6700   NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
6701   return result;
6702 }
6703 
6704 
NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6705 Local<String> String::NewFromOneByte(Isolate* isolate,
6706                                      const uint8_t* data,
6707                                      NewStringType type,
6708                                      int length) {
6709   NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data,
6710              static_cast<v8::NewStringType>(type), length);
6711   RETURN_TO_LOCAL_UNCHECKED(result, String);
6712 }
6713 
6714 
NewFromOneByte(Isolate * isolate,const uint8_t * data,v8::NewStringType type,int length)6715 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
6716                                           v8::NewStringType type, int length) {
6717   NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
6718   return result;
6719 }
6720 
6721 
NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6722 Local<String> String::NewFromTwoByte(Isolate* isolate,
6723                                      const uint16_t* data,
6724                                      NewStringType type,
6725                                      int length) {
6726   NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data,
6727              static_cast<v8::NewStringType>(type), length);
6728   RETURN_TO_LOCAL_UNCHECKED(result, String);
6729 }
6730 
6731 
NewFromTwoByte(Isolate * isolate,const uint16_t * data,v8::NewStringType type,int length)6732 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
6733                                           const uint16_t* data,
6734                                           v8::NewStringType type, int length) {
6735   NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
6736   return result;
6737 }
6738 
6739 
Concat(Local<String> left,Local<String> right)6740 Local<String> v8::String::Concat(Local<String> left, Local<String> right) {
6741   i::Handle<i::String> left_string = Utils::OpenHandle(*left);
6742   i::Isolate* isolate = left_string->GetIsolate();
6743   ENTER_V8(isolate);
6744   LOG_API(isolate, String, Concat);
6745   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
6746   // If we are steering towards a range error, do not wait for the error to be
6747   // thrown, and return the null handle instead.
6748   if (left_string->length() + right_string->length() > i::String::kMaxLength) {
6749     return Local<String>();
6750   }
6751   i::Handle<i::String> result = isolate->factory()->NewConsString(
6752       left_string, right_string).ToHandleChecked();
6753   return Utils::ToLocal(result);
6754 }
6755 
6756 
NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6757 MaybeLocal<String> v8::String::NewExternalTwoByte(
6758     Isolate* isolate, v8::String::ExternalStringResource* resource) {
6759   CHECK(resource && resource->data());
6760   // TODO(dcarney): throw a context free exception.
6761   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6762     return MaybeLocal<String>();
6763   }
6764   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6765   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6766   LOG_API(i_isolate, String, NewExternalTwoByte);
6767   if (resource->length() > 0) {
6768     i::Handle<i::String> string = i_isolate->factory()
6769                                       ->NewExternalStringFromTwoByte(resource)
6770                                       .ToHandleChecked();
6771     i_isolate->heap()->RegisterExternalString(*string);
6772     return Utils::ToLocal(string);
6773   } else {
6774     // The resource isn't going to be used, free it immediately.
6775     resource->Dispose();
6776     return Utils::ToLocal(i_isolate->factory()->empty_string());
6777   }
6778 }
6779 
6780 
NewExternal(Isolate * isolate,v8::String::ExternalStringResource * resource)6781 Local<String> v8::String::NewExternal(
6782     Isolate* isolate, v8::String::ExternalStringResource* resource) {
6783   RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String);
6784 }
6785 
6786 
NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6787 MaybeLocal<String> v8::String::NewExternalOneByte(
6788     Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6789   CHECK(resource && resource->data());
6790   // TODO(dcarney): throw a context free exception.
6791   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6792     return MaybeLocal<String>();
6793   }
6794   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6795   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6796   LOG_API(i_isolate, String, NewExternalOneByte);
6797   if (resource->length() > 0) {
6798     i::Handle<i::String> string = i_isolate->factory()
6799                                       ->NewExternalStringFromOneByte(resource)
6800                                       .ToHandleChecked();
6801     i_isolate->heap()->RegisterExternalString(*string);
6802     return Utils::ToLocal(string);
6803   } else {
6804     // The resource isn't going to be used, free it immediately.
6805     resource->Dispose();
6806     return Utils::ToLocal(i_isolate->factory()->empty_string());
6807   }
6808 }
6809 
6810 
NewExternal(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6811 Local<String> v8::String::NewExternal(
6812     Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6813   RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String);
6814 }
6815 
6816 
MakeExternal(v8::String::ExternalStringResource * resource)6817 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
6818   i::Handle<i::String> obj = Utils::OpenHandle(this);
6819   i::Isolate* isolate = obj->GetIsolate();
6820   if (i::StringShape(*obj).IsExternal()) {
6821     return false;  // Already an external string.
6822   }
6823   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6824   if (isolate->heap()->IsInGCPostProcessing()) {
6825     return false;
6826   }
6827   CHECK(resource && resource->data());
6828 
6829   bool result = obj->MakeExternal(resource);
6830   // Assert that if CanMakeExternal(), then externalizing actually succeeds.
6831   DCHECK(!CanMakeExternal() || result);
6832   if (result) {
6833     DCHECK(obj->IsExternalString());
6834     isolate->heap()->RegisterExternalString(*obj);
6835   }
6836   return result;
6837 }
6838 
6839 
MakeExternal(v8::String::ExternalOneByteStringResource * resource)6840 bool v8::String::MakeExternal(
6841     v8::String::ExternalOneByteStringResource* resource) {
6842   i::Handle<i::String> obj = Utils::OpenHandle(this);
6843   i::Isolate* isolate = obj->GetIsolate();
6844   if (i::StringShape(*obj).IsExternal()) {
6845     return false;  // Already an external string.
6846   }
6847   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6848   if (isolate->heap()->IsInGCPostProcessing()) {
6849     return false;
6850   }
6851   CHECK(resource && resource->data());
6852 
6853   bool result = obj->MakeExternal(resource);
6854   // Assert that if CanMakeExternal(), then externalizing actually succeeds.
6855   DCHECK(!CanMakeExternal() || result);
6856   if (result) {
6857     DCHECK(obj->IsExternalString());
6858     isolate->heap()->RegisterExternalString(*obj);
6859   }
6860   return result;
6861 }
6862 
6863 
CanMakeExternal()6864 bool v8::String::CanMakeExternal() {
6865   i::Handle<i::String> obj = Utils::OpenHandle(this);
6866   if (obj->IsExternalString()) return false;
6867 
6868   // Old space strings should be externalized.
6869   i::Isolate* isolate = obj->GetIsolate();
6870   return !isolate->heap()->new_space()->Contains(*obj);
6871 }
6872 
6873 
GetIsolate()6874 Isolate* v8::Object::GetIsolate() {
6875   i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
6876   return reinterpret_cast<Isolate*>(i_isolate);
6877 }
6878 
6879 
New(Isolate * isolate)6880 Local<v8::Object> v8::Object::New(Isolate* isolate) {
6881   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6882   LOG_API(i_isolate, Object, New);
6883   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6884   i::Handle<i::JSObject> obj =
6885       i_isolate->factory()->NewJSObject(i_isolate->object_function());
6886   return Utils::ToLocal(obj);
6887 }
6888 
6889 
New(Isolate * isolate,double value)6890 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
6891   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6892   LOG_API(i_isolate, NumberObject, New);
6893   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6894   i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
6895   i::Handle<i::Object> obj =
6896       i::Object::ToObject(i_isolate, number).ToHandleChecked();
6897   return Utils::ToLocal(obj);
6898 }
6899 
6900 
ValueOf() const6901 double v8::NumberObject::ValueOf() const {
6902   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6903   i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
6904   i::Isolate* isolate = jsvalue->GetIsolate();
6905   LOG_API(isolate, NumberObject, NumberValue);
6906   return jsvalue->value()->Number();
6907 }
6908 
6909 
New(Isolate * isolate,bool value)6910 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
6911   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6912   LOG_API(i_isolate, BooleanObject, New);
6913   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6914   i::Handle<i::Object> boolean(value ? i_isolate->heap()->true_value()
6915                                      : i_isolate->heap()->false_value(),
6916                                i_isolate);
6917   i::Handle<i::Object> obj =
6918       i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
6919   return Utils::ToLocal(obj);
6920 }
6921 
6922 
New(bool value)6923 Local<v8::Value> v8::BooleanObject::New(bool value) {
6924   return New(Isolate::GetCurrent(), value);
6925 }
6926 
6927 
ValueOf() const6928 bool v8::BooleanObject::ValueOf() const {
6929   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6930   i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
6931   i::Isolate* isolate = jsvalue->GetIsolate();
6932   LOG_API(isolate, BooleanObject, BooleanValue);
6933   return jsvalue->value()->IsTrue(isolate);
6934 }
6935 
6936 
New(Local<String> value)6937 Local<v8::Value> v8::StringObject::New(Local<String> value) {
6938   i::Handle<i::String> string = Utils::OpenHandle(*value);
6939   i::Isolate* isolate = string->GetIsolate();
6940   LOG_API(isolate, StringObject, New);
6941   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6942   i::Handle<i::Object> obj =
6943       i::Object::ToObject(isolate, string).ToHandleChecked();
6944   return Utils::ToLocal(obj);
6945 }
6946 
6947 
ValueOf() const6948 Local<v8::String> v8::StringObject::ValueOf() const {
6949   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6950   i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
6951   i::Isolate* isolate = jsvalue->GetIsolate();
6952   LOG_API(isolate, StringObject, StringValue);
6953   return Utils::ToLocal(
6954       i::Handle<i::String>(i::String::cast(jsvalue->value())));
6955 }
6956 
6957 
New(Isolate * isolate,Local<Symbol> value)6958 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
6959   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6960   LOG_API(i_isolate, SymbolObject, New);
6961   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6962   i::Handle<i::Object> obj = i::Object::ToObject(
6963       i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
6964   return Utils::ToLocal(obj);
6965 }
6966 
6967 
ValueOf() const6968 Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
6969   i::Handle<i::Object> obj = Utils::OpenHandle(this);
6970   i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
6971   i::Isolate* isolate = jsvalue->GetIsolate();
6972   LOG_API(isolate, SymbolObject, SymbolValue);
6973   return Utils::ToLocal(
6974       i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
6975 }
6976 
6977 
New(Local<Context> context,double time)6978 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
6979   if (std::isnan(time)) {
6980     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6981     time = std::numeric_limits<double>::quiet_NaN();
6982   }
6983   PREPARE_FOR_EXECUTION(context, Date, New, Value);
6984   Local<Value> result;
6985   has_pending_exception = !ToLocal<Value>(
6986       i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
6987       &result);
6988   RETURN_ON_FAILED_EXECUTION(Value);
6989   RETURN_ESCAPED(result);
6990 }
6991 
6992 
New(Isolate * isolate,double time)6993 Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
6994   auto context = isolate->GetCurrentContext();
6995   RETURN_TO_LOCAL_UNCHECKED(New(context, time), Value);
6996 }
6997 
6998 
ValueOf() const6999 double v8::Date::ValueOf() const {
7000   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7001   i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
7002   i::Isolate* isolate = jsdate->GetIsolate();
7003   LOG_API(isolate, Date, NumberValue);
7004   return jsdate->value()->Number();
7005 }
7006 
7007 
DateTimeConfigurationChangeNotification(Isolate * isolate)7008 void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
7009   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7010   LOG_API(i_isolate, Date, DateTimeConfigurationChangeNotification);
7011   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7012   i_isolate->date_cache()->ResetDateCache();
7013   if (!i_isolate->eternal_handles()->Exists(
7014           i::EternalHandles::DATE_CACHE_VERSION)) {
7015     return;
7016   }
7017   i::Handle<i::FixedArray> date_cache_version =
7018       i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
7019           i::EternalHandles::DATE_CACHE_VERSION));
7020   DCHECK_EQ(1, date_cache_version->length());
7021   CHECK(date_cache_version->get(0)->IsSmi());
7022   date_cache_version->set(
7023       0,
7024       i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1));
7025 }
7026 
7027 
New(Local<Context> context,Local<String> pattern,Flags flags)7028 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
7029                                        Local<String> pattern, Flags flags) {
7030   PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7031   Local<v8::RegExp> result;
7032   has_pending_exception =
7033       !ToLocal<RegExp>(i::JSRegExp::New(Utils::OpenHandle(*pattern),
7034                                         static_cast<i::JSRegExp::Flags>(flags)),
7035                        &result);
7036   RETURN_ON_FAILED_EXECUTION(RegExp);
7037   RETURN_ESCAPED(result);
7038 }
7039 
7040 
New(Local<String> pattern,Flags flags)7041 Local<v8::RegExp> v8::RegExp::New(Local<String> pattern, Flags flags) {
7042   auto isolate =
7043       reinterpret_cast<Isolate*>(Utils::OpenHandle(*pattern)->GetIsolate());
7044   auto context = isolate->GetCurrentContext();
7045   RETURN_TO_LOCAL_UNCHECKED(New(context, pattern, flags), RegExp);
7046 }
7047 
7048 
GetSource() const7049 Local<v8::String> v8::RegExp::GetSource() const {
7050   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7051   return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
7052 }
7053 
7054 
7055 // Assert that the static flags cast in GetFlags is valid.
7056 #define REGEXP_FLAG_ASSERT_EQ(flag)                   \
7057   STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
7058                 static_cast<int>(i::JSRegExp::flag))
7059 REGEXP_FLAG_ASSERT_EQ(kNone);
7060 REGEXP_FLAG_ASSERT_EQ(kGlobal);
7061 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7062 REGEXP_FLAG_ASSERT_EQ(kMultiline);
7063 REGEXP_FLAG_ASSERT_EQ(kSticky);
7064 REGEXP_FLAG_ASSERT_EQ(kUnicode);
7065 #undef REGEXP_FLAG_ASSERT_EQ
7066 
GetFlags() const7067 v8::RegExp::Flags v8::RegExp::GetFlags() const {
7068   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7069   return RegExp::Flags(static_cast<int>(obj->GetFlags()));
7070 }
7071 
7072 
New(Isolate * isolate,int length)7073 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
7074   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7075   LOG_API(i_isolate, Array, New);
7076   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7077   int real_length = length > 0 ? length : 0;
7078   i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
7079   i::Handle<i::Object> length_obj =
7080       i_isolate->factory()->NewNumberFromInt(real_length);
7081   obj->set_length(*length_obj);
7082   return Utils::ToLocal(obj);
7083 }
7084 
7085 
Length() const7086 uint32_t v8::Array::Length() const {
7087   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
7088   i::Object* length = obj->length();
7089   if (length->IsSmi()) {
7090     return i::Smi::cast(length)->value();
7091   } else {
7092     return static_cast<uint32_t>(length->Number());
7093   }
7094 }
7095 
7096 
CloneElementAt(Local<Context> context,uint32_t index)7097 MaybeLocal<Object> Array::CloneElementAt(Local<Context> context,
7098                                          uint32_t index) {
7099   PREPARE_FOR_EXECUTION(context, Array, CloneElementAt, Object);
7100   auto self = Utils::OpenHandle(this);
7101   if (!self->HasFastObjectElements()) return Local<Object>();
7102   i::FixedArray* elms = i::FixedArray::cast(self->elements());
7103   i::Object* paragon = elms->get(index);
7104   if (!paragon->IsJSObject()) return Local<Object>();
7105   i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
7106   Local<Object> result;
7107   has_pending_exception =
7108       !ToLocal<Object>(isolate->factory()->CopyJSObject(paragon_handle),
7109                        &result);
7110   RETURN_ON_FAILED_EXECUTION(Object);
7111   RETURN_ESCAPED(result);
7112 }
7113 
7114 
CloneElementAt(uint32_t index)7115 Local<Object> Array::CloneElementAt(uint32_t index) { return Local<Object>(); }
7116 
7117 
New(Isolate * isolate)7118 Local<v8::Map> v8::Map::New(Isolate* isolate) {
7119   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7120   LOG_API(i_isolate, Map, New);
7121   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7122   i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
7123   return Utils::ToLocal(obj);
7124 }
7125 
7126 
Size() const7127 size_t v8::Map::Size() const {
7128   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7129   return i::OrderedHashMap::cast(obj->table())->NumberOfElements();
7130 }
7131 
7132 
Clear()7133 void Map::Clear() {
7134   auto self = Utils::OpenHandle(this);
7135   i::Isolate* isolate = self->GetIsolate();
7136   LOG_API(isolate, Map, Clear);
7137   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7138   i::JSMap::Clear(self);
7139 }
7140 
7141 
Get(Local<Context> context,Local<Value> key)7142 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
7143   PREPARE_FOR_EXECUTION(context, Map, Get, Value);
7144   auto self = Utils::OpenHandle(this);
7145   Local<Value> result;
7146   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7147   has_pending_exception =
7148       !ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
7149                                          arraysize(argv), argv),
7150                       &result);
7151   RETURN_ON_FAILED_EXECUTION(Value);
7152   RETURN_ESCAPED(result);
7153 }
7154 
7155 
Set(Local<Context> context,Local<Value> key,Local<Value> value)7156 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
7157                          Local<Value> value) {
7158   PREPARE_FOR_EXECUTION(context, Map, Set, Map);
7159   auto self = Utils::OpenHandle(this);
7160   i::Handle<i::Object> result;
7161   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
7162                                  Utils::OpenHandle(*value)};
7163   has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self,
7164                                               arraysize(argv), argv)
7165                                .ToHandle(&result);
7166   RETURN_ON_FAILED_EXECUTION(Map);
7167   RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
7168 }
7169 
7170 
Has(Local<Context> context,Local<Value> key)7171 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
7172   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Map, Has, bool);
7173   auto self = Utils::OpenHandle(this);
7174   i::Handle<i::Object> result;
7175   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7176   has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self,
7177                                               arraysize(argv), argv)
7178                                .ToHandle(&result);
7179   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7180   return Just(result->IsTrue(isolate));
7181 }
7182 
7183 
Delete(Local<Context> context,Local<Value> key)7184 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
7185   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Map, Delete, bool);
7186   auto self = Utils::OpenHandle(this);
7187   i::Handle<i::Object> result;
7188   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7189   has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(),
7190                                               self, arraysize(argv), argv)
7191                                .ToHandle(&result);
7192   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7193   return Just(result->IsTrue(isolate));
7194 }
7195 
7196 namespace {
MapAsArray(i::Isolate * isolate,i::Object * table_obj,int offset,int kind)7197 i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
7198                                  int offset, int kind) {
7199   i::Factory* factory = isolate->factory();
7200   i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj));
7201   if (offset >= table->NumberOfElements()) return factory->NewJSArray(0);
7202   int length = (table->NumberOfElements() - offset) *
7203                (kind == i::JSMapIterator::kKindEntries ? 2 : 1);
7204   i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
7205   int result_index = 0;
7206   {
7207     i::DisallowHeapAllocation no_gc;
7208     int capacity = table->UsedCapacity();
7209     i::Oddball* the_hole = isolate->heap()->the_hole_value();
7210     for (int i = 0; i < capacity; ++i) {
7211       i::Object* key = table->KeyAt(i);
7212       if (key == the_hole) continue;
7213       if (offset-- > 0) continue;
7214       if (kind == i::JSMapIterator::kKindEntries ||
7215           kind == i::JSMapIterator::kKindKeys) {
7216         result->set(result_index++, key);
7217       }
7218       if (kind == i::JSMapIterator::kKindEntries ||
7219           kind == i::JSMapIterator::kKindValues) {
7220         result->set(result_index++, table->ValueAt(i));
7221       }
7222     }
7223   }
7224   DCHECK_EQ(result_index, result->length());
7225   DCHECK_EQ(result_index, length);
7226   return factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
7227 }
7228 }  // namespace
7229 
AsArray() const7230 Local<Array> Map::AsArray() const {
7231   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7232   i::Isolate* isolate = obj->GetIsolate();
7233   LOG_API(isolate, Map, AsArray);
7234   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7235   return Utils::ToLocal(
7236       MapAsArray(isolate, obj->table(), 0, i::JSMapIterator::kKindEntries));
7237 }
7238 
7239 
New(Isolate * isolate)7240 Local<v8::Set> v8::Set::New(Isolate* isolate) {
7241   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7242   LOG_API(i_isolate, Set, New);
7243   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7244   i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7245   return Utils::ToLocal(obj);
7246 }
7247 
7248 
Size() const7249 size_t v8::Set::Size() const {
7250   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7251   return i::OrderedHashSet::cast(obj->table())->NumberOfElements();
7252 }
7253 
7254 
Clear()7255 void Set::Clear() {
7256   auto self = Utils::OpenHandle(this);
7257   i::Isolate* isolate = self->GetIsolate();
7258   LOG_API(isolate, Set, Clear);
7259   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7260   i::JSSet::Clear(self);
7261 }
7262 
7263 
Add(Local<Context> context,Local<Value> key)7264 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7265   PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7266   auto self = Utils::OpenHandle(this);
7267   i::Handle<i::Object> result;
7268   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7269   has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self,
7270                                               arraysize(argv), argv)
7271                                .ToHandle(&result);
7272   RETURN_ON_FAILED_EXECUTION(Set);
7273   RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7274 }
7275 
7276 
Has(Local<Context> context,Local<Value> key)7277 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7278   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Set, Has, bool);
7279   auto self = Utils::OpenHandle(this);
7280   i::Handle<i::Object> result;
7281   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7282   has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self,
7283                                               arraysize(argv), argv)
7284                                .ToHandle(&result);
7285   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7286   return Just(result->IsTrue(isolate));
7287 }
7288 
7289 
Delete(Local<Context> context,Local<Value> key)7290 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7291   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Set, Delete, bool);
7292   auto self = Utils::OpenHandle(this);
7293   i::Handle<i::Object> result;
7294   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7295   has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(),
7296                                               self, arraysize(argv), argv)
7297                                .ToHandle(&result);
7298   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7299   return Just(result->IsTrue(isolate));
7300 }
7301 
7302 namespace {
SetAsArray(i::Isolate * isolate,i::Object * table_obj,int offset)7303 i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object* table_obj,
7304                                  int offset) {
7305   i::Factory* factory = isolate->factory();
7306   i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj));
7307   int length = table->NumberOfElements() - offset;
7308   if (length <= 0) return factory->NewJSArray(0);
7309   i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
7310   int result_index = 0;
7311   {
7312     i::DisallowHeapAllocation no_gc;
7313     int capacity = table->UsedCapacity();
7314     i::Oddball* the_hole = isolate->heap()->the_hole_value();
7315     for (int i = 0; i < capacity; ++i) {
7316       i::Object* key = table->KeyAt(i);
7317       if (key == the_hole) continue;
7318       if (offset-- > 0) continue;
7319       result->set(result_index++, key);
7320     }
7321   }
7322   DCHECK_EQ(result_index, result->length());
7323   DCHECK_EQ(result_index, length);
7324   return factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
7325 }
7326 }  // namespace
7327 
AsArray() const7328 Local<Array> Set::AsArray() const {
7329   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7330   i::Isolate* isolate = obj->GetIsolate();
7331   LOG_API(isolate, Set, AsArray);
7332   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7333   return Utils::ToLocal(SetAsArray(isolate, obj->table(), 0));
7334 }
7335 
7336 
New(Local<Context> context)7337 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7338   PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7339   i::Handle<i::Object> result;
7340   has_pending_exception =
7341       !i::Execution::Call(isolate, isolate->promise_internal_constructor(),
7342                           isolate->factory()->undefined_value(), 0, NULL)
7343            .ToHandle(&result);
7344   RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7345   RETURN_ESCAPED(Local<Promise::Resolver>::Cast(Utils::ToLocal(result)));
7346 }
7347 
7348 
New(Isolate * isolate)7349 Local<Promise::Resolver> Promise::Resolver::New(Isolate* isolate) {
7350   RETURN_TO_LOCAL_UNCHECKED(New(isolate->GetCurrentContext()),
7351                             Promise::Resolver);
7352 }
7353 
7354 
GetPromise()7355 Local<Promise> Promise::Resolver::GetPromise() {
7356   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7357   return Local<Promise>::Cast(Utils::ToLocal(promise));
7358 }
7359 
7360 
Resolve(Local<Context> context,Local<Value> value)7361 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7362                                        Local<Value> value) {
7363   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Promise_Resolver, Resolve, bool);
7364   auto self = Utils::OpenHandle(this);
7365   i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
7366   has_pending_exception =
7367       i::Execution::Call(isolate, isolate->promise_resolve(),
7368                          isolate->factory()->undefined_value(), arraysize(argv),
7369                          argv)
7370           .is_null();
7371   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7372   return Just(true);
7373 }
7374 
7375 
Resolve(Local<Value> value)7376 void Promise::Resolver::Resolve(Local<Value> value) {
7377   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7378   USE(Resolve(context, value));
7379 }
7380 
7381 
Reject(Local<Context> context,Local<Value> value)7382 Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7383                                       Local<Value> value) {
7384   PREPARE_FOR_EXECUTION_PRIMITIVE(context, Promise_Resolver, Resolve, bool);
7385   auto self = Utils::OpenHandle(this);
7386 
7387   // We pass true to trigger the debugger's on exception handler.
7388   i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value),
7389                                  isolate->factory()->ToBoolean(true)};
7390   has_pending_exception =
7391       i::Execution::Call(isolate, isolate->promise_internal_reject(),
7392                          isolate->factory()->undefined_value(), arraysize(argv),
7393                          argv)
7394           .is_null();
7395   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7396   return Just(true);
7397 }
7398 
7399 
Reject(Local<Value> value)7400 void Promise::Resolver::Reject(Local<Value> value) {
7401   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7402   USE(Reject(context, value));
7403 }
7404 
7405 
Catch(Local<Context> context,Local<Function> handler)7406 MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7407                                    Local<Function> handler) {
7408   PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7409   auto self = Utils::OpenHandle(this);
7410   i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
7411   i::Handle<i::Object> result;
7412   has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(),
7413                                               self, arraysize(argv), argv)
7414                                .ToHandle(&result);
7415   RETURN_ON_FAILED_EXECUTION(Promise);
7416   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7417 }
7418 
7419 
Catch(Local<Function> handler)7420 Local<Promise> Promise::Catch(Local<Function> handler) {
7421   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7422   RETURN_TO_LOCAL_UNCHECKED(Catch(context, handler), Promise);
7423 }
7424 
7425 
Then(Local<Context> context,Local<Function> handler)7426 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7427                                   Local<Function> handler) {
7428   PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7429   auto self = Utils::OpenHandle(this);
7430   i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
7431   i::Handle<i::Object> result;
7432   has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
7433                                               self, arraysize(argv), argv)
7434                                .ToHandle(&result);
7435   RETURN_ON_FAILED_EXECUTION(Promise);
7436   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7437 }
7438 
7439 
Then(Local<Function> handler)7440 Local<Promise> Promise::Then(Local<Function> handler) {
7441   auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7442   RETURN_TO_LOCAL_UNCHECKED(Then(context, handler), Promise);
7443 }
7444 
7445 
HasHandler()7446 bool Promise::HasHandler() {
7447   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7448   i::Isolate* isolate = promise->GetIsolate();
7449   LOG_API(isolate, Promise, HasRejectHandler);
7450   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7451   if (promise->IsJSPromise()) {
7452     i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7453     return js_promise->has_handler();
7454   }
7455   return false;
7456 }
7457 
Result()7458 Local<Value> Promise::Result() {
7459   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7460   i::Isolate* isolate = promise->GetIsolate();
7461   LOG_API(isolate, Promise, Result);
7462   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7463   Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7464                   "Promise is still pending");
7465   i::Handle<i::Object> result(js_promise->result(), isolate);
7466   return Utils::ToLocal(result);
7467 }
7468 
State()7469 Promise::PromiseState Promise::State() {
7470   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7471   i::Isolate* isolate = promise->GetIsolate();
7472   LOG_API(isolate, Promise, Status);
7473   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7474   return static_cast<PromiseState>(js_promise->status());
7475 }
7476 
GetTarget()7477 Local<Object> Proxy::GetTarget() {
7478   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7479   i::Handle<i::JSReceiver> target(self->target());
7480   return Utils::ToLocal(target);
7481 }
7482 
7483 
GetHandler()7484 Local<Value> Proxy::GetHandler() {
7485   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7486   i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7487   return Utils::ToLocal(handler);
7488 }
7489 
7490 
IsRevoked()7491 bool Proxy::IsRevoked() {
7492   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7493   return self->IsRevoked();
7494 }
7495 
7496 
Revoke()7497 void Proxy::Revoke() {
7498   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7499   i::JSProxy::Revoke(self);
7500 }
7501 
7502 
New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7503 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7504                              Local<Object> local_handler) {
7505   PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7506   i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7507   i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7508   Local<Proxy> result;
7509   has_pending_exception =
7510       !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7511   RETURN_ON_FAILED_EXECUTION(Proxy);
7512   RETURN_ESCAPED(result);
7513 }
7514 
GetWasmWireBytes()7515 Local<String> WasmCompiledModule::GetWasmWireBytes() {
7516   i::Handle<i::JSObject> obj =
7517       i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
7518   i::Handle<i::WasmCompiledModule> compiled_part =
7519       i::handle(i::WasmCompiledModule::cast(obj->GetInternalField(0)));
7520   i::Handle<i::String> wire_bytes(compiled_part->module_bytes());
7521   return Local<String>::Cast(Utils::ToLocal(wire_bytes));
7522 }
7523 
Serialize()7524 WasmCompiledModule::SerializedModule WasmCompiledModule::Serialize() {
7525   i::Handle<i::JSObject> obj =
7526       i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
7527   i::Handle<i::WasmCompiledModule> compiled_part =
7528       i::handle(i::WasmCompiledModule::cast(obj->GetInternalField(0)));
7529 
7530   std::unique_ptr<i::ScriptData> script_data =
7531       i::WasmCompiledModuleSerializer::SerializeWasmModule(obj->GetIsolate(),
7532                                                            compiled_part);
7533   script_data->ReleaseDataOwnership();
7534 
7535   size_t size = static_cast<size_t>(script_data->length());
7536   return {std::unique_ptr<const uint8_t[]>(script_data->data()), size};
7537 }
7538 
Deserialize(Isolate * isolate,const WasmCompiledModule::CallerOwnedBuffer & serialized_module,const WasmCompiledModule::CallerOwnedBuffer & wire_bytes)7539 MaybeLocal<WasmCompiledModule> WasmCompiledModule::Deserialize(
7540     Isolate* isolate,
7541     const WasmCompiledModule::CallerOwnedBuffer& serialized_module,
7542     const WasmCompiledModule::CallerOwnedBuffer& wire_bytes) {
7543   int size = static_cast<int>(serialized_module.second);
7544   i::ScriptData sc(serialized_module.first, size);
7545   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7546   i::MaybeHandle<i::FixedArray> maybe_compiled_part =
7547       i::WasmCompiledModuleSerializer::DeserializeWasmModule(
7548           i_isolate, &sc,
7549           {wire_bytes.first, static_cast<int>(wire_bytes.second)});
7550   i::Handle<i::FixedArray> compiled_part;
7551   if (!maybe_compiled_part.ToHandle(&compiled_part)) {
7552     return MaybeLocal<WasmCompiledModule>();
7553   }
7554   i::Handle<i::WasmCompiledModule> compiled_module =
7555       handle(i::WasmCompiledModule::cast(*compiled_part));
7556   return Local<WasmCompiledModule>::Cast(
7557       Utils::ToLocal(i::Handle<i::JSObject>::cast(
7558           i::WasmModuleObject::New(i_isolate, compiled_module))));
7559 }
7560 
DeserializeOrCompile(Isolate * isolate,const WasmCompiledModule::CallerOwnedBuffer & serialized_module,const WasmCompiledModule::CallerOwnedBuffer & wire_bytes)7561 MaybeLocal<WasmCompiledModule> WasmCompiledModule::DeserializeOrCompile(
7562     Isolate* isolate,
7563     const WasmCompiledModule::CallerOwnedBuffer& serialized_module,
7564     const WasmCompiledModule::CallerOwnedBuffer& wire_bytes) {
7565   MaybeLocal<WasmCompiledModule> ret =
7566       Deserialize(isolate, serialized_module, wire_bytes);
7567   if (!ret.IsEmpty()) {
7568     return ret;
7569   }
7570   return Compile(isolate, wire_bytes.first, wire_bytes.second);
7571 }
7572 
Compile(Isolate * isolate,const uint8_t * start,size_t length)7573 MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
7574                                                            const uint8_t* start,
7575                                                            size_t length) {
7576   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7577   i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Deserialize()");
7578   i::MaybeHandle<i::JSObject> maybe_compiled = i::wasm::SyncCompile(
7579       i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length));
7580   if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>();
7581   return Local<WasmCompiledModule>::Cast(
7582       Utils::ToLocal(maybe_compiled.ToHandleChecked()));
7583 }
7584 
7585 // static
NewDefaultAllocator()7586 v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7587   return new ArrayBufferAllocator();
7588 }
7589 
IsExternal() const7590 bool v8::ArrayBuffer::IsExternal() const {
7591   return Utils::OpenHandle(this)->is_external();
7592 }
7593 
7594 
IsNeuterable() const7595 bool v8::ArrayBuffer::IsNeuterable() const {
7596   return Utils::OpenHandle(this)->is_neuterable();
7597 }
7598 
7599 
Externalize()7600 v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
7601   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7602   i::Isolate* isolate = self->GetIsolate();
7603   Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize",
7604                   "ArrayBuffer already externalized");
7605   self->set_is_external(true);
7606   isolate->heap()->UnregisterArrayBuffer(*self);
7607 
7608   return GetContents();
7609 }
7610 
7611 
GetContents()7612 v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
7613   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7614   size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
7615   Contents contents;
7616   contents.data_ = self->backing_store();
7617   contents.byte_length_ = byte_length;
7618   return contents;
7619 }
7620 
7621 
Neuter()7622 void v8::ArrayBuffer::Neuter() {
7623   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7624   i::Isolate* isolate = obj->GetIsolate();
7625   Utils::ApiCheck(obj->is_external(),
7626                   "v8::ArrayBuffer::Neuter",
7627                   "Only externalized ArrayBuffers can be neutered");
7628   Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
7629                   "Only neuterable ArrayBuffers can be neutered");
7630   LOG_API(isolate, ArrayBuffer, Neuter);
7631   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7632   obj->Neuter();
7633 }
7634 
7635 
ByteLength() const7636 size_t v8::ArrayBuffer::ByteLength() const {
7637   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7638   return static_cast<size_t>(obj->byte_length()->Number());
7639 }
7640 
7641 
New(Isolate * isolate,size_t byte_length)7642 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
7643   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7644   LOG_API(i_isolate, ArrayBuffer, New);
7645   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7646   i::Handle<i::JSArrayBuffer> obj =
7647       i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
7648   // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7649   // version that throws an exception or otherwise does not crash.
7650   if (!i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length)) {
7651     i::FatalProcessOutOfMemory("v8::ArrayBuffer::New");
7652   }
7653   return Utils::ToLocal(obj);
7654 }
7655 
7656 
New(Isolate * isolate,void * data,size_t byte_length,ArrayBufferCreationMode mode)7657 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
7658                                         size_t byte_length,
7659                                         ArrayBufferCreationMode mode) {
7660   // Embedders must guarantee that the external backing store is valid.
7661   CHECK(byte_length == 0 || data != NULL);
7662   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7663   LOG_API(i_isolate, ArrayBuffer, New);
7664   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7665   i::Handle<i::JSArrayBuffer> obj =
7666       i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
7667   i::JSArrayBuffer::Setup(obj, i_isolate,
7668                           mode == ArrayBufferCreationMode::kExternalized, data,
7669                           byte_length);
7670   return Utils::ToLocal(obj);
7671 }
7672 
7673 
Buffer()7674 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
7675   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7676   i::Handle<i::JSArrayBuffer> buffer;
7677   if (obj->IsJSDataView()) {
7678     i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj));
7679     DCHECK(data_view->buffer()->IsJSArrayBuffer());
7680     buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()));
7681   } else {
7682     DCHECK(obj->IsJSTypedArray());
7683     buffer = i::JSTypedArray::cast(*obj)->GetBuffer();
7684   }
7685   return Utils::ToLocal(buffer);
7686 }
7687 
7688 
CopyContents(void * dest,size_t byte_length)7689 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
7690   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
7691   size_t byte_offset = i::NumberToSize(self->byte_offset());
7692   size_t bytes_to_copy =
7693       i::Min(byte_length, i::NumberToSize(self->byte_length()));
7694   if (bytes_to_copy) {
7695     i::DisallowHeapAllocation no_gc;
7696     i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
7697     const char* source = reinterpret_cast<char*>(buffer->backing_store());
7698     if (source == nullptr) {
7699       DCHECK(self->IsJSTypedArray());
7700       i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self));
7701       i::Handle<i::FixedTypedArrayBase> fixed_array(
7702           i::FixedTypedArrayBase::cast(typed_array->elements()));
7703       source = reinterpret_cast<char*>(fixed_array->DataPtr());
7704     }
7705     memcpy(dest, source + byte_offset, bytes_to_copy);
7706   }
7707   return bytes_to_copy;
7708 }
7709 
7710 
HasBuffer() const7711 bool v8::ArrayBufferView::HasBuffer() const {
7712   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
7713   i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
7714   return buffer->backing_store() != nullptr;
7715 }
7716 
7717 
ByteOffset()7718 size_t v8::ArrayBufferView::ByteOffset() {
7719   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7720   return static_cast<size_t>(obj->byte_offset()->Number());
7721 }
7722 
7723 
ByteLength()7724 size_t v8::ArrayBufferView::ByteLength() {
7725   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7726   return static_cast<size_t>(obj->byte_length()->Number());
7727 }
7728 
7729 
Length()7730 size_t v8::TypedArray::Length() {
7731   i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
7732   return static_cast<size_t>(obj->length_value());
7733 }
7734 
7735 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size)                     \
7736   Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer,     \
7737                                       size_t byte_offset, size_t length) { \
7738     i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();  \
7739     LOG_API(isolate, Type##Array, New);                                    \
7740     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
7741     if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
7742                          "v8::" #Type                                      \
7743                          "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
7744                          "length exceeds max allowed value")) {            \
7745       return Local<Type##Array>();                                         \
7746     }                                                                      \
7747     i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
7748     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
7749         i::kExternal##Type##Array, buffer, byte_offset, length);           \
7750     return Utils::ToLocal##Type##Array(obj);                               \
7751   }                                                                        \
7752   Local<Type##Array> Type##Array::New(                                     \
7753       Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset,    \
7754       size_t length) {                                                     \
7755     CHECK(i::FLAG_harmony_sharedarraybuffer);                              \
7756     i::Isolate* isolate =                                                  \
7757         Utils::OpenHandle(*shared_array_buffer)->GetIsolate();             \
7758     LOG_API(isolate, Type##Array, New);                                    \
7759     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
7760     if (!Utils::ApiCheck(                                                  \
7761             length <= static_cast<size_t>(i::Smi::kMaxValue),              \
7762             "v8::" #Type                                                   \
7763             "Array::New(Local<SharedArrayBuffer>, size_t, size_t)",        \
7764             "length exceeds max allowed value")) {                         \
7765       return Local<Type##Array>();                                         \
7766     }                                                                      \
7767     i::Handle<i::JSArrayBuffer> buffer =                                   \
7768         Utils::OpenHandle(*shared_array_buffer);                           \
7769     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
7770         i::kExternal##Type##Array, buffer, byte_offset, length);           \
7771     return Utils::ToLocal##Type##Array(obj);                               \
7772   }
7773 
TYPED_ARRAYS(TYPED_ARRAY_NEW)7774 TYPED_ARRAYS(TYPED_ARRAY_NEW)
7775 #undef TYPED_ARRAY_NEW
7776 
7777 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
7778                               size_t byte_offset, size_t byte_length) {
7779   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
7780   i::Isolate* isolate = buffer->GetIsolate();
7781   LOG_API(isolate, DataView, New);
7782   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7783   i::Handle<i::JSDataView> obj =
7784       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
7785   return Utils::ToLocal(obj);
7786 }
7787 
7788 
New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)7789 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
7790                               size_t byte_offset, size_t byte_length) {
7791   CHECK(i::FLAG_harmony_sharedarraybuffer);
7792   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
7793   i::Isolate* isolate = buffer->GetIsolate();
7794   LOG_API(isolate, DataView, New);
7795   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7796   i::Handle<i::JSDataView> obj =
7797       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
7798   return Utils::ToLocal(obj);
7799 }
7800 
7801 
IsExternal() const7802 bool v8::SharedArrayBuffer::IsExternal() const {
7803   return Utils::OpenHandle(this)->is_external();
7804 }
7805 
7806 
Externalize()7807 v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
7808   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7809   i::Isolate* isolate = self->GetIsolate();
7810   Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize",
7811                   "SharedArrayBuffer already externalized");
7812   self->set_is_external(true);
7813   isolate->heap()->UnregisterArrayBuffer(*self);
7814   return GetContents();
7815 }
7816 
7817 
GetContents()7818 v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() {
7819   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7820   size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
7821   Contents contents;
7822   contents.data_ = self->backing_store();
7823   contents.byte_length_ = byte_length;
7824   return contents;
7825 }
7826 
7827 
ByteLength() const7828 size_t v8::SharedArrayBuffer::ByteLength() const {
7829   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7830   return static_cast<size_t>(obj->byte_length()->Number());
7831 }
7832 
7833 
New(Isolate * isolate,size_t byte_length)7834 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
7835                                                     size_t byte_length) {
7836   CHECK(i::FLAG_harmony_sharedarraybuffer);
7837   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7838   LOG_API(i_isolate, SharedArrayBuffer, New);
7839   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7840   i::Handle<i::JSArrayBuffer> obj =
7841       i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
7842   // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7843   // version that throws an exception or otherwise does not crash.
7844   if (!i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length, true,
7845                                              i::SharedFlag::kShared)) {
7846     i::FatalProcessOutOfMemory("v8::SharedArrayBuffer::New");
7847   }
7848   return Utils::ToLocalShared(obj);
7849 }
7850 
7851 
New(Isolate * isolate,void * data,size_t byte_length,ArrayBufferCreationMode mode)7852 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
7853     Isolate* isolate, void* data, size_t byte_length,
7854     ArrayBufferCreationMode mode) {
7855   CHECK(i::FLAG_harmony_sharedarraybuffer);
7856   // Embedders must guarantee that the external backing store is valid.
7857   CHECK(byte_length == 0 || data != NULL);
7858   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7859   LOG_API(i_isolate, SharedArrayBuffer, New);
7860   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7861   i::Handle<i::JSArrayBuffer> obj =
7862       i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
7863   i::JSArrayBuffer::Setup(obj, i_isolate,
7864                           mode == ArrayBufferCreationMode::kExternalized, data,
7865                           byte_length, i::SharedFlag::kShared);
7866   return Utils::ToLocalShared(obj);
7867 }
7868 
7869 
New(Isolate * isolate,Local<String> name)7870 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
7871   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7872   LOG_API(i_isolate, Symbol, New);
7873   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7874   i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
7875   if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
7876   return Utils::ToLocal(result);
7877 }
7878 
7879 
For(Isolate * isolate,Local<String> name)7880 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
7881   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7882   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
7883   return Utils::ToLocal(i_isolate->SymbolFor(
7884       i::Heap::kPublicSymbolTableRootIndex, i_name, false));
7885 }
7886 
7887 
ForApi(Isolate * isolate,Local<String> name)7888 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
7889   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7890   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
7891   return Utils::ToLocal(
7892       i_isolate->SymbolFor(i::Heap::kApiSymbolTableRootIndex, i_name, false));
7893 }
7894 
7895 
GetIterator(Isolate * isolate)7896 Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
7897   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7898   return Utils::ToLocal(i_isolate->factory()->iterator_symbol());
7899 }
7900 
7901 
GetUnscopables(Isolate * isolate)7902 Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
7903   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7904   return Utils::ToLocal(i_isolate->factory()->unscopables_symbol());
7905 }
7906 
GetToPrimitive(Isolate * isolate)7907 Local<Symbol> v8::Symbol::GetToPrimitive(Isolate* isolate) {
7908   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7909   return Utils::ToLocal(i_isolate->factory()->to_primitive_symbol());
7910 }
7911 
GetToStringTag(Isolate * isolate)7912 Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) {
7913   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7914   return Utils::ToLocal(i_isolate->factory()->to_string_tag_symbol());
7915 }
7916 
7917 
GetIsConcatSpreadable(Isolate * isolate)7918 Local<Symbol> v8::Symbol::GetIsConcatSpreadable(Isolate* isolate) {
7919   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7920   return Utils::ToLocal(i_isolate->factory()->is_concat_spreadable_symbol());
7921 }
7922 
7923 
New(Isolate * isolate,Local<String> name)7924 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
7925   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7926   LOG_API(i_isolate, Private, New);
7927   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7928   i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
7929   if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
7930   Local<Symbol> result = Utils::ToLocal(symbol);
7931   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
7932 }
7933 
7934 
ForApi(Isolate * isolate,Local<String> name)7935 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
7936   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7937   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
7938   Local<Symbol> result = Utils::ToLocal(i_isolate->SymbolFor(
7939       i::Heap::kApiPrivateSymbolTableRootIndex, i_name, true));
7940   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
7941 }
7942 
7943 
New(Isolate * isolate,double value)7944 Local<Number> v8::Number::New(Isolate* isolate, double value) {
7945   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7946   if (std::isnan(value)) {
7947     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
7948     value = std::numeric_limits<double>::quiet_NaN();
7949   }
7950   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
7951   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
7952   return Utils::NumberToLocal(result);
7953 }
7954 
7955 
New(Isolate * isolate,int32_t value)7956 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
7957   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7958   if (i::Smi::IsValid(value)) {
7959     return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
7960                                                       internal_isolate));
7961   }
7962   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
7963   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
7964   return Utils::IntegerToLocal(result);
7965 }
7966 
7967 
NewFromUnsigned(Isolate * isolate,uint32_t value)7968 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
7969   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7970   bool fits_into_int32_t = (value & (1 << 31)) == 0;
7971   if (fits_into_int32_t) {
7972     return Integer::New(isolate, static_cast<int32_t>(value));
7973   }
7974   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
7975   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
7976   return Utils::IntegerToLocal(result);
7977 }
7978 
7979 
ReportExternalAllocationLimitReached()7980 void Isolate::ReportExternalAllocationLimitReached() {
7981   i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
7982   if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
7983   heap->ReportExternalMemoryPressure();
7984 }
7985 
7986 
GetHeapProfiler()7987 HeapProfiler* Isolate::GetHeapProfiler() {
7988   i::HeapProfiler* heap_profiler =
7989       reinterpret_cast<i::Isolate*>(this)->heap_profiler();
7990   return reinterpret_cast<HeapProfiler*>(heap_profiler);
7991 }
7992 
7993 
GetCpuProfiler()7994 CpuProfiler* Isolate::GetCpuProfiler() {
7995   i::CpuProfiler* cpu_profiler =
7996       reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
7997   return reinterpret_cast<CpuProfiler*>(cpu_profiler);
7998 }
7999 
8000 
InContext()8001 bool Isolate::InContext() {
8002   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8003   return isolate->context() != NULL;
8004 }
8005 
8006 
GetCurrentContext()8007 v8::Local<v8::Context> Isolate::GetCurrentContext() {
8008   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8009   i::Context* context = isolate->context();
8010   if (context == NULL) return Local<Context>();
8011   i::Context* native_context = context->native_context();
8012   if (native_context == NULL) return Local<Context>();
8013   return Utils::ToLocal(i::Handle<i::Context>(native_context));
8014 }
8015 
8016 
GetCallingContext()8017 v8::Local<v8::Context> Isolate::GetCallingContext() {
8018   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8019   i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
8020   if (calling.is_null()) return Local<Context>();
8021   return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
8022 }
8023 
8024 
GetEnteredContext()8025 v8::Local<v8::Context> Isolate::GetEnteredContext() {
8026   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8027   i::Handle<i::Object> last =
8028       isolate->handle_scope_implementer()->LastEnteredContext();
8029   if (last.is_null()) return Local<Context>();
8030   return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8031 }
8032 
GetEnteredOrMicrotaskContext()8033 v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8034   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8035   i::Handle<i::Object> last;
8036   if (isolate->handle_scope_implementer()
8037           ->MicrotaskContextIsLastEnteredContext()) {
8038     last = isolate->handle_scope_implementer()->MicrotaskContext();
8039   } else {
8040     last = isolate->handle_scope_implementer()->LastEnteredContext();
8041   }
8042   if (last.is_null()) return Local<Context>();
8043   return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8044 }
8045 
ThrowException(v8::Local<v8::Value> value)8046 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8047   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8048   ENTER_V8(isolate);
8049   // If we're passed an empty handle, we throw an undefined exception
8050   // to deal more gracefully with out of memory situations.
8051   if (value.IsEmpty()) {
8052     isolate->ScheduleThrow(isolate->heap()->undefined_value());
8053   } else {
8054     isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8055   }
8056   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8057 }
8058 
8059 
SetObjectGroupId(internal::Object ** object,UniqueId id)8060 void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
8061   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
8062   internal_isolate->global_handles()->SetObjectGroupId(
8063       i::Handle<i::Object>(object).location(), id);
8064 }
8065 
8066 
SetReferenceFromGroup(UniqueId id,internal::Object ** object)8067 void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
8068   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
8069   internal_isolate->global_handles()->SetReferenceFromGroup(
8070       id, i::Handle<i::Object>(object).location());
8071 }
8072 
8073 
SetReference(internal::Object ** parent,internal::Object ** child)8074 void Isolate::SetReference(internal::Object** parent,
8075                            internal::Object** child) {
8076   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
8077   i::Object** parent_location = i::Handle<i::Object>(parent).location();
8078   internal_isolate->global_handles()->SetReference(
8079       reinterpret_cast<i::HeapObject**>(parent_location),
8080       i::Handle<i::Object>(child).location());
8081 }
8082 
8083 
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8084 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8085   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8086   isolate->heap()->AddGCPrologueCallback(callback, gc_type);
8087 }
8088 
8089 
RemoveGCPrologueCallback(GCCallback callback)8090 void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8091   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8092   isolate->heap()->RemoveGCPrologueCallback(callback);
8093 }
8094 
8095 
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8096 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8097   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8098   isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
8099 }
8100 
8101 
RemoveGCEpilogueCallback(GCCallback callback)8102 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8103   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8104   isolate->heap()->RemoveGCEpilogueCallback(callback);
8105 }
8106 
8107 
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8108 void V8::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8109   i::Isolate* isolate = i::Isolate::Current();
8110   isolate->heap()->AddGCPrologueCallback(
8111       reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
8112 }
8113 
8114 
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8115 void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8116   i::Isolate* isolate = i::Isolate::Current();
8117   isolate->heap()->AddGCEpilogueCallback(
8118       reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
8119 }
8120 
SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8121 void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8122   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8123   isolate->heap()->SetEmbedderHeapTracer(tracer);
8124 }
8125 
TerminateExecution()8126 void Isolate::TerminateExecution() {
8127   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8128   isolate->stack_guard()->RequestTerminateExecution();
8129 }
8130 
8131 
IsExecutionTerminating()8132 bool Isolate::IsExecutionTerminating() {
8133   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8134   return IsExecutionTerminatingCheck(isolate);
8135 }
8136 
8137 
CancelTerminateExecution()8138 void Isolate::CancelTerminateExecution() {
8139   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8140   isolate->stack_guard()->ClearTerminateExecution();
8141   isolate->CancelTerminateExecution();
8142 }
8143 
8144 
RequestInterrupt(InterruptCallback callback,void * data)8145 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8146   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8147   isolate->RequestInterrupt(callback, data);
8148 }
8149 
8150 
RequestGarbageCollectionForTesting(GarbageCollectionType type)8151 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8152   CHECK(i::FLAG_expose_gc);
8153   if (type == kMinorGarbageCollection) {
8154     reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8155         i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8156         kGCCallbackFlagForced);
8157   } else {
8158     DCHECK_EQ(kFullGarbageCollection, type);
8159     reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
8160         i::Heap::kAbortIncrementalMarkingMask,
8161         i::GarbageCollectionReason::kTesting, kGCCallbackFlagForced);
8162   }
8163 }
8164 
8165 
GetCurrent()8166 Isolate* Isolate::GetCurrent() {
8167   i::Isolate* isolate = i::Isolate::Current();
8168   return reinterpret_cast<Isolate*>(isolate);
8169 }
8170 
8171 
New(const Isolate::CreateParams & params)8172 Isolate* Isolate::New(const Isolate::CreateParams& params) {
8173   i::Isolate* isolate = new i::Isolate(false);
8174   Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
8175   CHECK(params.array_buffer_allocator != NULL);
8176   isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8177   if (params.snapshot_blob != NULL) {
8178     isolate->set_snapshot_blob(params.snapshot_blob);
8179   } else {
8180     isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8181   }
8182   if (params.entry_hook) {
8183     isolate->set_function_entry_hook(params.entry_hook);
8184   }
8185   auto code_event_handler = params.code_event_handler;
8186 #ifdef ENABLE_GDB_JIT_INTERFACE
8187   if (code_event_handler == nullptr && i::FLAG_gdbjit) {
8188     code_event_handler = i::GDBJITInterface::EventHandler;
8189   }
8190 #endif  // ENABLE_GDB_JIT_INTERFACE
8191   if (code_event_handler) {
8192     isolate->InitializeLoggingAndCounters();
8193     isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
8194                                            code_event_handler);
8195   }
8196   if (params.counter_lookup_callback) {
8197     v8_isolate->SetCounterFunction(params.counter_lookup_callback);
8198   }
8199 
8200   if (params.create_histogram_callback) {
8201     v8_isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8202   }
8203 
8204   if (params.add_histogram_sample_callback) {
8205     v8_isolate->SetAddHistogramSampleFunction(
8206         params.add_histogram_sample_callback);
8207   }
8208 
8209   isolate->set_api_external_references(params.external_references);
8210   isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8211   SetResourceConstraints(isolate, params.constraints);
8212   // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
8213   Isolate::Scope isolate_scope(v8_isolate);
8214   if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
8215     isolate->Init(NULL);
8216   }
8217   return v8_isolate;
8218 }
8219 
8220 
Dispose()8221 void Isolate::Dispose() {
8222   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8223   if (!Utils::ApiCheck(!isolate->IsInUse(),
8224                        "v8::Isolate::Dispose()",
8225                        "Disposing the isolate that is entered by a thread.")) {
8226     return;
8227   }
8228   isolate->TearDown();
8229 }
8230 
8231 
DiscardThreadSpecificMetadata()8232 void Isolate::DiscardThreadSpecificMetadata() {
8233   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8234   isolate->DiscardPerThreadDataForThisThread();
8235 }
8236 
8237 
Enter()8238 void Isolate::Enter() {
8239   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8240   isolate->Enter();
8241 }
8242 
8243 
Exit()8244 void Isolate::Exit() {
8245   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8246   isolate->Exit();
8247 }
8248 
8249 
SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8250 void Isolate::SetAbortOnUncaughtExceptionCallback(
8251     AbortOnUncaughtExceptionCallback callback) {
8252   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8253   isolate->SetAbortOnUncaughtExceptionCallback(callback);
8254 }
8255 
8256 
DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8257 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8258     Isolate* isolate,
8259     Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8260     : on_failure_(on_failure) {
8261   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8262   if (on_failure_ == CRASH_ON_FAILURE) {
8263     internal_ = reinterpret_cast<void*>(
8264         new i::DisallowJavascriptExecution(i_isolate));
8265   } else {
8266     DCHECK_EQ(THROW_ON_FAILURE, on_failure);
8267     internal_ = reinterpret_cast<void*>(
8268         new i::ThrowOnJavascriptExecution(i_isolate));
8269   }
8270 }
8271 
8272 
~DisallowJavascriptExecutionScope()8273 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8274   if (on_failure_ == CRASH_ON_FAILURE) {
8275     delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
8276   } else {
8277     delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
8278   }
8279 }
8280 
8281 
AllowJavascriptExecutionScope(Isolate * isolate)8282 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8283     Isolate* isolate) {
8284   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8285   internal_assert_ = reinterpret_cast<void*>(
8286       new i::AllowJavascriptExecution(i_isolate));
8287   internal_throws_ = reinterpret_cast<void*>(
8288       new i::NoThrowOnJavascriptExecution(i_isolate));
8289 }
8290 
8291 
~AllowJavascriptExecutionScope()8292 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8293   delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
8294   delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
8295 }
8296 
8297 
SuppressMicrotaskExecutionScope(Isolate * isolate)8298 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8299     Isolate* isolate)
8300     : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
8301   isolate_->handle_scope_implementer()->IncrementCallDepth();
8302   isolate_->handle_scope_implementer()->IncrementMicrotasksSuppressions();
8303 }
8304 
8305 
~SuppressMicrotaskExecutionScope()8306 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8307   isolate_->handle_scope_implementer()->DecrementMicrotasksSuppressions();
8308   isolate_->handle_scope_implementer()->DecrementCallDepth();
8309 }
8310 
8311 
GetHeapStatistics(HeapStatistics * heap_statistics)8312 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8313   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8314   i::Heap* heap = isolate->heap();
8315   heap_statistics->total_heap_size_ = heap->CommittedMemory();
8316   heap_statistics->total_heap_size_executable_ =
8317       heap->CommittedMemoryExecutable();
8318   heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8319   heap_statistics->total_available_size_ = heap->Available();
8320   heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8321   heap_statistics->heap_size_limit_ = heap->MaxReserved();
8322   heap_statistics->malloced_memory_ =
8323       isolate->allocator()->GetCurrentMemoryUsage();
8324   heap_statistics->peak_malloced_memory_ =
8325       isolate->allocator()->GetMaxMemoryUsage();
8326   heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8327 }
8328 
8329 
NumberOfHeapSpaces()8330 size_t Isolate::NumberOfHeapSpaces() {
8331   return i::LAST_SPACE - i::FIRST_SPACE + 1;
8332 }
8333 
8334 
GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)8335 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
8336                                      size_t index) {
8337   if (!space_statistics) return false;
8338   if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
8339     return false;
8340 
8341   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8342   i::Heap* heap = isolate->heap();
8343   i::Space* space = heap->space(static_cast<int>(index));
8344 
8345   space_statistics->space_name_ = heap->GetSpaceName(static_cast<int>(index));
8346   space_statistics->space_size_ = space->CommittedMemory();
8347   space_statistics->space_used_size_ = space->SizeOfObjects();
8348   space_statistics->space_available_size_ = space->Available();
8349   space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8350   return true;
8351 }
8352 
8353 
NumberOfTrackedHeapObjectTypes()8354 size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8355   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8356   i::Heap* heap = isolate->heap();
8357   return heap->NumberOfTrackedHeapObjectTypes();
8358 }
8359 
8360 
GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)8361 bool Isolate::GetHeapObjectStatisticsAtLastGC(
8362     HeapObjectStatistics* object_statistics, size_t type_index) {
8363   if (!object_statistics) return false;
8364   if (V8_LIKELY(!i::FLAG_gc_stats)) return false;
8365 
8366   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8367   i::Heap* heap = isolate->heap();
8368   if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
8369 
8370   const char* object_type;
8371   const char* object_sub_type;
8372   size_t object_count = heap->ObjectCountAtLastGC(type_index);
8373   size_t object_size = heap->ObjectSizeAtLastGC(type_index);
8374   if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
8375     // There should be no objects counted when the type is unknown.
8376     DCHECK_EQ(object_count, 0U);
8377     DCHECK_EQ(object_size, 0U);
8378     return false;
8379   }
8380 
8381   object_statistics->object_type_ = object_type;
8382   object_statistics->object_sub_type_ = object_sub_type;
8383   object_statistics->object_count_ = object_count;
8384   object_statistics->object_size_ = object_size;
8385   return true;
8386 }
8387 
GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)8388 bool Isolate::GetHeapCodeAndMetadataStatistics(
8389     HeapCodeStatistics* code_statistics) {
8390   if (!code_statistics) return false;
8391 
8392   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8393   isolate->heap()->CollectCodeStatistics();
8394 
8395   code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
8396   code_statistics->bytecode_and_metadata_size_ =
8397       isolate->bytecode_and_metadata_size();
8398   return true;
8399 }
8400 
GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)8401 void Isolate::GetStackSample(const RegisterState& state, void** frames,
8402                              size_t frames_limit, SampleInfo* sample_info) {
8403   RegisterState regs = state;
8404   if (TickSample::GetStackSample(this, &regs, TickSample::kSkipCEntryFrame,
8405                                  frames, frames_limit, sample_info)) {
8406     return;
8407   }
8408   sample_info->frames_count = 0;
8409   sample_info->vm_state = OTHER;
8410   sample_info->external_callback_entry = nullptr;
8411 }
8412 
NumberOfPhantomHandleResetsSinceLastCall()8413 size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
8414   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8415   size_t result = isolate->global_handles()->NumberOfPhantomHandleResets();
8416   isolate->global_handles()->ResetNumberOfPhantomHandleResets();
8417   return result;
8418 }
8419 
SetEventLogger(LogEventCallback that)8420 void Isolate::SetEventLogger(LogEventCallback that) {
8421   // Do not overwrite the event logger if we want to log explicitly.
8422   if (i::FLAG_log_internal_timer_events) return;
8423   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8424   isolate->set_event_logger(that);
8425 }
8426 
8427 
AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)8428 void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
8429   if (callback == NULL) return;
8430   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8431   isolate->AddBeforeCallEnteredCallback(callback);
8432 }
8433 
8434 
RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)8435 void Isolate::RemoveBeforeCallEnteredCallback(
8436     BeforeCallEnteredCallback callback) {
8437   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8438   isolate->RemoveBeforeCallEnteredCallback(callback);
8439 }
8440 
8441 
AddCallCompletedCallback(CallCompletedCallback callback)8442 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
8443   if (callback == NULL) return;
8444   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8445   isolate->AddCallCompletedCallback(callback);
8446 }
8447 
8448 
RemoveCallCompletedCallback(CallCompletedCallback callback)8449 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
8450   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8451   isolate->RemoveCallCompletedCallback(callback);
8452 }
8453 
8454 
AddCallCompletedCallback(DeprecatedCallCompletedCallback callback)8455 void Isolate::AddCallCompletedCallback(
8456     DeprecatedCallCompletedCallback callback) {
8457   AddCallCompletedCallback(reinterpret_cast<CallCompletedCallback>(callback));
8458 }
8459 
8460 
RemoveCallCompletedCallback(DeprecatedCallCompletedCallback callback)8461 void Isolate::RemoveCallCompletedCallback(
8462     DeprecatedCallCompletedCallback callback) {
8463   RemoveCallCompletedCallback(
8464       reinterpret_cast<CallCompletedCallback>(callback));
8465 }
8466 
SetPromiseHook(PromiseHook hook)8467 void Isolate::SetPromiseHook(PromiseHook hook) {
8468   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8469   isolate->SetPromiseHook(hook);
8470 }
8471 
SetPromiseRejectCallback(PromiseRejectCallback callback)8472 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
8473   if (callback == NULL) return;
8474   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8475   isolate->SetPromiseRejectCallback(callback);
8476 }
8477 
8478 
RunMicrotasks()8479 void Isolate::RunMicrotasks() {
8480   DCHECK(MicrotasksPolicy::kScoped != GetMicrotasksPolicy());
8481   reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
8482 }
8483 
8484 
EnqueueMicrotask(Local<Function> microtask)8485 void Isolate::EnqueueMicrotask(Local<Function> microtask) {
8486   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8487   isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
8488 }
8489 
8490 
EnqueueMicrotask(MicrotaskCallback microtask,void * data)8491 void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
8492   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8493   i::HandleScope scope(isolate);
8494   i::Handle<i::CallHandlerInfo> callback_info =
8495       i::Handle<i::CallHandlerInfo>::cast(
8496           isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE));
8497   SET_FIELD_WRAPPED(callback_info, set_callback, microtask);
8498   SET_FIELD_WRAPPED(callback_info, set_data, data);
8499   isolate->EnqueueMicrotask(callback_info);
8500 }
8501 
8502 
SetAutorunMicrotasks(bool autorun)8503 void Isolate::SetAutorunMicrotasks(bool autorun) {
8504   SetMicrotasksPolicy(
8505       autorun ? MicrotasksPolicy::kAuto : MicrotasksPolicy::kExplicit);
8506 }
8507 
8508 
WillAutorunMicrotasks() const8509 bool Isolate::WillAutorunMicrotasks() const {
8510   return GetMicrotasksPolicy() == MicrotasksPolicy::kAuto;
8511 }
8512 
8513 
SetMicrotasksPolicy(MicrotasksPolicy policy)8514 void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
8515   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8516   isolate->handle_scope_implementer()->set_microtasks_policy(policy);
8517 }
8518 
8519 
GetMicrotasksPolicy() const8520 MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
8521   i::Isolate* isolate =
8522       reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
8523   return isolate->handle_scope_implementer()->microtasks_policy();
8524 }
8525 
8526 
AddMicrotasksCompletedCallback(MicrotasksCompletedCallback callback)8527 void Isolate::AddMicrotasksCompletedCallback(
8528     MicrotasksCompletedCallback callback) {
8529   DCHECK(callback);
8530   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8531   isolate->AddMicrotasksCompletedCallback(callback);
8532 }
8533 
8534 
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallback callback)8535 void Isolate::RemoveMicrotasksCompletedCallback(
8536     MicrotasksCompletedCallback callback) {
8537   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8538   isolate->RemoveMicrotasksCompletedCallback(callback);
8539 }
8540 
8541 
SetUseCounterCallback(UseCounterCallback callback)8542 void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
8543   reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
8544 }
8545 
8546 
SetCounterFunction(CounterLookupCallback callback)8547 void Isolate::SetCounterFunction(CounterLookupCallback callback) {
8548   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8549   isolate->stats_table()->SetCounterFunction(callback);
8550   isolate->InitializeLoggingAndCounters();
8551   isolate->counters()->ResetCounters();
8552 }
8553 
8554 
SetCreateHistogramFunction(CreateHistogramCallback callback)8555 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
8556   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8557   isolate->stats_table()->SetCreateHistogramFunction(callback);
8558   isolate->InitializeLoggingAndCounters();
8559   isolate->counters()->ResetHistograms();
8560 }
8561 
8562 
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)8563 void Isolate::SetAddHistogramSampleFunction(
8564     AddHistogramSampleCallback callback) {
8565   reinterpret_cast<i::Isolate*>(this)
8566       ->stats_table()
8567       ->SetAddHistogramSampleFunction(callback);
8568 }
8569 
8570 
IdleNotification(int idle_time_in_ms)8571 bool Isolate::IdleNotification(int idle_time_in_ms) {
8572   // Returning true tells the caller that it need not
8573   // continue to call IdleNotification.
8574   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8575   if (!i::FLAG_use_idle_notification) return true;
8576   return isolate->heap()->IdleNotification(idle_time_in_ms);
8577 }
8578 
8579 
IdleNotificationDeadline(double deadline_in_seconds)8580 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
8581   // Returning true tells the caller that it need not
8582   // continue to call IdleNotification.
8583   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8584   if (!i::FLAG_use_idle_notification) return true;
8585   return isolate->heap()->IdleNotification(deadline_in_seconds);
8586 }
8587 
8588 
LowMemoryNotification()8589 void Isolate::LowMemoryNotification() {
8590   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8591   {
8592     i::HistogramTimerScope idle_notification_scope(
8593         isolate->counters()->gc_low_memory_notification());
8594     TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
8595     isolate->heap()->CollectAllAvailableGarbage(
8596         i::GarbageCollectionReason::kLowMemoryNotification);
8597   }
8598 }
8599 
8600 
ContextDisposedNotification(bool dependant_context)8601 int Isolate::ContextDisposedNotification(bool dependant_context) {
8602   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8603   return isolate->heap()->NotifyContextDisposed(dependant_context);
8604 }
8605 
8606 
IsolateInForegroundNotification()8607 void Isolate::IsolateInForegroundNotification() {
8608   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8609   return isolate->IsolateInForegroundNotification();
8610 }
8611 
8612 
IsolateInBackgroundNotification()8613 void Isolate::IsolateInBackgroundNotification() {
8614   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8615   return isolate->IsolateInBackgroundNotification();
8616 }
8617 
MemoryPressureNotification(MemoryPressureLevel level)8618 void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
8619   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8620   bool on_isolate_thread =
8621       v8::Locker::IsActive()
8622           ? isolate->thread_manager()->IsLockedByCurrentThread()
8623           : i::ThreadId::Current().Equals(isolate->thread_id());
8624   isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
8625   isolate->allocator()->MemoryPressureNotification(level);
8626   isolate->compiler_dispatcher()->MemoryPressureNotification(level,
8627                                                              on_isolate_thread);
8628 }
8629 
SetRAILMode(RAILMode rail_mode)8630 void Isolate::SetRAILMode(RAILMode rail_mode) {
8631   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8632   return isolate->SetRAILMode(rail_mode);
8633 }
8634 
IncreaseHeapLimitForDebugging()8635 void Isolate::IncreaseHeapLimitForDebugging() {
8636   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8637   isolate->heap()->IncreaseHeapLimitForDebugging();
8638 }
8639 
RestoreOriginalHeapLimit()8640 void Isolate::RestoreOriginalHeapLimit() {
8641   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8642   isolate->heap()->RestoreOriginalHeapLimit();
8643 }
8644 
IsHeapLimitIncreasedForDebugging()8645 bool Isolate::IsHeapLimitIncreasedForDebugging() {
8646   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8647   return isolate->heap()->IsHeapLimitIncreasedForDebugging();
8648 }
8649 
SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)8650 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
8651                                      JitCodeEventHandler event_handler) {
8652   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8653   // Ensure that logging is initialized for our isolate.
8654   isolate->InitializeLoggingAndCounters();
8655   isolate->logger()->SetCodeEventHandler(options, event_handler);
8656 }
8657 
8658 
SetStackLimit(uintptr_t stack_limit)8659 void Isolate::SetStackLimit(uintptr_t stack_limit) {
8660   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8661   CHECK(stack_limit);
8662   isolate->stack_guard()->SetStackLimit(stack_limit);
8663 }
8664 
GetCodeRange(void ** start,size_t * length_in_bytes)8665 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
8666   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8667   if (isolate->heap()->memory_allocator()->code_range()->valid()) {
8668     *start = isolate->heap()->memory_allocator()->code_range()->start();
8669     *length_in_bytes =
8670         isolate->heap()->memory_allocator()->code_range()->size();
8671   } else {
8672     *start = NULL;
8673     *length_in_bytes = 0;
8674   }
8675 }
8676 
8677 
SetFatalErrorHandler(FatalErrorCallback that)8678 void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
8679   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8680   isolate->set_exception_behavior(that);
8681 }
8682 
SetOOMErrorHandler(OOMErrorCallback that)8683 void Isolate::SetOOMErrorHandler(OOMErrorCallback that) {
8684   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8685   isolate->set_oom_behavior(that);
8686 }
8687 
SetAllowCodeGenerationFromStringsCallback(AllowCodeGenerationFromStringsCallback callback)8688 void Isolate::SetAllowCodeGenerationFromStringsCallback(
8689     AllowCodeGenerationFromStringsCallback callback) {
8690   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8691   isolate->set_allow_code_gen_callback(callback);
8692 }
8693 
SetAllowWasmCompileCallback(AllowWasmCompileCallback callback)8694 void Isolate::SetAllowWasmCompileCallback(AllowWasmCompileCallback callback) {
8695   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8696   isolate->set_allow_wasm_compile_callback(callback);
8697 }
8698 
SetAllowWasmInstantiateCallback(AllowWasmInstantiateCallback callback)8699 void Isolate::SetAllowWasmInstantiateCallback(
8700     AllowWasmInstantiateCallback callback) {
8701   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8702   isolate->set_allow_wasm_instantiate_callback(callback);
8703 }
8704 
IsDead()8705 bool Isolate::IsDead() {
8706   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8707   return isolate->IsDead();
8708 }
8709 
AddMessageListener(MessageCallback that,Local<Value> data)8710 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
8711   return AddMessageListenerWithErrorLevel(that, kMessageError, data);
8712 }
8713 
AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)8714 bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
8715                                                int message_levels,
8716                                                Local<Value> data) {
8717   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8718   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8719   i::HandleScope scope(isolate);
8720   i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
8721   i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
8722   i::Handle<i::Foreign> foreign =
8723       isolate->factory()->NewForeign(FUNCTION_ADDR(that));
8724   listener->set(0, *foreign);
8725   listener->set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
8726                                   : *Utils::OpenHandle(*data));
8727   listener->set(2, i::Smi::FromInt(message_levels));
8728   list = i::TemplateList::Add(isolate, list, listener);
8729   isolate->heap()->SetMessageListeners(*list);
8730   return true;
8731 }
8732 
8733 
RemoveMessageListeners(MessageCallback that)8734 void Isolate::RemoveMessageListeners(MessageCallback that) {
8735   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8736   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8737   i::HandleScope scope(isolate);
8738   i::DisallowHeapAllocation no_gc;
8739   i::TemplateList* listeners = isolate->heap()->message_listeners();
8740   for (int i = 0; i < listeners->length(); i++) {
8741     if (listeners->get(i)->IsUndefined(isolate)) continue;  // skip deleted ones
8742     i::FixedArray* listener = i::FixedArray::cast(listeners->get(i));
8743     i::Foreign* callback_obj = i::Foreign::cast(listener->get(0));
8744     if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
8745       listeners->set(i, isolate->heap()->undefined_value());
8746     }
8747   }
8748 }
8749 
8750 
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)8751 void Isolate::SetFailedAccessCheckCallbackFunction(
8752     FailedAccessCheckCallback callback) {
8753   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8754   isolate->SetFailedAccessCheckCallback(callback);
8755 }
8756 
8757 
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)8758 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
8759     bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
8760   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8761   isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
8762                                                      options);
8763 }
8764 
8765 
VisitExternalResources(ExternalResourceVisitor * visitor)8766 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
8767   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8768   isolate->heap()->VisitExternalResources(visitor);
8769 }
8770 
8771 
IsInUse()8772 bool Isolate::IsInUse() {
8773   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8774   return isolate->IsInUse();
8775 }
8776 
8777 
8778 class VisitorAdapter : public i::ObjectVisitor {
8779  public:
VisitorAdapter(PersistentHandleVisitor * visitor)8780   explicit VisitorAdapter(PersistentHandleVisitor* visitor)
8781       : visitor_(visitor) {}
VisitPointers(i::Object ** start,i::Object ** end)8782   void VisitPointers(i::Object** start, i::Object** end) override {
8783     UNREACHABLE();
8784   }
8785   DISABLE_CFI_PERF
VisitEmbedderReference(i::Object ** p,uint16_t class_id)8786   void VisitEmbedderReference(i::Object** p, uint16_t class_id) override {
8787     Value* value = ToApi<Value>(i::Handle<i::Object>(p));
8788     visitor_->VisitPersistentHandle(
8789         reinterpret_cast<Persistent<Value>*>(&value), class_id);
8790   }
8791 
8792  private:
8793   PersistentHandleVisitor* visitor_;
8794 };
8795 
8796 
VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)8797 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
8798   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8799   i::DisallowHeapAllocation no_allocation;
8800   VisitorAdapter visitor_adapter(visitor);
8801   isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
8802 }
8803 
8804 
VisitHandlesForPartialDependence(PersistentHandleVisitor * visitor)8805 void Isolate::VisitHandlesForPartialDependence(
8806     PersistentHandleVisitor* visitor) {
8807   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8808   i::DisallowHeapAllocation no_allocation;
8809   VisitorAdapter visitor_adapter(visitor);
8810   isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
8811       &visitor_adapter);
8812 }
8813 
8814 
VisitWeakHandles(PersistentHandleVisitor * visitor)8815 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
8816   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8817   i::DisallowHeapAllocation no_allocation;
8818   VisitorAdapter visitor_adapter(visitor);
8819   isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds(
8820       &visitor_adapter);
8821 }
8822 
8823 
MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)8824 MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
8825     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8826       run_(type == MicrotasksScope::kRunMicrotasks) {
8827   auto handle_scope_implementer = isolate_->handle_scope_implementer();
8828   if (run_) handle_scope_implementer->IncrementMicrotasksScopeDepth();
8829 #ifdef DEBUG
8830   if (!run_) handle_scope_implementer->IncrementDebugMicrotasksScopeDepth();
8831 #endif
8832 }
8833 
8834 
~MicrotasksScope()8835 MicrotasksScope::~MicrotasksScope() {
8836   auto handle_scope_implementer = isolate_->handle_scope_implementer();
8837   if (run_) {
8838     handle_scope_implementer->DecrementMicrotasksScopeDepth();
8839     if (MicrotasksPolicy::kScoped ==
8840         handle_scope_implementer->microtasks_policy()) {
8841       PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
8842     }
8843   }
8844 #ifdef DEBUG
8845   if (!run_) handle_scope_implementer->DecrementDebugMicrotasksScopeDepth();
8846 #endif
8847 }
8848 
8849 
PerformCheckpoint(Isolate * v8Isolate)8850 void MicrotasksScope::PerformCheckpoint(Isolate* v8Isolate) {
8851   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
8852   if (IsExecutionTerminatingCheck(isolate)) return;
8853   auto handle_scope_implementer = isolate->handle_scope_implementer();
8854   if (!handle_scope_implementer->GetMicrotasksScopeDepth() &&
8855       !handle_scope_implementer->HasMicrotasksSuppressions()) {
8856     isolate->RunMicrotasks();
8857   }
8858 }
8859 
8860 
GetCurrentDepth(Isolate * v8Isolate)8861 int MicrotasksScope::GetCurrentDepth(Isolate* v8Isolate) {
8862   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
8863   return isolate->handle_scope_implementer()->GetMicrotasksScopeDepth();
8864 }
8865 
IsRunningMicrotasks(Isolate * v8Isolate)8866 bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8Isolate) {
8867   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
8868   return isolate->IsRunningMicrotasks();
8869 }
8870 
Utf8Value(v8::Local<v8::Value> obj)8871 String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
8872     : str_(NULL), length_(0) {
8873   if (obj.IsEmpty()) return;
8874   i::Isolate* isolate = i::Isolate::Current();
8875   Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
8876   ENTER_V8(isolate);
8877   i::HandleScope scope(isolate);
8878   Local<Context> context = v8_isolate->GetCurrentContext();
8879   TryCatch try_catch(v8_isolate);
8880   Local<String> str;
8881   if (!obj->ToString(context).ToLocal(&str)) return;
8882   i::Handle<i::String> i_str = Utils::OpenHandle(*str);
8883   length_ = v8::Utf8Length(*i_str, isolate);
8884   str_ = i::NewArray<char>(length_ + 1);
8885   str->WriteUtf8(str_);
8886 }
8887 
8888 
~Utf8Value()8889 String::Utf8Value::~Utf8Value() {
8890   i::DeleteArray(str_);
8891 }
8892 
8893 
Value(v8::Local<v8::Value> obj)8894 String::Value::Value(v8::Local<v8::Value> obj) : str_(NULL), length_(0) {
8895   if (obj.IsEmpty()) return;
8896   i::Isolate* isolate = i::Isolate::Current();
8897   Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
8898   ENTER_V8(isolate);
8899   i::HandleScope scope(isolate);
8900   Local<Context> context = v8_isolate->GetCurrentContext();
8901   TryCatch try_catch(v8_isolate);
8902   Local<String> str;
8903   if (!obj->ToString(context).ToLocal(&str)) return;
8904   length_ = str->Length();
8905   str_ = i::NewArray<uint16_t>(length_ + 1);
8906   str->Write(str_);
8907 }
8908 
8909 
~Value()8910 String::Value::~Value() {
8911   i::DeleteArray(str_);
8912 }
8913 
8914 #define DEFINE_ERROR(NAME, name)                                         \
8915   Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) {      \
8916     i::Isolate* isolate = i::Isolate::Current();                         \
8917     LOG_API(isolate, NAME, New);                                         \
8918     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                            \
8919     i::Object* error;                                                    \
8920     {                                                                    \
8921       i::HandleScope scope(isolate);                                     \
8922       i::Handle<i::String> message = Utils::OpenHandle(*raw_message);    \
8923       i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
8924       error = *isolate->factory()->NewError(constructor, message);       \
8925     }                                                                    \
8926     i::Handle<i::Object> result(error, isolate);                         \
8927     return Utils::ToLocal(result);                                       \
8928   }
8929 
DEFINE_ERROR(RangeError,range_error)8930 DEFINE_ERROR(RangeError, range_error)
8931 DEFINE_ERROR(ReferenceError, reference_error)
8932 DEFINE_ERROR(SyntaxError, syntax_error)
8933 DEFINE_ERROR(TypeError, type_error)
8934 DEFINE_ERROR(Error, error)
8935 
8936 #undef DEFINE_ERROR
8937 
8938 
8939 Local<Message> Exception::CreateMessage(Isolate* isolate,
8940                                         Local<Value> exception) {
8941   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
8942   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8943   ENTER_V8(i_isolate);
8944   i::HandleScope scope(i_isolate);
8945   return Utils::MessageToLocal(
8946       scope.CloseAndEscape(i_isolate->CreateMessage(obj, NULL)));
8947 }
8948 
8949 
CreateMessage(Local<Value> exception)8950 Local<Message> Exception::CreateMessage(Local<Value> exception) {
8951   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
8952   if (!obj->IsHeapObject()) return Local<Message>();
8953   i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
8954   return CreateMessage(reinterpret_cast<Isolate*>(isolate), exception);
8955 }
8956 
8957 
GetStackTrace(Local<Value> exception)8958 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
8959   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
8960   if (!obj->IsJSObject()) return Local<StackTrace>();
8961   i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
8962   i::Isolate* isolate = js_obj->GetIsolate();
8963   ENTER_V8(isolate);
8964   return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
8965 }
8966 
8967 
8968 // --- D e b u g   S u p p o r t ---
8969 
SetDebugEventListener(Isolate * isolate,EventCallback that,Local<Value> data)8970 bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that,
8971                                   Local<Value> data) {
8972   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8973   ENTER_V8(i_isolate);
8974   i::HandleScope scope(i_isolate);
8975   if (that == nullptr) {
8976     i_isolate->debug()->SetDebugDelegate(nullptr, false);
8977   } else {
8978     i::Handle<i::Object> i_data = i_isolate->factory()->undefined_value();
8979     if (!data.IsEmpty()) i_data = Utils::OpenHandle(*data);
8980     i::NativeDebugDelegate* delegate =
8981         new i::NativeDebugDelegate(i_isolate, that, i_data);
8982     i_isolate->debug()->SetDebugDelegate(delegate, true);
8983   }
8984   return true;
8985 }
8986 
DebugBreak(Isolate * isolate)8987 void Debug::DebugBreak(Isolate* isolate) {
8988   reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
8989 }
8990 
8991 
CancelDebugBreak(Isolate * isolate)8992 void Debug::CancelDebugBreak(Isolate* isolate) {
8993   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8994   internal_isolate->stack_guard()->ClearDebugBreak();
8995 }
8996 
8997 
CheckDebugBreak(Isolate * isolate)8998 bool Debug::CheckDebugBreak(Isolate* isolate) {
8999   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9000   return internal_isolate->stack_guard()->CheckDebugBreak();
9001 }
9002 
SetMessageHandler(Isolate * isolate,v8::Debug::MessageHandler handler)9003 void Debug::SetMessageHandler(Isolate* isolate,
9004                               v8::Debug::MessageHandler handler) {}
9005 
SendCommand(Isolate * isolate,const uint16_t * command,int length,ClientData * client_data)9006 void Debug::SendCommand(Isolate* isolate, const uint16_t* command, int length,
9007                         ClientData* client_data) {}
9008 
Call(Local<Context> context,v8::Local<v8::Function> fun,v8::Local<v8::Value> data)9009 MaybeLocal<Value> Debug::Call(Local<Context> context,
9010                               v8::Local<v8::Function> fun,
9011                               v8::Local<v8::Value> data) {
9012   PREPARE_FOR_EXECUTION(context, Debug, Call, Value);
9013   i::Handle<i::Object> data_obj;
9014   if (data.IsEmpty()) {
9015     data_obj = isolate->factory()->undefined_value();
9016   } else {
9017     data_obj = Utils::OpenHandle(*data);
9018   }
9019   Local<Value> result;
9020   has_pending_exception =
9021       !ToLocal<Value>(isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj),
9022                       &result);
9023   RETURN_ON_FAILED_EXECUTION(Value);
9024   RETURN_ESCAPED(result);
9025 }
9026 
9027 
ProcessDebugMessages(Isolate * isolate)9028 void Debug::ProcessDebugMessages(Isolate* isolate) {}
9029 
GetDebugContext(Isolate * isolate)9030 Local<Context> Debug::GetDebugContext(Isolate* isolate) {
9031   return debug::GetDebugContext(isolate);
9032 }
9033 
9034 
GetDebuggedContext(Isolate * isolate)9035 MaybeLocal<Context> Debug::GetDebuggedContext(Isolate* isolate) {
9036   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9037   ENTER_V8(i_isolate);
9038   if (!i_isolate->debug()->in_debug_scope()) return MaybeLocal<Context>();
9039   i::Handle<i::Object> calling = i_isolate->GetCallingNativeContext();
9040   if (calling.is_null()) return MaybeLocal<Context>();
9041   return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
9042 }
9043 
SetLiveEditEnabled(Isolate * isolate,bool enable)9044 void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
9045   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9046   internal_isolate->debug()->set_live_edit_enabled(enable);
9047 }
9048 
IsTailCallEliminationEnabled(Isolate * isolate)9049 bool Debug::IsTailCallEliminationEnabled(Isolate* isolate) {
9050   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9051   return internal_isolate->is_tail_call_elimination_enabled();
9052 }
9053 
SetTailCallEliminationEnabled(Isolate * isolate,bool enabled)9054 void Debug::SetTailCallEliminationEnabled(Isolate* isolate, bool enabled) {
9055   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9056   internal_isolate->SetTailCallEliminationEnabled(enabled);
9057 }
9058 
GetInternalProperties(Isolate * v8_isolate,Local<Value> value)9059 MaybeLocal<Array> Debug::GetInternalProperties(Isolate* v8_isolate,
9060                                                Local<Value> value) {
9061   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9062   ENTER_V8(isolate);
9063   i::Handle<i::Object> val = Utils::OpenHandle(*value);
9064   i::Handle<i::JSArray> result;
9065   if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result))
9066     return MaybeLocal<Array>();
9067   return Utils::ToLocal(result);
9068 }
9069 
GetDebugContext(Isolate * isolate)9070 Local<Context> debug::GetDebugContext(Isolate* isolate) {
9071   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9072   ENTER_V8(i_isolate);
9073   return Utils::ToLocal(i_isolate->debug()->GetDebugContext());
9074 }
9075 
Call(Local<Context> context,v8::Local<v8::Function> fun,v8::Local<v8::Value> data)9076 MaybeLocal<Value> debug::Call(Local<Context> context,
9077                               v8::Local<v8::Function> fun,
9078                               v8::Local<v8::Value> data) {
9079   return Debug::Call(context, fun, data);
9080 }
9081 
SetLiveEditEnabled(Isolate * isolate,bool enable)9082 void debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
9083   Debug::SetLiveEditEnabled(isolate, enable);
9084 }
9085 
DebugBreak(Isolate * isolate)9086 void debug::DebugBreak(Isolate* isolate) { Debug::DebugBreak(isolate); }
9087 
CancelDebugBreak(Isolate * isolate)9088 void debug::CancelDebugBreak(Isolate* isolate) {
9089   Debug::CancelDebugBreak(isolate);
9090 }
9091 
GetInternalProperties(Isolate * isolate,Local<Value> value)9092 MaybeLocal<Array> debug::GetInternalProperties(Isolate* isolate,
9093                                                Local<Value> value) {
9094   return Debug::GetInternalProperties(isolate, value);
9095 }
9096 
ChangeBreakOnException(Isolate * isolate,ExceptionBreakState type)9097 void debug::ChangeBreakOnException(Isolate* isolate, ExceptionBreakState type) {
9098   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9099   internal_isolate->debug()->ChangeBreakOnException(
9100       i::BreakException, type == BreakOnAnyException);
9101   internal_isolate->debug()->ChangeBreakOnException(i::BreakUncaughtException,
9102                                                     type != NoBreakOnException);
9103 }
9104 
SetBreakPointsActive(Isolate * v8_isolate,bool is_active)9105 void debug::SetBreakPointsActive(Isolate* v8_isolate, bool is_active) {
9106   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9107   ENTER_V8(isolate);
9108   isolate->debug()->set_break_points_active(is_active);
9109 }
9110 
SetOutOfMemoryCallback(Isolate * isolate,OutOfMemoryCallback callback,void * data)9111 void debug::SetOutOfMemoryCallback(Isolate* isolate,
9112                                    OutOfMemoryCallback callback, void* data) {
9113   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9114   ENTER_V8(i_isolate);
9115   i_isolate->heap()->SetOutOfMemoryCallback(callback, data);
9116 }
9117 
PrepareStep(Isolate * v8_isolate,StepAction action)9118 void debug::PrepareStep(Isolate* v8_isolate, StepAction action) {
9119   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9120   ENTER_V8(isolate);
9121   CHECK(isolate->debug()->CheckExecutionState());
9122   // Clear all current stepping setup.
9123   isolate->debug()->ClearStepping();
9124   // Prepare step.
9125   isolate->debug()->PrepareStep(static_cast<i::StepAction>(action));
9126 }
9127 
HasNonBlackboxedFrameOnStack(Isolate * v8_isolate)9128 bool debug::HasNonBlackboxedFrameOnStack(Isolate* v8_isolate) {
9129   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9130   ENTER_V8(isolate);
9131   i::HandleScope scope(isolate);
9132   for (i::StackTraceFrameIterator it(isolate); !it.done(); it.Advance()) {
9133     if (!it.is_javascript()) continue;
9134     if (!isolate->debug()->IsFrameBlackboxed(it.javascript_frame())) {
9135       return true;
9136     }
9137   }
9138   return false;
9139 }
9140 
GetIsolate() const9141 v8::Isolate* debug::Script::GetIsolate() const {
9142   return reinterpret_cast<v8::Isolate*>(Utils::OpenHandle(this)->GetIsolate());
9143 }
9144 
OriginOptions() const9145 ScriptOriginOptions debug::Script::OriginOptions() const {
9146   return Utils::OpenHandle(this)->origin_options();
9147 }
9148 
WasCompiled() const9149 bool debug::Script::WasCompiled() const {
9150   return Utils::OpenHandle(this)->compilation_state() ==
9151          i::Script::COMPILATION_STATE_COMPILED;
9152 }
9153 
Id() const9154 int debug::Script::Id() const { return Utils::OpenHandle(this)->id(); }
9155 
LineOffset() const9156 int debug::Script::LineOffset() const {
9157   return Utils::OpenHandle(this)->line_offset();
9158 }
9159 
ColumnOffset() const9160 int debug::Script::ColumnOffset() const {
9161   return Utils::OpenHandle(this)->column_offset();
9162 }
9163 
LineEnds() const9164 std::vector<int> debug::Script::LineEnds() const {
9165   i::Handle<i::Script> script = Utils::OpenHandle(this);
9166   if (script->type() == i::Script::TYPE_WASM) return std::vector<int>();
9167   i::Isolate* isolate = script->GetIsolate();
9168   i::HandleScope scope(isolate);
9169   i::Script::InitLineEnds(script);
9170   CHECK(script->line_ends()->IsFixedArray());
9171   i::Handle<i::FixedArray> line_ends(i::FixedArray::cast(script->line_ends()));
9172   std::vector<int> result(line_ends->length());
9173   for (int i = 0; i < line_ends->length(); ++i) {
9174     i::Smi* line_end = i::Smi::cast(line_ends->get(i));
9175     result[i] = line_end->value();
9176   }
9177   return result;
9178 }
9179 
Name() const9180 MaybeLocal<String> debug::Script::Name() const {
9181   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9182   i::HandleScope handle_scope(isolate);
9183   i::Handle<i::Script> script = Utils::OpenHandle(this);
9184   i::Handle<i::Object> value(script->name(), isolate);
9185   if (!value->IsString()) return MaybeLocal<String>();
9186   return Utils::ToLocal(
9187       handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9188 }
9189 
SourceURL() const9190 MaybeLocal<String> debug::Script::SourceURL() const {
9191   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9192   i::HandleScope handle_scope(isolate);
9193   i::Handle<i::Script> script = Utils::OpenHandle(this);
9194   i::Handle<i::Object> value(script->source_url(), isolate);
9195   if (!value->IsString()) return MaybeLocal<String>();
9196   return Utils::ToLocal(
9197       handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9198 }
9199 
SourceMappingURL() const9200 MaybeLocal<String> debug::Script::SourceMappingURL() const {
9201   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9202   i::HandleScope handle_scope(isolate);
9203   i::Handle<i::Script> script = Utils::OpenHandle(this);
9204   i::Handle<i::Object> value(script->source_mapping_url(), isolate);
9205   if (!value->IsString()) return MaybeLocal<String>();
9206   return Utils::ToLocal(
9207       handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9208 }
9209 
ContextData() const9210 MaybeLocal<Value> debug::Script::ContextData() const {
9211   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9212   i::HandleScope handle_scope(isolate);
9213   i::Handle<i::Script> script = Utils::OpenHandle(this);
9214   i::Handle<i::Object> value(script->context_data(), isolate);
9215   return Utils::ToLocal(handle_scope.CloseAndEscape(value));
9216 }
9217 
Source() const9218 MaybeLocal<String> debug::Script::Source() const {
9219   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9220   i::HandleScope handle_scope(isolate);
9221   i::Handle<i::Script> script = Utils::OpenHandle(this);
9222   i::Handle<i::Object> value(script->source(), isolate);
9223   if (!value->IsString()) return MaybeLocal<String>();
9224   return Utils::ToLocal(
9225       handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9226 }
9227 
IsWasm() const9228 bool debug::Script::IsWasm() const {
9229   return Utils::OpenHandle(this)->type() == i::Script::TYPE_WASM;
9230 }
9231 
IsModule() const9232 bool debug::Script::IsModule() const {
9233   return Utils::OpenHandle(this)->origin_options().IsModule();
9234 }
9235 
9236 namespace {
GetSmiValue(i::Handle<i::FixedArray> array,int index)9237 int GetSmiValue(i::Handle<i::FixedArray> array, int index) {
9238   return i::Smi::cast(array->get(index))->value();
9239 }
9240 }  // namespace
9241 
GetPossibleBreakpoints(const debug::Location & start,const debug::Location & end,std::vector<debug::Location> * locations) const9242 bool debug::Script::GetPossibleBreakpoints(
9243     const debug::Location& start, const debug::Location& end,
9244     std::vector<debug::Location>* locations) const {
9245   CHECK(!start.IsEmpty());
9246   i::Handle<i::Script> script = Utils::OpenHandle(this);
9247   if (script->type() == i::Script::TYPE_WASM) {
9248     i::Handle<i::WasmCompiledModule> compiled_module(
9249         i::WasmCompiledModule::cast(script->wasm_compiled_module()));
9250     return compiled_module->GetPossibleBreakpoints(start, end, locations);
9251   }
9252 
9253   i::Script::InitLineEnds(script);
9254   CHECK(script->line_ends()->IsFixedArray());
9255   i::Isolate* isolate = script->GetIsolate();
9256   i::Handle<i::FixedArray> line_ends =
9257       i::Handle<i::FixedArray>::cast(i::handle(script->line_ends(), isolate));
9258   CHECK(line_ends->length());
9259 
9260   int start_offset = GetSourcePosition(start);
9261   int end_offset;
9262   if (end.IsEmpty()) {
9263     end_offset = GetSmiValue(line_ends, line_ends->length() - 1) + 1;
9264   } else {
9265     end_offset = GetSourcePosition(end);
9266   }
9267   if (start_offset >= end_offset) return true;
9268 
9269   std::set<int> offsets;
9270   if (!isolate->debug()->GetPossibleBreakpoints(script, start_offset,
9271                                                 end_offset, &offsets)) {
9272     return false;
9273   }
9274 
9275   int current_line_end_index = 0;
9276   for (const auto& it : offsets) {
9277     int offset = it;
9278     while (offset > GetSmiValue(line_ends, current_line_end_index)) {
9279       ++current_line_end_index;
9280       CHECK(current_line_end_index < line_ends->length());
9281     }
9282     int line_offset = 0;
9283 
9284     if (current_line_end_index > 0) {
9285       line_offset = GetSmiValue(line_ends, current_line_end_index - 1) + 1;
9286     }
9287     locations->push_back(debug::Location(
9288         current_line_end_index + script->line_offset(),
9289         offset - line_offset +
9290             (current_line_end_index == 0 ? script->column_offset() : 0)));
9291   }
9292   return true;
9293 }
9294 
GetSourcePosition(const debug::Location & location) const9295 int debug::Script::GetSourcePosition(const debug::Location& location) const {
9296   i::Handle<i::Script> script = Utils::OpenHandle(this);
9297   if (script->type() == i::Script::TYPE_WASM) {
9298     // TODO(clemensh): Return the proper thing for wasm.
9299     return 0;
9300   }
9301 
9302   int line = std::max(location.GetLineNumber() - script->line_offset(), 0);
9303   int column = location.GetColumnNumber();
9304   if (line == 0) {
9305     column = std::max(0, column - script->column_offset());
9306   }
9307 
9308   i::Script::InitLineEnds(script);
9309   CHECK(script->line_ends()->IsFixedArray());
9310   i::Handle<i::FixedArray> line_ends = i::Handle<i::FixedArray>::cast(
9311       i::handle(script->line_ends(), script->GetIsolate()));
9312   CHECK(line_ends->length());
9313   if (line >= line_ends->length())
9314     return GetSmiValue(line_ends, line_ends->length() - 1);
9315   int line_offset = GetSmiValue(line_ends, line);
9316   if (line == 0) return std::min(column, line_offset);
9317   int prev_line_offset = GetSmiValue(line_ends, line - 1);
9318   return std::min(prev_line_offset + column + 1, line_offset);
9319 }
9320 
Cast(debug::Script * script)9321 debug::WasmScript* debug::WasmScript::Cast(debug::Script* script) {
9322   CHECK(script->IsWasm());
9323   return static_cast<WasmScript*>(script);
9324 }
9325 
NumFunctions() const9326 int debug::WasmScript::NumFunctions() const {
9327   i::DisallowHeapAllocation no_gc;
9328   i::Handle<i::Script> script = Utils::OpenHandle(this);
9329   DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9330   i::WasmCompiledModule* compiled_module =
9331       i::WasmCompiledModule::cast(script->wasm_compiled_module());
9332   DCHECK_GE(i::kMaxInt, compiled_module->module()->functions.size());
9333   return static_cast<int>(compiled_module->module()->functions.size());
9334 }
9335 
NumImportedFunctions() const9336 int debug::WasmScript::NumImportedFunctions() const {
9337   i::DisallowHeapAllocation no_gc;
9338   i::Handle<i::Script> script = Utils::OpenHandle(this);
9339   DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9340   i::WasmCompiledModule* compiled_module =
9341       i::WasmCompiledModule::cast(script->wasm_compiled_module());
9342   DCHECK_GE(i::kMaxInt, compiled_module->module()->num_imported_functions);
9343   return static_cast<int>(compiled_module->module()->num_imported_functions);
9344 }
9345 
GetFunctionRange(int function_index) const9346 std::pair<int, int> debug::WasmScript::GetFunctionRange(
9347     int function_index) const {
9348   i::DisallowHeapAllocation no_gc;
9349   i::Handle<i::Script> script = Utils::OpenHandle(this);
9350   DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9351   i::WasmCompiledModule* compiled_module =
9352       i::WasmCompiledModule::cast(script->wasm_compiled_module());
9353   DCHECK_LE(0, function_index);
9354   DCHECK_GT(compiled_module->module()->functions.size(), function_index);
9355   i::wasm::WasmFunction& func =
9356       compiled_module->module()->functions[function_index];
9357   DCHECK_GE(i::kMaxInt, func.code_start_offset);
9358   DCHECK_GE(i::kMaxInt, func.code_end_offset);
9359   return std::make_pair(static_cast<int>(func.code_start_offset),
9360                         static_cast<int>(func.code_end_offset));
9361 }
9362 
DisassembleFunction(int function_index) const9363 debug::WasmDisassembly debug::WasmScript::DisassembleFunction(
9364     int function_index) const {
9365   i::DisallowHeapAllocation no_gc;
9366   i::Handle<i::Script> script = Utils::OpenHandle(this);
9367   DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9368   i::WasmCompiledModule* compiled_module =
9369       i::WasmCompiledModule::cast(script->wasm_compiled_module());
9370   return compiled_module->DisassembleFunction(function_index);
9371 }
9372 
Location(int line_number,int column_number)9373 debug::Location::Location(int line_number, int column_number)
9374     : line_number_(line_number), column_number_(column_number) {
9375   CHECK(line_number >= 0);
9376   CHECK(column_number >= 0);
9377 }
9378 
Location()9379 debug::Location::Location()
9380     : line_number_(v8::Function::kLineOffsetNotFound),
9381       column_number_(v8::Function::kLineOffsetNotFound) {}
9382 
GetLineNumber() const9383 int debug::Location::GetLineNumber() const {
9384   CHECK(line_number_ >= 0);
9385   return line_number_;
9386 }
9387 
GetColumnNumber() const9388 int debug::Location::GetColumnNumber() const {
9389   CHECK(column_number_ >= 0);
9390   return column_number_;
9391 }
9392 
IsEmpty() const9393 bool debug::Location::IsEmpty() const {
9394   return line_number_ == -1 && column_number_ == -1;
9395 }
9396 
GetLoadedScripts(v8::Isolate * v8_isolate,PersistentValueVector<debug::Script> & scripts)9397 void debug::GetLoadedScripts(v8::Isolate* v8_isolate,
9398                              PersistentValueVector<debug::Script>& scripts) {
9399   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9400   ENTER_V8(isolate);
9401   // TODO(kozyatinskiy): remove this GC once tests are dealt with.
9402   isolate->heap()->CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask,
9403                                      i::GarbageCollectionReason::kDebugger);
9404   {
9405     i::DisallowHeapAllocation no_gc;
9406     i::Script::Iterator iterator(isolate);
9407     i::Script* script;
9408     while ((script = iterator.Next())) {
9409       if (script->type() != i::Script::TYPE_NORMAL) continue;
9410       if (script->HasValidSource()) {
9411         i::HandleScope handle_scope(isolate);
9412         i::Handle<i::Script> script_handle(script, isolate);
9413         scripts.Append(ToApiHandle<Script>(script_handle));
9414       }
9415     }
9416   }
9417 }
9418 
CompileInspectorScript(Isolate * v8_isolate,Local<String> source)9419 MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate,
9420                                                         Local<String> source) {
9421   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9422   PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, UnboundScript);
9423   i::ScriptData* script_data = NULL;
9424   i::Handle<i::String> str = Utils::OpenHandle(*source);
9425   i::Handle<i::SharedFunctionInfo> result;
9426   {
9427     ScriptOriginOptions origin_options;
9428     result = i::Compiler::GetSharedFunctionInfoForScript(
9429         str, i::Handle<i::Object>(), 0, 0, origin_options,
9430         i::Handle<i::Object>(), isolate->native_context(), NULL, &script_data,
9431         ScriptCompiler::kNoCompileOptions, i::INSPECTOR_CODE);
9432     has_pending_exception = result.is_null();
9433     RETURN_ON_FAILED_EXECUTION(UnboundScript);
9434   }
9435   RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
9436 }
9437 
SetDebugDelegate(Isolate * v8_isolate,debug::DebugDelegate * delegate)9438 void debug::SetDebugDelegate(Isolate* v8_isolate,
9439                              debug::DebugDelegate* delegate) {
9440   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9441   ENTER_V8(isolate);
9442   isolate->debug()->SetDebugDelegate(delegate, false);
9443 }
9444 
ResetBlackboxedStateCache(Isolate * v8_isolate,v8::Local<debug::Script> script)9445 void debug::ResetBlackboxedStateCache(Isolate* v8_isolate,
9446                                       v8::Local<debug::Script> script) {
9447   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9448   ENTER_V8(isolate);
9449   i::DisallowHeapAllocation no_gc;
9450   i::SharedFunctionInfo::ScriptIterator iter(Utils::OpenHandle(*script));
9451   while (i::SharedFunctionInfo* info = iter.Next()) {
9452     info->set_computed_debug_is_blackboxed(false);
9453   }
9454 }
9455 
EstimatedValueSize(Isolate * v8_isolate,v8::Local<v8::Value> value)9456 int debug::EstimatedValueSize(Isolate* v8_isolate, v8::Local<v8::Value> value) {
9457   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9458   ENTER_V8(isolate);
9459   i::Handle<i::Object> object = Utils::OpenHandle(*value);
9460   if (object->IsSmi()) return i::kPointerSize;
9461   CHECK(object->IsHeapObject());
9462   return i::Handle<i::HeapObject>::cast(object)->Size();
9463 }
9464 
EntriesPreview(Isolate * v8_isolate,v8::Local<v8::Value> value,bool * is_key_value)9465 v8::MaybeLocal<v8::Array> debug::EntriesPreview(Isolate* v8_isolate,
9466                                                 v8::Local<v8::Value> value,
9467                                                 bool* is_key_value) {
9468   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9469   ENTER_V8(isolate);
9470   if (value->IsMap()) {
9471     *is_key_value = true;
9472     return value.As<Map>()->AsArray();
9473   }
9474   if (value->IsSet()) {
9475     *is_key_value = false;
9476     return value.As<Set>()->AsArray();
9477   }
9478 
9479   i::Handle<i::Object> object = Utils::OpenHandle(*value);
9480   if (object->IsJSWeakCollection()) {
9481     *is_key_value = object->IsJSWeakMap();
9482     return Utils::ToLocal(i::JSWeakCollection::GetEntries(
9483         i::Handle<i::JSWeakCollection>::cast(object), 0));
9484   }
9485   if (object->IsJSMapIterator()) {
9486     i::Handle<i::JSMapIterator> iterator =
9487         i::Handle<i::JSMapIterator>::cast(object);
9488     int iterator_kind = i::Smi::cast(iterator->kind())->value();
9489     *is_key_value = iterator_kind == i::JSMapIterator::kKindEntries;
9490     if (!iterator->HasMore()) return v8::Array::New(v8_isolate);
9491     return Utils::ToLocal(MapAsArray(isolate, iterator->table(),
9492                                      i::Smi::cast(iterator->index())->value(),
9493                                      iterator_kind));
9494   }
9495   if (object->IsJSSetIterator()) {
9496     i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
9497     *is_key_value = false;
9498     if (!it->HasMore()) return v8::Array::New(v8_isolate);
9499     return Utils::ToLocal(
9500         SetAsArray(isolate, it->table(), i::Smi::cast(it->index())->value()));
9501   }
9502   return v8::MaybeLocal<v8::Array>();
9503 }
9504 
Script()9505 MaybeLocal<debug::Script> debug::GeneratorObject::Script() {
9506   i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
9507   i::Object* maybe_script = obj->function()->shared()->script();
9508   if (!maybe_script->IsScript()) return MaybeLocal<debug::Script>();
9509   i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
9510   return ToApiHandle<debug::Script>(script);
9511 }
9512 
Function()9513 Local<Function> debug::GeneratorObject::Function() {
9514   i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
9515   return Utils::ToLocal(handle(obj->function()));
9516 }
9517 
SuspendedLocation()9518 debug::Location debug::GeneratorObject::SuspendedLocation() {
9519   i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
9520   CHECK(obj->is_suspended());
9521   i::Object* maybe_script = obj->function()->shared()->script();
9522   if (!maybe_script->IsScript()) return debug::Location();
9523   i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
9524   i::Script::PositionInfo info;
9525   i::Script::GetPositionInfo(script, obj->source_position(), &info,
9526                              i::Script::WITH_OFFSET);
9527   return debug::Location(info.line, info.column);
9528 }
9529 
IsSuspended()9530 bool debug::GeneratorObject::IsSuspended() {
9531   return Utils::OpenHandle(this)->is_suspended();
9532 }
9533 
Cast(v8::Local<v8::Value> value)9534 v8::Local<debug::GeneratorObject> debug::GeneratorObject::Cast(
9535     v8::Local<v8::Value> value) {
9536   CHECK(value->IsGeneratorObject());
9537   return ToApiHandle<debug::GeneratorObject>(Utils::OpenHandle(*value));
9538 }
9539 
GetFunctionName() const9540 Local<String> CpuProfileNode::GetFunctionName() const {
9541   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9542   i::Isolate* isolate = node->isolate();
9543   const i::CodeEntry* entry = node->entry();
9544   i::Handle<i::String> name =
9545       isolate->factory()->InternalizeUtf8String(entry->name());
9546   if (!entry->has_name_prefix()) {
9547     return ToApiHandle<String>(name);
9548   } else {
9549     // We do not expect this to fail. Change this if it does.
9550     i::Handle<i::String> cons = isolate->factory()->NewConsString(
9551         isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
9552         name).ToHandleChecked();
9553     return ToApiHandle<String>(cons);
9554   }
9555 }
9556 
FunctionData(i::CoverageFunction * function,Local<debug::Script> script)9557 debug::Coverage::FunctionData::FunctionData(i::CoverageFunction* function,
9558                                             Local<debug::Script> script)
9559     : function_(function) {
9560   i::Handle<i::Script> i_script = v8::Utils::OpenHandle(*script);
9561   i::Script::PositionInfo start;
9562   i::Script::PositionInfo end;
9563   i::Script::GetPositionInfo(i_script, function->start, &start,
9564                              i::Script::WITH_OFFSET);
9565   i::Script::GetPositionInfo(i_script, function->end, &end,
9566                              i::Script::WITH_OFFSET);
9567   start_ = Location(start.line, start.column);
9568   end_ = Location(end.line, end.column);
9569 }
9570 
Count()9571 uint32_t debug::Coverage::FunctionData::Count() { return function_->count; }
9572 
Name()9573 MaybeLocal<String> debug::Coverage::FunctionData::Name() {
9574   return ToApiHandle<String>(function_->name);
9575 }
9576 
GetScript()9577 Local<debug::Script> debug::Coverage::ScriptData::GetScript() {
9578   return ToApiHandle<debug::Script>(script_->script);
9579 }
9580 
FunctionCount()9581 size_t debug::Coverage::ScriptData::FunctionCount() {
9582   return script_->functions.size();
9583 }
9584 
GetFunctionData(size_t i)9585 debug::Coverage::FunctionData debug::Coverage::ScriptData::GetFunctionData(
9586     size_t i) {
9587   return FunctionData(&script_->functions.at(i), GetScript());
9588 }
9589 
~Coverage()9590 debug::Coverage::~Coverage() { delete coverage_; }
9591 
ScriptCount()9592 size_t debug::Coverage::ScriptCount() { return coverage_->size(); }
9593 
GetScriptData(size_t i)9594 debug::Coverage::ScriptData debug::Coverage::GetScriptData(size_t i) {
9595   return ScriptData(&coverage_->at(i));
9596 }
9597 
Collect(Isolate * isolate,bool reset_count)9598 debug::Coverage debug::Coverage::Collect(Isolate* isolate, bool reset_count) {
9599   return Coverage(i::Coverage::Collect(reinterpret_cast<i::Isolate*>(isolate),
9600                                        reset_count));
9601 }
9602 
TogglePrecise(Isolate * isolate,bool enable)9603 void debug::Coverage::TogglePrecise(Isolate* isolate, bool enable) {
9604   i::Coverage::TogglePrecise(reinterpret_cast<i::Isolate*>(isolate), enable);
9605 }
9606 
GetFunctionNameStr() const9607 const char* CpuProfileNode::GetFunctionNameStr() const {
9608   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9609   return node->entry()->name();
9610 }
9611 
GetScriptId() const9612 int CpuProfileNode::GetScriptId() const {
9613   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9614   const i::CodeEntry* entry = node->entry();
9615   return entry->script_id();
9616 }
9617 
GetScriptResourceName() const9618 Local<String> CpuProfileNode::GetScriptResourceName() const {
9619   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9620   i::Isolate* isolate = node->isolate();
9621   return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
9622       node->entry()->resource_name()));
9623 }
9624 
GetScriptResourceNameStr() const9625 const char* CpuProfileNode::GetScriptResourceNameStr() const {
9626   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9627   return node->entry()->resource_name();
9628 }
9629 
GetLineNumber() const9630 int CpuProfileNode::GetLineNumber() const {
9631   return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
9632 }
9633 
9634 
GetColumnNumber() const9635 int CpuProfileNode::GetColumnNumber() const {
9636   return reinterpret_cast<const i::ProfileNode*>(this)->
9637       entry()->column_number();
9638 }
9639 
9640 
GetHitLineCount() const9641 unsigned int CpuProfileNode::GetHitLineCount() const {
9642   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9643   return node->GetHitLineCount();
9644 }
9645 
9646 
GetLineTicks(LineTick * entries,unsigned int length) const9647 bool CpuProfileNode::GetLineTicks(LineTick* entries,
9648                                   unsigned int length) const {
9649   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9650   return node->GetLineTicks(entries, length);
9651 }
9652 
9653 
GetBailoutReason() const9654 const char* CpuProfileNode::GetBailoutReason() const {
9655   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9656   return node->entry()->bailout_reason();
9657 }
9658 
9659 
GetHitCount() const9660 unsigned CpuProfileNode::GetHitCount() const {
9661   return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
9662 }
9663 
9664 
GetCallUid() const9665 unsigned CpuProfileNode::GetCallUid() const {
9666   return reinterpret_cast<const i::ProfileNode*>(this)->function_id();
9667 }
9668 
9669 
GetNodeId() const9670 unsigned CpuProfileNode::GetNodeId() const {
9671   return reinterpret_cast<const i::ProfileNode*>(this)->id();
9672 }
9673 
9674 
GetChildrenCount() const9675 int CpuProfileNode::GetChildrenCount() const {
9676   return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
9677 }
9678 
9679 
GetChild(int index) const9680 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
9681   const i::ProfileNode* child =
9682       reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
9683   return reinterpret_cast<const CpuProfileNode*>(child);
9684 }
9685 
9686 
GetDeoptInfos() const9687 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
9688   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9689   return node->deopt_infos();
9690 }
9691 
9692 
Delete()9693 void CpuProfile::Delete() {
9694   i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
9695   i::CpuProfiler* profiler = profile->cpu_profiler();
9696   DCHECK(profiler != nullptr);
9697   profiler->DeleteProfile(profile);
9698 }
9699 
9700 
GetTitle() const9701 Local<String> CpuProfile::GetTitle() const {
9702   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9703   i::Isolate* isolate = profile->top_down()->isolate();
9704   return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
9705       profile->title()));
9706 }
9707 
9708 
GetTopDownRoot() const9709 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
9710   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9711   return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
9712 }
9713 
9714 
GetSample(int index) const9715 const CpuProfileNode* CpuProfile::GetSample(int index) const {
9716   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9717   return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
9718 }
9719 
9720 
GetSampleTimestamp(int index) const9721 int64_t CpuProfile::GetSampleTimestamp(int index) const {
9722   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9723   return (profile->sample_timestamp(index) - base::TimeTicks())
9724       .InMicroseconds();
9725 }
9726 
9727 
GetStartTime() const9728 int64_t CpuProfile::GetStartTime() const {
9729   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9730   return (profile->start_time() - base::TimeTicks()).InMicroseconds();
9731 }
9732 
9733 
GetEndTime() const9734 int64_t CpuProfile::GetEndTime() const {
9735   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9736   return (profile->end_time() - base::TimeTicks()).InMicroseconds();
9737 }
9738 
9739 
GetSamplesCount() const9740 int CpuProfile::GetSamplesCount() const {
9741   return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
9742 }
9743 
New(Isolate * isolate)9744 CpuProfiler* CpuProfiler::New(Isolate* isolate) {
9745   return reinterpret_cast<CpuProfiler*>(
9746       new i::CpuProfiler(reinterpret_cast<i::Isolate*>(isolate)));
9747 }
9748 
Dispose()9749 void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
9750 
SetSamplingInterval(int us)9751 void CpuProfiler::SetSamplingInterval(int us) {
9752   DCHECK_GE(us, 0);
9753   return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
9754       base::TimeDelta::FromMicroseconds(us));
9755 }
9756 
CollectSample()9757 void CpuProfiler::CollectSample() {
9758   reinterpret_cast<i::CpuProfiler*>(this)->CollectSample();
9759 }
9760 
StartProfiling(Local<String> title,bool record_samples)9761 void CpuProfiler::StartProfiling(Local<String> title, bool record_samples) {
9762   reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9763       *Utils::OpenHandle(*title), record_samples);
9764 }
9765 
9766 
StopProfiling(Local<String> title)9767 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
9768   return reinterpret_cast<CpuProfile*>(
9769       reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
9770           *Utils::OpenHandle(*title)));
9771 }
9772 
9773 
SetIdle(bool is_idle)9774 void CpuProfiler::SetIdle(bool is_idle) {
9775   i::CpuProfiler* profiler = reinterpret_cast<i::CpuProfiler*>(this);
9776   i::Isolate* isolate = profiler->isolate();
9777   if (!isolate->is_profiling()) return;
9778   v8::StateTag state = isolate->current_vm_state();
9779   DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
9780   if (isolate->js_entry_sp() != NULL) return;
9781   if (is_idle) {
9782     isolate->set_current_vm_state(v8::IDLE);
9783   } else if (state == v8::IDLE) {
9784     isolate->set_current_vm_state(v8::EXTERNAL);
9785   }
9786 }
9787 
9788 
ToInternal(const HeapGraphEdge * edge)9789 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
9790   return const_cast<i::HeapGraphEdge*>(
9791       reinterpret_cast<const i::HeapGraphEdge*>(edge));
9792 }
9793 
9794 
GetType() const9795 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
9796   return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
9797 }
9798 
9799 
GetName() const9800 Local<Value> HeapGraphEdge::GetName() const {
9801   i::HeapGraphEdge* edge = ToInternal(this);
9802   i::Isolate* isolate = edge->isolate();
9803   switch (edge->type()) {
9804     case i::HeapGraphEdge::kContextVariable:
9805     case i::HeapGraphEdge::kInternal:
9806     case i::HeapGraphEdge::kProperty:
9807     case i::HeapGraphEdge::kShortcut:
9808     case i::HeapGraphEdge::kWeak:
9809       return ToApiHandle<String>(
9810           isolate->factory()->InternalizeUtf8String(edge->name()));
9811     case i::HeapGraphEdge::kElement:
9812     case i::HeapGraphEdge::kHidden:
9813       return ToApiHandle<Number>(
9814           isolate->factory()->NewNumberFromInt(edge->index()));
9815     default: UNREACHABLE();
9816   }
9817   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
9818 }
9819 
9820 
GetFromNode() const9821 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
9822   const i::HeapEntry* from = ToInternal(this)->from();
9823   return reinterpret_cast<const HeapGraphNode*>(from);
9824 }
9825 
9826 
GetToNode() const9827 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
9828   const i::HeapEntry* to = ToInternal(this)->to();
9829   return reinterpret_cast<const HeapGraphNode*>(to);
9830 }
9831 
9832 
ToInternal(const HeapGraphNode * entry)9833 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
9834   return const_cast<i::HeapEntry*>(
9835       reinterpret_cast<const i::HeapEntry*>(entry));
9836 }
9837 
9838 
GetType() const9839 HeapGraphNode::Type HeapGraphNode::GetType() const {
9840   return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
9841 }
9842 
9843 
GetName() const9844 Local<String> HeapGraphNode::GetName() const {
9845   i::Isolate* isolate = ToInternal(this)->isolate();
9846   return ToApiHandle<String>(
9847       isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
9848 }
9849 
9850 
GetId() const9851 SnapshotObjectId HeapGraphNode::GetId() const {
9852   return ToInternal(this)->id();
9853 }
9854 
9855 
GetShallowSize() const9856 size_t HeapGraphNode::GetShallowSize() const {
9857   return ToInternal(this)->self_size();
9858 }
9859 
9860 
GetChildrenCount() const9861 int HeapGraphNode::GetChildrenCount() const {
9862   return ToInternal(this)->children_count();
9863 }
9864 
9865 
GetChild(int index) const9866 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
9867   return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
9868 }
9869 
9870 
ToInternal(const HeapSnapshot * snapshot)9871 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
9872   return const_cast<i::HeapSnapshot*>(
9873       reinterpret_cast<const i::HeapSnapshot*>(snapshot));
9874 }
9875 
9876 
Delete()9877 void HeapSnapshot::Delete() {
9878   i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
9879   if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
9880     ToInternal(this)->Delete();
9881   } else {
9882     // If this is the last snapshot, clean up all accessory data as well.
9883     isolate->heap_profiler()->DeleteAllSnapshots();
9884   }
9885 }
9886 
9887 
GetRoot() const9888 const HeapGraphNode* HeapSnapshot::GetRoot() const {
9889   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
9890 }
9891 
9892 
GetNodeById(SnapshotObjectId id) const9893 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
9894   return reinterpret_cast<const HeapGraphNode*>(
9895       ToInternal(this)->GetEntryById(id));
9896 }
9897 
9898 
GetNodesCount() const9899 int HeapSnapshot::GetNodesCount() const {
9900   return ToInternal(this)->entries().length();
9901 }
9902 
9903 
GetNode(int index) const9904 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
9905   return reinterpret_cast<const HeapGraphNode*>(
9906       &ToInternal(this)->entries().at(index));
9907 }
9908 
9909 
GetMaxSnapshotJSObjectId() const9910 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
9911   return ToInternal(this)->max_snapshot_js_object_id();
9912 }
9913 
9914 
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const9915 void HeapSnapshot::Serialize(OutputStream* stream,
9916                              HeapSnapshot::SerializationFormat format) const {
9917   Utils::ApiCheck(format == kJSON,
9918                   "v8::HeapSnapshot::Serialize",
9919                   "Unknown serialization format");
9920   Utils::ApiCheck(stream->GetChunkSize() > 0,
9921                   "v8::HeapSnapshot::Serialize",
9922                   "Invalid stream chunk size");
9923   i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
9924   serializer.Serialize(stream);
9925 }
9926 
9927 
9928 // static
9929 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
9930     HeapProfiler::kUnknownObjectId;
9931 
9932 
GetSnapshotCount()9933 int HeapProfiler::GetSnapshotCount() {
9934   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
9935 }
9936 
9937 
GetHeapSnapshot(int index)9938 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
9939   return reinterpret_cast<const HeapSnapshot*>(
9940       reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
9941 }
9942 
9943 
GetObjectId(Local<Value> value)9944 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
9945   i::Handle<i::Object> obj = Utils::OpenHandle(*value);
9946   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
9947 }
9948 
9949 
FindObjectById(SnapshotObjectId id)9950 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
9951   i::Handle<i::Object> obj =
9952       reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
9953   if (obj.is_null()) return Local<Value>();
9954   return Utils::ToLocal(obj);
9955 }
9956 
9957 
ClearObjectIds()9958 void HeapProfiler::ClearObjectIds() {
9959   reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
9960 }
9961 
9962 
TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver)9963 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
9964     ActivityControl* control, ObjectNameResolver* resolver) {
9965   return reinterpret_cast<const HeapSnapshot*>(
9966       reinterpret_cast<i::HeapProfiler*>(this)
9967           ->TakeSnapshot(control, resolver));
9968 }
9969 
9970 
StartTrackingHeapObjects(bool track_allocations)9971 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
9972   reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
9973       track_allocations);
9974 }
9975 
9976 
StopTrackingHeapObjects()9977 void HeapProfiler::StopTrackingHeapObjects() {
9978   reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
9979 }
9980 
9981 
GetHeapStats(OutputStream * stream,int64_t * timestamp_us)9982 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
9983                                             int64_t* timestamp_us) {
9984   i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
9985   return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
9986 }
9987 
StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)9988 bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
9989                                              int stack_depth,
9990                                              SamplingFlags flags) {
9991   return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
9992       sample_interval, stack_depth, flags);
9993 }
9994 
9995 
StopSamplingHeapProfiler()9996 void HeapProfiler::StopSamplingHeapProfiler() {
9997   reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
9998 }
9999 
10000 
GetAllocationProfile()10001 AllocationProfile* HeapProfiler::GetAllocationProfile() {
10002   return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10003 }
10004 
10005 
DeleteAllHeapSnapshots()10006 void HeapProfiler::DeleteAllHeapSnapshots() {
10007   reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10008 }
10009 
10010 
SetWrapperClassInfoProvider(uint16_t class_id,WrapperInfoCallback callback)10011 void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
10012                                                WrapperInfoCallback callback) {
10013   reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
10014                                                                callback);
10015 }
10016 
SetGetRetainerInfosCallback(GetRetainerInfosCallback callback)10017 void HeapProfiler::SetGetRetainerInfosCallback(
10018     GetRetainerInfosCallback callback) {
10019   reinterpret_cast<i::HeapProfiler*>(this)->SetGetRetainerInfosCallback(
10020       callback);
10021 }
10022 
GetProfilerMemorySize()10023 size_t HeapProfiler::GetProfilerMemorySize() {
10024   return reinterpret_cast<i::HeapProfiler*>(this)->
10025       GetMemorySizeUsedByProfiler();
10026 }
10027 
10028 
SetRetainedObjectInfo(UniqueId id,RetainedObjectInfo * info)10029 void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
10030                                          RetainedObjectInfo* info) {
10031   reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
10032 }
10033 
10034 
10035 v8::Testing::StressType internal::Testing::stress_type_ =
10036     v8::Testing::kStressTypeOpt;
10037 
10038 
SetStressRunType(Testing::StressType type)10039 void Testing::SetStressRunType(Testing::StressType type) {
10040   internal::Testing::set_stress_type(type);
10041 }
10042 
10043 
GetStressRuns()10044 int Testing::GetStressRuns() {
10045   if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
10046 #ifdef DEBUG
10047   // In debug mode the code runs much slower so stressing will only make two
10048   // runs.
10049   return 2;
10050 #else
10051   return 5;
10052 #endif
10053 }
10054 
10055 
SetFlagsFromString(const char * flags)10056 static void SetFlagsFromString(const char* flags) {
10057   V8::SetFlagsFromString(flags, i::StrLength(flags));
10058 }
10059 
10060 
PrepareStressRun(int run)10061 void Testing::PrepareStressRun(int run) {
10062   static const char* kLazyOptimizations =
10063       "--prepare-always-opt "
10064       "--max-inlined-source-size=999999 "
10065       "--max-inlined-nodes=999999 "
10066       "--max-inlined-nodes-cumulative=999999 "
10067       "--noalways-opt";
10068   static const char* kForcedOptimizations = "--always-opt";
10069 
10070   // If deoptimization stressed turn on frequent deoptimization. If no value
10071   // is spefified through --deopt-every-n-times use a default default value.
10072   static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
10073   if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
10074       internal::FLAG_deopt_every_n_times == 0) {
10075     SetFlagsFromString(kDeoptEvery13Times);
10076   }
10077 
10078 #ifdef DEBUG
10079   // As stressing in debug mode only make two runs skip the deopt stressing
10080   // here.
10081   if (run == GetStressRuns() - 1) {
10082     SetFlagsFromString(kForcedOptimizations);
10083   } else {
10084     SetFlagsFromString(kLazyOptimizations);
10085   }
10086 #else
10087   if (run == GetStressRuns() - 1) {
10088     SetFlagsFromString(kForcedOptimizations);
10089   } else if (run != GetStressRuns() - 2) {
10090     SetFlagsFromString(kLazyOptimizations);
10091   }
10092 #endif
10093 }
10094 
10095 
DeoptimizeAll(Isolate * isolate)10096 void Testing::DeoptimizeAll(Isolate* isolate) {
10097   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
10098   i::HandleScope scope(i_isolate);
10099   internal::Deoptimizer::DeoptimizeAll(i_isolate);
10100 }
10101 
10102 
10103 namespace internal {
10104 
10105 
FreeThreadResources()10106 void HandleScopeImplementer::FreeThreadResources() {
10107   Free();
10108 }
10109 
10110 
ArchiveThread(char * storage)10111 char* HandleScopeImplementer::ArchiveThread(char* storage) {
10112   HandleScopeData* current = isolate_->handle_scope_data();
10113   handle_scope_data_ = *current;
10114   MemCopy(storage, this, sizeof(*this));
10115 
10116   ResetAfterArchive();
10117   current->Initialize();
10118 
10119   return storage + ArchiveSpacePerThread();
10120 }
10121 
10122 
ArchiveSpacePerThread()10123 int HandleScopeImplementer::ArchiveSpacePerThread() {
10124   return sizeof(HandleScopeImplementer);
10125 }
10126 
10127 
RestoreThread(char * storage)10128 char* HandleScopeImplementer::RestoreThread(char* storage) {
10129   MemCopy(this, storage, sizeof(*this));
10130   *isolate_->handle_scope_data() = handle_scope_data_;
10131   return storage + ArchiveSpacePerThread();
10132 }
10133 
10134 
IterateThis(ObjectVisitor * v)10135 void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
10136 #ifdef DEBUG
10137   bool found_block_before_deferred = false;
10138 #endif
10139   // Iterate over all handles in the blocks except for the last.
10140   for (int i = blocks()->length() - 2; i >= 0; --i) {
10141     Object** block = blocks()->at(i);
10142     if (last_handle_before_deferred_block_ != NULL &&
10143         (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
10144         (last_handle_before_deferred_block_ >= block)) {
10145       v->VisitPointers(block, last_handle_before_deferred_block_);
10146       DCHECK(!found_block_before_deferred);
10147 #ifdef DEBUG
10148       found_block_before_deferred = true;
10149 #endif
10150     } else {
10151       v->VisitPointers(block, &block[kHandleBlockSize]);
10152     }
10153   }
10154 
10155   DCHECK(last_handle_before_deferred_block_ == NULL ||
10156          found_block_before_deferred);
10157 
10158   // Iterate over live handles in the last block (if any).
10159   if (!blocks()->is_empty()) {
10160     v->VisitPointers(blocks()->last(), handle_scope_data_.next);
10161   }
10162 
10163   List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
10164   for (unsigned i = 0; i < arraysize(context_lists); i++) {
10165     if (context_lists[i]->is_empty()) continue;
10166     Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
10167     v->VisitPointers(start, start + context_lists[i]->length());
10168   }
10169   if (microtask_context_) {
10170     Object** start = reinterpret_cast<Object**>(&microtask_context_);
10171     v->VisitPointers(start, start + 1);
10172   }
10173 }
10174 
10175 
Iterate(ObjectVisitor * v)10176 void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
10177   HandleScopeData* current = isolate_->handle_scope_data();
10178   handle_scope_data_ = *current;
10179   IterateThis(v);
10180 }
10181 
10182 
Iterate(ObjectVisitor * v,char * storage)10183 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
10184   HandleScopeImplementer* scope_implementer =
10185       reinterpret_cast<HandleScopeImplementer*>(storage);
10186   scope_implementer->IterateThis(v);
10187   return storage + ArchiveSpacePerThread();
10188 }
10189 
10190 
Detach(Object ** prev_limit)10191 DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
10192   DeferredHandles* deferred =
10193       new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
10194 
10195   while (!blocks_.is_empty()) {
10196     Object** block_start = blocks_.last();
10197     Object** block_limit = &block_start[kHandleBlockSize];
10198     // We should not need to check for SealHandleScope here. Assert this.
10199     DCHECK(prev_limit == block_limit ||
10200            !(block_start <= prev_limit && prev_limit <= block_limit));
10201     if (prev_limit == block_limit) break;
10202     deferred->blocks_.Add(blocks_.last());
10203     blocks_.RemoveLast();
10204   }
10205 
10206   // deferred->blocks_ now contains the blocks installed on the
10207   // HandleScope stack since BeginDeferredScope was called, but in
10208   // reverse order.
10209 
10210   DCHECK(prev_limit == NULL || !blocks_.is_empty());
10211 
10212   DCHECK(!blocks_.is_empty() && prev_limit != NULL);
10213   DCHECK(last_handle_before_deferred_block_ != NULL);
10214   last_handle_before_deferred_block_ = NULL;
10215   return deferred;
10216 }
10217 
10218 
BeginDeferredScope()10219 void HandleScopeImplementer::BeginDeferredScope() {
10220   DCHECK(last_handle_before_deferred_block_ == NULL);
10221   last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10222 }
10223 
10224 
~DeferredHandles()10225 DeferredHandles::~DeferredHandles() {
10226   isolate_->UnlinkDeferredHandles(this);
10227 
10228   for (int i = 0; i < blocks_.length(); i++) {
10229 #ifdef ENABLE_HANDLE_ZAPPING
10230     HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
10231 #endif
10232     isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
10233   }
10234 }
10235 
10236 
Iterate(ObjectVisitor * v)10237 void DeferredHandles::Iterate(ObjectVisitor* v) {
10238   DCHECK(!blocks_.is_empty());
10239 
10240   DCHECK((first_block_limit_ >= blocks_.first()) &&
10241          (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
10242 
10243   v->VisitPointers(blocks_.first(), first_block_limit_);
10244 
10245   for (int i = 1; i < blocks_.length(); i++) {
10246     v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
10247   }
10248 }
10249 
10250 
InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)10251 void InvokeAccessorGetterCallback(
10252     v8::Local<v8::Name> property,
10253     const v8::PropertyCallbackInfo<v8::Value>& info,
10254     v8::AccessorNameGetterCallback getter) {
10255   // Leaving JavaScript.
10256   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10257   RuntimeCallTimerScope timer(isolate,
10258                               &RuntimeCallStats::AccessorGetterCallback);
10259   Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
10260       getter));
10261   VMState<EXTERNAL> state(isolate);
10262   ExternalCallbackScope call_scope(isolate, getter_address);
10263   getter(property, info);
10264 }
10265 
10266 
InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)10267 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
10268                             v8::FunctionCallback callback) {
10269   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10270   RuntimeCallTimerScope timer(isolate,
10271                               &RuntimeCallStats::InvokeFunctionCallback);
10272   Address callback_address =
10273       reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
10274   VMState<EXTERNAL> state(isolate);
10275   ExternalCallbackScope call_scope(isolate, callback_address);
10276   callback(info);
10277 }
10278 
10279 
10280 }  // namespace internal
10281 }  // namespace v8
10282