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