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