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