• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DefaultFatalErrorHandler(const char * location,const char * message)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 
GetFatalErrorHandler()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 
FatalProcessOutOfMemory(const char * location)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.
FatalProcessOutOfMemory(const char * location,bool take_snapshot)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 
ReportApiFailure(const char * location,const char * message)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 
IsDead()215 bool V8::IsDead() {
216   return i::V8::IsDead();
217 }
218 
219 
ApiCheck(bool condition,const char * location,const char * message)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 
ReportV8Dead(const char * location)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 
ReportEmptyHandle(const char * location)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  */
IsDeadCheck(i::Isolate * isolate,const char * location)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 
IsExecutionTerminatingCheck(i::Isolate * isolate)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 
EmptyCheck(const char * location,v8::Handle<v8::Data> obj)269 static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
270   return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
271 }
272 
273 
EmptyCheck(const char * location,const v8::Data * obj)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 
InitializeHelper()281 static bool InitializeHelper() {
282   if (i::Snapshot::Initialize()) return true;
283   return i::V8::Initialize(NULL);
284 }
285 
286 
EnsureInitializedForIsolate(i::Isolate * isolate,const char * location)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.
EnterIsolateIfNeeded()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 
SetFatalErrorHandler(FatalErrorCallback that)314 void V8::SetFatalErrorHandler(FatalErrorCallback that) {
315   i::Isolate* isolate = EnterIsolateIfNeeded();
316   isolate->set_exception_behavior(that);
317 }
318 
319 
320 #ifdef DEBUG
ZapHandleRange(i::Object ** begin,i::Object ** end)321 void ImplementationUtilities::ZapHandleRange(i::Object** begin,
322                                              i::Object** end) {
323   i::HandleScope::ZapRange(begin, end);
324 }
325 #endif
326 
327 
SetFlagsFromString(const char * str,int length)328 void V8::SetFlagsFromString(const char* str, int length) {
329   i::FlagList::SetFlagsFromString(str, length);
330 }
331 
332 
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)333 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
334   i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
335 }
336 
337 
ThrowException(v8::Handle<v8::Value> value)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 
RegisteredExtension(Extension * extension)358 RegisteredExtension::RegisteredExtension(Extension* extension)
359     : extension_(extension), state_(UNVISITED) { }
360 
361 
Register(RegisteredExtension * that)362 void RegisteredExtension::Register(RegisteredExtension* that) {
363   that->next_ = first_extension_;
364   first_extension_ = that;
365 }
366 
367 
RegisterExtension(Extension * that)368 void RegisterExtension(Extension* that) {
369   RegisteredExtension* extension = new RegisteredExtension(that);
370   RegisteredExtension::Register(extension);
371 }
372 
373 
Extension(const char * name,const char * source,int dep_count,const char ** deps)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 
Undefined()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 
Null()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 
True()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 
False()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 
ResourceConstraints()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 
SetResourceConstraints(ResourceConstraints * constraints)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 
GlobalizeReference(i::Object ** obj)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 
MakeWeak(i::Object ** object,void * parameters,WeakReferenceCallback callback)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 
ClearWeak(i::Object ** obj)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 
IsGlobalNearDeath(i::Object ** obj)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 
IsGlobalWeak(i::Object ** obj)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 
DisposeGlobal(i::Object ** obj)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 
HandleScope()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 
~HandleScope()519 HandleScope::~HandleScope() {
520   if (!is_closed_) {
521     Leave();
522   }
523 }
524 
525 
Leave()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 
NumberOfHandles()544 int HandleScope::NumberOfHandles() {
545   EnsureInitializedForIsolate(
546       i::Isolate::Current(), "HandleScope::NumberOfHandles");
547   return i::HandleScope::NumberOfHandles();
548 }
549 
550 
CreateHandle(i::Object * value)551 i::Object** HandleScope::CreateHandle(i::Object* value) {
552   return i::HandleScope::CreateHandle(value, i::Isolate::Current());
553 }
554 
555 
CreateHandle(i::HeapObject * value)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 
Enter()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 
Exit()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 
SetData(v8::Handle<String> data)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 
GetData()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 
RawClose(i::Object ** value)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.
NeanderObject(int size)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 
size()679 int NeanderObject::size() {
680   return i::FixedArray::cast(value_->elements())->length();
681 }
682 
683 
NeanderArray()684 NeanderArray::NeanderArray() : obj_(2) {
685   obj_.set(0, i::Smi::FromInt(0));
686 }
687 
688 
length()689 int NeanderArray::length() {
690   return i::Smi::cast(obj_.get(0))->value();
691 }
692 
693 
get(int offset)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.
add(i::Handle<i::Object> value)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 
set(int index,i::Object * value)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 
InitializeTemplate(i::Handle<i::TemplateInfo> that,int type)729 static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
730   that->set_tag(i::Smi::FromInt(type));
731 }
732 
733 
Set(v8::Handle<String> name,v8::Handle<Data> value,v8::PropertyAttribute attribute)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 ---
InitializeFunctionTemplate(i::Handle<i::FunctionTemplateInfo> info)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 
PrototypeTemplate()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 
Inherit(v8::Handle<FunctionTemplate> value)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 
New(InvocationCallback callback,v8::Handle<Value> data,v8::Handle<Signature> signature)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 
New(Handle<FunctionTemplate> receiver,int argc,Handle<FunctionTemplate> argv[])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 
New(Handle<FunctionTemplate> type)833 Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
834   Handle<FunctionTemplate> types[1] = { type };
835   return TypeSwitch::New(1, types);
836 }
837 
838 
New(int argc,Handle<FunctionTemplate> types[])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 
match(v8::Handle<Value> value)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 
SetCallHandler(InvocationCallback callback,v8::Handle<Value> data)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 
MakeAccessorInfo(v8::Handle<String> name,AccessorGetter getter,AccessorSetter setter,v8::Handle<Value> data,v8::AccessControl settings,v8::PropertyAttribute attributes)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 
AddInstancePropertyAccessor(v8::Handle<String> name,AccessorGetter getter,AccessorSetter setter,v8::Handle<Value> data,v8::AccessControl settings,v8::PropertyAttribute attributes)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 
InstanceTemplate()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 
SetClassName(Handle<String> name)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 
SetHiddenPrototype(bool value)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 
SetNamedInstancePropertyHandler(NamedPropertyGetter getter,NamedPropertySetter setter,NamedPropertyQuery query,NamedPropertyDeleter remover,NamedPropertyEnumerator enumerator,Handle<Value> data)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 
SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter,IndexedPropertySetter setter,IndexedPropertyQuery query,IndexedPropertyDeleter remover,IndexedPropertyEnumerator enumerator,Handle<Value> data)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 
SetInstanceCallAsFunctionHandler(InvocationCallback callback,Handle<Value> data)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 
New()1064 Local<ObjectTemplate> ObjectTemplate::New() {
1065   return New(Local<FunctionTemplate>());
1066 }
1067 
1068 
New(v8::Handle<FunctionTemplate> constructor)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.
EnsureConstructor(ObjectTemplate * object_template)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 
SetAccessor(v8::Handle<String> name,AccessorGetter getter,AccessorSetter setter,v8::Handle<Value> data,AccessControl settings,PropertyAttribute attribute)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 
SetNamedPropertyHandler(NamedPropertyGetter getter,NamedPropertySetter setter,NamedPropertyQuery query,NamedPropertyDeleter remover,NamedPropertyEnumerator enumerator,Handle<Value> data)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 
MarkAsUndetectable()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 
SetAccessCheckCallbacks(NamedSecurityCallback named_callback,IndexedSecurityCallback indexed_callback,Handle<Value> data,bool turned_on_by_default)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 
SetIndexedPropertyHandler(IndexedPropertyGetter getter,IndexedPropertySetter setter,IndexedPropertyQuery query,IndexedPropertyDeleter remover,IndexedPropertyEnumerator enumerator,Handle<Value> data)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 
SetCallAsFunctionHandler(InvocationCallback callback,Handle<Value> data)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 
InternalFieldCount()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 
SetInternalFieldCount(int value)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 
PreCompile(const char * input,int length)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 
PreCompile(v8::Handle<String> source)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 
New(const char * data,int length)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 
New(v8::Handle<String> source,v8::ScriptOrigin * origin,v8::ScriptData * pre_data,v8::Handle<String> script_data)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 
New(v8::Handle<String> source,v8::Handle<Value> file_name)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 
Compile(v8::Handle<String> source,v8::ScriptOrigin * origin,v8::ScriptData * pre_data,v8::Handle<String> script_data)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 
Compile(v8::Handle<String> source,v8::Handle<Value> file_name,v8::Handle<String> script_data)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 
Run()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 
OpenScript(Script * script)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 
Id()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 
SetData(v8::Handle<String> data)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 
TryCatch()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 
~TryCatch()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 
HasCaught() const1503 bool v8::TryCatch::HasCaught() const {
1504   return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1505 }
1506 
1507 
CanContinue() const1508 bool v8::TryCatch::CanContinue() const {
1509   return can_continue_;
1510 }
1511 
1512 
ReThrow()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 
Exception() const1520 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 
StackTrace() const1531 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 
Message() const1547 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 
Reset()1557 void v8::TryCatch::Reset() {
1558   exception_ = HEAP->the_hole_value();
1559   message_ = i::Smi::FromInt(0);
1560 }
1561 
1562 
SetVerbose(bool value)1563 void v8::TryCatch::SetVerbose(bool value) {
1564   is_verbose_ = value;
1565 }
1566 
1567 
SetCaptureMessage(bool value)1568 void v8::TryCatch::SetCaptureMessage(bool value) {
1569   capture_message_ = value;
1570 }
1571 
1572 
1573 // --- M e s s a g e ---
1574 
1575 
Get() const1576 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 
GetScriptResourceName() const1588 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 
GetScriptData() const1605 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 
GetStackTrace() const1622 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 
CallV8HeapFunction(const char * name,i::Handle<i::Object> recv,int argc,i::Object ** argv[],bool * has_pending_exception)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 
CallV8HeapFunction(const char * name,i::Handle<i::Object> data,bool * has_pending_exception)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 
GetLineNumber() const1668 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 
GetStartPosition() const1683 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 
GetEndPosition() const1694 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 
GetStartColumn() const1705 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 
GetEndColumn() const1723 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 
GetSourceLine() const1743 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 
PrintCurrentStackTrace(FILE * out)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 
GetFrame(uint32_t index) const1771 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 
GetFrameCount() const1785 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 
AsArray()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 
CurrentStackTrace(int frame_limit,StackTraceOptions options)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 
GetLineNumber() const1816 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 
GetColumn() const1832 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 
GetScriptName() const1848 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 
GetScriptNameOrSourceURL() const1864 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 
GetFunctionName() const1880 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 
IsEval() const1896 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 
IsConstructor() const1907 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 
IsUndefined() const1920 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 
IsNull() const1928 bool Value::IsNull() const {
1929   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
1930   return Utils::OpenHandle(this)->IsNull();
1931 }
1932 
1933 
IsTrue() const1934 bool Value::IsTrue() const {
1935   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
1936   return Utils::OpenHandle(this)->IsTrue();
1937 }
1938 
1939 
IsFalse() const1940 bool Value::IsFalse() const {
1941   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
1942   return Utils::OpenHandle(this)->IsFalse();
1943 }
1944 
1945 
IsFunction() const1946 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 
FullIsString() const1954 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 
IsArray() const1962 bool Value::IsArray() const {
1963   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
1964   return Utils::OpenHandle(this)->IsJSArray();
1965 }
1966 
1967 
IsObject() const1968 bool Value::IsObject() const {
1969   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
1970   return Utils::OpenHandle(this)->IsJSObject();
1971 }
1972 
1973 
IsNumber() const1974 bool Value::IsNumber() const {
1975   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
1976   return Utils::OpenHandle(this)->IsNumber();
1977 }
1978 
1979 
IsBoolean() const1980 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 
IsExternal() const1988 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 
IsInt32() const1996 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 
IsUint32() const2008 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 
IsDate() const2020 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 
IsRegExp() const2028 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 
ToString() const2035 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 
ToDetailString() const2055 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 
ToObject() const2075 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 
ToBoolean() const2095 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 
ToNumber() const2112 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 
ToInteger() const2132 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 
CheckCast(v8::Value * that)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 
CheckCast(Value * that)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 
CheckCast(Value * that)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 
CheckCast(v8::Value * that)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 
CheckCast(v8::Value * that)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 
CheckCast(v8::Value * that)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 
CheckCast(Value * that)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 
CheckCast(v8::Value * that)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 
CheckCast(v8::Value * that)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 
BooleanValue() const2232 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 
NumberValue() const2247 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 
IntegerValue() const2267 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 
ToInt32() const2289 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 
ToUint32() const2307 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 
ToArrayIndex() const2325 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 
Int32Value() const2354 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 
Equals(Handle<Value> that) const2376 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 
StrictEquals(Handle<Value> that) const2402 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 
Uint32Value() const2434 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 
Set(v8::Handle<Value> key,v8::Handle<Value> value,v8::PropertyAttribute attribs)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 
Set(uint32_t index,v8::Handle<Value> value)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 
ForceSet(v8::Handle<Value> key,v8::Handle<Value> value,v8::PropertyAttribute attribs)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 
ForceDelete(v8::Handle<Value> key)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 
Get(v8::Handle<Value> key)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 
Get(uint32_t index)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 
GetPrototype()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 
SetPrototype(Handle<Value> value)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 
FindInstanceInPrototypeChain(v8::Handle<FunctionTemplate> tmpl)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 
GetPropertyNames()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 
ObjectProtoToString()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 
GetConstructorName()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 
Delete(v8::Handle<String> key)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 
Has(v8::Handle<String> key)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 
Delete(uint32_t index)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 
Has(uint32_t index)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 
SetAccessor(Handle<String> name,AccessorGetter getter,AccessorSetter setter,v8::Handle<Value> data,AccessControl settings,PropertyAttribute attributes)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 
HasRealNamedProperty(Handle<String> key)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 
HasRealIndexedProperty(uint32_t index)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 
HasRealNamedCallbackProperty(Handle<String> key)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 
HasNamedLookupInterceptor()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 
HasIndexedLookupInterceptor()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 
GetPropertyByLookup(i::Isolate * isolate,i::Handle<i::JSObject> receiver,i::Handle<i::String> name,i::LookupResult * lookup)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 
GetRealNamedPropertyInPrototypeChain(Handle<String> key)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 
GetRealNamedProperty(Handle<String> key)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.
TurnOnAccessCheck()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 
IsDirty()2867 bool v8::Object::IsDirty() {
2868   return Utils::OpenHandle(this)->IsDirty();
2869 }
2870 
2871 
Clone()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 
GetCreationContext(i::JSObject * object)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 
CreationContext()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 
GetIdentityHash()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 
SetHiddenValue(v8::Handle<v8::String> key,v8::Handle<v8::Value> value)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 
GetHiddenValue(v8::Handle<v8::String> key)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 
DeleteHiddenValue(v8::Handle<v8::String> key)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 
PrepareExternalArrayElements(i::Handle<i::JSObject> object,void * data,ExternalArrayType array_type,int length)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 
SetIndexedPropertiesToPixelData(uint8_t * data,int length)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 
HasIndexedPropertiesInPixelData()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 
GetIndexedPropertiesPixelData()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 
GetIndexedPropertiesPixelDataLength()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 
SetIndexedPropertiesToExternalArrayData(void * data,ExternalArrayType array_type,int length)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 
HasIndexedPropertiesInExternalArrayData()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 
GetIndexedPropertiesExternalArrayData()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 
GetIndexedPropertiesExternalArrayDataType()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 
GetIndexedPropertiesExternalArrayDataLength()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 
NewInstance() const3185 Local<v8::Object> Function::NewInstance() const {
3186   return NewInstance(0, NULL);
3187 }
3188 
3189 
NewInstance(int argc,v8::Handle<v8::Value> argv[]) const3190 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 
Call(v8::Handle<v8::Object> recv,int argc,v8::Handle<v8::Value> argv[])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 
SetName(v8::Handle<v8::String> name)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 
GetName() const3241 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 
GetScriptOrigin() const3247 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 
GetScriptLineNumber() const3264 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 
Length() const3274 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 
Utf8Length() const3281 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 
WriteUtf8(char * buffer,int capacity,int * nchars_ref,WriteHints hints) const3288 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 
WriteAscii(char * buffer,int start,int length,WriteHints hints) const3345 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 
Write(uint16_t * buffer,int start,int length,WriteHints hints) const3379 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 
IsExternal() const3407 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 
IsExternalAscii() const3417 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 
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const3426 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*
GetExternalAsciiStringResource() const3441       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 
Value() const3456 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 
Value() const3463 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 
Value() const3470 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 
Value() const3481 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 
Value() const3492 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 
InternalFieldCount()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 
CheckedGetInternalField(int index)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 
SetInternalField(int index,v8::Handle<Value> value)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 
CanBeEncodedAsSmi(void * ptr)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 
EncodeAsSmi(void * ptr)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 
SetPointerInInternalField(int index,void * value)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 
Initialize()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 
Dispose()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 
HeapStatistics()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 
GetHeapStatistics(HeapStatistics * heap_statistics)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 
IdleNotification()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 
LowMemoryNotification()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 
ContextDisposedNotification()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 
GetVersion()3645 const char* v8::V8::GetVersion() {
3646   return i::Version::GetVersion();
3647 }
3648 
3649 
3650 static i::Handle<i::FunctionTemplateInfo>
EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ)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 
New(v8::ExtensionConfiguration * extensions,v8::Handle<ObjectTemplate> global_template,v8::Handle<Value> global_object)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 
SetSecurityToken(Handle<Value> token)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 
UseDefaultSecurityToken()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 
GetSecurityToken()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 
HasOutOfMemoryException()3769 bool Context::HasOutOfMemoryException() {
3770   i::Handle<i::Context> env = Utils::OpenHandle(this);
3771   return env->has_out_of_memory();
3772 }
3773 
3774 
InContext()3775 bool Context::InContext() {
3776   return i::Isolate::Current()->context() != NULL;
3777 }
3778 
3779 
GetEntered()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 
GetCurrent()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 
GetCalling()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 
Global()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 
DetachGlobal()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 
ReattachGlobal(Handle<Object> global_object)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 
SetWrapperClassId(i::Object ** global_handle,uint16_t class_id)3854 void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
3855   i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
3856 }
3857 
3858 
NewInstance()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 
GetFunction()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 
HasInstance(v8::Handle<v8::Value> value)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 
ExternalNewImpl(void * data)3897 static Local<External> ExternalNewImpl(void* data) {
3898   return Utils::ToLocal(FACTORY->NewProxy(static_cast<i::Address>(data)));
3899 }
3900 
ExternalValueImpl(i::Handle<i::Object> obj)3901 static void* ExternalValueImpl(i::Handle<i::Object> obj) {
3902   return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy());
3903 }
3904 
3905 
Wrap(void * data)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 
SlowGetPointerFromInternalField(int index)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 
FullUnwrap(v8::Handle<v8::Value> wrapper)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 
New(void * data)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 
Value() const3961 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 
Empty()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 
New(const char * data,int length)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 
Concat(Handle<String> left,Handle<String> right)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 
NewUndetectable(const char * data,int length)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 
TwoByteStringLength(const uint16_t * data)4017 static int TwoByteStringLength(const uint16_t* data) {
4018   int length = 0;
4019   while (data[length] != '\0') length++;
4020   return length;
4021 }
4022 
4023 
New(const uint16_t * data,int length)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 
NewUndetectable(const uint16_t * data,int length)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 
NewExternalStringHandle(i::Isolate * isolate,v8::String::ExternalStringResource * resource)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 
NewExternalAsciiStringHandle(i::Isolate * isolate,v8::String::ExternalAsciiStringResource * resource)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 
NewExternal(v8::String::ExternalStringResource * resource)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 
MakeExternal(v8::String::ExternalStringResource * resource)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 
NewExternal(v8::String::ExternalAsciiStringResource * resource)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 
MakeExternal(v8::String::ExternalAsciiStringResource * resource)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 
CanMakeExternal()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 
New()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 
New(double time)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 
NumberValue() const4174 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 
DateTimeConfigurationChangeNotification()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 
RegExpFlagsToString(RegExp::Flags flags)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 
New(Handle<String> pattern,Flags flags)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 
GetSource() const4245 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 
GetFlags() const4265 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 
New(int length)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 
Length() const4288 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 
CloneElementAt(uint32_t index)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 
NewSymbol(const char * data,int length)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 
New(double value)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 
New(int32_t value)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 
NewFromUnsigned(uint32_t value)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 
IgnoreOutOfMemoryException()4373 void V8::IgnoreOutOfMemoryException() {
4374   EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
4375 }
4376 
4377 
AddMessageListener(MessageCallback that,Handle<Value> data)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 
RemoveMessageListeners(MessageCallback that)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 
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)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 
SetCounterFunction(CounterLookupCallback callback)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 
SetCreateHistogramFunction(CreateHistogramCallback callback)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 
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)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 
EnableSlidingStateWindow()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 
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)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 
AddObjectGroup(Persistent<Value> * objects,size_t length,RetainedObjectInfo * info)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 
AddImplicitReferences(Persistent<Object> parent,Persistent<Value> * children,size_t length)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 
AdjustAmountOfExternalAllocatedMemory(int change_in_bytes)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 
SetGlobalGCPrologueCallback(GCCallback callback)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 
SetGlobalGCEpilogueCallback(GCCallback callback)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 
AddGCPrologueCallback(GCPrologueCallback callback,GCType gc_type)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 
RemoveGCPrologueCallback(GCPrologueCallback callback)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 
AddGCEpilogueCallback(GCEpilogueCallback callback,GCType gc_type)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 
RemoveGCEpilogueCallback(GCEpilogueCallback callback)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 
AddMemoryAllocationCallback(MemoryAllocationCallback callback,ObjectSpace space,AllocationAction action)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 
RemoveMemoryAllocationCallback(MemoryAllocationCallback callback)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 
PauseProfiler()4553 void V8::PauseProfiler() {
4554 #ifdef ENABLE_LOGGING_AND_PROFILING
4555   PauseProfilerEx(PROFILER_MODULE_CPU);
4556 #endif
4557 }
4558 
4559 
ResumeProfiler()4560 void V8::ResumeProfiler() {
4561 #ifdef ENABLE_LOGGING_AND_PROFILING
4562   ResumeProfilerEx(PROFILER_MODULE_CPU);
4563 #endif
4564 }
4565 
4566 
IsProfilerPaused()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 
ResumeProfilerEx(int flags,int tag)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 
PauseProfilerEx(int flags,int tag)4599 void V8::PauseProfilerEx(int flags, int tag) {
4600 #ifdef ENABLE_LOGGING_AND_PROFILING
4601   LOGGER->PauseProfiler(flags, tag);
4602 #endif
4603 }
4604 
4605 
GetActiveProfilerModules()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 
GetLogLines(int from_pos,char * dest_buf,int max_size)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 
GetCurrentThreadId()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 
TerminateExecution(int thread_id)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 
TerminateExecution(Isolate * isolate)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 
IsExecutionTerminating()4657 bool V8::IsExecutionTerminating() {
4658   i::Isolate* isolate = i::Isolate::Current();
4659   return IsExecutionTerminatingCheck(isolate);
4660 }
4661 
4662 
GetCurrent()4663 Isolate* Isolate::GetCurrent() {
4664   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4665   return reinterpret_cast<Isolate*>(isolate);
4666 }
4667 
4668 
New()4669 Isolate* Isolate::New() {
4670   i::Isolate* isolate = new i::Isolate();
4671   return reinterpret_cast<Isolate*>(isolate);
4672 }
4673 
4674 
Dispose()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 
Enter()4686 void Isolate::Enter() {
4687   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4688   isolate->Enter();
4689 }
4690 
4691 
Exit()4692 void Isolate::Exit() {
4693   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4694   isolate->Exit();
4695 }
4696 
4697 
Utf8Value(v8::Handle<v8::Value> obj)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 
~Utf8Value()4721 String::Utf8Value::~Utf8Value() {
4722   i::DeleteArray(str_);
4723 }
4724 
4725 
AsciiValue(v8::Handle<v8::Value> obj)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 
~AsciiValue()4749 String::AsciiValue::~AsciiValue() {
4750   i::DeleteArray(str_);
4751 }
4752 
4753 
Value(v8::Handle<v8::Value> obj)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 
~Value()4777 String::Value::~Value() {
4778   i::DeleteArray(str_);
4779 }
4780 
RangeError(v8::Handle<v8::String> raw_message)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 
ReferenceError(v8::Handle<v8::String> raw_message)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 
SyntaxError(v8::Handle<v8::String> raw_message)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 
TypeError(v8::Handle<v8::String> raw_message)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 
Error(v8::Handle<v8::String> raw_message)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 
EventCallbackWrapper(const v8::Debug::EventDetails & event_details)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 
SetDebugEventListener(EventCallback that,Handle<Value> data)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 
SetDebugEventListener2(EventCallback2 that,Handle<Value> data)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 
SetDebugEventListener(v8::Handle<v8::Object> that,Handle<Value> data)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 
DebugBreak(Isolate * isolate)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 
CancelDebugBreak(Isolate * isolate)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 
DebugBreakForCommand(ClientData * data,Isolate * isolate)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 
MessageHandlerWrapper(const v8::Debug::Message & message)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 
SetMessageHandler(v8::Debug::MessageHandler handler,bool message_handler_thread)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 
SetMessageHandler2(v8::Debug::MessageHandler2 handler)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 
SendCommand(const uint16_t * command,int length,ClientData * client_data,Isolate * isolate)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 
SetHostDispatchHandler(HostDispatchHandler handler,int period)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 
SetDebugMessageDispatchHandler(DebugMessageDispatchHandler handler,bool provide_locker)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 
Call(v8::Handle<v8::Function> fun,v8::Handle<v8::Value> data)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 
GetMirror(v8::Handle<v8::Value> obj)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 
EnableAgent(const char * name,int port,bool wait_for_connection)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 
ProcessDebugMessages()5079 void Debug::ProcessDebugMessages() {
5080   i::Execution::ProcessDebugMesssages(true);
5081 }
5082 
GetDebugContext()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 
GetFunctionName() const5095 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 
GetScriptResourceName() const5111 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 
GetLineNumber() const5120 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 
GetTotalTime() const5127 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 
GetSelfTime() const5134 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 
GetTotalSamplesCount() const5141 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 
GetSelfSamplesCount() const5148 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 
GetCallUid() const5155 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 
GetChildrenCount() const5162 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 
GetChild(int index) const5169 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 
Delete()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 
GetUid() const5190 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 
GetTitle() const5197 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 
GetBottomUpRoot() const5206 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 
GetTopDownRoot() const5214 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 
GetProfilesCount()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 
GetProfile(int index,Handle<Value> security_token)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 
FindProfile(unsigned uid,Handle<Value> security_token)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 
StartProfiling(Handle<String> title)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 
StopProfiling(Handle<String> title,Handle<Value> security_token)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 
DeleteAllProfiles()5269 void CpuProfiler::DeleteAllProfiles() {
5270   i::Isolate* isolate = i::Isolate::Current();
5271   IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5272   i::CpuProfiler::DeleteAllProfiles();
5273 }
5274 
5275 
ToInternal(const HeapGraphEdge * edge)5276 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5277   return const_cast<i::HeapGraphEdge*>(
5278       reinterpret_cast<const i::HeapGraphEdge*>(edge));
5279 }
5280 
GetType() const5281 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 
GetName() const5288 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 
GetFromNode() const5309 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 
GetToNode() const5317 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 
ToInternal(const HeapGraphNode * entry)5325 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5326   return const_cast<i::HeapEntry*>(
5327       reinterpret_cast<const i::HeapEntry*>(entry));
5328 }
5329 
5330 
GetType() const5331 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 
GetName() const5338 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 
GetId() const5346 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 
GetInstancesCount() const5354 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 
GetSelfSize() const5362 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 
GetRetainedSize(bool exact) const5369 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 
GetChildrenCount() const5376 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 
GetChild(int index) const5383 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 
GetRetainersCount() const5391 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 
GetRetainer(int index) const5398 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 
GetDominatorNode() const5406 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 
ToInternal(const HeapSnapshot * snapshot)5413 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5414   return const_cast<i::HeapSnapshot*>(
5415       reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5416 }
5417 
5418 
Delete()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 
GetType() const5431 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 
GetUid() const5438 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 
GetTitle() const5445 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 
GetRoot() const5453 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 
GetNodeById(uint64_t id) const5460 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 
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const5468 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 
GetSnapshotsCount()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 
GetSnapshot(int index)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 
FindSnapshot(unsigned uid)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 
TakeSnapshot(Handle<String> title,HeapSnapshot::Type type,ActivityControl * control)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 
DeleteAllSnapshots()5531 void HeapProfiler::DeleteAllSnapshots() {
5532   i::Isolate* isolate = i::Isolate::Current();
5533   IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5534   i::HeapProfiler::DeleteAllSnapshots();
5535 }
5536 
5537 
DefineWrapperClass(uint16_t class_id,WrapperInfoCallback callback)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 
SetStressRunType(Testing::StressType type)5551 void Testing::SetStressRunType(Testing::StressType type) {
5552   internal::Testing::set_stress_type(type);
5553 }
5554 
GetStressRuns()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 
SetFlagsFromString(const char * flags)5567 static void SetFlagsFromString(const char* flags) {
5568   V8::SetFlagsFromString(flags, i::StrLength(flags));
5569 }
5570 
5571 
PrepareStressRun(int run)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 
DeoptimizeAll()5608 void Testing::DeoptimizeAll() {
5609   internal::Deoptimizer::DeoptimizeAll();
5610 }
5611 
5612 
5613 namespace internal {
5614 
5615 
FreeThreadResources()5616 void HandleScopeImplementer::FreeThreadResources() {
5617   Free();
5618 }
5619 
5620 
ArchiveThread(char * storage)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 
ArchiveSpacePerThread()5635 int HandleScopeImplementer::ArchiveSpacePerThread() {
5636   return sizeof(HandleScopeImplementer);
5637 }
5638 
5639 
RestoreThread(char * storage)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 
IterateThis(ObjectVisitor * v)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 
Iterate(ObjectVisitor * v)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 
Iterate(ObjectVisitor * v,char * storage)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