Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "api.h"
     29 
     30 #include <math.h>  // For isnan.
     31 #include <string.h>  // For memcpy, strlen.
     32 #include "../include/v8-debug.h"
     33 #include "../include/v8-profiler.h"
     34 #include "../include/v8-testing.h"
     35 #include "bootstrapper.h"
     36 #include "compiler.h"
     37 #include "conversions-inl.h"
     38 #include "counters.h"
     39 #include "debug.h"
     40 #include "deoptimizer.h"
     41 #include "execution.h"
     42 #include "global-handles.h"
     43 #include "heap-profiler.h"
     44 #include "messages.h"
     45 #ifdef COMPRESS_STARTUP_DATA_BZ2
     46 #include "natives.h"
     47 #endif
     48 #include "parser.h"
     49 #include "platform.h"
     50 #include "profile-generator-inl.h"
     51 #include "property-details.h"
     52 #include "property.h"
     53 #include "runtime-profiler.h"
     54 #include "scanner-character-streams.h"
     55 #include "snapshot.h"
     56 #include "unicode-inl.h"
     57 #include "v8threads.h"
     58 #include "version.h"
     59 #include "vm-state-inl.h"
     60 
     61 
     62 #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
     63 
     64 #define ENTER_V8(isolate)                                        \
     65   ASSERT((isolate)->IsInitialized());                           \
     66   i::VMState __state__((isolate), i::OTHER)
     67 #define LEAVE_V8(isolate) \
     68   i::VMState __state__((isolate), i::EXTERNAL)
     69 
     70 namespace v8 {
     71 
     72 #define ON_BAILOUT(isolate, location, code)                        \
     73   if (IsDeadCheck(isolate, location) ||                            \
     74       IsExecutionTerminatingCheck(isolate)) {                      \
     75     code;                                                          \
     76     UNREACHABLE();                                                 \
     77   }
     78 
     79 
     80 #define EXCEPTION_PREAMBLE(isolate)                                         \
     81   (isolate)->handle_scope_implementer()->IncrementCallDepth();              \
     82   ASSERT(!(isolate)->external_caught_exception());                          \
     83   bool has_pending_exception = false
     84 
     85 
     86 #define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback)           \
     87   do {                                                                         \
     88     i::HandleScopeImplementer* handle_scope_implementer =                      \
     89         (isolate)->handle_scope_implementer();                                 \
     90     handle_scope_implementer->DecrementCallDepth();                            \
     91     if (has_pending_exception) {                                               \
     92       if (handle_scope_implementer->CallDepthIsZero() &&                       \
     93           (isolate)->is_out_of_memory()) {                                     \
     94         if (!(isolate)->ignore_out_of_memory())                                \
     95           i::V8::FatalProcessOutOfMemory(NULL);                                \
     96       }                                                                        \
     97       bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();   \
     98       (isolate)->OptionalRescheduleException(call_depth_is_zero);              \
     99       do_callback                                                              \
    100       return value;                                                            \
    101     }                                                                          \
    102     do_callback                                                                \
    103   } while (false)
    104 
    105 
    106 #define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value)                    \
    107   EXCEPTION_BAILOUT_CHECK_GENERIC(                                             \
    108       isolate, value, i::V8::FireCallCompletedCallback(isolate);)
    109 
    110 
    111 #define EXCEPTION_BAILOUT_CHECK(isolate, value)                                \
    112   EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
    113 
    114 
    115 #define API_ENTRY_CHECK(isolate, msg)                                          \
    116   do {                                                                         \
    117     if (v8::Locker::IsActive()) {                                              \
    118       ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(),           \
    119                msg,                                                            \
    120                "Entering the V8 API without proper locking in place");         \
    121     }                                                                          \
    122   } while (false)
    123 
    124 
    125 // --- E x c e p t i o n   B e h a v i o r ---
    126 
    127 
    128 static void DefaultFatalErrorHandler(const char* location,
    129                                      const char* message) {
    130   i::VMState __state__(i::Isolate::Current(), i::OTHER);
    131   API_Fatal(location, message);
    132 }
    133 
    134 
    135 static FatalErrorCallback GetFatalErrorHandler() {
    136   i::Isolate* isolate = i::Isolate::Current();
    137   if (isolate->exception_behavior() == NULL) {
    138     isolate->set_exception_behavior(DefaultFatalErrorHandler);
    139   }
    140   return isolate->exception_behavior();
    141 }
    142 
    143 
    144 void i::FatalProcessOutOfMemory(const char* location) {
    145   i::V8::FatalProcessOutOfMemory(location, false);
    146 }
    147 
    148 
    149 // When V8 cannot allocated memory FatalProcessOutOfMemory is called.
    150 // The default fatal error handler is called and execution is stopped.
    151 void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
    152   i::HeapStats heap_stats;
    153   int start_marker;
    154   heap_stats.start_marker = &start_marker;
    155   int new_space_size;
    156   heap_stats.new_space_size = &new_space_size;
    157   int new_space_capacity;
    158   heap_stats.new_space_capacity = &new_space_capacity;
    159   intptr_t old_pointer_space_size;
    160   heap_stats.old_pointer_space_size = &old_pointer_space_size;
    161   intptr_t old_pointer_space_capacity;
    162   heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
    163   intptr_t old_data_space_size;
    164   heap_stats.old_data_space_size = &old_data_space_size;
    165   intptr_t old_data_space_capacity;
    166   heap_stats.old_data_space_capacity = &old_data_space_capacity;
    167   intptr_t code_space_size;
    168   heap_stats.code_space_size = &code_space_size;
    169   intptr_t code_space_capacity;
    170   heap_stats.code_space_capacity = &code_space_capacity;
    171   intptr_t map_space_size;
    172   heap_stats.map_space_size = &map_space_size;
    173   intptr_t map_space_capacity;
    174   heap_stats.map_space_capacity = &map_space_capacity;
    175   intptr_t cell_space_size;
    176   heap_stats.cell_space_size = &cell_space_size;
    177   intptr_t cell_space_capacity;
    178   heap_stats.cell_space_capacity = &cell_space_capacity;
    179   intptr_t lo_space_size;
    180   heap_stats.lo_space_size = &lo_space_size;
    181   int global_handle_count;
    182   heap_stats.global_handle_count = &global_handle_count;
    183   int weak_global_handle_count;
    184   heap_stats.weak_global_handle_count = &weak_global_handle_count;
    185   int pending_global_handle_count;
    186   heap_stats.pending_global_handle_count = &pending_global_handle_count;
    187   int near_death_global_handle_count;
    188   heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
    189   int free_global_handle_count;
    190   heap_stats.free_global_handle_count = &free_global_handle_count;
    191   intptr_t memory_allocator_size;
    192   heap_stats.memory_allocator_size = &memory_allocator_size;
    193   intptr_t memory_allocator_capacity;
    194   heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
    195   int objects_per_type[LAST_TYPE + 1] = {0};
    196   heap_stats.objects_per_type = objects_per_type;
    197   int size_per_type[LAST_TYPE + 1] = {0};
    198   heap_stats.size_per_type = size_per_type;
    199   int os_error;
    200   heap_stats.os_error = &os_error;
    201   int end_marker;
    202   heap_stats.end_marker = &end_marker;
    203   i::Isolate* isolate = i::Isolate::Current();
    204   // BUG(1718):
    205   // Don't use the take_snapshot since we don't support HeapIterator here
    206   // without doing a special GC.
    207   isolate->heap()->RecordStats(&heap_stats, false);
    208   i::V8::SetFatalError();
    209   FatalErrorCallback callback = GetFatalErrorHandler();
    210   {
    211     LEAVE_V8(isolate);
    212     callback(location, "Allocation failed - process out of memory");
    213   }
    214   // If the callback returns, we stop execution.
    215   UNREACHABLE();
    216 }
    217 
    218 
    219 bool Utils::ReportApiFailure(const char* location, const char* message) {
    220   FatalErrorCallback callback = GetFatalErrorHandler();
    221   callback(location, message);
    222   i::V8::SetFatalError();
    223   return false;
    224 }
    225 
    226 
    227 bool V8::IsDead() {
    228   return i::V8::IsDead();
    229 }
    230 
    231 
    232 static inline bool ApiCheck(bool condition,
    233                             const char* location,
    234                             const char* message) {
    235   return condition ? true : Utils::ReportApiFailure(location, message);
    236 }
    237 
    238 
    239 static bool ReportV8Dead(const char* location) {
    240   FatalErrorCallback callback = GetFatalErrorHandler();
    241   callback(location, "V8 is no longer usable");
    242   return true;
    243 }
    244 
    245 
    246 static bool ReportEmptyHandle(const char* location) {
    247   FatalErrorCallback callback = GetFatalErrorHandler();
    248   callback(location, "Reading from empty handle");
    249   return true;
    250 }
    251 
    252 
    253 /**
    254  * IsDeadCheck checks that the vm is usable.  If, for instance, the vm has been
    255  * out of memory at some point this check will fail.  It should be called on
    256  * entry to all methods that touch anything in the heap, except destructors
    257  * which you sometimes can't avoid calling after the vm has crashed.  Functions
    258  * that call EnsureInitialized or ON_BAILOUT don't have to also call
    259  * IsDeadCheck.  ON_BAILOUT has the advantage over EnsureInitialized that you
    260  * can arrange to return if the VM is dead.  This is needed to ensure that no VM
    261  * heap allocations are attempted on a dead VM.  EnsureInitialized has the
    262  * advantage over ON_BAILOUT that it actually initializes the VM if this has not
    263  * yet been done.
    264  */
    265 static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
    266   return !isolate->IsInitialized()
    267       && i::V8::IsDead() ? ReportV8Dead(location) : false;
    268 }
    269 
    270 
    271 static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
    272   if (!isolate->IsInitialized()) return false;
    273   if (isolate->has_scheduled_exception()) {
    274     return isolate->scheduled_exception() ==
    275         isolate->heap()->termination_exception();
    276   }
    277   return false;
    278 }
    279 
    280 
    281 static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
    282   return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
    283 }
    284 
    285 
    286 static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
    287   return (obj == 0) ? ReportEmptyHandle(location) : false;
    288 }
    289 
    290 // --- S t a t i c s ---
    291 
    292 
    293 static bool InitializeHelper() {
    294   if (i::Snapshot::Initialize()) return true;
    295   return i::V8::Initialize(NULL);
    296 }
    297 
    298 
    299 static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
    300                                                const char* location) {
    301   if (IsDeadCheck(isolate, location)) return false;
    302   if (isolate != NULL) {
    303     if (isolate->IsInitialized()) return true;
    304   }
    305   ASSERT(isolate == i::Isolate::Current());
    306   return ApiCheck(InitializeHelper(), location, "Error initializing V8");
    307 }
    308 
    309 // Some initializing API functions are called early and may be
    310 // called on a thread different from static initializer thread.
    311 // If Isolate API is used, Isolate::Enter() will initialize TLS so
    312 // Isolate::Current() works. If it's a legacy case, then the thread
    313 // may not have TLS initialized yet. However, in initializing APIs it
    314 // may be too early to call EnsureInitialized() - some pre-init
    315 // parameters still have to be configured.
    316 static inline i::Isolate* EnterIsolateIfNeeded() {
    317   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
    318   if (isolate != NULL)
    319     return isolate;
    320 
    321   i::Isolate::EnterDefaultIsolate();
    322   isolate = i::Isolate::Current();
    323   return isolate;
    324 }
    325 
    326 
    327 StartupDataDecompressor::StartupDataDecompressor()
    328     : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
    329   for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
    330     raw_data[i] = NULL;
    331   }
    332 }
    333 
    334 
    335 StartupDataDecompressor::~StartupDataDecompressor() {
    336   for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
    337     i::DeleteArray(raw_data[i]);
    338   }
    339   i::DeleteArray(raw_data);
    340 }
    341 
    342 
    343 int StartupDataDecompressor::Decompress() {
    344   int compressed_data_count = V8::GetCompressedStartupDataCount();
    345   StartupData* compressed_data =
    346       i::NewArray<StartupData>(compressed_data_count);
    347   V8::GetCompressedStartupData(compressed_data);
    348   for (int i = 0; i < compressed_data_count; ++i) {
    349     char* decompressed = raw_data[i] =
    350         i::NewArray<char>(compressed_data[i].raw_size);
    351     if (compressed_data[i].compressed_size != 0) {
    352       int result = DecompressData(decompressed,
    353                                   &compressed_data[i].raw_size,
    354                                   compressed_data[i].data,
    355                                   compressed_data[i].compressed_size);
    356       if (result != 0) return result;
    357     } else {
    358       ASSERT_EQ(0, compressed_data[i].raw_size);
    359     }
    360     compressed_data[i].data = decompressed;
    361   }
    362   V8::SetDecompressedStartupData(compressed_data);
    363   i::DeleteArray(compressed_data);
    364   return 0;
    365 }
    366 
    367 
    368 StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
    369 #ifdef COMPRESS_STARTUP_DATA_BZ2
    370   return StartupData::kBZip2;
    371 #else
    372   return StartupData::kUncompressed;
    373 #endif
    374 }
    375 
    376 
    377 enum CompressedStartupDataItems {
    378   kSnapshot = 0,
    379   kSnapshotContext,
    380   kLibraries,
    381   kExperimentalLibraries,
    382   kCompressedStartupDataCount
    383 };
    384 
    385 int V8::GetCompressedStartupDataCount() {
    386 #ifdef COMPRESS_STARTUP_DATA_BZ2
    387   return kCompressedStartupDataCount;
    388 #else
    389   return 0;
    390 #endif
    391 }
    392 
    393 
    394 void V8::GetCompressedStartupData(StartupData* compressed_data) {
    395 #ifdef COMPRESS_STARTUP_DATA_BZ2
    396   compressed_data[kSnapshot].data =
    397       reinterpret_cast<const char*>(i::Snapshot::data());
    398   compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
    399   compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
    400 
    401   compressed_data[kSnapshotContext].data =
    402       reinterpret_cast<const char*>(i::Snapshot::context_data());
    403   compressed_data[kSnapshotContext].compressed_size =
    404       i::Snapshot::context_size();
    405   compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
    406 
    407   i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
    408   compressed_data[kLibraries].data =
    409       reinterpret_cast<const char*>(libraries_source.start());
    410   compressed_data[kLibraries].compressed_size = libraries_source.length();
    411   compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
    412 
    413   i::Vector<const i::byte> exp_libraries_source =
    414       i::ExperimentalNatives::GetScriptsSource();
    415   compressed_data[kExperimentalLibraries].data =
    416       reinterpret_cast<const char*>(exp_libraries_source.start());
    417   compressed_data[kExperimentalLibraries].compressed_size =
    418       exp_libraries_source.length();
    419   compressed_data[kExperimentalLibraries].raw_size =
    420       i::ExperimentalNatives::GetRawScriptsSize();
    421 #endif
    422 }
    423 
    424 
    425 void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
    426 #ifdef COMPRESS_STARTUP_DATA_BZ2
    427   ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
    428   i::Snapshot::set_raw_data(
    429       reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
    430 
    431   ASSERT_EQ(i::Snapshot::context_raw_size(),
    432             decompressed_data[kSnapshotContext].raw_size);
    433   i::Snapshot::set_context_raw_data(
    434       reinterpret_cast<const i::byte*>(
    435           decompressed_data[kSnapshotContext].data));
    436 
    437   ASSERT_EQ(i::Natives::GetRawScriptsSize(),
    438             decompressed_data[kLibraries].raw_size);
    439   i::Vector<const char> libraries_source(
    440       decompressed_data[kLibraries].data,
    441       decompressed_data[kLibraries].raw_size);
    442   i::Natives::SetRawScriptsSource(libraries_source);
    443 
    444   ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
    445             decompressed_data[kExperimentalLibraries].raw_size);
    446   i::Vector<const char> exp_libraries_source(
    447       decompressed_data[kExperimentalLibraries].data,
    448       decompressed_data[kExperimentalLibraries].raw_size);
    449   i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
    450 #endif
    451 }
    452 
    453 
    454 void V8::SetFatalErrorHandler(FatalErrorCallback that) {
    455   i::Isolate* isolate = EnterIsolateIfNeeded();
    456   isolate->set_exception_behavior(that);
    457 }
    458 
    459 
    460 void V8::SetAllowCodeGenerationFromStringsCallback(
    461     AllowCodeGenerationFromStringsCallback callback) {
    462   i::Isolate* isolate = EnterIsolateIfNeeded();
    463   isolate->set_allow_code_gen_callback(callback);
    464 }
    465 
    466 
    467 #ifdef DEBUG
    468 void ImplementationUtilities::ZapHandleRange(i::Object** begin,
    469                                              i::Object** end) {
    470   i::HandleScope::ZapRange(begin, end);
    471 }
    472 #endif
    473 
    474 
    475 void V8::SetFlagsFromString(const char* str, int length) {
    476   i::FlagList::SetFlagsFromString(str, length);
    477 }
    478 
    479 
    480 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
    481   i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
    482 }
    483 
    484 
    485 v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
    486   i::Isolate* isolate = i::Isolate::Current();
    487   if (IsDeadCheck(isolate, "v8::ThrowException()")) {
    488     return v8::Handle<Value>();
    489   }
    490   ENTER_V8(isolate);
    491   // If we're passed an empty handle, we throw an undefined exception
    492   // to deal more gracefully with out of memory situations.
    493   if (value.IsEmpty()) {
    494     isolate->ScheduleThrow(isolate->heap()->undefined_value());
    495   } else {
    496     isolate->ScheduleThrow(*Utils::OpenHandle(*value));
    497   }
    498   return v8::Undefined();
    499 }
    500 
    501 
    502 RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
    503 
    504 
    505 RegisteredExtension::RegisteredExtension(Extension* extension)
    506     : extension_(extension) { }
    507 
    508 
    509 void RegisteredExtension::Register(RegisteredExtension* that) {
    510   that->next_ = first_extension_;
    511   first_extension_ = that;
    512 }
    513 
    514 
    515 void RegisterExtension(Extension* that) {
    516   RegisteredExtension* extension = new RegisteredExtension(that);
    517   RegisteredExtension::Register(extension);
    518 }
    519 
    520 
    521 Extension::Extension(const char* name,
    522                      const char* source,
    523                      int dep_count,
    524                      const char** deps,
    525                      int source_length)
    526     : name_(name),
    527       source_length_(source_length >= 0 ?
    528                      source_length :
    529                      (source ? static_cast<int>(strlen(source)) : 0)),
    530       source_(source, source_length_),
    531       dep_count_(dep_count),
    532       deps_(deps),
    533       auto_enable_(false) { }
    534 
    535 
    536 v8::Handle<Primitive> Undefined() {
    537   i::Isolate* isolate = i::Isolate::Current();
    538   if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
    539     return v8::Handle<v8::Primitive>();
    540   }
    541   return v8::Handle<Primitive>(ToApi<Primitive>(
    542       isolate->factory()->undefined_value()));
    543 }
    544 
    545 
    546 v8::Handle<Primitive> Null() {
    547   i::Isolate* isolate = i::Isolate::Current();
    548   if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
    549     return v8::Handle<v8::Primitive>();
    550   }
    551   return v8::Handle<Primitive>(
    552       ToApi<Primitive>(isolate->factory()->null_value()));
    553 }
    554 
    555 
    556 v8::Handle<Boolean> True() {
    557   i::Isolate* isolate = i::Isolate::Current();
    558   if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
    559     return v8::Handle<Boolean>();
    560   }
    561   return v8::Handle<Boolean>(
    562       ToApi<Boolean>(isolate->factory()->true_value()));
    563 }
    564 
    565 
    566 v8::Handle<Boolean> False() {
    567   i::Isolate* isolate = i::Isolate::Current();
    568   if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
    569     return v8::Handle<Boolean>();
    570   }
    571   return v8::Handle<Boolean>(
    572       ToApi<Boolean>(isolate->factory()->false_value()));
    573 }
    574 
    575 
    576 ResourceConstraints::ResourceConstraints()
    577   : max_young_space_size_(0),
    578     max_old_space_size_(0),
    579     max_executable_size_(0),
    580     stack_limit_(NULL) { }
    581 
    582 
    583 bool SetResourceConstraints(ResourceConstraints* constraints) {
    584   i::Isolate* isolate = EnterIsolateIfNeeded();
    585 
    586   int young_space_size = constraints->max_young_space_size();
    587   int old_gen_size = constraints->max_old_space_size();
    588   int max_executable_size = constraints->max_executable_size();
    589   if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
    590     // After initialization it's too late to change Heap constraints.
    591     ASSERT(!isolate->IsInitialized());
    592     bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
    593                                                  old_gen_size,
    594                                                  max_executable_size);
    595     if (!result) return false;
    596   }
    597   if (constraints->stack_limit() != NULL) {
    598     uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
    599     isolate->stack_guard()->SetStackLimit(limit);
    600   }
    601   return true;
    602 }
    603 
    604 
    605 i::Object** V8::GlobalizeReference(i::Object** obj) {
    606   i::Isolate* isolate = i::Isolate::Current();
    607   if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
    608   LOG_API(isolate, "Persistent::New");
    609   i::Handle<i::Object> result =
    610       isolate->global_handles()->Create(*obj);
    611   return result.location();
    612 }
    613 
    614 
    615 void V8::MakeWeak(i::Object** object, void* parameters,
    616                   WeakReferenceCallback callback) {
    617   i::Isolate* isolate = i::Isolate::Current();
    618   LOG_API(isolate, "MakeWeak");
    619   isolate->global_handles()->MakeWeak(object, parameters,
    620                                                     callback);
    621 }
    622 
    623 
    624 void V8::ClearWeak(i::Object** obj) {
    625   i::Isolate* isolate = i::Isolate::Current();
    626   LOG_API(isolate, "ClearWeak");
    627   isolate->global_handles()->ClearWeakness(obj);
    628 }
    629 
    630 
    631 void V8::MarkIndependent(i::Object** object) {
    632   i::Isolate* isolate = i::Isolate::Current();
    633   LOG_API(isolate, "MakeIndependent");
    634   isolate->global_handles()->MarkIndependent(object);
    635 }
    636 
    637 
    638 bool V8::IsGlobalNearDeath(i::Object** obj) {
    639   i::Isolate* isolate = i::Isolate::Current();
    640   LOG_API(isolate, "IsGlobalNearDeath");
    641   if (!isolate->IsInitialized()) return false;
    642   return i::GlobalHandles::IsNearDeath(obj);
    643 }
    644 
    645 
    646 bool V8::IsGlobalWeak(i::Object** obj) {
    647   i::Isolate* isolate = i::Isolate::Current();
    648   LOG_API(isolate, "IsGlobalWeak");
    649   if (!isolate->IsInitialized()) return false;
    650   return i::GlobalHandles::IsWeak(obj);
    651 }
    652 
    653 
    654 void V8::DisposeGlobal(i::Object** obj) {
    655   i::Isolate* isolate = i::Isolate::Current();
    656   LOG_API(isolate, "DisposeGlobal");
    657   if (!isolate->IsInitialized()) return;
    658   isolate->global_handles()->Destroy(obj);
    659 }
    660 
    661 // --- H a n d l e s ---
    662 
    663 
    664 HandleScope::HandleScope() {
    665   i::Isolate* isolate = i::Isolate::Current();
    666   API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
    667   v8::ImplementationUtilities::HandleScopeData* current =
    668       isolate->handle_scope_data();
    669   isolate_ = isolate;
    670   prev_next_ = current->next;
    671   prev_limit_ = current->limit;
    672   is_closed_ = false;
    673   current->level++;
    674 }
    675 
    676 
    677 HandleScope::~HandleScope() {
    678   if (!is_closed_) {
    679     Leave();
    680   }
    681 }
    682 
    683 
    684 void HandleScope::Leave() {
    685   ASSERT(isolate_ == i::Isolate::Current());
    686   v8::ImplementationUtilities::HandleScopeData* current =
    687       isolate_->handle_scope_data();
    688   current->level--;
    689   ASSERT(current->level >= 0);
    690   current->next = prev_next_;
    691   if (current->limit != prev_limit_) {
    692     current->limit = prev_limit_;
    693     i::HandleScope::DeleteExtensions(isolate_);
    694   }
    695 
    696 #ifdef DEBUG
    697   i::HandleScope::ZapRange(prev_next_, prev_limit_);
    698 #endif
    699 }
    700 
    701 
    702 int HandleScope::NumberOfHandles() {
    703   EnsureInitializedForIsolate(
    704       i::Isolate::Current(), "HandleScope::NumberOfHandles");
    705   return i::HandleScope::NumberOfHandles();
    706 }
    707 
    708 
    709 i::Object** HandleScope::CreateHandle(i::Object* value) {
    710   return i::HandleScope::CreateHandle(value, i::Isolate::Current());
    711 }
    712 
    713 
    714 i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
    715   ASSERT(value->IsHeapObject());
    716   return reinterpret_cast<i::Object**>(
    717       i::HandleScope::CreateHandle(value, value->GetIsolate()));
    718 }
    719 
    720 
    721 void Context::Enter() {
    722   i::Handle<i::Context> env = Utils::OpenHandle(this);
    723   i::Isolate* isolate = env->GetIsolate();
    724   if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
    725   ENTER_V8(isolate);
    726 
    727   isolate->handle_scope_implementer()->EnterContext(env);
    728 
    729   isolate->handle_scope_implementer()->SaveContext(isolate->context());
    730   isolate->set_context(*env);
    731 }
    732 
    733 
    734 void Context::Exit() {
    735   // Exit is essentially a static function and doesn't use the
    736   // receiver, so we have to get the current isolate from the thread
    737   // local.
    738   i::Isolate* isolate = i::Isolate::Current();
    739   if (!isolate->IsInitialized()) return;
    740 
    741   if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(),
    742                 "v8::Context::Exit()",
    743                 "Cannot exit non-entered context")) {
    744     return;
    745   }
    746 
    747   // Content of 'last_context' could be NULL.
    748   i::Context* last_context =
    749       isolate->handle_scope_implementer()->RestoreContext();
    750   isolate->set_context(last_context);
    751   isolate->set_context_exit_happened(true);
    752 }
    753 
    754 
    755 void Context::SetData(v8::Handle<String> data) {
    756   i::Handle<i::Context> env = Utils::OpenHandle(this);
    757   i::Isolate* isolate = env->GetIsolate();
    758   if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
    759   i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
    760   ASSERT(env->IsGlobalContext());
    761   if (env->IsGlobalContext()) {
    762     env->set_data(*raw_data);
    763   }
    764 }
    765 
    766 
    767 v8::Local<v8::Value> Context::GetData() {
    768   i::Handle<i::Context> env = Utils::OpenHandle(this);
    769   i::Isolate* isolate = env->GetIsolate();
    770   if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
    771     return v8::Local<Value>();
    772   }
    773   i::Object* raw_result = NULL;
    774   ASSERT(env->IsGlobalContext());
    775   if (env->IsGlobalContext()) {
    776     raw_result = env->data();
    777   } else {
    778     return Local<Value>();
    779   }
    780   i::Handle<i::Object> result(raw_result, isolate);
    781   return Utils::ToLocal(result);
    782 }
    783 
    784 
    785 i::Object** v8::HandleScope::RawClose(i::Object** value) {
    786   if (!ApiCheck(!is_closed_,
    787                 "v8::HandleScope::Close()",
    788                 "Local scope has already been closed")) {
    789     return 0;
    790   }
    791   LOG_API(isolate_, "CloseHandleScope");
    792 
    793   // Read the result before popping the handle block.
    794   i::Object* result = NULL;
    795   if (value != NULL) {
    796     result = *value;
    797   }
    798   is_closed_ = true;
    799   Leave();
    800 
    801   if (value == NULL) {
    802     return NULL;
    803   }
    804 
    805   // Allocate a new handle on the previous handle block.
    806   i::Handle<i::Object> handle(result);
    807   return handle.location();
    808 }
    809 
    810 
    811 // --- N e a n d e r ---
    812 
    813 
    814 // A constructor cannot easily return an error value, therefore it is necessary
    815 // to check for a dead VM with ON_BAILOUT before constructing any Neander
    816 // objects.  To remind you about this there is no HandleScope in the
    817 // NeanderObject constructor.  When you add one to the site calling the
    818 // constructor you should check that you ensured the VM was not dead first.
    819 NeanderObject::NeanderObject(int size) {
    820   i::Isolate* isolate = i::Isolate::Current();
    821   EnsureInitializedForIsolate(isolate, "v8::Nowhere");
    822   ENTER_V8(isolate);
    823   value_ = isolate->factory()->NewNeanderObject();
    824   i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
    825   value_->set_elements(*elements);
    826 }
    827 
    828 
    829 int NeanderObject::size() {
    830   return i::FixedArray::cast(value_->elements())->length();
    831 }
    832 
    833 
    834 NeanderArray::NeanderArray() : obj_(2) {
    835   obj_.set(0, i::Smi::FromInt(0));
    836 }
    837 
    838 
    839 int NeanderArray::length() {
    840   return i::Smi::cast(obj_.get(0))->value();
    841 }
    842 
    843 
    844 i::Object* NeanderArray::get(int offset) {
    845   ASSERT(0 <= offset);
    846   ASSERT(offset < length());
    847   return obj_.get(offset + 1);
    848 }
    849 
    850 
    851 // This method cannot easily return an error value, therefore it is necessary
    852 // to check for a dead VM with ON_BAILOUT before calling it.  To remind you
    853 // about this there is no HandleScope in this method.  When you add one to the
    854 // site calling this method you should check that you ensured the VM was not
    855 // dead first.
    856 void NeanderArray::add(i::Handle<i::Object> value) {
    857   int length = this->length();
    858   int size = obj_.size();
    859   if (length == size - 1) {
    860     i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
    861     for (int i = 0; i < length; i++)
    862       new_elms->set(i + 1, get(i));
    863     obj_.value()->set_elements(*new_elms);
    864   }
    865   obj_.set(length + 1, *value);
    866   obj_.set(0, i::Smi::FromInt(length + 1));
    867 }
    868 
    869 
    870 void NeanderArray::set(int index, i::Object* value) {
    871   if (index < 0 || index >= this->length()) return;
    872   obj_.set(index + 1, value);
    873 }
    874 
    875 
    876 // --- T e m p l a t e ---
    877 
    878 
    879 static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
    880   that->set_tag(i::Smi::FromInt(type));
    881 }
    882 
    883 
    884 void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
    885                    v8::PropertyAttribute attribute) {
    886   i::Isolate* isolate = i::Isolate::Current();
    887   if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
    888   ENTER_V8(isolate);
    889   i::HandleScope scope(isolate);
    890   i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
    891   if (list->IsUndefined()) {
    892     list = NeanderArray().value();
    893     Utils::OpenHandle(this)->set_property_list(*list);
    894   }
    895   NeanderArray array(list);
    896   array.add(Utils::OpenHandle(*name));
    897   array.add(Utils::OpenHandle(*value));
    898   array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
    899 }
    900 
    901 
    902 // --- F u n c t i o n   T e m p l a t e ---
    903 static void InitializeFunctionTemplate(
    904       i::Handle<i::FunctionTemplateInfo> info) {
    905   info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
    906   info->set_flag(0);
    907 }
    908 
    909 
    910 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
    911   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
    912   if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
    913     return Local<ObjectTemplate>();
    914   }
    915   ENTER_V8(isolate);
    916   i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
    917   if (result->IsUndefined()) {
    918     result = Utils::OpenHandle(*ObjectTemplate::New());
    919     Utils::OpenHandle(this)->set_prototype_template(*result);
    920   }
    921   return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
    922 }
    923 
    924 
    925 void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
    926   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
    927   if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
    928   ENTER_V8(isolate);
    929   Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
    930 }
    931 
    932 
    933 Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
    934     v8::Handle<Value> data, v8::Handle<Signature> signature) {
    935   i::Isolate* isolate = i::Isolate::Current();
    936   EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
    937   LOG_API(isolate, "FunctionTemplate::New");
    938   ENTER_V8(isolate);
    939   i::Handle<i::Struct> struct_obj =
    940       isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
    941   i::Handle<i::FunctionTemplateInfo> obj =
    942       i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
    943   InitializeFunctionTemplate(obj);
    944   int next_serial_number = isolate->next_serial_number();
    945   isolate->set_next_serial_number(next_serial_number + 1);
    946   obj->set_serial_number(i::Smi::FromInt(next_serial_number));
    947   if (callback != 0) {
    948     if (data.IsEmpty()) data = v8::Undefined();
    949     Utils::ToLocal(obj)->SetCallHandler(callback, data);
    950   }
    951   obj->set_undetectable(false);
    952   obj->set_needs_access_check(false);
    953 
    954   if (!signature.IsEmpty())
    955     obj->set_signature(*Utils::OpenHandle(*signature));
    956   return Utils::ToLocal(obj);
    957 }
    958 
    959 
    960 Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
    961       int argc, Handle<FunctionTemplate> argv[]) {
    962   i::Isolate* isolate = i::Isolate::Current();
    963   EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
    964   LOG_API(isolate, "Signature::New");
    965   ENTER_V8(isolate);
    966   i::Handle<i::Struct> struct_obj =
    967       isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
    968   i::Handle<i::SignatureInfo> obj =
    969       i::Handle<i::SignatureInfo>::cast(struct_obj);
    970   if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
    971   if (argc > 0) {
    972     i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
    973     for (int i = 0; i < argc; i++) {
    974       if (!argv[i].IsEmpty())
    975         args->set(i, *Utils::OpenHandle(*argv[i]));
    976     }
    977     obj->set_args(*args);
    978   }
    979   return Utils::ToLocal(obj);
    980 }
    981 
    982 
    983 Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
    984   Handle<FunctionTemplate> types[1] = { type };
    985   return TypeSwitch::New(1, types);
    986 }
    987 
    988 
    989 Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
    990   i::Isolate* isolate = i::Isolate::Current();
    991   EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
    992   LOG_API(isolate, "TypeSwitch::New");
    993   ENTER_V8(isolate);
    994   i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
    995   for (int i = 0; i < argc; i++)
    996     vector->set(i, *Utils::OpenHandle(*types[i]));
    997   i::Handle<i::Struct> struct_obj =
    998       isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
    999   i::Handle<i::TypeSwitchInfo> obj =
   1000       i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
   1001   obj->set_types(*vector);
   1002   return Utils::ToLocal(obj);
   1003 }
   1004 
   1005 
   1006 int TypeSwitch::match(v8::Handle<Value> value) {
   1007   i::Isolate* isolate = i::Isolate::Current();
   1008   LOG_API(isolate, "TypeSwitch::match");
   1009   USE(isolate);
   1010   i::Handle<i::Object> obj = Utils::OpenHandle(*value);
   1011   i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
   1012   i::FixedArray* types = i::FixedArray::cast(info->types());
   1013   for (int i = 0; i < types->length(); i++) {
   1014     if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
   1015       return i + 1;
   1016   }
   1017   return 0;
   1018 }
   1019 
   1020 
   1021 #define SET_FIELD_WRAPPED(obj, setter, cdata) do {    \
   1022     i::Handle<i::Object> foreign = FromCData(cdata);  \
   1023     (obj)->setter(*foreign);                          \
   1024   } while (false)
   1025 
   1026 
   1027 void FunctionTemplate::SetCallHandler(InvocationCallback callback,
   1028                                       v8::Handle<Value> data) {
   1029   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1030   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
   1031   ENTER_V8(isolate);
   1032   i::HandleScope scope(isolate);
   1033   i::Handle<i::Struct> struct_obj =
   1034       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
   1035   i::Handle<i::CallHandlerInfo> obj =
   1036       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
   1037   SET_FIELD_WRAPPED(obj, set_callback, callback);
   1038   if (data.IsEmpty()) data = v8::Undefined();
   1039   obj->set_data(*Utils::OpenHandle(*data));
   1040   Utils::OpenHandle(this)->set_call_code(*obj);
   1041 }
   1042 
   1043 
   1044 static i::Handle<i::AccessorInfo> MakeAccessorInfo(
   1045       v8::Handle<String> name,
   1046       AccessorGetter getter,
   1047       AccessorSetter setter,
   1048       v8::Handle<Value> data,
   1049       v8::AccessControl settings,
   1050       v8::PropertyAttribute attributes) {
   1051   i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
   1052   ASSERT(getter != NULL);
   1053   SET_FIELD_WRAPPED(obj, set_getter, getter);
   1054   SET_FIELD_WRAPPED(obj, set_setter, setter);
   1055   if (data.IsEmpty()) data = v8::Undefined();
   1056   obj->set_data(*Utils::OpenHandle(*data));
   1057   obj->set_name(*Utils::OpenHandle(*name));
   1058   if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
   1059   if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
   1060   if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
   1061   obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
   1062   return obj;
   1063 }
   1064 
   1065 
   1066 void FunctionTemplate::AddInstancePropertyAccessor(
   1067       v8::Handle<String> name,
   1068       AccessorGetter getter,
   1069       AccessorSetter setter,
   1070       v8::Handle<Value> data,
   1071       v8::AccessControl settings,
   1072       v8::PropertyAttribute attributes) {
   1073   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1074   if (IsDeadCheck(isolate,
   1075                   "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
   1076     return;
   1077   }
   1078   ENTER_V8(isolate);
   1079   i::HandleScope scope(isolate);
   1080 
   1081   i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
   1082                                                     getter, setter, data,
   1083                                                     settings, attributes);
   1084   i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
   1085   if (list->IsUndefined()) {
   1086     list = NeanderArray().value();
   1087     Utils::OpenHandle(this)->set_property_accessors(*list);
   1088   }
   1089   NeanderArray array(list);
   1090   array.add(obj);
   1091 }
   1092 
   1093 
   1094 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
   1095   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1096   if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
   1097       || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
   1098     return Local<ObjectTemplate>();
   1099   ENTER_V8(isolate);
   1100   if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
   1101     Local<ObjectTemplate> templ =
   1102         ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
   1103     Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
   1104   }
   1105   i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
   1106         Utils::OpenHandle(this)->instance_template()));
   1107   return Utils::ToLocal(result);
   1108 }
   1109 
   1110 
   1111 void FunctionTemplate::SetClassName(Handle<String> name) {
   1112   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1113   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
   1114   ENTER_V8(isolate);
   1115   Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
   1116 }
   1117 
   1118 
   1119 void FunctionTemplate::SetHiddenPrototype(bool value) {
   1120   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1121   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
   1122     return;
   1123   }
   1124   ENTER_V8(isolate);
   1125   Utils::OpenHandle(this)->set_hidden_prototype(value);
   1126 }
   1127 
   1128 
   1129 void FunctionTemplate::ReadOnlyPrototype() {
   1130   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1131   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
   1132     return;
   1133   }
   1134   ENTER_V8(isolate);
   1135   Utils::OpenHandle(this)->set_read_only_prototype(true);
   1136 }
   1137 
   1138 
   1139 void FunctionTemplate::SetNamedInstancePropertyHandler(
   1140       NamedPropertyGetter getter,
   1141       NamedPropertySetter setter,
   1142       NamedPropertyQuery query,
   1143       NamedPropertyDeleter remover,
   1144       NamedPropertyEnumerator enumerator,
   1145       Handle<Value> data) {
   1146   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1147   if (IsDeadCheck(isolate,
   1148                   "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
   1149     return;
   1150   }
   1151   ENTER_V8(isolate);
   1152   i::HandleScope scope(isolate);
   1153   i::Handle<i::Struct> struct_obj =
   1154       isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
   1155   i::Handle<i::InterceptorInfo> obj =
   1156       i::Handle<i::InterceptorInfo>::cast(struct_obj);
   1157 
   1158   if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
   1159   if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
   1160   if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
   1161   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
   1162   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
   1163 
   1164   if (data.IsEmpty()) data = v8::Undefined();
   1165   obj->set_data(*Utils::OpenHandle(*data));
   1166   Utils::OpenHandle(this)->set_named_property_handler(*obj);
   1167 }
   1168 
   1169 
   1170 void FunctionTemplate::SetIndexedInstancePropertyHandler(
   1171       IndexedPropertyGetter getter,
   1172       IndexedPropertySetter setter,
   1173       IndexedPropertyQuery query,
   1174       IndexedPropertyDeleter remover,
   1175       IndexedPropertyEnumerator enumerator,
   1176       Handle<Value> data) {
   1177   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1178   if (IsDeadCheck(isolate,
   1179         "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
   1180     return;
   1181   }
   1182   ENTER_V8(isolate);
   1183   i::HandleScope scope(isolate);
   1184   i::Handle<i::Struct> struct_obj =
   1185       isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
   1186   i::Handle<i::InterceptorInfo> obj =
   1187       i::Handle<i::InterceptorInfo>::cast(struct_obj);
   1188 
   1189   if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
   1190   if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
   1191   if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
   1192   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
   1193   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
   1194 
   1195   if (data.IsEmpty()) data = v8::Undefined();
   1196   obj->set_data(*Utils::OpenHandle(*data));
   1197   Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
   1198 }
   1199 
   1200 
   1201 void FunctionTemplate::SetInstanceCallAsFunctionHandler(
   1202       InvocationCallback callback,
   1203       Handle<Value> data) {
   1204   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1205   if (IsDeadCheck(isolate,
   1206                   "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
   1207     return;
   1208   }
   1209   ENTER_V8(isolate);
   1210   i::HandleScope scope(isolate);
   1211   i::Handle<i::Struct> struct_obj =
   1212       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
   1213   i::Handle<i::CallHandlerInfo> obj =
   1214       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
   1215   SET_FIELD_WRAPPED(obj, set_callback, callback);
   1216   if (data.IsEmpty()) data = v8::Undefined();
   1217   obj->set_data(*Utils::OpenHandle(*data));
   1218   Utils::OpenHandle(this)->set_instance_call_handler(*obj);
   1219 }
   1220 
   1221 
   1222 // --- O b j e c t T e m p l a t e ---
   1223 
   1224 
   1225 Local<ObjectTemplate> ObjectTemplate::New() {
   1226   return New(Local<FunctionTemplate>());
   1227 }
   1228 
   1229 
   1230 Local<ObjectTemplate> ObjectTemplate::New(
   1231       v8::Handle<FunctionTemplate> constructor) {
   1232   i::Isolate* isolate = i::Isolate::Current();
   1233   if (IsDeadCheck(isolate, "v8::ObjectTemplate::New()")) {
   1234     return Local<ObjectTemplate>();
   1235   }
   1236   EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
   1237   LOG_API(isolate, "ObjectTemplate::New");
   1238   ENTER_V8(isolate);
   1239   i::Handle<i::Struct> struct_obj =
   1240       isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
   1241   i::Handle<i::ObjectTemplateInfo> obj =
   1242       i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
   1243   InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
   1244   if (!constructor.IsEmpty())
   1245     obj->set_constructor(*Utils::OpenHandle(*constructor));
   1246   obj->set_internal_field_count(i::Smi::FromInt(0));
   1247   return Utils::ToLocal(obj);
   1248 }
   1249 
   1250 
   1251 // Ensure that the object template has a constructor.  If no
   1252 // constructor is available we create one.
   1253 static void EnsureConstructor(ObjectTemplate* object_template) {
   1254   if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
   1255     Local<FunctionTemplate> templ = FunctionTemplate::New();
   1256     i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
   1257     constructor->set_instance_template(*Utils::OpenHandle(object_template));
   1258     Utils::OpenHandle(object_template)->set_constructor(*constructor);
   1259   }
   1260 }
   1261 
   1262 
   1263 void ObjectTemplate::SetAccessor(v8::Handle<String> name,
   1264                                  AccessorGetter getter,
   1265                                  AccessorSetter setter,
   1266                                  v8::Handle<Value> data,
   1267                                  AccessControl settings,
   1268                                  PropertyAttribute attribute) {
   1269   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1270   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
   1271   ENTER_V8(isolate);
   1272   i::HandleScope scope(isolate);
   1273   EnsureConstructor(this);
   1274   i::FunctionTemplateInfo* constructor =
   1275       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   1276   i::Handle<i::FunctionTemplateInfo> cons(constructor);
   1277   Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
   1278                                                     getter,
   1279                                                     setter,
   1280                                                     data,
   1281                                                     settings,
   1282                                                     attribute);
   1283 }
   1284 
   1285 
   1286 void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
   1287                                              NamedPropertySetter setter,
   1288                                              NamedPropertyQuery query,
   1289                                              NamedPropertyDeleter remover,
   1290                                              NamedPropertyEnumerator enumerator,
   1291                                              Handle<Value> data) {
   1292   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1293   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
   1294     return;
   1295   }
   1296   ENTER_V8(isolate);
   1297   i::HandleScope scope(isolate);
   1298   EnsureConstructor(this);
   1299   i::FunctionTemplateInfo* constructor =
   1300       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   1301   i::Handle<i::FunctionTemplateInfo> cons(constructor);
   1302   Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
   1303                                                         setter,
   1304                                                         query,
   1305                                                         remover,
   1306                                                         enumerator,
   1307                                                         data);
   1308 }
   1309 
   1310 
   1311 void ObjectTemplate::MarkAsUndetectable() {
   1312   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1313   if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
   1314   ENTER_V8(isolate);
   1315   i::HandleScope scope(isolate);
   1316   EnsureConstructor(this);
   1317   i::FunctionTemplateInfo* constructor =
   1318       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   1319   i::Handle<i::FunctionTemplateInfo> cons(constructor);
   1320   cons->set_undetectable(true);
   1321 }
   1322 
   1323 
   1324 void ObjectTemplate::SetAccessCheckCallbacks(
   1325       NamedSecurityCallback named_callback,
   1326       IndexedSecurityCallback indexed_callback,
   1327       Handle<Value> data,
   1328       bool turned_on_by_default) {
   1329   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1330   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
   1331     return;
   1332   }
   1333   ENTER_V8(isolate);
   1334   i::HandleScope scope(isolate);
   1335   EnsureConstructor(this);
   1336 
   1337   i::Handle<i::Struct> struct_info =
   1338       isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
   1339   i::Handle<i::AccessCheckInfo> info =
   1340       i::Handle<i::AccessCheckInfo>::cast(struct_info);
   1341 
   1342   SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
   1343   SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
   1344 
   1345   if (data.IsEmpty()) data = v8::Undefined();
   1346   info->set_data(*Utils::OpenHandle(*data));
   1347 
   1348   i::FunctionTemplateInfo* constructor =
   1349       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   1350   i::Handle<i::FunctionTemplateInfo> cons(constructor);
   1351   cons->set_access_check_info(*info);
   1352   cons->set_needs_access_check(turned_on_by_default);
   1353 }
   1354 
   1355 
   1356 void ObjectTemplate::SetIndexedPropertyHandler(
   1357       IndexedPropertyGetter getter,
   1358       IndexedPropertySetter setter,
   1359       IndexedPropertyQuery query,
   1360       IndexedPropertyDeleter remover,
   1361       IndexedPropertyEnumerator enumerator,
   1362       Handle<Value> data) {
   1363   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1364   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
   1365     return;
   1366   }
   1367   ENTER_V8(isolate);
   1368   i::HandleScope scope(isolate);
   1369   EnsureConstructor(this);
   1370   i::FunctionTemplateInfo* constructor =
   1371       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   1372   i::Handle<i::FunctionTemplateInfo> cons(constructor);
   1373   Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
   1374                                                           setter,
   1375                                                           query,
   1376                                                           remover,
   1377                                                           enumerator,
   1378                                                           data);
   1379 }
   1380 
   1381 
   1382 void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
   1383                                               Handle<Value> data) {
   1384   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1385   if (IsDeadCheck(isolate,
   1386                   "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
   1387     return;
   1388   }
   1389   ENTER_V8(isolate);
   1390   i::HandleScope scope(isolate);
   1391   EnsureConstructor(this);
   1392   i::FunctionTemplateInfo* constructor =
   1393       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   1394   i::Handle<i::FunctionTemplateInfo> cons(constructor);
   1395   Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
   1396 }
   1397 
   1398 
   1399 int ObjectTemplate::InternalFieldCount() {
   1400   if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
   1401                   "v8::ObjectTemplate::InternalFieldCount()")) {
   1402     return 0;
   1403   }
   1404   return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
   1405 }
   1406 
   1407 
   1408 void ObjectTemplate::SetInternalFieldCount(int value) {
   1409   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1410   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
   1411     return;
   1412   }
   1413   if (!ApiCheck(i::Smi::IsValid(value),
   1414                 "v8::ObjectTemplate::SetInternalFieldCount()",
   1415                 "Invalid internal field count")) {
   1416     return;
   1417   }
   1418   ENTER_V8(isolate);
   1419   if (value > 0) {
   1420     // The internal field count is set by the constructor function's
   1421     // construct code, so we ensure that there is a constructor
   1422     // function to do the setting.
   1423     EnsureConstructor(this);
   1424   }
   1425   Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
   1426 }
   1427 
   1428 
   1429 // --- S c r i p t D a t a ---
   1430 
   1431 
   1432 ScriptData* ScriptData::PreCompile(const char* input, int length) {
   1433   i::Utf8ToUtf16CharacterStream stream(
   1434       reinterpret_cast<const unsigned char*>(input), length);
   1435   return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping);
   1436 }
   1437 
   1438 
   1439 ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
   1440   i::Handle<i::String> str = Utils::OpenHandle(*source);
   1441   if (str->IsExternalTwoByteString()) {
   1442     i::ExternalTwoByteStringUtf16CharacterStream stream(
   1443       i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
   1444     return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping);
   1445   } else {
   1446     i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
   1447     return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping);
   1448   }
   1449 }
   1450 
   1451 
   1452 ScriptData* ScriptData::New(const char* data, int length) {
   1453   // Return an empty ScriptData if the length is obviously invalid.
   1454   if (length % sizeof(unsigned) != 0) {
   1455     return new i::ScriptDataImpl();
   1456   }
   1457 
   1458   // Copy the data to ensure it is properly aligned.
   1459   int deserialized_data_length = length / sizeof(unsigned);
   1460   // If aligned, don't create a copy of the data.
   1461   if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
   1462     return new i::ScriptDataImpl(data, length);
   1463   }
   1464   // Copy the data to align it.
   1465   unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
   1466   i::OS::MemCopy(deserialized_data, data, length);
   1467 
   1468   return new i::ScriptDataImpl(
   1469       i::Vector<unsigned>(deserialized_data, deserialized_data_length));
   1470 }
   1471 
   1472 
   1473 // --- S c r i p t ---
   1474 
   1475 
   1476 Local<Script> Script::New(v8::Handle<String> source,
   1477                           v8::ScriptOrigin* origin,
   1478                           v8::ScriptData* pre_data,
   1479                           v8::Handle<String> script_data) {
   1480   i::Isolate* isolate = i::Isolate::Current();
   1481   ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
   1482   LOG_API(isolate, "Script::New");
   1483   ENTER_V8(isolate);
   1484   i::SharedFunctionInfo* raw_result = NULL;
   1485   { i::HandleScope scope(isolate);
   1486     i::Handle<i::String> str = Utils::OpenHandle(*source);
   1487     i::Handle<i::Object> name_obj;
   1488     int line_offset = 0;
   1489     int column_offset = 0;
   1490     if (origin != NULL) {
   1491       if (!origin->ResourceName().IsEmpty()) {
   1492         name_obj = Utils::OpenHandle(*origin->ResourceName());
   1493       }
   1494       if (!origin->ResourceLineOffset().IsEmpty()) {
   1495         line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
   1496       }
   1497       if (!origin->ResourceColumnOffset().IsEmpty()) {
   1498         column_offset =
   1499             static_cast<int>(origin->ResourceColumnOffset()->Value());
   1500       }
   1501     }
   1502     EXCEPTION_PREAMBLE(isolate);
   1503     i::ScriptDataImpl* pre_data_impl =
   1504         static_cast<i::ScriptDataImpl*>(pre_data);
   1505     // We assert that the pre-data is sane, even though we can actually
   1506     // handle it if it turns out not to be in release mode.
   1507     ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
   1508     // If the pre-data isn't sane we simply ignore it
   1509     if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
   1510       pre_data_impl = NULL;
   1511     }
   1512     i::Handle<i::SharedFunctionInfo> result =
   1513       i::Compiler::Compile(str,
   1514                            name_obj,
   1515                            line_offset,
   1516                            column_offset,
   1517                            NULL,
   1518                            pre_data_impl,
   1519                            Utils::OpenHandle(*script_data),
   1520                            i::NOT_NATIVES_CODE);
   1521     has_pending_exception = result.is_null();
   1522     EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
   1523     raw_result = *result;
   1524   }
   1525   i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
   1526   return Local<Script>(ToApi<Script>(result));
   1527 }
   1528 
   1529 
   1530 Local<Script> Script::New(v8::Handle<String> source,
   1531                           v8::Handle<Value> file_name) {
   1532   ScriptOrigin origin(file_name);
   1533   return New(source, &origin);
   1534 }
   1535 
   1536 
   1537 Local<Script> Script::Compile(v8::Handle<String> source,
   1538                               v8::ScriptOrigin* origin,
   1539                               v8::ScriptData* pre_data,
   1540                               v8::Handle<String> script_data) {
   1541   i::Isolate* isolate = i::Isolate::Current();
   1542   ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
   1543   LOG_API(isolate, "Script::Compile");
   1544   ENTER_V8(isolate);
   1545   Local<Script> generic = New(source, origin, pre_data, script_data);
   1546   if (generic.IsEmpty())
   1547     return generic;
   1548   i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
   1549   i::Handle<i::SharedFunctionInfo> function =
   1550       i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
   1551   i::Handle<i::JSFunction> result =
   1552       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   1553           function,
   1554           isolate->global_context());
   1555   return Local<Script>(ToApi<Script>(result));
   1556 }
   1557 
   1558 
   1559 Local<Script> Script::Compile(v8::Handle<String> source,
   1560                               v8::Handle<Value> file_name,
   1561                               v8::Handle<String> script_data) {
   1562   ScriptOrigin origin(file_name);
   1563   return Compile(source, &origin, 0, script_data);
   1564 }
   1565 
   1566 
   1567 Local<Value> Script::Run() {
   1568   i::Isolate* isolate = i::Isolate::Current();
   1569   ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
   1570   LOG_API(isolate, "Script::Run");
   1571   ENTER_V8(isolate);
   1572   i::Object* raw_result = NULL;
   1573   {
   1574     i::HandleScope scope(isolate);
   1575     i::Handle<i::Object> obj = Utils::OpenHandle(this);
   1576     i::Handle<i::JSFunction> fun;
   1577     if (obj->IsSharedFunctionInfo()) {
   1578       i::Handle<i::SharedFunctionInfo>
   1579           function_info(i::SharedFunctionInfo::cast(*obj), isolate);
   1580       fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
   1581           function_info, isolate->global_context());
   1582     } else {
   1583       fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
   1584     }
   1585     EXCEPTION_PREAMBLE(isolate);
   1586     i::Handle<i::Object> receiver(
   1587         isolate->context()->global_proxy(), isolate);
   1588     i::Handle<i::Object> result =
   1589         i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
   1590     EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
   1591     raw_result = *result;
   1592   }
   1593   i::Handle<i::Object> result(raw_result, isolate);
   1594   return Utils::ToLocal(result);
   1595 }
   1596 
   1597 
   1598 static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
   1599   i::Handle<i::Object> obj = Utils::OpenHandle(script);
   1600   i::Handle<i::SharedFunctionInfo> result;
   1601   if (obj->IsSharedFunctionInfo()) {
   1602     result =
   1603         i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
   1604   } else {
   1605     result =
   1606         i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
   1607   }
   1608   return result;
   1609 }
   1610 
   1611 
   1612 Local<Value> Script::Id() {
   1613   i::Isolate* isolate = i::Isolate::Current();
   1614   ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
   1615   LOG_API(isolate, "Script::Id");
   1616   i::Object* raw_id = NULL;
   1617   {
   1618     i::HandleScope scope(isolate);
   1619     i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
   1620     i::Handle<i::Script> script(i::Script::cast(function_info->script()));
   1621     i::Handle<i::Object> id(script->id());
   1622     raw_id = *id;
   1623   }
   1624   i::Handle<i::Object> id(raw_id);
   1625   return Utils::ToLocal(id);
   1626 }
   1627 
   1628 
   1629 void Script::SetData(v8::Handle<String> data) {
   1630   i::Isolate* isolate = i::Isolate::Current();
   1631   ON_BAILOUT(isolate, "v8::Script::SetData()", return);
   1632   LOG_API(isolate, "Script::SetData");
   1633   {
   1634     i::HandleScope scope(isolate);
   1635     i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
   1636     i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
   1637     i::Handle<i::Script> script(i::Script::cast(function_info->script()));
   1638     script->set_data(*raw_data);
   1639   }
   1640 }
   1641 
   1642 
   1643 // --- E x c e p t i o n s ---
   1644 
   1645 
   1646 v8::TryCatch::TryCatch()
   1647     : isolate_(i::Isolate::Current()),
   1648       next_(isolate_->try_catch_handler_address()),
   1649       exception_(isolate_->heap()->the_hole_value()),
   1650       message_(i::Smi::FromInt(0)),
   1651       is_verbose_(false),
   1652       can_continue_(true),
   1653       capture_message_(true),
   1654       rethrow_(false) {
   1655   isolate_->RegisterTryCatchHandler(this);
   1656 }
   1657 
   1658 
   1659 v8::TryCatch::~TryCatch() {
   1660   ASSERT(isolate_ == i::Isolate::Current());
   1661   if (rethrow_) {
   1662     v8::HandleScope scope;
   1663     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
   1664     isolate_->UnregisterTryCatchHandler(this);
   1665     v8::ThrowException(exc);
   1666   } else {
   1667     isolate_->UnregisterTryCatchHandler(this);
   1668   }
   1669 }
   1670 
   1671 
   1672 bool v8::TryCatch::HasCaught() const {
   1673   return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
   1674 }
   1675 
   1676 
   1677 bool v8::TryCatch::CanContinue() const {
   1678   return can_continue_;
   1679 }
   1680 
   1681 
   1682 v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
   1683   if (!HasCaught()) return v8::Local<v8::Value>();
   1684   rethrow_ = true;
   1685   return v8::Undefined();
   1686 }
   1687 
   1688 
   1689 v8::Local<Value> v8::TryCatch::Exception() const {
   1690   ASSERT(isolate_ == i::Isolate::Current());
   1691   if (HasCaught()) {
   1692     // Check for out of memory exception.
   1693     i::Object* exception = reinterpret_cast<i::Object*>(exception_);
   1694     return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
   1695   } else {
   1696     return v8::Local<Value>();
   1697   }
   1698 }
   1699 
   1700 
   1701 v8::Local<Value> v8::TryCatch::StackTrace() const {
   1702   ASSERT(isolate_ == i::Isolate::Current());
   1703   if (HasCaught()) {
   1704     i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
   1705     if (!raw_obj->IsJSObject()) return v8::Local<Value>();
   1706     i::HandleScope scope(isolate_);
   1707     i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
   1708     i::Handle<i::String> name = isolate_->factory()->LookupAsciiSymbol("stack");
   1709     if (!obj->HasProperty(*name)) return v8::Local<Value>();
   1710     i::Handle<i::Object> value = i::GetProperty(obj, name);
   1711     if (value.is_null()) return v8::Local<Value>();
   1712     return v8::Utils::ToLocal(scope.CloseAndEscape(value));
   1713   } else {
   1714     return v8::Local<Value>();
   1715   }
   1716 }
   1717 
   1718 
   1719 v8::Local<v8::Message> v8::TryCatch::Message() const {
   1720   ASSERT(isolate_ == i::Isolate::Current());
   1721   if (HasCaught() && message_ != i::Smi::FromInt(0)) {
   1722     i::Object* message = reinterpret_cast<i::Object*>(message_);
   1723     return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
   1724   } else {
   1725     return v8::Local<v8::Message>();
   1726   }
   1727 }
   1728 
   1729 
   1730 void v8::TryCatch::Reset() {
   1731   ASSERT(isolate_ == i::Isolate::Current());
   1732   exception_ = isolate_->heap()->the_hole_value();
   1733   message_ = i::Smi::FromInt(0);
   1734 }
   1735 
   1736 
   1737 void v8::TryCatch::SetVerbose(bool value) {
   1738   is_verbose_ = value;
   1739 }
   1740 
   1741 
   1742 void v8::TryCatch::SetCaptureMessage(bool value) {
   1743   capture_message_ = value;
   1744 }
   1745 
   1746 
   1747 // --- M e s s a g e ---
   1748 
   1749 
   1750 Local<String> Message::Get() const {
   1751   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1752   ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
   1753   ENTER_V8(isolate);
   1754   HandleScope scope;
   1755   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   1756   i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
   1757   Local<String> result = Utils::ToLocal(raw_result);
   1758   return scope.Close(result);
   1759 }
   1760 
   1761 
   1762 v8::Handle<Value> Message::GetScriptResourceName() const {
   1763   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1764   if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
   1765     return Local<String>();
   1766   }
   1767   ENTER_V8(isolate);
   1768   HandleScope scope;
   1769   i::Handle<i::JSMessageObject> message =
   1770       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   1771   // Return this.script.name.
   1772   i::Handle<i::JSValue> script =
   1773       i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
   1774   i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
   1775   return scope.Close(Utils::ToLocal(resource_name));
   1776 }
   1777 
   1778 
   1779 v8::Handle<Value> Message::GetScriptData() const {
   1780   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1781   if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
   1782     return Local<Value>();
   1783   }
   1784   ENTER_V8(isolate);
   1785   HandleScope scope;
   1786   i::Handle<i::JSMessageObject> message =
   1787       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   1788   // Return this.script.data.
   1789   i::Handle<i::JSValue> script =
   1790       i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
   1791   i::Handle<i::Object> data(i::Script::cast(script->value())->data());
   1792   return scope.Close(Utils::ToLocal(data));
   1793 }
   1794 
   1795 
   1796 v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
   1797   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1798   if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
   1799     return Local<v8::StackTrace>();
   1800   }
   1801   ENTER_V8(isolate);
   1802   HandleScope scope;
   1803   i::Handle<i::JSMessageObject> message =
   1804       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   1805   i::Handle<i::Object> stackFramesObj(message->stack_frames());
   1806   if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
   1807   i::Handle<i::JSArray> stackTrace =
   1808       i::Handle<i::JSArray>::cast(stackFramesObj);
   1809   return scope.Close(Utils::StackTraceToLocal(stackTrace));
   1810 }
   1811 
   1812 
   1813 static i::Handle<i::Object> CallV8HeapFunction(const char* name,
   1814                                                i::Handle<i::Object> recv,
   1815                                                int argc,
   1816                                                i::Handle<i::Object> argv[],
   1817                                                bool* has_pending_exception) {
   1818   i::Isolate* isolate = i::Isolate::Current();
   1819   i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name);
   1820   i::Object* object_fun =
   1821       isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
   1822   i::Handle<i::JSFunction> fun =
   1823       i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
   1824   i::Handle<i::Object> value =
   1825       i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
   1826   return value;
   1827 }
   1828 
   1829 
   1830 static i::Handle<i::Object> CallV8HeapFunction(const char* name,
   1831                                                i::Handle<i::Object> data,
   1832                                                bool* has_pending_exception) {
   1833   i::Handle<i::Object> argv[] = { data };
   1834   return CallV8HeapFunction(name,
   1835                             i::Isolate::Current()->js_builtins_object(),
   1836                             ARRAY_SIZE(argv),
   1837                             argv,
   1838                             has_pending_exception);
   1839 }
   1840 
   1841 
   1842 int Message::GetLineNumber() const {
   1843   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1844   ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
   1845   ENTER_V8(isolate);
   1846   i::HandleScope scope(isolate);
   1847 
   1848   EXCEPTION_PREAMBLE(isolate);
   1849   i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
   1850                                                    Utils::OpenHandle(this),
   1851                                                    &has_pending_exception);
   1852   EXCEPTION_BAILOUT_CHECK(isolate, 0);
   1853   return static_cast<int>(result->Number());
   1854 }
   1855 
   1856 
   1857 int Message::GetStartPosition() const {
   1858   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1859   if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
   1860   ENTER_V8(isolate);
   1861   i::HandleScope scope(isolate);
   1862   i::Handle<i::JSMessageObject> message =
   1863       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   1864   return message->start_position();
   1865 }
   1866 
   1867 
   1868 int Message::GetEndPosition() const {
   1869   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1870   if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
   1871   ENTER_V8(isolate);
   1872   i::HandleScope scope(isolate);
   1873   i::Handle<i::JSMessageObject> message =
   1874       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   1875   return message->end_position();
   1876 }
   1877 
   1878 
   1879 int Message::GetStartColumn() const {
   1880   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1881   if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
   1882     return kNoColumnInfo;
   1883   }
   1884   ENTER_V8(isolate);
   1885   i::HandleScope scope(isolate);
   1886   i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
   1887   EXCEPTION_PREAMBLE(isolate);
   1888   i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
   1889       "GetPositionInLine",
   1890       data_obj,
   1891       &has_pending_exception);
   1892   EXCEPTION_BAILOUT_CHECK(isolate, 0);
   1893   return static_cast<int>(start_col_obj->Number());
   1894 }
   1895 
   1896 
   1897 int Message::GetEndColumn() const {
   1898   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1899   if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
   1900   ENTER_V8(isolate);
   1901   i::HandleScope scope(isolate);
   1902   i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
   1903   EXCEPTION_PREAMBLE(isolate);
   1904   i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
   1905       "GetPositionInLine",
   1906       data_obj,
   1907       &has_pending_exception);
   1908   EXCEPTION_BAILOUT_CHECK(isolate, 0);
   1909   i::Handle<i::JSMessageObject> message =
   1910       i::Handle<i::JSMessageObject>::cast(data_obj);
   1911   int start = message->start_position();
   1912   int end = message->end_position();
   1913   return static_cast<int>(start_col_obj->Number()) + (end - start);
   1914 }
   1915 
   1916 
   1917 Local<String> Message::GetSourceLine() const {
   1918   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1919   ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
   1920   ENTER_V8(isolate);
   1921   HandleScope scope;
   1922   EXCEPTION_PREAMBLE(isolate);
   1923   i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
   1924                                                    Utils::OpenHandle(this),
   1925                                                    &has_pending_exception);
   1926   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
   1927   if (result->IsString()) {
   1928     return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
   1929   } else {
   1930     return Local<String>();
   1931   }
   1932 }
   1933 
   1934 
   1935 void Message::PrintCurrentStackTrace(FILE* out) {
   1936   i::Isolate* isolate = i::Isolate::Current();
   1937   if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
   1938   ENTER_V8(isolate);
   1939   isolate->PrintCurrentStackTrace(out);
   1940 }
   1941 
   1942 
   1943 // --- S t a c k T r a c e ---
   1944 
   1945 Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
   1946   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1947   if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
   1948     return Local<StackFrame>();
   1949   }
   1950   ENTER_V8(isolate);
   1951   HandleScope scope;
   1952   i::Handle<i::JSArray> self = Utils::OpenHandle(this);
   1953   i::Object* raw_object = self->GetElementNoExceptionThrown(index);
   1954   i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
   1955   return scope.Close(Utils::StackFrameToLocal(obj));
   1956 }
   1957 
   1958 
   1959 int StackTrace::GetFrameCount() const {
   1960   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1961   if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
   1962   ENTER_V8(isolate);
   1963   return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
   1964 }
   1965 
   1966 
   1967 Local<Array> StackTrace::AsArray() {
   1968   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1969   if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
   1970   ENTER_V8(isolate);
   1971   return Utils::ToLocal(Utils::OpenHandle(this));
   1972 }
   1973 
   1974 
   1975 Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
   1976     StackTraceOptions options) {
   1977   i::Isolate* isolate = i::Isolate::Current();
   1978   if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
   1979     Local<StackTrace>();
   1980   }
   1981   ENTER_V8(isolate);
   1982   i::Handle<i::JSArray> stackTrace =
   1983       isolate->CaptureCurrentStackTrace(frame_limit, options);
   1984   return Utils::StackTraceToLocal(stackTrace);
   1985 }
   1986 
   1987 
   1988 // --- S t a c k F r a m e ---
   1989 
   1990 int StackFrame::GetLineNumber() const {
   1991   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   1992   if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
   1993     return Message::kNoLineNumberInfo;
   1994   }
   1995   ENTER_V8(isolate);
   1996   i::HandleScope scope(isolate);
   1997   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   1998   i::Handle<i::Object> line = GetProperty(self, "lineNumber");
   1999   if (!line->IsSmi()) {
   2000     return Message::kNoLineNumberInfo;
   2001   }
   2002   return i::Smi::cast(*line)->value();
   2003 }
   2004 
   2005 
   2006 int StackFrame::GetColumn() const {
   2007   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2008   if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
   2009     return Message::kNoColumnInfo;
   2010   }
   2011   ENTER_V8(isolate);
   2012   i::HandleScope scope(isolate);
   2013   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2014   i::Handle<i::Object> column = GetProperty(self, "column");
   2015   if (!column->IsSmi()) {
   2016     return Message::kNoColumnInfo;
   2017   }
   2018   return i::Smi::cast(*column)->value();
   2019 }
   2020 
   2021 
   2022 Local<String> StackFrame::GetScriptName() const {
   2023   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2024   if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
   2025     return Local<String>();
   2026   }
   2027   ENTER_V8(isolate);
   2028   HandleScope scope;
   2029   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2030   i::Handle<i::Object> name = GetProperty(self, "scriptName");
   2031   if (!name->IsString()) {
   2032     return Local<String>();
   2033   }
   2034   return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
   2035 }
   2036 
   2037 
   2038 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
   2039   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2040   if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
   2041     return Local<String>();
   2042   }
   2043   ENTER_V8(isolate);
   2044   HandleScope scope;
   2045   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2046   i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
   2047   if (!name->IsString()) {
   2048     return Local<String>();
   2049   }
   2050   return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
   2051 }
   2052 
   2053 
   2054 Local<String> StackFrame::GetFunctionName() const {
   2055   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2056   if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
   2057     return Local<String>();
   2058   }
   2059   ENTER_V8(isolate);
   2060   HandleScope scope;
   2061   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2062   i::Handle<i::Object> name = GetProperty(self, "functionName");
   2063   if (!name->IsString()) {
   2064     return Local<String>();
   2065   }
   2066   return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
   2067 }
   2068 
   2069 
   2070 bool StackFrame::IsEval() const {
   2071   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2072   if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
   2073   ENTER_V8(isolate);
   2074   i::HandleScope scope(isolate);
   2075   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2076   i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
   2077   return is_eval->IsTrue();
   2078 }
   2079 
   2080 
   2081 bool StackFrame::IsConstructor() const {
   2082   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2083   if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
   2084   ENTER_V8(isolate);
   2085   i::HandleScope scope(isolate);
   2086   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2087   i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
   2088   return is_constructor->IsTrue();
   2089 }
   2090 
   2091 
   2092 // --- D a t a ---
   2093 
   2094 bool Value::IsUndefined() const {
   2095   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
   2096     return false;
   2097   }
   2098   return Utils::OpenHandle(this)->IsUndefined();
   2099 }
   2100 
   2101 
   2102 bool Value::IsNull() const {
   2103   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
   2104   return Utils::OpenHandle(this)->IsNull();
   2105 }
   2106 
   2107 
   2108 bool Value::IsTrue() const {
   2109   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
   2110   return Utils::OpenHandle(this)->IsTrue();
   2111 }
   2112 
   2113 
   2114 bool Value::IsFalse() const {
   2115   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
   2116   return Utils::OpenHandle(this)->IsFalse();
   2117 }
   2118 
   2119 
   2120 bool Value::IsFunction() const {
   2121   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFunction()")) {
   2122     return false;
   2123   }
   2124   return Utils::OpenHandle(this)->IsJSFunction();
   2125 }
   2126 
   2127 
   2128 bool Value::FullIsString() const {
   2129   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsString()")) return false;
   2130   bool result = Utils::OpenHandle(this)->IsString();
   2131   ASSERT_EQ(result, QuickIsString());
   2132   return result;
   2133 }
   2134 
   2135 
   2136 bool Value::IsArray() const {
   2137   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
   2138   return Utils::OpenHandle(this)->IsJSArray();
   2139 }
   2140 
   2141 
   2142 bool Value::IsObject() const {
   2143   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
   2144   return Utils::OpenHandle(this)->IsJSObject();
   2145 }
   2146 
   2147 
   2148 bool Value::IsNumber() const {
   2149   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
   2150   return Utils::OpenHandle(this)->IsNumber();
   2151 }
   2152 
   2153 
   2154 bool Value::IsBoolean() const {
   2155   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsBoolean()")) {
   2156     return false;
   2157   }
   2158   return Utils::OpenHandle(this)->IsBoolean();
   2159 }
   2160 
   2161 
   2162 bool Value::IsExternal() const {
   2163   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
   2164     return false;
   2165   }
   2166   return Utils::OpenHandle(this)->IsForeign();
   2167 }
   2168 
   2169 
   2170 bool Value::IsInt32() const {
   2171   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
   2172   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2173   if (obj->IsSmi()) return true;
   2174   if (obj->IsNumber()) {
   2175     double value = obj->Number();
   2176     static const i::DoubleRepresentation minus_zero(-0.0);
   2177     i::DoubleRepresentation rep(value);
   2178     if (rep.bits == minus_zero.bits) {
   2179       return false;
   2180     }
   2181     return i::FastI2D(i::FastD2I(value)) == value;
   2182   }
   2183   return false;
   2184 }
   2185 
   2186 
   2187 bool Value::IsUint32() const {
   2188   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUint32()")) return false;
   2189   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2190   if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
   2191   if (obj->IsNumber()) {
   2192     double value = obj->Number();
   2193     static const i::DoubleRepresentation minus_zero(-0.0);
   2194     i::DoubleRepresentation rep(value);
   2195     if (rep.bits == minus_zero.bits) {
   2196       return false;
   2197     }
   2198     return i::FastUI2D(i::FastD2UI(value)) == value;
   2199   }
   2200   return false;
   2201 }
   2202 
   2203 
   2204 bool Value::IsDate() const {
   2205   i::Isolate* isolate = i::Isolate::Current();
   2206   if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
   2207   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2208   return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
   2209 }
   2210 
   2211 
   2212 bool Value::IsStringObject() const {
   2213   i::Isolate* isolate = i::Isolate::Current();
   2214   if (IsDeadCheck(isolate, "v8::Value::IsStringObject()")) return false;
   2215   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2216   return obj->HasSpecificClassOf(isolate->heap()->String_symbol());
   2217 }
   2218 
   2219 
   2220 bool Value::IsNumberObject() const {
   2221   i::Isolate* isolate = i::Isolate::Current();
   2222   if (IsDeadCheck(isolate, "v8::Value::IsNumberObject()")) return false;
   2223   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2224   return obj->HasSpecificClassOf(isolate->heap()->Number_symbol());
   2225 }
   2226 
   2227 
   2228 static i::Object* LookupBuiltin(i::Isolate* isolate,
   2229                                 const char* builtin_name) {
   2230   i::Handle<i::String> symbol =
   2231       isolate->factory()->LookupAsciiSymbol(builtin_name);
   2232   i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
   2233   return builtins->GetPropertyNoExceptionThrown(*symbol);
   2234 }
   2235 
   2236 
   2237 static bool CheckConstructor(i::Isolate* isolate,
   2238                              i::Handle<i::JSObject> obj,
   2239                              const char* class_name) {
   2240   return obj->map()->constructor() == LookupBuiltin(isolate, class_name);
   2241 }
   2242 
   2243 
   2244 bool Value::IsNativeError() const {
   2245   i::Isolate* isolate = i::Isolate::Current();
   2246   if (IsDeadCheck(isolate, "v8::Value::IsNativeError()")) return false;
   2247   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2248   if (obj->IsJSObject()) {
   2249     i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
   2250     return CheckConstructor(isolate, js_obj, "$Error") ||
   2251         CheckConstructor(isolate, js_obj, "$EvalError") ||
   2252         CheckConstructor(isolate, js_obj, "$RangeError") ||
   2253         CheckConstructor(isolate, js_obj, "$ReferenceError") ||
   2254         CheckConstructor(isolate, js_obj, "$SyntaxError") ||
   2255         CheckConstructor(isolate, js_obj, "$TypeError") ||
   2256         CheckConstructor(isolate, js_obj, "$URIError");
   2257   } else {
   2258     return false;
   2259   }
   2260 }
   2261 
   2262 
   2263 bool Value::IsBooleanObject() const {
   2264   i::Isolate* isolate = i::Isolate::Current();
   2265   if (IsDeadCheck(isolate, "v8::Value::IsBooleanObject()")) return false;
   2266   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2267   return obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol());
   2268 }
   2269 
   2270 
   2271 bool Value::IsRegExp() const {
   2272   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
   2273   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2274   return obj->IsJSRegExp();
   2275 }
   2276 
   2277 
   2278 Local<String> Value::ToString() const {
   2279   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2280   i::Handle<i::Object> str;
   2281   if (obj->IsString()) {
   2282     str = obj;
   2283   } else {
   2284     i::Isolate* isolate = i::Isolate::Current();
   2285     if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
   2286       return Local<String>();
   2287     }
   2288     LOG_API(isolate, "ToString");
   2289     ENTER_V8(isolate);
   2290     EXCEPTION_PREAMBLE(isolate);
   2291     str = i::Execution::ToString(obj, &has_pending_exception);
   2292     EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
   2293   }
   2294   return Local<String>(ToApi<String>(str));
   2295 }
   2296 
   2297 
   2298 Local<String> Value::ToDetailString() const {
   2299   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2300   i::Handle<i::Object> str;
   2301   if (obj->IsString()) {
   2302     str = obj;
   2303   } else {
   2304     i::Isolate* isolate = i::Isolate::Current();
   2305     if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
   2306       return Local<String>();
   2307     }
   2308     LOG_API(isolate, "ToDetailString");
   2309     ENTER_V8(isolate);
   2310     EXCEPTION_PREAMBLE(isolate);
   2311     str = i::Execution::ToDetailString(obj, &has_pending_exception);
   2312     EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
   2313   }
   2314   return Local<String>(ToApi<String>(str));
   2315 }
   2316 
   2317 
   2318 Local<v8::Object> Value::ToObject() const {
   2319   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2320   i::Handle<i::Object> val;
   2321   if (obj->IsJSObject()) {
   2322     val = obj;
   2323   } else {
   2324     i::Isolate* isolate = i::Isolate::Current();
   2325     if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
   2326       return Local<v8::Object>();
   2327     }
   2328     LOG_API(isolate, "ToObject");
   2329     ENTER_V8(isolate);
   2330     EXCEPTION_PREAMBLE(isolate);
   2331     val = i::Execution::ToObject(obj, &has_pending_exception);
   2332     EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
   2333   }
   2334   return Local<v8::Object>(ToApi<Object>(val));
   2335 }
   2336 
   2337 
   2338 Local<Boolean> Value::ToBoolean() const {
   2339   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2340   if (obj->IsBoolean()) {
   2341     return Local<Boolean>(ToApi<Boolean>(obj));
   2342   } else {
   2343     i::Isolate* isolate = i::Isolate::Current();
   2344     if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
   2345       return Local<Boolean>();
   2346     }
   2347     LOG_API(isolate, "ToBoolean");
   2348     ENTER_V8(isolate);
   2349     i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
   2350     return Local<Boolean>(ToApi<Boolean>(val));
   2351   }
   2352 }
   2353 
   2354 
   2355 Local<Number> Value::ToNumber() const {
   2356   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2357   i::Handle<i::Object> num;
   2358   if (obj->IsNumber()) {
   2359     num = obj;
   2360   } else {
   2361     i::Isolate* isolate = i::Isolate::Current();
   2362     if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
   2363       return Local<Number>();
   2364     }
   2365     LOG_API(isolate, "ToNumber");
   2366     ENTER_V8(isolate);
   2367     EXCEPTION_PREAMBLE(isolate);
   2368     num = i::Execution::ToNumber(obj, &has_pending_exception);
   2369     EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
   2370   }
   2371   return Local<Number>(ToApi<Number>(num));
   2372 }
   2373 
   2374 
   2375 Local<Integer> Value::ToInteger() const {
   2376   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2377   i::Handle<i::Object> num;
   2378   if (obj->IsSmi()) {
   2379     num = obj;
   2380   } else {
   2381     i::Isolate* isolate = i::Isolate::Current();
   2382     if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
   2383     LOG_API(isolate, "ToInteger");
   2384     ENTER_V8(isolate);
   2385     EXCEPTION_PREAMBLE(isolate);
   2386     num = i::Execution::ToInteger(obj, &has_pending_exception);
   2387     EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
   2388   }
   2389   return Local<Integer>(ToApi<Integer>(num));
   2390 }
   2391 
   2392 
   2393 void External::CheckCast(v8::Value* that) {
   2394   if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
   2395   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2396   ApiCheck(obj->IsForeign(),
   2397            "v8::External::Cast()",
   2398            "Could not convert to external");
   2399 }
   2400 
   2401 
   2402 void v8::Object::CheckCast(Value* that) {
   2403   if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
   2404   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2405   ApiCheck(obj->IsJSObject(),
   2406            "v8::Object::Cast()",
   2407            "Could not convert to object");
   2408 }
   2409 
   2410 
   2411 void v8::Function::CheckCast(Value* that) {
   2412   if (IsDeadCheck(i::Isolate::Current(), "v8::Function::Cast()")) return;
   2413   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2414   ApiCheck(obj->IsJSFunction(),
   2415            "v8::Function::Cast()",
   2416            "Could not convert to function");
   2417 }
   2418 
   2419 
   2420 void v8::String::CheckCast(v8::Value* that) {
   2421   if (IsDeadCheck(i::Isolate::Current(), "v8::String::Cast()")) return;
   2422   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2423   ApiCheck(obj->IsString(),
   2424            "v8::String::Cast()",
   2425            "Could not convert to string");
   2426 }
   2427 
   2428 
   2429 void v8::Number::CheckCast(v8::Value* that) {
   2430   if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Cast()")) return;
   2431   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2432   ApiCheck(obj->IsNumber(),
   2433            "v8::Number::Cast()",
   2434            "Could not convert to number");
   2435 }
   2436 
   2437 
   2438 void v8::Integer::CheckCast(v8::Value* that) {
   2439   if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Cast()")) return;
   2440   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2441   ApiCheck(obj->IsNumber(),
   2442            "v8::Integer::Cast()",
   2443            "Could not convert to number");
   2444 }
   2445 
   2446 
   2447 void v8::Array::CheckCast(Value* that) {
   2448   if (IsDeadCheck(i::Isolate::Current(), "v8::Array::Cast()")) return;
   2449   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2450   ApiCheck(obj->IsJSArray(),
   2451            "v8::Array::Cast()",
   2452            "Could not convert to array");
   2453 }
   2454 
   2455 
   2456 void v8::Date::CheckCast(v8::Value* that) {
   2457   i::Isolate* isolate = i::Isolate::Current();
   2458   if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
   2459   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2460   ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
   2461            "v8::Date::Cast()",
   2462            "Could not convert to date");
   2463 }
   2464 
   2465 
   2466 void v8::StringObject::CheckCast(v8::Value* that) {
   2467   i::Isolate* isolate = i::Isolate::Current();
   2468   if (IsDeadCheck(isolate, "v8::StringObject::Cast()")) return;
   2469   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2470   ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_symbol()),
   2471            "v8::StringObject::Cast()",
   2472            "Could not convert to StringObject");
   2473 }
   2474 
   2475 
   2476 void v8::NumberObject::CheckCast(v8::Value* that) {
   2477   i::Isolate* isolate = i::Isolate::Current();
   2478   if (IsDeadCheck(isolate, "v8::NumberObject::Cast()")) return;
   2479   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2480   ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_symbol()),
   2481            "v8::NumberObject::Cast()",
   2482            "Could not convert to NumberObject");
   2483 }
   2484 
   2485 
   2486 void v8::BooleanObject::CheckCast(v8::Value* that) {
   2487   i::Isolate* isolate = i::Isolate::Current();
   2488   if (IsDeadCheck(isolate, "v8::BooleanObject::Cast()")) return;
   2489   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2490   ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol()),
   2491            "v8::BooleanObject::Cast()",
   2492            "Could not convert to BooleanObject");
   2493 }
   2494 
   2495 
   2496 void v8::RegExp::CheckCast(v8::Value* that) {
   2497   if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
   2498   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   2499   ApiCheck(obj->IsJSRegExp(),
   2500            "v8::RegExp::Cast()",
   2501            "Could not convert to regular expression");
   2502 }
   2503 
   2504 
   2505 bool Value::BooleanValue() const {
   2506   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2507   if (obj->IsBoolean()) {
   2508     return obj->IsTrue();
   2509   } else {
   2510     i::Isolate* isolate = i::Isolate::Current();
   2511     if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
   2512     LOG_API(isolate, "BooleanValue");
   2513     ENTER_V8(isolate);
   2514     i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
   2515     return value->IsTrue();
   2516   }
   2517 }
   2518 
   2519 
   2520 double Value::NumberValue() const {
   2521   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2522   i::Handle<i::Object> num;
   2523   if (obj->IsNumber()) {
   2524     num = obj;
   2525   } else {
   2526     i::Isolate* isolate = i::Isolate::Current();
   2527     if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
   2528       return i::OS::nan_value();
   2529     }
   2530     LOG_API(isolate, "NumberValue");
   2531     ENTER_V8(isolate);
   2532     EXCEPTION_PREAMBLE(isolate);
   2533     num = i::Execution::ToNumber(obj, &has_pending_exception);
   2534     EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
   2535   }
   2536   return num->Number();
   2537 }
   2538 
   2539 
   2540 int64_t Value::IntegerValue() const {
   2541   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2542   i::Handle<i::Object> num;
   2543   if (obj->IsNumber()) {
   2544     num = obj;
   2545   } else {
   2546     i::Isolate* isolate = i::Isolate::Current();
   2547     if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
   2548     LOG_API(isolate, "IntegerValue");
   2549     ENTER_V8(isolate);
   2550     EXCEPTION_PREAMBLE(isolate);
   2551     num = i::Execution::ToInteger(obj, &has_pending_exception);
   2552     EXCEPTION_BAILOUT_CHECK(isolate, 0);
   2553   }
   2554   if (num->IsSmi()) {
   2555     return i::Smi::cast(*num)->value();
   2556   } else {
   2557     return static_cast<int64_t>(num->Number());
   2558   }
   2559 }
   2560 
   2561 
   2562 Local<Int32> Value::ToInt32() const {
   2563   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2564   i::Handle<i::Object> num;
   2565   if (obj->IsSmi()) {
   2566     num = obj;
   2567   } else {
   2568     i::Isolate* isolate = i::Isolate::Current();
   2569     if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
   2570     LOG_API(isolate, "ToInt32");
   2571     ENTER_V8(isolate);
   2572     EXCEPTION_PREAMBLE(isolate);
   2573     num = i::Execution::ToInt32(obj, &has_pending_exception);
   2574     EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
   2575   }
   2576   return Local<Int32>(ToApi<Int32>(num));
   2577 }
   2578 
   2579 
   2580 Local<Uint32> Value::ToUint32() const {
   2581   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2582   i::Handle<i::Object> num;
   2583   if (obj->IsSmi()) {
   2584     num = obj;
   2585   } else {
   2586     i::Isolate* isolate = i::Isolate::Current();
   2587     if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
   2588     LOG_API(isolate, "ToUInt32");
   2589     ENTER_V8(isolate);
   2590     EXCEPTION_PREAMBLE(isolate);
   2591     num = i::Execution::ToUint32(obj, &has_pending_exception);
   2592     EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
   2593   }
   2594   return Local<Uint32>(ToApi<Uint32>(num));
   2595 }
   2596 
   2597 
   2598 Local<Uint32> Value::ToArrayIndex() const {
   2599   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2600   if (obj->IsSmi()) {
   2601     if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
   2602     return Local<Uint32>();
   2603   }
   2604   i::Isolate* isolate = i::Isolate::Current();
   2605   if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
   2606   LOG_API(isolate, "ToArrayIndex");
   2607   ENTER_V8(isolate);
   2608   EXCEPTION_PREAMBLE(isolate);
   2609   i::Handle<i::Object> string_obj =
   2610       i::Execution::ToString(obj, &has_pending_exception);
   2611   EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
   2612   i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
   2613   uint32_t index;
   2614   if (str->AsArrayIndex(&index)) {
   2615     i::Handle<i::Object> value;
   2616     if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
   2617       value = i::Handle<i::Object>(i::Smi::FromInt(index));
   2618     } else {
   2619       value = isolate->factory()->NewNumber(index);
   2620     }
   2621     return Utils::Uint32ToLocal(value);
   2622   }
   2623   return Local<Uint32>();
   2624 }
   2625 
   2626 
   2627 int32_t Value::Int32Value() const {
   2628   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2629   if (obj->IsSmi()) {
   2630     return i::Smi::cast(*obj)->value();
   2631   } else {
   2632     i::Isolate* isolate = i::Isolate::Current();
   2633     if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
   2634     LOG_API(isolate, "Int32Value (slow)");
   2635     ENTER_V8(isolate);
   2636     EXCEPTION_PREAMBLE(isolate);
   2637     i::Handle<i::Object> num =
   2638         i::Execution::ToInt32(obj, &has_pending_exception);
   2639     EXCEPTION_BAILOUT_CHECK(isolate, 0);
   2640     if (num->IsSmi()) {
   2641       return i::Smi::cast(*num)->value();
   2642     } else {
   2643       return static_cast<int32_t>(num->Number());
   2644     }
   2645   }
   2646 }
   2647 
   2648 
   2649 bool Value::Equals(Handle<Value> that) const {
   2650   i::Isolate* isolate = i::Isolate::Current();
   2651   if (IsDeadCheck(isolate, "v8::Value::Equals()")
   2652       || EmptyCheck("v8::Value::Equals()", this)
   2653       || EmptyCheck("v8::Value::Equals()", that)) {
   2654     return false;
   2655   }
   2656   LOG_API(isolate, "Equals");
   2657   ENTER_V8(isolate);
   2658   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2659   i::Handle<i::Object> other = Utils::OpenHandle(*that);
   2660   // If both obj and other are JSObjects, we'd better compare by identity
   2661   // immediately when going into JS builtin.  The reason is Invoke
   2662   // would overwrite global object receiver with global proxy.
   2663   if (obj->IsJSObject() && other->IsJSObject()) {
   2664     return *obj == *other;
   2665   }
   2666   i::Handle<i::Object> args[] = { other };
   2667   EXCEPTION_PREAMBLE(isolate);
   2668   i::Handle<i::Object> result =
   2669       CallV8HeapFunction("EQUALS", obj, ARRAY_SIZE(args), args,
   2670                          &has_pending_exception);
   2671   EXCEPTION_BAILOUT_CHECK(isolate, false);
   2672   return *result == i::Smi::FromInt(i::EQUAL);
   2673 }
   2674 
   2675 
   2676 bool Value::StrictEquals(Handle<Value> that) const {
   2677   i::Isolate* isolate = i::Isolate::Current();
   2678   if (IsDeadCheck(isolate, "v8::Value::StrictEquals()")
   2679       || EmptyCheck("v8::Value::StrictEquals()", this)
   2680       || EmptyCheck("v8::Value::StrictEquals()", that)) {
   2681     return false;
   2682   }
   2683   LOG_API(isolate, "StrictEquals");
   2684   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2685   i::Handle<i::Object> other = Utils::OpenHandle(*that);
   2686   // Must check HeapNumber first, since NaN !== NaN.
   2687   if (obj->IsHeapNumber()) {
   2688     if (!other->IsNumber()) return false;
   2689     double x = obj->Number();
   2690     double y = other->Number();
   2691     // Must check explicitly for NaN:s on Windows, but -0 works fine.
   2692     return x == y && !isnan(x) && !isnan(y);
   2693   } else if (*obj == *other) {  // Also covers Booleans.
   2694     return true;
   2695   } else if (obj->IsSmi()) {
   2696     return other->IsNumber() && obj->Number() == other->Number();
   2697   } else if (obj->IsString()) {
   2698     return other->IsString() &&
   2699       i::String::cast(*obj)->Equals(i::String::cast(*other));
   2700   } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
   2701     return other->IsUndefined() || other->IsUndetectableObject();
   2702   } else {
   2703     return false;
   2704   }
   2705 }
   2706 
   2707 
   2708 uint32_t Value::Uint32Value() const {
   2709   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   2710   if (obj->IsSmi()) {
   2711     return i::Smi::cast(*obj)->value();
   2712   } else {
   2713     i::Isolate* isolate = i::Isolate::Current();
   2714     if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
   2715     LOG_API(isolate, "Uint32Value");
   2716     ENTER_V8(isolate);
   2717     EXCEPTION_PREAMBLE(isolate);
   2718     i::Handle<i::Object> num =
   2719         i::Execution::ToUint32(obj, &has_pending_exception);
   2720     EXCEPTION_BAILOUT_CHECK(isolate, 0);
   2721     if (num->IsSmi()) {
   2722       return i::Smi::cast(*num)->value();
   2723     } else {
   2724       return static_cast<uint32_t>(num->Number());
   2725     }
   2726   }
   2727 }
   2728 
   2729 
   2730 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
   2731                      v8::PropertyAttribute attribs) {
   2732   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2733   ON_BAILOUT(isolate, "v8::Object::Set()", return false);
   2734   ENTER_V8(isolate);
   2735   i::HandleScope scope(isolate);
   2736   i::Handle<i::Object> self = Utils::OpenHandle(this);
   2737   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   2738   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
   2739   EXCEPTION_PREAMBLE(isolate);
   2740   i::Handle<i::Object> obj = i::SetProperty(
   2741       self,
   2742       key_obj,
   2743       value_obj,
   2744       static_cast<PropertyAttributes>(attribs),
   2745       i::kNonStrictMode);
   2746   has_pending_exception = obj.is_null();
   2747   EXCEPTION_BAILOUT_CHECK(isolate, false);
   2748   return true;
   2749 }
   2750 
   2751 
   2752 bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
   2753   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2754   ON_BAILOUT(isolate, "v8::Object::Set()", return false);
   2755   ENTER_V8(isolate);
   2756   i::HandleScope scope(isolate);
   2757   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2758   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
   2759   EXCEPTION_PREAMBLE(isolate);
   2760   i::Handle<i::Object> obj = i::JSObject::SetElement(
   2761       self,
   2762       index,
   2763       value_obj,
   2764       NONE,
   2765       i::kNonStrictMode);
   2766   has_pending_exception = obj.is_null();
   2767   EXCEPTION_BAILOUT_CHECK(isolate, false);
   2768   return true;
   2769 }
   2770 
   2771 
   2772 bool v8::Object::ForceSet(v8::Handle<Value> key,
   2773                           v8::Handle<Value> value,
   2774                           v8::PropertyAttribute attribs) {
   2775   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2776   ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
   2777   ENTER_V8(isolate);
   2778   i::HandleScope scope(isolate);
   2779   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2780   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   2781   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
   2782   EXCEPTION_PREAMBLE(isolate);
   2783   i::Handle<i::Object> obj = i::ForceSetProperty(
   2784       self,
   2785       key_obj,
   2786       value_obj,
   2787       static_cast<PropertyAttributes>(attribs));
   2788   has_pending_exception = obj.is_null();
   2789   EXCEPTION_BAILOUT_CHECK(isolate, false);
   2790   return true;
   2791 }
   2792 
   2793 
   2794 bool v8::Object::ForceDelete(v8::Handle<Value> key) {
   2795   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2796   ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
   2797   ENTER_V8(isolate);
   2798   i::HandleScope scope(isolate);
   2799   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2800   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   2801 
   2802   // When turning on access checks for a global object deoptimize all functions
   2803   // as optimized code does not always handle access checks.
   2804   i::Deoptimizer::DeoptimizeGlobalObject(*self);
   2805 
   2806   EXCEPTION_PREAMBLE(isolate);
   2807   i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
   2808   has_pending_exception = obj.is_null();
   2809   EXCEPTION_BAILOUT_CHECK(isolate, false);
   2810   return obj->IsTrue();
   2811 }
   2812 
   2813 
   2814 Local<Value> v8::Object::Get(v8::Handle<Value> key) {
   2815   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2816   ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
   2817   ENTER_V8(isolate);
   2818   i::Handle<i::Object> self = Utils::OpenHandle(this);
   2819   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   2820   EXCEPTION_PREAMBLE(isolate);
   2821   i::Handle<i::Object> result = i::GetProperty(self, key_obj);
   2822   has_pending_exception = result.is_null();
   2823   EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   2824   return Utils::ToLocal(result);
   2825 }
   2826 
   2827 
   2828 Local<Value> v8::Object::Get(uint32_t index) {
   2829   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2830   ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
   2831   ENTER_V8(isolate);
   2832   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2833   EXCEPTION_PREAMBLE(isolate);
   2834   i::Handle<i::Object> result = i::Object::GetElement(self, index);
   2835   has_pending_exception = result.is_null();
   2836   EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   2837   return Utils::ToLocal(result);
   2838 }
   2839 
   2840 
   2841 PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
   2842   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2843   ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
   2844              return static_cast<PropertyAttribute>(NONE));
   2845   ENTER_V8(isolate);
   2846   i::HandleScope scope(isolate);
   2847   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2848   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   2849   if (!key_obj->IsString()) {
   2850     EXCEPTION_PREAMBLE(isolate);
   2851     key_obj = i::Execution::ToString(key_obj, &has_pending_exception);
   2852     EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
   2853   }
   2854   i::Handle<i::String> key_string = i::Handle<i::String>::cast(key_obj);
   2855   PropertyAttributes result = self->GetPropertyAttribute(*key_string);
   2856   if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
   2857   return static_cast<PropertyAttribute>(result);
   2858 }
   2859 
   2860 
   2861 Local<Value> v8::Object::GetPrototype() {
   2862   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2863   ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
   2864              return Local<v8::Value>());
   2865   ENTER_V8(isolate);
   2866   i::Handle<i::Object> self = Utils::OpenHandle(this);
   2867   i::Handle<i::Object> result(self->GetPrototype());
   2868   return Utils::ToLocal(result);
   2869 }
   2870 
   2871 
   2872 bool v8::Object::SetPrototype(Handle<Value> value) {
   2873   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2874   ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
   2875   ENTER_V8(isolate);
   2876   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2877   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
   2878   // We do not allow exceptions thrown while setting the prototype
   2879   // to propagate outside.
   2880   TryCatch try_catch;
   2881   EXCEPTION_PREAMBLE(isolate);
   2882   i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
   2883   has_pending_exception = result.is_null();
   2884   EXCEPTION_BAILOUT_CHECK(isolate, false);
   2885   return true;
   2886 }
   2887 
   2888 
   2889 Local<Object> v8::Object::FindInstanceInPrototypeChain(
   2890     v8::Handle<FunctionTemplate> tmpl) {
   2891   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2892   ON_BAILOUT(isolate,
   2893              "v8::Object::FindInstanceInPrototypeChain()",
   2894              return Local<v8::Object>());
   2895   ENTER_V8(isolate);
   2896   i::JSObject* object = *Utils::OpenHandle(this);
   2897   i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
   2898   while (!object->IsInstanceOf(tmpl_info)) {
   2899     i::Object* prototype = object->GetPrototype();
   2900     if (!prototype->IsJSObject()) return Local<Object>();
   2901     object = i::JSObject::cast(prototype);
   2902   }
   2903   return Utils::ToLocal(i::Handle<i::JSObject>(object));
   2904 }
   2905 
   2906 
   2907 Local<Array> v8::Object::GetPropertyNames() {
   2908   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2909   ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
   2910              return Local<v8::Array>());
   2911   ENTER_V8(isolate);
   2912   i::HandleScope scope(isolate);
   2913   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2914   bool threw = false;
   2915   i::Handle<i::FixedArray> value =
   2916       i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS, &threw);
   2917   if (threw) return Local<v8::Array>();
   2918   // Because we use caching to speed up enumeration it is important
   2919   // to never change the result of the basic enumeration function so
   2920   // we clone the result.
   2921   i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
   2922   i::Handle<i::JSArray> result =
   2923       isolate->factory()->NewJSArrayWithElements(elms);
   2924   return Utils::ToLocal(scope.CloseAndEscape(result));
   2925 }
   2926 
   2927 
   2928 Local<Array> v8::Object::GetOwnPropertyNames() {
   2929   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2930   ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
   2931              return Local<v8::Array>());
   2932   ENTER_V8(isolate);
   2933   i::HandleScope scope(isolate);
   2934   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2935   bool threw = false;
   2936   i::Handle<i::FixedArray> value =
   2937       i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY, &threw);
   2938   if (threw) return Local<v8::Array>();
   2939   // Because we use caching to speed up enumeration it is important
   2940   // to never change the result of the basic enumeration function so
   2941   // we clone the result.
   2942   i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
   2943   i::Handle<i::JSArray> result =
   2944       isolate->factory()->NewJSArrayWithElements(elms);
   2945   return Utils::ToLocal(scope.CloseAndEscape(result));
   2946 }
   2947 
   2948 
   2949 Local<String> v8::Object::ObjectProtoToString() {
   2950   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   2951   ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
   2952              return Local<v8::String>());
   2953   ENTER_V8(isolate);
   2954   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   2955 
   2956   i::Handle<i::Object> name(self->class_name());
   2957 
   2958   // Native implementation of Object.prototype.toString (v8natives.js):
   2959   //   var c = %ClassOf(this);
   2960   //   if (c === 'Arguments') c  = 'Object';
   2961   //   return "[object " + c + "]";
   2962 
   2963   if (!name->IsString()) {
   2964     return v8::String::New("[object ]");
   2965 
   2966   } else {
   2967     i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
   2968     if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
   2969       return v8::String::New("[object Object]");
   2970 
   2971     } else {
   2972       const char* prefix = "[object ";
   2973       Local<String> str = Utils::ToLocal(class_name);
   2974       const char* postfix = "]";
   2975 
   2976       int prefix_len = i::StrLength(prefix);
   2977       int str_len = str->Length();
   2978       int postfix_len = i::StrLength(postfix);
   2979 
   2980       int buf_len = prefix_len + str_len + postfix_len;
   2981       i::ScopedVector<char> buf(buf_len);
   2982 
   2983       // Write prefix.
   2984       char* ptr = buf.start();
   2985       memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
   2986       ptr += prefix_len;
   2987 
   2988       // Write real content.
   2989       str->WriteAscii(ptr, 0, str_len);
   2990       ptr += str_len;
   2991 
   2992       // Write postfix.
   2993       memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
   2994 
   2995       // Copy the buffer into a heap-allocated string and return it.
   2996       Local<String> result = v8::String::New(buf.start(), buf_len);
   2997       return result;
   2998     }
   2999   }
   3000 }
   3001 
   3002 
   3003 Local<String> v8::Object::GetConstructorName() {
   3004   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3005   ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
   3006              return Local<v8::String>());
   3007   ENTER_V8(isolate);
   3008   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3009   i::Handle<i::String> name(self->constructor_name());
   3010   return Utils::ToLocal(name);
   3011 }
   3012 
   3013 
   3014 bool v8::Object::Delete(v8::Handle<String> key) {
   3015   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3016   ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
   3017   ENTER_V8(isolate);
   3018   i::HandleScope scope(isolate);
   3019   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3020   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   3021   return i::JSObject::DeleteProperty(self, key_obj)->IsTrue();
   3022 }
   3023 
   3024 
   3025 bool v8::Object::Has(v8::Handle<String> key) {
   3026   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3027   ON_BAILOUT(isolate, "v8::Object::Has()", return false);
   3028   ENTER_V8(isolate);
   3029   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3030   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   3031   return self->HasProperty(*key_obj);
   3032 }
   3033 
   3034 
   3035 bool v8::Object::Delete(uint32_t index) {
   3036   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3037   ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
   3038              return false);
   3039   ENTER_V8(isolate);
   3040   HandleScope scope;
   3041   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3042   return i::JSObject::DeleteElement(self, index)->IsTrue();
   3043 }
   3044 
   3045 
   3046 bool v8::Object::Has(uint32_t index) {
   3047   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3048   ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
   3049   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3050   return self->HasElement(index);
   3051 }
   3052 
   3053 
   3054 bool Object::SetAccessor(Handle<String> name,
   3055                          AccessorGetter getter,
   3056                          AccessorSetter setter,
   3057                          v8::Handle<Value> data,
   3058                          AccessControl settings,
   3059                          PropertyAttribute attributes) {
   3060   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3061   ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
   3062   ENTER_V8(isolate);
   3063   i::HandleScope scope(isolate);
   3064   i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
   3065                                                      getter, setter, data,
   3066                                                      settings, attributes);
   3067   bool fast = Utils::OpenHandle(this)->HasFastProperties();
   3068   i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
   3069   if (result.is_null() || result->IsUndefined()) return false;
   3070   if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(this), 0);
   3071   return true;
   3072 }
   3073 
   3074 
   3075 bool v8::Object::HasOwnProperty(Handle<String> key) {
   3076   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3077   ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
   3078              return false);
   3079   return Utils::OpenHandle(this)->HasLocalProperty(
   3080       *Utils::OpenHandle(*key));
   3081 }
   3082 
   3083 
   3084 bool v8::Object::HasRealNamedProperty(Handle<String> key) {
   3085   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3086   ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
   3087              return false);
   3088   return Utils::OpenHandle(this)->HasRealNamedProperty(
   3089       *Utils::OpenHandle(*key));
   3090 }
   3091 
   3092 
   3093 bool v8::Object::HasRealIndexedProperty(uint32_t index) {
   3094   ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
   3095              "v8::Object::HasRealIndexedProperty()",
   3096              return false);
   3097   return Utils::OpenHandle(this)->HasRealElementProperty(index);
   3098 }
   3099 
   3100 
   3101 bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
   3102   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3103   ON_BAILOUT(isolate,
   3104              "v8::Object::HasRealNamedCallbackProperty()",
   3105              return false);
   3106   ENTER_V8(isolate);
   3107   return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
   3108       *Utils::OpenHandle(*key));
   3109 }
   3110 
   3111 
   3112 bool v8::Object::HasNamedLookupInterceptor() {
   3113   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3114   ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
   3115              return false);
   3116   return Utils::OpenHandle(this)->HasNamedInterceptor();
   3117 }
   3118 
   3119 
   3120 bool v8::Object::HasIndexedLookupInterceptor() {
   3121   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3122   ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
   3123              return false);
   3124   return Utils::OpenHandle(this)->HasIndexedInterceptor();
   3125 }
   3126 
   3127 
   3128 static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
   3129                                         i::Handle<i::JSObject> receiver,
   3130                                         i::Handle<i::String> name,
   3131                                         i::LookupResult* lookup) {
   3132   if (!lookup->IsProperty()) {
   3133     // No real property was found.
   3134     return Local<Value>();
   3135   }
   3136 
   3137   // If the property being looked up is a callback, it can throw
   3138   // an exception.
   3139   EXCEPTION_PREAMBLE(isolate);
   3140   PropertyAttributes ignored;
   3141   i::Handle<i::Object> result =
   3142       i::Object::GetProperty(receiver, receiver, lookup, name,
   3143                              &ignored);
   3144   has_pending_exception = result.is_null();
   3145   EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   3146 
   3147   return Utils::ToLocal(result);
   3148 }
   3149 
   3150 
   3151 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
   3152       Handle<String> key) {
   3153   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3154   ON_BAILOUT(isolate,
   3155              "v8::Object::GetRealNamedPropertyInPrototypeChain()",
   3156              return Local<Value>());
   3157   ENTER_V8(isolate);
   3158   i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
   3159   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   3160   i::LookupResult lookup(isolate);
   3161   self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
   3162   return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
   3163 }
   3164 
   3165 
   3166 Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
   3167   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3168   ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
   3169              return Local<Value>());
   3170   ENTER_V8(isolate);
   3171   i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
   3172   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   3173   i::LookupResult lookup(isolate);
   3174   self_obj->LookupRealNamedProperty(*key_obj, &lookup);
   3175   return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
   3176 }
   3177 
   3178 
   3179 // Turns on access checks by copying the map and setting the check flag.
   3180 // Because the object gets a new map, existing inline cache caching
   3181 // the old map of this object will fail.
   3182 void v8::Object::TurnOnAccessCheck() {
   3183   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3184   ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
   3185   ENTER_V8(isolate);
   3186   i::HandleScope scope(isolate);
   3187   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   3188 
   3189   // When turning on access checks for a global object deoptimize all functions
   3190   // as optimized code does not always handle access checks.
   3191   i::Deoptimizer::DeoptimizeGlobalObject(*obj);
   3192 
   3193   i::Handle<i::Map> new_map =
   3194       isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
   3195   new_map->set_is_access_check_needed(true);
   3196   obj->set_map(*new_map);
   3197 }
   3198 
   3199 
   3200 bool v8::Object::IsDirty() {
   3201   return Utils::OpenHandle(this)->IsDirty();
   3202 }
   3203 
   3204 
   3205 Local<v8::Object> v8::Object::Clone() {
   3206   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3207   ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
   3208   ENTER_V8(isolate);
   3209   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3210   EXCEPTION_PREAMBLE(isolate);
   3211   i::Handle<i::JSObject> result = i::Copy(self);
   3212   has_pending_exception = result.is_null();
   3213   EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
   3214   return Utils::ToLocal(result);
   3215 }
   3216 
   3217 
   3218 static i::Context* GetCreationContext(i::JSObject* object) {
   3219   i::Object* constructor = object->map()->constructor();
   3220   i::JSFunction* function;
   3221   if (!constructor->IsJSFunction()) {
   3222     // Functions have null as a constructor,
   3223     // but any JSFunction knows its context immediately.
   3224     ASSERT(object->IsJSFunction());
   3225     function = i::JSFunction::cast(object);
   3226   } else {
   3227     function = i::JSFunction::cast(constructor);
   3228   }
   3229   return function->context()->global_context();
   3230 }
   3231 
   3232 
   3233 Local<v8::Context> v8::Object::CreationContext() {
   3234   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3235   ON_BAILOUT(isolate,
   3236              "v8::Object::CreationContext()", return Local<v8::Context>());
   3237   ENTER_V8(isolate);
   3238   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3239   i::Context* context = GetCreationContext(*self);
   3240   return Utils::ToLocal(i::Handle<i::Context>(context));
   3241 }
   3242 
   3243 
   3244 int v8::Object::GetIdentityHash() {
   3245   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3246   ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
   3247   ENTER_V8(isolate);
   3248   i::HandleScope scope(isolate);
   3249   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3250   return i::JSObject::GetIdentityHash(self);
   3251 }
   3252 
   3253 
   3254 bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
   3255                                 v8::Handle<v8::Value> value) {
   3256   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3257   ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
   3258   ENTER_V8(isolate);
   3259   i::HandleScope scope(isolate);
   3260   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3261   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   3262   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
   3263   i::Handle<i::Object> result =
   3264       i::JSObject::SetHiddenProperty(self, key_obj, value_obj);
   3265   return *result == *self;
   3266 }
   3267 
   3268 
   3269 v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
   3270   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3271   ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
   3272              return Local<v8::Value>());
   3273   ENTER_V8(isolate);
   3274   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3275   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   3276   i::Handle<i::Object> result(self->GetHiddenProperty(*key_obj));
   3277   if (result->IsUndefined()) return v8::Local<v8::Value>();
   3278   return Utils::ToLocal(result);
   3279 }
   3280 
   3281 
   3282 bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
   3283   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3284   ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
   3285   ENTER_V8(isolate);
   3286   i::HandleScope scope(isolate);
   3287   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3288   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   3289   self->DeleteHiddenProperty(*key_obj);
   3290   return true;
   3291 }
   3292 
   3293 
   3294 namespace {
   3295 
   3296 static i::ElementsKind GetElementsKindFromExternalArrayType(
   3297     ExternalArrayType array_type) {
   3298   switch (array_type) {
   3299     case kExternalByteArray:
   3300       return i::EXTERNAL_BYTE_ELEMENTS;
   3301       break;
   3302     case kExternalUnsignedByteArray:
   3303       return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
   3304       break;
   3305     case kExternalShortArray:
   3306       return i::EXTERNAL_SHORT_ELEMENTS;
   3307       break;
   3308     case kExternalUnsignedShortArray:
   3309       return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
   3310       break;
   3311     case kExternalIntArray:
   3312       return i::EXTERNAL_INT_ELEMENTS;
   3313       break;
   3314     case kExternalUnsignedIntArray:
   3315       return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
   3316       break;
   3317     case kExternalFloatArray:
   3318       return i::EXTERNAL_FLOAT_ELEMENTS;
   3319       break;
   3320     case kExternalDoubleArray:
   3321       return i::EXTERNAL_DOUBLE_ELEMENTS;
   3322       break;
   3323     case kExternalPixelArray:
   3324       return i::EXTERNAL_PIXEL_ELEMENTS;
   3325       break;
   3326   }
   3327   UNREACHABLE();
   3328   return i::DICTIONARY_ELEMENTS;
   3329 }
   3330 
   3331 
   3332 void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
   3333                                   void* data,
   3334                                   ExternalArrayType array_type,
   3335                                   int length) {
   3336   i::Isolate* isolate = object->GetIsolate();
   3337   i::Handle<i::ExternalArray> array =
   3338       isolate->factory()->NewExternalArray(length, array_type, data);
   3339 
   3340   i::Handle<i::Map> external_array_map =
   3341       isolate->factory()->GetElementsTransitionMap(
   3342           object,
   3343           GetElementsKindFromExternalArrayType(array_type));
   3344 
   3345   object->set_map(*external_array_map);
   3346   object->set_elements(*array);
   3347 }
   3348 
   3349 }  // namespace
   3350 
   3351 
   3352 void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
   3353   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3354   ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
   3355   ENTER_V8(isolate);
   3356   i::HandleScope scope(isolate);
   3357   if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
   3358                 "v8::Object::SetIndexedPropertiesToPixelData()",
   3359                 "length exceeds max acceptable value")) {
   3360     return;
   3361   }
   3362   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3363   if (!ApiCheck(!self->IsJSArray(),
   3364                 "v8::Object::SetIndexedPropertiesToPixelData()",
   3365                 "JSArray is not supported")) {
   3366     return;
   3367   }
   3368   PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
   3369 }
   3370 
   3371 
   3372 bool v8::Object::HasIndexedPropertiesInPixelData() {
   3373   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3374   ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
   3375              return false);
   3376   return self->HasExternalPixelElements();
   3377 }
   3378 
   3379 
   3380 uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
   3381   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3382   ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
   3383              return NULL);
   3384   if (self->HasExternalPixelElements()) {
   3385     return i::ExternalPixelArray::cast(self->elements())->
   3386         external_pixel_pointer();
   3387   } else {
   3388     return NULL;
   3389   }
   3390 }
   3391 
   3392 
   3393 int v8::Object::GetIndexedPropertiesPixelDataLength() {
   3394   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3395   ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
   3396              return -1);
   3397   if (self->HasExternalPixelElements()) {
   3398     return i::ExternalPixelArray::cast(self->elements())->length();
   3399   } else {
   3400     return -1;
   3401   }
   3402 }
   3403 
   3404 
   3405 void v8::Object::SetIndexedPropertiesToExternalArrayData(
   3406     void* data,
   3407     ExternalArrayType array_type,
   3408     int length) {
   3409   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3410   ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
   3411   ENTER_V8(isolate);
   3412   i::HandleScope scope(isolate);
   3413   if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
   3414                 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
   3415                 "length exceeds max acceptable value")) {
   3416     return;
   3417   }
   3418   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3419   if (!ApiCheck(!self->IsJSArray(),
   3420                 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
   3421                 "JSArray is not supported")) {
   3422     return;
   3423   }
   3424   PrepareExternalArrayElements(self, data, array_type, length);
   3425 }
   3426 
   3427 
   3428 bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
   3429   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3430   ON_BAILOUT(self->GetIsolate(),
   3431              "v8::HasIndexedPropertiesInExternalArrayData()",
   3432              return false);
   3433   return self->HasExternalArrayElements();
   3434 }
   3435 
   3436 
   3437 void* v8::Object::GetIndexedPropertiesExternalArrayData() {
   3438   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3439   ON_BAILOUT(self->GetIsolate(),
   3440              "v8::GetIndexedPropertiesExternalArrayData()",
   3441              return NULL);
   3442   if (self->HasExternalArrayElements()) {
   3443     return i::ExternalArray::cast(self->elements())->external_pointer();
   3444   } else {
   3445     return NULL;
   3446   }
   3447 }
   3448 
   3449 
   3450 ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
   3451   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3452   ON_BAILOUT(self->GetIsolate(),
   3453              "v8::GetIndexedPropertiesExternalArrayDataType()",
   3454              return static_cast<ExternalArrayType>(-1));
   3455   switch (self->elements()->map()->instance_type()) {
   3456     case i::EXTERNAL_BYTE_ARRAY_TYPE:
   3457       return kExternalByteArray;
   3458     case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
   3459       return kExternalUnsignedByteArray;
   3460     case i::EXTERNAL_SHORT_ARRAY_TYPE:
   3461       return kExternalShortArray;
   3462     case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
   3463       return kExternalUnsignedShortArray;
   3464     case i::EXTERNAL_INT_ARRAY_TYPE:
   3465       return kExternalIntArray;
   3466     case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
   3467       return kExternalUnsignedIntArray;
   3468     case i::EXTERNAL_FLOAT_ARRAY_TYPE:
   3469       return kExternalFloatArray;
   3470     case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
   3471       return kExternalDoubleArray;
   3472     case i::EXTERNAL_PIXEL_ARRAY_TYPE:
   3473       return kExternalPixelArray;
   3474     default:
   3475       return static_cast<ExternalArrayType>(-1);
   3476   }
   3477 }
   3478 
   3479 
   3480 int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
   3481   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   3482   ON_BAILOUT(self->GetIsolate(),
   3483              "v8::GetIndexedPropertiesExternalArrayDataLength()",
   3484              return 0);
   3485   if (self->HasExternalArrayElements()) {
   3486     return i::ExternalArray::cast(self->elements())->length();
   3487   } else {
   3488     return -1;
   3489   }
   3490 }
   3491 
   3492 
   3493 bool v8::Object::IsCallable() {
   3494   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3495   ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
   3496   ENTER_V8(isolate);
   3497   i::HandleScope scope(isolate);
   3498   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   3499   if (obj->IsJSFunction()) return true;
   3500   return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
   3501 }
   3502 
   3503 
   3504 Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv,
   3505                                         int argc,
   3506                                         v8::Handle<v8::Value> argv[]) {
   3507   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3508   ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
   3509              return Local<v8::Value>());
   3510   LOG_API(isolate, "Object::CallAsFunction");
   3511   ENTER_V8(isolate);
   3512   i::HandleScope scope(isolate);
   3513   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   3514   i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
   3515   STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
   3516   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
   3517   i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
   3518   if (obj->IsJSFunction()) {
   3519     fun = i::Handle<i::JSFunction>::cast(obj);
   3520   } else {
   3521     EXCEPTION_PREAMBLE(isolate);
   3522     i::Handle<i::Object> delegate =
   3523         i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
   3524     EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   3525     fun = i::Handle<i::JSFunction>::cast(delegate);
   3526     recv_obj = obj;
   3527   }
   3528   EXCEPTION_PREAMBLE(isolate);
   3529   i::Handle<i::Object> returned =
   3530       i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
   3531   EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
   3532   return Utils::ToLocal(scope.CloseAndEscape(returned));
   3533 }
   3534 
   3535 
   3536 Local<v8::Value> Object::CallAsConstructor(int argc,
   3537                                            v8::Handle<v8::Value> argv[]) {
   3538   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3539   ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
   3540              return Local<v8::Object>());
   3541   LOG_API(isolate, "Object::CallAsConstructor");
   3542   ENTER_V8(isolate);
   3543   i::HandleScope scope(isolate);
   3544   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   3545   STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
   3546   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
   3547   if (obj->IsJSFunction()) {
   3548     i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
   3549     EXCEPTION_PREAMBLE(isolate);
   3550     i::Handle<i::Object> returned =
   3551         i::Execution::New(fun, argc, args, &has_pending_exception);
   3552     EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
   3553     return Utils::ToLocal(scope.CloseAndEscape(
   3554         i::Handle<i::JSObject>::cast(returned)));
   3555   }
   3556   EXCEPTION_PREAMBLE(isolate);
   3557   i::Handle<i::Object> delegate =
   3558       i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
   3559   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
   3560   if (!delegate->IsUndefined()) {
   3561     i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
   3562     EXCEPTION_PREAMBLE(isolate);
   3563     i::Handle<i::Object> returned =
   3564         i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
   3565     EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
   3566     ASSERT(!delegate->IsUndefined());
   3567     return Utils::ToLocal(scope.CloseAndEscape(returned));
   3568   }
   3569   return Local<v8::Object>();
   3570 }
   3571 
   3572 
   3573 Local<v8::Object> Function::NewInstance() const {
   3574   return NewInstance(0, NULL);
   3575 }
   3576 
   3577 
   3578 Local<v8::Object> Function::NewInstance(int argc,
   3579                                         v8::Handle<v8::Value> argv[]) const {
   3580   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3581   ON_BAILOUT(isolate, "v8::Function::NewInstance()",
   3582              return Local<v8::Object>());
   3583   LOG_API(isolate, "Function::NewInstance");
   3584   ENTER_V8(isolate);
   3585   HandleScope scope;
   3586   i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
   3587   STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
   3588   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
   3589   EXCEPTION_PREAMBLE(isolate);
   3590   i::Handle<i::Object> returned =
   3591       i::Execution::New(function, argc, args, &has_pending_exception);
   3592   EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
   3593   return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
   3594 }
   3595 
   3596 
   3597 Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
   3598                                 v8::Handle<v8::Value> argv[]) {
   3599   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3600   ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
   3601   LOG_API(isolate, "Function::Call");
   3602   ENTER_V8(isolate);
   3603   i::Object* raw_result = NULL;
   3604   {
   3605     i::HandleScope scope(isolate);
   3606     i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
   3607     i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
   3608     STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
   3609     i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
   3610     EXCEPTION_PREAMBLE(isolate);
   3611     i::Handle<i::Object> returned =
   3612         i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
   3613     EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
   3614     raw_result = *returned;
   3615   }
   3616   i::Handle<i::Object> result(raw_result);
   3617   return Utils::ToLocal(result);
   3618 }
   3619 
   3620 
   3621 void Function::SetName(v8::Handle<v8::String> name) {
   3622   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3623   ENTER_V8(isolate);
   3624   USE(isolate);
   3625   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   3626   func->shared()->set_name(*Utils::OpenHandle(*name));
   3627 }
   3628 
   3629 
   3630 Handle<Value> Function::GetName() const {
   3631   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   3632   return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
   3633 }
   3634 
   3635 
   3636 Handle<Value> Function::GetInferredName() const {
   3637   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   3638   return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name()));
   3639 }
   3640 
   3641 
   3642 ScriptOrigin Function::GetScriptOrigin() const {
   3643   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   3644   if (func->shared()->script()->IsScript()) {
   3645     i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
   3646     v8::ScriptOrigin origin(
   3647       Utils::ToLocal(i::Handle<i::Object>(script->name())),
   3648       v8::Integer::New(script->line_offset()->value()),
   3649       v8::Integer::New(script->column_offset()->value()));
   3650     return origin;
   3651   }
   3652   return v8::ScriptOrigin(Handle<Value>());
   3653 }
   3654 
   3655 
   3656 const int Function::kLineOffsetNotFound = -1;
   3657 
   3658 
   3659 int Function::GetScriptLineNumber() const {
   3660   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   3661   if (func->shared()->script()->IsScript()) {
   3662     i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
   3663     return i::GetScriptLineNumber(script, func->shared()->start_position());
   3664   }
   3665   return kLineOffsetNotFound;
   3666 }
   3667 
   3668 
   3669 int Function::GetScriptColumnNumber() const {
   3670   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   3671   if (func->shared()->script()->IsScript()) {
   3672     i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
   3673     return i::GetScriptColumnNumber(script, func->shared()->start_position());
   3674   }
   3675   return kLineOffsetNotFound;
   3676 }
   3677 
   3678 Handle<Value> Function::GetScriptId() const {
   3679   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   3680   if (!func->shared()->script()->IsScript())
   3681     return v8::Undefined();
   3682   i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
   3683   return Utils::ToLocal(i::Handle<i::Object>(script->id()));
   3684 }
   3685 
   3686 int String::Length() const {
   3687   i::Handle<i::String> str = Utils::OpenHandle(this);
   3688   if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
   3689   return str->length();
   3690 }
   3691 
   3692 
   3693 int String::Utf8Length() const {
   3694   i::Handle<i::String> str = Utils::OpenHandle(this);
   3695   if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
   3696   return i::Utf8Length(str);
   3697 }
   3698 
   3699 
   3700 // Will fail with a negative answer if the recursion depth is too high.
   3701 static int RecursivelySerializeToUtf8(i::String* string,
   3702                                       char* buffer,
   3703                                       int start,
   3704                                       int end,
   3705                                       int recursion_budget,
   3706                                       int32_t previous_character,
   3707                                       int32_t* last_character) {
   3708   int utf8_bytes = 0;
   3709   while (true) {
   3710     if (string->IsAsciiRepresentation()) {
   3711       i::String::WriteToFlat(string, buffer, start, end);
   3712       *last_character = unibrow::Utf16::kNoPreviousCharacter;
   3713       return utf8_bytes + end - start;
   3714     }
   3715     switch (i::StringShape(string).representation_tag()) {
   3716       case i::kExternalStringTag: {
   3717         const uint16_t* data = i::ExternalTwoByteString::cast(string)->
   3718           ExternalTwoByteStringGetData(0);
   3719         char* current = buffer;
   3720         for (int i = start; i < end; i++) {
   3721           uint16_t character = data[i];
   3722           current +=
   3723               unibrow::Utf8::Encode(current, character, previous_character);
   3724           previous_character = character;
   3725         }
   3726         *last_character = previous_character;
   3727         return static_cast<int>(utf8_bytes + current - buffer);
   3728       }
   3729       case i::kSeqStringTag: {
   3730         const uint16_t* data =
   3731             i::SeqTwoByteString::cast(string)->SeqTwoByteStringGetData(0);
   3732         char* current = buffer;
   3733         for (int i = start; i < end; i++) {
   3734           uint16_t character = data[i];
   3735           current +=
   3736               unibrow::Utf8::Encode(current, character, previous_character);
   3737           previous_character = character;
   3738         }
   3739         *last_character = previous_character;
   3740         return static_cast<int>(utf8_bytes + current - buffer);
   3741       }
   3742       case i::kSlicedStringTag: {
   3743         i::SlicedString* slice = i::SlicedString::cast(string);
   3744         unsigned offset = slice->offset();
   3745         string = slice->parent();
   3746         start += offset;
   3747         end += offset;
   3748         continue;
   3749       }
   3750       case i::kConsStringTag: {
   3751         i::ConsString* cons_string = i::ConsString::cast(string);
   3752         i::String* first = cons_string->first();
   3753         int boundary = first->length();
   3754         if (start >= boundary) {
   3755           // Only need RHS.
   3756           string = cons_string->second();
   3757           start -= boundary;
   3758           end -= boundary;
   3759           continue;
   3760         } else if (end <= boundary) {
   3761           // Only need LHS.
   3762           string = first;
   3763         } else {
   3764           if (recursion_budget == 0) return -1;
   3765           int extra_utf8_bytes =
   3766               RecursivelySerializeToUtf8(first,
   3767                                          buffer,
   3768                                          start,
   3769                                          boundary,
   3770                                          recursion_budget - 1,
   3771                                          previous_character,
   3772                                          &previous_character);
   3773           if (extra_utf8_bytes < 0) return extra_utf8_bytes;
   3774           buffer += extra_utf8_bytes;
   3775           utf8_bytes += extra_utf8_bytes;
   3776           string = cons_string->second();
   3777           start = 0;
   3778           end -= boundary;
   3779         }
   3780       }
   3781     }
   3782   }
   3783   UNREACHABLE();
   3784   return 0;
   3785 }
   3786 
   3787 
   3788 bool String::MayContainNonAscii() const {
   3789   i::Handle<i::String> str = Utils::OpenHandle(this);
   3790   if (IsDeadCheck(str->GetIsolate(), "v8::String::MayContainNonAscii()")) {
   3791     return false;
   3792   }
   3793   return !str->HasOnlyAsciiChars();
   3794 }
   3795 
   3796 
   3797 int String::WriteUtf8(char* buffer,
   3798                       int capacity,
   3799                       int* nchars_ref,
   3800                       int options) const {
   3801   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3802   if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
   3803   LOG_API(isolate, "String::WriteUtf8");
   3804   ENTER_V8(isolate);
   3805   i::Handle<i::String> str = Utils::OpenHandle(this);
   3806   int string_length = str->length();
   3807   if (str->IsAsciiRepresentation()) {
   3808     int len;
   3809     if (capacity == -1) {
   3810       capacity = str->length() + 1;
   3811       len = string_length;
   3812     } else {
   3813       len = i::Min(capacity, str->length());
   3814     }
   3815     i::String::WriteToFlat(*str, buffer, 0, len);
   3816     if (nchars_ref != NULL) *nchars_ref = len;
   3817     if (!(options & NO_NULL_TERMINATION) && capacity > len) {
   3818       buffer[len] = '\0';
   3819       return len + 1;
   3820     }
   3821     return len;
   3822   }
   3823 
   3824   if (capacity == -1 || capacity / 3 >= string_length) {
   3825     int32_t previous = unibrow::Utf16::kNoPreviousCharacter;
   3826     const int kMaxRecursion = 100;
   3827     int utf8_bytes =
   3828         RecursivelySerializeToUtf8(*str,
   3829                                    buffer,
   3830                                    0,
   3831                                    string_length,
   3832                                    kMaxRecursion,
   3833                                    previous,
   3834                                    &previous);
   3835     if (utf8_bytes >= 0) {
   3836       // Success serializing with recursion.
   3837       if ((options & NO_NULL_TERMINATION) == 0 &&
   3838           (capacity > utf8_bytes || capacity == -1)) {
   3839         buffer[utf8_bytes++] = '\0';
   3840       }
   3841       if (nchars_ref != NULL) *nchars_ref = string_length;
   3842       return utf8_bytes;
   3843     }
   3844     FlattenString(str);
   3845     // Recurse once.  This time around the string is flat and the serializing
   3846     // with recursion will certainly succeed.
   3847     return WriteUtf8(buffer, capacity, nchars_ref, options);
   3848   } else if (capacity >= string_length) {
   3849     // First check that the buffer is large enough.  If it is, then recurse
   3850     // once without a capacity limit, which will get into the other branch of
   3851     // this 'if'.
   3852     int utf8_bytes = i::Utf8Length(str);
   3853     if ((options & NO_NULL_TERMINATION) == 0) utf8_bytes++;
   3854     if (utf8_bytes <= capacity) {
   3855       return WriteUtf8(buffer, -1, nchars_ref, options);
   3856     }
   3857   }
   3858 
   3859   // Slow case.
   3860   i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
   3861   isolate->string_tracker()->RecordWrite(str);
   3862   if (options & HINT_MANY_WRITES_EXPECTED) {
   3863     // Flatten the string for efficiency.  This applies whether we are
   3864     // using StringInputBuffer or Get(i) to access the characters.
   3865     FlattenString(str);
   3866   }
   3867   write_input_buffer.Reset(0, *str);
   3868   int len = str->length();
   3869   // Encode the first K - 3 bytes directly into the buffer since we
   3870   // know there's room for them.  If no capacity is given we copy all
   3871   // of them here.
   3872   int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
   3873   int i;
   3874   int pos = 0;
   3875   int nchars = 0;
   3876   int previous = unibrow::Utf16::kNoPreviousCharacter;
   3877   for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
   3878     i::uc32 c = write_input_buffer.GetNext();
   3879     int written = unibrow::Utf8::Encode(buffer + pos, c, previous);
   3880     pos += written;
   3881     nchars++;
   3882     previous = c;
   3883   }
   3884   if (i < len) {
   3885     // For the last characters we need to check the length for each one
   3886     // because they may be longer than the remaining space in the
   3887     // buffer.
   3888     char intermediate[unibrow::Utf8::kMaxEncodedSize];
   3889     for (; i < len && pos < capacity; i++) {
   3890       i::uc32 c = write_input_buffer.GetNext();
   3891       if (unibrow::Utf16::IsTrailSurrogate(c) &&
   3892           unibrow::Utf16::IsLeadSurrogate(previous)) {
   3893         // We can't use the intermediate buffer here because the encoding
   3894         // of surrogate pairs is done under assumption that you can step
   3895         // back and fix the UTF8 stream.  Luckily we only need space for one
   3896         // more byte, so there is always space.
   3897         ASSERT(pos < capacity);
   3898         int written = unibrow::Utf8::Encode(buffer + pos, c, previous);
   3899         ASSERT(written == 1);
   3900         pos += written;
   3901         nchars++;
   3902       } else {
   3903         int written =
   3904             unibrow::Utf8::Encode(intermediate,
   3905                                   c,
   3906                                   unibrow::Utf16::kNoPreviousCharacter);
   3907         if (pos + written <= capacity) {
   3908           for (int j = 0; j < written; j++)
   3909             buffer[pos + j] = intermediate[j];
   3910           pos += written;
   3911           nchars++;
   3912         } else {
   3913           // We've reached the end of the buffer
   3914           break;
   3915         }
   3916       }
   3917       previous = c;
   3918     }
   3919   }
   3920   if (nchars_ref != NULL) *nchars_ref = nchars;
   3921   if (!(options & NO_NULL_TERMINATION) &&
   3922       (i == len && (capacity == -1 || pos < capacity)))
   3923     buffer[pos++] = '\0';
   3924   return pos;
   3925 }
   3926 
   3927 
   3928 int String::WriteAscii(char* buffer,
   3929                        int start,
   3930                        int length,
   3931                        int options) const {
   3932   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3933   if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
   3934   LOG_API(isolate, "String::WriteAscii");
   3935   ENTER_V8(isolate);
   3936   i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
   3937   ASSERT(start >= 0 && length >= -1);
   3938   i::Handle<i::String> str = Utils::OpenHandle(this);
   3939   isolate->string_tracker()->RecordWrite(str);
   3940   if (options & HINT_MANY_WRITES_EXPECTED) {
   3941     // Flatten the string for efficiency.  This applies whether we are
   3942     // using StringInputBuffer or Get(i) to access the characters.
   3943     str->TryFlatten();
   3944   }
   3945   int end = length;
   3946   if ( (length == -1) || (length > str->length() - start) )
   3947     end = str->length() - start;
   3948   if (end < 0) return 0;
   3949   write_input_buffer.Reset(start, *str);
   3950   int i;
   3951   for (i = 0; i < end; i++) {
   3952     char c = static_cast<char>(write_input_buffer.GetNext());
   3953     if (c == '\0') c = ' ';
   3954     buffer[i] = c;
   3955   }
   3956   if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length))
   3957     buffer[i] = '\0';
   3958   return i;
   3959 }
   3960 
   3961 
   3962 int String::Write(uint16_t* buffer,
   3963                   int start,
   3964                   int length,
   3965                   int options) const {
   3966   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   3967   if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
   3968   LOG_API(isolate, "String::Write");
   3969   ENTER_V8(isolate);
   3970   ASSERT(start >= 0 && length >= -1);
   3971   i::Handle<i::String> str = Utils::OpenHandle(this);
   3972   isolate->string_tracker()->RecordWrite(str);
   3973   if (options & HINT_MANY_WRITES_EXPECTED) {
   3974     // Flatten the string for efficiency.  This applies whether we are
   3975     // using StringInputBuffer or Get(i) to access the characters.
   3976     str->TryFlatten();
   3977   }
   3978   int end = start + length;
   3979   if ((length == -1) || (length > str->length() - start) )
   3980     end = str->length();
   3981   if (end < 0) return 0;
   3982   i::String::WriteToFlat(*str, buffer, start, end);
   3983   if (!(options & NO_NULL_TERMINATION) &&
   3984       (length == -1 || end - start < length)) {
   3985     buffer[end - start] = '\0';
   3986   }
   3987   return end - start;
   3988 }
   3989 
   3990 
   3991 bool v8::String::IsExternal() const {
   3992   i::Handle<i::String> str = Utils::OpenHandle(this);
   3993   if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
   3994     return false;
   3995   }
   3996   EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
   3997   return i::StringShape(*str).IsExternalTwoByte();
   3998 }
   3999 
   4000 
   4001 bool v8::String::IsExternalAscii() const {
   4002   i::Handle<i::String> str = Utils::OpenHandle(this);
   4003   if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
   4004     return false;
   4005   }
   4006   return i::StringShape(*str).IsExternalAscii();
   4007 }
   4008 
   4009 
   4010 void v8::String::VerifyExternalStringResource(
   4011     v8::String::ExternalStringResource* value) const {
   4012   i::Handle<i::String> str = Utils::OpenHandle(this);
   4013   const v8::String::ExternalStringResource* expected;
   4014   if (i::StringShape(*str).IsExternalTwoByte()) {
   4015     const void* resource =
   4016         i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
   4017     expected = reinterpret_cast<const ExternalStringResource*>(resource);
   4018   } else {
   4019     expected = NULL;
   4020   }
   4021   CHECK_EQ(expected, value);
   4022 }
   4023 
   4024 
   4025 const v8::String::ExternalAsciiStringResource*
   4026       v8::String::GetExternalAsciiStringResource() const {
   4027   i::Handle<i::String> str = Utils::OpenHandle(this);
   4028   if (IsDeadCheck(str->GetIsolate(),
   4029                   "v8::String::GetExternalAsciiStringResource()")) {
   4030     return NULL;
   4031   }
   4032   if (i::StringShape(*str).IsExternalAscii()) {
   4033     const void* resource =
   4034         i::Handle<i::ExternalAsciiString>::cast(str)->resource();
   4035     return reinterpret_cast<const ExternalAsciiStringResource*>(resource);
   4036   } else {
   4037     return NULL;
   4038   }
   4039 }
   4040 
   4041 
   4042 double Number::Value() const {
   4043   if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
   4044   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4045   return obj->Number();
   4046 }
   4047 
   4048 
   4049 bool Boolean::Value() const {
   4050   if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
   4051   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4052   return obj->IsTrue();
   4053 }
   4054 
   4055 
   4056 int64_t Integer::Value() const {
   4057   if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
   4058   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4059   if (obj->IsSmi()) {
   4060     return i::Smi::cast(*obj)->value();
   4061   } else {
   4062     return static_cast<int64_t>(obj->Number());
   4063   }
   4064 }
   4065 
   4066 
   4067 int32_t Int32::Value() const {
   4068   if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
   4069   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4070   if (obj->IsSmi()) {
   4071     return i::Smi::cast(*obj)->value();
   4072   } else {
   4073     return static_cast<int32_t>(obj->Number());
   4074   }
   4075 }
   4076 
   4077 
   4078 uint32_t Uint32::Value() const {
   4079   if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
   4080   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4081   if (obj->IsSmi()) {
   4082     return i::Smi::cast(*obj)->value();
   4083   } else {
   4084     return static_cast<uint32_t>(obj->Number());
   4085   }
   4086 }
   4087 
   4088 
   4089 int v8::Object::InternalFieldCount() {
   4090   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   4091   if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
   4092     return 0;
   4093   }
   4094   return obj->GetInternalFieldCount();
   4095 }
   4096 
   4097 
   4098 Local<Value> v8::Object::CheckedGetInternalField(int index) {
   4099   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   4100   if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
   4101     return Local<Value>();
   4102   }
   4103   if (!ApiCheck(index < obj->GetInternalFieldCount(),
   4104                 "v8::Object::GetInternalField()",
   4105                 "Reading internal field out of bounds")) {
   4106     return Local<Value>();
   4107   }
   4108   i::Handle<i::Object> value(obj->GetInternalField(index));
   4109   Local<Value> result = Utils::ToLocal(value);
   4110 #ifdef DEBUG
   4111   Local<Value> unchecked = UncheckedGetInternalField(index);
   4112   ASSERT(unchecked.IsEmpty() || (unchecked == result));
   4113 #endif
   4114   return result;
   4115 }
   4116 
   4117 
   4118 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
   4119   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   4120   i::Isolate* isolate = obj->GetIsolate();
   4121   if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
   4122     return;
   4123   }
   4124   if (!ApiCheck(index < obj->GetInternalFieldCount(),
   4125                 "v8::Object::SetInternalField()",
   4126                 "Writing internal field out of bounds")) {
   4127     return;
   4128   }
   4129   ENTER_V8(isolate);
   4130   i::Handle<i::Object> val = Utils::OpenHandle(*value);
   4131   obj->SetInternalField(index, *val);
   4132 }
   4133 
   4134 
   4135 static bool CanBeEncodedAsSmi(void* ptr) {
   4136   const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
   4137   return ((address & i::kEncodablePointerMask) == 0);
   4138 }
   4139 
   4140 
   4141 static i::Smi* EncodeAsSmi(void* ptr) {
   4142   ASSERT(CanBeEncodedAsSmi(ptr));
   4143   const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
   4144   i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
   4145   ASSERT(i::Internals::HasSmiTag(result));
   4146   ASSERT_EQ(result, i::Smi::FromInt(result->value()));
   4147   ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
   4148   return result;
   4149 }
   4150 
   4151 
   4152 void v8::Object::SetPointerInInternalField(int index, void* value) {
   4153   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   4154   ENTER_V8(isolate);
   4155   if (CanBeEncodedAsSmi(value)) {
   4156     Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
   4157   } else {
   4158     HandleScope scope;
   4159     i::Handle<i::Foreign> foreign =
   4160         isolate->factory()->NewForeign(
   4161             reinterpret_cast<i::Address>(value), i::TENURED);
   4162     if (!foreign.is_null())
   4163         Utils::OpenHandle(this)->SetInternalField(index, *foreign);
   4164   }
   4165   ASSERT_EQ(value, GetPointerFromInternalField(index));
   4166 }
   4167 
   4168 
   4169 // --- E n v i r o n m e n t ---
   4170 
   4171 
   4172 bool v8::V8::Initialize() {
   4173   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   4174   if (isolate != NULL && isolate->IsInitialized()) {
   4175     return true;
   4176   }
   4177   return InitializeHelper();
   4178 }
   4179 
   4180 
   4181 void v8::V8::SetEntropySource(EntropySource source) {
   4182   i::V8::SetEntropySource(source);
   4183 }
   4184 
   4185 
   4186 void v8::V8::SetReturnAddressLocationResolver(
   4187       ReturnAddressLocationResolver return_address_resolver) {
   4188   i::V8::SetReturnAddressLocationResolver(return_address_resolver);
   4189 }
   4190 
   4191 
   4192 bool v8::V8::Dispose() {
   4193   i::Isolate* isolate = i::Isolate::Current();
   4194   if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
   4195                 "v8::V8::Dispose()",
   4196                 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
   4197     return false;
   4198   }
   4199   i::V8::TearDown();
   4200   return true;
   4201 }
   4202 
   4203 
   4204 HeapStatistics::HeapStatistics(): total_heap_size_(0),
   4205                                   total_heap_size_executable_(0),
   4206                                   used_heap_size_(0),
   4207                                   heap_size_limit_(0) { }
   4208 
   4209 
   4210 void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
   4211   if (!i::Isolate::Current()->IsInitialized()) {
   4212     // Isolate is unitialized thus heap is not configured yet.
   4213     heap_statistics->set_total_heap_size(0);
   4214     heap_statistics->set_total_heap_size_executable(0);
   4215     heap_statistics->set_used_heap_size(0);
   4216     heap_statistics->set_heap_size_limit(0);
   4217     return;
   4218   }
   4219 
   4220   i::Heap* heap = i::Isolate::Current()->heap();
   4221   heap_statistics->set_total_heap_size(heap->CommittedMemory());
   4222   heap_statistics->set_total_heap_size_executable(
   4223       heap->CommittedMemoryExecutable());
   4224   heap_statistics->set_used_heap_size(heap->SizeOfObjects());
   4225   heap_statistics->set_heap_size_limit(heap->MaxReserved());
   4226 }
   4227 
   4228 
   4229 void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
   4230   i::Isolate* isolate = i::Isolate::Current();
   4231   IsDeadCheck(isolate, "v8::V8::VisitExternalResources");
   4232   isolate->heap()->VisitExternalResources(visitor);
   4233 }
   4234 
   4235 
   4236 bool v8::V8::IdleNotification(int hint) {
   4237   // Returning true tells the caller that it need not
   4238   // continue to call IdleNotification.
   4239   i::Isolate* isolate = i::Isolate::Current();
   4240   if (isolate == NULL || !isolate->IsInitialized()) return true;
   4241   return i::V8::IdleNotification(hint);
   4242 }
   4243 
   4244 
   4245 void v8::V8::LowMemoryNotification() {
   4246   i::Isolate* isolate = i::Isolate::Current();
   4247   if (isolate == NULL || !isolate->IsInitialized()) return;
   4248   isolate->heap()->CollectAllAvailableGarbage("low memory notification");
   4249 }
   4250 
   4251 
   4252 int v8::V8::ContextDisposedNotification() {
   4253   i::Isolate* isolate = i::Isolate::Current();
   4254   if (!isolate->IsInitialized()) return 0;
   4255   return isolate->heap()->NotifyContextDisposed();
   4256 }
   4257 
   4258 
   4259 const char* v8::V8::GetVersion() {
   4260   return i::Version::GetVersion();
   4261 }
   4262 
   4263 
   4264 static i::Handle<i::FunctionTemplateInfo>
   4265     EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
   4266   if (templ->constructor()->IsUndefined()) {
   4267     Local<FunctionTemplate> constructor = FunctionTemplate::New();
   4268     Utils::OpenHandle(*constructor)->set_instance_template(*templ);
   4269     templ->set_constructor(*Utils::OpenHandle(*constructor));
   4270   }
   4271   return i::Handle<i::FunctionTemplateInfo>(
   4272     i::FunctionTemplateInfo::cast(templ->constructor()));
   4273 }
   4274 
   4275 
   4276 Persistent<Context> v8::Context::New(
   4277     v8::ExtensionConfiguration* extensions,
   4278     v8::Handle<ObjectTemplate> global_template,
   4279     v8::Handle<Value> global_object) {
   4280   i::Isolate::EnsureDefaultIsolate();
   4281   i::Isolate* isolate = i::Isolate::Current();
   4282   EnsureInitializedForIsolate(isolate, "v8::Context::New()");
   4283   LOG_API(isolate, "Context::New");
   4284   ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
   4285 
   4286   // Enter V8 via an ENTER_V8 scope.
   4287   i::Handle<i::Context> env;
   4288   {
   4289     ENTER_V8(isolate);
   4290     v8::Handle<ObjectTemplate> proxy_template = global_template;
   4291     i::Handle<i::FunctionTemplateInfo> proxy_constructor;
   4292     i::Handle<i::FunctionTemplateInfo> global_constructor;
   4293 
   4294     if (!global_template.IsEmpty()) {
   4295       // Make sure that the global_template has a constructor.
   4296       global_constructor =
   4297           EnsureConstructor(Utils::OpenHandle(*global_template));
   4298 
   4299       // Create a fresh template for the global proxy object.
   4300       proxy_template = ObjectTemplate::New();
   4301       proxy_constructor =
   4302           EnsureConstructor(Utils::OpenHandle(*proxy_template));
   4303 
   4304       // Set the global template to be the prototype template of
   4305       // global proxy template.
   4306       proxy_constructor->set_prototype_template(
   4307           *Utils::OpenHandle(*global_template));
   4308 
   4309       // Migrate security handlers from global_template to
   4310       // proxy_template.  Temporarily removing access check
   4311       // information from the global template.
   4312       if (!global_constructor->access_check_info()->IsUndefined()) {
   4313         proxy_constructor->set_access_check_info(
   4314             global_constructor->access_check_info());
   4315         proxy_constructor->set_needs_access_check(
   4316             global_constructor->needs_access_check());
   4317         global_constructor->set_needs_access_check(false);
   4318         global_constructor->set_access_check_info(
   4319             isolate->heap()->undefined_value());
   4320       }
   4321     }
   4322 
   4323     // Create the environment.
   4324     env = isolate->bootstrapper()->CreateEnvironment(
   4325         isolate,
   4326         Utils::OpenHandle(*global_object),
   4327         proxy_template,
   4328         extensions);
   4329 
   4330     // Restore the access check info on the global template.
   4331     if (!global_template.IsEmpty()) {
   4332       ASSERT(!global_constructor.is_null());
   4333       ASSERT(!proxy_constructor.is_null());
   4334       global_constructor->set_access_check_info(
   4335           proxy_constructor->access_check_info());
   4336       global_constructor->set_needs_access_check(
   4337           proxy_constructor->needs_access_check());
   4338     }
   4339     isolate->runtime_profiler()->Reset();
   4340   }
   4341   // Leave V8.
   4342 
   4343   if (env.is_null()) {
   4344     return Persistent<Context>();
   4345   }
   4346   return Persistent<Context>(Utils::ToLocal(env));
   4347 }
   4348 
   4349 
   4350 void v8::Context::SetSecurityToken(Handle<Value> token) {
   4351   i::Isolate* isolate = i::Isolate::Current();
   4352   if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
   4353     return;
   4354   }
   4355   ENTER_V8(isolate);
   4356   i::Handle<i::Context> env = Utils::OpenHandle(this);
   4357   i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
   4358   env->set_security_token(*token_handle);
   4359 }
   4360 
   4361 
   4362 void v8::Context::UseDefaultSecurityToken() {
   4363   i::Isolate* isolate = i::Isolate::Current();
   4364   if (IsDeadCheck(isolate,
   4365                   "v8::Context::UseDefaultSecurityToken()")) {
   4366     return;
   4367   }
   4368   ENTER_V8(isolate);
   4369   i::Handle<i::Context> env = Utils::OpenHandle(this);
   4370   env->set_security_token(env->global());
   4371 }
   4372 
   4373 
   4374 Handle<Value> v8::Context::GetSecurityToken() {
   4375   i::Isolate* isolate = i::Isolate::Current();
   4376   if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
   4377     return Handle<Value>();
   4378   }
   4379   i::Handle<i::Context> env = Utils::OpenHandle(this);
   4380   i::Object* security_token = env->security_token();
   4381   i::Handle<i::Object> token_handle(security_token);
   4382   return Utils::ToLocal(token_handle);
   4383 }
   4384 
   4385 
   4386 bool Context::HasOutOfMemoryException() {
   4387   i::Handle<i::Context> env = Utils::OpenHandle(this);
   4388   return env->has_out_of_memory();
   4389 }
   4390 
   4391 
   4392 bool Context::InContext() {
   4393   return i::Isolate::Current()->context() != NULL;
   4394 }
   4395 
   4396 
   4397 v8::Local<v8::Context> Context::GetEntered() {
   4398   i::Isolate* isolate = i::Isolate::Current();
   4399   if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
   4400     return Local<Context>();
   4401   }
   4402   i::Handle<i::Object> last =
   4403       isolate->handle_scope_implementer()->LastEnteredContext();
   4404   if (last.is_null()) return Local<Context>();
   4405   i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
   4406   return Utils::ToLocal(context);
   4407 }
   4408 
   4409 
   4410 v8::Local<v8::Context> Context::GetCurrent() {
   4411   i::Isolate* isolate = i::Isolate::Current();
   4412   if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
   4413     return Local<Context>();
   4414   }
   4415   i::Handle<i::Object> current = isolate->global_context();
   4416   if (current.is_null()) return Local<Context>();
   4417   i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
   4418   return Utils::ToLocal(context);
   4419 }
   4420 
   4421 
   4422 v8::Local<v8::Context> Context::GetCalling() {
   4423   i::Isolate* isolate = i::Isolate::Current();
   4424   if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
   4425     return Local<Context>();
   4426   }
   4427   i::Handle<i::Object> calling =
   4428       isolate->GetCallingGlobalContext();
   4429   if (calling.is_null()) return Local<Context>();
   4430   i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
   4431   return Utils::ToLocal(context);
   4432 }
   4433 
   4434 
   4435 v8::Local<v8::Object> Context::Global() {
   4436   if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
   4437     return Local<v8::Object>();
   4438   }
   4439   i::Object** ctx = reinterpret_cast<i::Object**>(this);
   4440   i::Handle<i::Context> context =
   4441       i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
   4442   i::Handle<i::Object> global(context->global_proxy());
   4443   return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
   4444 }
   4445 
   4446 
   4447 void Context::DetachGlobal() {
   4448   i::Isolate* isolate = i::Isolate::Current();
   4449   if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
   4450   ENTER_V8(isolate);
   4451   i::Object** ctx = reinterpret_cast<i::Object**>(this);
   4452   i::Handle<i::Context> context =
   4453       i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
   4454   isolate->bootstrapper()->DetachGlobal(context);
   4455 }
   4456 
   4457 
   4458 void Context::ReattachGlobal(Handle<Object> global_object) {
   4459   i::Isolate* isolate = i::Isolate::Current();
   4460   if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
   4461   ENTER_V8(isolate);
   4462   i::Object** ctx = reinterpret_cast<i::Object**>(this);
   4463   i::Handle<i::Context> context =
   4464       i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
   4465   isolate->bootstrapper()->ReattachGlobal(
   4466       context,
   4467       Utils::OpenHandle(*global_object));
   4468 }
   4469 
   4470 
   4471 void Context::AllowCodeGenerationFromStrings(bool allow) {
   4472   i::Isolate* isolate = i::Isolate::Current();
   4473   if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
   4474     return;
   4475   }
   4476   ENTER_V8(isolate);
   4477   i::Object** ctx = reinterpret_cast<i::Object**>(this);
   4478   i::Handle<i::Context> context =
   4479       i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
   4480   context->set_allow_code_gen_from_strings(
   4481       allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
   4482 }
   4483 
   4484 
   4485 bool Context::IsCodeGenerationFromStringsAllowed() {
   4486   i::Isolate* isolate = i::Isolate::Current();
   4487   if (IsDeadCheck(isolate,
   4488                   "v8::Context::IsCodeGenerationFromStringsAllowed()")) {
   4489     return false;
   4490   }
   4491   ENTER_V8(isolate);
   4492   i::Object** ctx = reinterpret_cast<i::Object**>(this);
   4493   i::Handle<i::Context> context =
   4494       i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
   4495   return !context->allow_code_gen_from_strings()->IsFalse();
   4496 }
   4497 
   4498 
   4499 void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
   4500   i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
   4501 }
   4502 
   4503 
   4504 Local<v8::Object> ObjectTemplate::NewInstance() {
   4505   i::Isolate* isolate = i::Isolate::Current();
   4506   ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
   4507              return Local<v8::Object>());
   4508   LOG_API(isolate, "ObjectTemplate::NewInstance");
   4509   ENTER_V8(isolate);
   4510   EXCEPTION_PREAMBLE(isolate);
   4511   i::Handle<i::Object> obj =
   4512       i::Execution::InstantiateObject(Utils::OpenHandle(this),
   4513                                       &has_pending_exception);
   4514   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
   4515   return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
   4516 }
   4517 
   4518 
   4519 Local<v8::Function> FunctionTemplate::GetFunction() {
   4520   i::Isolate* isolate = i::Isolate::Current();
   4521   ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
   4522              return Local<v8::Function>());
   4523   LOG_API(isolate, "FunctionTemplate::GetFunction");
   4524   ENTER_V8(isolate);
   4525   EXCEPTION_PREAMBLE(isolate);
   4526   i::Handle<i::Object> obj =
   4527       i::Execution::InstantiateFunction(Utils::OpenHandle(this),
   4528                                         &has_pending_exception);
   4529   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
   4530   return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
   4531 }
   4532 
   4533 
   4534 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
   4535   ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
   4536              return false);
   4537   i::Object* obj = *Utils::OpenHandle(*value);
   4538   return obj->IsInstanceOf(*Utils::OpenHandle(this));
   4539 }
   4540 
   4541 
   4542 static Local<External> ExternalNewImpl(void* data) {
   4543   return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data)));
   4544 }
   4545 
   4546 static void* ExternalValueImpl(i::Handle<i::Object> obj) {
   4547   return reinterpret_cast<void*>(i::Foreign::cast(*obj)->foreign_address());
   4548 }
   4549 
   4550 
   4551 Local<Value> v8::External::Wrap(void* data) {
   4552   i::Isolate* isolate = i::Isolate::Current();
   4553   STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
   4554   EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
   4555   LOG_API(isolate, "External::Wrap");
   4556   ENTER_V8(isolate);
   4557 
   4558   v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
   4559       ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
   4560       : v8::Local<v8::Value>(ExternalNewImpl(data));
   4561 
   4562   ASSERT_EQ(data, Unwrap(result));
   4563   return result;
   4564 }
   4565 
   4566 
   4567 void* v8::Object::SlowGetPointerFromInternalField(int index) {
   4568   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   4569   i::Object* value = obj->GetInternalField(index);
   4570   if (value->IsSmi()) {
   4571     return i::Internals::GetExternalPointerFromSmi(value);
   4572   } else if (value->IsForeign()) {
   4573     return reinterpret_cast<void*>(i::Foreign::cast(value)->foreign_address());
   4574   } else {
   4575     return NULL;
   4576   }
   4577 }
   4578 
   4579 
   4580 void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
   4581   if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
   4582   i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
   4583   void* result;
   4584   if (obj->IsSmi()) {
   4585     result = i::Internals::GetExternalPointerFromSmi(*obj);
   4586   } else if (obj->IsForeign()) {
   4587     result = ExternalValueImpl(obj);
   4588   } else {
   4589     result = NULL;
   4590   }
   4591   ASSERT_EQ(result, QuickUnwrap(wrapper));
   4592   return result;
   4593 }
   4594 
   4595 
   4596 Local<External> v8::External::New(void* data) {
   4597   STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
   4598   i::Isolate* isolate = i::Isolate::Current();
   4599   EnsureInitializedForIsolate(isolate, "v8::External::New()");
   4600   LOG_API(isolate, "External::New");
   4601   ENTER_V8(isolate);
   4602   return ExternalNewImpl(data);
   4603 }
   4604 
   4605 
   4606 void* External::Value() const {
   4607   if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
   4608   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4609   return ExternalValueImpl(obj);
   4610 }
   4611 
   4612 
   4613 Local<String> v8::String::Empty() {
   4614   i::Isolate* isolate = i::Isolate::Current();
   4615   EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
   4616   LOG_API(isolate, "String::Empty()");
   4617   return Utils::ToLocal(isolate->factory()->empty_symbol());
   4618 }
   4619 
   4620 
   4621 Local<String> v8::String::New(const char* data, int length) {
   4622   i::Isolate* isolate = i::Isolate::Current();
   4623   EnsureInitializedForIsolate(isolate, "v8::String::New()");
   4624   LOG_API(isolate, "String::New(char)");
   4625   if (length == 0) return Empty();
   4626   ENTER_V8(isolate);
   4627   if (length == -1) length = i::StrLength(data);
   4628   i::Handle<i::String> result =
   4629       isolate->factory()->NewStringFromUtf8(
   4630           i::Vector<const char>(data, length));
   4631   return Utils::ToLocal(result);
   4632 }
   4633 
   4634 
   4635 Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
   4636   i::Handle<i::String> left_string = Utils::OpenHandle(*left);
   4637   i::Isolate* isolate = left_string->GetIsolate();
   4638   EnsureInitializedForIsolate(isolate, "v8::String::New()");
   4639   LOG_API(isolate, "String::New(char)");
   4640   ENTER_V8(isolate);
   4641   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
   4642   i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
   4643                                                                   right_string);
   4644   return Utils::ToLocal(result);
   4645 }
   4646 
   4647 
   4648 Local<String> v8::String::NewUndetectable(const char* data, int length) {
   4649   i::Isolate* isolate = i::Isolate::Current();
   4650   EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
   4651   LOG_API(isolate, "String::NewUndetectable(char)");
   4652   ENTER_V8(isolate);
   4653   if (length == -1) length = i::StrLength(data);
   4654   i::Handle<i::String> result =
   4655       isolate->factory()->NewStringFromUtf8(
   4656           i::Vector<const char>(data, length));
   4657   result->MarkAsUndetectable();
   4658   return Utils::ToLocal(result);
   4659 }
   4660 
   4661 
   4662 static int TwoByteStringLength(const uint16_t* data) {
   4663   int length = 0;
   4664   while (data[length] != '\0') length++;
   4665   return length;
   4666 }
   4667 
   4668 
   4669 Local<String> v8::String::New(const uint16_t* data, int length) {
   4670   i::Isolate* isolate = i::Isolate::Current();
   4671   EnsureInitializedForIsolate(isolate, "v8::String::New()");
   4672   LOG_API(isolate, "String::New(uint16_)");
   4673   if (length == 0) return Empty();
   4674   ENTER_V8(isolate);
   4675   if (length == -1) length = TwoByteStringLength(data);
   4676   i::Handle<i::String> result =
   4677       isolate->factory()->NewStringFromTwoByte(
   4678           i::Vector<const uint16_t>(data, length));
   4679   return Utils::ToLocal(result);
   4680 }
   4681 
   4682 
   4683 Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
   4684   i::Isolate* isolate = i::Isolate::Current();
   4685   EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
   4686   LOG_API(isolate, "String::NewUndetectable(uint16_)");
   4687   ENTER_V8(isolate);
   4688   if (length == -1) length = TwoByteStringLength(data);
   4689   i::Handle<i::String> result =
   4690       isolate->factory()->NewStringFromTwoByte(
   4691           i::Vector<const uint16_t>(data, length));
   4692   result->MarkAsUndetectable();
   4693   return Utils::ToLocal(result);
   4694 }
   4695 
   4696 
   4697 i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
   4698       v8::String::ExternalStringResource* resource) {
   4699   i::Handle<i::String> result =
   4700       isolate->factory()->NewExternalStringFromTwoByte(resource);
   4701   return result;
   4702 }
   4703 
   4704 
   4705 i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
   4706       v8::String::ExternalAsciiStringResource* resource) {
   4707   i::Handle<i::String> result =
   4708       isolate->factory()->NewExternalStringFromAscii(resource);
   4709   return result;
   4710 }
   4711 
   4712 
   4713 Local<String> v8::String::NewExternal(
   4714       v8::String::ExternalStringResource* resource) {
   4715   i::Isolate* isolate = i::Isolate::Current();
   4716   EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
   4717   LOG_API(isolate, "String::NewExternal");
   4718   ENTER_V8(isolate);
   4719   i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
   4720   isolate->heap()->external_string_table()->AddString(*result);
   4721   return Utils::ToLocal(result);
   4722 }
   4723 
   4724 
   4725 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
   4726   i::Handle<i::String> obj = Utils::OpenHandle(this);
   4727   i::Isolate* isolate = obj->GetIsolate();
   4728   if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
   4729   if (i::StringShape(*obj).IsExternalTwoByte()) {
   4730     return false;  // Already an external string.
   4731   }
   4732   ENTER_V8(isolate);
   4733   if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
   4734     return false;
   4735   }
   4736   if (isolate->heap()->IsInGCPostProcessing()) {
   4737     return false;
   4738   }
   4739   bool result = obj->MakeExternal(resource);
   4740   if (result && !obj->IsSymbol()) {
   4741     isolate->heap()->external_string_table()->AddString(*obj);
   4742   }
   4743   return result;
   4744 }
   4745 
   4746 
   4747 Local<String> v8::String::NewExternal(
   4748       v8::String::ExternalAsciiStringResource* resource) {
   4749   i::Isolate* isolate = i::Isolate::Current();
   4750   EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
   4751   LOG_API(isolate, "String::NewExternal");
   4752   ENTER_V8(isolate);
   4753   i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
   4754   isolate->heap()->external_string_table()->AddString(*result);
   4755   return Utils::ToLocal(result);
   4756 }
   4757 
   4758 
   4759 bool v8::String::MakeExternal(
   4760     v8::String::ExternalAsciiStringResource* resource) {
   4761   i::Handle<i::String> obj = Utils::OpenHandle(this);
   4762   i::Isolate* isolate = obj->GetIsolate();
   4763   if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
   4764   if (i::StringShape(*obj).IsExternalTwoByte()) {
   4765     return false;  // Already an external string.
   4766   }
   4767   ENTER_V8(isolate);
   4768   if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
   4769     return false;
   4770   }
   4771   if (isolate->heap()->IsInGCPostProcessing()) {
   4772     return false;
   4773   }
   4774   bool result = obj->MakeExternal(resource);
   4775   if (result && !obj->IsSymbol()) {
   4776     isolate->heap()->external_string_table()->AddString(*obj);
   4777   }
   4778   return result;
   4779 }
   4780 
   4781 
   4782 bool v8::String::CanMakeExternal() {
   4783   if (!internal::FLAG_clever_optimizations) return false;
   4784   i::Handle<i::String> obj = Utils::OpenHandle(this);
   4785   i::Isolate* isolate = obj->GetIsolate();
   4786   if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
   4787   if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
   4788   int size = obj->Size();  // Byte size of the original string.
   4789   if (size < i::ExternalString::kShortSize) return false;
   4790   i::StringShape shape(*obj);
   4791   return !shape.IsExternal();
   4792 }
   4793 
   4794 
   4795 Local<v8::Object> v8::Object::New() {
   4796   i::Isolate* isolate = i::Isolate::Current();
   4797   EnsureInitializedForIsolate(isolate, "v8::Object::New()");
   4798   LOG_API(isolate, "Object::New");
   4799   ENTER_V8(isolate);
   4800   i::Handle<i::JSObject> obj =
   4801       isolate->factory()->NewJSObject(isolate->object_function());
   4802   return Utils::ToLocal(obj);
   4803 }
   4804 
   4805 
   4806 Local<v8::Value> v8::NumberObject::New(double value) {
   4807   i::Isolate* isolate = i::Isolate::Current();
   4808   EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
   4809   LOG_API(isolate, "NumberObject::New");
   4810   ENTER_V8(isolate);
   4811   i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
   4812   i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
   4813   return Utils::ToLocal(obj);
   4814 }
   4815 
   4816 
   4817 double v8::NumberObject::NumberValue() const {
   4818   i::Isolate* isolate = i::Isolate::Current();
   4819   if (IsDeadCheck(isolate, "v8::NumberObject::NumberValue()")) return 0;
   4820   LOG_API(isolate, "NumberObject::NumberValue");
   4821   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4822   i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
   4823   return jsvalue->value()->Number();
   4824 }
   4825 
   4826 
   4827 Local<v8::Value> v8::BooleanObject::New(bool value) {
   4828   i::Isolate* isolate = i::Isolate::Current();
   4829   EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
   4830   LOG_API(isolate, "BooleanObject::New");
   4831   ENTER_V8(isolate);
   4832   i::Handle<i::Object> boolean(value ? isolate->heap()->true_value()
   4833                                      : isolate->heap()->false_value());
   4834   i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
   4835   return Utils::ToLocal(obj);
   4836 }
   4837 
   4838 
   4839 bool v8::BooleanObject::BooleanValue() const {
   4840   i::Isolate* isolate = i::Isolate::Current();
   4841   if (IsDeadCheck(isolate, "v8::BooleanObject::BooleanValue()")) return 0;
   4842   LOG_API(isolate, "BooleanObject::BooleanValue");
   4843   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4844   i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
   4845   return jsvalue->value()->IsTrue();
   4846 }
   4847 
   4848 
   4849 Local<v8::Value> v8::StringObject::New(Handle<String> value) {
   4850   i::Isolate* isolate = i::Isolate::Current();
   4851   EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
   4852   LOG_API(isolate, "StringObject::New");
   4853   ENTER_V8(isolate);
   4854   i::Handle<i::Object> obj =
   4855       isolate->factory()->ToObject(Utils::OpenHandle(*value));
   4856   return Utils::ToLocal(obj);
   4857 }
   4858 
   4859 
   4860 Local<v8::String> v8::StringObject::StringValue() const {
   4861   i::Isolate* isolate = i::Isolate::Current();
   4862   if (IsDeadCheck(isolate, "v8::StringObject::StringValue()")) {
   4863     return Local<v8::String>();
   4864   }
   4865   LOG_API(isolate, "StringObject::StringValue");
   4866   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4867   i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
   4868   return Utils::ToLocal(
   4869       i::Handle<i::String>(i::String::cast(jsvalue->value())));
   4870 }
   4871 
   4872 
   4873 Local<v8::Value> v8::Date::New(double time) {
   4874   i::Isolate* isolate = i::Isolate::Current();
   4875   EnsureInitializedForIsolate(isolate, "v8::Date::New()");
   4876   LOG_API(isolate, "Date::New");
   4877   if (isnan(time)) {
   4878     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
   4879     time = i::OS::nan_value();
   4880   }
   4881   ENTER_V8(isolate);
   4882   EXCEPTION_PREAMBLE(isolate);
   4883   i::Handle<i::Object> obj =
   4884       i::Execution::NewDate(time, &has_pending_exception);
   4885   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
   4886   return Utils::ToLocal(obj);
   4887 }
   4888 
   4889 
   4890 double v8::Date::NumberValue() const {
   4891   i::Isolate* isolate = i::Isolate::Current();
   4892   if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
   4893   LOG_API(isolate, "Date::NumberValue");
   4894   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   4895   i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
   4896   return jsdate->value()->Number();
   4897 }
   4898 
   4899 
   4900 void v8::Date::DateTimeConfigurationChangeNotification() {
   4901   i::Isolate* isolate = i::Isolate::Current();
   4902   ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
   4903              return);
   4904   LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
   4905   ENTER_V8(isolate);
   4906 
   4907   isolate->date_cache()->ResetDateCache();
   4908 
   4909   i::HandleScope scope(isolate);
   4910   // Get the function ResetDateCache (defined in date.js).
   4911   i::Handle<i::String> func_name_str =
   4912       isolate->factory()->LookupAsciiSymbol("ResetDateCache");
   4913   i::MaybeObject* result =
   4914       isolate->js_builtins_object()->GetProperty(*func_name_str);
   4915   i::Object* object_func;
   4916   if (!result->ToObject(&object_func)) {
   4917     return;
   4918   }
   4919 
   4920   if (object_func->IsJSFunction()) {
   4921     i::Handle<i::JSFunction> func =
   4922         i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
   4923 
   4924     // Call ResetDateCache(0 but expect no exceptions:
   4925     bool caught_exception = false;
   4926     i::Execution::TryCall(func,
   4927                           isolate->js_builtins_object(),
   4928                           0,
   4929                           NULL,
   4930                           &caught_exception);
   4931   }
   4932 }
   4933 
   4934 
   4935 static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
   4936   char flags_buf[3];
   4937   int num_flags = 0;
   4938   if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
   4939   if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
   4940   if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
   4941   ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
   4942   return FACTORY->LookupSymbol(
   4943       i::Vector<const char>(flags_buf, num_flags));
   4944 }
   4945 
   4946 
   4947 Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
   4948                                   Flags flags) {
   4949   i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
   4950   EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
   4951   LOG_API(isolate, "RegExp::New");
   4952   ENTER_V8(isolate);
   4953   EXCEPTION_PREAMBLE(isolate);
   4954   i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
   4955       Utils::OpenHandle(*pattern),
   4956       RegExpFlagsToString(flags),
   4957       &has_pending_exception);
   4958   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
   4959   return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
   4960 }
   4961 
   4962 
   4963 Local<v8::String> v8::RegExp::GetSource() const {
   4964   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   4965   if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
   4966     return Local<v8::String>();
   4967   }
   4968   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
   4969   return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
   4970 }
   4971 
   4972 
   4973 // Assert that the static flags cast in GetFlags is valid.
   4974 #define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag)        \
   4975   STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) ==     \
   4976                 static_cast<int>(i::JSRegExp::internal_flag))
   4977 REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
   4978 REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
   4979 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
   4980 REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
   4981 #undef REGEXP_FLAG_ASSERT_EQ
   4982 
   4983 v8::RegExp::Flags v8::RegExp::GetFlags() const {
   4984   if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
   4985     return v8::RegExp::kNone;
   4986   }
   4987   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
   4988   return static_cast<RegExp::Flags>(obj->GetFlags().value());
   4989 }
   4990 
   4991 
   4992 Local<v8::Array> v8::Array::New(int length) {
   4993   i::Isolate* isolate = i::Isolate::Current();
   4994   EnsureInitializedForIsolate(isolate, "v8::Array::New()");
   4995   LOG_API(isolate, "Array::New");
   4996   ENTER_V8(isolate);
   4997   int real_length = length > 0 ? length : 0;
   4998   i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
   4999   i::Handle<i::Object> length_obj =
   5000       isolate->factory()->NewNumberFromInt(real_length);
   5001   obj->set_length(*length_obj);
   5002   return Utils::ToLocal(obj);
   5003 }
   5004 
   5005 
   5006 uint32_t v8::Array::Length() const {
   5007   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   5008   if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
   5009   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
   5010   i::Object* length = obj->length();
   5011   if (length->IsSmi()) {
   5012     return i::Smi::cast(length)->value();
   5013   } else {
   5014     return static_cast<uint32_t>(length->Number());
   5015   }
   5016 }
   5017 
   5018 
   5019 Local<Object> Array::CloneElementAt(uint32_t index) {
   5020   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   5021   ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
   5022   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   5023   if (!self->HasFastElements()) {
   5024     return Local<Object>();
   5025   }
   5026   i::FixedArray* elms = i::FixedArray::cast(self->elements());
   5027   i::Object* paragon = elms->get(index);
   5028   if (!paragon->IsJSObject()) {
   5029     return Local<Object>();
   5030   }
   5031   i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
   5032   EXCEPTION_PREAMBLE(isolate);
   5033   ENTER_V8(isolate);
   5034   i::Handle<i::JSObject> result = i::Copy(paragon_handle);
   5035   has_pending_exception = result.is_null();
   5036   EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
   5037   return Utils::ToLocal(result);
   5038 }
   5039 
   5040 
   5041 Local<String> v8::String::NewSymbol(const char* data, int length) {
   5042   i::Isolate* isolate = i::Isolate::Current();
   5043   EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
   5044   LOG_API(isolate, "String::NewSymbol(char)");
   5045   ENTER_V8(isolate);
   5046   if (length == -1) length = i::StrLength(data);
   5047   i::Handle<i::String> result =
   5048       isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
   5049   return Utils::ToLocal(result);
   5050 }
   5051 
   5052 
   5053 Local<Number> v8::Number::New(double value) {
   5054   i::Isolate* isolate = i::Isolate::Current();
   5055   EnsureInitializedForIsolate(isolate, "v8::Number::New()");
   5056   if (isnan(value)) {
   5057     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
   5058     value = i::OS::nan_value();
   5059   }
   5060   ENTER_V8(isolate);
   5061   i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
   5062   return Utils::NumberToLocal(result);
   5063 }
   5064 
   5065 
   5066 Local<Integer> v8::Integer::New(int32_t value) {
   5067   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   5068   EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
   5069   if (i::Smi::IsValid(value)) {
   5070     return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
   5071                                                       isolate));
   5072   }
   5073   ENTER_V8(isolate);
   5074   i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
   5075   return Utils::IntegerToLocal(result);
   5076 }
   5077 
   5078 
   5079 Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
   5080   bool fits_into_int32_t = (value & (1 << 31)) == 0;
   5081   if (fits_into_int32_t) {
   5082     return Integer::New(static_cast<int32_t>(value));
   5083   }
   5084   i::Isolate* isolate = i::Isolate::Current();
   5085   ENTER_V8(isolate);
   5086   i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
   5087   return Utils::IntegerToLocal(result);
   5088 }
   5089 
   5090 
   5091 void V8::IgnoreOutOfMemoryException() {
   5092   EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
   5093 }
   5094 
   5095 
   5096 bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
   5097   i::Isolate* isolate = i::Isolate::Current();
   5098   EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
   5099   ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
   5100   ENTER_V8(isolate);
   5101   i::HandleScope scope(isolate);
   5102   NeanderArray listeners(isolate->factory()->message_listeners());
   5103   NeanderObject obj(2);
   5104   obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
   5105   obj.set(1, data.IsEmpty() ?
   5106              isolate->heap()->undefined_value() :
   5107              *Utils::OpenHandle(*data));
   5108   listeners.add(obj.value());
   5109   return true;
   5110 }
   5111 
   5112 
   5113 void V8::RemoveMessageListeners(MessageCallback that) {
   5114   i::Isolate* isolate = i::Isolate::Current();
   5115   EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
   5116   ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
   5117   ENTER_V8(isolate);
   5118   i::HandleScope scope(isolate);
   5119   NeanderArray listeners(isolate->factory()->message_listeners());
   5120   for (int i = 0; i < listeners.length(); i++) {
   5121     if (listeners.get(i)->IsUndefined()) continue;  // skip deleted ones
   5122 
   5123     NeanderObject listener(i::JSObject::cast(listeners.get(i)));
   5124     i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
   5125     if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
   5126       listeners.set(i, isolate->heap()->undefined_value());
   5127     }
   5128   }
   5129 }
   5130 
   5131 
   5132 void V8::SetCaptureStackTraceForUncaughtExceptions(
   5133       bool capture,
   5134       int frame_limit,
   5135       StackTrace::StackTraceOptions options) {
   5136   i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
   5137       capture,
   5138       frame_limit,
   5139       options);
   5140 }
   5141 
   5142 
   5143 void V8::SetCounterFunction(CounterLookupCallback callback) {
   5144   i::Isolate* isolate = EnterIsolateIfNeeded();
   5145   if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
   5146   isolate->stats_table()->SetCounterFunction(callback);
   5147 }
   5148 
   5149 void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
   5150   i::Isolate* isolate = EnterIsolateIfNeeded();
   5151   if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
   5152   isolate->stats_table()->SetCreateHistogramFunction(callback);
   5153 }
   5154 
   5155 void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
   5156   i::Isolate* isolate = EnterIsolateIfNeeded();
   5157   if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
   5158   isolate->stats_table()->
   5159       SetAddHistogramSampleFunction(callback);
   5160 }
   5161 
   5162 void V8::EnableSlidingStateWindow() {
   5163   i::Isolate* isolate = i::Isolate::Current();
   5164   if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
   5165   isolate->logger()->EnableSlidingStateWindow();
   5166 }
   5167 
   5168 
   5169 void V8::SetFailedAccessCheckCallbackFunction(
   5170       FailedAccessCheckCallback callback) {
   5171   i::Isolate* isolate = i::Isolate::Current();
   5172   if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
   5173     return;
   5174   }
   5175   isolate->SetFailedAccessCheckCallback(callback);
   5176 }
   5177 
   5178 void V8::AddObjectGroup(Persistent<Value>* objects,
   5179                         size_t length,
   5180                         RetainedObjectInfo* info) {
   5181   i::Isolate* isolate = i::Isolate::Current();
   5182   if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
   5183   STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
   5184   isolate->global_handles()->AddObjectGroup(
   5185       reinterpret_cast<i::Object***>(objects), length, info);
   5186 }
   5187 
   5188 
   5189 void V8::AddImplicitReferences(Persistent<Object> parent,
   5190                                Persistent<Value>* children,
   5191                                size_t length) {
   5192   i::Isolate* isolate = i::Isolate::Current();
   5193   if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
   5194   STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
   5195   isolate->global_handles()->AddImplicitReferences(
   5196       i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*parent)).location(),
   5197       reinterpret_cast<i::Object***>(children), length);
   5198 }
   5199 
   5200 
   5201 int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
   5202   i::Isolate* isolate = i::Isolate::Current();
   5203   if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
   5204     return 0;
   5205   }
   5206   return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
   5207       change_in_bytes);
   5208 }
   5209 
   5210 
   5211 void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
   5212   i::Isolate* isolate = i::Isolate::Current();
   5213   if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
   5214   isolate->heap()->SetGlobalGCPrologueCallback(callback);
   5215 }
   5216 
   5217 
   5218 void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
   5219   i::Isolate* isolate = i::Isolate::Current();
   5220   if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
   5221   isolate->heap()->SetGlobalGCEpilogueCallback(callback);
   5222 }
   5223 
   5224 
   5225 void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
   5226   i::Isolate* isolate = i::Isolate::Current();
   5227   if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
   5228   isolate->heap()->AddGCPrologueCallback(callback, gc_type);
   5229 }
   5230 
   5231 
   5232 void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
   5233   i::Isolate* isolate = i::Isolate::Current();
   5234   if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
   5235   isolate->heap()->RemoveGCPrologueCallback(callback);
   5236 }
   5237 
   5238 
   5239 void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
   5240   i::Isolate* isolate = i::Isolate::Current();
   5241   if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
   5242   isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
   5243 }
   5244 
   5245 
   5246 void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
   5247   i::Isolate* isolate = i::Isolate::Current();
   5248   if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
   5249   isolate->heap()->RemoveGCEpilogueCallback(callback);
   5250 }
   5251 
   5252 
   5253 void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
   5254                                      ObjectSpace space,
   5255                                      AllocationAction action) {
   5256   i::Isolate* isolate = i::Isolate::Current();
   5257   if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
   5258   isolate->memory_allocator()->AddMemoryAllocationCallback(
   5259       callback, space, action);
   5260 }
   5261 
   5262 
   5263 void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
   5264   i::Isolate* isolate = i::Isolate::Current();
   5265   if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
   5266   isolate->memory_allocator()->RemoveMemoryAllocationCallback(
   5267       callback);
   5268 }
   5269 
   5270 
   5271 void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
   5272   if (callback == NULL) return;
   5273   i::Isolate::EnsureDefaultIsolate();
   5274   i::Isolate* isolate = i::Isolate::Current();
   5275   if (IsDeadCheck(isolate, "v8::V8::AddLeaveScriptCallback()")) return;
   5276   i::V8::AddCallCompletedCallback(callback);
   5277 }
   5278 
   5279 
   5280 void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
   5281   i::Isolate::EnsureDefaultIsolate();
   5282   i::Isolate* isolate = i::Isolate::Current();
   5283   if (IsDeadCheck(isolate, "v8::V8::RemoveLeaveScriptCallback()")) return;
   5284   i::V8::RemoveCallCompletedCallback(callback);
   5285 }
   5286 
   5287 
   5288 void V8::PauseProfiler() {
   5289   i::Isolate* isolate = i::Isolate::Current();
   5290   isolate->logger()->PauseProfiler();
   5291 }
   5292 
   5293 
   5294 void V8::ResumeProfiler() {
   5295   i::Isolate* isolate = i::Isolate::Current();
   5296   isolate->logger()->ResumeProfiler();
   5297 }
   5298 
   5299 
   5300 bool V8::IsProfilerPaused() {
   5301   i::Isolate* isolate = i::Isolate::Current();
   5302   return isolate->logger()->IsProfilerPaused();
   5303 }
   5304 
   5305 
   5306 int V8::GetCurrentThreadId() {
   5307   i::Isolate* isolate = i::Isolate::Current();
   5308   EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
   5309   return isolate->thread_id().ToInteger();
   5310 }
   5311 
   5312 
   5313 void V8::TerminateExecution(int thread_id) {
   5314   i::Isolate* isolate = i::Isolate::Current();
   5315   if (!isolate->IsInitialized()) return;
   5316   API_ENTRY_CHECK(isolate, "V8::TerminateExecution()");
   5317   // If the thread_id identifies the current thread just terminate
   5318   // execution right away.  Otherwise, ask the thread manager to
   5319   // terminate the thread with the given id if any.
   5320   i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
   5321   if (isolate->thread_id().Equals(internal_tid)) {
   5322     isolate->stack_guard()->TerminateExecution();
   5323   } else {
   5324     isolate->thread_manager()->TerminateExecution(internal_tid);
   5325   }
   5326 }
   5327 
   5328 
   5329 void V8::TerminateExecution(Isolate* isolate) {
   5330   // If no isolate is supplied, use the default isolate.
   5331   if (isolate != NULL) {
   5332     reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
   5333   } else {
   5334     i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
   5335   }
   5336 }
   5337 
   5338 
   5339 bool V8::IsExecutionTerminating(Isolate* isolate) {
   5340   i::Isolate* i_isolate = isolate != NULL ?
   5341       reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
   5342   return IsExecutionTerminatingCheck(i_isolate);
   5343 }
   5344 
   5345 
   5346 Isolate* Isolate::GetCurrent() {
   5347   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   5348   return reinterpret_cast<Isolate*>(isolate);
   5349 }
   5350 
   5351 
   5352 Isolate* Isolate::New() {
   5353   i::Isolate* isolate = new i::Isolate();
   5354   return reinterpret_cast<Isolate*>(isolate);
   5355 }
   5356 
   5357 
   5358 void Isolate::Dispose() {
   5359   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   5360   if (!ApiCheck(!isolate->IsInUse(),
   5361                 "v8::Isolate::Dispose()",
   5362                 "Disposing the isolate that is entered by a thread.")) {
   5363     return;
   5364   }
   5365   isolate->TearDown();
   5366 }
   5367 
   5368 
   5369 void Isolate::Enter() {
   5370   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   5371   isolate->Enter();
   5372 }
   5373 
   5374 
   5375 void Isolate::Exit() {
   5376   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   5377   isolate->Exit();
   5378 }
   5379 
   5380 
   5381 void Isolate::SetData(void* data) {
   5382   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   5383   isolate->SetData(data);
   5384 }
   5385 
   5386 void* Isolate::GetData() {
   5387   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   5388   return isolate->GetData();
   5389 }
   5390 
   5391 
   5392 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
   5393     : str_(NULL), length_(0) {
   5394   i::Isolate* isolate = i::Isolate::Current();
   5395   if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
   5396   if (obj.IsEmpty()) return;
   5397   ENTER_V8(isolate);
   5398   i::HandleScope scope(isolate);
   5399   TryCatch try_catch;
   5400   Handle<String> str = obj->ToString();
   5401   if (str.IsEmpty()) return;
   5402   i::Handle<i::String> i_str = Utils::OpenHandle(*str);
   5403   length_ = i::Utf8Length(i_str);
   5404   str_ = i::NewArray<char>(length_ + 1);
   5405   str->WriteUtf8(str_);
   5406 }
   5407 
   5408 
   5409 String::Utf8Value::~Utf8Value() {
   5410   i::DeleteArray(str_);
   5411 }
   5412 
   5413 
   5414 String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
   5415     : str_(NULL), length_(0) {
   5416   i::Isolate* isolate = i::Isolate::Current();
   5417   if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
   5418   if (obj.IsEmpty()) return;
   5419   ENTER_V8(isolate);
   5420   i::HandleScope scope(isolate);
   5421   TryCatch try_catch;
   5422   Handle<String> str = obj->ToString();
   5423   if (str.IsEmpty()) return;
   5424   length_ = str->Length();
   5425   str_ = i::NewArray<char>(length_ + 1);
   5426   str->WriteAscii(str_);
   5427 }
   5428 
   5429 
   5430 String::AsciiValue::~AsciiValue() {
   5431   i::DeleteArray(str_);
   5432 }
   5433 
   5434 
   5435 String::Value::Value(v8::Handle<v8::Value> obj)
   5436     : str_(NULL), length_(0) {
   5437   i::Isolate* isolate = i::Isolate::Current();
   5438   if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
   5439   if (obj.IsEmpty()) return;
   5440   ENTER_V8(isolate);
   5441   i::HandleScope scope(isolate);
   5442   TryCatch try_catch;
   5443   Handle<String> str = obj->ToString();
   5444   if (str.IsEmpty()) return;
   5445   length_ = str->Length();
   5446   str_ = i::NewArray<uint16_t>(length_ + 1);
   5447   str->Write(str_);
   5448 }
   5449 
   5450 
   5451 String::Value::~Value() {
   5452   i::DeleteArray(str_);
   5453 }
   5454 
   5455 Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
   5456   i::Isolate* isolate = i::Isolate::Current();
   5457   LOG_API(isolate, "RangeError");
   5458   ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
   5459   ENTER_V8(isolate);
   5460   i::Object* error;
   5461   {
   5462     i::HandleScope scope(isolate);
   5463     i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
   5464     i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
   5465     error = *result;
   5466   }
   5467   i::Handle<i::Object> result(error);
   5468   return Utils::ToLocal(result);
   5469 }
   5470 
   5471 Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
   5472   i::Isolate* isolate = i::Isolate::Current();
   5473   LOG_API(isolate, "ReferenceError");
   5474   ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
   5475   ENTER_V8(isolate);
   5476   i::Object* error;
   5477   {
   5478     i::HandleScope scope(isolate);
   5479     i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
   5480     i::Handle<i::Object> result =
   5481         isolate->factory()->NewReferenceError(message);
   5482     error = *result;
   5483   }
   5484   i::Handle<i::Object> result(error);
   5485   return Utils::ToLocal(result);
   5486 }
   5487 
   5488 Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
   5489   i::Isolate* isolate = i::Isolate::Current();
   5490   LOG_API(isolate, "SyntaxError");
   5491   ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
   5492   ENTER_V8(isolate);
   5493   i::Object* error;
   5494   {
   5495     i::HandleScope scope(isolate);
   5496     i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
   5497     i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
   5498     error = *result;
   5499   }
   5500   i::Handle<i::Object> result(error);
   5501   return Utils::ToLocal(result);
   5502 }
   5503 
   5504 Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
   5505   i::Isolate* isolate = i::Isolate::Current();
   5506   LOG_API(isolate, "TypeError");
   5507   ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
   5508   ENTER_V8(isolate);
   5509   i::Object* error;
   5510   {
   5511     i::HandleScope scope(isolate);
   5512     i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
   5513     i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
   5514     error = *result;
   5515   }
   5516   i::Handle<i::Object> result(error);
   5517   return Utils::ToLocal(result);
   5518 }
   5519 
   5520 Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
   5521   i::Isolate* isolate = i::Isolate::Current();
   5522   LOG_API(isolate, "Error");
   5523   ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
   5524   ENTER_V8(isolate);
   5525   i::Object* error;
   5526   {
   5527     i::HandleScope scope(isolate);
   5528     i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
   5529     i::Handle<i::Object> result = isolate->factory()->NewError(message);
   5530     error = *result;
   5531   }
   5532   i::Handle<i::Object> result(error);
   5533   return Utils::ToLocal(result);
   5534 }
   5535 
   5536 
   5537 // --- D e b u g   S u p p o r t ---
   5538 
   5539 #ifdef ENABLE_DEBUGGER_SUPPORT
   5540 
   5541 static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
   5542   i::Isolate* isolate = i::Isolate::Current();
   5543   if (isolate->debug_event_callback() != NULL) {
   5544     isolate->debug_event_callback()(event_details.GetEvent(),
   5545                                     event_details.GetExecutionState(),
   5546                                     event_details.GetEventData(),
   5547                                     event_details.GetCallbackData());
   5548   }
   5549 }
   5550 
   5551 
   5552 bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
   5553   i::Isolate* isolate = i::Isolate::Current();
   5554   EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
   5555   ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
   5556   ENTER_V8(isolate);
   5557 
   5558   isolate->set_debug_event_callback(that);
   5559 
   5560   i::HandleScope scope(isolate);
   5561   i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
   5562   if (that != NULL) {
   5563     foreign =
   5564         isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
   5565   }
   5566   isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
   5567   return true;
   5568 }
   5569 
   5570 
   5571 bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
   5572   i::Isolate* isolate = i::Isolate::Current();
   5573   EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
   5574   ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
   5575   ENTER_V8(isolate);
   5576   i::HandleScope scope(isolate);
   5577   i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
   5578   if (that != NULL) {
   5579     foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
   5580   }
   5581   isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
   5582   return true;
   5583 }
   5584 
   5585 
   5586 bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
   5587                                   Handle<Value> data) {
   5588   i::Isolate* isolate = i::Isolate::Current();
   5589   ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
   5590   ENTER_V8(isolate);
   5591   isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
   5592                                                       Utils::OpenHandle(*data));
   5593   return true;
   5594 }
   5595 
   5596 
   5597 void Debug::DebugBreak(Isolate* isolate) {
   5598   // If no isolate is supplied, use the default isolate.
   5599   if (isolate != NULL) {
   5600     reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
   5601   } else {
   5602     i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
   5603   }
   5604 }
   5605 
   5606 
   5607 void Debug::CancelDebugBreak(Isolate* isolate) {
   5608   // If no isolate is supplied, use the default isolate.
   5609   if (isolate != NULL) {
   5610     i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
   5611     internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
   5612   } else {
   5613     i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
   5614   }
   5615 }
   5616 
   5617 
   5618 void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
   5619   // If no isolate is supplied, use the default isolate.
   5620   if (isolate != NULL) {
   5621     i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
   5622     internal_isolate->debugger()->EnqueueDebugCommand(data);
   5623   } else {
   5624     i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
   5625   }
   5626 }
   5627 
   5628 
   5629 static void MessageHandlerWrapper(const v8::Debug::Message& message) {
   5630   i::Isolate* isolate = i::Isolate::Current();
   5631   if (isolate->message_handler()) {
   5632     v8::String::Value json(message.GetJSON());
   5633     (isolate->message_handler())(*json, json.length(), message.GetClientData());
   5634   }
   5635 }
   5636 
   5637 
   5638 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
   5639                               bool message_handler_thread) {
   5640   i::Isolate* isolate = i::Isolate::Current();
   5641   EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
   5642   ENTER_V8(isolate);
   5643 
   5644   // Message handler thread not supported any more. Parameter temporally left in
   5645   // the API for client compatibility reasons.
   5646   CHECK(!message_handler_thread);
   5647 
   5648   // TODO(sgjesse) support the old message handler API through a simple wrapper.
   5649   isolate->set_message_handler(handler);
   5650   if (handler != NULL) {
   5651     isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
   5652   } else {
   5653     isolate->debugger()->SetMessageHandler(NULL);
   5654   }
   5655 }
   5656 
   5657 
   5658 void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
   5659   i::Isolate* isolate = i::Isolate::Current();
   5660   EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
   5661   ENTER_V8(isolate);
   5662   isolate->debugger()->SetMessageHandler(handler);
   5663 }
   5664 
   5665 
   5666 void Debug::SendCommand(const uint16_t* command, int length,
   5667                         ClientData* client_data,
   5668                         Isolate* isolate) {
   5669   // If no isolate is supplied, use the default isolate.
   5670   if (isolate != NULL) {
   5671     i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
   5672     internal_isolate->debugger()->ProcessCommand(
   5673         i::Vector<const uint16_t>(command, length), client_data);
   5674   } else {
   5675     i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
   5676         i::Vector<const uint16_t>(command, length), client_data);
   5677   }
   5678 }
   5679 
   5680 
   5681 void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
   5682                                    int period) {
   5683   i::Isolate* isolate = i::Isolate::Current();
   5684   EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
   5685   ENTER_V8(isolate);
   5686   isolate->debugger()->SetHostDispatchHandler(handler, period);
   5687 }
   5688 
   5689 
   5690 void Debug::SetDebugMessageDispatchHandler(
   5691     DebugMessageDispatchHandler handler, bool provide_locker) {
   5692   i::Isolate* isolate = i::Isolate::Current();
   5693   EnsureInitializedForIsolate(isolate,
   5694                               "v8::Debug::SetDebugMessageDispatchHandler");
   5695   ENTER_V8(isolate);
   5696   isolate->debugger()->SetDebugMessageDispatchHandler(
   5697       handler, provide_locker);
   5698 }
   5699 
   5700 
   5701 Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
   5702                          v8::Handle<v8::Value> data) {
   5703   i::Isolate* isolate = i::Isolate::Current();
   5704   if (!isolate->IsInitialized()) return Local<Value>();
   5705   ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
   5706   ENTER_V8(isolate);
   5707   i::Handle<i::Object> result;
   5708   EXCEPTION_PREAMBLE(isolate);
   5709   if (data.IsEmpty()) {
   5710     result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
   5711                                        isolate->factory()->undefined_value(),
   5712                                        &has_pending_exception);
   5713   } else {
   5714     result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
   5715                                        Utils::OpenHandle(*data),
   5716                                        &has_pending_exception);
   5717   }
   5718   EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   5719   return Utils::ToLocal(result);
   5720 }
   5721 
   5722 
   5723 Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
   5724   i::Isolate* isolate = i::Isolate::Current();
   5725   if (!isolate->IsInitialized()) return Local<Value>();
   5726   ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
   5727   ENTER_V8(isolate);
   5728   v8::HandleScope scope;
   5729   i::Debug* isolate_debug = isolate->debug();
   5730   isolate_debug->Load();
   5731   i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
   5732   i::Handle<i::String> name =
   5733       isolate->factory()->LookupAsciiSymbol("MakeMirror");
   5734   i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
   5735   i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
   5736   v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
   5737   const int kArgc = 1;
   5738   v8::Handle<v8::Value> argv[kArgc] = { obj };
   5739   EXCEPTION_PREAMBLE(isolate);
   5740   v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
   5741                                               kArgc,
   5742                                               argv);
   5743   EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   5744   return scope.Close(result);
   5745 }
   5746 
   5747 
   5748 bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
   5749   return i::Isolate::Current()->debugger()->StartAgent(name, port,
   5750                                                        wait_for_connection);
   5751 }
   5752 
   5753 
   5754 void Debug::DisableAgent() {
   5755   return i::Isolate::Current()->debugger()->StopAgent();
   5756 }
   5757 
   5758 
   5759 void Debug::ProcessDebugMessages() {
   5760   i::Execution::ProcessDebugMessages(true);
   5761 }
   5762 
   5763 Local<Context> Debug::GetDebugContext() {
   5764   i::Isolate* isolate = i::Isolate::Current();
   5765   EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
   5766   ENTER_V8(isolate);
   5767   return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
   5768 }
   5769 
   5770 #endif  // ENABLE_DEBUGGER_SUPPORT
   5771 
   5772 
   5773 Handle<String> CpuProfileNode::GetFunctionName() const {
   5774   i::Isolate* isolate = i::Isolate::Current();
   5775   IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
   5776   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
   5777   const i::CodeEntry* entry = node->entry();
   5778   if (!entry->has_name_prefix()) {
   5779     return Handle<String>(ToApi<String>(
   5780         isolate->factory()->LookupAsciiSymbol(entry->name())));
   5781   } else {
   5782     return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
   5783         isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
   5784         isolate->factory()->LookupAsciiSymbol(entry->name()))));
   5785   }
   5786 }
   5787 
   5788 
   5789 Handle<String> CpuProfileNode::GetScriptResourceName() const {
   5790   i::Isolate* isolate = i::Isolate::Current();
   5791   IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
   5792   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
   5793   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
   5794       node->entry()->resource_name())));
   5795 }
   5796 
   5797 
   5798 int CpuProfileNode::GetLineNumber() const {
   5799   i::Isolate* isolate = i::Isolate::Current();
   5800   IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
   5801   return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
   5802 }
   5803 
   5804 
   5805 double CpuProfileNode::GetTotalTime() const {
   5806   i::Isolate* isolate = i::Isolate::Current();
   5807   IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
   5808   return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
   5809 }
   5810 
   5811 
   5812 double CpuProfileNode::GetSelfTime() const {
   5813   i::Isolate* isolate = i::Isolate::Current();
   5814   IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
   5815   return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
   5816 }
   5817 
   5818 
   5819 double CpuProfileNode::GetTotalSamplesCount() const {
   5820   i::Isolate* isolate = i::Isolate::Current();
   5821   IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
   5822   return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
   5823 }
   5824 
   5825 
   5826 double CpuProfileNode::GetSelfSamplesCount() const {
   5827   i::Isolate* isolate = i::Isolate::Current();
   5828   IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
   5829   return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
   5830 }
   5831 
   5832 
   5833 unsigned CpuProfileNode::GetCallUid() const {
   5834   i::Isolate* isolate = i::Isolate::Current();
   5835   IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
   5836   return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
   5837 }
   5838 
   5839 
   5840 int CpuProfileNode::GetChildrenCount() const {
   5841   i::Isolate* isolate = i::Isolate::Current();
   5842   IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
   5843   return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
   5844 }
   5845 
   5846 
   5847 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
   5848   i::Isolate* isolate = i::Isolate::Current();
   5849   IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
   5850   const i::ProfileNode* child =
   5851       reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
   5852   return reinterpret_cast<const CpuProfileNode*>(child);
   5853 }
   5854 
   5855 
   5856 void CpuProfile::Delete() {
   5857   i::Isolate* isolate = i::Isolate::Current();
   5858   IsDeadCheck(isolate, "v8::CpuProfile::Delete");
   5859   i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
   5860   if (i::CpuProfiler::GetProfilesCount() == 0 &&
   5861       !i::CpuProfiler::HasDetachedProfiles()) {
   5862     // If this was the last profile, clean up all accessory data as well.
   5863     i::CpuProfiler::DeleteAllProfiles();
   5864   }
   5865 }
   5866 
   5867 
   5868 unsigned CpuProfile::GetUid() const {
   5869   i::Isolate* isolate = i::Isolate::Current();
   5870   IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
   5871   return reinterpret_cast<const i::CpuProfile*>(this)->uid();
   5872 }
   5873 
   5874 
   5875 Handle<String> CpuProfile::GetTitle() const {
   5876   i::Isolate* isolate = i::Isolate::Current();
   5877   IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
   5878   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
   5879   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
   5880       profile->title())));
   5881 }
   5882 
   5883 
   5884 const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
   5885   i::Isolate* isolate = i::Isolate::Current();
   5886   IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
   5887   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
   5888   return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
   5889 }
   5890 
   5891 
   5892 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
   5893   i::Isolate* isolate = i::Isolate::Current();
   5894   IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
   5895   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
   5896   return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
   5897 }
   5898 
   5899 
   5900 int CpuProfiler::GetProfilesCount() {
   5901   i::Isolate* isolate = i::Isolate::Current();
   5902   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
   5903   return i::CpuProfiler::GetProfilesCount();
   5904 }
   5905 
   5906 
   5907 const CpuProfile* CpuProfiler::GetProfile(int index,
   5908                                           Handle<Value> security_token) {
   5909   i::Isolate* isolate = i::Isolate::Current();
   5910   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
   5911   return reinterpret_cast<const CpuProfile*>(
   5912       i::CpuProfiler::GetProfile(
   5913           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
   5914           index));
   5915 }
   5916 
   5917 
   5918 const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
   5919                                            Handle<Value> security_token) {
   5920   i::Isolate* isolate = i::Isolate::Current();
   5921   IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
   5922   return reinterpret_cast<const CpuProfile*>(
   5923       i::CpuProfiler::FindProfile(
   5924           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
   5925           uid));
   5926 }
   5927 
   5928 
   5929 void CpuProfiler::StartProfiling(Handle<String> title) {
   5930   i::Isolate* isolate = i::Isolate::Current();
   5931   IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
   5932   i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
   5933 }
   5934 
   5935 
   5936 const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
   5937                                              Handle<Value> security_token) {
   5938   i::Isolate* isolate = i::Isolate::Current();
   5939   IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
   5940   return reinterpret_cast<const CpuProfile*>(
   5941       i::CpuProfiler::StopProfiling(
   5942           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
   5943           *Utils::OpenHandle(*title)));
   5944 }
   5945 
   5946 
   5947 void CpuProfiler::DeleteAllProfiles() {
   5948   i::Isolate* isolate = i::Isolate::Current();
   5949   IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
   5950   i::CpuProfiler::DeleteAllProfiles();
   5951 }
   5952 
   5953 
   5954 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
   5955   return const_cast<i::HeapGraphEdge*>(
   5956       reinterpret_cast<const i::HeapGraphEdge*>(edge));
   5957 }
   5958 
   5959 
   5960 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
   5961   i::Isolate* isolate = i::Isolate::Current();
   5962   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
   5963   return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
   5964 }
   5965 
   5966 
   5967 Handle<Value> HeapGraphEdge::GetName() const {
   5968   i::Isolate* isolate = i::Isolate::Current();
   5969   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
   5970   i::HeapGraphEdge* edge = ToInternal(this);
   5971   switch (edge->type()) {
   5972     case i::HeapGraphEdge::kContextVariable:
   5973     case i::HeapGraphEdge::kInternal:
   5974     case i::HeapGraphEdge::kProperty:
   5975     case i::HeapGraphEdge::kShortcut:
   5976       return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
   5977           edge->name())));
   5978     case i::HeapGraphEdge::kElement:
   5979     case i::HeapGraphEdge::kHidden:
   5980       return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
   5981           edge->index())));
   5982     default: UNREACHABLE();
   5983   }
   5984   return v8::Undefined();
   5985 }
   5986 
   5987 
   5988 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
   5989   i::Isolate* isolate = i::Isolate::Current();
   5990   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
   5991   const i::HeapEntry* from = ToInternal(this)->From();
   5992   return reinterpret_cast<const HeapGraphNode*>(from);
   5993 }
   5994 
   5995 
   5996 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
   5997   i::Isolate* isolate = i::Isolate::Current();
   5998   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
   5999   const i::HeapEntry* to = ToInternal(this)->to();
   6000   return reinterpret_cast<const HeapGraphNode*>(to);
   6001 }
   6002 
   6003 
   6004 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
   6005   return const_cast<i::HeapEntry*>(
   6006       reinterpret_cast<const i::HeapEntry*>(entry));
   6007 }
   6008 
   6009 
   6010 HeapGraphNode::Type HeapGraphNode::GetType() const {
   6011   i::Isolate* isolate = i::Isolate::Current();
   6012   IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
   6013   return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
   6014 }
   6015 
   6016 
   6017 Handle<String> HeapGraphNode::GetName() const {
   6018   i::Isolate* isolate = i::Isolate::Current();
   6019   IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
   6020   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
   6021       ToInternal(this)->name())));
   6022 }
   6023 
   6024 
   6025 uint64_t HeapGraphNode::GetId() const {
   6026   i::Isolate* isolate = i::Isolate::Current();
   6027   IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
   6028   return ToInternal(this)->id();
   6029 }
   6030 
   6031 
   6032 int HeapGraphNode::GetSelfSize() const {
   6033   i::Isolate* isolate = i::Isolate::Current();
   6034   IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
   6035   return ToInternal(this)->self_size();
   6036 }
   6037 
   6038 
   6039 int HeapGraphNode::GetRetainedSize() const {
   6040   i::Isolate* isolate = i::Isolate::Current();
   6041   IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
   6042   return ToInternal(this)->retained_size();
   6043 }
   6044 
   6045 
   6046 int HeapGraphNode::GetChildrenCount() const {
   6047   i::Isolate* isolate = i::Isolate::Current();
   6048   IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
   6049   return ToInternal(this)->children().length();
   6050 }
   6051 
   6052 
   6053 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
   6054   i::Isolate* isolate = i::Isolate::Current();
   6055   IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
   6056   return reinterpret_cast<const HeapGraphEdge*>(
   6057       &ToInternal(this)->children()[index]);
   6058 }
   6059 
   6060 
   6061 int HeapGraphNode::GetRetainersCount() const {
   6062   i::Isolate* isolate = i::Isolate::Current();
   6063   IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
   6064   return ToInternal(this)->retainers().length();
   6065 }
   6066 
   6067 
   6068 const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
   6069   i::Isolate* isolate = i::Isolate::Current();
   6070   IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
   6071   return reinterpret_cast<const HeapGraphEdge*>(
   6072       ToInternal(this)->retainers()[index]);
   6073 }
   6074 
   6075 
   6076 const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
   6077   i::Isolate* isolate = i::Isolate::Current();
   6078   IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
   6079   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
   6080 }
   6081 
   6082 
   6083 v8::Handle<v8::Value> HeapGraphNode::GetHeapValue() const {
   6084   i::Isolate* isolate = i::Isolate::Current();
   6085   IsDeadCheck(isolate, "v8::HeapGraphNode::GetHeapValue");
   6086   i::Handle<i::HeapObject> object = ToInternal(this)->GetHeapObject();
   6087   return v8::Handle<Value>(!object.is_null() ?
   6088                            ToApi<Value>(object) : ToApi<Value>(
   6089                                isolate->factory()->undefined_value()));
   6090 }
   6091 
   6092 
   6093 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
   6094   return const_cast<i::HeapSnapshot*>(
   6095       reinterpret_cast<const i::HeapSnapshot*>(snapshot));
   6096 }
   6097 
   6098 
   6099 void HeapSnapshot::Delete() {
   6100   i::Isolate* isolate = i::Isolate::Current();
   6101   IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
   6102   if (i::HeapProfiler::GetSnapshotsCount() > 1) {
   6103     ToInternal(this)->Delete();
   6104   } else {
   6105     // If this is the last snapshot, clean up all accessory data as well.
   6106     i::HeapProfiler::DeleteAllSnapshots();
   6107   }
   6108 }
   6109 
   6110 
   6111 HeapSnapshot::Type HeapSnapshot::GetType() const {
   6112   i::Isolate* isolate = i::Isolate::Current();
   6113   IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
   6114   return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
   6115 }
   6116 
   6117 
   6118 unsigned HeapSnapshot::GetUid() const {
   6119   i::Isolate* isolate = i::Isolate::Current();
   6120   IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
   6121   return ToInternal(this)->uid();
   6122 }
   6123 
   6124 
   6125 Handle<String> HeapSnapshot::GetTitle() const {
   6126   i::Isolate* isolate = i::Isolate::Current();
   6127   IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
   6128   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
   6129       ToInternal(this)->title())));
   6130 }
   6131 
   6132 
   6133 const HeapGraphNode* HeapSnapshot::GetRoot() const {
   6134   i::Isolate* isolate = i::Isolate::Current();
   6135   IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
   6136   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
   6137 }
   6138 
   6139 
   6140 const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
   6141   i::Isolate* isolate = i::Isolate::Current();
   6142   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
   6143   return reinterpret_cast<const HeapGraphNode*>(
   6144       ToInternal(this)->GetEntryById(static_cast<i::SnapshotObjectId>(id)));
   6145 }
   6146 
   6147 
   6148 int HeapSnapshot::GetNodesCount() const {
   6149   i::Isolate* isolate = i::Isolate::Current();
   6150   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
   6151   return ToInternal(this)->entries()->length();
   6152 }
   6153 
   6154 
   6155 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
   6156   i::Isolate* isolate = i::Isolate::Current();
   6157   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
   6158   return reinterpret_cast<const HeapGraphNode*>(
   6159       ToInternal(this)->entries()->at(index));
   6160 }
   6161 
   6162 
   6163 void HeapSnapshot::Serialize(OutputStream* stream,
   6164                              HeapSnapshot::SerializationFormat format) const {
   6165   i::Isolate* isolate = i::Isolate::Current();
   6166   IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
   6167   ApiCheck(format == kJSON,
   6168            "v8::HeapSnapshot::Serialize",
   6169            "Unknown serialization format");
   6170   ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
   6171            "v8::HeapSnapshot::Serialize",
   6172            "Unsupported output encoding");
   6173   ApiCheck(stream->GetChunkSize() > 0,
   6174            "v8::HeapSnapshot::Serialize",
   6175            "Invalid stream chunk size");
   6176   i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
   6177   serializer.Serialize(stream);
   6178 }
   6179 
   6180 
   6181 int HeapProfiler::GetSnapshotsCount() {
   6182   i::Isolate* isolate = i::Isolate::Current();
   6183   IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
   6184   return i::HeapProfiler::GetSnapshotsCount();
   6185 }
   6186 
   6187 
   6188 const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
   6189   i::Isolate* isolate = i::Isolate::Current();
   6190   IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
   6191   return reinterpret_cast<const HeapSnapshot*>(
   6192       i::HeapProfiler::GetSnapshot(index));
   6193 }
   6194 
   6195 
   6196 const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
   6197   i::Isolate* isolate = i::Isolate::Current();
   6198   IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
   6199   return reinterpret_cast<const HeapSnapshot*>(
   6200       i::HeapProfiler::FindSnapshot(uid));
   6201 }
   6202 
   6203 
   6204 const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
   6205                                                HeapSnapshot::Type type,
   6206                                                ActivityControl* control) {
   6207   i::Isolate* isolate = i::Isolate::Current();
   6208   IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
   6209   i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
   6210   switch (type) {
   6211     case HeapSnapshot::kFull:
   6212       internal_type = i::HeapSnapshot::kFull;
   6213       break;
   6214     default:
   6215       UNREACHABLE();
   6216   }
   6217   return reinterpret_cast<const HeapSnapshot*>(
   6218       i::HeapProfiler::TakeSnapshot(
   6219           *Utils::OpenHandle(*title), internal_type, control));
   6220 }
   6221 
   6222 
   6223 void HeapProfiler::DeleteAllSnapshots() {
   6224   i::Isolate* isolate = i::Isolate::Current();
   6225   IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
   6226   i::HeapProfiler::DeleteAllSnapshots();
   6227 }
   6228 
   6229 
   6230 void HeapProfiler::DefineWrapperClass(uint16_t class_id,
   6231                                       WrapperInfoCallback callback) {
   6232   i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
   6233                                                              callback);
   6234 }
   6235 
   6236 
   6237 int HeapProfiler::GetPersistentHandleCount() {
   6238   i::Isolate* isolate = i::Isolate::Current();
   6239   return isolate->global_handles()->NumberOfGlobalHandles();
   6240 }
   6241 
   6242 
   6243 v8::Testing::StressType internal::Testing::stress_type_ =
   6244     v8::Testing::kStressTypeOpt;
   6245 
   6246 
   6247 void Testing::SetStressRunType(Testing::StressType type) {
   6248   internal::Testing::set_stress_type(type);
   6249 }
   6250 
   6251 int Testing::GetStressRuns() {
   6252   if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
   6253 #ifdef DEBUG
   6254   // In debug mode the code runs much slower so stressing will only make two
   6255   // runs.
   6256   return 2;
   6257 #else
   6258   return 5;
   6259 #endif
   6260 }
   6261 
   6262 
   6263 static void SetFlagsFromString(const char* flags) {
   6264   V8::SetFlagsFromString(flags, i::StrLength(flags));
   6265 }
   6266 
   6267 
   6268 void Testing::PrepareStressRun(int run) {
   6269   static const char* kLazyOptimizations =
   6270       "--prepare-always-opt --nolimit-inlining --noalways-opt";
   6271   static const char* kForcedOptimizations = "--always-opt";
   6272 
   6273   // If deoptimization stressed turn on frequent deoptimization. If no value
   6274   // is spefified through --deopt-every-n-times use a default default value.
   6275   static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
   6276   if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
   6277       internal::FLAG_deopt_every_n_times == 0) {
   6278     SetFlagsFromString(kDeoptEvery13Times);
   6279   }
   6280 
   6281 #ifdef DEBUG
   6282   // As stressing in debug mode only make two runs skip the deopt stressing
   6283   // here.
   6284   if (run == GetStressRuns() - 1) {
   6285     SetFlagsFromString(kForcedOptimizations);
   6286   } else {
   6287     SetFlagsFromString(kLazyOptimizations);
   6288   }
   6289 #else
   6290   if (run == GetStressRuns() - 1) {
   6291     SetFlagsFromString(kForcedOptimizations);
   6292   } else if (run != GetStressRuns() - 2) {
   6293     SetFlagsFromString(kLazyOptimizations);
   6294   }
   6295 #endif
   6296 }
   6297 
   6298 
   6299 void Testing::DeoptimizeAll() {
   6300   internal::Deoptimizer::DeoptimizeAll();
   6301 }
   6302 
   6303 
   6304 namespace internal {
   6305 
   6306 
   6307 void HandleScopeImplementer::FreeThreadResources() {
   6308   Free();
   6309 }
   6310 
   6311 
   6312 char* HandleScopeImplementer::ArchiveThread(char* storage) {
   6313   v8::ImplementationUtilities::HandleScopeData* current =
   6314       isolate_->handle_scope_data();
   6315   handle_scope_data_ = *current;
   6316   memcpy(storage, this, sizeof(*this));
   6317 
   6318   ResetAfterArchive();
   6319   current->Initialize();
   6320 
   6321   return storage + ArchiveSpacePerThread();
   6322 }
   6323 
   6324 
   6325 int HandleScopeImplementer::ArchiveSpacePerThread() {
   6326   return sizeof(HandleScopeImplementer);
   6327 }
   6328 
   6329 
   6330 char* HandleScopeImplementer::RestoreThread(char* storage) {
   6331   memcpy(this, storage, sizeof(*this));
   6332   *isolate_->handle_scope_data() = handle_scope_data_;
   6333   return storage + ArchiveSpacePerThread();
   6334 }
   6335 
   6336 
   6337 void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
   6338   // Iterate over all handles in the blocks except for the last.
   6339   for (int i = blocks()->length() - 2; i >= 0; --i) {
   6340     Object** block = blocks()->at(i);
   6341     v->VisitPointers(block, &block[kHandleBlockSize]);
   6342   }
   6343 
   6344   // Iterate over live handles in the last block (if any).
   6345   if (!blocks()->is_empty()) {
   6346     v->VisitPointers(blocks()->last(), handle_scope_data_.next);
   6347   }
   6348 
   6349   if (!saved_contexts_.is_empty()) {
   6350     Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
   6351     v->VisitPointers(start, start + saved_contexts_.length());
   6352   }
   6353 }
   6354 
   6355 
   6356 void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
   6357   v8::ImplementationUtilities::HandleScopeData* current =
   6358       isolate_->handle_scope_data();
   6359   handle_scope_data_ = *current;
   6360   IterateThis(v);
   6361 }
   6362 
   6363 
   6364 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
   6365   HandleScopeImplementer* scope_implementer =
   6366       reinterpret_cast<HandleScopeImplementer*>(storage);
   6367   scope_implementer->IterateThis(v);
   6368   return storage + ArchiveSpacePerThread();
   6369 }
   6370 
   6371 } }  // namespace v8::internal
   6372