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