blob: 479be5af15b1a8904ba4378199817274d09492e4 [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"
Ben Murdoch69a99ed2011-11-30 16:03:39 +000038#include "flags.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000039#include "global-handles.h"
Kristian Monsen9dcf7e22010-06-28 14:14:28 +010040#include "heap-profiler.h"
Steve Block6ded16b2010-05-10 14:33:55 +010041#include "messages.h"
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000042#include "natives.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010043#include "parser.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000044#include "platform.h"
Steve Block6ded16b2010-05-10 14:33:55 +010045#include "profile-generator-inl.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010046#include "runtime-profiler.h"
Ben Murdoch589d6972011-11-30 16:04:58 +000047#include "scanner-character-streams.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000048#include "serialize.h"
49#include "snapshot.h"
50#include "v8threads.h"
51#include "version.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010052#include "vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000053
Steve Block6ded16b2010-05-10 14:33:55 +010054#include "../include/v8-profiler.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010055#include "../include/v8-testing.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000056
Steve Block44f0eee2011-05-26 01:26:41 +010057#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000058
Steve Block44f0eee2011-05-26 01:26:41 +010059#define ENTER_V8(isolate) \
60 ASSERT((isolate)->IsInitialized()); \
61 i::VMState __state__((isolate), i::OTHER)
62#define LEAVE_V8(isolate) \
63 i::VMState __state__((isolate), i::EXTERNAL)
Steve Blocka7e24c12009-10-30 11:49:00 +000064
65namespace v8 {
66
Steve Block44f0eee2011-05-26 01:26:41 +010067#define ON_BAILOUT(isolate, location, code) \
68 if (IsDeadCheck(isolate, location) || \
69 IsExecutionTerminatingCheck(isolate)) { \
Leon Clarkef7060e22010-06-03 12:02:55 +010070 code; \
71 UNREACHABLE(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000072 }
73
74
Steve Block44f0eee2011-05-26 01:26:41 +010075#define EXCEPTION_PREAMBLE(isolate) \
76 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
77 ASSERT(!(isolate)->external_caught_exception()); \
Steve Blocka7e24c12009-10-30 11:49:00 +000078 bool has_pending_exception = false
79
80
Steve Block44f0eee2011-05-26 01:26:41 +010081#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
Steve Blocka7e24c12009-10-30 11:49:00 +000082 do { \
Steve Block44f0eee2011-05-26 01:26:41 +010083 i::HandleScopeImplementer* handle_scope_implementer = \
84 (isolate)->handle_scope_implementer(); \
85 handle_scope_implementer->DecrementCallDepth(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000086 if (has_pending_exception) { \
Steve Block44f0eee2011-05-26 01:26:41 +010087 if (handle_scope_implementer->CallDepthIsZero() && \
88 (isolate)->is_out_of_memory()) { \
Ben Murdoch69a99ed2011-11-30 16:03:39 +000089 if (!(isolate)->ignore_out_of_memory()) \
Steve Blocka7e24c12009-10-30 11:49:00 +000090 i::V8::FatalProcessOutOfMemory(NULL); \
91 } \
Steve Block44f0eee2011-05-26 01:26:41 +010092 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
93 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
Steve Blocka7e24c12009-10-30 11:49:00 +000094 return value; \
95 } \
96 } while (false)
97
98
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000099#define API_ENTRY_CHECK(isolate, msg) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000100 do { \
101 if (v8::Locker::IsActive()) { \
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000102 ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(), \
Steve Blocka7e24c12009-10-30 11:49:00 +0000103 msg, \
104 "Entering the V8 API without proper locking in place"); \
105 } \
106 } while (false)
107
Ben Murdochb0fe1622011-05-05 13:52:32 +0100108
Steve Blocka7e24c12009-10-30 11:49:00 +0000109// --- E x c e p t i o n B e h a v i o r ---
110
111
Steve Blocka7e24c12009-10-30 11:49:00 +0000112static void DefaultFatalErrorHandler(const char* location,
113 const char* message) {
Steve Block44f0eee2011-05-26 01:26:41 +0100114 i::VMState __state__(i::Isolate::Current(), i::OTHER);
Steve Blocka7e24c12009-10-30 11:49:00 +0000115 API_Fatal(location, message);
116}
117
118
Steve Block44f0eee2011-05-26 01:26:41 +0100119static FatalErrorCallback GetFatalErrorHandler() {
120 i::Isolate* isolate = i::Isolate::Current();
121 if (isolate->exception_behavior() == NULL) {
122 isolate->set_exception_behavior(DefaultFatalErrorHandler);
Steve Blocka7e24c12009-10-30 11:49:00 +0000123 }
Steve Block44f0eee2011-05-26 01:26:41 +0100124 return isolate->exception_behavior();
Steve Blocka7e24c12009-10-30 11:49:00 +0000125}
126
127
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800128void i::FatalProcessOutOfMemory(const char* location) {
129 i::V8::FatalProcessOutOfMemory(location, false);
130}
131
Steve Blocka7e24c12009-10-30 11:49:00 +0000132
133// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
134// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100135void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Steve Blockd0582a62009-12-15 09:54:21 +0000136 i::HeapStats heap_stats;
137 int start_marker;
138 heap_stats.start_marker = &start_marker;
139 int new_space_size;
140 heap_stats.new_space_size = &new_space_size;
141 int new_space_capacity;
142 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100143 intptr_t old_pointer_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000144 heap_stats.old_pointer_space_size = &old_pointer_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100145 intptr_t old_pointer_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000146 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100147 intptr_t old_data_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000148 heap_stats.old_data_space_size = &old_data_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100149 intptr_t old_data_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000150 heap_stats.old_data_space_capacity = &old_data_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100151 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000152 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100153 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000154 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100155 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000156 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100157 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000158 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100159 intptr_t cell_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000160 heap_stats.cell_space_size = &cell_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100161 intptr_t cell_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000162 heap_stats.cell_space_capacity = &cell_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100163 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000164 heap_stats.lo_space_size = &lo_space_size;
165 int global_handle_count;
166 heap_stats.global_handle_count = &global_handle_count;
167 int weak_global_handle_count;
168 heap_stats.weak_global_handle_count = &weak_global_handle_count;
169 int pending_global_handle_count;
170 heap_stats.pending_global_handle_count = &pending_global_handle_count;
171 int near_death_global_handle_count;
172 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000173 int free_global_handle_count;
174 heap_stats.free_global_handle_count = &free_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100175 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100176 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100177 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100178 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
179 int objects_per_type[LAST_TYPE + 1] = {0};
180 heap_stats.objects_per_type = objects_per_type;
181 int size_per_type[LAST_TYPE + 1] = {0};
182 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100183 int os_error;
184 heap_stats.os_error = &os_error;
Steve Blockd0582a62009-12-15 09:54:21 +0000185 int end_marker;
186 heap_stats.end_marker = &end_marker;
Steve Block44f0eee2011-05-26 01:26:41 +0100187 i::Isolate* isolate = i::Isolate::Current();
188 isolate->heap()->RecordStats(&heap_stats, take_snapshot);
Steve Blocka7e24c12009-10-30 11:49:00 +0000189 i::V8::SetFatalError();
190 FatalErrorCallback callback = GetFatalErrorHandler();
191 {
Steve Block44f0eee2011-05-26 01:26:41 +0100192 LEAVE_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000193 callback(location, "Allocation failed - process out of memory");
194 }
195 // If the callback returns, we stop execution.
196 UNREACHABLE();
197}
198
199
Steve Blocka7e24c12009-10-30 11:49:00 +0000200bool Utils::ReportApiFailure(const char* location, const char* message) {
201 FatalErrorCallback callback = GetFatalErrorHandler();
202 callback(location, message);
203 i::V8::SetFatalError();
204 return false;
205}
206
207
208bool V8::IsDead() {
209 return i::V8::IsDead();
210}
211
212
213static inline bool ApiCheck(bool condition,
214 const char* location,
215 const char* message) {
216 return condition ? true : Utils::ReportApiFailure(location, message);
217}
218
219
220static bool ReportV8Dead(const char* location) {
221 FatalErrorCallback callback = GetFatalErrorHandler();
222 callback(location, "V8 is no longer usable");
223 return true;
224}
225
226
227static bool ReportEmptyHandle(const char* location) {
228 FatalErrorCallback callback = GetFatalErrorHandler();
229 callback(location, "Reading from empty handle");
230 return true;
231}
232
233
234/**
235 * IsDeadCheck checks that the vm is usable. If, for instance, the vm has been
236 * out of memory at some point this check will fail. It should be called on
237 * entry to all methods that touch anything in the heap, except destructors
238 * which you sometimes can't avoid calling after the vm has crashed. Functions
239 * that call EnsureInitialized or ON_BAILOUT don't have to also call
240 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you
241 * can arrange to return if the VM is dead. This is needed to ensure that no VM
242 * heap allocations are attempted on a dead VM. EnsureInitialized has the
243 * advantage over ON_BAILOUT that it actually initializes the VM if this has not
244 * yet been done.
245 */
Steve Block44f0eee2011-05-26 01:26:41 +0100246static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
247 return !isolate->IsInitialized()
Steve Blocka7e24c12009-10-30 11:49:00 +0000248 && i::V8::IsDead() ? ReportV8Dead(location) : false;
249}
250
251
Steve Block44f0eee2011-05-26 01:26:41 +0100252static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
253 if (!isolate->IsInitialized()) return false;
254 if (isolate->has_scheduled_exception()) {
255 return isolate->scheduled_exception() ==
256 isolate->heap()->termination_exception();
257 }
258 return false;
259}
260
261
Steve Blocka7e24c12009-10-30 11:49:00 +0000262static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
263 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
264}
265
266
267static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
268 return (obj == 0) ? ReportEmptyHandle(location) : false;
269}
270
271// --- S t a t i c s ---
272
273
Steve Block44f0eee2011-05-26 01:26:41 +0100274static bool InitializeHelper() {
275 if (i::Snapshot::Initialize()) return true;
276 return i::V8::Initialize(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000277}
278
279
Steve Block44f0eee2011-05-26 01:26:41 +0100280static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
281 const char* location) {
282 if (IsDeadCheck(isolate, location)) return false;
283 if (isolate != NULL) {
284 if (isolate->IsInitialized()) return true;
285 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000286 ASSERT(isolate == i::Isolate::Current());
Steve Block44f0eee2011-05-26 01:26:41 +0100287 return ApiCheck(InitializeHelper(), location, "Error initializing V8");
288}
289
290// Some initializing API functions are called early and may be
291// called on a thread different from static initializer thread.
292// If Isolate API is used, Isolate::Enter() will initialize TLS so
293// Isolate::Current() works. If it's a legacy case, then the thread
294// may not have TLS initialized yet. However, in initializing APIs it
295// may be too early to call EnsureInitialized() - some pre-init
296// parameters still have to be configured.
297static inline i::Isolate* EnterIsolateIfNeeded() {
298 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
299 if (isolate != NULL)
300 return isolate;
301
302 i::Isolate::EnterDefaultIsolate();
303 isolate = i::Isolate::Current();
304 return isolate;
305}
306
307
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000308StartupDataDecompressor::StartupDataDecompressor()
309 : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
310 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
311 raw_data[i] = NULL;
312 }
313}
314
315
316StartupDataDecompressor::~StartupDataDecompressor() {
317 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
318 i::DeleteArray(raw_data[i]);
319 }
320 i::DeleteArray(raw_data);
321}
322
323
324int StartupDataDecompressor::Decompress() {
325 int compressed_data_count = V8::GetCompressedStartupDataCount();
326 StartupData* compressed_data =
327 i::NewArray<StartupData>(compressed_data_count);
328 V8::GetCompressedStartupData(compressed_data);
329 for (int i = 0; i < compressed_data_count; ++i) {
330 char* decompressed = raw_data[i] =
331 i::NewArray<char>(compressed_data[i].raw_size);
332 if (compressed_data[i].compressed_size != 0) {
333 int result = DecompressData(decompressed,
334 &compressed_data[i].raw_size,
335 compressed_data[i].data,
336 compressed_data[i].compressed_size);
337 if (result != 0) return result;
338 } else {
339 ASSERT_EQ(0, compressed_data[i].raw_size);
340 }
341 compressed_data[i].data = decompressed;
342 }
343 V8::SetDecompressedStartupData(compressed_data);
344 return 0;
345}
346
347
Ben Murdoch257744e2011-11-30 15:57:28 +0000348StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
349#ifdef COMPRESS_STARTUP_DATA_BZ2
350 return StartupData::kBZip2;
351#else
352 return StartupData::kUncompressed;
353#endif
354}
355
356
357enum CompressedStartupDataItems {
358 kSnapshot = 0,
359 kSnapshotContext,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000360 kLibraries,
361 kExperimentalLibraries,
Ben Murdoch257744e2011-11-30 15:57:28 +0000362 kCompressedStartupDataCount
363};
364
365int V8::GetCompressedStartupDataCount() {
366#ifdef COMPRESS_STARTUP_DATA_BZ2
367 return kCompressedStartupDataCount;
368#else
369 return 0;
370#endif
371}
372
373
374void V8::GetCompressedStartupData(StartupData* compressed_data) {
375#ifdef COMPRESS_STARTUP_DATA_BZ2
376 compressed_data[kSnapshot].data =
377 reinterpret_cast<const char*>(i::Snapshot::data());
378 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
379 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
380
381 compressed_data[kSnapshotContext].data =
382 reinterpret_cast<const char*>(i::Snapshot::context_data());
383 compressed_data[kSnapshotContext].compressed_size =
384 i::Snapshot::context_size();
385 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000386
387 i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
388 compressed_data[kLibraries].data =
389 reinterpret_cast<const char*>(libraries_source.start());
390 compressed_data[kLibraries].compressed_size = libraries_source.length();
391 compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
392
393 i::Vector<const i::byte> exp_libraries_source =
394 i::ExperimentalNatives::GetScriptsSource();
395 compressed_data[kExperimentalLibraries].data =
396 reinterpret_cast<const char*>(exp_libraries_source.start());
397 compressed_data[kExperimentalLibraries].compressed_size =
398 exp_libraries_source.length();
399 compressed_data[kExperimentalLibraries].raw_size =
400 i::ExperimentalNatives::GetRawScriptsSize();
Ben Murdoch257744e2011-11-30 15:57:28 +0000401#endif
402}
403
404
405void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
406#ifdef COMPRESS_STARTUP_DATA_BZ2
407 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
408 i::Snapshot::set_raw_data(
409 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
410
411 ASSERT_EQ(i::Snapshot::context_raw_size(),
412 decompressed_data[kSnapshotContext].raw_size);
413 i::Snapshot::set_context_raw_data(
414 reinterpret_cast<const i::byte*>(
415 decompressed_data[kSnapshotContext].data));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000416
417 ASSERT_EQ(i::Natives::GetRawScriptsSize(),
418 decompressed_data[kLibraries].raw_size);
419 i::Vector<const char> libraries_source(
420 decompressed_data[kLibraries].data,
421 decompressed_data[kLibraries].raw_size);
422 i::Natives::SetRawScriptsSource(libraries_source);
423
424 ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
425 decompressed_data[kExperimentalLibraries].raw_size);
426 i::Vector<const char> exp_libraries_source(
427 decompressed_data[kExperimentalLibraries].data,
428 decompressed_data[kExperimentalLibraries].raw_size);
429 i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
Ben Murdoch257744e2011-11-30 15:57:28 +0000430#endif
431}
432
433
Steve Block44f0eee2011-05-26 01:26:41 +0100434void V8::SetFatalErrorHandler(FatalErrorCallback that) {
435 i::Isolate* isolate = EnterIsolateIfNeeded();
436 isolate->set_exception_behavior(that);
Steve Blocka7e24c12009-10-30 11:49:00 +0000437}
438
439
Ben Murdoch257744e2011-11-30 15:57:28 +0000440void V8::SetAllowCodeGenerationFromStringsCallback(
441 AllowCodeGenerationFromStringsCallback callback) {
442 i::Isolate* isolate = EnterIsolateIfNeeded();
443 isolate->set_allow_code_gen_callback(callback);
444}
445
446
Steve Blocka7e24c12009-10-30 11:49:00 +0000447#ifdef DEBUG
448void ImplementationUtilities::ZapHandleRange(i::Object** begin,
449 i::Object** end) {
450 i::HandleScope::ZapRange(begin, end);
451}
452#endif
453
454
Steve Blocka7e24c12009-10-30 11:49:00 +0000455void V8::SetFlagsFromString(const char* str, int length) {
456 i::FlagList::SetFlagsFromString(str, length);
457}
458
459
460void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
461 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
462}
463
464
465v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100466 i::Isolate* isolate = i::Isolate::Current();
467 if (IsDeadCheck(isolate, "v8::ThrowException()")) {
468 return v8::Handle<Value>();
469 }
470 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000471 // If we're passed an empty handle, we throw an undefined exception
472 // to deal more gracefully with out of memory situations.
473 if (value.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100474 isolate->ScheduleThrow(isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000475 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100476 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +0000477 }
478 return v8::Undefined();
479}
480
481
482RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
483
484
485RegisteredExtension::RegisteredExtension(Extension* extension)
486 : extension_(extension), state_(UNVISITED) { }
487
488
489void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100490 that->next_ = first_extension_;
491 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000492}
493
494
495void RegisterExtension(Extension* that) {
496 RegisteredExtension* extension = new RegisteredExtension(that);
497 RegisteredExtension::Register(extension);
498}
499
500
501Extension::Extension(const char* name,
502 const char* source,
503 int dep_count,
504 const char** deps)
505 : name_(name),
506 source_(source),
507 dep_count_(dep_count),
508 deps_(deps),
509 auto_enable_(false) { }
510
511
512v8::Handle<Primitive> Undefined() {
Steve Block44f0eee2011-05-26 01:26:41 +0100513 i::Isolate* isolate = i::Isolate::Current();
514 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
515 return v8::Handle<v8::Primitive>();
516 }
517 return v8::Handle<Primitive>(ToApi<Primitive>(
518 isolate->factory()->undefined_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000519}
520
521
522v8::Handle<Primitive> Null() {
Steve Block44f0eee2011-05-26 01:26:41 +0100523 i::Isolate* isolate = i::Isolate::Current();
524 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
525 return v8::Handle<v8::Primitive>();
526 }
527 return v8::Handle<Primitive>(
528 ToApi<Primitive>(isolate->factory()->null_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000529}
530
531
532v8::Handle<Boolean> True() {
Steve Block44f0eee2011-05-26 01:26:41 +0100533 i::Isolate* isolate = i::Isolate::Current();
534 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
535 return v8::Handle<Boolean>();
536 }
537 return v8::Handle<Boolean>(
538 ToApi<Boolean>(isolate->factory()->true_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000539}
540
541
542v8::Handle<Boolean> False() {
Steve Block44f0eee2011-05-26 01:26:41 +0100543 i::Isolate* isolate = i::Isolate::Current();
544 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
545 return v8::Handle<Boolean>();
546 }
547 return v8::Handle<Boolean>(
548 ToApi<Boolean>(isolate->factory()->false_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000549}
550
551
552ResourceConstraints::ResourceConstraints()
553 : max_young_space_size_(0),
554 max_old_space_size_(0),
Russell Brenner90bac252010-11-18 13:33:46 -0800555 max_executable_size_(0),
Steve Blocka7e24c12009-10-30 11:49:00 +0000556 stack_limit_(NULL) { }
557
558
559bool SetResourceConstraints(ResourceConstraints* constraints) {
Steve Block44f0eee2011-05-26 01:26:41 +0100560 i::Isolate* isolate = EnterIsolateIfNeeded();
561
Steve Block3ce2e202009-11-05 08:53:23 +0000562 int young_space_size = constraints->max_young_space_size();
Steve Blocka7e24c12009-10-30 11:49:00 +0000563 int old_gen_size = constraints->max_old_space_size();
Russell Brenner90bac252010-11-18 13:33:46 -0800564 int max_executable_size = constraints->max_executable_size();
565 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100566 // After initialization it's too late to change Heap constraints.
567 ASSERT(!isolate->IsInitialized());
568 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
569 old_gen_size,
570 max_executable_size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000571 if (!result) return false;
572 }
573 if (constraints->stack_limit() != NULL) {
574 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
Steve Block44f0eee2011-05-26 01:26:41 +0100575 isolate->stack_guard()->SetStackLimit(limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000576 }
577 return true;
578}
579
580
581i::Object** V8::GlobalizeReference(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100582 i::Isolate* isolate = i::Isolate::Current();
583 if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
584 LOG_API(isolate, "Persistent::New");
Steve Blocka7e24c12009-10-30 11:49:00 +0000585 i::Handle<i::Object> result =
Steve Block44f0eee2011-05-26 01:26:41 +0100586 isolate->global_handles()->Create(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000587 return result.location();
588}
589
590
591void V8::MakeWeak(i::Object** object, void* parameters,
592 WeakReferenceCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +0100593 i::Isolate* isolate = i::Isolate::Current();
594 LOG_API(isolate, "MakeWeak");
595 isolate->global_handles()->MakeWeak(object, parameters,
596 callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000597}
598
599
600void V8::ClearWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100601 i::Isolate* isolate = i::Isolate::Current();
602 LOG_API(isolate, "ClearWeak");
603 isolate->global_handles()->ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000604}
605
606
Ben Murdoch257744e2011-11-30 15:57:28 +0000607void V8::MarkIndependent(i::Object** object) {
608 i::Isolate* isolate = i::Isolate::Current();
609 LOG_API(isolate, "MakeIndependent");
610 isolate->global_handles()->MarkIndependent(object);
611}
612
613
Steve Blocka7e24c12009-10-30 11:49:00 +0000614bool V8::IsGlobalNearDeath(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100615 i::Isolate* isolate = i::Isolate::Current();
616 LOG_API(isolate, "IsGlobalNearDeath");
617 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000618 return i::GlobalHandles::IsNearDeath(obj);
619}
620
621
622bool V8::IsGlobalWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100623 i::Isolate* isolate = i::Isolate::Current();
624 LOG_API(isolate, "IsGlobalWeak");
625 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000626 return i::GlobalHandles::IsWeak(obj);
627}
628
629
630void V8::DisposeGlobal(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100631 i::Isolate* isolate = i::Isolate::Current();
632 LOG_API(isolate, "DisposeGlobal");
633 if (!isolate->IsInitialized()) return;
634 isolate->global_handles()->Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000635}
636
637// --- H a n d l e s ---
638
639
Steve Block44f0eee2011-05-26 01:26:41 +0100640HandleScope::HandleScope() {
Steve Block44f0eee2011-05-26 01:26:41 +0100641 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000642 API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
Steve Block44f0eee2011-05-26 01:26:41 +0100643 v8::ImplementationUtilities::HandleScopeData* current =
644 isolate->handle_scope_data();
645 isolate_ = isolate;
646 prev_next_ = current->next;
647 prev_limit_ = current->limit;
648 is_closed_ = false;
649 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000650}
651
652
653HandleScope::~HandleScope() {
654 if (!is_closed_) {
John Reck59135872010-11-02 12:39:01 -0700655 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000656 }
657}
658
659
John Reck59135872010-11-02 12:39:01 -0700660void HandleScope::Leave() {
Steve Block44f0eee2011-05-26 01:26:41 +0100661 ASSERT(isolate_ == i::Isolate::Current());
662 v8::ImplementationUtilities::HandleScopeData* current =
663 isolate_->handle_scope_data();
664 current->level--;
665 ASSERT(current->level >= 0);
666 current->next = prev_next_;
667 if (current->limit != prev_limit_) {
668 current->limit = prev_limit_;
669 i::HandleScope::DeleteExtensions(isolate_);
John Reck59135872010-11-02 12:39:01 -0700670 }
671
672#ifdef DEBUG
673 i::HandleScope::ZapRange(prev_next_, prev_limit_);
674#endif
675}
676
677
Steve Blocka7e24c12009-10-30 11:49:00 +0000678int HandleScope::NumberOfHandles() {
Steve Block44f0eee2011-05-26 01:26:41 +0100679 EnsureInitializedForIsolate(
680 i::Isolate::Current(), "HandleScope::NumberOfHandles");
Steve Blocka7e24c12009-10-30 11:49:00 +0000681 return i::HandleScope::NumberOfHandles();
682}
683
684
Steve Block44f0eee2011-05-26 01:26:41 +0100685i::Object** HandleScope::CreateHandle(i::Object* value) {
686 return i::HandleScope::CreateHandle(value, i::Isolate::Current());
687}
688
689
690i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
691 ASSERT(value->IsHeapObject());
692 return reinterpret_cast<i::Object**>(
693 i::HandleScope::CreateHandle(value, value->GetIsolate()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000694}
695
696
697void Context::Enter() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000698 i::Handle<i::Context> env = Utils::OpenHandle(this);
699 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100700 if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
701 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000702
Steve Block44f0eee2011-05-26 01:26:41 +0100703 isolate->handle_scope_implementer()->EnterContext(env);
704
705 isolate->handle_scope_implementer()->SaveContext(isolate->context());
706 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000707}
708
709
710void Context::Exit() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000711 // Exit is essentially a static function and doesn't use the
712 // receiver, so we have to get the current isolate from the thread
713 // local.
Steve Block44f0eee2011-05-26 01:26:41 +0100714 i::Isolate* isolate = i::Isolate::Current();
715 if (!isolate->IsInitialized()) return;
716
717 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000718 "v8::Context::Exit()",
719 "Cannot exit non-entered context")) {
720 return;
721 }
722
723 // Content of 'last_context' could be NULL.
Steve Block44f0eee2011-05-26 01:26:41 +0100724 i::Context* last_context =
725 isolate->handle_scope_implementer()->RestoreContext();
726 isolate->set_context(last_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000727}
728
729
Steve Blockd0582a62009-12-15 09:54:21 +0000730void Context::SetData(v8::Handle<String> data) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000731 i::Handle<i::Context> env = Utils::OpenHandle(this);
732 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100733 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000734 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
735 ASSERT(env->IsGlobalContext());
736 if (env->IsGlobalContext()) {
737 env->set_data(*raw_data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000738 }
739}
740
741
742v8::Local<v8::Value> Context::GetData() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000743 i::Handle<i::Context> env = Utils::OpenHandle(this);
744 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100745 if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
746 return v8::Local<Value>();
747 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000748 i::Object* raw_result = NULL;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000749 ASSERT(env->IsGlobalContext());
750 if (env->IsGlobalContext()) {
751 raw_result = env->data();
752 } else {
753 return Local<Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000754 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000755 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000756 return Utils::ToLocal(result);
757}
758
759
760i::Object** v8::HandleScope::RawClose(i::Object** value) {
761 if (!ApiCheck(!is_closed_,
762 "v8::HandleScope::Close()",
763 "Local scope has already been closed")) {
764 return 0;
765 }
Steve Block44f0eee2011-05-26 01:26:41 +0100766 LOG_API(isolate_, "CloseHandleScope");
Steve Blocka7e24c12009-10-30 11:49:00 +0000767
768 // Read the result before popping the handle block.
Steve Block6ded16b2010-05-10 14:33:55 +0100769 i::Object* result = NULL;
770 if (value != NULL) {
771 result = *value;
772 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000773 is_closed_ = true;
John Reck59135872010-11-02 12:39:01 -0700774 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000775
Steve Block6ded16b2010-05-10 14:33:55 +0100776 if (value == NULL) {
777 return NULL;
778 }
779
Steve Blocka7e24c12009-10-30 11:49:00 +0000780 // Allocate a new handle on the previous handle block.
781 i::Handle<i::Object> handle(result);
782 return handle.location();
783}
784
785
786// --- N e a n d e r ---
787
788
789// A constructor cannot easily return an error value, therefore it is necessary
790// to check for a dead VM with ON_BAILOUT before constructing any Neander
791// objects. To remind you about this there is no HandleScope in the
792// NeanderObject constructor. When you add one to the site calling the
793// constructor you should check that you ensured the VM was not dead first.
794NeanderObject::NeanderObject(int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100795 i::Isolate* isolate = i::Isolate::Current();
796 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
797 ENTER_V8(isolate);
798 value_ = isolate->factory()->NewNeanderObject();
799 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000800 value_->set_elements(*elements);
801}
802
803
804int NeanderObject::size() {
805 return i::FixedArray::cast(value_->elements())->length();
806}
807
808
809NeanderArray::NeanderArray() : obj_(2) {
810 obj_.set(0, i::Smi::FromInt(0));
811}
812
813
814int NeanderArray::length() {
815 return i::Smi::cast(obj_.get(0))->value();
816}
817
818
819i::Object* NeanderArray::get(int offset) {
820 ASSERT(0 <= offset);
821 ASSERT(offset < length());
822 return obj_.get(offset + 1);
823}
824
825
826// This method cannot easily return an error value, therefore it is necessary
827// to check for a dead VM with ON_BAILOUT before calling it. To remind you
828// about this there is no HandleScope in this method. When you add one to the
829// site calling this method you should check that you ensured the VM was not
830// dead first.
831void NeanderArray::add(i::Handle<i::Object> value) {
832 int length = this->length();
833 int size = obj_.size();
834 if (length == size - 1) {
Steve Block44f0eee2011-05-26 01:26:41 +0100835 i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000836 for (int i = 0; i < length; i++)
837 new_elms->set(i + 1, get(i));
838 obj_.value()->set_elements(*new_elms);
839 }
840 obj_.set(length + 1, *value);
841 obj_.set(0, i::Smi::FromInt(length + 1));
842}
843
844
845void NeanderArray::set(int index, i::Object* value) {
846 if (index < 0 || index >= this->length()) return;
847 obj_.set(index + 1, value);
848}
849
850
851// --- T e m p l a t e ---
852
853
854static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
855 that->set_tag(i::Smi::FromInt(type));
856}
857
858
859void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
860 v8::PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +0100861 i::Isolate* isolate = i::Isolate::Current();
862 if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
863 ENTER_V8(isolate);
864 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000865 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
866 if (list->IsUndefined()) {
867 list = NeanderArray().value();
868 Utils::OpenHandle(this)->set_property_list(*list);
869 }
870 NeanderArray array(list);
871 array.add(Utils::OpenHandle(*name));
872 array.add(Utils::OpenHandle(*value));
873 array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
874}
875
876
877// --- F u n c t i o n T e m p l a t e ---
878static void InitializeFunctionTemplate(
879 i::Handle<i::FunctionTemplateInfo> info) {
880 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
881 info->set_flag(0);
882}
883
884
885Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +0100886 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
887 if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000888 return Local<ObjectTemplate>();
889 }
Steve Block44f0eee2011-05-26 01:26:41 +0100890 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000891 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
892 if (result->IsUndefined()) {
893 result = Utils::OpenHandle(*ObjectTemplate::New());
894 Utils::OpenHandle(this)->set_prototype_template(*result);
895 }
896 return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
897}
898
899
900void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100901 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
902 if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
903 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000904 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
905}
906
907
Steve Blocka7e24c12009-10-30 11:49:00 +0000908Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
909 v8::Handle<Value> data, v8::Handle<Signature> signature) {
Steve Block44f0eee2011-05-26 01:26:41 +0100910 i::Isolate* isolate = i::Isolate::Current();
911 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
912 LOG_API(isolate, "FunctionTemplate::New");
913 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000914 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100915 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000916 i::Handle<i::FunctionTemplateInfo> obj =
917 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
918 InitializeFunctionTemplate(obj);
Steve Block44f0eee2011-05-26 01:26:41 +0100919 int next_serial_number = isolate->next_serial_number();
920 isolate->set_next_serial_number(next_serial_number + 1);
921 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +0000922 if (callback != 0) {
923 if (data.IsEmpty()) data = v8::Undefined();
924 Utils::ToLocal(obj)->SetCallHandler(callback, data);
925 }
926 obj->set_undetectable(false);
927 obj->set_needs_access_check(false);
928
929 if (!signature.IsEmpty())
930 obj->set_signature(*Utils::OpenHandle(*signature));
931 return Utils::ToLocal(obj);
932}
933
934
935Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
936 int argc, Handle<FunctionTemplate> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100937 i::Isolate* isolate = i::Isolate::Current();
938 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
939 LOG_API(isolate, "Signature::New");
940 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000941 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100942 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000943 i::Handle<i::SignatureInfo> obj =
944 i::Handle<i::SignatureInfo>::cast(struct_obj);
945 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
946 if (argc > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100947 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000948 for (int i = 0; i < argc; i++) {
949 if (!argv[i].IsEmpty())
950 args->set(i, *Utils::OpenHandle(*argv[i]));
951 }
952 obj->set_args(*args);
953 }
954 return Utils::ToLocal(obj);
955}
956
957
958Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
959 Handle<FunctionTemplate> types[1] = { type };
960 return TypeSwitch::New(1, types);
961}
962
963
964Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100965 i::Isolate* isolate = i::Isolate::Current();
966 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
967 LOG_API(isolate, "TypeSwitch::New");
968 ENTER_V8(isolate);
969 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000970 for (int i = 0; i < argc; i++)
971 vector->set(i, *Utils::OpenHandle(*types[i]));
972 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100973 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000974 i::Handle<i::TypeSwitchInfo> obj =
975 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
976 obj->set_types(*vector);
977 return Utils::ToLocal(obj);
978}
979
980
981int TypeSwitch::match(v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100982 i::Isolate* isolate = i::Isolate::Current();
983 LOG_API(isolate, "TypeSwitch::match");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000984 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000985 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
986 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
987 i::FixedArray* types = i::FixedArray::cast(info->types());
988 for (int i = 0; i < types->length(); i++) {
989 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
990 return i + 1;
991 }
992 return 0;
993}
994
995
Ben Murdoch257744e2011-11-30 15:57:28 +0000996#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
997 i::Handle<i::Object> foreign = FromCData(cdata); \
998 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100999 } while (false)
1000
1001
Steve Blocka7e24c12009-10-30 11:49:00 +00001002void FunctionTemplate::SetCallHandler(InvocationCallback callback,
1003 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001004 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1005 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
1006 ENTER_V8(isolate);
1007 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001008 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001009 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001010 i::Handle<i::CallHandlerInfo> obj =
1011 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001012 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001013 if (data.IsEmpty()) data = v8::Undefined();
1014 obj->set_data(*Utils::OpenHandle(*data));
1015 Utils::OpenHandle(this)->set_call_code(*obj);
1016}
1017
1018
Leon Clarkef7060e22010-06-03 12:02:55 +01001019static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1020 v8::Handle<String> name,
1021 AccessorGetter getter,
1022 AccessorSetter setter,
1023 v8::Handle<Value> data,
1024 v8::AccessControl settings,
1025 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01001026 i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
Leon Clarkef7060e22010-06-03 12:02:55 +01001027 ASSERT(getter != NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001028 SET_FIELD_WRAPPED(obj, set_getter, getter);
1029 SET_FIELD_WRAPPED(obj, set_setter, setter);
Leon Clarkef7060e22010-06-03 12:02:55 +01001030 if (data.IsEmpty()) data = v8::Undefined();
1031 obj->set_data(*Utils::OpenHandle(*data));
1032 obj->set_name(*Utils::OpenHandle(*name));
1033 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1034 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1035 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
1036 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
1037 return obj;
1038}
1039
1040
Steve Blocka7e24c12009-10-30 11:49:00 +00001041void FunctionTemplate::AddInstancePropertyAccessor(
1042 v8::Handle<String> name,
1043 AccessorGetter getter,
1044 AccessorSetter setter,
1045 v8::Handle<Value> data,
1046 v8::AccessControl settings,
1047 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01001048 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1049 if (IsDeadCheck(isolate,
1050 "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001051 return;
1052 }
Steve Block44f0eee2011-05-26 01:26:41 +01001053 ENTER_V8(isolate);
1054 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001055
Leon Clarkef7060e22010-06-03 12:02:55 +01001056 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
1057 getter, setter, data,
1058 settings, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00001059 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
1060 if (list->IsUndefined()) {
1061 list = NeanderArray().value();
1062 Utils::OpenHandle(this)->set_property_accessors(*list);
1063 }
1064 NeanderArray array(list);
1065 array.add(obj);
1066}
1067
1068
1069Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +01001070 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1071 if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
Steve Blocka7e24c12009-10-30 11:49:00 +00001072 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
1073 return Local<ObjectTemplate>();
Steve Block44f0eee2011-05-26 01:26:41 +01001074 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001075 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
1076 Local<ObjectTemplate> templ =
1077 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
1078 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
1079 }
1080 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
1081 Utils::OpenHandle(this)->instance_template()));
1082 return Utils::ToLocal(result);
1083}
1084
1085
1086void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01001087 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1088 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
1089 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001090 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1091}
1092
1093
1094void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001095 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1096 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
1097 return;
1098 }
1099 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001100 Utils::OpenHandle(this)->set_hidden_prototype(value);
1101}
1102
1103
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001104void FunctionTemplate::ReadOnlyPrototype() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001105 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1106 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
1107 return;
1108 }
1109 ENTER_V8(isolate);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001110 Utils::OpenHandle(this)->set_read_only_prototype(true);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001111}
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);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001410 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping);
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());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001419 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001420 } else {
1421 i::GenericStringUC16CharacterStream stream(str, 0, str->length());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001422 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001423 }
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()) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003168 // Functions have null as a constructor,
Ben Murdoch8b112d22011-06-08 16:22:53 +01003169 // but any JSFunction knows its context immediately.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003170 ASSERT(object->IsJSFunction());
Ben Murdoch8b112d22011-06-08 16:22:53 +01003171 function = i::JSFunction::cast(object);
3172 } else {
3173 function = i::JSFunction::cast(constructor);
3174 }
3175 return function->context()->global_context();
3176}
3177
3178
3179Local<v8::Context> v8::Object::CreationContext() {
3180 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3181 ON_BAILOUT(isolate,
3182 "v8::Object::CreationContext()", return Local<v8::Context>());
3183 ENTER_V8(isolate);
3184 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3185 i::Context* context = GetCreationContext(*self);
3186 return Utils::ToLocal(i::Handle<i::Context>(context));
3187}
3188
3189
Steve Blocka7e24c12009-10-30 11:49:00 +00003190int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01003191 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3192 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
3193 ENTER_V8(isolate);
3194 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003195 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003196 return i::GetIdentityHash(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00003197}
3198
3199
3200bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3201 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003202 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3203 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
3204 ENTER_V8(isolate);
3205 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003206 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003207 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
3208 self,
3209 i::JSObject::ALLOW_CREATION));
Steve Blocka7e24c12009-10-30 11:49:00 +00003210 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3211 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003212 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003213 i::Handle<i::Object> obj = i::SetProperty(
3214 hidden_props,
3215 key_obj,
3216 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01003217 static_cast<PropertyAttributes>(None),
3218 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003219 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003220 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003221 return true;
3222}
3223
3224
3225v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003226 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3227 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3228 return Local<v8::Value>());
3229 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003230 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003231 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
3232 self,
3233 i::JSObject::OMIT_CREATION));
Steve Blocka7e24c12009-10-30 11:49:00 +00003234 if (hidden_props->IsUndefined()) {
3235 return v8::Local<v8::Value>();
3236 }
3237 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01003238 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003239 i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
3240 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003241 EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003242 if (result->IsUndefined()) {
3243 return v8::Local<v8::Value>();
3244 }
3245 return Utils::ToLocal(result);
3246}
3247
3248
3249bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003250 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3251 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
3252 ENTER_V8(isolate);
3253 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003254 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003255 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
3256 self,
3257 i::JSObject::OMIT_CREATION));
Steve Blocka7e24c12009-10-30 11:49:00 +00003258 if (hidden_props->IsUndefined()) {
3259 return true;
3260 }
3261 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
3262 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3263 return i::DeleteProperty(js_obj, key_obj)->IsTrue();
3264}
3265
3266
Steve Block44f0eee2011-05-26 01:26:41 +01003267namespace {
3268
Ben Murdoch589d6972011-11-30 16:04:58 +00003269static i::ElementsKind GetElementsKindFromExternalArrayType(
3270 ExternalArrayType array_type) {
3271 switch (array_type) {
3272 case kExternalByteArray:
3273 return i::EXTERNAL_BYTE_ELEMENTS;
3274 break;
3275 case kExternalUnsignedByteArray:
3276 return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3277 break;
3278 case kExternalShortArray:
3279 return i::EXTERNAL_SHORT_ELEMENTS;
3280 break;
3281 case kExternalUnsignedShortArray:
3282 return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3283 break;
3284 case kExternalIntArray:
3285 return i::EXTERNAL_INT_ELEMENTS;
3286 break;
3287 case kExternalUnsignedIntArray:
3288 return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
3289 break;
3290 case kExternalFloatArray:
3291 return i::EXTERNAL_FLOAT_ELEMENTS;
3292 break;
3293 case kExternalDoubleArray:
3294 return i::EXTERNAL_DOUBLE_ELEMENTS;
3295 break;
3296 case kExternalPixelArray:
3297 return i::EXTERNAL_PIXEL_ELEMENTS;
3298 break;
3299 }
3300 UNREACHABLE();
3301 return i::DICTIONARY_ELEMENTS;
3302}
3303
3304
Steve Block44f0eee2011-05-26 01:26:41 +01003305void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3306 void* data,
3307 ExternalArrayType array_type,
3308 int length) {
3309 i::Isolate* isolate = object->GetIsolate();
3310 i::Handle<i::ExternalArray> array =
3311 isolate->factory()->NewExternalArray(length, array_type, data);
3312
3313 // If the object already has external elements, create a new, unique
3314 // map if the element type is now changing, because assumptions about
3315 // generated code based on the receiver's map will be invalid.
3316 i::Handle<i::HeapObject> elements(object->elements());
3317 bool cant_reuse_map =
3318 elements->map()->IsUndefined() ||
3319 !elements->map()->has_external_array_elements() ||
3320 elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
3321 if (cant_reuse_map) {
3322 i::Handle<i::Map> external_array_map =
Ben Murdoch589d6972011-11-30 16:04:58 +00003323 isolate->factory()->GetElementsTransitionMap(
Steve Block44f0eee2011-05-26 01:26:41 +01003324 i::Handle<i::Map>(object->map()),
Ben Murdoch589d6972011-11-30 16:04:58 +00003325 GetElementsKindFromExternalArrayType(array_type),
Steve Block44f0eee2011-05-26 01:26:41 +01003326 object->HasFastProperties());
3327 object->set_map(*external_array_map);
3328 }
3329 object->set_elements(*array);
3330}
3331
3332} // namespace
3333
3334
Steve Blocka7e24c12009-10-30 11:49:00 +00003335void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003336 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3337 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3338 ENTER_V8(isolate);
3339 i::HandleScope scope(isolate);
3340 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
Steve Blocka7e24c12009-10-30 11:49:00 +00003341 "v8::Object::SetIndexedPropertiesToPixelData()",
3342 "length exceeds max acceptable value")) {
3343 return;
3344 }
3345 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3346 if (!ApiCheck(!self->IsJSArray(),
3347 "v8::Object::SetIndexedPropertiesToPixelData()",
3348 "JSArray is not supported")) {
3349 return;
3350 }
Steve Block44f0eee2011-05-26 01:26:41 +01003351 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003352}
3353
3354
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003355bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003356 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003357 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3358 return false);
3359 return self->HasExternalPixelElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003360}
3361
3362
3363uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003364 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003365 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3366 return NULL);
3367 if (self->HasExternalPixelElements()) {
3368 return i::ExternalPixelArray::cast(self->elements())->
3369 external_pixel_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003370 } else {
3371 return NULL;
3372 }
3373}
3374
3375
3376int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003377 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003378 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3379 return -1);
3380 if (self->HasExternalPixelElements()) {
3381 return i::ExternalPixelArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003382 } else {
3383 return -1;
3384 }
3385}
3386
Ben Murdoch589d6972011-11-30 16:04:58 +00003387
Steve Block3ce2e202009-11-05 08:53:23 +00003388void v8::Object::SetIndexedPropertiesToExternalArrayData(
3389 void* data,
3390 ExternalArrayType array_type,
3391 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003392 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3393 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3394 ENTER_V8(isolate);
3395 i::HandleScope scope(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003396 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3397 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3398 "length exceeds max acceptable value")) {
3399 return;
3400 }
3401 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3402 if (!ApiCheck(!self->IsJSArray(),
3403 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3404 "JSArray is not supported")) {
3405 return;
3406 }
Steve Block44f0eee2011-05-26 01:26:41 +01003407 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003408}
3409
3410
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003411bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003412 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003413 ON_BAILOUT(self->GetIsolate(),
3414 "v8::HasIndexedPropertiesInExternalArrayData()",
3415 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003416 return self->HasExternalArrayElements();
3417}
3418
3419
3420void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003421 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003422 ON_BAILOUT(self->GetIsolate(),
3423 "v8::GetIndexedPropertiesExternalArrayData()",
3424 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003425 if (self->HasExternalArrayElements()) {
3426 return i::ExternalArray::cast(self->elements())->external_pointer();
3427 } else {
3428 return NULL;
3429 }
3430}
3431
3432
3433ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003434 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003435 ON_BAILOUT(self->GetIsolate(),
3436 "v8::GetIndexedPropertiesExternalArrayDataType()",
3437 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003438 switch (self->elements()->map()->instance_type()) {
3439 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3440 return kExternalByteArray;
3441 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3442 return kExternalUnsignedByteArray;
3443 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3444 return kExternalShortArray;
3445 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3446 return kExternalUnsignedShortArray;
3447 case i::EXTERNAL_INT_ARRAY_TYPE:
3448 return kExternalIntArray;
3449 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3450 return kExternalUnsignedIntArray;
3451 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3452 return kExternalFloatArray;
Ben Murdoch257744e2011-11-30 15:57:28 +00003453 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3454 return kExternalDoubleArray;
Steve Block44f0eee2011-05-26 01:26:41 +01003455 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3456 return kExternalPixelArray;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003457 default:
3458 return static_cast<ExternalArrayType>(-1);
3459 }
3460}
3461
3462
3463int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003464 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003465 ON_BAILOUT(self->GetIsolate(),
3466 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3467 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003468 if (self->HasExternalArrayElements()) {
3469 return i::ExternalArray::cast(self->elements())->length();
3470 } else {
3471 return -1;
3472 }
3473}
3474
3475
Ben Murdoch257744e2011-11-30 15:57:28 +00003476bool v8::Object::IsCallable() {
3477 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3478 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3479 ENTER_V8(isolate);
3480 i::HandleScope scope(isolate);
3481 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3482 if (obj->IsJSFunction()) return true;
3483 return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
3484}
3485
3486
3487Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
3488 v8::Handle<v8::Value> argv[]) {
3489 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3490 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3491 return Local<v8::Value>());
3492 LOG_API(isolate, "Object::CallAsFunction");
3493 ENTER_V8(isolate);
3494 i::HandleScope scope(isolate);
3495 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3496 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3497 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3498 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3499 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3500 if (obj->IsJSFunction()) {
3501 fun = i::Handle<i::JSFunction>::cast(obj);
3502 } else {
3503 EXCEPTION_PREAMBLE(isolate);
3504 i::Handle<i::Object> delegate =
3505 i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
3506 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3507 fun = i::Handle<i::JSFunction>::cast(delegate);
3508 recv_obj = obj;
3509 }
3510 EXCEPTION_PREAMBLE(isolate);
3511 i::Handle<i::Object> returned =
3512 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
3513 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3514 return Utils::ToLocal(scope.CloseAndEscape(returned));
3515}
3516
3517
3518Local<v8::Value> Object::CallAsConstructor(int argc,
3519 v8::Handle<v8::Value> argv[]) {
3520 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3521 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3522 return Local<v8::Object>());
3523 LOG_API(isolate, "Object::CallAsConstructor");
3524 ENTER_V8(isolate);
3525 i::HandleScope scope(isolate);
3526 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3527 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3528 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3529 if (obj->IsJSFunction()) {
3530 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
3531 EXCEPTION_PREAMBLE(isolate);
3532 i::Handle<i::Object> returned =
3533 i::Execution::New(fun, argc, args, &has_pending_exception);
3534 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3535 return Utils::ToLocal(scope.CloseAndEscape(
3536 i::Handle<i::JSObject>::cast(returned)));
3537 }
3538 EXCEPTION_PREAMBLE(isolate);
3539 i::Handle<i::Object> delegate =
3540 i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
3541 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3542 if (!delegate->IsUndefined()) {
3543 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
3544 EXCEPTION_PREAMBLE(isolate);
3545 i::Handle<i::Object> returned =
3546 i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
3547 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3548 ASSERT(!delegate->IsUndefined());
3549 return Utils::ToLocal(scope.CloseAndEscape(returned));
3550 }
3551 return Local<v8::Object>();
3552}
3553
3554
Steve Blocka7e24c12009-10-30 11:49:00 +00003555Local<v8::Object> Function::NewInstance() const {
3556 return NewInstance(0, NULL);
3557}
3558
3559
3560Local<v8::Object> Function::NewInstance(int argc,
3561 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003562 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3563 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3564 return Local<v8::Object>());
3565 LOG_API(isolate, "Function::NewInstance");
3566 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003567 HandleScope scope;
3568 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3569 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3570 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003571 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003572 i::Handle<i::Object> returned =
3573 i::Execution::New(function, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003574 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003575 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3576}
3577
3578
3579Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3580 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01003581 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3582 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3583 LOG_API(isolate, "Function::Call");
3584 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003585 i::Object* raw_result = NULL;
3586 {
Steve Block44f0eee2011-05-26 01:26:41 +01003587 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003588 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3589 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3590 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3591 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003592 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003593 i::Handle<i::Object> returned =
3594 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003595 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003596 raw_result = *returned;
3597 }
3598 i::Handle<i::Object> result(raw_result);
3599 return Utils::ToLocal(result);
3600}
3601
3602
3603void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01003604 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3605 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003606 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003607 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3608 func->shared()->set_name(*Utils::OpenHandle(*name));
3609}
3610
3611
3612Handle<Value> Function::GetName() const {
3613 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3614 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3615}
3616
3617
Andrei Popescu402d9372010-02-26 13:31:12 +00003618ScriptOrigin Function::GetScriptOrigin() const {
3619 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3620 if (func->shared()->script()->IsScript()) {
3621 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3622 v8::ScriptOrigin origin(
3623 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3624 v8::Integer::New(script->line_offset()->value()),
3625 v8::Integer::New(script->column_offset()->value()));
3626 return origin;
3627 }
3628 return v8::ScriptOrigin(Handle<Value>());
3629}
3630
3631
3632const int Function::kLineOffsetNotFound = -1;
3633
3634
3635int Function::GetScriptLineNumber() const {
3636 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3637 if (func->shared()->script()->IsScript()) {
3638 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3639 return i::GetScriptLineNumber(script, func->shared()->start_position());
3640 }
3641 return kLineOffsetNotFound;
3642}
3643
3644
Steve Blocka7e24c12009-10-30 11:49:00 +00003645int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003646 i::Handle<i::String> str = Utils::OpenHandle(this);
3647 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3648 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003649}
3650
3651
3652int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003653 i::Handle<i::String> str = Utils::OpenHandle(this);
3654 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
3655 return str->Utf8Length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003656}
3657
3658
Steve Block6ded16b2010-05-10 14:33:55 +01003659int String::WriteUtf8(char* buffer,
3660 int capacity,
3661 int* nchars_ref,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003662 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003663 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3664 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3665 LOG_API(isolate, "String::WriteUtf8");
3666 ENTER_V8(isolate);
3667 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003668 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003669 isolate->string_tracker()->RecordWrite(str);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003670 if (options & HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01003671 // Flatten the string for efficiency. This applies whether we are
3672 // using StringInputBuffer or Get(i) to access the characters.
3673 str->TryFlatten();
3674 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003675 write_input_buffer.Reset(0, *str);
3676 int len = str->length();
3677 // Encode the first K - 3 bytes directly into the buffer since we
3678 // know there's room for them. If no capacity is given we copy all
3679 // of them here.
3680 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3681 int i;
3682 int pos = 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003683 int nchars = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003684 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3685 i::uc32 c = write_input_buffer.GetNext();
3686 int written = unibrow::Utf8::Encode(buffer + pos, c);
3687 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003688 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003689 }
3690 if (i < len) {
3691 // For the last characters we need to check the length for each one
3692 // because they may be longer than the remaining space in the
3693 // buffer.
3694 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3695 for (; i < len && pos < capacity; i++) {
3696 i::uc32 c = write_input_buffer.GetNext();
3697 int written = unibrow::Utf8::Encode(intermediate, c);
3698 if (pos + written <= capacity) {
3699 for (int j = 0; j < written; j++)
3700 buffer[pos + j] = intermediate[j];
3701 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003702 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003703 } else {
3704 // We've reached the end of the buffer
3705 break;
3706 }
3707 }
3708 }
Steve Block6ded16b2010-05-10 14:33:55 +01003709 if (nchars_ref != NULL) *nchars_ref = nchars;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003710 if (!(options & NO_NULL_TERMINATION) &&
3711 (i == len && (capacity == -1 || pos < capacity)))
Steve Blocka7e24c12009-10-30 11:49:00 +00003712 buffer[pos++] = '\0';
3713 return pos;
3714}
3715
3716
Steve Block6ded16b2010-05-10 14:33:55 +01003717int String::WriteAscii(char* buffer,
3718 int start,
3719 int length,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003720 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003721 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3722 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3723 LOG_API(isolate, "String::WriteAscii");
3724 ENTER_V8(isolate);
3725 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003726 ASSERT(start >= 0 && length >= -1);
3727 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003728 isolate->string_tracker()->RecordWrite(str);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003729 if (options & HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01003730 // Flatten the string for efficiency. This applies whether we are
3731 // using StringInputBuffer or Get(i) to access the characters.
3732 str->TryFlatten();
3733 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003734 int end = length;
3735 if ( (length == -1) || (length > str->length() - start) )
3736 end = str->length() - start;
3737 if (end < 0) return 0;
3738 write_input_buffer.Reset(start, *str);
3739 int i;
3740 for (i = 0; i < end; i++) {
3741 char c = static_cast<char>(write_input_buffer.GetNext());
3742 if (c == '\0') c = ' ';
3743 buffer[i] = c;
3744 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003745 if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length))
Steve Blocka7e24c12009-10-30 11:49:00 +00003746 buffer[i] = '\0';
3747 return i;
3748}
3749
3750
Steve Block6ded16b2010-05-10 14:33:55 +01003751int String::Write(uint16_t* buffer,
3752 int start,
3753 int length,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003754 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003755 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3756 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
3757 LOG_API(isolate, "String::Write");
3758 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003759 ASSERT(start >= 0 && length >= -1);
3760 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003761 isolate->string_tracker()->RecordWrite(str);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003762 if (options & HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01003763 // Flatten the string for efficiency. This applies whether we are
3764 // using StringInputBuffer or Get(i) to access the characters.
3765 str->TryFlatten();
3766 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003767 int end = start + length;
3768 if ((length == -1) || (length > str->length() - start) )
3769 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003770 if (end < 0) return 0;
3771 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003772 if (!(options & NO_NULL_TERMINATION) &&
3773 (length == -1 || end - start < length)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01003774 buffer[end - start] = '\0';
3775 }
3776 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003777}
3778
3779
3780bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003781 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003782 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
3783 return false;
3784 }
3785 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
Steve Blocka7e24c12009-10-30 11:49:00 +00003786 return i::StringShape(*str).IsExternalTwoByte();
3787}
3788
3789
3790bool v8::String::IsExternalAscii() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003791 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003792 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
3793 return false;
3794 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003795 return i::StringShape(*str).IsExternalAscii();
3796}
3797
3798
3799void v8::String::VerifyExternalStringResource(
3800 v8::String::ExternalStringResource* value) const {
3801 i::Handle<i::String> str = Utils::OpenHandle(this);
3802 v8::String::ExternalStringResource* expected;
3803 if (i::StringShape(*str).IsExternalTwoByte()) {
3804 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
3805 expected = reinterpret_cast<ExternalStringResource*>(resource);
3806 } else {
3807 expected = NULL;
3808 }
3809 CHECK_EQ(expected, value);
3810}
3811
3812
3813v8::String::ExternalAsciiStringResource*
3814 v8::String::GetExternalAsciiStringResource() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003815 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003816 if (IsDeadCheck(str->GetIsolate(),
3817 "v8::String::GetExternalAsciiStringResource()")) {
3818 return NULL;
3819 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003820 if (i::StringShape(*str).IsExternalAscii()) {
3821 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
3822 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
3823 } else {
3824 return NULL;
3825 }
3826}
3827
3828
3829double Number::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003830 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003831 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3832 return obj->Number();
3833}
3834
3835
3836bool Boolean::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003837 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003838 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3839 return obj->IsTrue();
3840}
3841
3842
3843int64_t Integer::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003844 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003845 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3846 if (obj->IsSmi()) {
3847 return i::Smi::cast(*obj)->value();
3848 } else {
3849 return static_cast<int64_t>(obj->Number());
3850 }
3851}
3852
3853
3854int32_t Int32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003855 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003856 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3857 if (obj->IsSmi()) {
3858 return i::Smi::cast(*obj)->value();
3859 } else {
3860 return static_cast<int32_t>(obj->Number());
3861 }
3862}
3863
3864
Steve Block6ded16b2010-05-10 14:33:55 +01003865uint32_t Uint32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003866 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003867 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3868 if (obj->IsSmi()) {
3869 return i::Smi::cast(*obj)->value();
3870 } else {
3871 return static_cast<uint32_t>(obj->Number());
3872 }
3873}
3874
3875
Steve Blocka7e24c12009-10-30 11:49:00 +00003876int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003877 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003878 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
3879 return 0;
3880 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003881 return obj->GetInternalFieldCount();
3882}
3883
3884
3885Local<Value> v8::Object::CheckedGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003886 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003887 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
3888 return Local<Value>();
3889 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003890 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3891 "v8::Object::GetInternalField()",
3892 "Reading internal field out of bounds")) {
3893 return Local<Value>();
3894 }
3895 i::Handle<i::Object> value(obj->GetInternalField(index));
3896 Local<Value> result = Utils::ToLocal(value);
3897#ifdef DEBUG
3898 Local<Value> unchecked = UncheckedGetInternalField(index);
3899 ASSERT(unchecked.IsEmpty() || (unchecked == result));
3900#endif
3901 return result;
3902}
3903
3904
3905void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003906 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003907 i::Isolate* isolate = obj->GetIsolate();
3908 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
3909 return;
3910 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003911 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3912 "v8::Object::SetInternalField()",
3913 "Writing internal field out of bounds")) {
3914 return;
3915 }
Steve Block44f0eee2011-05-26 01:26:41 +01003916 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003917 i::Handle<i::Object> val = Utils::OpenHandle(*value);
3918 obj->SetInternalField(index, *val);
3919}
3920
3921
Ben Murdochb8e0da22011-05-16 14:20:40 +01003922static bool CanBeEncodedAsSmi(void* ptr) {
Steve Block1e0659c2011-05-24 12:43:12 +01003923 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003924 return ((address & i::kEncodablePointerMask) == 0);
3925}
3926
3927
3928static i::Smi* EncodeAsSmi(void* ptr) {
3929 ASSERT(CanBeEncodedAsSmi(ptr));
Steve Block1e0659c2011-05-24 12:43:12 +01003930 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003931 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
3932 ASSERT(i::Internals::HasSmiTag(result));
3933 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
3934 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
3935 return result;
3936}
3937
3938
Steve Blocka7e24c12009-10-30 11:49:00 +00003939void v8::Object::SetPointerInInternalField(int index, void* value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003940 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3941 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003942 if (CanBeEncodedAsSmi(value)) {
3943 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
3944 } else {
3945 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00003946 i::Handle<i::Foreign> foreign =
3947 isolate->factory()->NewForeign(
Steve Block44f0eee2011-05-26 01:26:41 +01003948 reinterpret_cast<i::Address>(value), i::TENURED);
Ben Murdoch257744e2011-11-30 15:57:28 +00003949 if (!foreign.is_null())
3950 Utils::OpenHandle(this)->SetInternalField(index, *foreign);
Steve Block3ce2e202009-11-05 08:53:23 +00003951 }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003952 ASSERT_EQ(value, GetPointerFromInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003953}
3954
3955
3956// --- E n v i r o n m e n t ---
3957
Steve Block44f0eee2011-05-26 01:26:41 +01003958
Steve Blocka7e24c12009-10-30 11:49:00 +00003959bool v8::V8::Initialize() {
Steve Block44f0eee2011-05-26 01:26:41 +01003960 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
3961 if (isolate != NULL && isolate->IsInitialized()) {
3962 return true;
3963 }
3964 return InitializeHelper();
Steve Blocka7e24c12009-10-30 11:49:00 +00003965}
3966
3967
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003968void v8::V8::SetEntropySource(EntropySource source) {
3969 i::V8::SetEntropySource(source);
3970}
3971
3972
Steve Blocka7e24c12009-10-30 11:49:00 +00003973bool v8::V8::Dispose() {
Steve Block44f0eee2011-05-26 01:26:41 +01003974 i::Isolate* isolate = i::Isolate::Current();
3975 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
3976 "v8::V8::Dispose()",
3977 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
3978 return false;
3979 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003980 i::V8::TearDown();
3981 return true;
3982}
3983
3984
Russell Brenner90bac252010-11-18 13:33:46 -08003985HeapStatistics::HeapStatistics(): total_heap_size_(0),
3986 total_heap_size_executable_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01003987 used_heap_size_(0),
3988 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00003989
3990
3991void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
Steve Block44f0eee2011-05-26 01:26:41 +01003992 i::Heap* heap = i::Isolate::Current()->heap();
3993 heap_statistics->set_total_heap_size(heap->CommittedMemory());
Russell Brenner90bac252010-11-18 13:33:46 -08003994 heap_statistics->set_total_heap_size_executable(
Steve Block44f0eee2011-05-26 01:26:41 +01003995 heap->CommittedMemoryExecutable());
3996 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
3997 heap_statistics->set_heap_size_limit(heap->MaxReserved());
Steve Block3ce2e202009-11-05 08:53:23 +00003998}
3999
4000
4001bool v8::V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004002 // Returning true tells the caller that it need not
4003 // continue to call IdleNotification.
Steve Block44f0eee2011-05-26 01:26:41 +01004004 if (!i::Isolate::Current()->IsInitialized()) return true;
Steve Block3ce2e202009-11-05 08:53:23 +00004005 return i::V8::IdleNotification();
Steve Blocka7e24c12009-10-30 11:49:00 +00004006}
4007
4008
4009void v8::V8::LowMemoryNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004010 i::Isolate* isolate = i::Isolate::Current();
4011 if (!isolate->IsInitialized()) return;
4012 isolate->heap()->CollectAllGarbage(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004013}
4014
4015
Steve Block6ded16b2010-05-10 14:33:55 +01004016int v8::V8::ContextDisposedNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004017 i::Isolate* isolate = i::Isolate::Current();
4018 if (!isolate->IsInitialized()) return 0;
4019 return isolate->heap()->NotifyContextDisposed();
Steve Block6ded16b2010-05-10 14:33:55 +01004020}
4021
4022
Steve Blocka7e24c12009-10-30 11:49:00 +00004023const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01004024 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00004025}
4026
4027
4028static i::Handle<i::FunctionTemplateInfo>
4029 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
4030 if (templ->constructor()->IsUndefined()) {
4031 Local<FunctionTemplate> constructor = FunctionTemplate::New();
4032 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
4033 templ->set_constructor(*Utils::OpenHandle(*constructor));
4034 }
4035 return i::Handle<i::FunctionTemplateInfo>(
4036 i::FunctionTemplateInfo::cast(templ->constructor()));
4037}
4038
4039
4040Persistent<Context> v8::Context::New(
4041 v8::ExtensionConfiguration* extensions,
4042 v8::Handle<ObjectTemplate> global_template,
4043 v8::Handle<Value> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01004044 i::Isolate* isolate = i::Isolate::Current();
4045 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
4046 LOG_API(isolate, "Context::New");
4047 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004048
4049 // Enter V8 via an ENTER_V8 scope.
4050 i::Handle<i::Context> env;
4051 {
Steve Block44f0eee2011-05-26 01:26:41 +01004052 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004053 v8::Handle<ObjectTemplate> proxy_template = global_template;
4054 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
4055 i::Handle<i::FunctionTemplateInfo> global_constructor;
4056
4057 if (!global_template.IsEmpty()) {
4058 // Make sure that the global_template has a constructor.
4059 global_constructor =
4060 EnsureConstructor(Utils::OpenHandle(*global_template));
4061
4062 // Create a fresh template for the global proxy object.
4063 proxy_template = ObjectTemplate::New();
4064 proxy_constructor =
4065 EnsureConstructor(Utils::OpenHandle(*proxy_template));
4066
4067 // Set the global template to be the prototype template of
4068 // global proxy template.
4069 proxy_constructor->set_prototype_template(
4070 *Utils::OpenHandle(*global_template));
4071
4072 // Migrate security handlers from global_template to
4073 // proxy_template. Temporarily removing access check
4074 // information from the global template.
4075 if (!global_constructor->access_check_info()->IsUndefined()) {
4076 proxy_constructor->set_access_check_info(
4077 global_constructor->access_check_info());
4078 proxy_constructor->set_needs_access_check(
4079 global_constructor->needs_access_check());
4080 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01004081 global_constructor->set_access_check_info(
4082 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004083 }
4084 }
4085
4086 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01004087 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdoch257744e2011-11-30 15:57:28 +00004088 isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004089 Utils::OpenHandle(*global_object),
4090 proxy_template,
4091 extensions);
4092
4093 // Restore the access check info on the global template.
4094 if (!global_template.IsEmpty()) {
4095 ASSERT(!global_constructor.is_null());
4096 ASSERT(!proxy_constructor.is_null());
4097 global_constructor->set_access_check_info(
4098 proxy_constructor->access_check_info());
4099 global_constructor->set_needs_access_check(
4100 proxy_constructor->needs_access_check());
4101 }
Steve Block44f0eee2011-05-26 01:26:41 +01004102 isolate->runtime_profiler()->Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +00004103 }
4104 // Leave V8.
4105
4106 if (env.is_null())
4107 return Persistent<Context>();
4108 return Persistent<Context>(Utils::ToLocal(env));
4109}
4110
4111
4112void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01004113 i::Isolate* isolate = i::Isolate::Current();
4114 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
4115 return;
4116 }
4117 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004118 i::Handle<i::Context> env = Utils::OpenHandle(this);
4119 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
4120 env->set_security_token(*token_handle);
4121}
4122
4123
4124void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01004125 i::Isolate* isolate = i::Isolate::Current();
4126 if (IsDeadCheck(isolate,
4127 "v8::Context::UseDefaultSecurityToken()")) {
4128 return;
4129 }
4130 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004131 i::Handle<i::Context> env = Utils::OpenHandle(this);
4132 env->set_security_token(env->global());
4133}
4134
4135
4136Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01004137 i::Isolate* isolate = i::Isolate::Current();
4138 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
4139 return Handle<Value>();
4140 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004141 i::Handle<i::Context> env = Utils::OpenHandle(this);
4142 i::Object* security_token = env->security_token();
4143 i::Handle<i::Object> token_handle(security_token);
4144 return Utils::ToLocal(token_handle);
4145}
4146
4147
4148bool Context::HasOutOfMemoryException() {
4149 i::Handle<i::Context> env = Utils::OpenHandle(this);
4150 return env->has_out_of_memory();
4151}
4152
4153
4154bool Context::InContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01004155 return i::Isolate::Current()->context() != NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00004156}
4157
4158
4159v8::Local<v8::Context> Context::GetEntered() {
Steve Block44f0eee2011-05-26 01:26:41 +01004160 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004161 if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
Steve Block44f0eee2011-05-26 01:26:41 +01004162 return Local<Context>();
4163 }
4164 i::Handle<i::Object> last =
4165 isolate->handle_scope_implementer()->LastEnteredContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00004166 if (last.is_null()) return Local<Context>();
4167 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
4168 return Utils::ToLocal(context);
4169}
4170
4171
4172v8::Local<v8::Context> Context::GetCurrent() {
Steve Block44f0eee2011-05-26 01:26:41 +01004173 i::Isolate* isolate = i::Isolate::Current();
4174 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
4175 return Local<Context>();
4176 }
4177 i::Handle<i::Object> current = isolate->global_context();
Steve Block3ce2e202009-11-05 08:53:23 +00004178 if (current.is_null()) return Local<Context>();
4179 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
Steve Blocka7e24c12009-10-30 11:49:00 +00004180 return Utils::ToLocal(context);
4181}
4182
4183
4184v8::Local<v8::Context> Context::GetCalling() {
Steve Block44f0eee2011-05-26 01:26:41 +01004185 i::Isolate* isolate = i::Isolate::Current();
4186 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
4187 return Local<Context>();
4188 }
4189 i::Handle<i::Object> calling =
4190 isolate->GetCallingGlobalContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00004191 if (calling.is_null()) return Local<Context>();
4192 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
4193 return Utils::ToLocal(context);
4194}
4195
4196
4197v8::Local<v8::Object> Context::Global() {
Steve Block44f0eee2011-05-26 01:26:41 +01004198 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
4199 return Local<v8::Object>();
4200 }
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));
4204 i::Handle<i::Object> global(context->global_proxy());
4205 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
4206}
4207
4208
4209void Context::DetachGlobal() {
Steve Block44f0eee2011-05-26 01:26:41 +01004210 i::Isolate* isolate = i::Isolate::Current();
4211 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
4212 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004213 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4214 i::Handle<i::Context> context =
4215 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01004216 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00004217}
4218
4219
Andrei Popescu74b3c142010-03-29 12:03:09 +01004220void Context::ReattachGlobal(Handle<Object> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01004221 i::Isolate* isolate = i::Isolate::Current();
4222 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
4223 ENTER_V8(isolate);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004224 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4225 i::Handle<i::Context> context =
4226 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01004227 isolate->bootstrapper()->ReattachGlobal(
4228 context,
4229 Utils::OpenHandle(*global_object));
4230}
4231
4232
Ben Murdoch257744e2011-11-30 15:57:28 +00004233void Context::AllowCodeGenerationFromStrings(bool allow) {
4234 i::Isolate* isolate = i::Isolate::Current();
4235 if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
4236 return;
4237 }
4238 ENTER_V8(isolate);
4239 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4240 i::Handle<i::Context> context =
4241 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4242 context->set_allow_code_gen_from_strings(
4243 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
4244}
4245
4246
Steve Block44f0eee2011-05-26 01:26:41 +01004247void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
4248 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004249}
4250
4251
Steve Blocka7e24c12009-10-30 11:49:00 +00004252Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01004253 i::Isolate* isolate = i::Isolate::Current();
4254 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
4255 return Local<v8::Object>());
4256 LOG_API(isolate, "ObjectTemplate::NewInstance");
4257 ENTER_V8(isolate);
4258 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004259 i::Handle<i::Object> obj =
4260 i::Execution::InstantiateObject(Utils::OpenHandle(this),
4261 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004262 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004263 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
4264}
4265
4266
4267Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01004268 i::Isolate* isolate = i::Isolate::Current();
4269 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00004270 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01004271 LOG_API(isolate, "FunctionTemplate::GetFunction");
4272 ENTER_V8(isolate);
4273 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004274 i::Handle<i::Object> obj =
4275 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
4276 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004277 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004278 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
4279}
4280
4281
4282bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004283 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
4284 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004285 i::Object* obj = *Utils::OpenHandle(*value);
4286 return obj->IsInstanceOf(*Utils::OpenHandle(this));
4287}
4288
4289
4290static Local<External> ExternalNewImpl(void* data) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004291 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004292}
4293
4294static void* ExternalValueImpl(i::Handle<i::Object> obj) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004295 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->address());
Steve Blocka7e24c12009-10-30 11:49:00 +00004296}
4297
4298
Steve Blocka7e24c12009-10-30 11:49:00 +00004299Local<Value> v8::External::Wrap(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004300 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004301 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Ben Murdoch257744e2011-11-30 15:57:28 +00004302 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004303 LOG_API(isolate, "External::Wrap");
Steve Block44f0eee2011-05-26 01:26:41 +01004304 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004305
4306 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
4307 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
4308 : v8::Local<v8::Value>(ExternalNewImpl(data));
4309
4310 ASSERT_EQ(data, Unwrap(result));
4311 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004312}
4313
4314
Steve Block3ce2e202009-11-05 08:53:23 +00004315void* v8::Object::SlowGetPointerFromInternalField(int index) {
4316 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4317 i::Object* value = obj->GetInternalField(index);
4318 if (value->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004319 return i::Internals::GetExternalPointerFromSmi(value);
Ben Murdoch257744e2011-11-30 15:57:28 +00004320 } else if (value->IsForeign()) {
4321 return reinterpret_cast<void*>(i::Foreign::cast(value)->address());
Steve Block3ce2e202009-11-05 08:53:23 +00004322 } else {
4323 return NULL;
4324 }
4325}
4326
4327
Steve Blocka7e24c12009-10-30 11:49:00 +00004328void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
Steve Block44f0eee2011-05-26 01:26:41 +01004329 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004330 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
4331 void* result;
4332 if (obj->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004333 result = i::Internals::GetExternalPointerFromSmi(*obj);
Ben Murdoch257744e2011-11-30 15:57:28 +00004334 } else if (obj->IsForeign()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004335 result = ExternalValueImpl(obj);
4336 } else {
4337 result = NULL;
4338 }
4339 ASSERT_EQ(result, QuickUnwrap(wrapper));
4340 return result;
4341}
4342
4343
4344Local<External> v8::External::New(void* data) {
4345 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01004346 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00004347 EnsureInitializedForIsolate(isolate, "v8::External::New()");
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004348 LOG_API(isolate, "External::New");
Steve Block44f0eee2011-05-26 01:26:41 +01004349 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004350 return ExternalNewImpl(data);
4351}
4352
4353
4354void* External::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004355 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004356 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4357 return ExternalValueImpl(obj);
4358}
4359
4360
4361Local<String> v8::String::Empty() {
Steve Block44f0eee2011-05-26 01:26:41 +01004362 i::Isolate* isolate = i::Isolate::Current();
4363 EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
4364 LOG_API(isolate, "String::Empty()");
4365 return Utils::ToLocal(isolate->factory()->empty_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00004366}
4367
4368
4369Local<String> v8::String::New(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004370 i::Isolate* isolate = i::Isolate::Current();
4371 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4372 LOG_API(isolate, "String::New(char)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004373 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004374 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004375 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004376 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004377 isolate->factory()->NewStringFromUtf8(
4378 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004379 return Utils::ToLocal(result);
4380}
4381
4382
Steve Block3ce2e202009-11-05 08:53:23 +00004383Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00004384 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01004385 i::Isolate* isolate = left_string->GetIsolate();
4386 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4387 LOG_API(isolate, "String::New(char)");
4388 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00004389 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Steve Block44f0eee2011-05-26 01:26:41 +01004390 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
4391 right_string);
Steve Block3ce2e202009-11-05 08:53:23 +00004392 return Utils::ToLocal(result);
4393}
4394
4395
Steve Blocka7e24c12009-10-30 11:49:00 +00004396Local<String> v8::String::NewUndetectable(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004397 i::Isolate* isolate = i::Isolate::Current();
4398 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4399 LOG_API(isolate, "String::NewUndetectable(char)");
4400 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004401 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004402 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004403 isolate->factory()->NewStringFromUtf8(
4404 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004405 result->MarkAsUndetectable();
4406 return Utils::ToLocal(result);
4407}
4408
4409
4410static int TwoByteStringLength(const uint16_t* data) {
4411 int length = 0;
4412 while (data[length] != '\0') length++;
4413 return length;
4414}
4415
4416
4417Local<String> v8::String::New(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004418 i::Isolate* isolate = i::Isolate::Current();
4419 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4420 LOG_API(isolate, "String::New(uint16_)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004421 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004422 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004423 if (length == -1) length = TwoByteStringLength(data);
4424 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004425 isolate->factory()->NewStringFromTwoByte(
4426 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004427 return Utils::ToLocal(result);
4428}
4429
4430
4431Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004432 i::Isolate* isolate = i::Isolate::Current();
4433 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4434 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4435 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004436 if (length == -1) length = TwoByteStringLength(data);
4437 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004438 isolate->factory()->NewStringFromTwoByte(
4439 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004440 result->MarkAsUndetectable();
4441 return Utils::ToLocal(result);
4442}
4443
4444
Steve Block44f0eee2011-05-26 01:26:41 +01004445i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004446 v8::String::ExternalStringResource* resource) {
4447 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004448 isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004449 return result;
4450}
4451
4452
Steve Block44f0eee2011-05-26 01:26:41 +01004453i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004454 v8::String::ExternalAsciiStringResource* resource) {
4455 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004456 isolate->factory()->NewExternalStringFromAscii(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004457 return result;
4458}
4459
4460
Steve Blocka7e24c12009-10-30 11:49:00 +00004461Local<String> v8::String::NewExternal(
4462 v8::String::ExternalStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004463 i::Isolate* isolate = i::Isolate::Current();
4464 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4465 LOG_API(isolate, "String::NewExternal");
4466 ENTER_V8(isolate);
4467 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4468 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004469 return Utils::ToLocal(result);
4470}
4471
4472
4473bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004474 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004475 i::Isolate* isolate = obj->GetIsolate();
4476 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4477 if (i::StringShape(*obj).IsExternalTwoByte()) {
4478 return false; // Already an external string.
4479 }
4480 ENTER_V8(isolate);
4481 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4482 return false;
4483 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004484 if (isolate->heap()->IsInGCPostProcessing()) {
4485 return false;
4486 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004487 bool result = obj->MakeExternal(resource);
4488 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004489 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004490 }
4491 return result;
4492}
4493
4494
4495Local<String> v8::String::NewExternal(
4496 v8::String::ExternalAsciiStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004497 i::Isolate* isolate = i::Isolate::Current();
4498 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4499 LOG_API(isolate, "String::NewExternal");
4500 ENTER_V8(isolate);
4501 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4502 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004503 return Utils::ToLocal(result);
4504}
4505
4506
4507bool v8::String::MakeExternal(
4508 v8::String::ExternalAsciiStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004509 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004510 i::Isolate* isolate = obj->GetIsolate();
4511 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4512 if (i::StringShape(*obj).IsExternalTwoByte()) {
4513 return false; // Already an external string.
4514 }
4515 ENTER_V8(isolate);
4516 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4517 return false;
4518 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004519 if (isolate->heap()->IsInGCPostProcessing()) {
4520 return false;
4521 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004522 bool result = obj->MakeExternal(resource);
4523 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004524 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004525 }
4526 return result;
4527}
4528
4529
4530bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004531 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004532 i::Isolate* isolate = obj->GetIsolate();
4533 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4534 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4535 return false;
4536 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004537 int size = obj->Size(); // Byte size of the original string.
4538 if (size < i::ExternalString::kSize)
4539 return false;
4540 i::StringShape shape(*obj);
4541 return !shape.IsExternal();
4542}
4543
4544
4545Local<v8::Object> v8::Object::New() {
Steve Block44f0eee2011-05-26 01:26:41 +01004546 i::Isolate* isolate = i::Isolate::Current();
4547 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4548 LOG_API(isolate, "Object::New");
4549 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004550 i::Handle<i::JSObject> obj =
Steve Block44f0eee2011-05-26 01:26:41 +01004551 isolate->factory()->NewJSObject(isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00004552 return Utils::ToLocal(obj);
4553}
4554
4555
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004556Local<v8::Value> v8::NumberObject::New(double value) {
4557 i::Isolate* isolate = i::Isolate::Current();
4558 EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
4559 LOG_API(isolate, "NumberObject::New");
4560 ENTER_V8(isolate);
4561 i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
4562 i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
4563 return Utils::ToLocal(obj);
4564}
4565
4566
4567double v8::NumberObject::NumberValue() const {
4568 i::Isolate* isolate = i::Isolate::Current();
4569 if (IsDeadCheck(isolate, "v8::NumberObject::NumberValue()")) return 0;
4570 LOG_API(isolate, "NumberObject::NumberValue");
4571 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4572 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4573 return jsvalue->value()->Number();
4574}
4575
4576
4577Local<v8::Value> v8::BooleanObject::New(bool value) {
4578 i::Isolate* isolate = i::Isolate::Current();
4579 EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
4580 LOG_API(isolate, "BooleanObject::New");
4581 ENTER_V8(isolate);
4582 i::Handle<i::Object> boolean(value ? isolate->heap()->true_value()
4583 : isolate->heap()->false_value());
4584 i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
4585 return Utils::ToLocal(obj);
4586}
4587
4588
4589bool v8::BooleanObject::BooleanValue() const {
4590 i::Isolate* isolate = i::Isolate::Current();
4591 if (IsDeadCheck(isolate, "v8::BooleanObject::BooleanValue()")) return 0;
4592 LOG_API(isolate, "BooleanObject::BooleanValue");
4593 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4594 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4595 return jsvalue->value()->IsTrue();
4596}
4597
4598
4599Local<v8::Value> v8::StringObject::New(Handle<String> value) {
4600 i::Isolate* isolate = i::Isolate::Current();
4601 EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
4602 LOG_API(isolate, "StringObject::New");
4603 ENTER_V8(isolate);
4604 i::Handle<i::Object> obj =
4605 isolate->factory()->ToObject(Utils::OpenHandle(*value));
4606 return Utils::ToLocal(obj);
4607}
4608
4609
4610Local<v8::String> v8::StringObject::StringValue() const {
4611 i::Isolate* isolate = i::Isolate::Current();
4612 if (IsDeadCheck(isolate, "v8::StringObject::StringValue()")) {
4613 return Local<v8::String>();
4614 }
4615 LOG_API(isolate, "StringObject::StringValue");
4616 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4617 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4618 return Utils::ToLocal(
4619 i::Handle<i::String>(i::String::cast(jsvalue->value())));
4620}
4621
4622
Steve Blocka7e24c12009-10-30 11:49:00 +00004623Local<v8::Value> v8::Date::New(double time) {
Steve Block44f0eee2011-05-26 01:26:41 +01004624 i::Isolate* isolate = i::Isolate::Current();
4625 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4626 LOG_API(isolate, "Date::New");
Steve Blockd0582a62009-12-15 09:54:21 +00004627 if (isnan(time)) {
4628 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4629 time = i::OS::nan_value();
4630 }
Steve Block44f0eee2011-05-26 01:26:41 +01004631 ENTER_V8(isolate);
4632 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004633 i::Handle<i::Object> obj =
4634 i::Execution::NewDate(time, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004635 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004636 return Utils::ToLocal(obj);
4637}
4638
4639
4640double v8::Date::NumberValue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004641 i::Isolate* isolate = i::Isolate::Current();
4642 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4643 LOG_API(isolate, "Date::NumberValue");
Steve Blocka7e24c12009-10-30 11:49:00 +00004644 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4645 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4646 return jsvalue->value()->Number();
4647}
4648
4649
Ben Murdochb0fe1622011-05-05 13:52:32 +01004650void v8::Date::DateTimeConfigurationChangeNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004651 i::Isolate* isolate = i::Isolate::Current();
4652 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4653 return);
4654 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
4655 ENTER_V8(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004656
Steve Block44f0eee2011-05-26 01:26:41 +01004657 i::HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004658 // Get the function ResetDateCache (defined in date-delay.js).
4659 i::Handle<i::String> func_name_str =
Steve Block44f0eee2011-05-26 01:26:41 +01004660 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4661 i::MaybeObject* result =
4662 isolate->js_builtins_object()->GetProperty(*func_name_str);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004663 i::Object* object_func;
4664 if (!result->ToObject(&object_func)) {
4665 return;
4666 }
4667
4668 if (object_func->IsJSFunction()) {
4669 i::Handle<i::JSFunction> func =
4670 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4671
4672 // Call ResetDateCache(0 but expect no exceptions:
4673 bool caught_exception = false;
Ben Murdoch8b112d22011-06-08 16:22:53 +01004674 i::Execution::TryCall(func,
4675 isolate->js_builtins_object(),
4676 0,
4677 NULL,
4678 &caught_exception);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004679 }
4680}
4681
4682
Ben Murdochf87a2032010-10-22 12:50:53 +01004683static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4684 char flags_buf[3];
4685 int num_flags = 0;
4686 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4687 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4688 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4689 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
Steve Block44f0eee2011-05-26 01:26:41 +01004690 return FACTORY->LookupSymbol(
Ben Murdochf87a2032010-10-22 12:50:53 +01004691 i::Vector<const char>(flags_buf, num_flags));
4692}
4693
4694
4695Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4696 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01004697 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
4698 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
4699 LOG_API(isolate, "RegExp::New");
4700 ENTER_V8(isolate);
4701 EXCEPTION_PREAMBLE(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01004702 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
4703 Utils::OpenHandle(*pattern),
4704 RegExpFlagsToString(flags),
4705 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004706 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01004707 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
4708}
4709
4710
4711Local<v8::String> v8::RegExp::GetSource() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004712 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4713 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
4714 return Local<v8::String>();
4715 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004716 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4717 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
4718}
4719
4720
4721// Assert that the static flags cast in GetFlags is valid.
4722#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
4723 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
4724 static_cast<int>(i::JSRegExp::internal_flag))
4725REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
4726REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
4727REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
4728REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
4729#undef REGEXP_FLAG_ASSERT_EQ
4730
4731v8::RegExp::Flags v8::RegExp::GetFlags() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004732 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
4733 return v8::RegExp::kNone;
4734 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004735 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4736 return static_cast<RegExp::Flags>(obj->GetFlags().value());
4737}
4738
4739
Steve Blocka7e24c12009-10-30 11:49:00 +00004740Local<v8::Array> v8::Array::New(int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004741 i::Isolate* isolate = i::Isolate::Current();
4742 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
4743 LOG_API(isolate, "Array::New");
4744 ENTER_V8(isolate);
4745 int real_length = length > 0 ? length : 0;
4746 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004747 i::Handle<i::Object> length_obj =
4748 isolate->factory()->NewNumberFromInt(real_length);
4749 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004750 return Utils::ToLocal(obj);
4751}
4752
4753
4754uint32_t v8::Array::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004755 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4756 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004757 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
4758 i::Object* length = obj->length();
4759 if (length->IsSmi()) {
4760 return i::Smi::cast(length)->value();
4761 } else {
4762 return static_cast<uint32_t>(length->Number());
4763 }
4764}
4765
4766
4767Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01004768 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4769 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004770 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
4771 if (!self->HasFastElements()) {
4772 return Local<Object>();
4773 }
4774 i::FixedArray* elms = i::FixedArray::cast(self->elements());
4775 i::Object* paragon = elms->get(index);
4776 if (!paragon->IsJSObject()) {
4777 return Local<Object>();
4778 }
4779 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01004780 EXCEPTION_PREAMBLE(isolate);
4781 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004782 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
4783 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01004784 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004785 return Utils::ToLocal(result);
4786}
4787
4788
4789Local<String> v8::String::NewSymbol(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004790 i::Isolate* isolate = i::Isolate::Current();
4791 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
4792 LOG_API(isolate, "String::NewSymbol(char)");
4793 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004794 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004795 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004796 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004797 return Utils::ToLocal(result);
4798}
4799
4800
4801Local<Number> v8::Number::New(double value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004802 i::Isolate* isolate = i::Isolate::Current();
4803 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
Steve Blockd0582a62009-12-15 09:54:21 +00004804 if (isnan(value)) {
4805 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4806 value = i::OS::nan_value();
4807 }
Steve Block44f0eee2011-05-26 01:26:41 +01004808 ENTER_V8(isolate);
4809 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004810 return Utils::NumberToLocal(result);
4811}
4812
4813
4814Local<Integer> v8::Integer::New(int32_t value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004815 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4816 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004817 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004818 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
4819 isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004820 }
Steve Block44f0eee2011-05-26 01:26:41 +01004821 ENTER_V8(isolate);
4822 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004823 return Utils::IntegerToLocal(result);
4824}
4825
4826
Steve Block3ce2e202009-11-05 08:53:23 +00004827Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
4828 bool fits_into_int32_t = (value & (1 << 31)) == 0;
4829 if (fits_into_int32_t) {
4830 return Integer::New(static_cast<int32_t>(value));
4831 }
Steve Block44f0eee2011-05-26 01:26:41 +01004832 i::Isolate* isolate = i::Isolate::Current();
4833 ENTER_V8(isolate);
4834 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00004835 return Utils::IntegerToLocal(result);
4836}
4837
4838
Steve Blocka7e24c12009-10-30 11:49:00 +00004839void V8::IgnoreOutOfMemoryException() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004840 EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004841}
4842
4843
4844bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004845 i::Isolate* isolate = i::Isolate::Current();
4846 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
4847 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
4848 ENTER_V8(isolate);
4849 i::HandleScope scope(isolate);
4850 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004851 NeanderObject obj(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00004852 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004853 obj.set(1, data.IsEmpty() ?
Steve Block44f0eee2011-05-26 01:26:41 +01004854 isolate->heap()->undefined_value() :
Steve Blocka7e24c12009-10-30 11:49:00 +00004855 *Utils::OpenHandle(*data));
4856 listeners.add(obj.value());
4857 return true;
4858}
4859
4860
4861void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01004862 i::Isolate* isolate = i::Isolate::Current();
4863 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
4864 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
4865 ENTER_V8(isolate);
4866 i::HandleScope scope(isolate);
4867 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004868 for (int i = 0; i < listeners.length(); i++) {
4869 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
4870
4871 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
Ben Murdoch257744e2011-11-30 15:57:28 +00004872 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
4873 if (callback_obj->address() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004874 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004875 }
4876 }
4877}
4878
4879
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004880void V8::SetCaptureStackTraceForUncaughtExceptions(
4881 bool capture,
4882 int frame_limit,
4883 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01004884 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004885 capture,
4886 frame_limit,
4887 options);
4888}
4889
4890
Steve Blocka7e24c12009-10-30 11:49:00 +00004891void V8::SetCounterFunction(CounterLookupCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004892 i::Isolate* isolate = EnterIsolateIfNeeded();
4893 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
4894 isolate->stats_table()->SetCounterFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004895}
4896
4897void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004898 i::Isolate* isolate = EnterIsolateIfNeeded();
4899 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
4900 isolate->stats_table()->SetCreateHistogramFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004901}
4902
4903void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004904 i::Isolate* isolate = EnterIsolateIfNeeded();
4905 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
4906 isolate->stats_table()->
4907 SetAddHistogramSampleFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004908}
4909
4910void V8::EnableSlidingStateWindow() {
Steve Block44f0eee2011-05-26 01:26:41 +01004911 i::Isolate* isolate = i::Isolate::Current();
4912 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
4913 isolate->logger()->EnableSlidingStateWindow();
Steve Blocka7e24c12009-10-30 11:49:00 +00004914}
4915
4916
4917void V8::SetFailedAccessCheckCallbackFunction(
4918 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004919 i::Isolate* isolate = i::Isolate::Current();
4920 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
4921 return;
4922 }
4923 isolate->SetFailedAccessCheckCallback(callback);
4924}
4925
4926void V8::AddObjectGroup(Persistent<Value>* objects,
4927 size_t length,
4928 RetainedObjectInfo* info) {
4929 i::Isolate* isolate = i::Isolate::Current();
4930 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
4931 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
4932 isolate->global_handles()->AddObjectGroup(
4933 reinterpret_cast<i::Object***>(objects), length, info);
Steve Blocka7e24c12009-10-30 11:49:00 +00004934}
4935
4936
Steve Block44f0eee2011-05-26 01:26:41 +01004937void V8::AddImplicitReferences(Persistent<Object> parent,
4938 Persistent<Value>* children,
4939 size_t length) {
4940 i::Isolate* isolate = i::Isolate::Current();
4941 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004942 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
Steve Block44f0eee2011-05-26 01:26:41 +01004943 isolate->global_handles()->AddImplicitReferences(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004944 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*parent)).location(),
Steve Block44f0eee2011-05-26 01:26:41 +01004945 reinterpret_cast<i::Object***>(children), length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004946}
4947
4948
4949int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
Steve Block44f0eee2011-05-26 01:26:41 +01004950 i::Isolate* isolate = i::Isolate::Current();
4951 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
4952 return 0;
4953 }
4954 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
4955 change_in_bytes);
Steve Blocka7e24c12009-10-30 11:49:00 +00004956}
4957
4958
4959void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004960 i::Isolate* isolate = i::Isolate::Current();
4961 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
4962 isolate->heap()->SetGlobalGCPrologueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004963}
4964
4965
4966void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004967 i::Isolate* isolate = i::Isolate::Current();
4968 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
4969 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004970}
4971
4972
Steve Block6ded16b2010-05-10 14:33:55 +01004973void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004974 i::Isolate* isolate = i::Isolate::Current();
4975 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
4976 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004977}
4978
4979
4980void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004981 i::Isolate* isolate = i::Isolate::Current();
4982 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
4983 isolate->heap()->RemoveGCPrologueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004984}
4985
4986
4987void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004988 i::Isolate* isolate = i::Isolate::Current();
4989 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
4990 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004991}
4992
4993
4994void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004995 i::Isolate* isolate = i::Isolate::Current();
4996 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
4997 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004998}
4999
5000
Iain Merrick9ac36c92010-09-13 15:29:50 +01005001void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
5002 ObjectSpace space,
5003 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01005004 i::Isolate* isolate = i::Isolate::Current();
5005 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
5006 isolate->memory_allocator()->AddMemoryAllocationCallback(
5007 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01005008}
5009
5010
5011void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01005012 i::Isolate* isolate = i::Isolate::Current();
5013 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
5014 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
5015 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01005016}
5017
5018
Steve Blocka7e24c12009-10-30 11:49:00 +00005019void V8::PauseProfiler() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005020 i::Isolate* isolate = i::Isolate::Current();
5021 isolate->logger()->PauseProfiler();
Steve Blocka7e24c12009-10-30 11:49:00 +00005022}
5023
5024
5025void V8::ResumeProfiler() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005026 i::Isolate* isolate = i::Isolate::Current();
5027 isolate->logger()->ResumeProfiler();
Steve Blocka7e24c12009-10-30 11:49:00 +00005028}
5029
5030
5031bool V8::IsProfilerPaused() {
Steve Block44f0eee2011-05-26 01:26:41 +01005032 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005033 return isolate->logger()->IsProfilerPaused();
Steve Blocka7e24c12009-10-30 11:49:00 +00005034}
5035
5036
5037int V8::GetCurrentThreadId() {
Steve Block44f0eee2011-05-26 01:26:41 +01005038 i::Isolate* isolate = i::Isolate::Current();
5039 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
Ben Murdoch8b112d22011-06-08 16:22:53 +01005040 return isolate->thread_id().ToInteger();
Steve Blocka7e24c12009-10-30 11:49:00 +00005041}
5042
5043
5044void V8::TerminateExecution(int thread_id) {
Steve Block44f0eee2011-05-26 01:26:41 +01005045 i::Isolate* isolate = i::Isolate::Current();
5046 if (!isolate->IsInitialized()) return;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005047 API_ENTRY_CHECK(isolate, "V8::TerminateExecution()");
Steve Blocka7e24c12009-10-30 11:49:00 +00005048 // If the thread_id identifies the current thread just terminate
5049 // execution right away. Otherwise, ask the thread manager to
5050 // terminate the thread with the given id if any.
Ben Murdoch8b112d22011-06-08 16:22:53 +01005051 i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
5052 if (isolate->thread_id().Equals(internal_tid)) {
Steve Block44f0eee2011-05-26 01:26:41 +01005053 isolate->stack_guard()->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00005054 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +01005055 isolate->thread_manager()->TerminateExecution(internal_tid);
Steve Blocka7e24c12009-10-30 11:49:00 +00005056 }
5057}
5058
5059
Steve Block44f0eee2011-05-26 01:26:41 +01005060void V8::TerminateExecution(Isolate* isolate) {
5061 // If no isolate is supplied, use the default isolate.
5062 if (isolate != NULL) {
5063 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
5064 } else {
5065 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
5066 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005067}
5068
5069
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005070bool V8::IsExecutionTerminating(Isolate* isolate) {
5071 i::Isolate* i_isolate = isolate != NULL ?
5072 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
5073 return IsExecutionTerminatingCheck(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005074}
5075
5076
5077Isolate* Isolate::GetCurrent() {
5078 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
5079 return reinterpret_cast<Isolate*>(isolate);
5080}
5081
5082
5083Isolate* Isolate::New() {
5084 i::Isolate* isolate = new i::Isolate();
5085 return reinterpret_cast<Isolate*>(isolate);
5086}
5087
5088
5089void Isolate::Dispose() {
5090 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5091 if (!ApiCheck(!isolate->IsInUse(),
5092 "v8::Isolate::Dispose()",
5093 "Disposing the isolate that is entered by a thread.")) {
5094 return;
Steve Block6ded16b2010-05-10 14:33:55 +01005095 }
Steve Block44f0eee2011-05-26 01:26:41 +01005096 isolate->TearDown();
5097}
5098
5099
5100void Isolate::Enter() {
5101 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5102 isolate->Enter();
5103}
5104
5105
5106void Isolate::Exit() {
5107 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5108 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01005109}
5110
5111
Ben Murdoch257744e2011-11-30 15:57:28 +00005112void Isolate::SetData(void* data) {
5113 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5114 isolate->SetData(data);
5115}
5116
5117void* Isolate::GetData() {
5118 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5119 return isolate->GetData();
5120}
5121
5122
5123String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
5124 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005125 i::Isolate* isolate = i::Isolate::Current();
5126 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005127 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005128 ENTER_V8(isolate);
5129 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005130 TryCatch try_catch;
5131 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005132 if (str.IsEmpty()) return;
5133 length_ = str->Utf8Length();
5134 str_ = i::NewArray<char>(length_ + 1);
5135 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005136}
5137
5138
5139String::Utf8Value::~Utf8Value() {
5140 i::DeleteArray(str_);
5141}
5142
5143
Ben Murdoch257744e2011-11-30 15:57:28 +00005144String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
5145 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005146 i::Isolate* isolate = i::Isolate::Current();
5147 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005148 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005149 ENTER_V8(isolate);
5150 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005151 TryCatch try_catch;
5152 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005153 if (str.IsEmpty()) return;
5154 length_ = str->Length();
5155 str_ = i::NewArray<char>(length_ + 1);
5156 str->WriteAscii(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005157}
5158
5159
5160String::AsciiValue::~AsciiValue() {
5161 i::DeleteArray(str_);
5162}
5163
5164
Ben Murdoch257744e2011-11-30 15:57:28 +00005165String::Value::Value(v8::Handle<v8::Value> obj)
5166 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005167 i::Isolate* isolate = i::Isolate::Current();
5168 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005169 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005170 ENTER_V8(isolate);
5171 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005172 TryCatch try_catch;
5173 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005174 if (str.IsEmpty()) return;
5175 length_ = str->Length();
5176 str_ = i::NewArray<uint16_t>(length_ + 1);
5177 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005178}
5179
5180
5181String::Value::~Value() {
5182 i::DeleteArray(str_);
5183}
5184
5185Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005186 i::Isolate* isolate = i::Isolate::Current();
5187 LOG_API(isolate, "RangeError");
5188 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
5189 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005190 i::Object* error;
5191 {
Steve Block44f0eee2011-05-26 01:26:41 +01005192 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005193 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005194 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005195 error = *result;
5196 }
5197 i::Handle<i::Object> result(error);
5198 return Utils::ToLocal(result);
5199}
5200
5201Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005202 i::Isolate* isolate = i::Isolate::Current();
5203 LOG_API(isolate, "ReferenceError");
5204 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
5205 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005206 i::Object* error;
5207 {
Steve Block44f0eee2011-05-26 01:26:41 +01005208 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005209 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005210 i::Handle<i::Object> result =
5211 isolate->factory()->NewReferenceError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005212 error = *result;
5213 }
5214 i::Handle<i::Object> result(error);
5215 return Utils::ToLocal(result);
5216}
5217
5218Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005219 i::Isolate* isolate = i::Isolate::Current();
5220 LOG_API(isolate, "SyntaxError");
5221 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
5222 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005223 i::Object* error;
5224 {
Steve Block44f0eee2011-05-26 01:26:41 +01005225 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005226 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005227 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005228 error = *result;
5229 }
5230 i::Handle<i::Object> result(error);
5231 return Utils::ToLocal(result);
5232}
5233
5234Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005235 i::Isolate* isolate = i::Isolate::Current();
5236 LOG_API(isolate, "TypeError");
5237 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
5238 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005239 i::Object* error;
5240 {
Steve Block44f0eee2011-05-26 01:26:41 +01005241 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005242 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005243 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005244 error = *result;
5245 }
5246 i::Handle<i::Object> result(error);
5247 return Utils::ToLocal(result);
5248}
5249
5250Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005251 i::Isolate* isolate = i::Isolate::Current();
5252 LOG_API(isolate, "Error");
5253 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
5254 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005255 i::Object* error;
5256 {
Steve Block44f0eee2011-05-26 01:26:41 +01005257 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005258 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005259 i::Handle<i::Object> result = isolate->factory()->NewError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005260 error = *result;
5261 }
5262 i::Handle<i::Object> result(error);
5263 return Utils::ToLocal(result);
5264}
5265
5266
5267// --- D e b u g S u p p o r t ---
5268
5269#ifdef ENABLE_DEBUGGER_SUPPORT
Leon Clarkef7060e22010-06-03 12:02:55 +01005270
Leon Clarkef7060e22010-06-03 12:02:55 +01005271static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
Steve Block44f0eee2011-05-26 01:26:41 +01005272 i::Isolate* isolate = i::Isolate::Current();
5273 if (isolate->debug_event_callback() != NULL) {
5274 isolate->debug_event_callback()(event_details.GetEvent(),
5275 event_details.GetExecutionState(),
5276 event_details.GetEventData(),
5277 event_details.GetCallbackData());
Leon Clarkef7060e22010-06-03 12:02:55 +01005278 }
5279}
5280
5281
Steve Blocka7e24c12009-10-30 11:49:00 +00005282bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005283 i::Isolate* isolate = i::Isolate::Current();
5284 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
5285 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5286 ENTER_V8(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01005287
Steve Block44f0eee2011-05-26 01:26:41 +01005288 isolate->set_debug_event_callback(that);
Leon Clarkef7060e22010-06-03 12:02:55 +01005289
Steve Block44f0eee2011-05-26 01:26:41 +01005290 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005291 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Leon Clarkef7060e22010-06-03 12:02:55 +01005292 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005293 foreign =
5294 isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
Leon Clarkef7060e22010-06-03 12:02:55 +01005295 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005296 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Leon Clarkef7060e22010-06-03 12:02:55 +01005297 return true;
5298}
5299
5300
5301bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005302 i::Isolate* isolate = i::Isolate::Current();
5303 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
5304 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
5305 ENTER_V8(isolate);
5306 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005307 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00005308 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005309 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00005310 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005311 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005312 return true;
5313}
5314
5315
5316bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
5317 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005318 i::Isolate* isolate = i::Isolate::Current();
5319 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5320 ENTER_V8(isolate);
5321 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
5322 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005323 return true;
5324}
5325
5326
Steve Block44f0eee2011-05-26 01:26:41 +01005327void Debug::DebugBreak(Isolate* isolate) {
5328 // If no isolate is supplied, use the default isolate.
5329 if (isolate != NULL) {
5330 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
5331 } else {
5332 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
5333 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005334}
5335
5336
Steve Block44f0eee2011-05-26 01:26:41 +01005337void Debug::CancelDebugBreak(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->stack_guard()->Continue(i::DEBUGBREAK);
5342 } else {
5343 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
5344 }
Ben Murdochf87a2032010-10-22 12:50:53 +01005345}
5346
5347
Steve Block44f0eee2011-05-26 01:26:41 +01005348void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
5349 // If no isolate is supplied, use the default isolate.
5350 if (isolate != NULL) {
5351 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5352 internal_isolate->debugger()->EnqueueDebugCommand(data);
5353 } else {
5354 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
5355 }
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005356}
5357
5358
Steve Blocka7e24c12009-10-30 11:49:00 +00005359static void MessageHandlerWrapper(const v8::Debug::Message& message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005360 i::Isolate* isolate = i::Isolate::Current();
5361 if (isolate->message_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005362 v8::String::Value json(message.GetJSON());
Steve Block44f0eee2011-05-26 01:26:41 +01005363 (isolate->message_handler())(*json, json.length(), message.GetClientData());
Steve Blocka7e24c12009-10-30 11:49:00 +00005364 }
5365}
5366
5367
5368void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
5369 bool message_handler_thread) {
Steve Block44f0eee2011-05-26 01:26:41 +01005370 i::Isolate* isolate = i::Isolate::Current();
5371 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5372 ENTER_V8(isolate);
5373
Steve Blocka7e24c12009-10-30 11:49:00 +00005374 // Message handler thread not supported any more. Parameter temporally left in
Steve Block44f0eee2011-05-26 01:26:41 +01005375 // the API for client compatibility reasons.
Steve Blocka7e24c12009-10-30 11:49:00 +00005376 CHECK(!message_handler_thread);
5377
5378 // TODO(sgjesse) support the old message handler API through a simple wrapper.
Steve Block44f0eee2011-05-26 01:26:41 +01005379 isolate->set_message_handler(handler);
5380 if (handler != NULL) {
5381 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
Steve Blocka7e24c12009-10-30 11:49:00 +00005382 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005383 isolate->debugger()->SetMessageHandler(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00005384 }
5385}
5386
5387
5388void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01005389 i::Isolate* isolate = i::Isolate::Current();
5390 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5391 ENTER_V8(isolate);
5392 isolate->debugger()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00005393}
5394
5395
5396void Debug::SendCommand(const uint16_t* command, int length,
Steve Block44f0eee2011-05-26 01:26:41 +01005397 ClientData* client_data,
5398 Isolate* isolate) {
5399 // If no isolate is supplied, use the default isolate.
5400 if (isolate != NULL) {
5401 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5402 internal_isolate->debugger()->ProcessCommand(
5403 i::Vector<const uint16_t>(command, length), client_data);
5404 } else {
5405 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
5406 i::Vector<const uint16_t>(command, length), client_data);
5407 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005408}
5409
5410
5411void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
5412 int period) {
Steve Block44f0eee2011-05-26 01:26:41 +01005413 i::Isolate* isolate = i::Isolate::Current();
5414 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
5415 ENTER_V8(isolate);
5416 isolate->debugger()->SetHostDispatchHandler(handler, period);
Steve Blocka7e24c12009-10-30 11:49:00 +00005417}
5418
5419
Steve Blockd0582a62009-12-15 09:54:21 +00005420void Debug::SetDebugMessageDispatchHandler(
Leon Clarkee46be812010-01-19 14:06:41 +00005421 DebugMessageDispatchHandler handler, bool provide_locker) {
Steve Block44f0eee2011-05-26 01:26:41 +01005422 i::Isolate* isolate = i::Isolate::Current();
5423 EnsureInitializedForIsolate(isolate,
5424 "v8::Debug::SetDebugMessageDispatchHandler");
5425 ENTER_V8(isolate);
5426 isolate->debugger()->SetDebugMessageDispatchHandler(
5427 handler, provide_locker);
Steve Blockd0582a62009-12-15 09:54:21 +00005428}
5429
5430
Steve Blocka7e24c12009-10-30 11:49:00 +00005431Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
5432 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005433 i::Isolate* isolate = i::Isolate::Current();
5434 if (!isolate->IsInitialized()) return Local<Value>();
5435 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
5436 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005437 i::Handle<i::Object> result;
Steve Block44f0eee2011-05-26 01:26:41 +01005438 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005439 if (data.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005440 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5441 isolate->factory()->undefined_value(),
5442 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005443 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005444 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5445 Utils::OpenHandle(*data),
5446 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005447 }
Steve Block44f0eee2011-05-26 01:26:41 +01005448 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005449 return Utils::ToLocal(result);
5450}
5451
5452
5453Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01005454 i::Isolate* isolate = i::Isolate::Current();
5455 if (!isolate->IsInitialized()) return Local<Value>();
5456 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
5457 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005458 v8::HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01005459 i::Debug* isolate_debug = isolate->debug();
5460 isolate_debug->Load();
5461 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5462 i::Handle<i::String> name =
5463 isolate->factory()->LookupAsciiSymbol("MakeMirror");
Steve Blocka7e24c12009-10-30 11:49:00 +00005464 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5465 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5466 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5467 const int kArgc = 1;
5468 v8::Handle<v8::Value> argv[kArgc] = { obj };
Steve Block44f0eee2011-05-26 01:26:41 +01005469 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005470 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5471 kArgc,
5472 argv);
Steve Block44f0eee2011-05-26 01:26:41 +01005473 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005474 return scope.Close(result);
5475}
5476
5477
Leon Clarkee46be812010-01-19 14:06:41 +00005478bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
Steve Block44f0eee2011-05-26 01:26:41 +01005479 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5480 wait_for_connection);
Steve Blocka7e24c12009-10-30 11:49:00 +00005481}
Leon Clarkee46be812010-01-19 14:06:41 +00005482
5483void Debug::ProcessDebugMessages() {
5484 i::Execution::ProcessDebugMesssages(true);
5485}
5486
Steve Block6ded16b2010-05-10 14:33:55 +01005487Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01005488 i::Isolate* isolate = i::Isolate::Current();
5489 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5490 ENTER_V8(isolate);
5491 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01005492}
5493
Steve Blocka7e24c12009-10-30 11:49:00 +00005494#endif // ENABLE_DEBUGGER_SUPPORT
5495
Steve Block6ded16b2010-05-10 14:33:55 +01005496
Steve Block6ded16b2010-05-10 14:33:55 +01005497Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005498 i::Isolate* isolate = i::Isolate::Current();
5499 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
Steve Block6ded16b2010-05-10 14:33:55 +01005500 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5501 const i::CodeEntry* entry = node->entry();
5502 if (!entry->has_name_prefix()) {
5503 return Handle<String>(ToApi<String>(
Steve Block44f0eee2011-05-26 01:26:41 +01005504 isolate->factory()->LookupAsciiSymbol(entry->name())));
Steve Block6ded16b2010-05-10 14:33:55 +01005505 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005506 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5507 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5508 isolate->factory()->LookupAsciiSymbol(entry->name()))));
Steve Block6ded16b2010-05-10 14:33:55 +01005509 }
5510}
5511
5512
5513Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005514 i::Isolate* isolate = i::Isolate::Current();
5515 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
Steve Block6ded16b2010-05-10 14:33:55 +01005516 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005517 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005518 node->entry()->resource_name())));
5519}
5520
5521
5522int CpuProfileNode::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005523 i::Isolate* isolate = i::Isolate::Current();
5524 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
Steve Block6ded16b2010-05-10 14:33:55 +01005525 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5526}
5527
5528
5529double CpuProfileNode::GetTotalTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005530 i::Isolate* isolate = i::Isolate::Current();
5531 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005532 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5533}
5534
5535
5536double CpuProfileNode::GetSelfTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005537 i::Isolate* isolate = i::Isolate::Current();
5538 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005539 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5540}
5541
5542
5543double CpuProfileNode::GetTotalSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005544 i::Isolate* isolate = i::Isolate::Current();
5545 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005546 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5547}
5548
5549
5550double CpuProfileNode::GetSelfSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005551 i::Isolate* isolate = i::Isolate::Current();
5552 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005553 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5554}
5555
5556
5557unsigned CpuProfileNode::GetCallUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005558 i::Isolate* isolate = i::Isolate::Current();
5559 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005560 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01005561}
5562
5563
5564int CpuProfileNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005565 i::Isolate* isolate = i::Isolate::Current();
5566 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005567 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5568}
5569
5570
5571const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005572 i::Isolate* isolate = i::Isolate::Current();
5573 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
Steve Block6ded16b2010-05-10 14:33:55 +01005574 const i::ProfileNode* child =
5575 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5576 return reinterpret_cast<const CpuProfileNode*>(child);
5577}
5578
5579
Steve Block44f0eee2011-05-26 01:26:41 +01005580void CpuProfile::Delete() {
5581 i::Isolate* isolate = i::Isolate::Current();
5582 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5583 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5584 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5585 !i::CpuProfiler::HasDetachedProfiles()) {
5586 // If this was the last profile, clean up all accessory data as well.
5587 i::CpuProfiler::DeleteAllProfiles();
5588 }
5589}
5590
5591
Steve Block6ded16b2010-05-10 14:33:55 +01005592unsigned CpuProfile::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005593 i::Isolate* isolate = i::Isolate::Current();
5594 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
Steve Block6ded16b2010-05-10 14:33:55 +01005595 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5596}
5597
5598
5599Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005600 i::Isolate* isolate = i::Isolate::Current();
5601 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
Steve Block6ded16b2010-05-10 14:33:55 +01005602 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005603 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005604 profile->title())));
5605}
5606
5607
5608const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005609 i::Isolate* isolate = i::Isolate::Current();
5610 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005611 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5612 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5613}
5614
5615
5616const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005617 i::Isolate* isolate = i::Isolate::Current();
5618 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005619 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5620 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5621}
5622
5623
5624int CpuProfiler::GetProfilesCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005625 i::Isolate* isolate = i::Isolate::Current();
5626 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005627 return i::CpuProfiler::GetProfilesCount();
5628}
5629
5630
Leon Clarkef7060e22010-06-03 12:02:55 +01005631const CpuProfile* CpuProfiler::GetProfile(int index,
5632 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005633 i::Isolate* isolate = i::Isolate::Current();
5634 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005635 return reinterpret_cast<const CpuProfile*>(
5636 i::CpuProfiler::GetProfile(
5637 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5638 index));
Steve Block6ded16b2010-05-10 14:33:55 +01005639}
5640
5641
Leon Clarkef7060e22010-06-03 12:02:55 +01005642const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5643 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005644 i::Isolate* isolate = i::Isolate::Current();
5645 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005646 return reinterpret_cast<const CpuProfile*>(
5647 i::CpuProfiler::FindProfile(
5648 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5649 uid));
Steve Block6ded16b2010-05-10 14:33:55 +01005650}
5651
5652
5653void CpuProfiler::StartProfiling(Handle<String> title) {
Steve Block44f0eee2011-05-26 01:26:41 +01005654 i::Isolate* isolate = i::Isolate::Current();
5655 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005656 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5657}
5658
5659
Leon Clarkef7060e22010-06-03 12:02:55 +01005660const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5661 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005662 i::Isolate* isolate = i::Isolate::Current();
5663 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005664 return reinterpret_cast<const CpuProfile*>(
Leon Clarkef7060e22010-06-03 12:02:55 +01005665 i::CpuProfiler::StopProfiling(
5666 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5667 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01005668}
5669
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005670
Steve Block44f0eee2011-05-26 01:26:41 +01005671void CpuProfiler::DeleteAllProfiles() {
5672 i::Isolate* isolate = i::Isolate::Current();
5673 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5674 i::CpuProfiler::DeleteAllProfiles();
5675}
5676
5677
Iain Merrick75681382010-08-19 15:07:18 +01005678static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5679 return const_cast<i::HeapGraphEdge*>(
5680 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5681}
5682
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005683
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005684HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005685 i::Isolate* isolate = i::Isolate::Current();
5686 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005687 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005688}
5689
5690
5691Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005692 i::Isolate* isolate = i::Isolate::Current();
5693 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
Iain Merrick75681382010-08-19 15:07:18 +01005694 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005695 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01005696 case i::HeapGraphEdge::kContextVariable:
5697 case i::HeapGraphEdge::kInternal:
5698 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005699 case i::HeapGraphEdge::kShortcut:
Steve Block44f0eee2011-05-26 01:26:41 +01005700 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005701 edge->name())));
Iain Merrick75681382010-08-19 15:07:18 +01005702 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005703 case i::HeapGraphEdge::kHidden:
Steve Block44f0eee2011-05-26 01:26:41 +01005704 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005705 edge->index())));
5706 default: UNREACHABLE();
5707 }
Steve Block44f0eee2011-05-26 01:26:41 +01005708 return v8::Undefined();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005709}
5710
5711
5712const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005713 i::Isolate* isolate = i::Isolate::Current();
5714 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
Iain Merrick75681382010-08-19 15:07:18 +01005715 const i::HeapEntry* from = ToInternal(this)->From();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005716 return reinterpret_cast<const HeapGraphNode*>(from);
5717}
5718
5719
5720const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005721 i::Isolate* isolate = i::Isolate::Current();
5722 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
Iain Merrick75681382010-08-19 15:07:18 +01005723 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005724 return reinterpret_cast<const HeapGraphNode*>(to);
5725}
5726
5727
Iain Merrick75681382010-08-19 15:07:18 +01005728static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5729 return const_cast<i::HeapEntry*>(
5730 reinterpret_cast<const i::HeapEntry*>(entry));
5731}
5732
5733
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005734HeapGraphNode::Type HeapGraphNode::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005735 i::Isolate* isolate = i::Isolate::Current();
5736 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005737 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005738}
5739
5740
5741Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005742 i::Isolate* isolate = i::Isolate::Current();
5743 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
5744 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005745 ToInternal(this)->name())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005746}
5747
5748
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005749uint64_t HeapGraphNode::GetId() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005750 i::Isolate* isolate = i::Isolate::Current();
5751 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
Iain Merrick75681382010-08-19 15:07:18 +01005752 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005753}
5754
5755
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005756int HeapGraphNode::GetSelfSize() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005757 i::Isolate* isolate = i::Isolate::Current();
5758 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
Iain Merrick75681382010-08-19 15:07:18 +01005759 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005760}
5761
5762
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005763int HeapGraphNode::GetRetainedSize(bool exact) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005764 i::Isolate* isolate = i::Isolate::Current();
5765 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005766 return ToInternal(this)->RetainedSize(exact);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005767}
5768
5769
5770int HeapGraphNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005771 i::Isolate* isolate = i::Isolate::Current();
5772 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
Iain Merrick75681382010-08-19 15:07:18 +01005773 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005774}
5775
5776
5777const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005778 i::Isolate* isolate = i::Isolate::Current();
5779 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005780 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005781 &ToInternal(this)->children()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005782}
5783
5784
5785int HeapGraphNode::GetRetainersCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005786 i::Isolate* isolate = i::Isolate::Current();
5787 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
Iain Merrick75681382010-08-19 15:07:18 +01005788 return ToInternal(this)->retainers().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005789}
5790
5791
5792const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005793 i::Isolate* isolate = i::Isolate::Current();
5794 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005795 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005796 ToInternal(this)->retainers()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005797}
5798
5799
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005800const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005801 i::Isolate* isolate = i::Isolate::Current();
5802 IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005803 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
5804}
5805
5806
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005807v8::Handle<v8::Value> HeapGraphNode::GetHeapValue() const {
5808 i::Isolate* isolate = i::Isolate::Current();
5809 IsDeadCheck(isolate, "v8::HeapGraphNode::GetHeapValue");
5810 i::Handle<i::HeapObject> object = ToInternal(this)->GetHeapObject();
5811 return v8::Handle<Value>(!object.is_null() ?
5812 ToApi<Value>(object) : ToApi<Value>(
5813 isolate->factory()->undefined_value()));
5814}
5815
5816
Iain Merrick75681382010-08-19 15:07:18 +01005817static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5818 return const_cast<i::HeapSnapshot*>(
5819 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5820}
5821
5822
Steve Block44f0eee2011-05-26 01:26:41 +01005823void HeapSnapshot::Delete() {
5824 i::Isolate* isolate = i::Isolate::Current();
5825 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
5826 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
5827 ToInternal(this)->Delete();
5828 } else {
5829 // If this is the last snapshot, clean up all accessory data as well.
5830 i::HeapProfiler::DeleteAllSnapshots();
5831 }
5832}
5833
5834
Steve Block791712a2010-08-27 10:21:07 +01005835HeapSnapshot::Type HeapSnapshot::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005836 i::Isolate* isolate = i::Isolate::Current();
5837 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
Steve Block791712a2010-08-27 10:21:07 +01005838 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
5839}
5840
5841
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005842unsigned HeapSnapshot::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005843 i::Isolate* isolate = i::Isolate::Current();
5844 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
Iain Merrick75681382010-08-19 15:07:18 +01005845 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005846}
5847
5848
5849Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005850 i::Isolate* isolate = i::Isolate::Current();
5851 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
5852 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005853 ToInternal(this)->title())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005854}
5855
5856
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005857const HeapGraphNode* HeapSnapshot::GetRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005858 i::Isolate* isolate = i::Isolate::Current();
5859 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
Iain Merrick75681382010-08-19 15:07:18 +01005860 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005861}
5862
5863
Ben Murdochb0fe1622011-05-05 13:52:32 +01005864const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005865 i::Isolate* isolate = i::Isolate::Current();
5866 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
Ben Murdochb0fe1622011-05-05 13:52:32 +01005867 return reinterpret_cast<const HeapGraphNode*>(
5868 ToInternal(this)->GetEntryById(id));
5869}
5870
5871
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005872int HeapSnapshot::GetNodesCount() const {
5873 i::Isolate* isolate = i::Isolate::Current();
5874 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
5875 return ToInternal(this)->entries()->length();
5876}
5877
5878
5879const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
5880 i::Isolate* isolate = i::Isolate::Current();
5881 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
5882 return reinterpret_cast<const HeapGraphNode*>(
5883 ToInternal(this)->entries()->at(index));
5884}
5885
5886
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005887void HeapSnapshot::Serialize(OutputStream* stream,
5888 HeapSnapshot::SerializationFormat format) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005889 i::Isolate* isolate = i::Isolate::Current();
5890 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005891 ApiCheck(format == kJSON,
5892 "v8::HeapSnapshot::Serialize",
5893 "Unknown serialization format");
5894 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
5895 "v8::HeapSnapshot::Serialize",
5896 "Unsupported output encoding");
5897 ApiCheck(stream->GetChunkSize() > 0,
5898 "v8::HeapSnapshot::Serialize",
5899 "Invalid stream chunk size");
5900 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
5901 serializer.Serialize(stream);
5902}
5903
5904
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005905int HeapProfiler::GetSnapshotsCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005906 i::Isolate* isolate = i::Isolate::Current();
5907 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005908 return i::HeapProfiler::GetSnapshotsCount();
5909}
5910
5911
5912const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005913 i::Isolate* isolate = i::Isolate::Current();
5914 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005915 return reinterpret_cast<const HeapSnapshot*>(
5916 i::HeapProfiler::GetSnapshot(index));
5917}
5918
5919
5920const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
Steve Block44f0eee2011-05-26 01:26:41 +01005921 i::Isolate* isolate = i::Isolate::Current();
5922 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005923 return reinterpret_cast<const HeapSnapshot*>(
5924 i::HeapProfiler::FindSnapshot(uid));
5925}
5926
5927
Steve Block791712a2010-08-27 10:21:07 +01005928const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
Ben Murdochb0fe1622011-05-05 13:52:32 +01005929 HeapSnapshot::Type type,
5930 ActivityControl* control) {
Steve Block44f0eee2011-05-26 01:26:41 +01005931 i::Isolate* isolate = i::Isolate::Current();
5932 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
Steve Block791712a2010-08-27 10:21:07 +01005933 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
5934 switch (type) {
5935 case HeapSnapshot::kFull:
5936 internal_type = i::HeapSnapshot::kFull;
5937 break;
Steve Block791712a2010-08-27 10:21:07 +01005938 default:
5939 UNREACHABLE();
5940 }
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005941 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb0fe1622011-05-05 13:52:32 +01005942 i::HeapProfiler::TakeSnapshot(
5943 *Utils::OpenHandle(*title), internal_type, control));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005944}
5945
Steve Block44f0eee2011-05-26 01:26:41 +01005946
5947void HeapProfiler::DeleteAllSnapshots() {
5948 i::Isolate* isolate = i::Isolate::Current();
5949 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5950 i::HeapProfiler::DeleteAllSnapshots();
5951}
5952
5953
5954void HeapProfiler::DefineWrapperClass(uint16_t class_id,
5955 WrapperInfoCallback callback) {
5956 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
5957 callback);
5958}
5959
Steve Block6ded16b2010-05-10 14:33:55 +01005960
5961
Ben Murdochb0fe1622011-05-05 13:52:32 +01005962v8::Testing::StressType internal::Testing::stress_type_ =
5963 v8::Testing::kStressTypeOpt;
5964
5965
5966void Testing::SetStressRunType(Testing::StressType type) {
5967 internal::Testing::set_stress_type(type);
5968}
5969
5970int Testing::GetStressRuns() {
5971 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
5972#ifdef DEBUG
5973 // In debug mode the code runs much slower so stressing will only make two
5974 // runs.
5975 return 2;
5976#else
5977 return 5;
5978#endif
5979}
5980
5981
5982static void SetFlagsFromString(const char* flags) {
5983 V8::SetFlagsFromString(flags, i::StrLength(flags));
5984}
5985
5986
5987void Testing::PrepareStressRun(int run) {
5988 static const char* kLazyOptimizations =
5989 "--prepare-always-opt --nolimit-inlining "
5990 "--noalways-opt --noopt-eagerly";
5991 static const char* kEagerOptimizations = "--opt-eagerly";
5992 static const char* kForcedOptimizations = "--always-opt";
5993
5994 // If deoptimization stressed turn on frequent deoptimization. If no value
5995 // is spefified through --deopt-every-n-times use a default default value.
5996 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
5997 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
5998 internal::FLAG_deopt_every_n_times == 0) {
5999 SetFlagsFromString(kDeoptEvery13Times);
6000 }
6001
6002#ifdef DEBUG
6003 // As stressing in debug mode only make two runs skip the deopt stressing
6004 // here.
6005 if (run == GetStressRuns() - 1) {
6006 SetFlagsFromString(kForcedOptimizations);
6007 } else {
6008 SetFlagsFromString(kEagerOptimizations);
6009 SetFlagsFromString(kLazyOptimizations);
6010 }
6011#else
6012 if (run == GetStressRuns() - 1) {
6013 SetFlagsFromString(kForcedOptimizations);
6014 } else if (run == GetStressRuns() - 2) {
6015 SetFlagsFromString(kEagerOptimizations);
6016 } else {
6017 SetFlagsFromString(kLazyOptimizations);
6018 }
6019#endif
6020}
6021
6022
Steve Block44f0eee2011-05-26 01:26:41 +01006023void Testing::DeoptimizeAll() {
6024 internal::Deoptimizer::DeoptimizeAll();
Steve Blocka7e24c12009-10-30 11:49:00 +00006025}
6026
6027
Steve Block44f0eee2011-05-26 01:26:41 +01006028namespace internal {
6029
6030
Steve Blocka7e24c12009-10-30 11:49:00 +00006031void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01006032 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00006033}
6034
6035
6036char* HandleScopeImplementer::ArchiveThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006037 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00006038 isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00006039 handle_scope_data_ = *current;
6040 memcpy(storage, this, sizeof(*this));
6041
6042 ResetAfterArchive();
6043 current->Initialize();
6044
6045 return storage + ArchiveSpacePerThread();
6046}
6047
6048
6049int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01006050 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00006051}
6052
6053
6054char* HandleScopeImplementer::RestoreThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006055 memcpy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00006056 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00006057 return storage + ArchiveSpacePerThread();
6058}
6059
6060
6061void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
6062 // Iterate over all handles in the blocks except for the last.
6063 for (int i = blocks()->length() - 2; i >= 0; --i) {
6064 Object** block = blocks()->at(i);
6065 v->VisitPointers(block, &block[kHandleBlockSize]);
6066 }
6067
6068 // Iterate over live handles in the last block (if any).
6069 if (!blocks()->is_empty()) {
6070 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
6071 }
6072
6073 if (!saved_contexts_.is_empty()) {
6074 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
6075 v->VisitPointers(start, start + saved_contexts_.length());
6076 }
6077}
6078
6079
6080void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
6081 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00006082 isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01006083 handle_scope_data_ = *current;
6084 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00006085}
6086
6087
6088char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01006089 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00006090 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01006091 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00006092 return storage + ArchiveSpacePerThread();
6093}
6094
6095} } // namespace v8::internal