blob: b0e977564b87ea54042b9c99b777ea70054afd6d [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "api.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010031
Steve Blocka7e24c12009-10-30 11:49:00 +000032#include "arguments.h"
33#include "bootstrapper.h"
34#include "compiler.h"
35#include "debug.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010036#include "deoptimizer.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037#include "execution.h"
38#include "global-handles.h"
Kristian Monsen9dcf7e22010-06-28 14:14:28 +010039#include "heap-profiler.h"
Steve Block6ded16b2010-05-10 14:33:55 +010040#include "messages.h"
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000041#include "natives.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010042#include "parser.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000043#include "platform.h"
Steve Block6ded16b2010-05-10 14:33:55 +010044#include "profile-generator-inl.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010045#include "runtime-profiler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000046#include "serialize.h"
47#include "snapshot.h"
48#include "v8threads.h"
49#include "version.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010050#include "vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000051
Steve Block6ded16b2010-05-10 14:33:55 +010052#include "../include/v8-profiler.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010053#include "../include/v8-testing.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000054
Steve Block44f0eee2011-05-26 01:26:41 +010055#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000056
Steve Block44f0eee2011-05-26 01:26:41 +010057#define ENTER_V8(isolate) \
58 ASSERT((isolate)->IsInitialized()); \
59 i::VMState __state__((isolate), i::OTHER)
60#define LEAVE_V8(isolate) \
61 i::VMState __state__((isolate), i::EXTERNAL)
Steve Blocka7e24c12009-10-30 11:49:00 +000062
63namespace v8 {
64
Steve Block44f0eee2011-05-26 01:26:41 +010065#define ON_BAILOUT(isolate, location, code) \
66 if (IsDeadCheck(isolate, location) || \
67 IsExecutionTerminatingCheck(isolate)) { \
Leon Clarkef7060e22010-06-03 12:02:55 +010068 code; \
69 UNREACHABLE(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000070 }
71
72
Steve Block44f0eee2011-05-26 01:26:41 +010073#define EXCEPTION_PREAMBLE(isolate) \
74 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
75 ASSERT(!(isolate)->external_caught_exception()); \
Steve Blocka7e24c12009-10-30 11:49:00 +000076 bool has_pending_exception = false
77
78
Steve Block44f0eee2011-05-26 01:26:41 +010079#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
Steve Blocka7e24c12009-10-30 11:49:00 +000080 do { \
Steve Block44f0eee2011-05-26 01:26:41 +010081 i::HandleScopeImplementer* handle_scope_implementer = \
82 (isolate)->handle_scope_implementer(); \
83 handle_scope_implementer->DecrementCallDepth(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000084 if (has_pending_exception) { \
Steve Block44f0eee2011-05-26 01:26:41 +010085 if (handle_scope_implementer->CallDepthIsZero() && \
86 (isolate)->is_out_of_memory()) { \
Ben Murdoch257744e2011-11-30 15:57:28 +000087 if (!handle_scope_implementer->ignore_out_of_memory()) \
Steve Blocka7e24c12009-10-30 11:49:00 +000088 i::V8::FatalProcessOutOfMemory(NULL); \
89 } \
Steve Block44f0eee2011-05-26 01:26:41 +010090 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
91 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
Steve Blocka7e24c12009-10-30 11:49:00 +000092 return value; \
93 } \
94 } while (false)
95
96
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000097#define API_ENTRY_CHECK(isolate, msg) \
Steve Blocka7e24c12009-10-30 11:49:00 +000098 do { \
99 if (v8::Locker::IsActive()) { \
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000100 ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(), \
Steve Blocka7e24c12009-10-30 11:49:00 +0000101 msg, \
102 "Entering the V8 API without proper locking in place"); \
103 } \
104 } while (false)
105
Ben Murdochb0fe1622011-05-05 13:52:32 +0100106
Steve Blocka7e24c12009-10-30 11:49:00 +0000107// --- E x c e p t i o n B e h a v i o r ---
108
109
Steve Blocka7e24c12009-10-30 11:49:00 +0000110static void DefaultFatalErrorHandler(const char* location,
111 const char* message) {
Steve Block44f0eee2011-05-26 01:26:41 +0100112 i::VMState __state__(i::Isolate::Current(), i::OTHER);
Steve Blocka7e24c12009-10-30 11:49:00 +0000113 API_Fatal(location, message);
114}
115
116
Steve Block44f0eee2011-05-26 01:26:41 +0100117static FatalErrorCallback GetFatalErrorHandler() {
118 i::Isolate* isolate = i::Isolate::Current();
119 if (isolate->exception_behavior() == NULL) {
120 isolate->set_exception_behavior(DefaultFatalErrorHandler);
Steve Blocka7e24c12009-10-30 11:49:00 +0000121 }
Steve Block44f0eee2011-05-26 01:26:41 +0100122 return isolate->exception_behavior();
Steve Blocka7e24c12009-10-30 11:49:00 +0000123}
124
125
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800126void i::FatalProcessOutOfMemory(const char* location) {
127 i::V8::FatalProcessOutOfMemory(location, false);
128}
129
Steve Blocka7e24c12009-10-30 11:49:00 +0000130
131// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
132// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100133void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Steve Blockd0582a62009-12-15 09:54:21 +0000134 i::HeapStats heap_stats;
135 int start_marker;
136 heap_stats.start_marker = &start_marker;
137 int new_space_size;
138 heap_stats.new_space_size = &new_space_size;
139 int new_space_capacity;
140 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100141 intptr_t old_pointer_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000142 heap_stats.old_pointer_space_size = &old_pointer_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100143 intptr_t old_pointer_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000144 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100145 intptr_t old_data_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000146 heap_stats.old_data_space_size = &old_data_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100147 intptr_t old_data_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000148 heap_stats.old_data_space_capacity = &old_data_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100149 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000150 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100151 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000152 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100153 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000154 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100155 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000156 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100157 intptr_t cell_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000158 heap_stats.cell_space_size = &cell_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100159 intptr_t cell_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000160 heap_stats.cell_space_capacity = &cell_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100161 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000162 heap_stats.lo_space_size = &lo_space_size;
163 int global_handle_count;
164 heap_stats.global_handle_count = &global_handle_count;
165 int weak_global_handle_count;
166 heap_stats.weak_global_handle_count = &weak_global_handle_count;
167 int pending_global_handle_count;
168 heap_stats.pending_global_handle_count = &pending_global_handle_count;
169 int near_death_global_handle_count;
170 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000171 int free_global_handle_count;
172 heap_stats.free_global_handle_count = &free_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100173 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100174 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100175 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100176 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
177 int objects_per_type[LAST_TYPE + 1] = {0};
178 heap_stats.objects_per_type = objects_per_type;
179 int size_per_type[LAST_TYPE + 1] = {0};
180 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100181 int os_error;
182 heap_stats.os_error = &os_error;
Steve Blockd0582a62009-12-15 09:54:21 +0000183 int end_marker;
184 heap_stats.end_marker = &end_marker;
Steve Block44f0eee2011-05-26 01:26:41 +0100185 i::Isolate* isolate = i::Isolate::Current();
186 isolate->heap()->RecordStats(&heap_stats, take_snapshot);
Steve Blocka7e24c12009-10-30 11:49:00 +0000187 i::V8::SetFatalError();
188 FatalErrorCallback callback = GetFatalErrorHandler();
189 {
Steve Block44f0eee2011-05-26 01:26:41 +0100190 LEAVE_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 callback(location, "Allocation failed - process out of memory");
192 }
193 // If the callback returns, we stop execution.
194 UNREACHABLE();
195}
196
197
Steve Blocka7e24c12009-10-30 11:49:00 +0000198bool Utils::ReportApiFailure(const char* location, const char* message) {
199 FatalErrorCallback callback = GetFatalErrorHandler();
200 callback(location, message);
201 i::V8::SetFatalError();
202 return false;
203}
204
205
206bool V8::IsDead() {
207 return i::V8::IsDead();
208}
209
210
211static inline bool ApiCheck(bool condition,
212 const char* location,
213 const char* message) {
214 return condition ? true : Utils::ReportApiFailure(location, message);
215}
216
217
218static bool ReportV8Dead(const char* location) {
219 FatalErrorCallback callback = GetFatalErrorHandler();
220 callback(location, "V8 is no longer usable");
221 return true;
222}
223
224
225static bool ReportEmptyHandle(const char* location) {
226 FatalErrorCallback callback = GetFatalErrorHandler();
227 callback(location, "Reading from empty handle");
228 return true;
229}
230
231
232/**
233 * IsDeadCheck checks that the vm is usable. If, for instance, the vm has been
234 * out of memory at some point this check will fail. It should be called on
235 * entry to all methods that touch anything in the heap, except destructors
236 * which you sometimes can't avoid calling after the vm has crashed. Functions
237 * that call EnsureInitialized or ON_BAILOUT don't have to also call
238 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you
239 * can arrange to return if the VM is dead. This is needed to ensure that no VM
240 * heap allocations are attempted on a dead VM. EnsureInitialized has the
241 * advantage over ON_BAILOUT that it actually initializes the VM if this has not
242 * yet been done.
243 */
Steve Block44f0eee2011-05-26 01:26:41 +0100244static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
245 return !isolate->IsInitialized()
Steve Blocka7e24c12009-10-30 11:49:00 +0000246 && i::V8::IsDead() ? ReportV8Dead(location) : false;
247}
248
249
Steve Block44f0eee2011-05-26 01:26:41 +0100250static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
251 if (!isolate->IsInitialized()) return false;
252 if (isolate->has_scheduled_exception()) {
253 return isolate->scheduled_exception() ==
254 isolate->heap()->termination_exception();
255 }
256 return false;
257}
258
259
Steve Blocka7e24c12009-10-30 11:49:00 +0000260static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
261 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
262}
263
264
265static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
266 return (obj == 0) ? ReportEmptyHandle(location) : false;
267}
268
269// --- S t a t i c s ---
270
271
Steve Block44f0eee2011-05-26 01:26:41 +0100272static bool InitializeHelper() {
273 if (i::Snapshot::Initialize()) return true;
274 return i::V8::Initialize(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000275}
276
277
Steve Block44f0eee2011-05-26 01:26:41 +0100278static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
279 const char* location) {
280 if (IsDeadCheck(isolate, location)) return false;
281 if (isolate != NULL) {
282 if (isolate->IsInitialized()) return true;
283 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000284 ASSERT(isolate == i::Isolate::Current());
Steve Block44f0eee2011-05-26 01:26:41 +0100285 return ApiCheck(InitializeHelper(), location, "Error initializing V8");
286}
287
288// Some initializing API functions are called early and may be
289// called on a thread different from static initializer thread.
290// If Isolate API is used, Isolate::Enter() will initialize TLS so
291// Isolate::Current() works. If it's a legacy case, then the thread
292// may not have TLS initialized yet. However, in initializing APIs it
293// may be too early to call EnsureInitialized() - some pre-init
294// parameters still have to be configured.
295static inline i::Isolate* EnterIsolateIfNeeded() {
296 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
297 if (isolate != NULL)
298 return isolate;
299
300 i::Isolate::EnterDefaultIsolate();
301 isolate = i::Isolate::Current();
302 return isolate;
303}
304
305
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000306StartupDataDecompressor::StartupDataDecompressor()
307 : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
308 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
309 raw_data[i] = NULL;
310 }
311}
312
313
314StartupDataDecompressor::~StartupDataDecompressor() {
315 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
316 i::DeleteArray(raw_data[i]);
317 }
318 i::DeleteArray(raw_data);
319}
320
321
322int StartupDataDecompressor::Decompress() {
323 int compressed_data_count = V8::GetCompressedStartupDataCount();
324 StartupData* compressed_data =
325 i::NewArray<StartupData>(compressed_data_count);
326 V8::GetCompressedStartupData(compressed_data);
327 for (int i = 0; i < compressed_data_count; ++i) {
328 char* decompressed = raw_data[i] =
329 i::NewArray<char>(compressed_data[i].raw_size);
330 if (compressed_data[i].compressed_size != 0) {
331 int result = DecompressData(decompressed,
332 &compressed_data[i].raw_size,
333 compressed_data[i].data,
334 compressed_data[i].compressed_size);
335 if (result != 0) return result;
336 } else {
337 ASSERT_EQ(0, compressed_data[i].raw_size);
338 }
339 compressed_data[i].data = decompressed;
340 }
341 V8::SetDecompressedStartupData(compressed_data);
342 return 0;
343}
344
345
Ben Murdoch257744e2011-11-30 15:57:28 +0000346StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
347#ifdef COMPRESS_STARTUP_DATA_BZ2
348 return StartupData::kBZip2;
349#else
350 return StartupData::kUncompressed;
351#endif
352}
353
354
355enum CompressedStartupDataItems {
356 kSnapshot = 0,
357 kSnapshotContext,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000358 kLibraries,
359 kExperimentalLibraries,
Ben Murdoch257744e2011-11-30 15:57:28 +0000360 kCompressedStartupDataCount
361};
362
363int V8::GetCompressedStartupDataCount() {
364#ifdef COMPRESS_STARTUP_DATA_BZ2
365 return kCompressedStartupDataCount;
366#else
367 return 0;
368#endif
369}
370
371
372void V8::GetCompressedStartupData(StartupData* compressed_data) {
373#ifdef COMPRESS_STARTUP_DATA_BZ2
374 compressed_data[kSnapshot].data =
375 reinterpret_cast<const char*>(i::Snapshot::data());
376 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
377 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
378
379 compressed_data[kSnapshotContext].data =
380 reinterpret_cast<const char*>(i::Snapshot::context_data());
381 compressed_data[kSnapshotContext].compressed_size =
382 i::Snapshot::context_size();
383 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000384
385 i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
386 compressed_data[kLibraries].data =
387 reinterpret_cast<const char*>(libraries_source.start());
388 compressed_data[kLibraries].compressed_size = libraries_source.length();
389 compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
390
391 i::Vector<const i::byte> exp_libraries_source =
392 i::ExperimentalNatives::GetScriptsSource();
393 compressed_data[kExperimentalLibraries].data =
394 reinterpret_cast<const char*>(exp_libraries_source.start());
395 compressed_data[kExperimentalLibraries].compressed_size =
396 exp_libraries_source.length();
397 compressed_data[kExperimentalLibraries].raw_size =
398 i::ExperimentalNatives::GetRawScriptsSize();
Ben Murdoch257744e2011-11-30 15:57:28 +0000399#endif
400}
401
402
403void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
404#ifdef COMPRESS_STARTUP_DATA_BZ2
405 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
406 i::Snapshot::set_raw_data(
407 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
408
409 ASSERT_EQ(i::Snapshot::context_raw_size(),
410 decompressed_data[kSnapshotContext].raw_size);
411 i::Snapshot::set_context_raw_data(
412 reinterpret_cast<const i::byte*>(
413 decompressed_data[kSnapshotContext].data));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000414
415 ASSERT_EQ(i::Natives::GetRawScriptsSize(),
416 decompressed_data[kLibraries].raw_size);
417 i::Vector<const char> libraries_source(
418 decompressed_data[kLibraries].data,
419 decompressed_data[kLibraries].raw_size);
420 i::Natives::SetRawScriptsSource(libraries_source);
421
422 ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
423 decompressed_data[kExperimentalLibraries].raw_size);
424 i::Vector<const char> exp_libraries_source(
425 decompressed_data[kExperimentalLibraries].data,
426 decompressed_data[kExperimentalLibraries].raw_size);
427 i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
Ben Murdoch257744e2011-11-30 15:57:28 +0000428#endif
429}
430
431
Steve Block44f0eee2011-05-26 01:26:41 +0100432void V8::SetFatalErrorHandler(FatalErrorCallback that) {
433 i::Isolate* isolate = EnterIsolateIfNeeded();
434 isolate->set_exception_behavior(that);
Steve Blocka7e24c12009-10-30 11:49:00 +0000435}
436
437
Ben Murdoch257744e2011-11-30 15:57:28 +0000438void V8::SetAllowCodeGenerationFromStringsCallback(
439 AllowCodeGenerationFromStringsCallback callback) {
440 i::Isolate* isolate = EnterIsolateIfNeeded();
441 isolate->set_allow_code_gen_callback(callback);
442}
443
444
Steve Blocka7e24c12009-10-30 11:49:00 +0000445#ifdef DEBUG
446void ImplementationUtilities::ZapHandleRange(i::Object** begin,
447 i::Object** end) {
448 i::HandleScope::ZapRange(begin, end);
449}
450#endif
451
452
Steve Blocka7e24c12009-10-30 11:49:00 +0000453void V8::SetFlagsFromString(const char* str, int length) {
454 i::FlagList::SetFlagsFromString(str, length);
455}
456
457
458void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
459 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
460}
461
462
463v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100464 i::Isolate* isolate = i::Isolate::Current();
465 if (IsDeadCheck(isolate, "v8::ThrowException()")) {
466 return v8::Handle<Value>();
467 }
468 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000469 // If we're passed an empty handle, we throw an undefined exception
470 // to deal more gracefully with out of memory situations.
471 if (value.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100472 isolate->ScheduleThrow(isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000473 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100474 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +0000475 }
476 return v8::Undefined();
477}
478
479
480RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
481
482
483RegisteredExtension::RegisteredExtension(Extension* extension)
484 : extension_(extension), state_(UNVISITED) { }
485
486
487void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100488 that->next_ = first_extension_;
489 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000490}
491
492
493void RegisterExtension(Extension* that) {
494 RegisteredExtension* extension = new RegisteredExtension(that);
495 RegisteredExtension::Register(extension);
496}
497
498
499Extension::Extension(const char* name,
500 const char* source,
501 int dep_count,
502 const char** deps)
503 : name_(name),
504 source_(source),
505 dep_count_(dep_count),
506 deps_(deps),
507 auto_enable_(false) { }
508
509
510v8::Handle<Primitive> Undefined() {
Steve Block44f0eee2011-05-26 01:26:41 +0100511 i::Isolate* isolate = i::Isolate::Current();
512 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
513 return v8::Handle<v8::Primitive>();
514 }
515 return v8::Handle<Primitive>(ToApi<Primitive>(
516 isolate->factory()->undefined_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000517}
518
519
520v8::Handle<Primitive> Null() {
Steve Block44f0eee2011-05-26 01:26:41 +0100521 i::Isolate* isolate = i::Isolate::Current();
522 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
523 return v8::Handle<v8::Primitive>();
524 }
525 return v8::Handle<Primitive>(
526 ToApi<Primitive>(isolate->factory()->null_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000527}
528
529
530v8::Handle<Boolean> True() {
Steve Block44f0eee2011-05-26 01:26:41 +0100531 i::Isolate* isolate = i::Isolate::Current();
532 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
533 return v8::Handle<Boolean>();
534 }
535 return v8::Handle<Boolean>(
536 ToApi<Boolean>(isolate->factory()->true_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000537}
538
539
540v8::Handle<Boolean> False() {
Steve Block44f0eee2011-05-26 01:26:41 +0100541 i::Isolate* isolate = i::Isolate::Current();
542 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
543 return v8::Handle<Boolean>();
544 }
545 return v8::Handle<Boolean>(
546 ToApi<Boolean>(isolate->factory()->false_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000547}
548
549
550ResourceConstraints::ResourceConstraints()
551 : max_young_space_size_(0),
552 max_old_space_size_(0),
Russell Brenner90bac252010-11-18 13:33:46 -0800553 max_executable_size_(0),
Steve Blocka7e24c12009-10-30 11:49:00 +0000554 stack_limit_(NULL) { }
555
556
557bool SetResourceConstraints(ResourceConstraints* constraints) {
Steve Block44f0eee2011-05-26 01:26:41 +0100558 i::Isolate* isolate = EnterIsolateIfNeeded();
559
Steve Block3ce2e202009-11-05 08:53:23 +0000560 int young_space_size = constraints->max_young_space_size();
Steve Blocka7e24c12009-10-30 11:49:00 +0000561 int old_gen_size = constraints->max_old_space_size();
Russell Brenner90bac252010-11-18 13:33:46 -0800562 int max_executable_size = constraints->max_executable_size();
563 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100564 // After initialization it's too late to change Heap constraints.
565 ASSERT(!isolate->IsInitialized());
566 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
567 old_gen_size,
568 max_executable_size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000569 if (!result) return false;
570 }
571 if (constraints->stack_limit() != NULL) {
572 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
Steve Block44f0eee2011-05-26 01:26:41 +0100573 isolate->stack_guard()->SetStackLimit(limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000574 }
575 return true;
576}
577
578
579i::Object** V8::GlobalizeReference(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100580 i::Isolate* isolate = i::Isolate::Current();
581 if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
582 LOG_API(isolate, "Persistent::New");
Steve Blocka7e24c12009-10-30 11:49:00 +0000583 i::Handle<i::Object> result =
Steve Block44f0eee2011-05-26 01:26:41 +0100584 isolate->global_handles()->Create(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000585 return result.location();
586}
587
588
589void V8::MakeWeak(i::Object** object, void* parameters,
590 WeakReferenceCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +0100591 i::Isolate* isolate = i::Isolate::Current();
592 LOG_API(isolate, "MakeWeak");
593 isolate->global_handles()->MakeWeak(object, parameters,
594 callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000595}
596
597
598void V8::ClearWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100599 i::Isolate* isolate = i::Isolate::Current();
600 LOG_API(isolate, "ClearWeak");
601 isolate->global_handles()->ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000602}
603
604
Ben Murdoch257744e2011-11-30 15:57:28 +0000605void V8::MarkIndependent(i::Object** object) {
606 i::Isolate* isolate = i::Isolate::Current();
607 LOG_API(isolate, "MakeIndependent");
608 isolate->global_handles()->MarkIndependent(object);
609}
610
611
Steve Blocka7e24c12009-10-30 11:49:00 +0000612bool V8::IsGlobalNearDeath(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100613 i::Isolate* isolate = i::Isolate::Current();
614 LOG_API(isolate, "IsGlobalNearDeath");
615 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000616 return i::GlobalHandles::IsNearDeath(obj);
617}
618
619
620bool V8::IsGlobalWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100621 i::Isolate* isolate = i::Isolate::Current();
622 LOG_API(isolate, "IsGlobalWeak");
623 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000624 return i::GlobalHandles::IsWeak(obj);
625}
626
627
628void V8::DisposeGlobal(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100629 i::Isolate* isolate = i::Isolate::Current();
630 LOG_API(isolate, "DisposeGlobal");
631 if (!isolate->IsInitialized()) return;
632 isolate->global_handles()->Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000633}
634
635// --- H a n d l e s ---
636
637
Steve Block44f0eee2011-05-26 01:26:41 +0100638HandleScope::HandleScope() {
Steve Block44f0eee2011-05-26 01:26:41 +0100639 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000640 API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
Steve Block44f0eee2011-05-26 01:26:41 +0100641 v8::ImplementationUtilities::HandleScopeData* current =
642 isolate->handle_scope_data();
643 isolate_ = isolate;
644 prev_next_ = current->next;
645 prev_limit_ = current->limit;
646 is_closed_ = false;
647 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000648}
649
650
651HandleScope::~HandleScope() {
652 if (!is_closed_) {
John Reck59135872010-11-02 12:39:01 -0700653 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000654 }
655}
656
657
John Reck59135872010-11-02 12:39:01 -0700658void HandleScope::Leave() {
Steve Block44f0eee2011-05-26 01:26:41 +0100659 ASSERT(isolate_ == i::Isolate::Current());
660 v8::ImplementationUtilities::HandleScopeData* current =
661 isolate_->handle_scope_data();
662 current->level--;
663 ASSERT(current->level >= 0);
664 current->next = prev_next_;
665 if (current->limit != prev_limit_) {
666 current->limit = prev_limit_;
667 i::HandleScope::DeleteExtensions(isolate_);
John Reck59135872010-11-02 12:39:01 -0700668 }
669
670#ifdef DEBUG
671 i::HandleScope::ZapRange(prev_next_, prev_limit_);
672#endif
673}
674
675
Steve Blocka7e24c12009-10-30 11:49:00 +0000676int HandleScope::NumberOfHandles() {
Steve Block44f0eee2011-05-26 01:26:41 +0100677 EnsureInitializedForIsolate(
678 i::Isolate::Current(), "HandleScope::NumberOfHandles");
Steve Blocka7e24c12009-10-30 11:49:00 +0000679 return i::HandleScope::NumberOfHandles();
680}
681
682
Steve Block44f0eee2011-05-26 01:26:41 +0100683i::Object** HandleScope::CreateHandle(i::Object* value) {
684 return i::HandleScope::CreateHandle(value, i::Isolate::Current());
685}
686
687
688i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
689 ASSERT(value->IsHeapObject());
690 return reinterpret_cast<i::Object**>(
691 i::HandleScope::CreateHandle(value, value->GetIsolate()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000692}
693
694
695void Context::Enter() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000696 i::Handle<i::Context> env = Utils::OpenHandle(this);
697 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100698 if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
699 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000700
Steve Block44f0eee2011-05-26 01:26:41 +0100701 isolate->handle_scope_implementer()->EnterContext(env);
702
703 isolate->handle_scope_implementer()->SaveContext(isolate->context());
704 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000705}
706
707
708void Context::Exit() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000709 // Exit is essentially a static function and doesn't use the
710 // receiver, so we have to get the current isolate from the thread
711 // local.
Steve Block44f0eee2011-05-26 01:26:41 +0100712 i::Isolate* isolate = i::Isolate::Current();
713 if (!isolate->IsInitialized()) return;
714
715 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 "v8::Context::Exit()",
717 "Cannot exit non-entered context")) {
718 return;
719 }
720
721 // Content of 'last_context' could be NULL.
Steve Block44f0eee2011-05-26 01:26:41 +0100722 i::Context* last_context =
723 isolate->handle_scope_implementer()->RestoreContext();
724 isolate->set_context(last_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000725}
726
727
Steve Blockd0582a62009-12-15 09:54:21 +0000728void Context::SetData(v8::Handle<String> data) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000729 i::Handle<i::Context> env = Utils::OpenHandle(this);
730 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100731 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000732 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
733 ASSERT(env->IsGlobalContext());
734 if (env->IsGlobalContext()) {
735 env->set_data(*raw_data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000736 }
737}
738
739
740v8::Local<v8::Value> Context::GetData() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000741 i::Handle<i::Context> env = Utils::OpenHandle(this);
742 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100743 if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
744 return v8::Local<Value>();
745 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000746 i::Object* raw_result = NULL;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000747 ASSERT(env->IsGlobalContext());
748 if (env->IsGlobalContext()) {
749 raw_result = env->data();
750 } else {
751 return Local<Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000752 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000753 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000754 return Utils::ToLocal(result);
755}
756
757
758i::Object** v8::HandleScope::RawClose(i::Object** value) {
759 if (!ApiCheck(!is_closed_,
760 "v8::HandleScope::Close()",
761 "Local scope has already been closed")) {
762 return 0;
763 }
Steve Block44f0eee2011-05-26 01:26:41 +0100764 LOG_API(isolate_, "CloseHandleScope");
Steve Blocka7e24c12009-10-30 11:49:00 +0000765
766 // Read the result before popping the handle block.
Steve Block6ded16b2010-05-10 14:33:55 +0100767 i::Object* result = NULL;
768 if (value != NULL) {
769 result = *value;
770 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000771 is_closed_ = true;
John Reck59135872010-11-02 12:39:01 -0700772 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000773
Steve Block6ded16b2010-05-10 14:33:55 +0100774 if (value == NULL) {
775 return NULL;
776 }
777
Steve Blocka7e24c12009-10-30 11:49:00 +0000778 // Allocate a new handle on the previous handle block.
779 i::Handle<i::Object> handle(result);
780 return handle.location();
781}
782
783
784// --- N e a n d e r ---
785
786
787// A constructor cannot easily return an error value, therefore it is necessary
788// to check for a dead VM with ON_BAILOUT before constructing any Neander
789// objects. To remind you about this there is no HandleScope in the
790// NeanderObject constructor. When you add one to the site calling the
791// constructor you should check that you ensured the VM was not dead first.
792NeanderObject::NeanderObject(int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100793 i::Isolate* isolate = i::Isolate::Current();
794 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
795 ENTER_V8(isolate);
796 value_ = isolate->factory()->NewNeanderObject();
797 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000798 value_->set_elements(*elements);
799}
800
801
802int NeanderObject::size() {
803 return i::FixedArray::cast(value_->elements())->length();
804}
805
806
807NeanderArray::NeanderArray() : obj_(2) {
808 obj_.set(0, i::Smi::FromInt(0));
809}
810
811
812int NeanderArray::length() {
813 return i::Smi::cast(obj_.get(0))->value();
814}
815
816
817i::Object* NeanderArray::get(int offset) {
818 ASSERT(0 <= offset);
819 ASSERT(offset < length());
820 return obj_.get(offset + 1);
821}
822
823
824// This method cannot easily return an error value, therefore it is necessary
825// to check for a dead VM with ON_BAILOUT before calling it. To remind you
826// about this there is no HandleScope in this method. When you add one to the
827// site calling this method you should check that you ensured the VM was not
828// dead first.
829void NeanderArray::add(i::Handle<i::Object> value) {
830 int length = this->length();
831 int size = obj_.size();
832 if (length == size - 1) {
Steve Block44f0eee2011-05-26 01:26:41 +0100833 i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000834 for (int i = 0; i < length; i++)
835 new_elms->set(i + 1, get(i));
836 obj_.value()->set_elements(*new_elms);
837 }
838 obj_.set(length + 1, *value);
839 obj_.set(0, i::Smi::FromInt(length + 1));
840}
841
842
843void NeanderArray::set(int index, i::Object* value) {
844 if (index < 0 || index >= this->length()) return;
845 obj_.set(index + 1, value);
846}
847
848
849// --- T e m p l a t e ---
850
851
852static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
853 that->set_tag(i::Smi::FromInt(type));
854}
855
856
857void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
858 v8::PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +0100859 i::Isolate* isolate = i::Isolate::Current();
860 if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
861 ENTER_V8(isolate);
862 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000863 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
864 if (list->IsUndefined()) {
865 list = NeanderArray().value();
866 Utils::OpenHandle(this)->set_property_list(*list);
867 }
868 NeanderArray array(list);
869 array.add(Utils::OpenHandle(*name));
870 array.add(Utils::OpenHandle(*value));
871 array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
872}
873
874
875// --- F u n c t i o n T e m p l a t e ---
876static void InitializeFunctionTemplate(
877 i::Handle<i::FunctionTemplateInfo> info) {
878 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
879 info->set_flag(0);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000880 info->set_prototype_attributes(i::Smi::FromInt(v8::None));
Steve Blocka7e24c12009-10-30 11:49:00 +0000881}
882
883
884Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +0100885 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
886 if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000887 return Local<ObjectTemplate>();
888 }
Steve Block44f0eee2011-05-26 01:26:41 +0100889 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000890 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
891 if (result->IsUndefined()) {
892 result = Utils::OpenHandle(*ObjectTemplate::New());
893 Utils::OpenHandle(this)->set_prototype_template(*result);
894 }
895 return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
896}
897
898
899void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100900 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
901 if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
902 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000903 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
904}
905
906
Steve Blocka7e24c12009-10-30 11:49:00 +0000907Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
908 v8::Handle<Value> data, v8::Handle<Signature> signature) {
Steve Block44f0eee2011-05-26 01:26:41 +0100909 i::Isolate* isolate = i::Isolate::Current();
910 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
911 LOG_API(isolate, "FunctionTemplate::New");
912 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000913 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100914 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000915 i::Handle<i::FunctionTemplateInfo> obj =
916 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
917 InitializeFunctionTemplate(obj);
Steve Block44f0eee2011-05-26 01:26:41 +0100918 int next_serial_number = isolate->next_serial_number();
919 isolate->set_next_serial_number(next_serial_number + 1);
920 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +0000921 if (callback != 0) {
922 if (data.IsEmpty()) data = v8::Undefined();
923 Utils::ToLocal(obj)->SetCallHandler(callback, data);
924 }
925 obj->set_undetectable(false);
926 obj->set_needs_access_check(false);
927
928 if (!signature.IsEmpty())
929 obj->set_signature(*Utils::OpenHandle(*signature));
930 return Utils::ToLocal(obj);
931}
932
933
934Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
935 int argc, Handle<FunctionTemplate> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100936 i::Isolate* isolate = i::Isolate::Current();
937 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
938 LOG_API(isolate, "Signature::New");
939 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000940 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100941 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000942 i::Handle<i::SignatureInfo> obj =
943 i::Handle<i::SignatureInfo>::cast(struct_obj);
944 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
945 if (argc > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100946 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000947 for (int i = 0; i < argc; i++) {
948 if (!argv[i].IsEmpty())
949 args->set(i, *Utils::OpenHandle(*argv[i]));
950 }
951 obj->set_args(*args);
952 }
953 return Utils::ToLocal(obj);
954}
955
956
957Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
958 Handle<FunctionTemplate> types[1] = { type };
959 return TypeSwitch::New(1, types);
960}
961
962
963Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100964 i::Isolate* isolate = i::Isolate::Current();
965 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
966 LOG_API(isolate, "TypeSwitch::New");
967 ENTER_V8(isolate);
968 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000969 for (int i = 0; i < argc; i++)
970 vector->set(i, *Utils::OpenHandle(*types[i]));
971 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100972 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000973 i::Handle<i::TypeSwitchInfo> obj =
974 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
975 obj->set_types(*vector);
976 return Utils::ToLocal(obj);
977}
978
979
980int TypeSwitch::match(v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100981 i::Isolate* isolate = i::Isolate::Current();
982 LOG_API(isolate, "TypeSwitch::match");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000983 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000984 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
985 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
986 i::FixedArray* types = i::FixedArray::cast(info->types());
987 for (int i = 0; i < types->length(); i++) {
988 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
989 return i + 1;
990 }
991 return 0;
992}
993
994
Ben Murdoch257744e2011-11-30 15:57:28 +0000995#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
996 i::Handle<i::Object> foreign = FromCData(cdata); \
997 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100998 } while (false)
999
1000
Steve Blocka7e24c12009-10-30 11:49:00 +00001001void FunctionTemplate::SetCallHandler(InvocationCallback callback,
1002 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001003 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1004 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
1005 ENTER_V8(isolate);
1006 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001007 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001008 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001009 i::Handle<i::CallHandlerInfo> obj =
1010 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001011 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001012 if (data.IsEmpty()) data = v8::Undefined();
1013 obj->set_data(*Utils::OpenHandle(*data));
1014 Utils::OpenHandle(this)->set_call_code(*obj);
1015}
1016
1017
Leon Clarkef7060e22010-06-03 12:02:55 +01001018static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1019 v8::Handle<String> name,
1020 AccessorGetter getter,
1021 AccessorSetter setter,
1022 v8::Handle<Value> data,
1023 v8::AccessControl settings,
1024 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01001025 i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
Leon Clarkef7060e22010-06-03 12:02:55 +01001026 ASSERT(getter != NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001027 SET_FIELD_WRAPPED(obj, set_getter, getter);
1028 SET_FIELD_WRAPPED(obj, set_setter, setter);
Leon Clarkef7060e22010-06-03 12:02:55 +01001029 if (data.IsEmpty()) data = v8::Undefined();
1030 obj->set_data(*Utils::OpenHandle(*data));
1031 obj->set_name(*Utils::OpenHandle(*name));
1032 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1033 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1034 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
1035 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
1036 return obj;
1037}
1038
1039
Steve Blocka7e24c12009-10-30 11:49:00 +00001040void FunctionTemplate::AddInstancePropertyAccessor(
1041 v8::Handle<String> name,
1042 AccessorGetter getter,
1043 AccessorSetter setter,
1044 v8::Handle<Value> data,
1045 v8::AccessControl settings,
1046 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01001047 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1048 if (IsDeadCheck(isolate,
1049 "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001050 return;
1051 }
Steve Block44f0eee2011-05-26 01:26:41 +01001052 ENTER_V8(isolate);
1053 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001054
Leon Clarkef7060e22010-06-03 12:02:55 +01001055 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
1056 getter, setter, data,
1057 settings, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00001058 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
1059 if (list->IsUndefined()) {
1060 list = NeanderArray().value();
1061 Utils::OpenHandle(this)->set_property_accessors(*list);
1062 }
1063 NeanderArray array(list);
1064 array.add(obj);
1065}
1066
1067
1068Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +01001069 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1070 if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
Steve Blocka7e24c12009-10-30 11:49:00 +00001071 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
1072 return Local<ObjectTemplate>();
Steve Block44f0eee2011-05-26 01:26:41 +01001073 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001074 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
1075 Local<ObjectTemplate> templ =
1076 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
1077 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
1078 }
1079 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
1080 Utils::OpenHandle(this)->instance_template()));
1081 return Utils::ToLocal(result);
1082}
1083
1084
1085void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01001086 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1087 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
1088 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001089 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1090}
1091
1092
1093void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001094 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1095 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
1096 return;
1097 }
1098 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001099 Utils::OpenHandle(this)->set_hidden_prototype(value);
1100}
1101
1102
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001103void FunctionTemplate::SetPrototypeAttributes(int attributes) {
1104 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1105 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
1106 return;
1107 }
1108 ENTER_V8(isolate);
1109 Utils::OpenHandle(this)->set_prototype_attributes(
1110 i::Smi::FromInt(attributes));
1111}
1112
1113
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001114void FunctionTemplate::SetNamedInstancePropertyHandler(
Steve Blocka7e24c12009-10-30 11:49:00 +00001115 NamedPropertyGetter getter,
1116 NamedPropertySetter setter,
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001117 NamedPropertyQuery query,
Steve Blocka7e24c12009-10-30 11:49:00 +00001118 NamedPropertyDeleter remover,
1119 NamedPropertyEnumerator enumerator,
1120 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001121 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1122 if (IsDeadCheck(isolate,
1123 "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001124 return;
1125 }
Steve Block44f0eee2011-05-26 01:26:41 +01001126 ENTER_V8(isolate);
1127 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001128 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001129 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001130 i::Handle<i::InterceptorInfo> obj =
1131 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001132
1133 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1134 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1135 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1136 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1137 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1138
Steve Blocka7e24c12009-10-30 11:49:00 +00001139 if (data.IsEmpty()) data = v8::Undefined();
1140 obj->set_data(*Utils::OpenHandle(*data));
1141 Utils::OpenHandle(this)->set_named_property_handler(*obj);
1142}
1143
1144
1145void FunctionTemplate::SetIndexedInstancePropertyHandler(
1146 IndexedPropertyGetter getter,
1147 IndexedPropertySetter setter,
1148 IndexedPropertyQuery query,
1149 IndexedPropertyDeleter remover,
1150 IndexedPropertyEnumerator enumerator,
1151 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001152 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1153 if (IsDeadCheck(isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00001154 "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
1155 return;
1156 }
Steve Block44f0eee2011-05-26 01:26:41 +01001157 ENTER_V8(isolate);
1158 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001159 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001160 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001161 i::Handle<i::InterceptorInfo> obj =
1162 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001163
1164 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1165 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1166 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1167 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1168 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1169
Steve Blocka7e24c12009-10-30 11:49:00 +00001170 if (data.IsEmpty()) data = v8::Undefined();
1171 obj->set_data(*Utils::OpenHandle(*data));
1172 Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
1173}
1174
1175
1176void FunctionTemplate::SetInstanceCallAsFunctionHandler(
1177 InvocationCallback callback,
1178 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001179 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1180 if (IsDeadCheck(isolate,
1181 "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001182 return;
1183 }
Steve Block44f0eee2011-05-26 01:26:41 +01001184 ENTER_V8(isolate);
1185 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001186 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001187 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001188 i::Handle<i::CallHandlerInfo> obj =
1189 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001190 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001191 if (data.IsEmpty()) data = v8::Undefined();
1192 obj->set_data(*Utils::OpenHandle(*data));
1193 Utils::OpenHandle(this)->set_instance_call_handler(*obj);
1194}
1195
1196
1197// --- O b j e c t T e m p l a t e ---
1198
1199
1200Local<ObjectTemplate> ObjectTemplate::New() {
1201 return New(Local<FunctionTemplate>());
1202}
1203
1204
1205Local<ObjectTemplate> ObjectTemplate::New(
1206 v8::Handle<FunctionTemplate> constructor) {
Steve Block44f0eee2011-05-26 01:26:41 +01001207 i::Isolate* isolate = i::Isolate::Current();
1208 if (IsDeadCheck(isolate, "v8::ObjectTemplate::New()")) {
1209 return Local<ObjectTemplate>();
1210 }
1211 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1212 LOG_API(isolate, "ObjectTemplate::New");
1213 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001214 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001215 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001216 i::Handle<i::ObjectTemplateInfo> obj =
1217 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1218 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1219 if (!constructor.IsEmpty())
1220 obj->set_constructor(*Utils::OpenHandle(*constructor));
1221 obj->set_internal_field_count(i::Smi::FromInt(0));
1222 return Utils::ToLocal(obj);
1223}
1224
1225
1226// Ensure that the object template has a constructor. If no
1227// constructor is available we create one.
1228static void EnsureConstructor(ObjectTemplate* object_template) {
1229 if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
1230 Local<FunctionTemplate> templ = FunctionTemplate::New();
1231 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1232 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1233 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1234 }
1235}
1236
1237
1238void ObjectTemplate::SetAccessor(v8::Handle<String> name,
1239 AccessorGetter getter,
1240 AccessorSetter setter,
1241 v8::Handle<Value> data,
1242 AccessControl settings,
1243 PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +01001244 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1245 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
1246 ENTER_V8(isolate);
1247 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001248 EnsureConstructor(this);
1249 i::FunctionTemplateInfo* constructor =
1250 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1251 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1252 Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
1253 getter,
1254 setter,
1255 data,
1256 settings,
1257 attribute);
1258}
1259
1260
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001261void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
1262 NamedPropertySetter setter,
1263 NamedPropertyQuery query,
1264 NamedPropertyDeleter remover,
1265 NamedPropertyEnumerator enumerator,
1266 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001267 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1268 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
1269 return;
1270 }
1271 ENTER_V8(isolate);
1272 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001273 EnsureConstructor(this);
1274 i::FunctionTemplateInfo* constructor =
1275 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1276 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001277 Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
1278 setter,
1279 query,
1280 remover,
1281 enumerator,
1282 data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001283}
1284
1285
1286void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001287 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1288 if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
1289 ENTER_V8(isolate);
1290 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001291 EnsureConstructor(this);
1292 i::FunctionTemplateInfo* constructor =
1293 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1294 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1295 cons->set_undetectable(true);
1296}
1297
1298
1299void ObjectTemplate::SetAccessCheckCallbacks(
1300 NamedSecurityCallback named_callback,
1301 IndexedSecurityCallback indexed_callback,
1302 Handle<Value> data,
1303 bool turned_on_by_default) {
Steve Block44f0eee2011-05-26 01:26:41 +01001304 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1305 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
1306 return;
1307 }
1308 ENTER_V8(isolate);
1309 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001310 EnsureConstructor(this);
1311
1312 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001313 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001314 i::Handle<i::AccessCheckInfo> info =
1315 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001316
1317 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1318 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1319
Steve Blocka7e24c12009-10-30 11:49:00 +00001320 if (data.IsEmpty()) data = v8::Undefined();
1321 info->set_data(*Utils::OpenHandle(*data));
1322
1323 i::FunctionTemplateInfo* constructor =
1324 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1325 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1326 cons->set_access_check_info(*info);
1327 cons->set_needs_access_check(turned_on_by_default);
1328}
1329
1330
1331void ObjectTemplate::SetIndexedPropertyHandler(
1332 IndexedPropertyGetter getter,
1333 IndexedPropertySetter setter,
1334 IndexedPropertyQuery query,
1335 IndexedPropertyDeleter remover,
1336 IndexedPropertyEnumerator enumerator,
1337 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001338 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1339 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
1340 return;
1341 }
1342 ENTER_V8(isolate);
1343 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001344 EnsureConstructor(this);
1345 i::FunctionTemplateInfo* constructor =
1346 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1347 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1348 Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
1349 setter,
1350 query,
1351 remover,
1352 enumerator,
1353 data);
1354}
1355
1356
1357void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
1358 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001359 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1360 if (IsDeadCheck(isolate,
1361 "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
1362 return;
1363 }
1364 ENTER_V8(isolate);
1365 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001366 EnsureConstructor(this);
1367 i::FunctionTemplateInfo* constructor =
1368 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1369 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1370 Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
1371}
1372
1373
1374int ObjectTemplate::InternalFieldCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01001375 if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
1376 "v8::ObjectTemplate::InternalFieldCount()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001377 return 0;
1378 }
1379 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1380}
1381
1382
1383void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001384 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1385 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
1386 return;
1387 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001388 if (!ApiCheck(i::Smi::IsValid(value),
1389 "v8::ObjectTemplate::SetInternalFieldCount()",
1390 "Invalid internal field count")) {
1391 return;
1392 }
Steve Block44f0eee2011-05-26 01:26:41 +01001393 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001394 if (value > 0) {
1395 // The internal field count is set by the constructor function's
1396 // construct code, so we ensure that there is a constructor
1397 // function to do the setting.
1398 EnsureConstructor(this);
1399 }
1400 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1401}
1402
1403
1404// --- S c r i p t D a t a ---
1405
1406
1407ScriptData* ScriptData::PreCompile(const char* input, int length) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001408 i::Utf8ToUC16CharacterStream stream(
1409 reinterpret_cast<const unsigned char*>(input), length);
1410 return i::ParserApi::PreParse(&stream, NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00001411}
1412
1413
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001414ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1415 i::Handle<i::String> str = Utils::OpenHandle(*source);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001416 if (str->IsExternalTwoByteString()) {
1417 i::ExternalTwoByteStringUC16CharacterStream stream(
1418 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
1419 return i::ParserApi::PreParse(&stream, NULL);
1420 } else {
1421 i::GenericStringUC16CharacterStream stream(str, 0, str->length());
1422 return i::ParserApi::PreParse(&stream, NULL);
1423 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001424}
1425
1426
Leon Clarkef7060e22010-06-03 12:02:55 +01001427ScriptData* ScriptData::New(const char* data, int length) {
1428 // Return an empty ScriptData if the length is obviously invalid.
1429 if (length % sizeof(unsigned) != 0) {
Iain Merrick9ac36c92010-09-13 15:29:50 +01001430 return new i::ScriptDataImpl();
Leon Clarkef7060e22010-06-03 12:02:55 +01001431 }
1432
1433 // Copy the data to ensure it is properly aligned.
1434 int deserialized_data_length = length / sizeof(unsigned);
Iain Merrick9ac36c92010-09-13 15:29:50 +01001435 // If aligned, don't create a copy of the data.
1436 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1437 return new i::ScriptDataImpl(data, length);
1438 }
1439 // Copy the data to align it.
Leon Clarkef7060e22010-06-03 12:02:55 +01001440 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001441 i::OS::MemCopy(deserialized_data, data, length);
Leon Clarkef7060e22010-06-03 12:02:55 +01001442
1443 return new i::ScriptDataImpl(
1444 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
Steve Blocka7e24c12009-10-30 11:49:00 +00001445}
1446
1447
1448// --- S c r i p t ---
1449
1450
1451Local<Script> Script::New(v8::Handle<String> source,
1452 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001453 v8::ScriptData* pre_data,
1454 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001455 i::Isolate* isolate = i::Isolate::Current();
1456 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1457 LOG_API(isolate, "Script::New");
1458 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001459 i::Handle<i::String> str = Utils::OpenHandle(*source);
1460 i::Handle<i::Object> name_obj;
1461 int line_offset = 0;
1462 int column_offset = 0;
1463 if (origin != NULL) {
1464 if (!origin->ResourceName().IsEmpty()) {
1465 name_obj = Utils::OpenHandle(*origin->ResourceName());
1466 }
1467 if (!origin->ResourceLineOffset().IsEmpty()) {
1468 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1469 }
1470 if (!origin->ResourceColumnOffset().IsEmpty()) {
1471 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
1472 }
1473 }
Steve Block44f0eee2011-05-26 01:26:41 +01001474 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001475 i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001476 // We assert that the pre-data is sane, even though we can actually
1477 // handle it if it turns out not to be in release mode.
Andrei Popescu402d9372010-02-26 13:31:12 +00001478 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
Steve Blocka7e24c12009-10-30 11:49:00 +00001479 // If the pre-data isn't sane we simply ignore it
Andrei Popescu402d9372010-02-26 13:31:12 +00001480 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1481 pre_data_impl = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001482 }
Steve Block6ded16b2010-05-10 14:33:55 +01001483 i::Handle<i::SharedFunctionInfo> result =
Andrei Popescu31002712010-02-23 13:46:05 +00001484 i::Compiler::Compile(str,
1485 name_obj,
1486 line_offset,
1487 column_offset,
1488 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001489 pre_data_impl,
1490 Utils::OpenHandle(*script_data),
Andrei Popescu31002712010-02-23 13:46:05 +00001491 i::NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001492 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01001493 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
Steve Block6ded16b2010-05-10 14:33:55 +01001494 return Local<Script>(ToApi<Script>(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00001495}
1496
1497
1498Local<Script> Script::New(v8::Handle<String> source,
1499 v8::Handle<Value> file_name) {
1500 ScriptOrigin origin(file_name);
1501 return New(source, &origin);
1502}
1503
1504
1505Local<Script> Script::Compile(v8::Handle<String> source,
1506 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001507 v8::ScriptData* pre_data,
1508 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001509 i::Isolate* isolate = i::Isolate::Current();
1510 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1511 LOG_API(isolate, "Script::Compile");
1512 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001513 Local<Script> generic = New(source, origin, pre_data, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001514 if (generic.IsEmpty())
1515 return generic;
Steve Block6ded16b2010-05-10 14:33:55 +01001516 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1517 i::Handle<i::SharedFunctionInfo> function =
1518 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
Steve Blocka7e24c12009-10-30 11:49:00 +00001519 i::Handle<i::JSFunction> result =
Steve Block44f0eee2011-05-26 01:26:41 +01001520 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1521 function,
1522 isolate->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001523 return Local<Script>(ToApi<Script>(result));
1524}
1525
1526
1527Local<Script> Script::Compile(v8::Handle<String> source,
Andrei Popescu402d9372010-02-26 13:31:12 +00001528 v8::Handle<Value> file_name,
1529 v8::Handle<String> script_data) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001530 ScriptOrigin origin(file_name);
Andrei Popescu402d9372010-02-26 13:31:12 +00001531 return Compile(source, &origin, 0, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001532}
1533
1534
1535Local<Value> Script::Run() {
Steve Block44f0eee2011-05-26 01:26:41 +01001536 i::Isolate* isolate = i::Isolate::Current();
1537 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1538 LOG_API(isolate, "Script::Run");
1539 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001540 i::Object* raw_result = NULL;
1541 {
Steve Block44f0eee2011-05-26 01:26:41 +01001542 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001543 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1544 i::Handle<i::JSFunction> fun;
1545 if (obj->IsSharedFunctionInfo()) {
1546 i::Handle<i::SharedFunctionInfo>
Steve Block44f0eee2011-05-26 01:26:41 +01001547 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
1548 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
1549 function_info, isolate->global_context());
Steve Block6ded16b2010-05-10 14:33:55 +01001550 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001551 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001552 }
Steve Block44f0eee2011-05-26 01:26:41 +01001553 EXCEPTION_PREAMBLE(isolate);
1554 i::Handle<i::Object> receiver(
1555 isolate->context()->global_proxy(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001556 i::Handle<i::Object> result =
1557 i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001558 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001559 raw_result = *result;
1560 }
Steve Block44f0eee2011-05-26 01:26:41 +01001561 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001562 return Utils::ToLocal(result);
1563}
1564
1565
Steve Block6ded16b2010-05-10 14:33:55 +01001566static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1567 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1568 i::Handle<i::SharedFunctionInfo> result;
1569 if (obj->IsSharedFunctionInfo()) {
1570 result =
1571 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1572 } else {
1573 result =
1574 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1575 }
1576 return result;
1577}
1578
1579
Steve Blocka7e24c12009-10-30 11:49:00 +00001580Local<Value> Script::Id() {
Steve Block44f0eee2011-05-26 01:26:41 +01001581 i::Isolate* isolate = i::Isolate::Current();
1582 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1583 LOG_API(isolate, "Script::Id");
Steve Blocka7e24c12009-10-30 11:49:00 +00001584 i::Object* raw_id = NULL;
1585 {
Steve Block44f0eee2011-05-26 01:26:41 +01001586 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001587 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1588 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001589 i::Handle<i::Object> id(script->id());
1590 raw_id = *id;
1591 }
1592 i::Handle<i::Object> id(raw_id);
1593 return Utils::ToLocal(id);
1594}
1595
1596
Steve Blockd0582a62009-12-15 09:54:21 +00001597void Script::SetData(v8::Handle<String> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001598 i::Isolate* isolate = i::Isolate::Current();
1599 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1600 LOG_API(isolate, "Script::SetData");
Steve Blocka7e24c12009-10-30 11:49:00 +00001601 {
Steve Block44f0eee2011-05-26 01:26:41 +01001602 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001603 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001604 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
Steve Block6ded16b2010-05-10 14:33:55 +01001605 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001606 script->set_data(*raw_data);
1607 }
1608}
1609
1610
1611// --- E x c e p t i o n s ---
1612
1613
1614v8::TryCatch::TryCatch()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001615 : isolate_(i::Isolate::Current()),
1616 next_(isolate_->try_catch_handler_address()),
1617 exception_(isolate_->heap()->the_hole_value()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001618 message_(i::Smi::FromInt(0)),
1619 is_verbose_(false),
1620 can_continue_(true),
1621 capture_message_(true),
Steve Blockd0582a62009-12-15 09:54:21 +00001622 rethrow_(false) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001623 isolate_->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001624}
1625
1626
1627v8::TryCatch::~TryCatch() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001628 ASSERT(isolate_ == i::Isolate::Current());
Steve Blockd0582a62009-12-15 09:54:21 +00001629 if (rethrow_) {
1630 v8::HandleScope scope;
1631 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001632 isolate_->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001633 v8::ThrowException(exc);
1634 } else {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001635 isolate_->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001636 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001637}
1638
1639
1640bool v8::TryCatch::HasCaught() const {
1641 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1642}
1643
1644
1645bool v8::TryCatch::CanContinue() const {
1646 return can_continue_;
1647}
1648
1649
Steve Blockd0582a62009-12-15 09:54:21 +00001650v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1651 if (!HasCaught()) return v8::Local<v8::Value>();
1652 rethrow_ = true;
1653 return v8::Undefined();
1654}
1655
1656
Steve Blocka7e24c12009-10-30 11:49:00 +00001657v8::Local<Value> v8::TryCatch::Exception() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001658 ASSERT(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001659 if (HasCaught()) {
1660 // Check for out of memory exception.
1661 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001662 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001663 } else {
1664 return v8::Local<Value>();
1665 }
1666}
1667
1668
1669v8::Local<Value> v8::TryCatch::StackTrace() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001670 ASSERT(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001671 if (HasCaught()) {
1672 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1673 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001674 i::HandleScope scope(isolate_);
1675 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
1676 i::Handle<i::String> name = isolate_->factory()->LookupAsciiSymbol("stack");
1677 if (!obj->HasProperty(*name)) return v8::Local<Value>();
1678 i::Handle<i::Object> value = i::GetProperty(obj, name);
1679 if (value.is_null()) return v8::Local<Value>();
1680 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001681 } else {
1682 return v8::Local<Value>();
1683 }
1684}
1685
1686
1687v8::Local<v8::Message> v8::TryCatch::Message() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001688 ASSERT(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001689 if (HasCaught() && message_ != i::Smi::FromInt(0)) {
1690 i::Object* message = reinterpret_cast<i::Object*>(message_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001691 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001692 } else {
1693 return v8::Local<v8::Message>();
1694 }
1695}
1696
1697
1698void v8::TryCatch::Reset() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001699 ASSERT(isolate_ == i::Isolate::Current());
1700 exception_ = isolate_->heap()->the_hole_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00001701 message_ = i::Smi::FromInt(0);
1702}
1703
1704
1705void v8::TryCatch::SetVerbose(bool value) {
1706 is_verbose_ = value;
1707}
1708
1709
1710void v8::TryCatch::SetCaptureMessage(bool value) {
1711 capture_message_ = value;
1712}
1713
1714
1715// --- M e s s a g e ---
1716
1717
1718Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001719 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1720 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
1721 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001722 HandleScope scope;
1723 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1724 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
1725 Local<String> result = Utils::ToLocal(raw_result);
1726 return scope.Close(result);
1727}
1728
1729
1730v8::Handle<Value> Message::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001731 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1732 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001733 return Local<String>();
1734 }
Steve Block44f0eee2011-05-26 01:26:41 +01001735 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001736 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001737 i::Handle<i::JSMessageObject> message =
1738 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001739 // Return this.script.name.
1740 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001741 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001742 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
1743 return scope.Close(Utils::ToLocal(resource_name));
1744}
1745
1746
1747v8::Handle<Value> Message::GetScriptData() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001748 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1749 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001750 return Local<Value>();
1751 }
Steve Block44f0eee2011-05-26 01:26:41 +01001752 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001753 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001754 i::Handle<i::JSMessageObject> message =
1755 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001756 // Return this.script.data.
1757 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001758 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001759 i::Handle<i::Object> data(i::Script::cast(script->value())->data());
1760 return scope.Close(Utils::ToLocal(data));
1761}
1762
1763
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001764v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001765 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1766 if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001767 return Local<v8::StackTrace>();
1768 }
Steve Block44f0eee2011-05-26 01:26:41 +01001769 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001770 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001771 i::Handle<i::JSMessageObject> message =
1772 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1773 i::Handle<i::Object> stackFramesObj(message->stack_frames());
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001774 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
1775 i::Handle<i::JSArray> stackTrace =
1776 i::Handle<i::JSArray>::cast(stackFramesObj);
1777 return scope.Close(Utils::StackTraceToLocal(stackTrace));
1778}
1779
1780
Steve Blocka7e24c12009-10-30 11:49:00 +00001781static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1782 i::Handle<i::Object> recv,
1783 int argc,
1784 i::Object** argv[],
1785 bool* has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +01001786 i::Isolate* isolate = i::Isolate::Current();
1787 i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name);
John Reck59135872010-11-02 12:39:01 -07001788 i::Object* object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001789 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
Steve Blocka7e24c12009-10-30 11:49:00 +00001790 i::Handle<i::JSFunction> fun =
1791 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
1792 i::Handle<i::Object> value =
1793 i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
1794 return value;
1795}
1796
1797
1798static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1799 i::Handle<i::Object> data,
1800 bool* has_pending_exception) {
1801 i::Object** argv[1] = { data.location() };
1802 return CallV8HeapFunction(name,
Steve Block44f0eee2011-05-26 01:26:41 +01001803 i::Isolate::Current()->js_builtins_object(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001804 1,
1805 argv,
1806 has_pending_exception);
1807}
1808
1809
1810int Message::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001811 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1812 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
1813 ENTER_V8(isolate);
1814 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001815
Steve Block44f0eee2011-05-26 01:26:41 +01001816 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001817 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
1818 Utils::OpenHandle(this),
1819 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001820 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001821 return static_cast<int>(result->Number());
1822}
1823
1824
1825int Message::GetStartPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001826 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1827 if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
1828 ENTER_V8(isolate);
1829 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001830 i::Handle<i::JSMessageObject> message =
1831 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1832 return message->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001833}
1834
1835
1836int Message::GetEndPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001837 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1838 if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
1839 ENTER_V8(isolate);
1840 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001841 i::Handle<i::JSMessageObject> message =
1842 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1843 return message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001844}
1845
1846
1847int Message::GetStartColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001848 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1849 if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
1850 return kNoColumnInfo;
1851 }
1852 ENTER_V8(isolate);
1853 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001854 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001855 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001856 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1857 "GetPositionInLine",
1858 data_obj,
1859 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001860 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001861 return static_cast<int>(start_col_obj->Number());
1862}
1863
1864
1865int Message::GetEndColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001866 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1867 if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
1868 ENTER_V8(isolate);
1869 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001870 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001871 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001872 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1873 "GetPositionInLine",
1874 data_obj,
1875 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001876 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Block1e0659c2011-05-24 12:43:12 +01001877 i::Handle<i::JSMessageObject> message =
1878 i::Handle<i::JSMessageObject>::cast(data_obj);
1879 int start = message->start_position();
1880 int end = message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001881 return static_cast<int>(start_col_obj->Number()) + (end - start);
1882}
1883
1884
1885Local<String> Message::GetSourceLine() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001886 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1887 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
1888 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001889 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01001890 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001891 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
1892 Utils::OpenHandle(this),
1893 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001894 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001895 if (result->IsString()) {
1896 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
1897 } else {
1898 return Local<String>();
1899 }
1900}
1901
1902
1903void Message::PrintCurrentStackTrace(FILE* out) {
Steve Block44f0eee2011-05-26 01:26:41 +01001904 i::Isolate* isolate = i::Isolate::Current();
1905 if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
1906 ENTER_V8(isolate);
1907 isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00001908}
1909
1910
Kristian Monsen25f61362010-05-21 11:50:48 +01001911// --- S t a c k T r a c e ---
1912
1913Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01001914 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1915 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
1916 return Local<StackFrame>();
1917 }
1918 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001919 HandleScope scope;
1920 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
John Reck59135872010-11-02 12:39:01 -07001921 i::Object* raw_object = self->GetElementNoExceptionThrown(index);
1922 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001923 return scope.Close(Utils::StackFrameToLocal(obj));
1924}
1925
1926
1927int StackTrace::GetFrameCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001928 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1929 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
1930 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001931 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
1932}
1933
1934
1935Local<Array> StackTrace::AsArray() {
Steve Block44f0eee2011-05-26 01:26:41 +01001936 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1937 if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
1938 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001939 return Utils::ToLocal(Utils::OpenHandle(this));
1940}
1941
1942
1943Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
1944 StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01001945 i::Isolate* isolate = i::Isolate::Current();
1946 if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
1947 Local<StackTrace>();
1948 }
1949 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001950 i::Handle<i::JSArray> stackTrace =
Steve Block44f0eee2011-05-26 01:26:41 +01001951 isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001952 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01001953}
1954
1955
1956// --- S t a c k F r a m e ---
1957
1958int StackFrame::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001959 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1960 if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001961 return Message::kNoLineNumberInfo;
1962 }
Steve Block44f0eee2011-05-26 01:26:41 +01001963 ENTER_V8(isolate);
1964 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001965 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1966 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
1967 if (!line->IsSmi()) {
1968 return Message::kNoLineNumberInfo;
1969 }
1970 return i::Smi::cast(*line)->value();
1971}
1972
1973
1974int StackFrame::GetColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001975 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1976 if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001977 return Message::kNoColumnInfo;
1978 }
Steve Block44f0eee2011-05-26 01:26:41 +01001979 ENTER_V8(isolate);
1980 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001981 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1982 i::Handle<i::Object> column = GetProperty(self, "column");
1983 if (!column->IsSmi()) {
1984 return Message::kNoColumnInfo;
1985 }
1986 return i::Smi::cast(*column)->value();
1987}
1988
1989
1990Local<String> StackFrame::GetScriptName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001991 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1992 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
1993 return Local<String>();
1994 }
1995 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001996 HandleScope scope;
1997 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1998 i::Handle<i::Object> name = GetProperty(self, "scriptName");
1999 if (!name->IsString()) {
2000 return Local<String>();
2001 }
2002 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2003}
2004
2005
Ben Murdochf87a2032010-10-22 12:50:53 +01002006Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002007 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2008 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
Ben Murdochf87a2032010-10-22 12:50:53 +01002009 return Local<String>();
2010 }
Steve Block44f0eee2011-05-26 01:26:41 +01002011 ENTER_V8(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01002012 HandleScope scope;
2013 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2014 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
2015 if (!name->IsString()) {
2016 return Local<String>();
2017 }
2018 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2019}
2020
2021
Kristian Monsen25f61362010-05-21 11:50:48 +01002022Local<String> StackFrame::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002023 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2024 if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
2025 return Local<String>();
2026 }
2027 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002028 HandleScope scope;
2029 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2030 i::Handle<i::Object> name = GetProperty(self, "functionName");
2031 if (!name->IsString()) {
2032 return Local<String>();
2033 }
2034 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2035}
2036
2037
2038bool StackFrame::IsEval() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002039 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2040 if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
2041 ENTER_V8(isolate);
2042 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002043 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2044 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
2045 return is_eval->IsTrue();
2046}
2047
2048
2049bool StackFrame::IsConstructor() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002050 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2051 if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
2052 ENTER_V8(isolate);
2053 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002054 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2055 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
2056 return is_constructor->IsTrue();
2057}
2058
2059
Steve Blocka7e24c12009-10-30 11:49:00 +00002060// --- D a t a ---
2061
2062bool Value::IsUndefined() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002063 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
2064 return false;
2065 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002066 return Utils::OpenHandle(this)->IsUndefined();
2067}
2068
2069
2070bool Value::IsNull() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002071 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002072 return Utils::OpenHandle(this)->IsNull();
2073}
2074
2075
2076bool Value::IsTrue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002077 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002078 return Utils::OpenHandle(this)->IsTrue();
2079}
2080
2081
2082bool Value::IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002083 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002084 return Utils::OpenHandle(this)->IsFalse();
2085}
2086
2087
2088bool Value::IsFunction() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002089 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFunction()")) {
2090 return false;
2091 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002092 return Utils::OpenHandle(this)->IsJSFunction();
2093}
2094
2095
2096bool Value::FullIsString() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002097 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsString()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002098 bool result = Utils::OpenHandle(this)->IsString();
2099 ASSERT_EQ(result, QuickIsString());
2100 return result;
2101}
2102
2103
2104bool Value::IsArray() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002105 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002106 return Utils::OpenHandle(this)->IsJSArray();
2107}
2108
2109
2110bool Value::IsObject() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002111 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002112 return Utils::OpenHandle(this)->IsJSObject();
2113}
2114
2115
2116bool Value::IsNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002117 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002118 return Utils::OpenHandle(this)->IsNumber();
2119}
2120
2121
2122bool Value::IsBoolean() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002123 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsBoolean()")) {
2124 return false;
2125 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002126 return Utils::OpenHandle(this)->IsBoolean();
2127}
2128
2129
2130bool Value::IsExternal() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002131 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
2132 return false;
2133 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002134 return Utils::OpenHandle(this)->IsForeign();
Steve Blocka7e24c12009-10-30 11:49:00 +00002135}
2136
2137
2138bool Value::IsInt32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002139 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002140 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2141 if (obj->IsSmi()) return true;
2142 if (obj->IsNumber()) {
2143 double value = obj->Number();
2144 return i::FastI2D(i::FastD2I(value)) == value;
2145 }
2146 return false;
2147}
2148
2149
Steve Block6ded16b2010-05-10 14:33:55 +01002150bool Value::IsUint32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002151 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUint32()")) return false;
Steve Block6ded16b2010-05-10 14:33:55 +01002152 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2153 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2154 if (obj->IsNumber()) {
2155 double value = obj->Number();
2156 return i::FastUI2D(i::FastD2UI(value)) == value;
2157 }
2158 return false;
2159}
2160
2161
Steve Blocka7e24c12009-10-30 11:49:00 +00002162bool Value::IsDate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002163 i::Isolate* isolate = i::Isolate::Current();
2164 if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002165 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002166 return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00002167}
2168
2169
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002170bool Value::IsStringObject() const {
2171 i::Isolate* isolate = i::Isolate::Current();
2172 if (IsDeadCheck(isolate, "v8::Value::IsStringObject()")) return false;
2173 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2174 return obj->HasSpecificClassOf(isolate->heap()->String_symbol());
2175}
2176
2177
2178bool Value::IsNumberObject() const {
2179 i::Isolate* isolate = i::Isolate::Current();
2180 if (IsDeadCheck(isolate, "v8::Value::IsNumberObject()")) return false;
2181 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2182 return obj->HasSpecificClassOf(isolate->heap()->Number_symbol());
2183}
2184
2185
2186static i::Object* LookupBuiltin(i::Isolate* isolate,
2187 const char* builtin_name) {
2188 i::Handle<i::String> symbol =
2189 isolate->factory()->LookupAsciiSymbol(builtin_name);
2190 i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
2191 return builtins->GetPropertyNoExceptionThrown(*symbol);
2192}
2193
2194
2195static bool CheckConstructor(i::Isolate* isolate,
2196 i::Handle<i::JSObject> obj,
2197 const char* class_name) {
2198 return obj->map()->constructor() == LookupBuiltin(isolate, class_name);
2199}
2200
2201
2202bool Value::IsNativeError() const {
2203 i::Isolate* isolate = i::Isolate::Current();
2204 if (IsDeadCheck(isolate, "v8::Value::IsNativeError()")) return false;
2205 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2206 if (obj->IsJSObject()) {
2207 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
2208 return CheckConstructor(isolate, js_obj, "$Error") ||
2209 CheckConstructor(isolate, js_obj, "$EvalError") ||
2210 CheckConstructor(isolate, js_obj, "$RangeError") ||
2211 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2212 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2213 CheckConstructor(isolate, js_obj, "$TypeError") ||
2214 CheckConstructor(isolate, js_obj, "$URIError");
2215 } else {
2216 return false;
2217 }
2218}
2219
2220
2221bool Value::IsBooleanObject() const {
2222 i::Isolate* isolate = i::Isolate::Current();
2223 if (IsDeadCheck(isolate, "v8::Value::IsBooleanObject()")) return false;
2224 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2225 return obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol());
2226}
2227
2228
Iain Merrick75681382010-08-19 15:07:18 +01002229bool Value::IsRegExp() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002230 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
Iain Merrick75681382010-08-19 15:07:18 +01002231 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2232 return obj->IsJSRegExp();
2233}
2234
2235
Steve Blocka7e24c12009-10-30 11:49:00 +00002236Local<String> Value::ToString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002237 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2238 i::Handle<i::Object> str;
2239 if (obj->IsString()) {
2240 str = obj;
2241 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002242 i::Isolate* isolate = i::Isolate::Current();
2243 if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
2244 return Local<String>();
2245 }
2246 LOG_API(isolate, "ToString");
2247 ENTER_V8(isolate);
2248 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002249 str = i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002250 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002251 }
2252 return Local<String>(ToApi<String>(str));
2253}
2254
2255
2256Local<String> Value::ToDetailString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002257 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2258 i::Handle<i::Object> str;
2259 if (obj->IsString()) {
2260 str = obj;
2261 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002262 i::Isolate* isolate = i::Isolate::Current();
2263 if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
2264 return Local<String>();
2265 }
2266 LOG_API(isolate, "ToDetailString");
2267 ENTER_V8(isolate);
2268 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002269 str = i::Execution::ToDetailString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002270 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002271 }
2272 return Local<String>(ToApi<String>(str));
2273}
2274
2275
2276Local<v8::Object> Value::ToObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002277 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2278 i::Handle<i::Object> val;
2279 if (obj->IsJSObject()) {
2280 val = obj;
2281 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002282 i::Isolate* isolate = i::Isolate::Current();
2283 if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
2284 return Local<v8::Object>();
2285 }
2286 LOG_API(isolate, "ToObject");
2287 ENTER_V8(isolate);
2288 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002289 val = i::Execution::ToObject(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002290 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002291 }
2292 return Local<v8::Object>(ToApi<Object>(val));
2293}
2294
2295
2296Local<Boolean> Value::ToBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002297 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2298 if (obj->IsBoolean()) {
2299 return Local<Boolean>(ToApi<Boolean>(obj));
2300 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002301 i::Isolate* isolate = i::Isolate::Current();
2302 if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
2303 return Local<Boolean>();
2304 }
2305 LOG_API(isolate, "ToBoolean");
2306 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002307 i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
2308 return Local<Boolean>(ToApi<Boolean>(val));
2309 }
2310}
2311
2312
2313Local<Number> Value::ToNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002314 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2315 i::Handle<i::Object> num;
2316 if (obj->IsNumber()) {
2317 num = obj;
2318 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002319 i::Isolate* isolate = i::Isolate::Current();
2320 if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
2321 return Local<Number>();
2322 }
2323 LOG_API(isolate, "ToNumber");
2324 ENTER_V8(isolate);
2325 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002326 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002327 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002328 }
2329 return Local<Number>(ToApi<Number>(num));
2330}
2331
2332
2333Local<Integer> Value::ToInteger() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002334 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2335 i::Handle<i::Object> num;
2336 if (obj->IsSmi()) {
2337 num = obj;
2338 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002339 i::Isolate* isolate = i::Isolate::Current();
2340 if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
2341 LOG_API(isolate, "ToInteger");
2342 ENTER_V8(isolate);
2343 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002344 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002345 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002346 }
2347 return Local<Integer>(ToApi<Integer>(num));
2348}
2349
2350
2351void External::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002352 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002353 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch257744e2011-11-30 15:57:28 +00002354 ApiCheck(obj->IsForeign(),
Steve Blocka7e24c12009-10-30 11:49:00 +00002355 "v8::External::Cast()",
2356 "Could not convert to external");
2357}
2358
2359
2360void v8::Object::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002361 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002362 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2363 ApiCheck(obj->IsJSObject(),
2364 "v8::Object::Cast()",
2365 "Could not convert to object");
2366}
2367
2368
2369void v8::Function::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002370 if (IsDeadCheck(i::Isolate::Current(), "v8::Function::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002371 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2372 ApiCheck(obj->IsJSFunction(),
2373 "v8::Function::Cast()",
2374 "Could not convert to function");
2375}
2376
2377
2378void v8::String::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002379 if (IsDeadCheck(i::Isolate::Current(), "v8::String::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002380 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2381 ApiCheck(obj->IsString(),
2382 "v8::String::Cast()",
2383 "Could not convert to string");
2384}
2385
2386
2387void v8::Number::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002388 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002389 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2390 ApiCheck(obj->IsNumber(),
2391 "v8::Number::Cast()",
2392 "Could not convert to number");
2393}
2394
2395
2396void v8::Integer::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002397 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002398 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2399 ApiCheck(obj->IsNumber(),
2400 "v8::Integer::Cast()",
2401 "Could not convert to number");
2402}
2403
2404
2405void v8::Array::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002406 if (IsDeadCheck(i::Isolate::Current(), "v8::Array::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002407 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2408 ApiCheck(obj->IsJSArray(),
2409 "v8::Array::Cast()",
2410 "Could not convert to array");
2411}
2412
2413
2414void v8::Date::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002415 i::Isolate* isolate = i::Isolate::Current();
2416 if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002417 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Steve Block44f0eee2011-05-26 01:26:41 +01002418 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
Steve Blocka7e24c12009-10-30 11:49:00 +00002419 "v8::Date::Cast()",
2420 "Could not convert to date");
2421}
2422
2423
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002424void v8::StringObject::CheckCast(v8::Value* that) {
2425 i::Isolate* isolate = i::Isolate::Current();
2426 if (IsDeadCheck(isolate, "v8::StringObject::Cast()")) return;
2427 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2428 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_symbol()),
2429 "v8::StringObject::Cast()",
2430 "Could not convert to StringObject");
2431}
2432
2433
2434void v8::NumberObject::CheckCast(v8::Value* that) {
2435 i::Isolate* isolate = i::Isolate::Current();
2436 if (IsDeadCheck(isolate, "v8::NumberObject::Cast()")) return;
2437 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2438 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_symbol()),
2439 "v8::NumberObject::Cast()",
2440 "Could not convert to NumberObject");
2441}
2442
2443
2444void v8::BooleanObject::CheckCast(v8::Value* that) {
2445 i::Isolate* isolate = i::Isolate::Current();
2446 if (IsDeadCheck(isolate, "v8::BooleanObject::Cast()")) return;
2447 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2448 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol()),
2449 "v8::BooleanObject::Cast()",
2450 "Could not convert to BooleanObject");
2451}
2452
2453
Ben Murdochf87a2032010-10-22 12:50:53 +01002454void v8::RegExp::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002455 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
Ben Murdochf87a2032010-10-22 12:50:53 +01002456 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2457 ApiCheck(obj->IsJSRegExp(),
2458 "v8::RegExp::Cast()",
2459 "Could not convert to regular expression");
2460}
2461
2462
Steve Blocka7e24c12009-10-30 11:49:00 +00002463bool Value::BooleanValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002464 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2465 if (obj->IsBoolean()) {
2466 return obj->IsTrue();
2467 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002468 i::Isolate* isolate = i::Isolate::Current();
2469 if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
2470 LOG_API(isolate, "BooleanValue");
2471 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002472 i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
2473 return value->IsTrue();
2474 }
2475}
2476
2477
2478double Value::NumberValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002479 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2480 i::Handle<i::Object> num;
2481 if (obj->IsNumber()) {
2482 num = obj;
2483 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002484 i::Isolate* isolate = i::Isolate::Current();
2485 if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
2486 return i::OS::nan_value();
2487 }
2488 LOG_API(isolate, "NumberValue");
2489 ENTER_V8(isolate);
2490 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002491 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002492 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002493 }
2494 return num->Number();
2495}
2496
2497
2498int64_t Value::IntegerValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002499 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2500 i::Handle<i::Object> num;
2501 if (obj->IsNumber()) {
2502 num = obj;
2503 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002504 i::Isolate* isolate = i::Isolate::Current();
2505 if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
2506 LOG_API(isolate, "IntegerValue");
2507 ENTER_V8(isolate);
2508 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002509 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002510 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002511 }
2512 if (num->IsSmi()) {
2513 return i::Smi::cast(*num)->value();
2514 } else {
2515 return static_cast<int64_t>(num->Number());
2516 }
2517}
2518
2519
2520Local<Int32> Value::ToInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002521 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2522 i::Handle<i::Object> num;
2523 if (obj->IsSmi()) {
2524 num = obj;
2525 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002526 i::Isolate* isolate = i::Isolate::Current();
2527 if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
2528 LOG_API(isolate, "ToInt32");
2529 ENTER_V8(isolate);
2530 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002531 num = i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002532 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002533 }
2534 return Local<Int32>(ToApi<Int32>(num));
2535}
2536
2537
2538Local<Uint32> Value::ToUint32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002539 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2540 i::Handle<i::Object> num;
2541 if (obj->IsSmi()) {
2542 num = obj;
2543 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002544 i::Isolate* isolate = i::Isolate::Current();
2545 if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
2546 LOG_API(isolate, "ToUInt32");
2547 ENTER_V8(isolate);
2548 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002549 num = i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002550 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002551 }
2552 return Local<Uint32>(ToApi<Uint32>(num));
2553}
2554
2555
2556Local<Uint32> Value::ToArrayIndex() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002557 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2558 if (obj->IsSmi()) {
2559 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2560 return Local<Uint32>();
2561 }
Steve Block44f0eee2011-05-26 01:26:41 +01002562 i::Isolate* isolate = i::Isolate::Current();
2563 if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
2564 LOG_API(isolate, "ToArrayIndex");
2565 ENTER_V8(isolate);
2566 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002567 i::Handle<i::Object> string_obj =
2568 i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002569 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002570 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2571 uint32_t index;
2572 if (str->AsArrayIndex(&index)) {
2573 i::Handle<i::Object> value;
2574 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
2575 value = i::Handle<i::Object>(i::Smi::FromInt(index));
2576 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002577 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002578 }
2579 return Utils::Uint32ToLocal(value);
2580 }
2581 return Local<Uint32>();
2582}
2583
2584
2585int32_t Value::Int32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002586 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2587 if (obj->IsSmi()) {
2588 return i::Smi::cast(*obj)->value();
2589 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002590 i::Isolate* isolate = i::Isolate::Current();
2591 if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
2592 LOG_API(isolate, "Int32Value (slow)");
2593 ENTER_V8(isolate);
2594 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002595 i::Handle<i::Object> num =
2596 i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002597 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002598 if (num->IsSmi()) {
2599 return i::Smi::cast(*num)->value();
2600 } else {
2601 return static_cast<int32_t>(num->Number());
2602 }
2603 }
2604}
2605
2606
2607bool Value::Equals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002608 i::Isolate* isolate = i::Isolate::Current();
2609 if (IsDeadCheck(isolate, "v8::Value::Equals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002610 || EmptyCheck("v8::Value::Equals()", this)
2611 || EmptyCheck("v8::Value::Equals()", that)) {
2612 return false;
2613 }
Steve Block44f0eee2011-05-26 01:26:41 +01002614 LOG_API(isolate, "Equals");
2615 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002616 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2617 i::Handle<i::Object> other = Utils::OpenHandle(*that);
Steve Block1e0659c2011-05-24 12:43:12 +01002618 // If both obj and other are JSObjects, we'd better compare by identity
2619 // immediately when going into JS builtin. The reason is Invoke
2620 // would overwrite global object receiver with global proxy.
2621 if (obj->IsJSObject() && other->IsJSObject()) {
2622 return *obj == *other;
2623 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002624 i::Object** args[1] = { other.location() };
Steve Block44f0eee2011-05-26 01:26:41 +01002625 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002626 i::Handle<i::Object> result =
2627 CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002628 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002629 return *result == i::Smi::FromInt(i::EQUAL);
2630}
2631
2632
2633bool Value::StrictEquals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002634 i::Isolate* isolate = i::Isolate::Current();
2635 if (IsDeadCheck(isolate, "v8::Value::StrictEquals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002636 || EmptyCheck("v8::Value::StrictEquals()", this)
2637 || EmptyCheck("v8::Value::StrictEquals()", that)) {
2638 return false;
2639 }
Steve Block44f0eee2011-05-26 01:26:41 +01002640 LOG_API(isolate, "StrictEquals");
Steve Blocka7e24c12009-10-30 11:49:00 +00002641 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2642 i::Handle<i::Object> other = Utils::OpenHandle(*that);
2643 // Must check HeapNumber first, since NaN !== NaN.
2644 if (obj->IsHeapNumber()) {
2645 if (!other->IsNumber()) return false;
2646 double x = obj->Number();
2647 double y = other->Number();
2648 // Must check explicitly for NaN:s on Windows, but -0 works fine.
2649 return x == y && !isnan(x) && !isnan(y);
2650 } else if (*obj == *other) { // Also covers Booleans.
2651 return true;
2652 } else if (obj->IsSmi()) {
2653 return other->IsNumber() && obj->Number() == other->Number();
2654 } else if (obj->IsString()) {
2655 return other->IsString() &&
2656 i::String::cast(*obj)->Equals(i::String::cast(*other));
2657 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
2658 return other->IsUndefined() || other->IsUndetectableObject();
2659 } else {
2660 return false;
2661 }
2662}
2663
2664
2665uint32_t Value::Uint32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002666 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2667 if (obj->IsSmi()) {
2668 return i::Smi::cast(*obj)->value();
2669 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002670 i::Isolate* isolate = i::Isolate::Current();
2671 if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
2672 LOG_API(isolate, "Uint32Value");
2673 ENTER_V8(isolate);
2674 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002675 i::Handle<i::Object> num =
2676 i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002677 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002678 if (num->IsSmi()) {
2679 return i::Smi::cast(*num)->value();
2680 } else {
2681 return static_cast<uint32_t>(num->Number());
2682 }
2683 }
2684}
2685
2686
2687bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
2688 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002689 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2690 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2691 ENTER_V8(isolate);
2692 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002693 i::Handle<i::Object> self = Utils::OpenHandle(this);
2694 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2695 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002696 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002697 i::Handle<i::Object> obj = i::SetProperty(
2698 self,
2699 key_obj,
2700 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002701 static_cast<PropertyAttributes>(attribs),
2702 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002703 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002704 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002705 return true;
2706}
2707
2708
Steve Block6ded16b2010-05-10 14:33:55 +01002709bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002710 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2711 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2712 ENTER_V8(isolate);
2713 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002714 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2715 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002716 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002717 i::Handle<i::Object> obj = i::SetElement(
2718 self,
2719 index,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002720 value_obj,
2721 i::kNonStrictMode);
Steve Block6ded16b2010-05-10 14:33:55 +01002722 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002723 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Block6ded16b2010-05-10 14:33:55 +01002724 return true;
2725}
2726
2727
Steve Blocka7e24c12009-10-30 11:49:00 +00002728bool v8::Object::ForceSet(v8::Handle<Value> key,
2729 v8::Handle<Value> value,
2730 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002731 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2732 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
2733 ENTER_V8(isolate);
2734 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002735 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2736 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2737 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002738 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002739 i::Handle<i::Object> obj = i::ForceSetProperty(
2740 self,
2741 key_obj,
2742 value_obj,
2743 static_cast<PropertyAttributes>(attribs));
2744 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002745 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002746 return true;
2747}
2748
2749
2750bool v8::Object::ForceDelete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002751 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2752 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
2753 ENTER_V8(isolate);
2754 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002755 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2756 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002757
2758 // When turning on access checks for a global object deoptimize all functions
2759 // as optimized code does not always handle access checks.
2760 i::Deoptimizer::DeoptimizeGlobalObject(*self);
2761
Steve Block44f0eee2011-05-26 01:26:41 +01002762 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002763 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
2764 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002765 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002766 return obj->IsTrue();
2767}
2768
2769
2770Local<Value> v8::Object::Get(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002771 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2772 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2773 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002774 i::Handle<i::Object> self = Utils::OpenHandle(this);
2775 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002776 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002777 i::Handle<i::Object> result = i::GetProperty(self, key_obj);
2778 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002779 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002780 return Utils::ToLocal(result);
2781}
2782
2783
Steve Block6ded16b2010-05-10 14:33:55 +01002784Local<Value> v8::Object::Get(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002785 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2786 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2787 ENTER_V8(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002788 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002789 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002790 i::Handle<i::Object> result = i::GetElement(self, index);
2791 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002792 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Block6ded16b2010-05-10 14:33:55 +01002793 return Utils::ToLocal(result);
2794}
2795
2796
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002797PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
2798 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2799 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
2800 return static_cast<PropertyAttribute>(NONE));
2801 ENTER_V8(isolate);
2802 i::HandleScope scope(isolate);
2803 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2804 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2805 if (!key_obj->IsString()) {
2806 EXCEPTION_PREAMBLE(isolate);
2807 key_obj = i::Execution::ToString(key_obj, &has_pending_exception);
2808 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
2809 }
2810 i::Handle<i::String> key_string = i::Handle<i::String>::cast(key_obj);
2811 PropertyAttributes result = self->GetPropertyAttribute(*key_string);
2812 if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
2813 return static_cast<PropertyAttribute>(result);
2814}
2815
2816
Steve Blocka7e24c12009-10-30 11:49:00 +00002817Local<Value> v8::Object::GetPrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01002818 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2819 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
2820 return Local<v8::Value>());
2821 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002822 i::Handle<i::Object> self = Utils::OpenHandle(this);
2823 i::Handle<i::Object> result = i::GetPrototype(self);
2824 return Utils::ToLocal(result);
2825}
2826
2827
Andrei Popescu402d9372010-02-26 13:31:12 +00002828bool v8::Object::SetPrototype(Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002829 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2830 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
2831 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002832 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2833 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002834 // We do not allow exceptions thrown while setting the prototype
2835 // to propagate outside.
2836 TryCatch try_catch;
Steve Block44f0eee2011-05-26 01:26:41 +01002837 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002838 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2839 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002840 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00002841 return true;
2842}
2843
2844
Steve Blocka7e24c12009-10-30 11:49:00 +00002845Local<Object> v8::Object::FindInstanceInPrototypeChain(
2846 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01002847 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2848 ON_BAILOUT(isolate,
2849 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002850 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01002851 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002852 i::JSObject* object = *Utils::OpenHandle(this);
2853 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2854 while (!object->IsInstanceOf(tmpl_info)) {
2855 i::Object* prototype = object->GetPrototype();
2856 if (!prototype->IsJSObject()) return Local<Object>();
2857 object = i::JSObject::cast(prototype);
2858 }
2859 return Utils::ToLocal(i::Handle<i::JSObject>(object));
2860}
2861
2862
2863Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01002864 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2865 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
2866 return Local<v8::Array>());
2867 ENTER_V8(isolate);
2868 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002869 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2870 i::Handle<i::FixedArray> value =
2871 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
2872 // Because we use caching to speed up enumeration it is important
2873 // to never change the result of the basic enumeration function so
2874 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01002875 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2876 i::Handle<i::JSArray> result =
2877 isolate->factory()->NewJSArrayWithElements(elms);
2878 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00002879}
2880
2881
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002882Local<Array> v8::Object::GetOwnPropertyNames() {
2883 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2884 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
2885 return Local<v8::Array>());
2886 ENTER_V8(isolate);
2887 i::HandleScope scope(isolate);
2888 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2889 i::Handle<i::FixedArray> value =
2890 i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY);
2891 // Because we use caching to speed up enumeration it is important
2892 // to never change the result of the basic enumeration function so
2893 // we clone the result.
2894 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2895 i::Handle<i::JSArray> result =
2896 isolate->factory()->NewJSArrayWithElements(elms);
2897 return Utils::ToLocal(scope.CloseAndEscape(result));
2898}
2899
2900
Steve Blocka7e24c12009-10-30 11:49:00 +00002901Local<String> v8::Object::ObjectProtoToString() {
Steve Block44f0eee2011-05-26 01:26:41 +01002902 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2903 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
2904 return Local<v8::String>());
2905 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002906 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2907
2908 i::Handle<i::Object> name(self->class_name());
2909
2910 // Native implementation of Object.prototype.toString (v8natives.js):
2911 // var c = %ClassOf(this);
2912 // if (c === 'Arguments') c = 'Object';
2913 // return "[object " + c + "]";
2914
2915 if (!name->IsString()) {
2916 return v8::String::New("[object ]");
2917
2918 } else {
2919 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
2920 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
2921 return v8::String::New("[object Object]");
2922
2923 } else {
2924 const char* prefix = "[object ";
2925 Local<String> str = Utils::ToLocal(class_name);
2926 const char* postfix = "]";
2927
Steve Blockd0582a62009-12-15 09:54:21 +00002928 int prefix_len = i::StrLength(prefix);
2929 int str_len = str->Length();
2930 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00002931
Steve Blockd0582a62009-12-15 09:54:21 +00002932 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01002933 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002934
2935 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01002936 char* ptr = buf.start();
Steve Blocka7e24c12009-10-30 11:49:00 +00002937 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
2938 ptr += prefix_len;
2939
2940 // Write real content.
2941 str->WriteAscii(ptr, 0, str_len);
2942 ptr += str_len;
2943
2944 // Write postfix.
2945 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
2946
2947 // Copy the buffer into a heap-allocated string and return it.
Kristian Monsen25f61362010-05-21 11:50:48 +01002948 Local<String> result = v8::String::New(buf.start(), buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002949 return result;
2950 }
2951 }
2952}
2953
2954
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002955Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01002956 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2957 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
2958 return Local<v8::String>());
2959 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002960 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2961 i::Handle<i::String> name(self->constructor_name());
2962 return Utils::ToLocal(name);
2963}
2964
2965
Steve Blocka7e24c12009-10-30 11:49:00 +00002966bool v8::Object::Delete(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002967 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2968 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
2969 ENTER_V8(isolate);
2970 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002971 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2972 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2973 return i::DeleteProperty(self, key_obj)->IsTrue();
2974}
2975
2976
2977bool v8::Object::Has(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002978 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2979 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
2980 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002981 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2982 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2983 return self->HasProperty(*key_obj);
2984}
2985
2986
2987bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002988 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2989 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
2990 return false);
2991 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002992 HandleScope scope;
2993 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2994 return i::DeleteElement(self, index)->IsTrue();
2995}
2996
2997
2998bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002999 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3000 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003001 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3002 return self->HasElement(index);
3003}
3004
3005
Leon Clarkef7060e22010-06-03 12:02:55 +01003006bool Object::SetAccessor(Handle<String> name,
3007 AccessorGetter getter,
3008 AccessorSetter setter,
3009 v8::Handle<Value> data,
3010 AccessControl settings,
3011 PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01003012 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3013 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3014 ENTER_V8(isolate);
3015 i::HandleScope scope(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01003016 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
3017 getter, setter, data,
3018 settings, attributes);
3019 i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
3020 return !result.is_null() && !result->IsUndefined();
3021}
3022
3023
Ben Murdoch257744e2011-11-30 15:57:28 +00003024bool v8::Object::HasOwnProperty(Handle<String> key) {
3025 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3026 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3027 return false);
3028 return Utils::OpenHandle(this)->HasLocalProperty(
3029 *Utils::OpenHandle(*key));
3030}
3031
3032
Steve Blocka7e24c12009-10-30 11:49:00 +00003033bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003034 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3035 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
3036 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003037 return Utils::OpenHandle(this)->HasRealNamedProperty(
3038 *Utils::OpenHandle(*key));
3039}
3040
3041
3042bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01003043 ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
3044 "v8::Object::HasRealIndexedProperty()",
3045 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003046 return Utils::OpenHandle(this)->HasRealElementProperty(index);
3047}
3048
3049
3050bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003051 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3052 ON_BAILOUT(isolate,
3053 "v8::Object::HasRealNamedCallbackProperty()",
3054 return false);
3055 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003056 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
3057 *Utils::OpenHandle(*key));
3058}
3059
3060
3061bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003062 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3063 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
3064 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003065 return Utils::OpenHandle(this)->HasNamedInterceptor();
3066}
3067
3068
3069bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003070 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3071 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
3072 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003073 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3074}
3075
3076
Ben Murdoch8b112d22011-06-08 16:22:53 +01003077static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
3078 i::Handle<i::JSObject> receiver,
3079 i::Handle<i::String> name,
3080 i::LookupResult* lookup) {
3081 if (!lookup->IsProperty()) {
3082 // No real property was found.
3083 return Local<Value>();
3084 }
3085
3086 // If the property being looked up is a callback, it can throw
3087 // an exception.
3088 EXCEPTION_PREAMBLE(isolate);
3089 i::Handle<i::Object> result = i::GetProperty(receiver, name, lookup);
3090 has_pending_exception = result.is_null();
3091 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3092
3093 return Utils::ToLocal(result);
3094}
3095
3096
Steve Blocka7e24c12009-10-30 11:49:00 +00003097Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
3098 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003099 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3100 ON_BAILOUT(isolate,
3101 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003102 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01003103 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003104 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3105 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3106 i::LookupResult lookup;
3107 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003108 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00003109}
3110
3111
3112Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003113 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3114 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
3115 return Local<Value>());
3116 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003117 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3118 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3119 i::LookupResult lookup;
3120 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003121 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00003122}
3123
3124
3125// Turns on access checks by copying the map and setting the check flag.
3126// Because the object gets a new map, existing inline cache caching
3127// the old map of this object will fail.
3128void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01003129 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3130 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
3131 ENTER_V8(isolate);
3132 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003133 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3134
Ben Murdochb0fe1622011-05-05 13:52:32 +01003135 // When turning on access checks for a global object deoptimize all functions
3136 // as optimized code does not always handle access checks.
3137 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3138
Steve Blocka7e24c12009-10-30 11:49:00 +00003139 i::Handle<i::Map> new_map =
Steve Block44f0eee2011-05-26 01:26:41 +01003140 isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003141 new_map->set_is_access_check_needed(true);
3142 obj->set_map(*new_map);
3143}
3144
3145
3146bool v8::Object::IsDirty() {
3147 return Utils::OpenHandle(this)->IsDirty();
3148}
3149
3150
3151Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01003152 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3153 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
3154 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003155 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003156 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003157 i::Handle<i::JSObject> result = i::Copy(self);
3158 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003159 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003160 return Utils::ToLocal(result);
3161}
3162
3163
Ben Murdoch8b112d22011-06-08 16:22:53 +01003164static i::Context* GetCreationContext(i::JSObject* object) {
3165 i::Object* constructor = object->map()->constructor();
3166 i::JSFunction* function;
3167 if (!constructor->IsJSFunction()) {
3168 // API functions have null as a constructor,
3169 // but any JSFunction knows its context immediately.
3170 ASSERT(object->IsJSFunction() &&
3171 i::JSFunction::cast(object)->shared()->IsApiFunction());
3172 function = i::JSFunction::cast(object);
3173 } else {
3174 function = i::JSFunction::cast(constructor);
3175 }
3176 return function->context()->global_context();
3177}
3178
3179
3180Local<v8::Context> v8::Object::CreationContext() {
3181 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3182 ON_BAILOUT(isolate,
3183 "v8::Object::CreationContext()", return Local<v8::Context>());
3184 ENTER_V8(isolate);
3185 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3186 i::Context* context = GetCreationContext(*self);
3187 return Utils::ToLocal(i::Handle<i::Context>(context));
3188}
3189
3190
Steve Blocka7e24c12009-10-30 11:49:00 +00003191int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01003192 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3193 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
3194 ENTER_V8(isolate);
3195 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003196 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block1e0659c2011-05-24 12:43:12 +01003197 i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true));
3198 if (!hidden_props_obj->IsJSObject()) {
3199 // We failed to create hidden properties. That's a detached
3200 // global proxy.
3201 ASSERT(hidden_props_obj->IsUndefined());
3202 return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003203 }
Steve Block1e0659c2011-05-24 12:43:12 +01003204 i::Handle<i::JSObject> hidden_props =
3205 i::Handle<i::JSObject>::cast(hidden_props_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01003206 i::Handle<i::String> hash_symbol = isolate->factory()->identity_hash_symbol();
Steve Block1e0659c2011-05-24 12:43:12 +01003207 if (hidden_props->HasLocalProperty(*hash_symbol)) {
3208 i::Handle<i::Object> hash = i::GetProperty(hidden_props, hash_symbol);
3209 CHECK(!hash.is_null());
3210 CHECK(hash->IsSmi());
3211 return i::Smi::cast(*hash)->value();
3212 }
3213
3214 int hash_value;
3215 int attempts = 0;
3216 do {
3217 // Generate a random 32-bit hash value but limit range to fit
3218 // within a smi.
Steve Block44f0eee2011-05-26 01:26:41 +01003219 hash_value = i::V8::Random(self->GetIsolate()) & i::Smi::kMaxValue;
Steve Block1e0659c2011-05-24 12:43:12 +01003220 attempts++;
3221 } while (hash_value == 0 && attempts < 30);
3222 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
3223 CHECK(!i::SetLocalPropertyIgnoreAttributes(
3224 hidden_props,
3225 hash_symbol,
3226 i::Handle<i::Object>(i::Smi::FromInt(hash_value)),
3227 static_cast<PropertyAttributes>(None)).is_null());
3228
Steve Blocka7e24c12009-10-30 11:49:00 +00003229 return hash_value;
3230}
3231
3232
3233bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3234 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003235 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3236 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
3237 ENTER_V8(isolate);
3238 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003239 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3240 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true));
3241 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3242 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003243 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003244 i::Handle<i::Object> obj = i::SetProperty(
3245 hidden_props,
3246 key_obj,
3247 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01003248 static_cast<PropertyAttributes>(None),
3249 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003250 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003251 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003252 return true;
3253}
3254
3255
3256v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003257 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3258 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3259 return Local<v8::Value>());
3260 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003261 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3262 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
3263 if (hidden_props->IsUndefined()) {
3264 return v8::Local<v8::Value>();
3265 }
3266 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01003267 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003268 i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
3269 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003270 EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003271 if (result->IsUndefined()) {
3272 return v8::Local<v8::Value>();
3273 }
3274 return Utils::ToLocal(result);
3275}
3276
3277
3278bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003279 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3280 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
3281 ENTER_V8(isolate);
3282 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003283 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3284 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
3285 if (hidden_props->IsUndefined()) {
3286 return true;
3287 }
3288 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
3289 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3290 return i::DeleteProperty(js_obj, key_obj)->IsTrue();
3291}
3292
3293
Steve Block44f0eee2011-05-26 01:26:41 +01003294namespace {
3295
3296void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3297 void* data,
3298 ExternalArrayType array_type,
3299 int length) {
3300 i::Isolate* isolate = object->GetIsolate();
3301 i::Handle<i::ExternalArray> array =
3302 isolate->factory()->NewExternalArray(length, array_type, data);
3303
3304 // If the object already has external elements, create a new, unique
3305 // map if the element type is now changing, because assumptions about
3306 // generated code based on the receiver's map will be invalid.
3307 i::Handle<i::HeapObject> elements(object->elements());
3308 bool cant_reuse_map =
3309 elements->map()->IsUndefined() ||
3310 !elements->map()->has_external_array_elements() ||
3311 elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
3312 if (cant_reuse_map) {
3313 i::Handle<i::Map> external_array_map =
3314 isolate->factory()->GetExternalArrayElementsMap(
3315 i::Handle<i::Map>(object->map()),
3316 array_type,
3317 object->HasFastProperties());
3318 object->set_map(*external_array_map);
3319 }
3320 object->set_elements(*array);
3321}
3322
3323} // namespace
3324
3325
Steve Blocka7e24c12009-10-30 11:49:00 +00003326void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003327 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3328 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3329 ENTER_V8(isolate);
3330 i::HandleScope scope(isolate);
3331 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
Steve Blocka7e24c12009-10-30 11:49:00 +00003332 "v8::Object::SetIndexedPropertiesToPixelData()",
3333 "length exceeds max acceptable value")) {
3334 return;
3335 }
3336 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3337 if (!ApiCheck(!self->IsJSArray(),
3338 "v8::Object::SetIndexedPropertiesToPixelData()",
3339 "JSArray is not supported")) {
3340 return;
3341 }
Steve Block44f0eee2011-05-26 01:26:41 +01003342 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003343}
3344
3345
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003346bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003347 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003348 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3349 return false);
3350 return self->HasExternalPixelElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003351}
3352
3353
3354uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003355 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003356 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3357 return NULL);
3358 if (self->HasExternalPixelElements()) {
3359 return i::ExternalPixelArray::cast(self->elements())->
3360 external_pixel_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003361 } else {
3362 return NULL;
3363 }
3364}
3365
3366
3367int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003368 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003369 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3370 return -1);
3371 if (self->HasExternalPixelElements()) {
3372 return i::ExternalPixelArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003373 } else {
3374 return -1;
3375 }
3376}
3377
Steve Block3ce2e202009-11-05 08:53:23 +00003378void v8::Object::SetIndexedPropertiesToExternalArrayData(
3379 void* data,
3380 ExternalArrayType array_type,
3381 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003382 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3383 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3384 ENTER_V8(isolate);
3385 i::HandleScope scope(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003386 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3387 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3388 "length exceeds max acceptable value")) {
3389 return;
3390 }
3391 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3392 if (!ApiCheck(!self->IsJSArray(),
3393 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3394 "JSArray is not supported")) {
3395 return;
3396 }
Steve Block44f0eee2011-05-26 01:26:41 +01003397 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003398}
3399
3400
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003401bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003402 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003403 ON_BAILOUT(self->GetIsolate(),
3404 "v8::HasIndexedPropertiesInExternalArrayData()",
3405 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003406 return self->HasExternalArrayElements();
3407}
3408
3409
3410void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003411 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003412 ON_BAILOUT(self->GetIsolate(),
3413 "v8::GetIndexedPropertiesExternalArrayData()",
3414 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003415 if (self->HasExternalArrayElements()) {
3416 return i::ExternalArray::cast(self->elements())->external_pointer();
3417 } else {
3418 return NULL;
3419 }
3420}
3421
3422
3423ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003424 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003425 ON_BAILOUT(self->GetIsolate(),
3426 "v8::GetIndexedPropertiesExternalArrayDataType()",
3427 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003428 switch (self->elements()->map()->instance_type()) {
3429 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3430 return kExternalByteArray;
3431 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3432 return kExternalUnsignedByteArray;
3433 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3434 return kExternalShortArray;
3435 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3436 return kExternalUnsignedShortArray;
3437 case i::EXTERNAL_INT_ARRAY_TYPE:
3438 return kExternalIntArray;
3439 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3440 return kExternalUnsignedIntArray;
3441 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3442 return kExternalFloatArray;
Ben Murdoch257744e2011-11-30 15:57:28 +00003443 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3444 return kExternalDoubleArray;
Steve Block44f0eee2011-05-26 01:26:41 +01003445 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3446 return kExternalPixelArray;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003447 default:
3448 return static_cast<ExternalArrayType>(-1);
3449 }
3450}
3451
3452
3453int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003454 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003455 ON_BAILOUT(self->GetIsolate(),
3456 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3457 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003458 if (self->HasExternalArrayElements()) {
3459 return i::ExternalArray::cast(self->elements())->length();
3460 } else {
3461 return -1;
3462 }
3463}
3464
3465
Ben Murdoch257744e2011-11-30 15:57:28 +00003466bool v8::Object::IsCallable() {
3467 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3468 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3469 ENTER_V8(isolate);
3470 i::HandleScope scope(isolate);
3471 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3472 if (obj->IsJSFunction()) return true;
3473 return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
3474}
3475
3476
3477Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
3478 v8::Handle<v8::Value> argv[]) {
3479 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3480 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3481 return Local<v8::Value>());
3482 LOG_API(isolate, "Object::CallAsFunction");
3483 ENTER_V8(isolate);
3484 i::HandleScope scope(isolate);
3485 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3486 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3487 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3488 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3489 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3490 if (obj->IsJSFunction()) {
3491 fun = i::Handle<i::JSFunction>::cast(obj);
3492 } else {
3493 EXCEPTION_PREAMBLE(isolate);
3494 i::Handle<i::Object> delegate =
3495 i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
3496 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3497 fun = i::Handle<i::JSFunction>::cast(delegate);
3498 recv_obj = obj;
3499 }
3500 EXCEPTION_PREAMBLE(isolate);
3501 i::Handle<i::Object> returned =
3502 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
3503 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3504 return Utils::ToLocal(scope.CloseAndEscape(returned));
3505}
3506
3507
3508Local<v8::Value> Object::CallAsConstructor(int argc,
3509 v8::Handle<v8::Value> argv[]) {
3510 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3511 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3512 return Local<v8::Object>());
3513 LOG_API(isolate, "Object::CallAsConstructor");
3514 ENTER_V8(isolate);
3515 i::HandleScope scope(isolate);
3516 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3517 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3518 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3519 if (obj->IsJSFunction()) {
3520 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
3521 EXCEPTION_PREAMBLE(isolate);
3522 i::Handle<i::Object> returned =
3523 i::Execution::New(fun, argc, args, &has_pending_exception);
3524 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3525 return Utils::ToLocal(scope.CloseAndEscape(
3526 i::Handle<i::JSObject>::cast(returned)));
3527 }
3528 EXCEPTION_PREAMBLE(isolate);
3529 i::Handle<i::Object> delegate =
3530 i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
3531 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3532 if (!delegate->IsUndefined()) {
3533 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
3534 EXCEPTION_PREAMBLE(isolate);
3535 i::Handle<i::Object> returned =
3536 i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
3537 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3538 ASSERT(!delegate->IsUndefined());
3539 return Utils::ToLocal(scope.CloseAndEscape(returned));
3540 }
3541 return Local<v8::Object>();
3542}
3543
3544
Steve Blocka7e24c12009-10-30 11:49:00 +00003545Local<v8::Object> Function::NewInstance() const {
3546 return NewInstance(0, NULL);
3547}
3548
3549
3550Local<v8::Object> Function::NewInstance(int argc,
3551 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003552 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3553 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3554 return Local<v8::Object>());
3555 LOG_API(isolate, "Function::NewInstance");
3556 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003557 HandleScope scope;
3558 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3559 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3560 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003561 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003562 i::Handle<i::Object> returned =
3563 i::Execution::New(function, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003564 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003565 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3566}
3567
3568
3569Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3570 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01003571 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3572 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3573 LOG_API(isolate, "Function::Call");
3574 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003575 i::Object* raw_result = NULL;
3576 {
Steve Block44f0eee2011-05-26 01:26:41 +01003577 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003578 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3579 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3580 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3581 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003582 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003583 i::Handle<i::Object> returned =
3584 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003585 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003586 raw_result = *returned;
3587 }
3588 i::Handle<i::Object> result(raw_result);
3589 return Utils::ToLocal(result);
3590}
3591
3592
3593void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01003594 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3595 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003596 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003597 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3598 func->shared()->set_name(*Utils::OpenHandle(*name));
3599}
3600
3601
3602Handle<Value> Function::GetName() const {
3603 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3604 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3605}
3606
3607
Andrei Popescu402d9372010-02-26 13:31:12 +00003608ScriptOrigin Function::GetScriptOrigin() const {
3609 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3610 if (func->shared()->script()->IsScript()) {
3611 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3612 v8::ScriptOrigin origin(
3613 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3614 v8::Integer::New(script->line_offset()->value()),
3615 v8::Integer::New(script->column_offset()->value()));
3616 return origin;
3617 }
3618 return v8::ScriptOrigin(Handle<Value>());
3619}
3620
3621
3622const int Function::kLineOffsetNotFound = -1;
3623
3624
3625int Function::GetScriptLineNumber() const {
3626 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3627 if (func->shared()->script()->IsScript()) {
3628 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3629 return i::GetScriptLineNumber(script, func->shared()->start_position());
3630 }
3631 return kLineOffsetNotFound;
3632}
3633
3634
Steve Blocka7e24c12009-10-30 11:49:00 +00003635int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003636 i::Handle<i::String> str = Utils::OpenHandle(this);
3637 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3638 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003639}
3640
3641
3642int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003643 i::Handle<i::String> str = Utils::OpenHandle(this);
3644 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
3645 return str->Utf8Length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003646}
3647
3648
Steve Block6ded16b2010-05-10 14:33:55 +01003649int String::WriteUtf8(char* buffer,
3650 int capacity,
3651 int* nchars_ref,
3652 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003653 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3654 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3655 LOG_API(isolate, "String::WriteUtf8");
3656 ENTER_V8(isolate);
3657 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003658 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003659 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003660 if (hints & HINT_MANY_WRITES_EXPECTED) {
3661 // Flatten the string for efficiency. This applies whether we are
3662 // using StringInputBuffer or Get(i) to access the characters.
3663 str->TryFlatten();
3664 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003665 write_input_buffer.Reset(0, *str);
3666 int len = str->length();
3667 // Encode the first K - 3 bytes directly into the buffer since we
3668 // know there's room for them. If no capacity is given we copy all
3669 // of them here.
3670 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3671 int i;
3672 int pos = 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003673 int nchars = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003674 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3675 i::uc32 c = write_input_buffer.GetNext();
3676 int written = unibrow::Utf8::Encode(buffer + pos, c);
3677 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003678 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003679 }
3680 if (i < len) {
3681 // For the last characters we need to check the length for each one
3682 // because they may be longer than the remaining space in the
3683 // buffer.
3684 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3685 for (; i < len && pos < capacity; i++) {
3686 i::uc32 c = write_input_buffer.GetNext();
3687 int written = unibrow::Utf8::Encode(intermediate, c);
3688 if (pos + written <= capacity) {
3689 for (int j = 0; j < written; j++)
3690 buffer[pos + j] = intermediate[j];
3691 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003692 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003693 } else {
3694 // We've reached the end of the buffer
3695 break;
3696 }
3697 }
3698 }
Steve Block6ded16b2010-05-10 14:33:55 +01003699 if (nchars_ref != NULL) *nchars_ref = nchars;
Steve Blocka7e24c12009-10-30 11:49:00 +00003700 if (i == len && (capacity == -1 || pos < capacity))
3701 buffer[pos++] = '\0';
3702 return pos;
3703}
3704
3705
Steve Block6ded16b2010-05-10 14:33:55 +01003706int String::WriteAscii(char* buffer,
3707 int start,
3708 int length,
3709 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003710 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3711 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3712 LOG_API(isolate, "String::WriteAscii");
3713 ENTER_V8(isolate);
3714 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003715 ASSERT(start >= 0 && length >= -1);
3716 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003717 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003718 if (hints & HINT_MANY_WRITES_EXPECTED) {
3719 // Flatten the string for efficiency. This applies whether we are
3720 // using StringInputBuffer or Get(i) to access the characters.
3721 str->TryFlatten();
3722 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003723 int end = length;
3724 if ( (length == -1) || (length > str->length() - start) )
3725 end = str->length() - start;
3726 if (end < 0) return 0;
3727 write_input_buffer.Reset(start, *str);
3728 int i;
3729 for (i = 0; i < end; i++) {
3730 char c = static_cast<char>(write_input_buffer.GetNext());
3731 if (c == '\0') c = ' ';
3732 buffer[i] = c;
3733 }
3734 if (length == -1 || i < length)
3735 buffer[i] = '\0';
3736 return i;
3737}
3738
3739
Steve Block6ded16b2010-05-10 14:33:55 +01003740int String::Write(uint16_t* buffer,
3741 int start,
3742 int length,
3743 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003744 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3745 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
3746 LOG_API(isolate, "String::Write");
3747 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003748 ASSERT(start >= 0 && length >= -1);
3749 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003750 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003751 if (hints & HINT_MANY_WRITES_EXPECTED) {
3752 // Flatten the string for efficiency. This applies whether we are
3753 // using StringInputBuffer or Get(i) to access the characters.
3754 str->TryFlatten();
3755 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003756 int end = start + length;
3757 if ((length == -1) || (length > str->length() - start) )
3758 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003759 if (end < 0) return 0;
3760 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003761 if (length == -1 || end - start < length) {
3762 buffer[end - start] = '\0';
3763 }
3764 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003765}
3766
3767
3768bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003769 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003770 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
3771 return false;
3772 }
3773 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
Steve Blocka7e24c12009-10-30 11:49:00 +00003774 return i::StringShape(*str).IsExternalTwoByte();
3775}
3776
3777
3778bool v8::String::IsExternalAscii() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003779 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003780 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
3781 return false;
3782 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003783 return i::StringShape(*str).IsExternalAscii();
3784}
3785
3786
3787void v8::String::VerifyExternalStringResource(
3788 v8::String::ExternalStringResource* value) const {
3789 i::Handle<i::String> str = Utils::OpenHandle(this);
3790 v8::String::ExternalStringResource* expected;
3791 if (i::StringShape(*str).IsExternalTwoByte()) {
3792 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
3793 expected = reinterpret_cast<ExternalStringResource*>(resource);
3794 } else {
3795 expected = NULL;
3796 }
3797 CHECK_EQ(expected, value);
3798}
3799
3800
3801v8::String::ExternalAsciiStringResource*
3802 v8::String::GetExternalAsciiStringResource() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003803 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003804 if (IsDeadCheck(str->GetIsolate(),
3805 "v8::String::GetExternalAsciiStringResource()")) {
3806 return NULL;
3807 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003808 if (i::StringShape(*str).IsExternalAscii()) {
3809 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
3810 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
3811 } else {
3812 return NULL;
3813 }
3814}
3815
3816
3817double Number::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003818 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003819 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3820 return obj->Number();
3821}
3822
3823
3824bool Boolean::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003825 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003826 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3827 return obj->IsTrue();
3828}
3829
3830
3831int64_t Integer::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003832 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003833 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3834 if (obj->IsSmi()) {
3835 return i::Smi::cast(*obj)->value();
3836 } else {
3837 return static_cast<int64_t>(obj->Number());
3838 }
3839}
3840
3841
3842int32_t Int32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003843 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003844 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3845 if (obj->IsSmi()) {
3846 return i::Smi::cast(*obj)->value();
3847 } else {
3848 return static_cast<int32_t>(obj->Number());
3849 }
3850}
3851
3852
Steve Block6ded16b2010-05-10 14:33:55 +01003853uint32_t Uint32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003854 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003855 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3856 if (obj->IsSmi()) {
3857 return i::Smi::cast(*obj)->value();
3858 } else {
3859 return static_cast<uint32_t>(obj->Number());
3860 }
3861}
3862
3863
Steve Blocka7e24c12009-10-30 11:49:00 +00003864int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003865 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003866 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
3867 return 0;
3868 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003869 return obj->GetInternalFieldCount();
3870}
3871
3872
3873Local<Value> v8::Object::CheckedGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003874 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003875 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
3876 return Local<Value>();
3877 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003878 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3879 "v8::Object::GetInternalField()",
3880 "Reading internal field out of bounds")) {
3881 return Local<Value>();
3882 }
3883 i::Handle<i::Object> value(obj->GetInternalField(index));
3884 Local<Value> result = Utils::ToLocal(value);
3885#ifdef DEBUG
3886 Local<Value> unchecked = UncheckedGetInternalField(index);
3887 ASSERT(unchecked.IsEmpty() || (unchecked == result));
3888#endif
3889 return result;
3890}
3891
3892
3893void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003894 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003895 i::Isolate* isolate = obj->GetIsolate();
3896 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
3897 return;
3898 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003899 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3900 "v8::Object::SetInternalField()",
3901 "Writing internal field out of bounds")) {
3902 return;
3903 }
Steve Block44f0eee2011-05-26 01:26:41 +01003904 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003905 i::Handle<i::Object> val = Utils::OpenHandle(*value);
3906 obj->SetInternalField(index, *val);
3907}
3908
3909
Ben Murdochb8e0da22011-05-16 14:20:40 +01003910static bool CanBeEncodedAsSmi(void* ptr) {
Steve Block1e0659c2011-05-24 12:43:12 +01003911 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003912 return ((address & i::kEncodablePointerMask) == 0);
3913}
3914
3915
3916static i::Smi* EncodeAsSmi(void* ptr) {
3917 ASSERT(CanBeEncodedAsSmi(ptr));
Steve Block1e0659c2011-05-24 12:43:12 +01003918 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003919 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
3920 ASSERT(i::Internals::HasSmiTag(result));
3921 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
3922 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
3923 return result;
3924}
3925
3926
Steve Blocka7e24c12009-10-30 11:49:00 +00003927void v8::Object::SetPointerInInternalField(int index, void* value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003928 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3929 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003930 if (CanBeEncodedAsSmi(value)) {
3931 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
3932 } else {
3933 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00003934 i::Handle<i::Foreign> foreign =
3935 isolate->factory()->NewForeign(
Steve Block44f0eee2011-05-26 01:26:41 +01003936 reinterpret_cast<i::Address>(value), i::TENURED);
Ben Murdoch257744e2011-11-30 15:57:28 +00003937 if (!foreign.is_null())
3938 Utils::OpenHandle(this)->SetInternalField(index, *foreign);
Steve Block3ce2e202009-11-05 08:53:23 +00003939 }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003940 ASSERT_EQ(value, GetPointerFromInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003941}
3942
3943
3944// --- E n v i r o n m e n t ---
3945
Steve Block44f0eee2011-05-26 01:26:41 +01003946
Steve Blocka7e24c12009-10-30 11:49:00 +00003947bool v8::V8::Initialize() {
Steve Block44f0eee2011-05-26 01:26:41 +01003948 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
3949 if (isolate != NULL && isolate->IsInitialized()) {
3950 return true;
3951 }
3952 return InitializeHelper();
Steve Blocka7e24c12009-10-30 11:49:00 +00003953}
3954
3955
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003956void v8::V8::SetEntropySource(EntropySource source) {
3957 i::V8::SetEntropySource(source);
3958}
3959
3960
Steve Blocka7e24c12009-10-30 11:49:00 +00003961bool v8::V8::Dispose() {
Steve Block44f0eee2011-05-26 01:26:41 +01003962 i::Isolate* isolate = i::Isolate::Current();
3963 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
3964 "v8::V8::Dispose()",
3965 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
3966 return false;
3967 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003968 i::V8::TearDown();
3969 return true;
3970}
3971
3972
Russell Brenner90bac252010-11-18 13:33:46 -08003973HeapStatistics::HeapStatistics(): total_heap_size_(0),
3974 total_heap_size_executable_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01003975 used_heap_size_(0),
3976 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00003977
3978
3979void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
Steve Block44f0eee2011-05-26 01:26:41 +01003980 i::Heap* heap = i::Isolate::Current()->heap();
3981 heap_statistics->set_total_heap_size(heap->CommittedMemory());
Russell Brenner90bac252010-11-18 13:33:46 -08003982 heap_statistics->set_total_heap_size_executable(
Steve Block44f0eee2011-05-26 01:26:41 +01003983 heap->CommittedMemoryExecutable());
3984 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
3985 heap_statistics->set_heap_size_limit(heap->MaxReserved());
Steve Block3ce2e202009-11-05 08:53:23 +00003986}
3987
3988
3989bool v8::V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003990 // Returning true tells the caller that it need not
3991 // continue to call IdleNotification.
Steve Block44f0eee2011-05-26 01:26:41 +01003992 if (!i::Isolate::Current()->IsInitialized()) return true;
Steve Block3ce2e202009-11-05 08:53:23 +00003993 return i::V8::IdleNotification();
Steve Blocka7e24c12009-10-30 11:49:00 +00003994}
3995
3996
3997void v8::V8::LowMemoryNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003998 i::Isolate* isolate = i::Isolate::Current();
3999 if (!isolate->IsInitialized()) return;
4000 isolate->heap()->CollectAllGarbage(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004001}
4002
4003
Steve Block6ded16b2010-05-10 14:33:55 +01004004int v8::V8::ContextDisposedNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004005 i::Isolate* isolate = i::Isolate::Current();
4006 if (!isolate->IsInitialized()) return 0;
4007 return isolate->heap()->NotifyContextDisposed();
Steve Block6ded16b2010-05-10 14:33:55 +01004008}
4009
4010
Steve Blocka7e24c12009-10-30 11:49:00 +00004011const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01004012 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00004013}
4014
4015
4016static i::Handle<i::FunctionTemplateInfo>
4017 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
4018 if (templ->constructor()->IsUndefined()) {
4019 Local<FunctionTemplate> constructor = FunctionTemplate::New();
4020 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
4021 templ->set_constructor(*Utils::OpenHandle(*constructor));
4022 }
4023 return i::Handle<i::FunctionTemplateInfo>(
4024 i::FunctionTemplateInfo::cast(templ->constructor()));
4025}
4026
4027
4028Persistent<Context> v8::Context::New(
4029 v8::ExtensionConfiguration* extensions,
4030 v8::Handle<ObjectTemplate> global_template,
4031 v8::Handle<Value> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01004032 i::Isolate* isolate = i::Isolate::Current();
4033 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
4034 LOG_API(isolate, "Context::New");
4035 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004036
4037 // Enter V8 via an ENTER_V8 scope.
4038 i::Handle<i::Context> env;
4039 {
Steve Block44f0eee2011-05-26 01:26:41 +01004040 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004041 v8::Handle<ObjectTemplate> proxy_template = global_template;
4042 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
4043 i::Handle<i::FunctionTemplateInfo> global_constructor;
4044
4045 if (!global_template.IsEmpty()) {
4046 // Make sure that the global_template has a constructor.
4047 global_constructor =
4048 EnsureConstructor(Utils::OpenHandle(*global_template));
4049
4050 // Create a fresh template for the global proxy object.
4051 proxy_template = ObjectTemplate::New();
4052 proxy_constructor =
4053 EnsureConstructor(Utils::OpenHandle(*proxy_template));
4054
4055 // Set the global template to be the prototype template of
4056 // global proxy template.
4057 proxy_constructor->set_prototype_template(
4058 *Utils::OpenHandle(*global_template));
4059
4060 // Migrate security handlers from global_template to
4061 // proxy_template. Temporarily removing access check
4062 // information from the global template.
4063 if (!global_constructor->access_check_info()->IsUndefined()) {
4064 proxy_constructor->set_access_check_info(
4065 global_constructor->access_check_info());
4066 proxy_constructor->set_needs_access_check(
4067 global_constructor->needs_access_check());
4068 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01004069 global_constructor->set_access_check_info(
4070 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004071 }
4072 }
4073
4074 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01004075 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdoch257744e2011-11-30 15:57:28 +00004076 isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004077 Utils::OpenHandle(*global_object),
4078 proxy_template,
4079 extensions);
4080
4081 // Restore the access check info on the global template.
4082 if (!global_template.IsEmpty()) {
4083 ASSERT(!global_constructor.is_null());
4084 ASSERT(!proxy_constructor.is_null());
4085 global_constructor->set_access_check_info(
4086 proxy_constructor->access_check_info());
4087 global_constructor->set_needs_access_check(
4088 proxy_constructor->needs_access_check());
4089 }
Steve Block44f0eee2011-05-26 01:26:41 +01004090 isolate->runtime_profiler()->Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +00004091 }
4092 // Leave V8.
4093
4094 if (env.is_null())
4095 return Persistent<Context>();
4096 return Persistent<Context>(Utils::ToLocal(env));
4097}
4098
4099
4100void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01004101 i::Isolate* isolate = i::Isolate::Current();
4102 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
4103 return;
4104 }
4105 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004106 i::Handle<i::Context> env = Utils::OpenHandle(this);
4107 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
4108 env->set_security_token(*token_handle);
4109}
4110
4111
4112void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01004113 i::Isolate* isolate = i::Isolate::Current();
4114 if (IsDeadCheck(isolate,
4115 "v8::Context::UseDefaultSecurityToken()")) {
4116 return;
4117 }
4118 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004119 i::Handle<i::Context> env = Utils::OpenHandle(this);
4120 env->set_security_token(env->global());
4121}
4122
4123
4124Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01004125 i::Isolate* isolate = i::Isolate::Current();
4126 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
4127 return Handle<Value>();
4128 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004129 i::Handle<i::Context> env = Utils::OpenHandle(this);
4130 i::Object* security_token = env->security_token();
4131 i::Handle<i::Object> token_handle(security_token);
4132 return Utils::ToLocal(token_handle);
4133}
4134
4135
4136bool Context::HasOutOfMemoryException() {
4137 i::Handle<i::Context> env = Utils::OpenHandle(this);
4138 return env->has_out_of_memory();
4139}
4140
4141
4142bool Context::InContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01004143 return i::Isolate::Current()->context() != NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00004144}
4145
4146
4147v8::Local<v8::Context> Context::GetEntered() {
Steve Block44f0eee2011-05-26 01:26:41 +01004148 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00004149 if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
Steve Block44f0eee2011-05-26 01:26:41 +01004150 return Local<Context>();
4151 }
4152 i::Handle<i::Object> last =
4153 isolate->handle_scope_implementer()->LastEnteredContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00004154 if (last.is_null()) return Local<Context>();
4155 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
4156 return Utils::ToLocal(context);
4157}
4158
4159
4160v8::Local<v8::Context> Context::GetCurrent() {
Steve Block44f0eee2011-05-26 01:26:41 +01004161 i::Isolate* isolate = i::Isolate::Current();
4162 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
4163 return Local<Context>();
4164 }
4165 i::Handle<i::Object> current = isolate->global_context();
Steve Block3ce2e202009-11-05 08:53:23 +00004166 if (current.is_null()) return Local<Context>();
4167 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
Steve Blocka7e24c12009-10-30 11:49:00 +00004168 return Utils::ToLocal(context);
4169}
4170
4171
4172v8::Local<v8::Context> Context::GetCalling() {
Steve Block44f0eee2011-05-26 01:26:41 +01004173 i::Isolate* isolate = i::Isolate::Current();
4174 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
4175 return Local<Context>();
4176 }
4177 i::Handle<i::Object> calling =
4178 isolate->GetCallingGlobalContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00004179 if (calling.is_null()) return Local<Context>();
4180 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
4181 return Utils::ToLocal(context);
4182}
4183
4184
4185v8::Local<v8::Object> Context::Global() {
Steve Block44f0eee2011-05-26 01:26:41 +01004186 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
4187 return Local<v8::Object>();
4188 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004189 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4190 i::Handle<i::Context> context =
4191 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4192 i::Handle<i::Object> global(context->global_proxy());
4193 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
4194}
4195
4196
4197void Context::DetachGlobal() {
Steve Block44f0eee2011-05-26 01:26:41 +01004198 i::Isolate* isolate = i::Isolate::Current();
4199 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
4200 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004201 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4202 i::Handle<i::Context> context =
4203 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01004204 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00004205}
4206
4207
Andrei Popescu74b3c142010-03-29 12:03:09 +01004208void Context::ReattachGlobal(Handle<Object> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01004209 i::Isolate* isolate = i::Isolate::Current();
4210 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
4211 ENTER_V8(isolate);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004212 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4213 i::Handle<i::Context> context =
4214 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01004215 isolate->bootstrapper()->ReattachGlobal(
4216 context,
4217 Utils::OpenHandle(*global_object));
4218}
4219
4220
Ben Murdoch257744e2011-11-30 15:57:28 +00004221void Context::AllowCodeGenerationFromStrings(bool allow) {
4222 i::Isolate* isolate = i::Isolate::Current();
4223 if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
4224 return;
4225 }
4226 ENTER_V8(isolate);
4227 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4228 i::Handle<i::Context> context =
4229 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4230 context->set_allow_code_gen_from_strings(
4231 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
4232}
4233
4234
Steve Block44f0eee2011-05-26 01:26:41 +01004235void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
4236 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004237}
4238
4239
Steve Blocka7e24c12009-10-30 11:49:00 +00004240Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01004241 i::Isolate* isolate = i::Isolate::Current();
4242 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
4243 return Local<v8::Object>());
4244 LOG_API(isolate, "ObjectTemplate::NewInstance");
4245 ENTER_V8(isolate);
4246 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004247 i::Handle<i::Object> obj =
4248 i::Execution::InstantiateObject(Utils::OpenHandle(this),
4249 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004250 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004251 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
4252}
4253
4254
4255Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01004256 i::Isolate* isolate = i::Isolate::Current();
4257 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00004258 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01004259 LOG_API(isolate, "FunctionTemplate::GetFunction");
4260 ENTER_V8(isolate);
4261 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004262 i::Handle<i::Object> obj =
4263 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
4264 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004265 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004266 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
4267}
4268
4269
4270bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004271 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
4272 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004273 i::Object* obj = *Utils::OpenHandle(*value);
4274 return obj->IsInstanceOf(*Utils::OpenHandle(this));
4275}
4276
4277
4278static Local<External> ExternalNewImpl(void* data) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004279 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004280}
4281
4282static void* ExternalValueImpl(i::Handle<i::Object> obj) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004283 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->address());
Steve Blocka7e24c12009-10-30 11:49:00 +00004284}
4285
4286
Steve Blocka7e24c12009-10-30 11:49:00 +00004287Local<Value> v8::External::Wrap(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004288 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004289 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Ben Murdoch6d7cb002011-08-04 19:25:22 +01004290 LOG_API(isolate, "External::Wrap");
Ben Murdoch257744e2011-11-30 15:57:28 +00004291 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
Steve Block44f0eee2011-05-26 01:26:41 +01004292 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004293
4294 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
4295 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
4296 : v8::Local<v8::Value>(ExternalNewImpl(data));
4297
4298 ASSERT_EQ(data, Unwrap(result));
4299 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004300}
4301
4302
Steve Block3ce2e202009-11-05 08:53:23 +00004303void* v8::Object::SlowGetPointerFromInternalField(int index) {
4304 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4305 i::Object* value = obj->GetInternalField(index);
4306 if (value->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004307 return i::Internals::GetExternalPointerFromSmi(value);
Ben Murdoch257744e2011-11-30 15:57:28 +00004308 } else if (value->IsForeign()) {
4309 return reinterpret_cast<void*>(i::Foreign::cast(value)->address());
Steve Block3ce2e202009-11-05 08:53:23 +00004310 } else {
4311 return NULL;
4312 }
4313}
4314
4315
Steve Blocka7e24c12009-10-30 11:49:00 +00004316void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
Steve Block44f0eee2011-05-26 01:26:41 +01004317 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004318 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
4319 void* result;
4320 if (obj->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004321 result = i::Internals::GetExternalPointerFromSmi(*obj);
Ben Murdoch257744e2011-11-30 15:57:28 +00004322 } else if (obj->IsForeign()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004323 result = ExternalValueImpl(obj);
4324 } else {
4325 result = NULL;
4326 }
4327 ASSERT_EQ(result, QuickUnwrap(wrapper));
4328 return result;
4329}
4330
4331
4332Local<External> v8::External::New(void* data) {
4333 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01004334 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch6d7cb002011-08-04 19:25:22 +01004335 LOG_API(isolate, "External::New");
Ben Murdoch257744e2011-11-30 15:57:28 +00004336 EnsureInitializedForIsolate(isolate, "v8::External::New()");
Steve Block44f0eee2011-05-26 01:26:41 +01004337 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004338 return ExternalNewImpl(data);
4339}
4340
4341
4342void* External::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004343 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004344 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4345 return ExternalValueImpl(obj);
4346}
4347
4348
4349Local<String> v8::String::Empty() {
Steve Block44f0eee2011-05-26 01:26:41 +01004350 i::Isolate* isolate = i::Isolate::Current();
4351 EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
4352 LOG_API(isolate, "String::Empty()");
4353 return Utils::ToLocal(isolate->factory()->empty_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00004354}
4355
4356
4357Local<String> v8::String::New(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004358 i::Isolate* isolate = i::Isolate::Current();
4359 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4360 LOG_API(isolate, "String::New(char)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004361 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004362 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004363 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004364 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004365 isolate->factory()->NewStringFromUtf8(
4366 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004367 return Utils::ToLocal(result);
4368}
4369
4370
Steve Block3ce2e202009-11-05 08:53:23 +00004371Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00004372 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01004373 i::Isolate* isolate = left_string->GetIsolate();
4374 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4375 LOG_API(isolate, "String::New(char)");
4376 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00004377 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Steve Block44f0eee2011-05-26 01:26:41 +01004378 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
4379 right_string);
Steve Block3ce2e202009-11-05 08:53:23 +00004380 return Utils::ToLocal(result);
4381}
4382
4383
Steve Blocka7e24c12009-10-30 11:49:00 +00004384Local<String> v8::String::NewUndetectable(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004385 i::Isolate* isolate = i::Isolate::Current();
4386 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4387 LOG_API(isolate, "String::NewUndetectable(char)");
4388 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004389 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004390 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004391 isolate->factory()->NewStringFromUtf8(
4392 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004393 result->MarkAsUndetectable();
4394 return Utils::ToLocal(result);
4395}
4396
4397
4398static int TwoByteStringLength(const uint16_t* data) {
4399 int length = 0;
4400 while (data[length] != '\0') length++;
4401 return length;
4402}
4403
4404
4405Local<String> v8::String::New(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004406 i::Isolate* isolate = i::Isolate::Current();
4407 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4408 LOG_API(isolate, "String::New(uint16_)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004409 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004410 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004411 if (length == -1) length = TwoByteStringLength(data);
4412 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004413 isolate->factory()->NewStringFromTwoByte(
4414 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004415 return Utils::ToLocal(result);
4416}
4417
4418
4419Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004420 i::Isolate* isolate = i::Isolate::Current();
4421 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4422 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4423 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004424 if (length == -1) length = TwoByteStringLength(data);
4425 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004426 isolate->factory()->NewStringFromTwoByte(
4427 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004428 result->MarkAsUndetectable();
4429 return Utils::ToLocal(result);
4430}
4431
4432
Steve Block44f0eee2011-05-26 01:26:41 +01004433i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004434 v8::String::ExternalStringResource* resource) {
4435 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004436 isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004437 return result;
4438}
4439
4440
Steve Block44f0eee2011-05-26 01:26:41 +01004441i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004442 v8::String::ExternalAsciiStringResource* resource) {
4443 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004444 isolate->factory()->NewExternalStringFromAscii(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004445 return result;
4446}
4447
4448
Steve Blocka7e24c12009-10-30 11:49:00 +00004449Local<String> v8::String::NewExternal(
4450 v8::String::ExternalStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004451 i::Isolate* isolate = i::Isolate::Current();
4452 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4453 LOG_API(isolate, "String::NewExternal");
4454 ENTER_V8(isolate);
4455 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4456 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004457 return Utils::ToLocal(result);
4458}
4459
4460
4461bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004462 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004463 i::Isolate* isolate = obj->GetIsolate();
4464 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4465 if (i::StringShape(*obj).IsExternalTwoByte()) {
4466 return false; // Already an external string.
4467 }
4468 ENTER_V8(isolate);
4469 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4470 return false;
4471 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004472 if (isolate->heap()->IsInGCPostProcessing()) {
4473 return false;
4474 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004475 bool result = obj->MakeExternal(resource);
4476 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004477 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004478 }
4479 return result;
4480}
4481
4482
4483Local<String> v8::String::NewExternal(
4484 v8::String::ExternalAsciiStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004485 i::Isolate* isolate = i::Isolate::Current();
4486 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4487 LOG_API(isolate, "String::NewExternal");
4488 ENTER_V8(isolate);
4489 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4490 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004491 return Utils::ToLocal(result);
4492}
4493
4494
4495bool v8::String::MakeExternal(
4496 v8::String::ExternalAsciiStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004497 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004498 i::Isolate* isolate = obj->GetIsolate();
4499 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4500 if (i::StringShape(*obj).IsExternalTwoByte()) {
4501 return false; // Already an external string.
4502 }
4503 ENTER_V8(isolate);
4504 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4505 return false;
4506 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004507 if (isolate->heap()->IsInGCPostProcessing()) {
4508 return false;
4509 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004510 bool result = obj->MakeExternal(resource);
4511 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004512 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004513 }
4514 return result;
4515}
4516
4517
4518bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004519 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004520 i::Isolate* isolate = obj->GetIsolate();
4521 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4522 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4523 return false;
4524 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004525 int size = obj->Size(); // Byte size of the original string.
4526 if (size < i::ExternalString::kSize)
4527 return false;
4528 i::StringShape shape(*obj);
4529 return !shape.IsExternal();
4530}
4531
4532
4533Local<v8::Object> v8::Object::New() {
Steve Block44f0eee2011-05-26 01:26:41 +01004534 i::Isolate* isolate = i::Isolate::Current();
4535 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4536 LOG_API(isolate, "Object::New");
4537 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004538 i::Handle<i::JSObject> obj =
Steve Block44f0eee2011-05-26 01:26:41 +01004539 isolate->factory()->NewJSObject(isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00004540 return Utils::ToLocal(obj);
4541}
4542
4543
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004544Local<v8::Value> v8::NumberObject::New(double value) {
4545 i::Isolate* isolate = i::Isolate::Current();
4546 EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
4547 LOG_API(isolate, "NumberObject::New");
4548 ENTER_V8(isolate);
4549 i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
4550 i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
4551 return Utils::ToLocal(obj);
4552}
4553
4554
4555double v8::NumberObject::NumberValue() const {
4556 i::Isolate* isolate = i::Isolate::Current();
4557 if (IsDeadCheck(isolate, "v8::NumberObject::NumberValue()")) return 0;
4558 LOG_API(isolate, "NumberObject::NumberValue");
4559 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4560 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4561 return jsvalue->value()->Number();
4562}
4563
4564
4565Local<v8::Value> v8::BooleanObject::New(bool value) {
4566 i::Isolate* isolate = i::Isolate::Current();
4567 EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
4568 LOG_API(isolate, "BooleanObject::New");
4569 ENTER_V8(isolate);
4570 i::Handle<i::Object> boolean(value ? isolate->heap()->true_value()
4571 : isolate->heap()->false_value());
4572 i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
4573 return Utils::ToLocal(obj);
4574}
4575
4576
4577bool v8::BooleanObject::BooleanValue() const {
4578 i::Isolate* isolate = i::Isolate::Current();
4579 if (IsDeadCheck(isolate, "v8::BooleanObject::BooleanValue()")) return 0;
4580 LOG_API(isolate, "BooleanObject::BooleanValue");
4581 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4582 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4583 return jsvalue->value()->IsTrue();
4584}
4585
4586
4587Local<v8::Value> v8::StringObject::New(Handle<String> value) {
4588 i::Isolate* isolate = i::Isolate::Current();
4589 EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
4590 LOG_API(isolate, "StringObject::New");
4591 ENTER_V8(isolate);
4592 i::Handle<i::Object> obj =
4593 isolate->factory()->ToObject(Utils::OpenHandle(*value));
4594 return Utils::ToLocal(obj);
4595}
4596
4597
4598Local<v8::String> v8::StringObject::StringValue() const {
4599 i::Isolate* isolate = i::Isolate::Current();
4600 if (IsDeadCheck(isolate, "v8::StringObject::StringValue()")) {
4601 return Local<v8::String>();
4602 }
4603 LOG_API(isolate, "StringObject::StringValue");
4604 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4605 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4606 return Utils::ToLocal(
4607 i::Handle<i::String>(i::String::cast(jsvalue->value())));
4608}
4609
4610
Steve Blocka7e24c12009-10-30 11:49:00 +00004611Local<v8::Value> v8::Date::New(double time) {
Steve Block44f0eee2011-05-26 01:26:41 +01004612 i::Isolate* isolate = i::Isolate::Current();
4613 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4614 LOG_API(isolate, "Date::New");
Steve Blockd0582a62009-12-15 09:54:21 +00004615 if (isnan(time)) {
4616 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4617 time = i::OS::nan_value();
4618 }
Steve Block44f0eee2011-05-26 01:26:41 +01004619 ENTER_V8(isolate);
4620 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004621 i::Handle<i::Object> obj =
4622 i::Execution::NewDate(time, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004623 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004624 return Utils::ToLocal(obj);
4625}
4626
4627
4628double v8::Date::NumberValue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004629 i::Isolate* isolate = i::Isolate::Current();
4630 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4631 LOG_API(isolate, "Date::NumberValue");
Steve Blocka7e24c12009-10-30 11:49:00 +00004632 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4633 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4634 return jsvalue->value()->Number();
4635}
4636
4637
Ben Murdochb0fe1622011-05-05 13:52:32 +01004638void v8::Date::DateTimeConfigurationChangeNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004639 i::Isolate* isolate = i::Isolate::Current();
4640 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4641 return);
4642 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
4643 ENTER_V8(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004644
Steve Block44f0eee2011-05-26 01:26:41 +01004645 i::HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004646 // Get the function ResetDateCache (defined in date-delay.js).
4647 i::Handle<i::String> func_name_str =
Steve Block44f0eee2011-05-26 01:26:41 +01004648 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4649 i::MaybeObject* result =
4650 isolate->js_builtins_object()->GetProperty(*func_name_str);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004651 i::Object* object_func;
4652 if (!result->ToObject(&object_func)) {
4653 return;
4654 }
4655
4656 if (object_func->IsJSFunction()) {
4657 i::Handle<i::JSFunction> func =
4658 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4659
4660 // Call ResetDateCache(0 but expect no exceptions:
4661 bool caught_exception = false;
Ben Murdoch8b112d22011-06-08 16:22:53 +01004662 i::Execution::TryCall(func,
4663 isolate->js_builtins_object(),
4664 0,
4665 NULL,
4666 &caught_exception);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004667 }
4668}
4669
4670
Ben Murdochf87a2032010-10-22 12:50:53 +01004671static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4672 char flags_buf[3];
4673 int num_flags = 0;
4674 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4675 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4676 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4677 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
Steve Block44f0eee2011-05-26 01:26:41 +01004678 return FACTORY->LookupSymbol(
Ben Murdochf87a2032010-10-22 12:50:53 +01004679 i::Vector<const char>(flags_buf, num_flags));
4680}
4681
4682
4683Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4684 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01004685 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
4686 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
4687 LOG_API(isolate, "RegExp::New");
4688 ENTER_V8(isolate);
4689 EXCEPTION_PREAMBLE(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01004690 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
4691 Utils::OpenHandle(*pattern),
4692 RegExpFlagsToString(flags),
4693 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004694 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01004695 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
4696}
4697
4698
4699Local<v8::String> v8::RegExp::GetSource() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004700 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4701 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
4702 return Local<v8::String>();
4703 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004704 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4705 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
4706}
4707
4708
4709// Assert that the static flags cast in GetFlags is valid.
4710#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
4711 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
4712 static_cast<int>(i::JSRegExp::internal_flag))
4713REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
4714REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
4715REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
4716REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
4717#undef REGEXP_FLAG_ASSERT_EQ
4718
4719v8::RegExp::Flags v8::RegExp::GetFlags() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004720 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
4721 return v8::RegExp::kNone;
4722 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004723 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4724 return static_cast<RegExp::Flags>(obj->GetFlags().value());
4725}
4726
4727
Steve Blocka7e24c12009-10-30 11:49:00 +00004728Local<v8::Array> v8::Array::New(int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004729 i::Isolate* isolate = i::Isolate::Current();
4730 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
4731 LOG_API(isolate, "Array::New");
4732 ENTER_V8(isolate);
4733 int real_length = length > 0 ? length : 0;
4734 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004735 i::Handle<i::Object> length_obj =
4736 isolate->factory()->NewNumberFromInt(real_length);
4737 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004738 return Utils::ToLocal(obj);
4739}
4740
4741
4742uint32_t v8::Array::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004743 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4744 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004745 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
4746 i::Object* length = obj->length();
4747 if (length->IsSmi()) {
4748 return i::Smi::cast(length)->value();
4749 } else {
4750 return static_cast<uint32_t>(length->Number());
4751 }
4752}
4753
4754
4755Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01004756 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4757 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004758 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
4759 if (!self->HasFastElements()) {
4760 return Local<Object>();
4761 }
4762 i::FixedArray* elms = i::FixedArray::cast(self->elements());
4763 i::Object* paragon = elms->get(index);
4764 if (!paragon->IsJSObject()) {
4765 return Local<Object>();
4766 }
4767 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01004768 EXCEPTION_PREAMBLE(isolate);
4769 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004770 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
4771 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01004772 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004773 return Utils::ToLocal(result);
4774}
4775
4776
4777Local<String> v8::String::NewSymbol(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004778 i::Isolate* isolate = i::Isolate::Current();
4779 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
4780 LOG_API(isolate, "String::NewSymbol(char)");
4781 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004782 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004783 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004784 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004785 return Utils::ToLocal(result);
4786}
4787
4788
4789Local<Number> v8::Number::New(double value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004790 i::Isolate* isolate = i::Isolate::Current();
4791 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
Steve Blockd0582a62009-12-15 09:54:21 +00004792 if (isnan(value)) {
4793 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4794 value = i::OS::nan_value();
4795 }
Steve Block44f0eee2011-05-26 01:26:41 +01004796 ENTER_V8(isolate);
4797 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004798 return Utils::NumberToLocal(result);
4799}
4800
4801
4802Local<Integer> v8::Integer::New(int32_t value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004803 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4804 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004805 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004806 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
4807 isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004808 }
Steve Block44f0eee2011-05-26 01:26:41 +01004809 ENTER_V8(isolate);
4810 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004811 return Utils::IntegerToLocal(result);
4812}
4813
4814
Steve Block3ce2e202009-11-05 08:53:23 +00004815Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
4816 bool fits_into_int32_t = (value & (1 << 31)) == 0;
4817 if (fits_into_int32_t) {
4818 return Integer::New(static_cast<int32_t>(value));
4819 }
Steve Block44f0eee2011-05-26 01:26:41 +01004820 i::Isolate* isolate = i::Isolate::Current();
4821 ENTER_V8(isolate);
4822 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00004823 return Utils::IntegerToLocal(result);
4824}
4825
4826
Steve Blocka7e24c12009-10-30 11:49:00 +00004827void V8::IgnoreOutOfMemoryException() {
Ben Murdoch257744e2011-11-30 15:57:28 +00004828 EnterIsolateIfNeeded()->handle_scope_implementer()->set_ignore_out_of_memory(
4829 true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004830}
4831
4832
4833bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004834 i::Isolate* isolate = i::Isolate::Current();
4835 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
4836 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
4837 ENTER_V8(isolate);
4838 i::HandleScope scope(isolate);
4839 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004840 NeanderObject obj(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00004841 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004842 obj.set(1, data.IsEmpty() ?
Steve Block44f0eee2011-05-26 01:26:41 +01004843 isolate->heap()->undefined_value() :
Steve Blocka7e24c12009-10-30 11:49:00 +00004844 *Utils::OpenHandle(*data));
4845 listeners.add(obj.value());
4846 return true;
4847}
4848
4849
4850void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01004851 i::Isolate* isolate = i::Isolate::Current();
4852 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
4853 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
4854 ENTER_V8(isolate);
4855 i::HandleScope scope(isolate);
4856 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004857 for (int i = 0; i < listeners.length(); i++) {
4858 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
4859
4860 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
Ben Murdoch257744e2011-11-30 15:57:28 +00004861 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
4862 if (callback_obj->address() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004863 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004864 }
4865 }
4866}
4867
4868
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004869void V8::SetCaptureStackTraceForUncaughtExceptions(
4870 bool capture,
4871 int frame_limit,
4872 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01004873 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004874 capture,
4875 frame_limit,
4876 options);
4877}
4878
4879
Steve Blocka7e24c12009-10-30 11:49:00 +00004880void V8::SetCounterFunction(CounterLookupCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004881 i::Isolate* isolate = EnterIsolateIfNeeded();
4882 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
4883 isolate->stats_table()->SetCounterFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004884}
4885
4886void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004887 i::Isolate* isolate = EnterIsolateIfNeeded();
4888 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
4889 isolate->stats_table()->SetCreateHistogramFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004890}
4891
4892void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004893 i::Isolate* isolate = EnterIsolateIfNeeded();
4894 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
4895 isolate->stats_table()->
4896 SetAddHistogramSampleFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004897}
4898
4899void V8::EnableSlidingStateWindow() {
Steve Block44f0eee2011-05-26 01:26:41 +01004900 i::Isolate* isolate = i::Isolate::Current();
4901 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
4902 isolate->logger()->EnableSlidingStateWindow();
Steve Blocka7e24c12009-10-30 11:49:00 +00004903}
4904
4905
4906void V8::SetFailedAccessCheckCallbackFunction(
4907 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004908 i::Isolate* isolate = i::Isolate::Current();
4909 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
4910 return;
4911 }
4912 isolate->SetFailedAccessCheckCallback(callback);
4913}
4914
4915void V8::AddObjectGroup(Persistent<Value>* objects,
4916 size_t length,
4917 RetainedObjectInfo* info) {
4918 i::Isolate* isolate = i::Isolate::Current();
4919 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
4920 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
4921 isolate->global_handles()->AddObjectGroup(
4922 reinterpret_cast<i::Object***>(objects), length, info);
Steve Blocka7e24c12009-10-30 11:49:00 +00004923}
4924
4925
Steve Block44f0eee2011-05-26 01:26:41 +01004926void V8::AddImplicitReferences(Persistent<Object> parent,
4927 Persistent<Value>* children,
4928 size_t length) {
4929 i::Isolate* isolate = i::Isolate::Current();
4930 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004931 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
Steve Block44f0eee2011-05-26 01:26:41 +01004932 isolate->global_handles()->AddImplicitReferences(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004933 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*parent)).location(),
Steve Block44f0eee2011-05-26 01:26:41 +01004934 reinterpret_cast<i::Object***>(children), length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004935}
4936
4937
4938int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
Steve Block44f0eee2011-05-26 01:26:41 +01004939 i::Isolate* isolate = i::Isolate::Current();
4940 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
4941 return 0;
4942 }
4943 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
4944 change_in_bytes);
Steve Blocka7e24c12009-10-30 11:49:00 +00004945}
4946
4947
4948void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004949 i::Isolate* isolate = i::Isolate::Current();
4950 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
4951 isolate->heap()->SetGlobalGCPrologueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004952}
4953
4954
4955void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004956 i::Isolate* isolate = i::Isolate::Current();
4957 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
4958 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004959}
4960
4961
Steve Block6ded16b2010-05-10 14:33:55 +01004962void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004963 i::Isolate* isolate = i::Isolate::Current();
4964 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
4965 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004966}
4967
4968
4969void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004970 i::Isolate* isolate = i::Isolate::Current();
4971 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
4972 isolate->heap()->RemoveGCPrologueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004973}
4974
4975
4976void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004977 i::Isolate* isolate = i::Isolate::Current();
4978 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
4979 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004980}
4981
4982
4983void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004984 i::Isolate* isolate = i::Isolate::Current();
4985 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
4986 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004987}
4988
4989
Iain Merrick9ac36c92010-09-13 15:29:50 +01004990void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
4991 ObjectSpace space,
4992 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01004993 i::Isolate* isolate = i::Isolate::Current();
4994 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
4995 isolate->memory_allocator()->AddMemoryAllocationCallback(
4996 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004997}
4998
4999
5000void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01005001 i::Isolate* isolate = i::Isolate::Current();
5002 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
5003 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
5004 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01005005}
5006
5007
Steve Blocka7e24c12009-10-30 11:49:00 +00005008void V8::PauseProfiler() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005009 i::Isolate* isolate = i::Isolate::Current();
5010 isolate->logger()->PauseProfiler();
Steve Blocka7e24c12009-10-30 11:49:00 +00005011}
5012
5013
5014void V8::ResumeProfiler() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005015 i::Isolate* isolate = i::Isolate::Current();
5016 isolate->logger()->ResumeProfiler();
Steve Blocka7e24c12009-10-30 11:49:00 +00005017}
5018
5019
5020bool V8::IsProfilerPaused() {
Steve Block44f0eee2011-05-26 01:26:41 +01005021 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005022 return isolate->logger()->IsProfilerPaused();
Steve Blocka7e24c12009-10-30 11:49:00 +00005023}
5024
5025
5026int V8::GetCurrentThreadId() {
Steve Block44f0eee2011-05-26 01:26:41 +01005027 i::Isolate* isolate = i::Isolate::Current();
5028 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
Ben Murdoch8b112d22011-06-08 16:22:53 +01005029 return isolate->thread_id().ToInteger();
Steve Blocka7e24c12009-10-30 11:49:00 +00005030}
5031
5032
5033void V8::TerminateExecution(int thread_id) {
Steve Block44f0eee2011-05-26 01:26:41 +01005034 i::Isolate* isolate = i::Isolate::Current();
5035 if (!isolate->IsInitialized()) return;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005036 API_ENTRY_CHECK(isolate, "V8::TerminateExecution()");
Steve Blocka7e24c12009-10-30 11:49:00 +00005037 // If the thread_id identifies the current thread just terminate
5038 // execution right away. Otherwise, ask the thread manager to
5039 // terminate the thread with the given id if any.
Ben Murdoch8b112d22011-06-08 16:22:53 +01005040 i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
5041 if (isolate->thread_id().Equals(internal_tid)) {
Steve Block44f0eee2011-05-26 01:26:41 +01005042 isolate->stack_guard()->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00005043 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +01005044 isolate->thread_manager()->TerminateExecution(internal_tid);
Steve Blocka7e24c12009-10-30 11:49:00 +00005045 }
5046}
5047
5048
Steve Block44f0eee2011-05-26 01:26:41 +01005049void V8::TerminateExecution(Isolate* isolate) {
5050 // If no isolate is supplied, use the default isolate.
5051 if (isolate != NULL) {
5052 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
5053 } else {
5054 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
5055 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005056}
5057
5058
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005059bool V8::IsExecutionTerminating(Isolate* isolate) {
5060 i::Isolate* i_isolate = isolate != NULL ?
5061 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
5062 return IsExecutionTerminatingCheck(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005063}
5064
5065
5066Isolate* Isolate::GetCurrent() {
5067 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
5068 return reinterpret_cast<Isolate*>(isolate);
5069}
5070
5071
5072Isolate* Isolate::New() {
5073 i::Isolate* isolate = new i::Isolate();
5074 return reinterpret_cast<Isolate*>(isolate);
5075}
5076
5077
5078void Isolate::Dispose() {
5079 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5080 if (!ApiCheck(!isolate->IsInUse(),
5081 "v8::Isolate::Dispose()",
5082 "Disposing the isolate that is entered by a thread.")) {
5083 return;
Steve Block6ded16b2010-05-10 14:33:55 +01005084 }
Steve Block44f0eee2011-05-26 01:26:41 +01005085 isolate->TearDown();
5086}
5087
5088
5089void Isolate::Enter() {
5090 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5091 isolate->Enter();
5092}
5093
5094
5095void Isolate::Exit() {
5096 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5097 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01005098}
5099
5100
Ben Murdoch257744e2011-11-30 15:57:28 +00005101void Isolate::SetData(void* data) {
5102 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5103 isolate->SetData(data);
5104}
5105
5106void* Isolate::GetData() {
5107 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5108 return isolate->GetData();
5109}
5110
5111
5112String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
5113 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005114 i::Isolate* isolate = i::Isolate::Current();
5115 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005116 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005117 ENTER_V8(isolate);
5118 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005119 TryCatch try_catch;
5120 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005121 if (str.IsEmpty()) return;
5122 length_ = str->Utf8Length();
5123 str_ = i::NewArray<char>(length_ + 1);
5124 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005125}
5126
5127
5128String::Utf8Value::~Utf8Value() {
5129 i::DeleteArray(str_);
5130}
5131
5132
Ben Murdoch257744e2011-11-30 15:57:28 +00005133String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
5134 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005135 i::Isolate* isolate = i::Isolate::Current();
5136 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005137 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005138 ENTER_V8(isolate);
5139 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005140 TryCatch try_catch;
5141 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005142 if (str.IsEmpty()) return;
5143 length_ = str->Length();
5144 str_ = i::NewArray<char>(length_ + 1);
5145 str->WriteAscii(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005146}
5147
5148
5149String::AsciiValue::~AsciiValue() {
5150 i::DeleteArray(str_);
5151}
5152
5153
Ben Murdoch257744e2011-11-30 15:57:28 +00005154String::Value::Value(v8::Handle<v8::Value> obj)
5155 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005156 i::Isolate* isolate = i::Isolate::Current();
5157 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005158 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005159 ENTER_V8(isolate);
5160 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005161 TryCatch try_catch;
5162 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005163 if (str.IsEmpty()) return;
5164 length_ = str->Length();
5165 str_ = i::NewArray<uint16_t>(length_ + 1);
5166 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005167}
5168
5169
5170String::Value::~Value() {
5171 i::DeleteArray(str_);
5172}
5173
5174Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005175 i::Isolate* isolate = i::Isolate::Current();
5176 LOG_API(isolate, "RangeError");
5177 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
5178 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005179 i::Object* error;
5180 {
Steve Block44f0eee2011-05-26 01:26:41 +01005181 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005182 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005183 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005184 error = *result;
5185 }
5186 i::Handle<i::Object> result(error);
5187 return Utils::ToLocal(result);
5188}
5189
5190Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005191 i::Isolate* isolate = i::Isolate::Current();
5192 LOG_API(isolate, "ReferenceError");
5193 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
5194 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005195 i::Object* error;
5196 {
Steve Block44f0eee2011-05-26 01:26:41 +01005197 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005198 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005199 i::Handle<i::Object> result =
5200 isolate->factory()->NewReferenceError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005201 error = *result;
5202 }
5203 i::Handle<i::Object> result(error);
5204 return Utils::ToLocal(result);
5205}
5206
5207Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005208 i::Isolate* isolate = i::Isolate::Current();
5209 LOG_API(isolate, "SyntaxError");
5210 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
5211 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005212 i::Object* error;
5213 {
Steve Block44f0eee2011-05-26 01:26:41 +01005214 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005215 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005216 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005217 error = *result;
5218 }
5219 i::Handle<i::Object> result(error);
5220 return Utils::ToLocal(result);
5221}
5222
5223Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005224 i::Isolate* isolate = i::Isolate::Current();
5225 LOG_API(isolate, "TypeError");
5226 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
5227 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005228 i::Object* error;
5229 {
Steve Block44f0eee2011-05-26 01:26:41 +01005230 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005231 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005232 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005233 error = *result;
5234 }
5235 i::Handle<i::Object> result(error);
5236 return Utils::ToLocal(result);
5237}
5238
5239Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005240 i::Isolate* isolate = i::Isolate::Current();
5241 LOG_API(isolate, "Error");
5242 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
5243 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005244 i::Object* error;
5245 {
Steve Block44f0eee2011-05-26 01:26:41 +01005246 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005247 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005248 i::Handle<i::Object> result = isolate->factory()->NewError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005249 error = *result;
5250 }
5251 i::Handle<i::Object> result(error);
5252 return Utils::ToLocal(result);
5253}
5254
5255
5256// --- D e b u g S u p p o r t ---
5257
5258#ifdef ENABLE_DEBUGGER_SUPPORT
Leon Clarkef7060e22010-06-03 12:02:55 +01005259
Leon Clarkef7060e22010-06-03 12:02:55 +01005260static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
Steve Block44f0eee2011-05-26 01:26:41 +01005261 i::Isolate* isolate = i::Isolate::Current();
5262 if (isolate->debug_event_callback() != NULL) {
5263 isolate->debug_event_callback()(event_details.GetEvent(),
5264 event_details.GetExecutionState(),
5265 event_details.GetEventData(),
5266 event_details.GetCallbackData());
Leon Clarkef7060e22010-06-03 12:02:55 +01005267 }
5268}
5269
5270
Steve Blocka7e24c12009-10-30 11:49:00 +00005271bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005272 i::Isolate* isolate = i::Isolate::Current();
5273 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
5274 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5275 ENTER_V8(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01005276
Steve Block44f0eee2011-05-26 01:26:41 +01005277 isolate->set_debug_event_callback(that);
Leon Clarkef7060e22010-06-03 12:02:55 +01005278
Steve Block44f0eee2011-05-26 01:26:41 +01005279 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005280 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Leon Clarkef7060e22010-06-03 12:02:55 +01005281 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005282 foreign =
5283 isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
Leon Clarkef7060e22010-06-03 12:02:55 +01005284 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005285 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Leon Clarkef7060e22010-06-03 12:02:55 +01005286 return true;
5287}
5288
5289
5290bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005291 i::Isolate* isolate = i::Isolate::Current();
5292 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
5293 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
5294 ENTER_V8(isolate);
5295 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005296 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00005297 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005298 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00005299 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005300 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005301 return true;
5302}
5303
5304
5305bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
5306 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005307 i::Isolate* isolate = i::Isolate::Current();
5308 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5309 ENTER_V8(isolate);
5310 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
5311 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005312 return true;
5313}
5314
5315
Steve Block44f0eee2011-05-26 01:26:41 +01005316void Debug::DebugBreak(Isolate* isolate) {
5317 // If no isolate is supplied, use the default isolate.
5318 if (isolate != NULL) {
5319 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
5320 } else {
5321 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
5322 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005323}
5324
5325
Steve Block44f0eee2011-05-26 01:26:41 +01005326void Debug::CancelDebugBreak(Isolate* isolate) {
5327 // If no isolate is supplied, use the default isolate.
5328 if (isolate != NULL) {
5329 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5330 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
5331 } else {
5332 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
5333 }
Ben Murdochf87a2032010-10-22 12:50:53 +01005334}
5335
5336
Steve Block44f0eee2011-05-26 01:26:41 +01005337void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
5338 // If no isolate is supplied, use the default isolate.
5339 if (isolate != NULL) {
5340 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5341 internal_isolate->debugger()->EnqueueDebugCommand(data);
5342 } else {
5343 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
5344 }
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005345}
5346
5347
Steve Blocka7e24c12009-10-30 11:49:00 +00005348static void MessageHandlerWrapper(const v8::Debug::Message& message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005349 i::Isolate* isolate = i::Isolate::Current();
5350 if (isolate->message_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005351 v8::String::Value json(message.GetJSON());
Steve Block44f0eee2011-05-26 01:26:41 +01005352 (isolate->message_handler())(*json, json.length(), message.GetClientData());
Steve Blocka7e24c12009-10-30 11:49:00 +00005353 }
5354}
5355
5356
5357void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
5358 bool message_handler_thread) {
Steve Block44f0eee2011-05-26 01:26:41 +01005359 i::Isolate* isolate = i::Isolate::Current();
5360 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5361 ENTER_V8(isolate);
5362
Steve Blocka7e24c12009-10-30 11:49:00 +00005363 // Message handler thread not supported any more. Parameter temporally left in
Steve Block44f0eee2011-05-26 01:26:41 +01005364 // the API for client compatibility reasons.
Steve Blocka7e24c12009-10-30 11:49:00 +00005365 CHECK(!message_handler_thread);
5366
5367 // TODO(sgjesse) support the old message handler API through a simple wrapper.
Steve Block44f0eee2011-05-26 01:26:41 +01005368 isolate->set_message_handler(handler);
5369 if (handler != NULL) {
5370 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
Steve Blocka7e24c12009-10-30 11:49:00 +00005371 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005372 isolate->debugger()->SetMessageHandler(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00005373 }
5374}
5375
5376
5377void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01005378 i::Isolate* isolate = i::Isolate::Current();
5379 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5380 ENTER_V8(isolate);
5381 isolate->debugger()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00005382}
5383
5384
5385void Debug::SendCommand(const uint16_t* command, int length,
Steve Block44f0eee2011-05-26 01:26:41 +01005386 ClientData* client_data,
5387 Isolate* isolate) {
5388 // If no isolate is supplied, use the default isolate.
5389 if (isolate != NULL) {
5390 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5391 internal_isolate->debugger()->ProcessCommand(
5392 i::Vector<const uint16_t>(command, length), client_data);
5393 } else {
5394 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
5395 i::Vector<const uint16_t>(command, length), client_data);
5396 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005397}
5398
5399
5400void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
5401 int period) {
Steve Block44f0eee2011-05-26 01:26:41 +01005402 i::Isolate* isolate = i::Isolate::Current();
5403 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
5404 ENTER_V8(isolate);
5405 isolate->debugger()->SetHostDispatchHandler(handler, period);
Steve Blocka7e24c12009-10-30 11:49:00 +00005406}
5407
5408
Steve Blockd0582a62009-12-15 09:54:21 +00005409void Debug::SetDebugMessageDispatchHandler(
Leon Clarkee46be812010-01-19 14:06:41 +00005410 DebugMessageDispatchHandler handler, bool provide_locker) {
Steve Block44f0eee2011-05-26 01:26:41 +01005411 i::Isolate* isolate = i::Isolate::Current();
5412 EnsureInitializedForIsolate(isolate,
5413 "v8::Debug::SetDebugMessageDispatchHandler");
5414 ENTER_V8(isolate);
5415 isolate->debugger()->SetDebugMessageDispatchHandler(
5416 handler, provide_locker);
Steve Blockd0582a62009-12-15 09:54:21 +00005417}
5418
5419
Steve Blocka7e24c12009-10-30 11:49:00 +00005420Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
5421 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005422 i::Isolate* isolate = i::Isolate::Current();
5423 if (!isolate->IsInitialized()) return Local<Value>();
5424 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
5425 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005426 i::Handle<i::Object> result;
Steve Block44f0eee2011-05-26 01:26:41 +01005427 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005428 if (data.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005429 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5430 isolate->factory()->undefined_value(),
5431 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005432 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005433 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5434 Utils::OpenHandle(*data),
5435 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005436 }
Steve Block44f0eee2011-05-26 01:26:41 +01005437 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005438 return Utils::ToLocal(result);
5439}
5440
5441
5442Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01005443 i::Isolate* isolate = i::Isolate::Current();
5444 if (!isolate->IsInitialized()) return Local<Value>();
5445 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
5446 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005447 v8::HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01005448 i::Debug* isolate_debug = isolate->debug();
5449 isolate_debug->Load();
5450 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5451 i::Handle<i::String> name =
5452 isolate->factory()->LookupAsciiSymbol("MakeMirror");
Steve Blocka7e24c12009-10-30 11:49:00 +00005453 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5454 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5455 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5456 const int kArgc = 1;
5457 v8::Handle<v8::Value> argv[kArgc] = { obj };
Steve Block44f0eee2011-05-26 01:26:41 +01005458 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005459 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5460 kArgc,
5461 argv);
Steve Block44f0eee2011-05-26 01:26:41 +01005462 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005463 return scope.Close(result);
5464}
5465
5466
Leon Clarkee46be812010-01-19 14:06:41 +00005467bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
Steve Block44f0eee2011-05-26 01:26:41 +01005468 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5469 wait_for_connection);
Steve Blocka7e24c12009-10-30 11:49:00 +00005470}
Leon Clarkee46be812010-01-19 14:06:41 +00005471
5472void Debug::ProcessDebugMessages() {
5473 i::Execution::ProcessDebugMesssages(true);
5474}
5475
Steve Block6ded16b2010-05-10 14:33:55 +01005476Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01005477 i::Isolate* isolate = i::Isolate::Current();
5478 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5479 ENTER_V8(isolate);
5480 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01005481}
5482
Steve Blocka7e24c12009-10-30 11:49:00 +00005483#endif // ENABLE_DEBUGGER_SUPPORT
5484
Steve Block6ded16b2010-05-10 14:33:55 +01005485
Steve Block6ded16b2010-05-10 14:33:55 +01005486Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005487 i::Isolate* isolate = i::Isolate::Current();
5488 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
Steve Block6ded16b2010-05-10 14:33:55 +01005489 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5490 const i::CodeEntry* entry = node->entry();
5491 if (!entry->has_name_prefix()) {
5492 return Handle<String>(ToApi<String>(
Steve Block44f0eee2011-05-26 01:26:41 +01005493 isolate->factory()->LookupAsciiSymbol(entry->name())));
Steve Block6ded16b2010-05-10 14:33:55 +01005494 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005495 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5496 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5497 isolate->factory()->LookupAsciiSymbol(entry->name()))));
Steve Block6ded16b2010-05-10 14:33:55 +01005498 }
5499}
5500
5501
5502Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005503 i::Isolate* isolate = i::Isolate::Current();
5504 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
Steve Block6ded16b2010-05-10 14:33:55 +01005505 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005506 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005507 node->entry()->resource_name())));
5508}
5509
5510
5511int CpuProfileNode::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005512 i::Isolate* isolate = i::Isolate::Current();
5513 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
Steve Block6ded16b2010-05-10 14:33:55 +01005514 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5515}
5516
5517
5518double CpuProfileNode::GetTotalTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005519 i::Isolate* isolate = i::Isolate::Current();
5520 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005521 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5522}
5523
5524
5525double CpuProfileNode::GetSelfTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005526 i::Isolate* isolate = i::Isolate::Current();
5527 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005528 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5529}
5530
5531
5532double CpuProfileNode::GetTotalSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005533 i::Isolate* isolate = i::Isolate::Current();
5534 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005535 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5536}
5537
5538
5539double CpuProfileNode::GetSelfSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005540 i::Isolate* isolate = i::Isolate::Current();
5541 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005542 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5543}
5544
5545
5546unsigned CpuProfileNode::GetCallUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005547 i::Isolate* isolate = i::Isolate::Current();
5548 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005549 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01005550}
5551
5552
5553int CpuProfileNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005554 i::Isolate* isolate = i::Isolate::Current();
5555 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005556 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5557}
5558
5559
5560const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005561 i::Isolate* isolate = i::Isolate::Current();
5562 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
Steve Block6ded16b2010-05-10 14:33:55 +01005563 const i::ProfileNode* child =
5564 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5565 return reinterpret_cast<const CpuProfileNode*>(child);
5566}
5567
5568
Steve Block44f0eee2011-05-26 01:26:41 +01005569void CpuProfile::Delete() {
5570 i::Isolate* isolate = i::Isolate::Current();
5571 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5572 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5573 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5574 !i::CpuProfiler::HasDetachedProfiles()) {
5575 // If this was the last profile, clean up all accessory data as well.
5576 i::CpuProfiler::DeleteAllProfiles();
5577 }
5578}
5579
5580
Steve Block6ded16b2010-05-10 14:33:55 +01005581unsigned CpuProfile::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005582 i::Isolate* isolate = i::Isolate::Current();
5583 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
Steve Block6ded16b2010-05-10 14:33:55 +01005584 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5585}
5586
5587
5588Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005589 i::Isolate* isolate = i::Isolate::Current();
5590 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
Steve Block6ded16b2010-05-10 14:33:55 +01005591 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005592 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005593 profile->title())));
5594}
5595
5596
5597const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005598 i::Isolate* isolate = i::Isolate::Current();
5599 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005600 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5601 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5602}
5603
5604
5605const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005606 i::Isolate* isolate = i::Isolate::Current();
5607 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005608 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5609 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5610}
5611
5612
5613int CpuProfiler::GetProfilesCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005614 i::Isolate* isolate = i::Isolate::Current();
5615 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005616 return i::CpuProfiler::GetProfilesCount();
5617}
5618
5619
Leon Clarkef7060e22010-06-03 12:02:55 +01005620const CpuProfile* CpuProfiler::GetProfile(int index,
5621 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005622 i::Isolate* isolate = i::Isolate::Current();
5623 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005624 return reinterpret_cast<const CpuProfile*>(
5625 i::CpuProfiler::GetProfile(
5626 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5627 index));
Steve Block6ded16b2010-05-10 14:33:55 +01005628}
5629
5630
Leon Clarkef7060e22010-06-03 12:02:55 +01005631const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5632 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005633 i::Isolate* isolate = i::Isolate::Current();
5634 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005635 return reinterpret_cast<const CpuProfile*>(
5636 i::CpuProfiler::FindProfile(
5637 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5638 uid));
Steve Block6ded16b2010-05-10 14:33:55 +01005639}
5640
5641
5642void CpuProfiler::StartProfiling(Handle<String> title) {
Steve Block44f0eee2011-05-26 01:26:41 +01005643 i::Isolate* isolate = i::Isolate::Current();
5644 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005645 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5646}
5647
5648
Leon Clarkef7060e22010-06-03 12:02:55 +01005649const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5650 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005651 i::Isolate* isolate = i::Isolate::Current();
5652 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005653 return reinterpret_cast<const CpuProfile*>(
Leon Clarkef7060e22010-06-03 12:02:55 +01005654 i::CpuProfiler::StopProfiling(
5655 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5656 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01005657}
5658
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005659
Steve Block44f0eee2011-05-26 01:26:41 +01005660void CpuProfiler::DeleteAllProfiles() {
5661 i::Isolate* isolate = i::Isolate::Current();
5662 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5663 i::CpuProfiler::DeleteAllProfiles();
5664}
5665
5666
Iain Merrick75681382010-08-19 15:07:18 +01005667static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5668 return const_cast<i::HeapGraphEdge*>(
5669 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5670}
5671
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005672
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005673HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005674 i::Isolate* isolate = i::Isolate::Current();
5675 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005676 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005677}
5678
5679
5680Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005681 i::Isolate* isolate = i::Isolate::Current();
5682 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
Iain Merrick75681382010-08-19 15:07:18 +01005683 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005684 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01005685 case i::HeapGraphEdge::kContextVariable:
5686 case i::HeapGraphEdge::kInternal:
5687 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005688 case i::HeapGraphEdge::kShortcut:
Steve Block44f0eee2011-05-26 01:26:41 +01005689 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005690 edge->name())));
Iain Merrick75681382010-08-19 15:07:18 +01005691 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005692 case i::HeapGraphEdge::kHidden:
Steve Block44f0eee2011-05-26 01:26:41 +01005693 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005694 edge->index())));
5695 default: UNREACHABLE();
5696 }
Steve Block44f0eee2011-05-26 01:26:41 +01005697 return v8::Undefined();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005698}
5699
5700
5701const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005702 i::Isolate* isolate = i::Isolate::Current();
5703 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
Iain Merrick75681382010-08-19 15:07:18 +01005704 const i::HeapEntry* from = ToInternal(this)->From();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005705 return reinterpret_cast<const HeapGraphNode*>(from);
5706}
5707
5708
5709const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005710 i::Isolate* isolate = i::Isolate::Current();
5711 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
Iain Merrick75681382010-08-19 15:07:18 +01005712 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005713 return reinterpret_cast<const HeapGraphNode*>(to);
5714}
5715
5716
Iain Merrick75681382010-08-19 15:07:18 +01005717static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5718 return const_cast<i::HeapEntry*>(
5719 reinterpret_cast<const i::HeapEntry*>(entry));
5720}
5721
5722
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005723HeapGraphNode::Type HeapGraphNode::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005724 i::Isolate* isolate = i::Isolate::Current();
5725 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005726 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005727}
5728
5729
5730Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005731 i::Isolate* isolate = i::Isolate::Current();
5732 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
5733 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005734 ToInternal(this)->name())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005735}
5736
5737
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005738uint64_t HeapGraphNode::GetId() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005739 i::Isolate* isolate = i::Isolate::Current();
5740 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
Iain Merrick75681382010-08-19 15:07:18 +01005741 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005742}
5743
5744
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005745int HeapGraphNode::GetSelfSize() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005746 i::Isolate* isolate = i::Isolate::Current();
5747 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
Iain Merrick75681382010-08-19 15:07:18 +01005748 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005749}
5750
5751
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005752int HeapGraphNode::GetRetainedSize(bool exact) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005753 i::Isolate* isolate = i::Isolate::Current();
5754 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005755 return ToInternal(this)->RetainedSize(exact);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005756}
5757
5758
5759int HeapGraphNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005760 i::Isolate* isolate = i::Isolate::Current();
5761 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
Iain Merrick75681382010-08-19 15:07:18 +01005762 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005763}
5764
5765
5766const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005767 i::Isolate* isolate = i::Isolate::Current();
5768 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005769 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005770 &ToInternal(this)->children()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005771}
5772
5773
5774int HeapGraphNode::GetRetainersCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005775 i::Isolate* isolate = i::Isolate::Current();
5776 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
Iain Merrick75681382010-08-19 15:07:18 +01005777 return ToInternal(this)->retainers().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005778}
5779
5780
5781const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005782 i::Isolate* isolate = i::Isolate::Current();
5783 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005784 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005785 ToInternal(this)->retainers()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005786}
5787
5788
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005789const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005790 i::Isolate* isolate = i::Isolate::Current();
5791 IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005792 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
5793}
5794
5795
Iain Merrick75681382010-08-19 15:07:18 +01005796static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5797 return const_cast<i::HeapSnapshot*>(
5798 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5799}
5800
5801
Steve Block44f0eee2011-05-26 01:26:41 +01005802void HeapSnapshot::Delete() {
5803 i::Isolate* isolate = i::Isolate::Current();
5804 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
5805 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
5806 ToInternal(this)->Delete();
5807 } else {
5808 // If this is the last snapshot, clean up all accessory data as well.
5809 i::HeapProfiler::DeleteAllSnapshots();
5810 }
5811}
5812
5813
Steve Block791712a2010-08-27 10:21:07 +01005814HeapSnapshot::Type HeapSnapshot::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005815 i::Isolate* isolate = i::Isolate::Current();
5816 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
Steve Block791712a2010-08-27 10:21:07 +01005817 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
5818}
5819
5820
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005821unsigned HeapSnapshot::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005822 i::Isolate* isolate = i::Isolate::Current();
5823 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
Iain Merrick75681382010-08-19 15:07:18 +01005824 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005825}
5826
5827
5828Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005829 i::Isolate* isolate = i::Isolate::Current();
5830 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
5831 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005832 ToInternal(this)->title())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005833}
5834
5835
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005836const HeapGraphNode* HeapSnapshot::GetRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005837 i::Isolate* isolate = i::Isolate::Current();
5838 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
Iain Merrick75681382010-08-19 15:07:18 +01005839 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005840}
5841
5842
Ben Murdochb0fe1622011-05-05 13:52:32 +01005843const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005844 i::Isolate* isolate = i::Isolate::Current();
5845 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
Ben Murdochb0fe1622011-05-05 13:52:32 +01005846 return reinterpret_cast<const HeapGraphNode*>(
5847 ToInternal(this)->GetEntryById(id));
5848}
5849
5850
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005851int HeapSnapshot::GetNodesCount() const {
5852 i::Isolate* isolate = i::Isolate::Current();
5853 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
5854 return ToInternal(this)->entries()->length();
5855}
5856
5857
5858const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
5859 i::Isolate* isolate = i::Isolate::Current();
5860 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
5861 return reinterpret_cast<const HeapGraphNode*>(
5862 ToInternal(this)->entries()->at(index));
5863}
5864
5865
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005866void HeapSnapshot::Serialize(OutputStream* stream,
5867 HeapSnapshot::SerializationFormat format) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005868 i::Isolate* isolate = i::Isolate::Current();
5869 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005870 ApiCheck(format == kJSON,
5871 "v8::HeapSnapshot::Serialize",
5872 "Unknown serialization format");
5873 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
5874 "v8::HeapSnapshot::Serialize",
5875 "Unsupported output encoding");
5876 ApiCheck(stream->GetChunkSize() > 0,
5877 "v8::HeapSnapshot::Serialize",
5878 "Invalid stream chunk size");
5879 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
5880 serializer.Serialize(stream);
5881}
5882
5883
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005884int HeapProfiler::GetSnapshotsCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005885 i::Isolate* isolate = i::Isolate::Current();
5886 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005887 return i::HeapProfiler::GetSnapshotsCount();
5888}
5889
5890
5891const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005892 i::Isolate* isolate = i::Isolate::Current();
5893 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005894 return reinterpret_cast<const HeapSnapshot*>(
5895 i::HeapProfiler::GetSnapshot(index));
5896}
5897
5898
5899const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
Steve Block44f0eee2011-05-26 01:26:41 +01005900 i::Isolate* isolate = i::Isolate::Current();
5901 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005902 return reinterpret_cast<const HeapSnapshot*>(
5903 i::HeapProfiler::FindSnapshot(uid));
5904}
5905
5906
Steve Block791712a2010-08-27 10:21:07 +01005907const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
Ben Murdochb0fe1622011-05-05 13:52:32 +01005908 HeapSnapshot::Type type,
5909 ActivityControl* control) {
Steve Block44f0eee2011-05-26 01:26:41 +01005910 i::Isolate* isolate = i::Isolate::Current();
5911 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
Steve Block791712a2010-08-27 10:21:07 +01005912 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
5913 switch (type) {
5914 case HeapSnapshot::kFull:
5915 internal_type = i::HeapSnapshot::kFull;
5916 break;
Steve Block791712a2010-08-27 10:21:07 +01005917 default:
5918 UNREACHABLE();
5919 }
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005920 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb0fe1622011-05-05 13:52:32 +01005921 i::HeapProfiler::TakeSnapshot(
5922 *Utils::OpenHandle(*title), internal_type, control));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005923}
5924
Steve Block44f0eee2011-05-26 01:26:41 +01005925
5926void HeapProfiler::DeleteAllSnapshots() {
5927 i::Isolate* isolate = i::Isolate::Current();
5928 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5929 i::HeapProfiler::DeleteAllSnapshots();
5930}
5931
5932
5933void HeapProfiler::DefineWrapperClass(uint16_t class_id,
5934 WrapperInfoCallback callback) {
5935 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
5936 callback);
5937}
5938
Steve Block6ded16b2010-05-10 14:33:55 +01005939
5940
Ben Murdochb0fe1622011-05-05 13:52:32 +01005941v8::Testing::StressType internal::Testing::stress_type_ =
5942 v8::Testing::kStressTypeOpt;
5943
5944
5945void Testing::SetStressRunType(Testing::StressType type) {
5946 internal::Testing::set_stress_type(type);
5947}
5948
5949int Testing::GetStressRuns() {
5950 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
5951#ifdef DEBUG
5952 // In debug mode the code runs much slower so stressing will only make two
5953 // runs.
5954 return 2;
5955#else
5956 return 5;
5957#endif
5958}
5959
5960
5961static void SetFlagsFromString(const char* flags) {
5962 V8::SetFlagsFromString(flags, i::StrLength(flags));
5963}
5964
5965
5966void Testing::PrepareStressRun(int run) {
5967 static const char* kLazyOptimizations =
5968 "--prepare-always-opt --nolimit-inlining "
5969 "--noalways-opt --noopt-eagerly";
5970 static const char* kEagerOptimizations = "--opt-eagerly";
5971 static const char* kForcedOptimizations = "--always-opt";
5972
5973 // If deoptimization stressed turn on frequent deoptimization. If no value
5974 // is spefified through --deopt-every-n-times use a default default value.
5975 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
5976 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
5977 internal::FLAG_deopt_every_n_times == 0) {
5978 SetFlagsFromString(kDeoptEvery13Times);
5979 }
5980
5981#ifdef DEBUG
5982 // As stressing in debug mode only make two runs skip the deopt stressing
5983 // here.
5984 if (run == GetStressRuns() - 1) {
5985 SetFlagsFromString(kForcedOptimizations);
5986 } else {
5987 SetFlagsFromString(kEagerOptimizations);
5988 SetFlagsFromString(kLazyOptimizations);
5989 }
5990#else
5991 if (run == GetStressRuns() - 1) {
5992 SetFlagsFromString(kForcedOptimizations);
5993 } else if (run == GetStressRuns() - 2) {
5994 SetFlagsFromString(kEagerOptimizations);
5995 } else {
5996 SetFlagsFromString(kLazyOptimizations);
5997 }
5998#endif
5999}
6000
6001
Steve Block44f0eee2011-05-26 01:26:41 +01006002void Testing::DeoptimizeAll() {
6003 internal::Deoptimizer::DeoptimizeAll();
Steve Blocka7e24c12009-10-30 11:49:00 +00006004}
6005
6006
Steve Block44f0eee2011-05-26 01:26:41 +01006007namespace internal {
6008
6009
Steve Blocka7e24c12009-10-30 11:49:00 +00006010void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01006011 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00006012}
6013
6014
6015char* HandleScopeImplementer::ArchiveThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006016 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00006017 isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00006018 handle_scope_data_ = *current;
6019 memcpy(storage, this, sizeof(*this));
6020
6021 ResetAfterArchive();
6022 current->Initialize();
6023
6024 return storage + ArchiveSpacePerThread();
6025}
6026
6027
6028int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01006029 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00006030}
6031
6032
6033char* HandleScopeImplementer::RestoreThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006034 memcpy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00006035 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00006036 return storage + ArchiveSpacePerThread();
6037}
6038
6039
6040void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
6041 // Iterate over all handles in the blocks except for the last.
6042 for (int i = blocks()->length() - 2; i >= 0; --i) {
6043 Object** block = blocks()->at(i);
6044 v->VisitPointers(block, &block[kHandleBlockSize]);
6045 }
6046
6047 // Iterate over live handles in the last block (if any).
6048 if (!blocks()->is_empty()) {
6049 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
6050 }
6051
6052 if (!saved_contexts_.is_empty()) {
6053 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
6054 v->VisitPointers(start, start + saved_contexts_.length());
6055 }
6056}
6057
6058
6059void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
6060 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00006061 isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01006062 handle_scope_data_ = *current;
6063 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00006064}
6065
6066
6067char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01006068 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00006069 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01006070 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00006071 return storage + ArchiveSpacePerThread();
6072}
6073
6074} } // namespace v8::internal