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,