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