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