blob: 598085431248735d8617aa7db8e4ae21f9b79ff7 [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "api.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010031
Steve Blocka7e24c12009-10-30 11:49:00 +000032#include "arguments.h"
33#include "bootstrapper.h"
34#include "compiler.h"
35#include "debug.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010036#include "deoptimizer.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037#include "execution.h"
38#include "global-handles.h"
Kristian Monsen9dcf7e22010-06-28 14:14:28 +010039#include "heap-profiler.h"
Steve Block6ded16b2010-05-10 14:33:55 +010040#include "messages.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010041#include "parser.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000042#include "platform.h"
Steve Block6ded16b2010-05-10 14:33:55 +010043#include "profile-generator-inl.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010044#include "runtime-profiler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000045#include "serialize.h"
46#include "snapshot.h"
47#include "v8threads.h"
48#include "version.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010049#include "vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000050
Steve Block6ded16b2010-05-10 14:33:55 +010051#include "../include/v8-profiler.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010052#include "../include/v8-testing.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000053
Steve Block44f0eee2011-05-26 01:26:41 +010054#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000055
Leon Clarkef7060e22010-06-03 12:02:55 +010056#ifdef ENABLE_VMSTATE_TRACKING
Steve Block44f0eee2011-05-26 01:26:41 +010057#define ENTER_V8(isolate) \
58 ASSERT((isolate)->IsInitialized()); \
59 i::VMState __state__((isolate), i::OTHER)
60#define LEAVE_V8(isolate) \
61 i::VMState __state__((isolate), i::EXTERNAL)
Steve Blocka7e24c12009-10-30 11:49:00 +000062#else
Steve Block44f0eee2011-05-26 01:26:41 +010063#define ENTER_V8(isolate) ((void) 0)
64#define LEAVE_V8(isolate) ((void) 0)
Steve Blocka7e24c12009-10-30 11:49:00 +000065#endif
66
67namespace v8 {
68
Steve Block44f0eee2011-05-26 01:26:41 +010069#define ON_BAILOUT(isolate, location, code) \
70 if (IsDeadCheck(isolate, location) || \
71 IsExecutionTerminatingCheck(isolate)) { \
Leon Clarkef7060e22010-06-03 12:02:55 +010072 code; \
73 UNREACHABLE(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000074 }
75
76
Steve Block44f0eee2011-05-26 01:26:41 +010077#define EXCEPTION_PREAMBLE(isolate) \
78 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
79 ASSERT(!(isolate)->external_caught_exception()); \
Steve Blocka7e24c12009-10-30 11:49:00 +000080 bool has_pending_exception = false
81
82
Steve Block44f0eee2011-05-26 01:26:41 +010083#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
Steve Blocka7e24c12009-10-30 11:49:00 +000084 do { \
Steve Block44f0eee2011-05-26 01:26:41 +010085 i::HandleScopeImplementer* handle_scope_implementer = \
86 (isolate)->handle_scope_implementer(); \
87 handle_scope_implementer->DecrementCallDepth(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000088 if (has_pending_exception) { \
Steve Block44f0eee2011-05-26 01:26:41 +010089 if (handle_scope_implementer->CallDepthIsZero() && \
90 (isolate)->is_out_of_memory()) { \
Ben Murdoch257744e2011-11-30 15:57:28 +000091 if (!handle_scope_implementer->ignore_out_of_memory()) \
Steve Blocka7e24c12009-10-30 11:49:00 +000092 i::V8::FatalProcessOutOfMemory(NULL); \
93 } \
Steve Block44f0eee2011-05-26 01:26:41 +010094 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
95 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
Steve Blocka7e24c12009-10-30 11:49:00 +000096 return value; \
97 } \
98 } while (false)
99
Steve Block44f0eee2011-05-26 01:26:41 +0100100// TODO(isolates): Add a parameter to this macro for an isolate.
Steve Blocka7e24c12009-10-30 11:49:00 +0000101
102#define API_ENTRY_CHECK(msg) \
103 do { \
104 if (v8::Locker::IsActive()) { \
Steve Block44f0eee2011-05-26 01:26:41 +0100105 ApiCheck(i::Isolate::Current()->thread_manager()-> \
106 IsLockedByCurrentThread(), \
Steve Blocka7e24c12009-10-30 11:49:00 +0000107 msg, \
108 "Entering the V8 API without proper locking in place"); \
109 } \
110 } while (false)
111
Ben Murdochb0fe1622011-05-05 13:52:32 +0100112
Steve Blocka7e24c12009-10-30 11:49:00 +0000113// --- E x c e p t i o n B e h a v i o r ---
114
115
Steve Blocka7e24c12009-10-30 11:49:00 +0000116static void DefaultFatalErrorHandler(const char* location,
117 const char* message) {
Steve Block1e0659c2011-05-24 12:43:12 +0100118#ifdef ENABLE_VMSTATE_TRACKING
Steve Block44f0eee2011-05-26 01:26:41 +0100119 i::VMState __state__(i::Isolate::Current(), i::OTHER);
Steve Block1e0659c2011-05-24 12:43:12 +0100120#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000121 API_Fatal(location, message);
122}
123
124
Steve Block44f0eee2011-05-26 01:26:41 +0100125static FatalErrorCallback GetFatalErrorHandler() {
126 i::Isolate* isolate = i::Isolate::Current();
127 if (isolate->exception_behavior() == NULL) {
128 isolate->set_exception_behavior(DefaultFatalErrorHandler);
Steve Blocka7e24c12009-10-30 11:49:00 +0000129 }
Steve Block44f0eee2011-05-26 01:26:41 +0100130 return isolate->exception_behavior();
Steve Blocka7e24c12009-10-30 11:49:00 +0000131}
132
133
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800134void i::FatalProcessOutOfMemory(const char* location) {
135 i::V8::FatalProcessOutOfMemory(location, false);
136}
137
Steve Blocka7e24c12009-10-30 11:49:00 +0000138
139// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
140// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100141void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Steve Blockd0582a62009-12-15 09:54:21 +0000142 i::HeapStats heap_stats;
143 int start_marker;
144 heap_stats.start_marker = &start_marker;
145 int new_space_size;
146 heap_stats.new_space_size = &new_space_size;
147 int new_space_capacity;
148 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100149 intptr_t old_pointer_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000150 heap_stats.old_pointer_space_size = &old_pointer_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100151 intptr_t old_pointer_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000152 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100153 intptr_t old_data_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000154 heap_stats.old_data_space_size = &old_data_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100155 intptr_t old_data_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000156 heap_stats.old_data_space_capacity = &old_data_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100157 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000158 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100159 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000160 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100161 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000162 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100163 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000164 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100165 intptr_t cell_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000166 heap_stats.cell_space_size = &cell_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100167 intptr_t cell_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000168 heap_stats.cell_space_capacity = &cell_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100169 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000170 heap_stats.lo_space_size = &lo_space_size;
171 int global_handle_count;
172 heap_stats.global_handle_count = &global_handle_count;
173 int weak_global_handle_count;
174 heap_stats.weak_global_handle_count = &weak_global_handle_count;
175 int pending_global_handle_count;
176 heap_stats.pending_global_handle_count = &pending_global_handle_count;
177 int near_death_global_handle_count;
178 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
179 int destroyed_global_handle_count;
180 heap_stats.destroyed_global_handle_count = &destroyed_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100181 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100182 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100183 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100184 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
185 int objects_per_type[LAST_TYPE + 1] = {0};
186 heap_stats.objects_per_type = objects_per_type;
187 int size_per_type[LAST_TYPE + 1] = {0};
188 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100189 int os_error;
190 heap_stats.os_error = &os_error;
Steve Blockd0582a62009-12-15 09:54:21 +0000191 int end_marker;
192 heap_stats.end_marker = &end_marker;
Steve Block44f0eee2011-05-26 01:26:41 +0100193 i::Isolate* isolate = i::Isolate::Current();
194 isolate->heap()->RecordStats(&heap_stats, take_snapshot);
Steve Blocka7e24c12009-10-30 11:49:00 +0000195 i::V8::SetFatalError();
196 FatalErrorCallback callback = GetFatalErrorHandler();
197 {
Steve Block44f0eee2011-05-26 01:26:41 +0100198 LEAVE_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000199 callback(location, "Allocation failed - process out of memory");
200 }
201 // If the callback returns, we stop execution.
202 UNREACHABLE();
203}
204
205
Steve Blocka7e24c12009-10-30 11:49:00 +0000206bool Utils::ReportApiFailure(const char* location, const char* message) {
207 FatalErrorCallback callback = GetFatalErrorHandler();
208 callback(location, message);
209 i::V8::SetFatalError();
210 return false;
211}
212
213
214bool V8::IsDead() {
215 return i::V8::IsDead();
216}
217
218
219static inline bool ApiCheck(bool condition,
220 const char* location,
221 const char* message) {
222 return condition ? true : Utils::ReportApiFailure(location, message);
223}
224
225
226static bool ReportV8Dead(const char* location) {
227 FatalErrorCallback callback = GetFatalErrorHandler();
228 callback(location, "V8 is no longer usable");
229 return true;
230}
231
232
233static bool ReportEmptyHandle(const char* location) {
234 FatalErrorCallback callback = GetFatalErrorHandler();
235 callback(location, "Reading from empty handle");
236 return true;
237}
238
239
240/**
241 * IsDeadCheck checks that the vm is usable. If, for instance, the vm has been
242 * out of memory at some point this check will fail. It should be called on
243 * entry to all methods that touch anything in the heap, except destructors
244 * which you sometimes can't avoid calling after the vm has crashed. Functions
245 * that call EnsureInitialized or ON_BAILOUT don't have to also call
246 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you
247 * can arrange to return if the VM is dead. This is needed to ensure that no VM
248 * heap allocations are attempted on a dead VM. EnsureInitialized has the
249 * advantage over ON_BAILOUT that it actually initializes the VM if this has not
250 * yet been done.
251 */
Steve Block44f0eee2011-05-26 01:26:41 +0100252static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
253 return !isolate->IsInitialized()
Steve Blocka7e24c12009-10-30 11:49:00 +0000254 && i::V8::IsDead() ? ReportV8Dead(location) : false;
255}
256
257
Steve Block44f0eee2011-05-26 01:26:41 +0100258static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
259 if (!isolate->IsInitialized()) return false;
260 if (isolate->has_scheduled_exception()) {
261 return isolate->scheduled_exception() ==
262 isolate->heap()->termination_exception();
263 }
264 return false;
265}
266
267
Steve Blocka7e24c12009-10-30 11:49:00 +0000268static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
269 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
270}
271
272
273static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
274 return (obj == 0) ? ReportEmptyHandle(location) : false;
275}
276
277// --- S t a t i c s ---
278
279
Steve Block44f0eee2011-05-26 01:26:41 +0100280static bool InitializeHelper() {
281 if (i::Snapshot::Initialize()) return true;
282 return i::V8::Initialize(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000283}
284
285
Steve Block44f0eee2011-05-26 01:26:41 +0100286static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
287 const char* location) {
288 if (IsDeadCheck(isolate, location)) return false;
289 if (isolate != NULL) {
290 if (isolate->IsInitialized()) return true;
291 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000292 ASSERT(isolate == i::Isolate::Current());
Steve Block44f0eee2011-05-26 01:26:41 +0100293 return ApiCheck(InitializeHelper(), location, "Error initializing V8");
294}
295
296// Some initializing API functions are called early and may be
297// called on a thread different from static initializer thread.
298// If Isolate API is used, Isolate::Enter() will initialize TLS so
299// Isolate::Current() works. If it's a legacy case, then the thread
300// may not have TLS initialized yet. However, in initializing APIs it
301// may be too early to call EnsureInitialized() - some pre-init
302// parameters still have to be configured.
303static inline i::Isolate* EnterIsolateIfNeeded() {
304 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
305 if (isolate != NULL)
306 return isolate;
307
308 i::Isolate::EnterDefaultIsolate();
309 isolate = i::Isolate::Current();
310 return isolate;
311}
312
313
Ben Murdoch257744e2011-11-30 15:57:28 +0000314StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
315#ifdef COMPRESS_STARTUP_DATA_BZ2
316 return StartupData::kBZip2;
317#else
318 return StartupData::kUncompressed;
319#endif
320}
321
322
323enum CompressedStartupDataItems {
324 kSnapshot = 0,
325 kSnapshotContext,
326 kCompressedStartupDataCount
327};
328
329int V8::GetCompressedStartupDataCount() {
330#ifdef COMPRESS_STARTUP_DATA_BZ2
331 return kCompressedStartupDataCount;
332#else
333 return 0;
334#endif
335}
336
337
338void V8::GetCompressedStartupData(StartupData* compressed_data) {
339#ifdef COMPRESS_STARTUP_DATA_BZ2
340 compressed_data[kSnapshot].data =
341 reinterpret_cast<const char*>(i::Snapshot::data());
342 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
343 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
344
345 compressed_data[kSnapshotContext].data =
346 reinterpret_cast<const char*>(i::Snapshot::context_data());
347 compressed_data[kSnapshotContext].compressed_size =
348 i::Snapshot::context_size();
349 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
350#endif
351}
352
353
354void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
355#ifdef COMPRESS_STARTUP_DATA_BZ2
356 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
357 i::Snapshot::set_raw_data(
358 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
359
360 ASSERT_EQ(i::Snapshot::context_raw_size(),
361 decompressed_data[kSnapshotContext].raw_size);
362 i::Snapshot::set_context_raw_data(
363 reinterpret_cast<const i::byte*>(
364 decompressed_data[kSnapshotContext].data));
365#endif
366}
367
368
Steve Block44f0eee2011-05-26 01:26:41 +0100369void V8::SetFatalErrorHandler(FatalErrorCallback that) {
370 i::Isolate* isolate = EnterIsolateIfNeeded();
371 isolate->set_exception_behavior(that);
Steve Blocka7e24c12009-10-30 11:49:00 +0000372}
373
374
Ben Murdoch257744e2011-11-30 15:57:28 +0000375void V8::SetAllowCodeGenerationFromStringsCallback(
376 AllowCodeGenerationFromStringsCallback callback) {
377 i::Isolate* isolate = EnterIsolateIfNeeded();
378 isolate->set_allow_code_gen_callback(callback);
379}
380
381
Steve Blocka7e24c12009-10-30 11:49:00 +0000382#ifdef DEBUG
383void ImplementationUtilities::ZapHandleRange(i::Object** begin,
384 i::Object** end) {
385 i::HandleScope::ZapRange(begin, end);
386}
387#endif
388
389
Steve Blocka7e24c12009-10-30 11:49:00 +0000390void V8::SetFlagsFromString(const char* str, int length) {
391 i::FlagList::SetFlagsFromString(str, length);
392}
393
394
395void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
396 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
397}
398
399
400v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100401 i::Isolate* isolate = i::Isolate::Current();
402 if (IsDeadCheck(isolate, "v8::ThrowException()")) {
403 return v8::Handle<Value>();
404 }
405 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000406 // If we're passed an empty handle, we throw an undefined exception
407 // to deal more gracefully with out of memory situations.
408 if (value.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100409 isolate->ScheduleThrow(isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000410 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100411 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +0000412 }
413 return v8::Undefined();
414}
415
416
417RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
418
419
420RegisteredExtension::RegisteredExtension(Extension* extension)
421 : extension_(extension), state_(UNVISITED) { }
422
423
424void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100425 that->next_ = first_extension_;
426 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000427}
428
429
430void RegisterExtension(Extension* that) {
431 RegisteredExtension* extension = new RegisteredExtension(that);
432 RegisteredExtension::Register(extension);
433}
434
435
436Extension::Extension(const char* name,
437 const char* source,
438 int dep_count,
439 const char** deps)
440 : name_(name),
441 source_(source),
442 dep_count_(dep_count),
443 deps_(deps),
444 auto_enable_(false) { }
445
446
447v8::Handle<Primitive> Undefined() {
Steve Block44f0eee2011-05-26 01:26:41 +0100448 i::Isolate* isolate = i::Isolate::Current();
449 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
450 return v8::Handle<v8::Primitive>();
451 }
452 return v8::Handle<Primitive>(ToApi<Primitive>(
453 isolate->factory()->undefined_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000454}
455
456
457v8::Handle<Primitive> Null() {
Steve Block44f0eee2011-05-26 01:26:41 +0100458 i::Isolate* isolate = i::Isolate::Current();
459 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
460 return v8::Handle<v8::Primitive>();
461 }
462 return v8::Handle<Primitive>(
463 ToApi<Primitive>(isolate->factory()->null_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000464}
465
466
467v8::Handle<Boolean> True() {
Steve Block44f0eee2011-05-26 01:26:41 +0100468 i::Isolate* isolate = i::Isolate::Current();
469 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
470 return v8::Handle<Boolean>();
471 }
472 return v8::Handle<Boolean>(
473 ToApi<Boolean>(isolate->factory()->true_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000474}
475
476
477v8::Handle<Boolean> False() {
Steve Block44f0eee2011-05-26 01:26:41 +0100478 i::Isolate* isolate = i::Isolate::Current();
479 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
480 return v8::Handle<Boolean>();
481 }
482 return v8::Handle<Boolean>(
483 ToApi<Boolean>(isolate->factory()->false_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000484}
485
486
487ResourceConstraints::ResourceConstraints()
488 : max_young_space_size_(0),
489 max_old_space_size_(0),
Russell Brenner90bac252010-11-18 13:33:46 -0800490 max_executable_size_(0),
Steve Blocka7e24c12009-10-30 11:49:00 +0000491 stack_limit_(NULL) { }
492
493
494bool SetResourceConstraints(ResourceConstraints* constraints) {
Steve Block44f0eee2011-05-26 01:26:41 +0100495 i::Isolate* isolate = EnterIsolateIfNeeded();
496
Steve Block3ce2e202009-11-05 08:53:23 +0000497 int young_space_size = constraints->max_young_space_size();
Steve Blocka7e24c12009-10-30 11:49:00 +0000498 int old_gen_size = constraints->max_old_space_size();
Russell Brenner90bac252010-11-18 13:33:46 -0800499 int max_executable_size = constraints->max_executable_size();
500 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100501 // After initialization it's too late to change Heap constraints.
502 ASSERT(!isolate->IsInitialized());
503 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
504 old_gen_size,
505 max_executable_size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000506 if (!result) return false;
507 }
508 if (constraints->stack_limit() != NULL) {
509 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
Steve Block44f0eee2011-05-26 01:26:41 +0100510 isolate->stack_guard()->SetStackLimit(limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000511 }
512 return true;
513}
514
515
516i::Object** V8::GlobalizeReference(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100517 i::Isolate* isolate = i::Isolate::Current();
518 if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
519 LOG_API(isolate, "Persistent::New");
Steve Blocka7e24c12009-10-30 11:49:00 +0000520 i::Handle<i::Object> result =
Steve Block44f0eee2011-05-26 01:26:41 +0100521 isolate->global_handles()->Create(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000522 return result.location();
523}
524
525
526void V8::MakeWeak(i::Object** object, void* parameters,
527 WeakReferenceCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +0100528 i::Isolate* isolate = i::Isolate::Current();
529 LOG_API(isolate, "MakeWeak");
530 isolate->global_handles()->MakeWeak(object, parameters,
531 callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000532}
533
534
535void V8::ClearWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100536 i::Isolate* isolate = i::Isolate::Current();
537 LOG_API(isolate, "ClearWeak");
538 isolate->global_handles()->ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000539}
540
541
Ben Murdoch257744e2011-11-30 15:57:28 +0000542void V8::MarkIndependent(i::Object** object) {
543 i::Isolate* isolate = i::Isolate::Current();
544 LOG_API(isolate, "MakeIndependent");
545 isolate->global_handles()->MarkIndependent(object);
546}
547
548
Steve Blocka7e24c12009-10-30 11:49:00 +0000549bool V8::IsGlobalNearDeath(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100550 i::Isolate* isolate = i::Isolate::Current();
551 LOG_API(isolate, "IsGlobalNearDeath");
552 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000553 return i::GlobalHandles::IsNearDeath(obj);
554}
555
556
557bool V8::IsGlobalWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100558 i::Isolate* isolate = i::Isolate::Current();
559 LOG_API(isolate, "IsGlobalWeak");
560 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000561 return i::GlobalHandles::IsWeak(obj);
562}
563
564
565void V8::DisposeGlobal(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100566 i::Isolate* isolate = i::Isolate::Current();
567 LOG_API(isolate, "DisposeGlobal");
568 if (!isolate->IsInitialized()) return;
569 isolate->global_handles()->Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000570}
571
572// --- H a n d l e s ---
573
574
Steve Block44f0eee2011-05-26 01:26:41 +0100575HandleScope::HandleScope() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000576 API_ENTRY_CHECK("HandleScope::HandleScope");
Steve Block44f0eee2011-05-26 01:26:41 +0100577 i::Isolate* isolate = i::Isolate::Current();
578 v8::ImplementationUtilities::HandleScopeData* current =
579 isolate->handle_scope_data();
580 isolate_ = isolate;
581 prev_next_ = current->next;
582 prev_limit_ = current->limit;
583 is_closed_ = false;
584 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000585}
586
587
588HandleScope::~HandleScope() {
589 if (!is_closed_) {
John Reck59135872010-11-02 12:39:01 -0700590 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000591 }
592}
593
594
John Reck59135872010-11-02 12:39:01 -0700595void HandleScope::Leave() {
Steve Block44f0eee2011-05-26 01:26:41 +0100596 ASSERT(isolate_ == i::Isolate::Current());
597 v8::ImplementationUtilities::HandleScopeData* current =
598 isolate_->handle_scope_data();
599 current->level--;
600 ASSERT(current->level >= 0);
601 current->next = prev_next_;
602 if (current->limit != prev_limit_) {
603 current->limit = prev_limit_;
604 i::HandleScope::DeleteExtensions(isolate_);
John Reck59135872010-11-02 12:39:01 -0700605 }
606
607#ifdef DEBUG
608 i::HandleScope::ZapRange(prev_next_, prev_limit_);
609#endif
610}
611
612
Steve Blocka7e24c12009-10-30 11:49:00 +0000613int HandleScope::NumberOfHandles() {
Steve Block44f0eee2011-05-26 01:26:41 +0100614 EnsureInitializedForIsolate(
615 i::Isolate::Current(), "HandleScope::NumberOfHandles");
Steve Blocka7e24c12009-10-30 11:49:00 +0000616 return i::HandleScope::NumberOfHandles();
617}
618
619
Steve Block44f0eee2011-05-26 01:26:41 +0100620i::Object** HandleScope::CreateHandle(i::Object* value) {
621 return i::HandleScope::CreateHandle(value, i::Isolate::Current());
622}
623
624
625i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
626 ASSERT(value->IsHeapObject());
627 return reinterpret_cast<i::Object**>(
628 i::HandleScope::CreateHandle(value, value->GetIsolate()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000629}
630
631
632void Context::Enter() {
Steve Block44f0eee2011-05-26 01:26:41 +0100633 // TODO(isolates): Context should have a pointer to isolate.
634 i::Isolate* isolate = i::Isolate::Current();
635 if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
636 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000637
Steve Block44f0eee2011-05-26 01:26:41 +0100638 i::Handle<i::Context> env = Utils::OpenHandle(this);
639 isolate->handle_scope_implementer()->EnterContext(env);
640
641 isolate->handle_scope_implementer()->SaveContext(isolate->context());
642 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000643}
644
645
646void Context::Exit() {
Steve Block44f0eee2011-05-26 01:26:41 +0100647 // TODO(isolates): Context should have a pointer to isolate.
648 i::Isolate* isolate = i::Isolate::Current();
649 if (!isolate->IsInitialized()) return;
650
651 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000652 "v8::Context::Exit()",
653 "Cannot exit non-entered context")) {
654 return;
655 }
656
657 // Content of 'last_context' could be NULL.
Steve Block44f0eee2011-05-26 01:26:41 +0100658 i::Context* last_context =
659 isolate->handle_scope_implementer()->RestoreContext();
660 isolate->set_context(last_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000661}
662
663
Steve Blockd0582a62009-12-15 09:54:21 +0000664void Context::SetData(v8::Handle<String> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100665 // TODO(isolates): Context should have a pointer to isolate.
666 i::Isolate* isolate = i::Isolate::Current();
667 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
668 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000669 {
Steve Block44f0eee2011-05-26 01:26:41 +0100670 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000671 i::Handle<i::Context> env = Utils::OpenHandle(this);
672 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
673 ASSERT(env->IsGlobalContext());
674 if (env->IsGlobalContext()) {
675 env->set_data(*raw_data);
676 }
677 }
678}
679
680
681v8::Local<v8::Value> Context::GetData() {
Steve Block44f0eee2011-05-26 01:26:41 +0100682 // TODO(isolates): Context should have a pointer to isolate.
683 i::Isolate* isolate = i::Isolate::Current();
684 if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
685 return v8::Local<Value>();
686 }
687 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000688 i::Object* raw_result = NULL;
689 {
Steve Block44f0eee2011-05-26 01:26:41 +0100690 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000691 i::Handle<i::Context> env = Utils::OpenHandle(this);
692 ASSERT(env->IsGlobalContext());
693 if (env->IsGlobalContext()) {
694 raw_result = env->data();
695 } else {
696 return Local<Value>();
697 }
698 }
699 i::Handle<i::Object> result(raw_result);
700 return Utils::ToLocal(result);
701}
702
703
704i::Object** v8::HandleScope::RawClose(i::Object** value) {
705 if (!ApiCheck(!is_closed_,
706 "v8::HandleScope::Close()",
707 "Local scope has already been closed")) {
708 return 0;
709 }
Steve Block44f0eee2011-05-26 01:26:41 +0100710 LOG_API(isolate_, "CloseHandleScope");
Steve Blocka7e24c12009-10-30 11:49:00 +0000711
712 // Read the result before popping the handle block.
Steve Block6ded16b2010-05-10 14:33:55 +0100713 i::Object* result = NULL;
714 if (value != NULL) {
715 result = *value;
716 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000717 is_closed_ = true;
John Reck59135872010-11-02 12:39:01 -0700718 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000719
Steve Block6ded16b2010-05-10 14:33:55 +0100720 if (value == NULL) {
721 return NULL;
722 }
723
Steve Blocka7e24c12009-10-30 11:49:00 +0000724 // Allocate a new handle on the previous handle block.
725 i::Handle<i::Object> handle(result);
726 return handle.location();
727}
728
729
730// --- N e a n d e r ---
731
732
733// A constructor cannot easily return an error value, therefore it is necessary
734// to check for a dead VM with ON_BAILOUT before constructing any Neander
735// objects. To remind you about this there is no HandleScope in the
736// NeanderObject constructor. When you add one to the site calling the
737// constructor you should check that you ensured the VM was not dead first.
738NeanderObject::NeanderObject(int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100739 i::Isolate* isolate = i::Isolate::Current();
740 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
741 ENTER_V8(isolate);
742 value_ = isolate->factory()->NewNeanderObject();
743 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000744 value_->set_elements(*elements);
745}
746
747
748int NeanderObject::size() {
749 return i::FixedArray::cast(value_->elements())->length();
750}
751
752
753NeanderArray::NeanderArray() : obj_(2) {
754 obj_.set(0, i::Smi::FromInt(0));
755}
756
757
758int NeanderArray::length() {
759 return i::Smi::cast(obj_.get(0))->value();
760}
761
762
763i::Object* NeanderArray::get(int offset) {
764 ASSERT(0 <= offset);
765 ASSERT(offset < length());
766 return obj_.get(offset + 1);
767}
768
769
770// This method cannot easily return an error value, therefore it is necessary
771// to check for a dead VM with ON_BAILOUT before calling it. To remind you
772// about this there is no HandleScope in this method. When you add one to the
773// site calling this method you should check that you ensured the VM was not
774// dead first.
775void NeanderArray::add(i::Handle<i::Object> value) {
776 int length = this->length();
777 int size = obj_.size();
778 if (length == size - 1) {
Steve Block44f0eee2011-05-26 01:26:41 +0100779 i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000780 for (int i = 0; i < length; i++)
781 new_elms->set(i + 1, get(i));
782 obj_.value()->set_elements(*new_elms);
783 }
784 obj_.set(length + 1, *value);
785 obj_.set(0, i::Smi::FromInt(length + 1));
786}
787
788
789void NeanderArray::set(int index, i::Object* value) {
790 if (index < 0 || index >= this->length()) return;
791 obj_.set(index + 1, value);
792}
793
794
795// --- T e m p l a t e ---
796
797
798static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
799 that->set_tag(i::Smi::FromInt(type));
800}
801
802
803void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
804 v8::PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +0100805 i::Isolate* isolate = i::Isolate::Current();
806 if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
807 ENTER_V8(isolate);
808 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000809 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
810 if (list->IsUndefined()) {
811 list = NeanderArray().value();
812 Utils::OpenHandle(this)->set_property_list(*list);
813 }
814 NeanderArray array(list);
815 array.add(Utils::OpenHandle(*name));
816 array.add(Utils::OpenHandle(*value));
817 array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
818}
819
820
821// --- F u n c t i o n T e m p l a t e ---
822static void InitializeFunctionTemplate(
823 i::Handle<i::FunctionTemplateInfo> info) {
824 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
825 info->set_flag(0);
826}
827
828
829Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +0100830 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
831 if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000832 return Local<ObjectTemplate>();
833 }
Steve Block44f0eee2011-05-26 01:26:41 +0100834 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000835 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
836 if (result->IsUndefined()) {
837 result = Utils::OpenHandle(*ObjectTemplate::New());
838 Utils::OpenHandle(this)->set_prototype_template(*result);
839 }
840 return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
841}
842
843
844void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100845 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
846 if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
847 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000848 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
849}
850
851
Steve Blocka7e24c12009-10-30 11:49:00 +0000852Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
853 v8::Handle<Value> data, v8::Handle<Signature> signature) {
Steve Block44f0eee2011-05-26 01:26:41 +0100854 i::Isolate* isolate = i::Isolate::Current();
855 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
856 LOG_API(isolate, "FunctionTemplate::New");
857 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000858 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100859 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000860 i::Handle<i::FunctionTemplateInfo> obj =
861 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
862 InitializeFunctionTemplate(obj);
Steve Block44f0eee2011-05-26 01:26:41 +0100863 int next_serial_number = isolate->next_serial_number();
864 isolate->set_next_serial_number(next_serial_number + 1);
865 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +0000866 if (callback != 0) {
867 if (data.IsEmpty()) data = v8::Undefined();
868 Utils::ToLocal(obj)->SetCallHandler(callback, data);
869 }
870 obj->set_undetectable(false);
871 obj->set_needs_access_check(false);
872
873 if (!signature.IsEmpty())
874 obj->set_signature(*Utils::OpenHandle(*signature));
875 return Utils::ToLocal(obj);
876}
877
878
879Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
880 int argc, Handle<FunctionTemplate> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100881 i::Isolate* isolate = i::Isolate::Current();
882 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
883 LOG_API(isolate, "Signature::New");
884 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000885 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100886 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000887 i::Handle<i::SignatureInfo> obj =
888 i::Handle<i::SignatureInfo>::cast(struct_obj);
889 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
890 if (argc > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100891 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000892 for (int i = 0; i < argc; i++) {
893 if (!argv[i].IsEmpty())
894 args->set(i, *Utils::OpenHandle(*argv[i]));
895 }
896 obj->set_args(*args);
897 }
898 return Utils::ToLocal(obj);
899}
900
901
902Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
903 Handle<FunctionTemplate> types[1] = { type };
904 return TypeSwitch::New(1, types);
905}
906
907
908Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100909 i::Isolate* isolate = i::Isolate::Current();
910 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
911 LOG_API(isolate, "TypeSwitch::New");
912 ENTER_V8(isolate);
913 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000914 for (int i = 0; i < argc; i++)
915 vector->set(i, *Utils::OpenHandle(*types[i]));
916 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100917 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000918 i::Handle<i::TypeSwitchInfo> obj =
919 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
920 obj->set_types(*vector);
921 return Utils::ToLocal(obj);
922}
923
924
925int TypeSwitch::match(v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100926 i::Isolate* isolate = i::Isolate::Current();
927 LOG_API(isolate, "TypeSwitch::match");
Steve Blocka7e24c12009-10-30 11:49:00 +0000928 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
929 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
930 i::FixedArray* types = i::FixedArray::cast(info->types());
931 for (int i = 0; i < types->length(); i++) {
932 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
933 return i + 1;
934 }
935 return 0;
936}
937
938
Ben Murdoch257744e2011-11-30 15:57:28 +0000939#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
940 i::Handle<i::Object> foreign = FromCData(cdata); \
941 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100942 } while (false)
943
944
Steve Blocka7e24c12009-10-30 11:49:00 +0000945void FunctionTemplate::SetCallHandler(InvocationCallback callback,
946 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100947 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
948 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
949 ENTER_V8(isolate);
950 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000951 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100952 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000953 i::Handle<i::CallHandlerInfo> obj =
954 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100955 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000956 if (data.IsEmpty()) data = v8::Undefined();
957 obj->set_data(*Utils::OpenHandle(*data));
958 Utils::OpenHandle(this)->set_call_code(*obj);
959}
960
961
Leon Clarkef7060e22010-06-03 12:02:55 +0100962static i::Handle<i::AccessorInfo> MakeAccessorInfo(
963 v8::Handle<String> name,
964 AccessorGetter getter,
965 AccessorSetter setter,
966 v8::Handle<Value> data,
967 v8::AccessControl settings,
968 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +0100969 i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
Leon Clarkef7060e22010-06-03 12:02:55 +0100970 ASSERT(getter != NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100971 SET_FIELD_WRAPPED(obj, set_getter, getter);
972 SET_FIELD_WRAPPED(obj, set_setter, setter);
Leon Clarkef7060e22010-06-03 12:02:55 +0100973 if (data.IsEmpty()) data = v8::Undefined();
974 obj->set_data(*Utils::OpenHandle(*data));
975 obj->set_name(*Utils::OpenHandle(*name));
976 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
977 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
978 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
979 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
980 return obj;
981}
982
983
Steve Blocka7e24c12009-10-30 11:49:00 +0000984void FunctionTemplate::AddInstancePropertyAccessor(
985 v8::Handle<String> name,
986 AccessorGetter getter,
987 AccessorSetter setter,
988 v8::Handle<Value> data,
989 v8::AccessControl settings,
990 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +0100991 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
992 if (IsDeadCheck(isolate,
993 "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000994 return;
995 }
Steve Block44f0eee2011-05-26 01:26:41 +0100996 ENTER_V8(isolate);
997 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000998
Leon Clarkef7060e22010-06-03 12:02:55 +0100999 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
1000 getter, setter, data,
1001 settings, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00001002 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
1003 if (list->IsUndefined()) {
1004 list = NeanderArray().value();
1005 Utils::OpenHandle(this)->set_property_accessors(*list);
1006 }
1007 NeanderArray array(list);
1008 array.add(obj);
1009}
1010
1011
1012Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +01001013 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1014 if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
Steve Blocka7e24c12009-10-30 11:49:00 +00001015 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
1016 return Local<ObjectTemplate>();
Steve Block44f0eee2011-05-26 01:26:41 +01001017 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001018 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
1019 Local<ObjectTemplate> templ =
1020 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
1021 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
1022 }
1023 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
1024 Utils::OpenHandle(this)->instance_template()));
1025 return Utils::ToLocal(result);
1026}
1027
1028
1029void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01001030 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1031 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
1032 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001033 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1034}
1035
1036
1037void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001038 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1039 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
1040 return;
1041 }
1042 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001043 Utils::OpenHandle(this)->set_hidden_prototype(value);
1044}
1045
1046
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001047void FunctionTemplate::SetNamedInstancePropertyHandler(
Steve Blocka7e24c12009-10-30 11:49:00 +00001048 NamedPropertyGetter getter,
1049 NamedPropertySetter setter,
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001050 NamedPropertyQuery query,
Steve Blocka7e24c12009-10-30 11:49:00 +00001051 NamedPropertyDeleter remover,
1052 NamedPropertyEnumerator enumerator,
1053 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001054 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1055 if (IsDeadCheck(isolate,
1056 "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001057 return;
1058 }
Steve Block44f0eee2011-05-26 01:26:41 +01001059 ENTER_V8(isolate);
1060 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001061 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001062 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001063 i::Handle<i::InterceptorInfo> obj =
1064 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001065
1066 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1067 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1068 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1069 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1070 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1071
Steve Blocka7e24c12009-10-30 11:49:00 +00001072 if (data.IsEmpty()) data = v8::Undefined();
1073 obj->set_data(*Utils::OpenHandle(*data));
1074 Utils::OpenHandle(this)->set_named_property_handler(*obj);
1075}
1076
1077
1078void FunctionTemplate::SetIndexedInstancePropertyHandler(
1079 IndexedPropertyGetter getter,
1080 IndexedPropertySetter setter,
1081 IndexedPropertyQuery query,
1082 IndexedPropertyDeleter remover,
1083 IndexedPropertyEnumerator enumerator,
1084 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001085 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1086 if (IsDeadCheck(isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00001087 "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
1088 return;
1089 }
Steve Block44f0eee2011-05-26 01:26:41 +01001090 ENTER_V8(isolate);
1091 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001092 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001093 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001094 i::Handle<i::InterceptorInfo> obj =
1095 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001096
1097 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1098 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1099 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1100 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1101 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1102
Steve Blocka7e24c12009-10-30 11:49:00 +00001103 if (data.IsEmpty()) data = v8::Undefined();
1104 obj->set_data(*Utils::OpenHandle(*data));
1105 Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
1106}
1107
1108
1109void FunctionTemplate::SetInstanceCallAsFunctionHandler(
1110 InvocationCallback callback,
1111 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001112 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1113 if (IsDeadCheck(isolate,
1114 "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001115 return;
1116 }
Steve Block44f0eee2011-05-26 01:26:41 +01001117 ENTER_V8(isolate);
1118 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001119 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001120 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001121 i::Handle<i::CallHandlerInfo> obj =
1122 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001123 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001124 if (data.IsEmpty()) data = v8::Undefined();
1125 obj->set_data(*Utils::OpenHandle(*data));
1126 Utils::OpenHandle(this)->set_instance_call_handler(*obj);
1127}
1128
1129
1130// --- O b j e c t T e m p l a t e ---
1131
1132
1133Local<ObjectTemplate> ObjectTemplate::New() {
1134 return New(Local<FunctionTemplate>());
1135}
1136
1137
1138Local<ObjectTemplate> ObjectTemplate::New(
1139 v8::Handle<FunctionTemplate> constructor) {
Steve Block44f0eee2011-05-26 01:26:41 +01001140 i::Isolate* isolate = i::Isolate::Current();
1141 if (IsDeadCheck(isolate, "v8::ObjectTemplate::New()")) {
1142 return Local<ObjectTemplate>();
1143 }
1144 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1145 LOG_API(isolate, "ObjectTemplate::New");
1146 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001147 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001148 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001149 i::Handle<i::ObjectTemplateInfo> obj =
1150 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1151 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1152 if (!constructor.IsEmpty())
1153 obj->set_constructor(*Utils::OpenHandle(*constructor));
1154 obj->set_internal_field_count(i::Smi::FromInt(0));
1155 return Utils::ToLocal(obj);
1156}
1157
1158
1159// Ensure that the object template has a constructor. If no
1160// constructor is available we create one.
1161static void EnsureConstructor(ObjectTemplate* object_template) {
1162 if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
1163 Local<FunctionTemplate> templ = FunctionTemplate::New();
1164 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1165 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1166 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1167 }
1168}
1169
1170
1171void ObjectTemplate::SetAccessor(v8::Handle<String> name,
1172 AccessorGetter getter,
1173 AccessorSetter setter,
1174 v8::Handle<Value> data,
1175 AccessControl settings,
1176 PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +01001177 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1178 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
1179 ENTER_V8(isolate);
1180 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001181 EnsureConstructor(this);
1182 i::FunctionTemplateInfo* constructor =
1183 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1184 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1185 Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
1186 getter,
1187 setter,
1188 data,
1189 settings,
1190 attribute);
1191}
1192
1193
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001194void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
1195 NamedPropertySetter setter,
1196 NamedPropertyQuery query,
1197 NamedPropertyDeleter remover,
1198 NamedPropertyEnumerator enumerator,
1199 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001200 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1201 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
1202 return;
1203 }
1204 ENTER_V8(isolate);
1205 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001206 EnsureConstructor(this);
1207 i::FunctionTemplateInfo* constructor =
1208 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1209 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001210 Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
1211 setter,
1212 query,
1213 remover,
1214 enumerator,
1215 data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001216}
1217
1218
1219void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001220 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1221 if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
1222 ENTER_V8(isolate);
1223 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001224 EnsureConstructor(this);
1225 i::FunctionTemplateInfo* constructor =
1226 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1227 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1228 cons->set_undetectable(true);
1229}
1230
1231
1232void ObjectTemplate::SetAccessCheckCallbacks(
1233 NamedSecurityCallback named_callback,
1234 IndexedSecurityCallback indexed_callback,
1235 Handle<Value> data,
1236 bool turned_on_by_default) {
Steve Block44f0eee2011-05-26 01:26:41 +01001237 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1238 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
1239 return;
1240 }
1241 ENTER_V8(isolate);
1242 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001243 EnsureConstructor(this);
1244
1245 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001246 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001247 i::Handle<i::AccessCheckInfo> info =
1248 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001249
1250 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1251 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1252
Steve Blocka7e24c12009-10-30 11:49:00 +00001253 if (data.IsEmpty()) data = v8::Undefined();
1254 info->set_data(*Utils::OpenHandle(*data));
1255
1256 i::FunctionTemplateInfo* constructor =
1257 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1258 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1259 cons->set_access_check_info(*info);
1260 cons->set_needs_access_check(turned_on_by_default);
1261}
1262
1263
1264void ObjectTemplate::SetIndexedPropertyHandler(
1265 IndexedPropertyGetter getter,
1266 IndexedPropertySetter setter,
1267 IndexedPropertyQuery query,
1268 IndexedPropertyDeleter remover,
1269 IndexedPropertyEnumerator enumerator,
1270 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001271 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1272 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
1273 return;
1274 }
1275 ENTER_V8(isolate);
1276 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001277 EnsureConstructor(this);
1278 i::FunctionTemplateInfo* constructor =
1279 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1280 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1281 Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
1282 setter,
1283 query,
1284 remover,
1285 enumerator,
1286 data);
1287}
1288
1289
1290void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
1291 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001292 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1293 if (IsDeadCheck(isolate,
1294 "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
1295 return;
1296 }
1297 ENTER_V8(isolate);
1298 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001299 EnsureConstructor(this);
1300 i::FunctionTemplateInfo* constructor =
1301 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1302 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1303 Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
1304}
1305
1306
1307int ObjectTemplate::InternalFieldCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01001308 if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
1309 "v8::ObjectTemplate::InternalFieldCount()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001310 return 0;
1311 }
1312 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1313}
1314
1315
1316void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001317 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1318 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
1319 return;
1320 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001321 if (!ApiCheck(i::Smi::IsValid(value),
1322 "v8::ObjectTemplate::SetInternalFieldCount()",
1323 "Invalid internal field count")) {
1324 return;
1325 }
Steve Block44f0eee2011-05-26 01:26:41 +01001326 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001327 if (value > 0) {
1328 // The internal field count is set by the constructor function's
1329 // construct code, so we ensure that there is a constructor
1330 // function to do the setting.
1331 EnsureConstructor(this);
1332 }
1333 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1334}
1335
1336
1337// --- S c r i p t D a t a ---
1338
1339
1340ScriptData* ScriptData::PreCompile(const char* input, int length) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001341 i::Utf8ToUC16CharacterStream stream(
1342 reinterpret_cast<const unsigned char*>(input), length);
1343 return i::ParserApi::PreParse(&stream, NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00001344}
1345
1346
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001347ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1348 i::Handle<i::String> str = Utils::OpenHandle(*source);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001349 if (str->IsExternalTwoByteString()) {
1350 i::ExternalTwoByteStringUC16CharacterStream stream(
1351 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
1352 return i::ParserApi::PreParse(&stream, NULL);
1353 } else {
1354 i::GenericStringUC16CharacterStream stream(str, 0, str->length());
1355 return i::ParserApi::PreParse(&stream, NULL);
1356 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001357}
1358
1359
Leon Clarkef7060e22010-06-03 12:02:55 +01001360ScriptData* ScriptData::New(const char* data, int length) {
1361 // Return an empty ScriptData if the length is obviously invalid.
1362 if (length % sizeof(unsigned) != 0) {
Iain Merrick9ac36c92010-09-13 15:29:50 +01001363 return new i::ScriptDataImpl();
Leon Clarkef7060e22010-06-03 12:02:55 +01001364 }
1365
1366 // Copy the data to ensure it is properly aligned.
1367 int deserialized_data_length = length / sizeof(unsigned);
Iain Merrick9ac36c92010-09-13 15:29:50 +01001368 // If aligned, don't create a copy of the data.
1369 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1370 return new i::ScriptDataImpl(data, length);
1371 }
1372 // Copy the data to align it.
Leon Clarkef7060e22010-06-03 12:02:55 +01001373 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001374 i::OS::MemCopy(deserialized_data, data, length);
Leon Clarkef7060e22010-06-03 12:02:55 +01001375
1376 return new i::ScriptDataImpl(
1377 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
Steve Blocka7e24c12009-10-30 11:49:00 +00001378}
1379
1380
1381// --- S c r i p t ---
1382
1383
1384Local<Script> Script::New(v8::Handle<String> source,
1385 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001386 v8::ScriptData* pre_data,
1387 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001388 i::Isolate* isolate = i::Isolate::Current();
1389 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1390 LOG_API(isolate, "Script::New");
1391 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001392 i::Handle<i::String> str = Utils::OpenHandle(*source);
1393 i::Handle<i::Object> name_obj;
1394 int line_offset = 0;
1395 int column_offset = 0;
1396 if (origin != NULL) {
1397 if (!origin->ResourceName().IsEmpty()) {
1398 name_obj = Utils::OpenHandle(*origin->ResourceName());
1399 }
1400 if (!origin->ResourceLineOffset().IsEmpty()) {
1401 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1402 }
1403 if (!origin->ResourceColumnOffset().IsEmpty()) {
1404 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
1405 }
1406 }
Steve Block44f0eee2011-05-26 01:26:41 +01001407 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001408 i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001409 // We assert that the pre-data is sane, even though we can actually
1410 // handle it if it turns out not to be in release mode.
Andrei Popescu402d9372010-02-26 13:31:12 +00001411 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
Steve Blocka7e24c12009-10-30 11:49:00 +00001412 // If the pre-data isn't sane we simply ignore it
Andrei Popescu402d9372010-02-26 13:31:12 +00001413 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1414 pre_data_impl = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001415 }
Steve Block6ded16b2010-05-10 14:33:55 +01001416 i::Handle<i::SharedFunctionInfo> result =
Andrei Popescu31002712010-02-23 13:46:05 +00001417 i::Compiler::Compile(str,
1418 name_obj,
1419 line_offset,
1420 column_offset,
1421 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001422 pre_data_impl,
1423 Utils::OpenHandle(*script_data),
Andrei Popescu31002712010-02-23 13:46:05 +00001424 i::NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001425 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01001426 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
Steve Block6ded16b2010-05-10 14:33:55 +01001427 return Local<Script>(ToApi<Script>(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00001428}
1429
1430
1431Local<Script> Script::New(v8::Handle<String> source,
1432 v8::Handle<Value> file_name) {
1433 ScriptOrigin origin(file_name);
1434 return New(source, &origin);
1435}
1436
1437
1438Local<Script> Script::Compile(v8::Handle<String> source,
1439 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001440 v8::ScriptData* pre_data,
1441 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001442 i::Isolate* isolate = i::Isolate::Current();
1443 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1444 LOG_API(isolate, "Script::Compile");
1445 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001446 Local<Script> generic = New(source, origin, pre_data, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001447 if (generic.IsEmpty())
1448 return generic;
Steve Block6ded16b2010-05-10 14:33:55 +01001449 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1450 i::Handle<i::SharedFunctionInfo> function =
1451 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
Steve Blocka7e24c12009-10-30 11:49:00 +00001452 i::Handle<i::JSFunction> result =
Steve Block44f0eee2011-05-26 01:26:41 +01001453 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1454 function,
1455 isolate->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001456 return Local<Script>(ToApi<Script>(result));
1457}
1458
1459
1460Local<Script> Script::Compile(v8::Handle<String> source,
Andrei Popescu402d9372010-02-26 13:31:12 +00001461 v8::Handle<Value> file_name,
1462 v8::Handle<String> script_data) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001463 ScriptOrigin origin(file_name);
Andrei Popescu402d9372010-02-26 13:31:12 +00001464 return Compile(source, &origin, 0, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001465}
1466
1467
1468Local<Value> Script::Run() {
Steve Block44f0eee2011-05-26 01:26:41 +01001469 i::Isolate* isolate = i::Isolate::Current();
1470 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1471 LOG_API(isolate, "Script::Run");
1472 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001473 i::Object* raw_result = NULL;
1474 {
Steve Block44f0eee2011-05-26 01:26:41 +01001475 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001476 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1477 i::Handle<i::JSFunction> fun;
1478 if (obj->IsSharedFunctionInfo()) {
1479 i::Handle<i::SharedFunctionInfo>
Steve Block44f0eee2011-05-26 01:26:41 +01001480 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
1481 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
1482 function_info, isolate->global_context());
Steve Block6ded16b2010-05-10 14:33:55 +01001483 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001484 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001485 }
Steve Block44f0eee2011-05-26 01:26:41 +01001486 EXCEPTION_PREAMBLE(isolate);
1487 i::Handle<i::Object> receiver(
1488 isolate->context()->global_proxy(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001489 i::Handle<i::Object> result =
1490 i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001491 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001492 raw_result = *result;
1493 }
Steve Block44f0eee2011-05-26 01:26:41 +01001494 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001495 return Utils::ToLocal(result);
1496}
1497
1498
Steve Block6ded16b2010-05-10 14:33:55 +01001499static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1500 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1501 i::Handle<i::SharedFunctionInfo> result;
1502 if (obj->IsSharedFunctionInfo()) {
1503 result =
1504 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1505 } else {
1506 result =
1507 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1508 }
1509 return result;
1510}
1511
1512
Steve Blocka7e24c12009-10-30 11:49:00 +00001513Local<Value> Script::Id() {
Steve Block44f0eee2011-05-26 01:26:41 +01001514 i::Isolate* isolate = i::Isolate::Current();
1515 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1516 LOG_API(isolate, "Script::Id");
Steve Blocka7e24c12009-10-30 11:49:00 +00001517 i::Object* raw_id = NULL;
1518 {
Steve Block44f0eee2011-05-26 01:26:41 +01001519 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001520 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1521 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001522 i::Handle<i::Object> id(script->id());
1523 raw_id = *id;
1524 }
1525 i::Handle<i::Object> id(raw_id);
1526 return Utils::ToLocal(id);
1527}
1528
1529
Steve Blockd0582a62009-12-15 09:54:21 +00001530void Script::SetData(v8::Handle<String> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001531 i::Isolate* isolate = i::Isolate::Current();
1532 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1533 LOG_API(isolate, "Script::SetData");
Steve Blocka7e24c12009-10-30 11:49:00 +00001534 {
Steve Block44f0eee2011-05-26 01:26:41 +01001535 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001536 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001537 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
Steve Block6ded16b2010-05-10 14:33:55 +01001538 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001539 script->set_data(*raw_data);
1540 }
1541}
1542
1543
1544// --- E x c e p t i o n s ---
1545
1546
1547v8::TryCatch::TryCatch()
Steve Block44f0eee2011-05-26 01:26:41 +01001548 : next_(i::Isolate::Current()->try_catch_handler_address()),
1549 exception_(HEAP->the_hole_value()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001550 message_(i::Smi::FromInt(0)),
1551 is_verbose_(false),
1552 can_continue_(true),
1553 capture_message_(true),
Steve Blockd0582a62009-12-15 09:54:21 +00001554 rethrow_(false) {
Steve Block44f0eee2011-05-26 01:26:41 +01001555 i::Isolate::Current()->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001556}
1557
1558
1559v8::TryCatch::~TryCatch() {
Steve Block44f0eee2011-05-26 01:26:41 +01001560 i::Isolate* isolate = i::Isolate::Current();
Steve Blockd0582a62009-12-15 09:54:21 +00001561 if (rethrow_) {
1562 v8::HandleScope scope;
1563 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
Steve Block44f0eee2011-05-26 01:26:41 +01001564 isolate->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001565 v8::ThrowException(exc);
1566 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001567 isolate->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001568 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001569}
1570
1571
1572bool v8::TryCatch::HasCaught() const {
1573 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1574}
1575
1576
1577bool v8::TryCatch::CanContinue() const {
1578 return can_continue_;
1579}
1580
1581
Steve Blockd0582a62009-12-15 09:54:21 +00001582v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1583 if (!HasCaught()) return v8::Local<v8::Value>();
1584 rethrow_ = true;
1585 return v8::Undefined();
1586}
1587
1588
Steve Blocka7e24c12009-10-30 11:49:00 +00001589v8::Local<Value> v8::TryCatch::Exception() const {
1590 if (HasCaught()) {
1591 // Check for out of memory exception.
1592 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
1593 return v8::Utils::ToLocal(i::Handle<i::Object>(exception));
1594 } else {
1595 return v8::Local<Value>();
1596 }
1597}
1598
1599
1600v8::Local<Value> v8::TryCatch::StackTrace() const {
1601 if (HasCaught()) {
1602 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1603 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
1604 v8::HandleScope scope;
1605 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj));
Steve Block44f0eee2011-05-26 01:26:41 +01001606 i::Handle<i::String> name = FACTORY->LookupAsciiSymbol("stack");
Steve Blocka7e24c12009-10-30 11:49:00 +00001607 if (!obj->HasProperty(*name))
1608 return v8::Local<Value>();
1609 return scope.Close(v8::Utils::ToLocal(i::GetProperty(obj, name)));
1610 } else {
1611 return v8::Local<Value>();
1612 }
1613}
1614
1615
1616v8::Local<v8::Message> v8::TryCatch::Message() const {
1617 if (HasCaught() && message_ != i::Smi::FromInt(0)) {
1618 i::Object* message = reinterpret_cast<i::Object*>(message_);
1619 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
1620 } else {
1621 return v8::Local<v8::Message>();
1622 }
1623}
1624
1625
1626void v8::TryCatch::Reset() {
Steve Block44f0eee2011-05-26 01:26:41 +01001627 exception_ = HEAP->the_hole_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00001628 message_ = i::Smi::FromInt(0);
1629}
1630
1631
1632void v8::TryCatch::SetVerbose(bool value) {
1633 is_verbose_ = value;
1634}
1635
1636
1637void v8::TryCatch::SetCaptureMessage(bool value) {
1638 capture_message_ = value;
1639}
1640
1641
1642// --- M e s s a g e ---
1643
1644
1645Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001646 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1647 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
1648 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001649 HandleScope scope;
1650 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1651 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
1652 Local<String> result = Utils::ToLocal(raw_result);
1653 return scope.Close(result);
1654}
1655
1656
1657v8::Handle<Value> Message::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001658 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1659 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001660 return Local<String>();
1661 }
Steve Block44f0eee2011-05-26 01:26:41 +01001662 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001663 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001664 i::Handle<i::JSMessageObject> message =
1665 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001666 // Return this.script.name.
1667 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001668 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001669 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
1670 return scope.Close(Utils::ToLocal(resource_name));
1671}
1672
1673
1674v8::Handle<Value> Message::GetScriptData() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001675 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1676 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001677 return Local<Value>();
1678 }
Steve Block44f0eee2011-05-26 01:26:41 +01001679 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001680 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001681 i::Handle<i::JSMessageObject> message =
1682 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001683 // Return this.script.data.
1684 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001685 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001686 i::Handle<i::Object> data(i::Script::cast(script->value())->data());
1687 return scope.Close(Utils::ToLocal(data));
1688}
1689
1690
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001691v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001692 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1693 if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001694 return Local<v8::StackTrace>();
1695 }
Steve Block44f0eee2011-05-26 01:26:41 +01001696 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001697 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001698 i::Handle<i::JSMessageObject> message =
1699 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1700 i::Handle<i::Object> stackFramesObj(message->stack_frames());
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001701 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
1702 i::Handle<i::JSArray> stackTrace =
1703 i::Handle<i::JSArray>::cast(stackFramesObj);
1704 return scope.Close(Utils::StackTraceToLocal(stackTrace));
1705}
1706
1707
Steve Blocka7e24c12009-10-30 11:49:00 +00001708static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1709 i::Handle<i::Object> recv,
1710 int argc,
1711 i::Object** argv[],
1712 bool* has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +01001713 i::Isolate* isolate = i::Isolate::Current();
1714 i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name);
John Reck59135872010-11-02 12:39:01 -07001715 i::Object* object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001716 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
Steve Blocka7e24c12009-10-30 11:49:00 +00001717 i::Handle<i::JSFunction> fun =
1718 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
1719 i::Handle<i::Object> value =
1720 i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
1721 return value;
1722}
1723
1724
1725static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1726 i::Handle<i::Object> data,
1727 bool* has_pending_exception) {
1728 i::Object** argv[1] = { data.location() };
1729 return CallV8HeapFunction(name,
Steve Block44f0eee2011-05-26 01:26:41 +01001730 i::Isolate::Current()->js_builtins_object(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001731 1,
1732 argv,
1733 has_pending_exception);
1734}
1735
1736
1737int Message::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001738 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1739 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
1740 ENTER_V8(isolate);
1741 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001742
Steve Block44f0eee2011-05-26 01:26:41 +01001743 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001744 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
1745 Utils::OpenHandle(this),
1746 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001747 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001748 return static_cast<int>(result->Number());
1749}
1750
1751
1752int Message::GetStartPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001753 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1754 if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
1755 ENTER_V8(isolate);
1756 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001757 i::Handle<i::JSMessageObject> message =
1758 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1759 return message->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001760}
1761
1762
1763int Message::GetEndPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001764 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1765 if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
1766 ENTER_V8(isolate);
1767 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001768 i::Handle<i::JSMessageObject> message =
1769 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1770 return message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001771}
1772
1773
1774int Message::GetStartColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001775 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1776 if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
1777 return kNoColumnInfo;
1778 }
1779 ENTER_V8(isolate);
1780 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001781 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001782 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001783 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1784 "GetPositionInLine",
1785 data_obj,
1786 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001787 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001788 return static_cast<int>(start_col_obj->Number());
1789}
1790
1791
1792int Message::GetEndColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001793 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1794 if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
1795 ENTER_V8(isolate);
1796 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001797 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001798 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001799 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1800 "GetPositionInLine",
1801 data_obj,
1802 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001803 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Block1e0659c2011-05-24 12:43:12 +01001804 i::Handle<i::JSMessageObject> message =
1805 i::Handle<i::JSMessageObject>::cast(data_obj);
1806 int start = message->start_position();
1807 int end = message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001808 return static_cast<int>(start_col_obj->Number()) + (end - start);
1809}
1810
1811
1812Local<String> Message::GetSourceLine() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001813 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1814 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
1815 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001816 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01001817 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001818 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
1819 Utils::OpenHandle(this),
1820 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001821 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001822 if (result->IsString()) {
1823 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
1824 } else {
1825 return Local<String>();
1826 }
1827}
1828
1829
1830void Message::PrintCurrentStackTrace(FILE* out) {
Steve Block44f0eee2011-05-26 01:26:41 +01001831 i::Isolate* isolate = i::Isolate::Current();
1832 if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
1833 ENTER_V8(isolate);
1834 isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00001835}
1836
1837
Kristian Monsen25f61362010-05-21 11:50:48 +01001838// --- S t a c k T r a c e ---
1839
1840Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01001841 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1842 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
1843 return Local<StackFrame>();
1844 }
1845 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001846 HandleScope scope;
1847 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
John Reck59135872010-11-02 12:39:01 -07001848 i::Object* raw_object = self->GetElementNoExceptionThrown(index);
1849 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001850 return scope.Close(Utils::StackFrameToLocal(obj));
1851}
1852
1853
1854int StackTrace::GetFrameCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001855 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1856 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
1857 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001858 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
1859}
1860
1861
1862Local<Array> StackTrace::AsArray() {
Steve Block44f0eee2011-05-26 01:26:41 +01001863 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1864 if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
1865 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001866 return Utils::ToLocal(Utils::OpenHandle(this));
1867}
1868
1869
1870Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
1871 StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01001872 i::Isolate* isolate = i::Isolate::Current();
1873 if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
1874 Local<StackTrace>();
1875 }
1876 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001877 i::Handle<i::JSArray> stackTrace =
Steve Block44f0eee2011-05-26 01:26:41 +01001878 isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001879 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01001880}
1881
1882
1883// --- S t a c k F r a m e ---
1884
1885int StackFrame::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001886 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1887 if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001888 return Message::kNoLineNumberInfo;
1889 }
Steve Block44f0eee2011-05-26 01:26:41 +01001890 ENTER_V8(isolate);
1891 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001892 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1893 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
1894 if (!line->IsSmi()) {
1895 return Message::kNoLineNumberInfo;
1896 }
1897 return i::Smi::cast(*line)->value();
1898}
1899
1900
1901int StackFrame::GetColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001902 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1903 if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001904 return Message::kNoColumnInfo;
1905 }
Steve Block44f0eee2011-05-26 01:26:41 +01001906 ENTER_V8(isolate);
1907 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001908 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1909 i::Handle<i::Object> column = GetProperty(self, "column");
1910 if (!column->IsSmi()) {
1911 return Message::kNoColumnInfo;
1912 }
1913 return i::Smi::cast(*column)->value();
1914}
1915
1916
1917Local<String> StackFrame::GetScriptName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001918 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1919 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
1920 return Local<String>();
1921 }
1922 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001923 HandleScope scope;
1924 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1925 i::Handle<i::Object> name = GetProperty(self, "scriptName");
1926 if (!name->IsString()) {
1927 return Local<String>();
1928 }
1929 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1930}
1931
1932
Ben Murdochf87a2032010-10-22 12:50:53 +01001933Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001934 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1935 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
Ben Murdochf87a2032010-10-22 12:50:53 +01001936 return Local<String>();
1937 }
Steve Block44f0eee2011-05-26 01:26:41 +01001938 ENTER_V8(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01001939 HandleScope scope;
1940 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1941 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
1942 if (!name->IsString()) {
1943 return Local<String>();
1944 }
1945 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1946}
1947
1948
Kristian Monsen25f61362010-05-21 11:50:48 +01001949Local<String> StackFrame::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001950 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1951 if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
1952 return Local<String>();
1953 }
1954 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001955 HandleScope scope;
1956 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1957 i::Handle<i::Object> name = GetProperty(self, "functionName");
1958 if (!name->IsString()) {
1959 return Local<String>();
1960 }
1961 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1962}
1963
1964
1965bool StackFrame::IsEval() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001966 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1967 if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
1968 ENTER_V8(isolate);
1969 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001970 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1971 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
1972 return is_eval->IsTrue();
1973}
1974
1975
1976bool StackFrame::IsConstructor() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001977 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1978 if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
1979 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> is_constructor = GetProperty(self, "isConstructor");
1983 return is_constructor->IsTrue();
1984}
1985
1986
Steve Blocka7e24c12009-10-30 11:49:00 +00001987// --- D a t a ---
1988
1989bool Value::IsUndefined() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001990 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
1991 return false;
1992 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001993 return Utils::OpenHandle(this)->IsUndefined();
1994}
1995
1996
1997bool Value::IsNull() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001998 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001999 return Utils::OpenHandle(this)->IsNull();
2000}
2001
2002
2003bool Value::IsTrue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002004 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002005 return Utils::OpenHandle(this)->IsTrue();
2006}
2007
2008
2009bool Value::IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002010 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002011 return Utils::OpenHandle(this)->IsFalse();
2012}
2013
2014
2015bool Value::IsFunction() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002016 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFunction()")) {
2017 return false;
2018 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002019 return Utils::OpenHandle(this)->IsJSFunction();
2020}
2021
2022
2023bool Value::FullIsString() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002024 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsString()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002025 bool result = Utils::OpenHandle(this)->IsString();
2026 ASSERT_EQ(result, QuickIsString());
2027 return result;
2028}
2029
2030
2031bool Value::IsArray() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002032 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002033 return Utils::OpenHandle(this)->IsJSArray();
2034}
2035
2036
2037bool Value::IsObject() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002038 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002039 return Utils::OpenHandle(this)->IsJSObject();
2040}
2041
2042
2043bool Value::IsNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002044 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002045 return Utils::OpenHandle(this)->IsNumber();
2046}
2047
2048
2049bool Value::IsBoolean() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002050 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsBoolean()")) {
2051 return false;
2052 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002053 return Utils::OpenHandle(this)->IsBoolean();
2054}
2055
2056
2057bool Value::IsExternal() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002058 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
2059 return false;
2060 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002061 return Utils::OpenHandle(this)->IsForeign();
Steve Blocka7e24c12009-10-30 11:49:00 +00002062}
2063
2064
2065bool Value::IsInt32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002066 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002067 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2068 if (obj->IsSmi()) return true;
2069 if (obj->IsNumber()) {
2070 double value = obj->Number();
2071 return i::FastI2D(i::FastD2I(value)) == value;
2072 }
2073 return false;
2074}
2075
2076
Steve Block6ded16b2010-05-10 14:33:55 +01002077bool Value::IsUint32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002078 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUint32()")) return false;
Steve Block6ded16b2010-05-10 14:33:55 +01002079 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2080 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2081 if (obj->IsNumber()) {
2082 double value = obj->Number();
2083 return i::FastUI2D(i::FastD2UI(value)) == value;
2084 }
2085 return false;
2086}
2087
2088
Steve Blocka7e24c12009-10-30 11:49:00 +00002089bool Value::IsDate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002090 i::Isolate* isolate = i::Isolate::Current();
2091 if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002092 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002093 return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00002094}
2095
2096
Iain Merrick75681382010-08-19 15:07:18 +01002097bool Value::IsRegExp() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002098 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
Iain Merrick75681382010-08-19 15:07:18 +01002099 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2100 return obj->IsJSRegExp();
2101}
2102
2103
Steve Blocka7e24c12009-10-30 11:49:00 +00002104Local<String> Value::ToString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002105 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2106 i::Handle<i::Object> str;
2107 if (obj->IsString()) {
2108 str = obj;
2109 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002110 i::Isolate* isolate = i::Isolate::Current();
2111 if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
2112 return Local<String>();
2113 }
2114 LOG_API(isolate, "ToString");
2115 ENTER_V8(isolate);
2116 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002117 str = i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002118 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002119 }
2120 return Local<String>(ToApi<String>(str));
2121}
2122
2123
2124Local<String> Value::ToDetailString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002125 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2126 i::Handle<i::Object> str;
2127 if (obj->IsString()) {
2128 str = obj;
2129 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002130 i::Isolate* isolate = i::Isolate::Current();
2131 if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
2132 return Local<String>();
2133 }
2134 LOG_API(isolate, "ToDetailString");
2135 ENTER_V8(isolate);
2136 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002137 str = i::Execution::ToDetailString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002138 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002139 }
2140 return Local<String>(ToApi<String>(str));
2141}
2142
2143
2144Local<v8::Object> Value::ToObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002145 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2146 i::Handle<i::Object> val;
2147 if (obj->IsJSObject()) {
2148 val = obj;
2149 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002150 i::Isolate* isolate = i::Isolate::Current();
2151 if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
2152 return Local<v8::Object>();
2153 }
2154 LOG_API(isolate, "ToObject");
2155 ENTER_V8(isolate);
2156 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002157 val = i::Execution::ToObject(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002158 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002159 }
2160 return Local<v8::Object>(ToApi<Object>(val));
2161}
2162
2163
2164Local<Boolean> Value::ToBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002165 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2166 if (obj->IsBoolean()) {
2167 return Local<Boolean>(ToApi<Boolean>(obj));
2168 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002169 i::Isolate* isolate = i::Isolate::Current();
2170 if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
2171 return Local<Boolean>();
2172 }
2173 LOG_API(isolate, "ToBoolean");
2174 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002175 i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
2176 return Local<Boolean>(ToApi<Boolean>(val));
2177 }
2178}
2179
2180
2181Local<Number> Value::ToNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002182 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2183 i::Handle<i::Object> num;
2184 if (obj->IsNumber()) {
2185 num = obj;
2186 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002187 i::Isolate* isolate = i::Isolate::Current();
2188 if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
2189 return Local<Number>();
2190 }
2191 LOG_API(isolate, "ToNumber");
2192 ENTER_V8(isolate);
2193 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002194 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002195 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002196 }
2197 return Local<Number>(ToApi<Number>(num));
2198}
2199
2200
2201Local<Integer> Value::ToInteger() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002202 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2203 i::Handle<i::Object> num;
2204 if (obj->IsSmi()) {
2205 num = obj;
2206 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002207 i::Isolate* isolate = i::Isolate::Current();
2208 if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
2209 LOG_API(isolate, "ToInteger");
2210 ENTER_V8(isolate);
2211 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002212 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002213 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002214 }
2215 return Local<Integer>(ToApi<Integer>(num));
2216}
2217
2218
2219void External::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002220 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002221 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch257744e2011-11-30 15:57:28 +00002222 ApiCheck(obj->IsForeign(),
Steve Blocka7e24c12009-10-30 11:49:00 +00002223 "v8::External::Cast()",
2224 "Could not convert to external");
2225}
2226
2227
2228void v8::Object::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002229 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002230 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2231 ApiCheck(obj->IsJSObject(),
2232 "v8::Object::Cast()",
2233 "Could not convert to object");
2234}
2235
2236
2237void v8::Function::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002238 if (IsDeadCheck(i::Isolate::Current(), "v8::Function::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002239 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2240 ApiCheck(obj->IsJSFunction(),
2241 "v8::Function::Cast()",
2242 "Could not convert to function");
2243}
2244
2245
2246void v8::String::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002247 if (IsDeadCheck(i::Isolate::Current(), "v8::String::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002248 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2249 ApiCheck(obj->IsString(),
2250 "v8::String::Cast()",
2251 "Could not convert to string");
2252}
2253
2254
2255void v8::Number::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002256 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002257 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2258 ApiCheck(obj->IsNumber(),
2259 "v8::Number::Cast()",
2260 "Could not convert to number");
2261}
2262
2263
2264void v8::Integer::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002265 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002266 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2267 ApiCheck(obj->IsNumber(),
2268 "v8::Integer::Cast()",
2269 "Could not convert to number");
2270}
2271
2272
2273void v8::Array::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002274 if (IsDeadCheck(i::Isolate::Current(), "v8::Array::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002275 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2276 ApiCheck(obj->IsJSArray(),
2277 "v8::Array::Cast()",
2278 "Could not convert to array");
2279}
2280
2281
2282void v8::Date::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002283 i::Isolate* isolate = i::Isolate::Current();
2284 if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002285 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Steve Block44f0eee2011-05-26 01:26:41 +01002286 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
Steve Blocka7e24c12009-10-30 11:49:00 +00002287 "v8::Date::Cast()",
2288 "Could not convert to date");
2289}
2290
2291
Ben Murdochf87a2032010-10-22 12:50:53 +01002292void v8::RegExp::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002293 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
Ben Murdochf87a2032010-10-22 12:50:53 +01002294 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2295 ApiCheck(obj->IsJSRegExp(),
2296 "v8::RegExp::Cast()",
2297 "Could not convert to regular expression");
2298}
2299
2300
Steve Blocka7e24c12009-10-30 11:49:00 +00002301bool Value::BooleanValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002302 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2303 if (obj->IsBoolean()) {
2304 return obj->IsTrue();
2305 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002306 i::Isolate* isolate = i::Isolate::Current();
2307 if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
2308 LOG_API(isolate, "BooleanValue");
2309 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002310 i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
2311 return value->IsTrue();
2312 }
2313}
2314
2315
2316double Value::NumberValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002317 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2318 i::Handle<i::Object> num;
2319 if (obj->IsNumber()) {
2320 num = obj;
2321 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002322 i::Isolate* isolate = i::Isolate::Current();
2323 if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
2324 return i::OS::nan_value();
2325 }
2326 LOG_API(isolate, "NumberValue");
2327 ENTER_V8(isolate);
2328 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002329 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002330 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002331 }
2332 return num->Number();
2333}
2334
2335
2336int64_t Value::IntegerValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002337 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2338 i::Handle<i::Object> num;
2339 if (obj->IsNumber()) {
2340 num = obj;
2341 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002342 i::Isolate* isolate = i::Isolate::Current();
2343 if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
2344 LOG_API(isolate, "IntegerValue");
2345 ENTER_V8(isolate);
2346 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002347 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002348 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002349 }
2350 if (num->IsSmi()) {
2351 return i::Smi::cast(*num)->value();
2352 } else {
2353 return static_cast<int64_t>(num->Number());
2354 }
2355}
2356
2357
2358Local<Int32> Value::ToInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002359 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2360 i::Handle<i::Object> num;
2361 if (obj->IsSmi()) {
2362 num = obj;
2363 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002364 i::Isolate* isolate = i::Isolate::Current();
2365 if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
2366 LOG_API(isolate, "ToInt32");
2367 ENTER_V8(isolate);
2368 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002369 num = i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002370 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002371 }
2372 return Local<Int32>(ToApi<Int32>(num));
2373}
2374
2375
2376Local<Uint32> Value::ToUint32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002377 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2378 i::Handle<i::Object> num;
2379 if (obj->IsSmi()) {
2380 num = obj;
2381 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002382 i::Isolate* isolate = i::Isolate::Current();
2383 if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
2384 LOG_API(isolate, "ToUInt32");
2385 ENTER_V8(isolate);
2386 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002387 num = i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002388 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002389 }
2390 return Local<Uint32>(ToApi<Uint32>(num));
2391}
2392
2393
2394Local<Uint32> Value::ToArrayIndex() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002395 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2396 if (obj->IsSmi()) {
2397 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2398 return Local<Uint32>();
2399 }
Steve Block44f0eee2011-05-26 01:26:41 +01002400 i::Isolate* isolate = i::Isolate::Current();
2401 if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
2402 LOG_API(isolate, "ToArrayIndex");
2403 ENTER_V8(isolate);
2404 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002405 i::Handle<i::Object> string_obj =
2406 i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002407 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002408 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2409 uint32_t index;
2410 if (str->AsArrayIndex(&index)) {
2411 i::Handle<i::Object> value;
2412 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
2413 value = i::Handle<i::Object>(i::Smi::FromInt(index));
2414 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002415 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002416 }
2417 return Utils::Uint32ToLocal(value);
2418 }
2419 return Local<Uint32>();
2420}
2421
2422
2423int32_t Value::Int32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002424 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2425 if (obj->IsSmi()) {
2426 return i::Smi::cast(*obj)->value();
2427 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002428 i::Isolate* isolate = i::Isolate::Current();
2429 if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
2430 LOG_API(isolate, "Int32Value (slow)");
2431 ENTER_V8(isolate);
2432 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002433 i::Handle<i::Object> num =
2434 i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002435 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002436 if (num->IsSmi()) {
2437 return i::Smi::cast(*num)->value();
2438 } else {
2439 return static_cast<int32_t>(num->Number());
2440 }
2441 }
2442}
2443
2444
2445bool Value::Equals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002446 i::Isolate* isolate = i::Isolate::Current();
2447 if (IsDeadCheck(isolate, "v8::Value::Equals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002448 || EmptyCheck("v8::Value::Equals()", this)
2449 || EmptyCheck("v8::Value::Equals()", that)) {
2450 return false;
2451 }
Steve Block44f0eee2011-05-26 01:26:41 +01002452 LOG_API(isolate, "Equals");
2453 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002454 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2455 i::Handle<i::Object> other = Utils::OpenHandle(*that);
Steve Block1e0659c2011-05-24 12:43:12 +01002456 // If both obj and other are JSObjects, we'd better compare by identity
2457 // immediately when going into JS builtin. The reason is Invoke
2458 // would overwrite global object receiver with global proxy.
2459 if (obj->IsJSObject() && other->IsJSObject()) {
2460 return *obj == *other;
2461 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002462 i::Object** args[1] = { other.location() };
Steve Block44f0eee2011-05-26 01:26:41 +01002463 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002464 i::Handle<i::Object> result =
2465 CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002466 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002467 return *result == i::Smi::FromInt(i::EQUAL);
2468}
2469
2470
2471bool Value::StrictEquals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002472 i::Isolate* isolate = i::Isolate::Current();
2473 if (IsDeadCheck(isolate, "v8::Value::StrictEquals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002474 || EmptyCheck("v8::Value::StrictEquals()", this)
2475 || EmptyCheck("v8::Value::StrictEquals()", that)) {
2476 return false;
2477 }
Steve Block44f0eee2011-05-26 01:26:41 +01002478 LOG_API(isolate, "StrictEquals");
Steve Blocka7e24c12009-10-30 11:49:00 +00002479 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2480 i::Handle<i::Object> other = Utils::OpenHandle(*that);
2481 // Must check HeapNumber first, since NaN !== NaN.
2482 if (obj->IsHeapNumber()) {
2483 if (!other->IsNumber()) return false;
2484 double x = obj->Number();
2485 double y = other->Number();
2486 // Must check explicitly for NaN:s on Windows, but -0 works fine.
2487 return x == y && !isnan(x) && !isnan(y);
2488 } else if (*obj == *other) { // Also covers Booleans.
2489 return true;
2490 } else if (obj->IsSmi()) {
2491 return other->IsNumber() && obj->Number() == other->Number();
2492 } else if (obj->IsString()) {
2493 return other->IsString() &&
2494 i::String::cast(*obj)->Equals(i::String::cast(*other));
2495 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
2496 return other->IsUndefined() || other->IsUndetectableObject();
2497 } else {
2498 return false;
2499 }
2500}
2501
2502
2503uint32_t Value::Uint32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002504 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2505 if (obj->IsSmi()) {
2506 return i::Smi::cast(*obj)->value();
2507 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002508 i::Isolate* isolate = i::Isolate::Current();
2509 if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
2510 LOG_API(isolate, "Uint32Value");
2511 ENTER_V8(isolate);
2512 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002513 i::Handle<i::Object> num =
2514 i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002515 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002516 if (num->IsSmi()) {
2517 return i::Smi::cast(*num)->value();
2518 } else {
2519 return static_cast<uint32_t>(num->Number());
2520 }
2521 }
2522}
2523
2524
2525bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
2526 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002527 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2528 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2529 ENTER_V8(isolate);
2530 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002531 i::Handle<i::Object> self = Utils::OpenHandle(this);
2532 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2533 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002534 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002535 i::Handle<i::Object> obj = i::SetProperty(
2536 self,
2537 key_obj,
2538 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002539 static_cast<PropertyAttributes>(attribs),
2540 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002541 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002542 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002543 return true;
2544}
2545
2546
Steve Block6ded16b2010-05-10 14:33:55 +01002547bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002548 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2549 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2550 ENTER_V8(isolate);
2551 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002552 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2553 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002554 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002555 i::Handle<i::Object> obj = i::SetElement(
2556 self,
2557 index,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002558 value_obj,
2559 i::kNonStrictMode);
Steve Block6ded16b2010-05-10 14:33:55 +01002560 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002561 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Block6ded16b2010-05-10 14:33:55 +01002562 return true;
2563}
2564
2565
Steve Blocka7e24c12009-10-30 11:49:00 +00002566bool v8::Object::ForceSet(v8::Handle<Value> key,
2567 v8::Handle<Value> value,
2568 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002569 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2570 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
2571 ENTER_V8(isolate);
2572 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002573 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2574 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2575 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002576 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002577 i::Handle<i::Object> obj = i::ForceSetProperty(
2578 self,
2579 key_obj,
2580 value_obj,
2581 static_cast<PropertyAttributes>(attribs));
2582 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002583 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002584 return true;
2585}
2586
2587
2588bool v8::Object::ForceDelete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002589 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2590 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
2591 ENTER_V8(isolate);
2592 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002593 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2594 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002595
2596 // When turning on access checks for a global object deoptimize all functions
2597 // as optimized code does not always handle access checks.
2598 i::Deoptimizer::DeoptimizeGlobalObject(*self);
2599
Steve Block44f0eee2011-05-26 01:26:41 +01002600 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002601 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
2602 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002603 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002604 return obj->IsTrue();
2605}
2606
2607
2608Local<Value> v8::Object::Get(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002609 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2610 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2611 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002612 i::Handle<i::Object> self = Utils::OpenHandle(this);
2613 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002614 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002615 i::Handle<i::Object> result = i::GetProperty(self, key_obj);
2616 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002617 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002618 return Utils::ToLocal(result);
2619}
2620
2621
Steve Block6ded16b2010-05-10 14:33:55 +01002622Local<Value> v8::Object::Get(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002623 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2624 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2625 ENTER_V8(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002626 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002627 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002628 i::Handle<i::Object> result = i::GetElement(self, index);
2629 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002630 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Block6ded16b2010-05-10 14:33:55 +01002631 return Utils::ToLocal(result);
2632}
2633
2634
Steve Blocka7e24c12009-10-30 11:49:00 +00002635Local<Value> v8::Object::GetPrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01002636 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2637 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
2638 return Local<v8::Value>());
2639 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002640 i::Handle<i::Object> self = Utils::OpenHandle(this);
2641 i::Handle<i::Object> result = i::GetPrototype(self);
2642 return Utils::ToLocal(result);
2643}
2644
2645
Andrei Popescu402d9372010-02-26 13:31:12 +00002646bool v8::Object::SetPrototype(Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002647 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2648 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
2649 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002650 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2651 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002652 // We do not allow exceptions thrown while setting the prototype
2653 // to propagate outside.
2654 TryCatch try_catch;
Steve Block44f0eee2011-05-26 01:26:41 +01002655 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002656 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2657 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002658 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00002659 return true;
2660}
2661
2662
Steve Blocka7e24c12009-10-30 11:49:00 +00002663Local<Object> v8::Object::FindInstanceInPrototypeChain(
2664 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01002665 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2666 ON_BAILOUT(isolate,
2667 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002668 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01002669 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002670 i::JSObject* object = *Utils::OpenHandle(this);
2671 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2672 while (!object->IsInstanceOf(tmpl_info)) {
2673 i::Object* prototype = object->GetPrototype();
2674 if (!prototype->IsJSObject()) return Local<Object>();
2675 object = i::JSObject::cast(prototype);
2676 }
2677 return Utils::ToLocal(i::Handle<i::JSObject>(object));
2678}
2679
2680
2681Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01002682 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2683 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
2684 return Local<v8::Array>());
2685 ENTER_V8(isolate);
2686 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002687 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2688 i::Handle<i::FixedArray> value =
2689 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
2690 // Because we use caching to speed up enumeration it is important
2691 // to never change the result of the basic enumeration function so
2692 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01002693 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2694 i::Handle<i::JSArray> result =
2695 isolate->factory()->NewJSArrayWithElements(elms);
2696 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00002697}
2698
2699
2700Local<String> v8::Object::ObjectProtoToString() {
Steve Block44f0eee2011-05-26 01:26:41 +01002701 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2702 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
2703 return Local<v8::String>());
2704 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002705 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2706
2707 i::Handle<i::Object> name(self->class_name());
2708
2709 // Native implementation of Object.prototype.toString (v8natives.js):
2710 // var c = %ClassOf(this);
2711 // if (c === 'Arguments') c = 'Object';
2712 // return "[object " + c + "]";
2713
2714 if (!name->IsString()) {
2715 return v8::String::New("[object ]");
2716
2717 } else {
2718 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
2719 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
2720 return v8::String::New("[object Object]");
2721
2722 } else {
2723 const char* prefix = "[object ";
2724 Local<String> str = Utils::ToLocal(class_name);
2725 const char* postfix = "]";
2726
Steve Blockd0582a62009-12-15 09:54:21 +00002727 int prefix_len = i::StrLength(prefix);
2728 int str_len = str->Length();
2729 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00002730
Steve Blockd0582a62009-12-15 09:54:21 +00002731 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01002732 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002733
2734 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01002735 char* ptr = buf.start();
Steve Blocka7e24c12009-10-30 11:49:00 +00002736 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
2737 ptr += prefix_len;
2738
2739 // Write real content.
2740 str->WriteAscii(ptr, 0, str_len);
2741 ptr += str_len;
2742
2743 // Write postfix.
2744 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
2745
2746 // Copy the buffer into a heap-allocated string and return it.
Kristian Monsen25f61362010-05-21 11:50:48 +01002747 Local<String> result = v8::String::New(buf.start(), buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002748 return result;
2749 }
2750 }
2751}
2752
2753
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002754Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01002755 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2756 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
2757 return Local<v8::String>());
2758 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002759 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2760 i::Handle<i::String> name(self->constructor_name());
2761 return Utils::ToLocal(name);
2762}
2763
2764
Steve Blocka7e24c12009-10-30 11:49:00 +00002765bool v8::Object::Delete(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002766 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2767 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
2768 ENTER_V8(isolate);
2769 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002770 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2771 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2772 return i::DeleteProperty(self, key_obj)->IsTrue();
2773}
2774
2775
2776bool v8::Object::Has(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002777 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2778 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
2779 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002780 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2781 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2782 return self->HasProperty(*key_obj);
2783}
2784
2785
2786bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002787 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2788 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
2789 return false);
2790 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002791 HandleScope scope;
2792 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2793 return i::DeleteElement(self, index)->IsTrue();
2794}
2795
2796
2797bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002798 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2799 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002800 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2801 return self->HasElement(index);
2802}
2803
2804
Leon Clarkef7060e22010-06-03 12:02:55 +01002805bool Object::SetAccessor(Handle<String> name,
2806 AccessorGetter getter,
2807 AccessorSetter setter,
2808 v8::Handle<Value> data,
2809 AccessControl settings,
2810 PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01002811 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2812 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
2813 ENTER_V8(isolate);
2814 i::HandleScope scope(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01002815 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
2816 getter, setter, data,
2817 settings, attributes);
2818 i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
2819 return !result.is_null() && !result->IsUndefined();
2820}
2821
2822
Ben Murdoch257744e2011-11-30 15:57:28 +00002823bool v8::Object::HasOwnProperty(Handle<String> key) {
2824 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2825 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
2826 return false);
2827 return Utils::OpenHandle(this)->HasLocalProperty(
2828 *Utils::OpenHandle(*key));
2829}
2830
2831
Steve Blocka7e24c12009-10-30 11:49:00 +00002832bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002833 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2834 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
2835 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002836 return Utils::OpenHandle(this)->HasRealNamedProperty(
2837 *Utils::OpenHandle(*key));
2838}
2839
2840
2841bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002842 ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
2843 "v8::Object::HasRealIndexedProperty()",
2844 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002845 return Utils::OpenHandle(this)->HasRealElementProperty(index);
2846}
2847
2848
2849bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002850 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2851 ON_BAILOUT(isolate,
2852 "v8::Object::HasRealNamedCallbackProperty()",
2853 return false);
2854 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002855 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
2856 *Utils::OpenHandle(*key));
2857}
2858
2859
2860bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002861 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2862 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
2863 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002864 return Utils::OpenHandle(this)->HasNamedInterceptor();
2865}
2866
2867
2868bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002869 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2870 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
2871 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002872 return Utils::OpenHandle(this)->HasIndexedInterceptor();
2873}
2874
2875
Ben Murdoch8b112d22011-06-08 16:22:53 +01002876static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
2877 i::Handle<i::JSObject> receiver,
2878 i::Handle<i::String> name,
2879 i::LookupResult* lookup) {
2880 if (!lookup->IsProperty()) {
2881 // No real property was found.
2882 return Local<Value>();
2883 }
2884
2885 // If the property being looked up is a callback, it can throw
2886 // an exception.
2887 EXCEPTION_PREAMBLE(isolate);
2888 i::Handle<i::Object> result = i::GetProperty(receiver, name, lookup);
2889 has_pending_exception = result.is_null();
2890 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
2891
2892 return Utils::ToLocal(result);
2893}
2894
2895
Steve Blocka7e24c12009-10-30 11:49:00 +00002896Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
2897 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002898 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2899 ON_BAILOUT(isolate,
2900 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002901 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01002902 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002903 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2904 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2905 i::LookupResult lookup;
2906 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002907 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00002908}
2909
2910
2911Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002912 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2913 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
2914 return Local<Value>());
2915 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002916 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2917 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2918 i::LookupResult lookup;
2919 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002920 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00002921}
2922
2923
2924// Turns on access checks by copying the map and setting the check flag.
2925// Because the object gets a new map, existing inline cache caching
2926// the old map of this object will fail.
2927void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01002928 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2929 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
2930 ENTER_V8(isolate);
2931 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002932 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
2933
Ben Murdochb0fe1622011-05-05 13:52:32 +01002934 // When turning on access checks for a global object deoptimize all functions
2935 // as optimized code does not always handle access checks.
2936 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
2937
Steve Blocka7e24c12009-10-30 11:49:00 +00002938 i::Handle<i::Map> new_map =
Steve Block44f0eee2011-05-26 01:26:41 +01002939 isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002940 new_map->set_is_access_check_needed(true);
2941 obj->set_map(*new_map);
2942}
2943
2944
2945bool v8::Object::IsDirty() {
2946 return Utils::OpenHandle(this)->IsDirty();
2947}
2948
2949
2950Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01002951 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2952 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
2953 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002954 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002955 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002956 i::Handle<i::JSObject> result = i::Copy(self);
2957 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002958 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002959 return Utils::ToLocal(result);
2960}
2961
2962
Ben Murdoch8b112d22011-06-08 16:22:53 +01002963static i::Context* GetCreationContext(i::JSObject* object) {
2964 i::Object* constructor = object->map()->constructor();
2965 i::JSFunction* function;
2966 if (!constructor->IsJSFunction()) {
2967 // API functions have null as a constructor,
2968 // but any JSFunction knows its context immediately.
2969 ASSERT(object->IsJSFunction() &&
2970 i::JSFunction::cast(object)->shared()->IsApiFunction());
2971 function = i::JSFunction::cast(object);
2972 } else {
2973 function = i::JSFunction::cast(constructor);
2974 }
2975 return function->context()->global_context();
2976}
2977
2978
2979Local<v8::Context> v8::Object::CreationContext() {
2980 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2981 ON_BAILOUT(isolate,
2982 "v8::Object::CreationContext()", return Local<v8::Context>());
2983 ENTER_V8(isolate);
2984 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2985 i::Context* context = GetCreationContext(*self);
2986 return Utils::ToLocal(i::Handle<i::Context>(context));
2987}
2988
2989
Steve Blocka7e24c12009-10-30 11:49:00 +00002990int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01002991 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2992 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
2993 ENTER_V8(isolate);
2994 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002995 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block1e0659c2011-05-24 12:43:12 +01002996 i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true));
2997 if (!hidden_props_obj->IsJSObject()) {
2998 // We failed to create hidden properties. That's a detached
2999 // global proxy.
3000 ASSERT(hidden_props_obj->IsUndefined());
3001 return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003002 }
Steve Block1e0659c2011-05-24 12:43:12 +01003003 i::Handle<i::JSObject> hidden_props =
3004 i::Handle<i::JSObject>::cast(hidden_props_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01003005 i::Handle<i::String> hash_symbol = isolate->factory()->identity_hash_symbol();
Steve Block1e0659c2011-05-24 12:43:12 +01003006 if (hidden_props->HasLocalProperty(*hash_symbol)) {
3007 i::Handle<i::Object> hash = i::GetProperty(hidden_props, hash_symbol);
3008 CHECK(!hash.is_null());
3009 CHECK(hash->IsSmi());
3010 return i::Smi::cast(*hash)->value();
3011 }
3012
3013 int hash_value;
3014 int attempts = 0;
3015 do {
3016 // Generate a random 32-bit hash value but limit range to fit
3017 // within a smi.
Steve Block44f0eee2011-05-26 01:26:41 +01003018 hash_value = i::V8::Random(self->GetIsolate()) & i::Smi::kMaxValue;
Steve Block1e0659c2011-05-24 12:43:12 +01003019 attempts++;
3020 } while (hash_value == 0 && attempts < 30);
3021 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
3022 CHECK(!i::SetLocalPropertyIgnoreAttributes(
3023 hidden_props,
3024 hash_symbol,
3025 i::Handle<i::Object>(i::Smi::FromInt(hash_value)),
3026 static_cast<PropertyAttributes>(None)).is_null());
3027
Steve Blocka7e24c12009-10-30 11:49:00 +00003028 return hash_value;
3029}
3030
3031
3032bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3033 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003034 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3035 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
3036 ENTER_V8(isolate);
3037 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003038 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3039 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true));
3040 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3041 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003042 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003043 i::Handle<i::Object> obj = i::SetProperty(
3044 hidden_props,
3045 key_obj,
3046 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01003047 static_cast<PropertyAttributes>(None),
3048 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003049 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003050 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003051 return true;
3052}
3053
3054
3055v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003056 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3057 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3058 return Local<v8::Value>());
3059 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003060 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3061 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
3062 if (hidden_props->IsUndefined()) {
3063 return v8::Local<v8::Value>();
3064 }
3065 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01003066 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003067 i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
3068 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003069 EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003070 if (result->IsUndefined()) {
3071 return v8::Local<v8::Value>();
3072 }
3073 return Utils::ToLocal(result);
3074}
3075
3076
3077bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003078 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3079 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
3080 ENTER_V8(isolate);
3081 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003082 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3083 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
3084 if (hidden_props->IsUndefined()) {
3085 return true;
3086 }
3087 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
3088 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3089 return i::DeleteProperty(js_obj, key_obj)->IsTrue();
3090}
3091
3092
Steve Block44f0eee2011-05-26 01:26:41 +01003093namespace {
3094
3095void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3096 void* data,
3097 ExternalArrayType array_type,
3098 int length) {
3099 i::Isolate* isolate = object->GetIsolate();
3100 i::Handle<i::ExternalArray> array =
3101 isolate->factory()->NewExternalArray(length, array_type, data);
3102
3103 // If the object already has external elements, create a new, unique
3104 // map if the element type is now changing, because assumptions about
3105 // generated code based on the receiver's map will be invalid.
3106 i::Handle<i::HeapObject> elements(object->elements());
3107 bool cant_reuse_map =
3108 elements->map()->IsUndefined() ||
3109 !elements->map()->has_external_array_elements() ||
3110 elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
3111 if (cant_reuse_map) {
3112 i::Handle<i::Map> external_array_map =
3113 isolate->factory()->GetExternalArrayElementsMap(
3114 i::Handle<i::Map>(object->map()),
3115 array_type,
3116 object->HasFastProperties());
3117 object->set_map(*external_array_map);
3118 }
3119 object->set_elements(*array);
3120}
3121
3122} // namespace
3123
3124
Steve Blocka7e24c12009-10-30 11:49:00 +00003125void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003126 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3127 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3128 ENTER_V8(isolate);
3129 i::HandleScope scope(isolate);
3130 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
Steve Blocka7e24c12009-10-30 11:49:00 +00003131 "v8::Object::SetIndexedPropertiesToPixelData()",
3132 "length exceeds max acceptable value")) {
3133 return;
3134 }
3135 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3136 if (!ApiCheck(!self->IsJSArray(),
3137 "v8::Object::SetIndexedPropertiesToPixelData()",
3138 "JSArray is not supported")) {
3139 return;
3140 }
Steve Block44f0eee2011-05-26 01:26:41 +01003141 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003142}
3143
3144
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003145bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003146 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003147 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3148 return false);
3149 return self->HasExternalPixelElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003150}
3151
3152
3153uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003154 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003155 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3156 return NULL);
3157 if (self->HasExternalPixelElements()) {
3158 return i::ExternalPixelArray::cast(self->elements())->
3159 external_pixel_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003160 } else {
3161 return NULL;
3162 }
3163}
3164
3165
3166int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003167 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003168 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3169 return -1);
3170 if (self->HasExternalPixelElements()) {
3171 return i::ExternalPixelArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003172 } else {
3173 return -1;
3174 }
3175}
3176
Steve Block3ce2e202009-11-05 08:53:23 +00003177void v8::Object::SetIndexedPropertiesToExternalArrayData(
3178 void* data,
3179 ExternalArrayType array_type,
3180 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003181 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3182 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3183 ENTER_V8(isolate);
3184 i::HandleScope scope(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003185 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3186 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3187 "length exceeds max acceptable value")) {
3188 return;
3189 }
3190 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3191 if (!ApiCheck(!self->IsJSArray(),
3192 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3193 "JSArray is not supported")) {
3194 return;
3195 }
Steve Block44f0eee2011-05-26 01:26:41 +01003196 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003197}
3198
3199
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003200bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003201 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003202 ON_BAILOUT(self->GetIsolate(),
3203 "v8::HasIndexedPropertiesInExternalArrayData()",
3204 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003205 return self->HasExternalArrayElements();
3206}
3207
3208
3209void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003210 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003211 ON_BAILOUT(self->GetIsolate(),
3212 "v8::GetIndexedPropertiesExternalArrayData()",
3213 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003214 if (self->HasExternalArrayElements()) {
3215 return i::ExternalArray::cast(self->elements())->external_pointer();
3216 } else {
3217 return NULL;
3218 }
3219}
3220
3221
3222ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003223 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003224 ON_BAILOUT(self->GetIsolate(),
3225 "v8::GetIndexedPropertiesExternalArrayDataType()",
3226 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003227 switch (self->elements()->map()->instance_type()) {
3228 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3229 return kExternalByteArray;
3230 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3231 return kExternalUnsignedByteArray;
3232 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3233 return kExternalShortArray;
3234 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3235 return kExternalUnsignedShortArray;
3236 case i::EXTERNAL_INT_ARRAY_TYPE:
3237 return kExternalIntArray;
3238 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3239 return kExternalUnsignedIntArray;
3240 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3241 return kExternalFloatArray;
Ben Murdoch257744e2011-11-30 15:57:28 +00003242 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3243 return kExternalDoubleArray;
Steve Block44f0eee2011-05-26 01:26:41 +01003244 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3245 return kExternalPixelArray;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003246 default:
3247 return static_cast<ExternalArrayType>(-1);
3248 }
3249}
3250
3251
3252int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003253 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003254 ON_BAILOUT(self->GetIsolate(),
3255 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3256 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003257 if (self->HasExternalArrayElements()) {
3258 return i::ExternalArray::cast(self->elements())->length();
3259 } else {
3260 return -1;
3261 }
3262}
3263
3264
Ben Murdoch257744e2011-11-30 15:57:28 +00003265bool v8::Object::IsCallable() {
3266 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3267 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3268 ENTER_V8(isolate);
3269 i::HandleScope scope(isolate);
3270 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3271 if (obj->IsJSFunction()) return true;
3272 return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
3273}
3274
3275
3276Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
3277 v8::Handle<v8::Value> argv[]) {
3278 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3279 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3280 return Local<v8::Value>());
3281 LOG_API(isolate, "Object::CallAsFunction");
3282 ENTER_V8(isolate);
3283 i::HandleScope scope(isolate);
3284 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3285 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3286 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3287 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3288 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3289 if (obj->IsJSFunction()) {
3290 fun = i::Handle<i::JSFunction>::cast(obj);
3291 } else {
3292 EXCEPTION_PREAMBLE(isolate);
3293 i::Handle<i::Object> delegate =
3294 i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
3295 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3296 fun = i::Handle<i::JSFunction>::cast(delegate);
3297 recv_obj = obj;
3298 }
3299 EXCEPTION_PREAMBLE(isolate);
3300 i::Handle<i::Object> returned =
3301 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
3302 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3303 return Utils::ToLocal(scope.CloseAndEscape(returned));
3304}
3305
3306
3307Local<v8::Value> Object::CallAsConstructor(int argc,
3308 v8::Handle<v8::Value> argv[]) {
3309 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3310 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3311 return Local<v8::Object>());
3312 LOG_API(isolate, "Object::CallAsConstructor");
3313 ENTER_V8(isolate);
3314 i::HandleScope scope(isolate);
3315 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3316 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3317 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3318 if (obj->IsJSFunction()) {
3319 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
3320 EXCEPTION_PREAMBLE(isolate);
3321 i::Handle<i::Object> returned =
3322 i::Execution::New(fun, argc, args, &has_pending_exception);
3323 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3324 return Utils::ToLocal(scope.CloseAndEscape(
3325 i::Handle<i::JSObject>::cast(returned)));
3326 }
3327 EXCEPTION_PREAMBLE(isolate);
3328 i::Handle<i::Object> delegate =
3329 i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
3330 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3331 if (!delegate->IsUndefined()) {
3332 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
3333 EXCEPTION_PREAMBLE(isolate);
3334 i::Handle<i::Object> returned =
3335 i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
3336 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3337 ASSERT(!delegate->IsUndefined());
3338 return Utils::ToLocal(scope.CloseAndEscape(returned));
3339 }
3340 return Local<v8::Object>();
3341}
3342
3343
Steve Blocka7e24c12009-10-30 11:49:00 +00003344Local<v8::Object> Function::NewInstance() const {
3345 return NewInstance(0, NULL);
3346}
3347
3348
3349Local<v8::Object> Function::NewInstance(int argc,
3350 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003351 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3352 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3353 return Local<v8::Object>());
3354 LOG_API(isolate, "Function::NewInstance");
3355 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003356 HandleScope scope;
3357 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3358 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3359 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003360 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003361 i::Handle<i::Object> returned =
3362 i::Execution::New(function, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003363 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003364 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3365}
3366
3367
3368Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3369 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01003370 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3371 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3372 LOG_API(isolate, "Function::Call");
3373 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003374 i::Object* raw_result = NULL;
3375 {
Steve Block44f0eee2011-05-26 01:26:41 +01003376 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003377 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3378 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3379 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3380 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003381 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003382 i::Handle<i::Object> returned =
3383 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003384 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003385 raw_result = *returned;
3386 }
3387 i::Handle<i::Object> result(raw_result);
3388 return Utils::ToLocal(result);
3389}
3390
3391
3392void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01003393 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3394 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003395 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3396 func->shared()->set_name(*Utils::OpenHandle(*name));
3397}
3398
3399
3400Handle<Value> Function::GetName() const {
3401 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3402 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3403}
3404
3405
Andrei Popescu402d9372010-02-26 13:31:12 +00003406ScriptOrigin Function::GetScriptOrigin() const {
3407 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3408 if (func->shared()->script()->IsScript()) {
3409 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3410 v8::ScriptOrigin origin(
3411 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3412 v8::Integer::New(script->line_offset()->value()),
3413 v8::Integer::New(script->column_offset()->value()));
3414 return origin;
3415 }
3416 return v8::ScriptOrigin(Handle<Value>());
3417}
3418
3419
3420const int Function::kLineOffsetNotFound = -1;
3421
3422
3423int Function::GetScriptLineNumber() const {
3424 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3425 if (func->shared()->script()->IsScript()) {
3426 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3427 return i::GetScriptLineNumber(script, func->shared()->start_position());
3428 }
3429 return kLineOffsetNotFound;
3430}
3431
3432
Steve Blocka7e24c12009-10-30 11:49:00 +00003433int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003434 i::Handle<i::String> str = Utils::OpenHandle(this);
3435 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3436 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003437}
3438
3439
3440int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003441 i::Handle<i::String> str = Utils::OpenHandle(this);
3442 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
3443 return str->Utf8Length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003444}
3445
3446
Steve Block6ded16b2010-05-10 14:33:55 +01003447int String::WriteUtf8(char* buffer,
3448 int capacity,
3449 int* nchars_ref,
3450 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003451 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3452 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3453 LOG_API(isolate, "String::WriteUtf8");
3454 ENTER_V8(isolate);
3455 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003456 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003457 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003458 if (hints & HINT_MANY_WRITES_EXPECTED) {
3459 // Flatten the string for efficiency. This applies whether we are
3460 // using StringInputBuffer or Get(i) to access the characters.
3461 str->TryFlatten();
3462 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003463 write_input_buffer.Reset(0, *str);
3464 int len = str->length();
3465 // Encode the first K - 3 bytes directly into the buffer since we
3466 // know there's room for them. If no capacity is given we copy all
3467 // of them here.
3468 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3469 int i;
3470 int pos = 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003471 int nchars = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003472 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3473 i::uc32 c = write_input_buffer.GetNext();
3474 int written = unibrow::Utf8::Encode(buffer + pos, c);
3475 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003476 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003477 }
3478 if (i < len) {
3479 // For the last characters we need to check the length for each one
3480 // because they may be longer than the remaining space in the
3481 // buffer.
3482 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3483 for (; i < len && pos < capacity; i++) {
3484 i::uc32 c = write_input_buffer.GetNext();
3485 int written = unibrow::Utf8::Encode(intermediate, c);
3486 if (pos + written <= capacity) {
3487 for (int j = 0; j < written; j++)
3488 buffer[pos + j] = intermediate[j];
3489 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003490 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003491 } else {
3492 // We've reached the end of the buffer
3493 break;
3494 }
3495 }
3496 }
Steve Block6ded16b2010-05-10 14:33:55 +01003497 if (nchars_ref != NULL) *nchars_ref = nchars;
Steve Blocka7e24c12009-10-30 11:49:00 +00003498 if (i == len && (capacity == -1 || pos < capacity))
3499 buffer[pos++] = '\0';
3500 return pos;
3501}
3502
3503
Steve Block6ded16b2010-05-10 14:33:55 +01003504int String::WriteAscii(char* buffer,
3505 int start,
3506 int length,
3507 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003508 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3509 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3510 LOG_API(isolate, "String::WriteAscii");
3511 ENTER_V8(isolate);
3512 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003513 ASSERT(start >= 0 && length >= -1);
3514 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003515 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003516 if (hints & HINT_MANY_WRITES_EXPECTED) {
3517 // Flatten the string for efficiency. This applies whether we are
3518 // using StringInputBuffer or Get(i) to access the characters.
3519 str->TryFlatten();
3520 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003521 int end = length;
3522 if ( (length == -1) || (length > str->length() - start) )
3523 end = str->length() - start;
3524 if (end < 0) return 0;
3525 write_input_buffer.Reset(start, *str);
3526 int i;
3527 for (i = 0; i < end; i++) {
3528 char c = static_cast<char>(write_input_buffer.GetNext());
3529 if (c == '\0') c = ' ';
3530 buffer[i] = c;
3531 }
3532 if (length == -1 || i < length)
3533 buffer[i] = '\0';
3534 return i;
3535}
3536
3537
Steve Block6ded16b2010-05-10 14:33:55 +01003538int String::Write(uint16_t* buffer,
3539 int start,
3540 int length,
3541 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003542 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3543 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
3544 LOG_API(isolate, "String::Write");
3545 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003546 ASSERT(start >= 0 && length >= -1);
3547 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003548 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003549 if (hints & HINT_MANY_WRITES_EXPECTED) {
3550 // Flatten the string for efficiency. This applies whether we are
3551 // using StringInputBuffer or Get(i) to access the characters.
3552 str->TryFlatten();
3553 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003554 int end = start + length;
3555 if ((length == -1) || (length > str->length() - start) )
3556 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003557 if (end < 0) return 0;
3558 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003559 if (length == -1 || end - start < length) {
3560 buffer[end - start] = '\0';
3561 }
3562 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003563}
3564
3565
3566bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003567 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003568 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
3569 return false;
3570 }
3571 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
Steve Blocka7e24c12009-10-30 11:49:00 +00003572 return i::StringShape(*str).IsExternalTwoByte();
3573}
3574
3575
3576bool v8::String::IsExternalAscii() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003577 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003578 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
3579 return false;
3580 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003581 return i::StringShape(*str).IsExternalAscii();
3582}
3583
3584
3585void v8::String::VerifyExternalStringResource(
3586 v8::String::ExternalStringResource* value) const {
3587 i::Handle<i::String> str = Utils::OpenHandle(this);
3588 v8::String::ExternalStringResource* expected;
3589 if (i::StringShape(*str).IsExternalTwoByte()) {
3590 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
3591 expected = reinterpret_cast<ExternalStringResource*>(resource);
3592 } else {
3593 expected = NULL;
3594 }
3595 CHECK_EQ(expected, value);
3596}
3597
3598
3599v8::String::ExternalAsciiStringResource*
3600 v8::String::GetExternalAsciiStringResource() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003601 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003602 if (IsDeadCheck(str->GetIsolate(),
3603 "v8::String::GetExternalAsciiStringResource()")) {
3604 return NULL;
3605 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003606 if (i::StringShape(*str).IsExternalAscii()) {
3607 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
3608 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
3609 } else {
3610 return NULL;
3611 }
3612}
3613
3614
3615double Number::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003616 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003617 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3618 return obj->Number();
3619}
3620
3621
3622bool Boolean::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003623 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003624 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3625 return obj->IsTrue();
3626}
3627
3628
3629int64_t Integer::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003630 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003631 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3632 if (obj->IsSmi()) {
3633 return i::Smi::cast(*obj)->value();
3634 } else {
3635 return static_cast<int64_t>(obj->Number());
3636 }
3637}
3638
3639
3640int32_t Int32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003641 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003642 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3643 if (obj->IsSmi()) {
3644 return i::Smi::cast(*obj)->value();
3645 } else {
3646 return static_cast<int32_t>(obj->Number());
3647 }
3648}
3649
3650
Steve Block6ded16b2010-05-10 14:33:55 +01003651uint32_t Uint32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003652 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003653 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3654 if (obj->IsSmi()) {
3655 return i::Smi::cast(*obj)->value();
3656 } else {
3657 return static_cast<uint32_t>(obj->Number());
3658 }
3659}
3660
3661
Steve Blocka7e24c12009-10-30 11:49:00 +00003662int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003663 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003664 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
3665 return 0;
3666 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003667 return obj->GetInternalFieldCount();
3668}
3669
3670
3671Local<Value> v8::Object::CheckedGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003672 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003673 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
3674 return Local<Value>();
3675 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003676 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3677 "v8::Object::GetInternalField()",
3678 "Reading internal field out of bounds")) {
3679 return Local<Value>();
3680 }
3681 i::Handle<i::Object> value(obj->GetInternalField(index));
3682 Local<Value> result = Utils::ToLocal(value);
3683#ifdef DEBUG
3684 Local<Value> unchecked = UncheckedGetInternalField(index);
3685 ASSERT(unchecked.IsEmpty() || (unchecked == result));
3686#endif
3687 return result;
3688}
3689
3690
3691void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003692 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003693 i::Isolate* isolate = obj->GetIsolate();
3694 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
3695 return;
3696 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003697 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3698 "v8::Object::SetInternalField()",
3699 "Writing internal field out of bounds")) {
3700 return;
3701 }
Steve Block44f0eee2011-05-26 01:26:41 +01003702 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003703 i::Handle<i::Object> val = Utils::OpenHandle(*value);
3704 obj->SetInternalField(index, *val);
3705}
3706
3707
Ben Murdochb8e0da22011-05-16 14:20:40 +01003708static bool CanBeEncodedAsSmi(void* ptr) {
Steve Block1e0659c2011-05-24 12:43:12 +01003709 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003710 return ((address & i::kEncodablePointerMask) == 0);
3711}
3712
3713
3714static i::Smi* EncodeAsSmi(void* ptr) {
3715 ASSERT(CanBeEncodedAsSmi(ptr));
Steve Block1e0659c2011-05-24 12:43:12 +01003716 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003717 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
3718 ASSERT(i::Internals::HasSmiTag(result));
3719 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
3720 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
3721 return result;
3722}
3723
3724
Steve Blocka7e24c12009-10-30 11:49:00 +00003725void v8::Object::SetPointerInInternalField(int index, void* value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003726 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3727 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003728 if (CanBeEncodedAsSmi(value)) {
3729 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
3730 } else {
3731 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00003732 i::Handle<i::Foreign> foreign =
3733 isolate->factory()->NewForeign(
Steve Block44f0eee2011-05-26 01:26:41 +01003734 reinterpret_cast<i::Address>(value), i::TENURED);
Ben Murdoch257744e2011-11-30 15:57:28 +00003735 if (!foreign.is_null())
3736 Utils::OpenHandle(this)->SetInternalField(index, *foreign);
Steve Block3ce2e202009-11-05 08:53:23 +00003737 }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003738 ASSERT_EQ(value, GetPointerFromInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003739}
3740
3741
3742// --- E n v i r o n m e n t ---
3743
Steve Block44f0eee2011-05-26 01:26:41 +01003744
Steve Blocka7e24c12009-10-30 11:49:00 +00003745bool v8::V8::Initialize() {
Steve Block44f0eee2011-05-26 01:26:41 +01003746 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
3747 if (isolate != NULL && isolate->IsInitialized()) {
3748 return true;
3749 }
3750 return InitializeHelper();
Steve Blocka7e24c12009-10-30 11:49:00 +00003751}
3752
3753
3754bool v8::V8::Dispose() {
Steve Block44f0eee2011-05-26 01:26:41 +01003755 i::Isolate* isolate = i::Isolate::Current();
3756 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
3757 "v8::V8::Dispose()",
3758 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
3759 return false;
3760 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003761 i::V8::TearDown();
3762 return true;
3763}
3764
3765
Russell Brenner90bac252010-11-18 13:33:46 -08003766HeapStatistics::HeapStatistics(): total_heap_size_(0),
3767 total_heap_size_executable_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01003768 used_heap_size_(0),
3769 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00003770
3771
3772void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
Steve Block44f0eee2011-05-26 01:26:41 +01003773 i::Heap* heap = i::Isolate::Current()->heap();
3774 heap_statistics->set_total_heap_size(heap->CommittedMemory());
Russell Brenner90bac252010-11-18 13:33:46 -08003775 heap_statistics->set_total_heap_size_executable(
Steve Block44f0eee2011-05-26 01:26:41 +01003776 heap->CommittedMemoryExecutable());
3777 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
3778 heap_statistics->set_heap_size_limit(heap->MaxReserved());
Steve Block3ce2e202009-11-05 08:53:23 +00003779}
3780
3781
3782bool v8::V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003783 // Returning true tells the caller that it need not
3784 // continue to call IdleNotification.
Steve Block44f0eee2011-05-26 01:26:41 +01003785 if (!i::Isolate::Current()->IsInitialized()) return true;
Steve Block3ce2e202009-11-05 08:53:23 +00003786 return i::V8::IdleNotification();
Steve Blocka7e24c12009-10-30 11:49:00 +00003787}
3788
3789
3790void v8::V8::LowMemoryNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003791 i::Isolate* isolate = i::Isolate::Current();
3792 if (!isolate->IsInitialized()) return;
3793 isolate->heap()->CollectAllGarbage(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003794}
3795
3796
Steve Block6ded16b2010-05-10 14:33:55 +01003797int v8::V8::ContextDisposedNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003798 i::Isolate* isolate = i::Isolate::Current();
3799 if (!isolate->IsInitialized()) return 0;
3800 return isolate->heap()->NotifyContextDisposed();
Steve Block6ded16b2010-05-10 14:33:55 +01003801}
3802
3803
Steve Blocka7e24c12009-10-30 11:49:00 +00003804const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01003805 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00003806}
3807
3808
3809static i::Handle<i::FunctionTemplateInfo>
3810 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
3811 if (templ->constructor()->IsUndefined()) {
3812 Local<FunctionTemplate> constructor = FunctionTemplate::New();
3813 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
3814 templ->set_constructor(*Utils::OpenHandle(*constructor));
3815 }
3816 return i::Handle<i::FunctionTemplateInfo>(
3817 i::FunctionTemplateInfo::cast(templ->constructor()));
3818}
3819
3820
3821Persistent<Context> v8::Context::New(
3822 v8::ExtensionConfiguration* extensions,
3823 v8::Handle<ObjectTemplate> global_template,
3824 v8::Handle<Value> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01003825 i::Isolate* isolate = i::Isolate::Current();
3826 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
3827 LOG_API(isolate, "Context::New");
3828 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003829
3830 // Enter V8 via an ENTER_V8 scope.
3831 i::Handle<i::Context> env;
3832 {
Steve Block44f0eee2011-05-26 01:26:41 +01003833 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003834 v8::Handle<ObjectTemplate> proxy_template = global_template;
3835 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
3836 i::Handle<i::FunctionTemplateInfo> global_constructor;
3837
3838 if (!global_template.IsEmpty()) {
3839 // Make sure that the global_template has a constructor.
3840 global_constructor =
3841 EnsureConstructor(Utils::OpenHandle(*global_template));
3842
3843 // Create a fresh template for the global proxy object.
3844 proxy_template = ObjectTemplate::New();
3845 proxy_constructor =
3846 EnsureConstructor(Utils::OpenHandle(*proxy_template));
3847
3848 // Set the global template to be the prototype template of
3849 // global proxy template.
3850 proxy_constructor->set_prototype_template(
3851 *Utils::OpenHandle(*global_template));
3852
3853 // Migrate security handlers from global_template to
3854 // proxy_template. Temporarily removing access check
3855 // information from the global template.
3856 if (!global_constructor->access_check_info()->IsUndefined()) {
3857 proxy_constructor->set_access_check_info(
3858 global_constructor->access_check_info());
3859 proxy_constructor->set_needs_access_check(
3860 global_constructor->needs_access_check());
3861 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01003862 global_constructor->set_access_check_info(
3863 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003864 }
3865 }
3866
3867 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01003868 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdoch257744e2011-11-30 15:57:28 +00003869 isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00003870 Utils::OpenHandle(*global_object),
3871 proxy_template,
3872 extensions);
3873
3874 // Restore the access check info on the global template.
3875 if (!global_template.IsEmpty()) {
3876 ASSERT(!global_constructor.is_null());
3877 ASSERT(!proxy_constructor.is_null());
3878 global_constructor->set_access_check_info(
3879 proxy_constructor->access_check_info());
3880 global_constructor->set_needs_access_check(
3881 proxy_constructor->needs_access_check());
3882 }
Steve Block44f0eee2011-05-26 01:26:41 +01003883 isolate->runtime_profiler()->Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +00003884 }
3885 // Leave V8.
3886
3887 if (env.is_null())
3888 return Persistent<Context>();
3889 return Persistent<Context>(Utils::ToLocal(env));
3890}
3891
3892
3893void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01003894 i::Isolate* isolate = i::Isolate::Current();
3895 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
3896 return;
3897 }
3898 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003899 i::Handle<i::Context> env = Utils::OpenHandle(this);
3900 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
3901 env->set_security_token(*token_handle);
3902}
3903
3904
3905void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003906 i::Isolate* isolate = i::Isolate::Current();
3907 if (IsDeadCheck(isolate,
3908 "v8::Context::UseDefaultSecurityToken()")) {
3909 return;
3910 }
3911 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003912 i::Handle<i::Context> env = Utils::OpenHandle(this);
3913 env->set_security_token(env->global());
3914}
3915
3916
3917Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003918 i::Isolate* isolate = i::Isolate::Current();
3919 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
3920 return Handle<Value>();
3921 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003922 i::Handle<i::Context> env = Utils::OpenHandle(this);
3923 i::Object* security_token = env->security_token();
3924 i::Handle<i::Object> token_handle(security_token);
3925 return Utils::ToLocal(token_handle);
3926}
3927
3928
3929bool Context::HasOutOfMemoryException() {
3930 i::Handle<i::Context> env = Utils::OpenHandle(this);
3931 return env->has_out_of_memory();
3932}
3933
3934
3935bool Context::InContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01003936 return i::Isolate::Current()->context() != NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00003937}
3938
3939
3940v8::Local<v8::Context> Context::GetEntered() {
Steve Block44f0eee2011-05-26 01:26:41 +01003941 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00003942 if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
Steve Block44f0eee2011-05-26 01:26:41 +01003943 return Local<Context>();
3944 }
3945 i::Handle<i::Object> last =
3946 isolate->handle_scope_implementer()->LastEnteredContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003947 if (last.is_null()) return Local<Context>();
3948 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
3949 return Utils::ToLocal(context);
3950}
3951
3952
3953v8::Local<v8::Context> Context::GetCurrent() {
Steve Block44f0eee2011-05-26 01:26:41 +01003954 i::Isolate* isolate = i::Isolate::Current();
3955 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
3956 return Local<Context>();
3957 }
3958 i::Handle<i::Object> current = isolate->global_context();
Steve Block3ce2e202009-11-05 08:53:23 +00003959 if (current.is_null()) return Local<Context>();
3960 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
Steve Blocka7e24c12009-10-30 11:49:00 +00003961 return Utils::ToLocal(context);
3962}
3963
3964
3965v8::Local<v8::Context> Context::GetCalling() {
Steve Block44f0eee2011-05-26 01:26:41 +01003966 i::Isolate* isolate = i::Isolate::Current();
3967 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
3968 return Local<Context>();
3969 }
3970 i::Handle<i::Object> calling =
3971 isolate->GetCallingGlobalContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003972 if (calling.is_null()) return Local<Context>();
3973 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
3974 return Utils::ToLocal(context);
3975}
3976
3977
3978v8::Local<v8::Object> Context::Global() {
Steve Block44f0eee2011-05-26 01:26:41 +01003979 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
3980 return Local<v8::Object>();
3981 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003982 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3983 i::Handle<i::Context> context =
3984 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
3985 i::Handle<i::Object> global(context->global_proxy());
3986 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
3987}
3988
3989
3990void Context::DetachGlobal() {
Steve Block44f0eee2011-05-26 01:26:41 +01003991 i::Isolate* isolate = i::Isolate::Current();
3992 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
3993 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003994 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3995 i::Handle<i::Context> context =
3996 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01003997 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00003998}
3999
4000
Andrei Popescu74b3c142010-03-29 12:03:09 +01004001void Context::ReattachGlobal(Handle<Object> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01004002 i::Isolate* isolate = i::Isolate::Current();
4003 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
4004 ENTER_V8(isolate);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004005 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4006 i::Handle<i::Context> context =
4007 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01004008 isolate->bootstrapper()->ReattachGlobal(
4009 context,
4010 Utils::OpenHandle(*global_object));
4011}
4012
4013
Ben Murdoch257744e2011-11-30 15:57:28 +00004014void Context::AllowCodeGenerationFromStrings(bool allow) {
4015 i::Isolate* isolate = i::Isolate::Current();
4016 if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
4017 return;
4018 }
4019 ENTER_V8(isolate);
4020 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4021 i::Handle<i::Context> context =
4022 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4023 context->set_allow_code_gen_from_strings(
4024 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
4025}
4026
4027
Steve Block44f0eee2011-05-26 01:26:41 +01004028void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
4029 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004030}
4031
4032
Steve Blocka7e24c12009-10-30 11:49:00 +00004033Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01004034 i::Isolate* isolate = i::Isolate::Current();
4035 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
4036 return Local<v8::Object>());
4037 LOG_API(isolate, "ObjectTemplate::NewInstance");
4038 ENTER_V8(isolate);
4039 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004040 i::Handle<i::Object> obj =
4041 i::Execution::InstantiateObject(Utils::OpenHandle(this),
4042 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004043 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004044 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
4045}
4046
4047
4048Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01004049 i::Isolate* isolate = i::Isolate::Current();
4050 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00004051 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01004052 LOG_API(isolate, "FunctionTemplate::GetFunction");
4053 ENTER_V8(isolate);
4054 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004055 i::Handle<i::Object> obj =
4056 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
4057 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004058 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004059 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
4060}
4061
4062
4063bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004064 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
4065 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004066 i::Object* obj = *Utils::OpenHandle(*value);
4067 return obj->IsInstanceOf(*Utils::OpenHandle(this));
4068}
4069
4070
4071static Local<External> ExternalNewImpl(void* data) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004072 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004073}
4074
4075static void* ExternalValueImpl(i::Handle<i::Object> obj) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004076 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->address());
Steve Blocka7e24c12009-10-30 11:49:00 +00004077}
4078
4079
Steve Blocka7e24c12009-10-30 11:49:00 +00004080Local<Value> v8::External::Wrap(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004081 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004082 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Ben Murdoch6d7cb002011-08-04 19:25:22 +01004083 LOG_API(isolate, "External::Wrap");
Ben Murdoch257744e2011-11-30 15:57:28 +00004084 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
Steve Block44f0eee2011-05-26 01:26:41 +01004085 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004086
4087 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
4088 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
4089 : v8::Local<v8::Value>(ExternalNewImpl(data));
4090
4091 ASSERT_EQ(data, Unwrap(result));
4092 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004093}
4094
4095
Steve Block3ce2e202009-11-05 08:53:23 +00004096void* v8::Object::SlowGetPointerFromInternalField(int index) {
4097 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4098 i::Object* value = obj->GetInternalField(index);
4099 if (value->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004100 return i::Internals::GetExternalPointerFromSmi(value);
Ben Murdoch257744e2011-11-30 15:57:28 +00004101 } else if (value->IsForeign()) {
4102 return reinterpret_cast<void*>(i::Foreign::cast(value)->address());
Steve Block3ce2e202009-11-05 08:53:23 +00004103 } else {
4104 return NULL;
4105 }
4106}
4107
4108
Steve Blocka7e24c12009-10-30 11:49:00 +00004109void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
Steve Block44f0eee2011-05-26 01:26:41 +01004110 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004111 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
4112 void* result;
4113 if (obj->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004114 result = i::Internals::GetExternalPointerFromSmi(*obj);
Ben Murdoch257744e2011-11-30 15:57:28 +00004115 } else if (obj->IsForeign()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004116 result = ExternalValueImpl(obj);
4117 } else {
4118 result = NULL;
4119 }
4120 ASSERT_EQ(result, QuickUnwrap(wrapper));
4121 return result;
4122}
4123
4124
4125Local<External> v8::External::New(void* data) {
4126 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01004127 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch6d7cb002011-08-04 19:25:22 +01004128 LOG_API(isolate, "External::New");
Ben Murdoch257744e2011-11-30 15:57:28 +00004129 EnsureInitializedForIsolate(isolate, "v8::External::New()");
Steve Block44f0eee2011-05-26 01:26:41 +01004130 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004131 return ExternalNewImpl(data);
4132}
4133
4134
4135void* External::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004136 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004137 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4138 return ExternalValueImpl(obj);
4139}
4140
4141
4142Local<String> v8::String::Empty() {
Steve Block44f0eee2011-05-26 01:26:41 +01004143 i::Isolate* isolate = i::Isolate::Current();
4144 EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
4145 LOG_API(isolate, "String::Empty()");
4146 return Utils::ToLocal(isolate->factory()->empty_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00004147}
4148
4149
4150Local<String> v8::String::New(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004151 i::Isolate* isolate = i::Isolate::Current();
4152 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4153 LOG_API(isolate, "String::New(char)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004154 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004155 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004156 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004157 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004158 isolate->factory()->NewStringFromUtf8(
4159 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004160 return Utils::ToLocal(result);
4161}
4162
4163
Steve Block3ce2e202009-11-05 08:53:23 +00004164Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00004165 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01004166 i::Isolate* isolate = left_string->GetIsolate();
4167 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4168 LOG_API(isolate, "String::New(char)");
4169 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00004170 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Steve Block44f0eee2011-05-26 01:26:41 +01004171 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
4172 right_string);
Steve Block3ce2e202009-11-05 08:53:23 +00004173 return Utils::ToLocal(result);
4174}
4175
4176
Steve Blocka7e24c12009-10-30 11:49:00 +00004177Local<String> v8::String::NewUndetectable(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004178 i::Isolate* isolate = i::Isolate::Current();
4179 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4180 LOG_API(isolate, "String::NewUndetectable(char)");
4181 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004182 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004183 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004184 isolate->factory()->NewStringFromUtf8(
4185 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004186 result->MarkAsUndetectable();
4187 return Utils::ToLocal(result);
4188}
4189
4190
4191static int TwoByteStringLength(const uint16_t* data) {
4192 int length = 0;
4193 while (data[length] != '\0') length++;
4194 return length;
4195}
4196
4197
4198Local<String> v8::String::New(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004199 i::Isolate* isolate = i::Isolate::Current();
4200 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4201 LOG_API(isolate, "String::New(uint16_)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004202 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004203 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004204 if (length == -1) length = TwoByteStringLength(data);
4205 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004206 isolate->factory()->NewStringFromTwoByte(
4207 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004208 return Utils::ToLocal(result);
4209}
4210
4211
4212Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004213 i::Isolate* isolate = i::Isolate::Current();
4214 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4215 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4216 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004217 if (length == -1) length = TwoByteStringLength(data);
4218 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004219 isolate->factory()->NewStringFromTwoByte(
4220 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004221 result->MarkAsUndetectable();
4222 return Utils::ToLocal(result);
4223}
4224
4225
Steve Block44f0eee2011-05-26 01:26:41 +01004226i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004227 v8::String::ExternalStringResource* resource) {
4228 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004229 isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004230 return result;
4231}
4232
4233
Steve Block44f0eee2011-05-26 01:26:41 +01004234i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004235 v8::String::ExternalAsciiStringResource* resource) {
4236 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004237 isolate->factory()->NewExternalStringFromAscii(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004238 return result;
4239}
4240
4241
Steve Blocka7e24c12009-10-30 11:49:00 +00004242Local<String> v8::String::NewExternal(
4243 v8::String::ExternalStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004244 i::Isolate* isolate = i::Isolate::Current();
4245 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4246 LOG_API(isolate, "String::NewExternal");
4247 ENTER_V8(isolate);
4248 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4249 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004250 return Utils::ToLocal(result);
4251}
4252
4253
4254bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004255 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004256 i::Isolate* isolate = obj->GetIsolate();
4257 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4258 if (i::StringShape(*obj).IsExternalTwoByte()) {
4259 return false; // Already an external string.
4260 }
4261 ENTER_V8(isolate);
4262 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4263 return false;
4264 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004265 bool result = obj->MakeExternal(resource);
4266 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004267 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004268 }
4269 return result;
4270}
4271
4272
4273Local<String> v8::String::NewExternal(
4274 v8::String::ExternalAsciiStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004275 i::Isolate* isolate = i::Isolate::Current();
4276 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4277 LOG_API(isolate, "String::NewExternal");
4278 ENTER_V8(isolate);
4279 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4280 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004281 return Utils::ToLocal(result);
4282}
4283
4284
4285bool v8::String::MakeExternal(
4286 v8::String::ExternalAsciiStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004287 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004288 i::Isolate* isolate = obj->GetIsolate();
4289 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4290 if (i::StringShape(*obj).IsExternalTwoByte()) {
4291 return false; // Already an external string.
4292 }
4293 ENTER_V8(isolate);
4294 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4295 return false;
4296 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004297 bool result = obj->MakeExternal(resource);
4298 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004299 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004300 }
4301 return result;
4302}
4303
4304
4305bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004306 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004307 i::Isolate* isolate = obj->GetIsolate();
4308 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4309 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4310 return false;
4311 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004312 int size = obj->Size(); // Byte size of the original string.
4313 if (size < i::ExternalString::kSize)
4314 return false;
4315 i::StringShape shape(*obj);
4316 return !shape.IsExternal();
4317}
4318
4319
4320Local<v8::Object> v8::Object::New() {
Steve Block44f0eee2011-05-26 01:26:41 +01004321 i::Isolate* isolate = i::Isolate::Current();
4322 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4323 LOG_API(isolate, "Object::New");
4324 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004325 i::Handle<i::JSObject> obj =
Steve Block44f0eee2011-05-26 01:26:41 +01004326 isolate->factory()->NewJSObject(isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00004327 return Utils::ToLocal(obj);
4328}
4329
4330
4331Local<v8::Value> v8::Date::New(double time) {
Steve Block44f0eee2011-05-26 01:26:41 +01004332 i::Isolate* isolate = i::Isolate::Current();
4333 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4334 LOG_API(isolate, "Date::New");
Steve Blockd0582a62009-12-15 09:54:21 +00004335 if (isnan(time)) {
4336 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4337 time = i::OS::nan_value();
4338 }
Steve Block44f0eee2011-05-26 01:26:41 +01004339 ENTER_V8(isolate);
4340 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004341 i::Handle<i::Object> obj =
4342 i::Execution::NewDate(time, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004343 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004344 return Utils::ToLocal(obj);
4345}
4346
4347
4348double v8::Date::NumberValue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004349 i::Isolate* isolate = i::Isolate::Current();
4350 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4351 LOG_API(isolate, "Date::NumberValue");
Steve Blocka7e24c12009-10-30 11:49:00 +00004352 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4353 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4354 return jsvalue->value()->Number();
4355}
4356
4357
Ben Murdochb0fe1622011-05-05 13:52:32 +01004358void v8::Date::DateTimeConfigurationChangeNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004359 i::Isolate* isolate = i::Isolate::Current();
4360 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4361 return);
4362 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
4363 ENTER_V8(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004364
Steve Block44f0eee2011-05-26 01:26:41 +01004365 i::HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004366 // Get the function ResetDateCache (defined in date-delay.js).
4367 i::Handle<i::String> func_name_str =
Steve Block44f0eee2011-05-26 01:26:41 +01004368 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4369 i::MaybeObject* result =
4370 isolate->js_builtins_object()->GetProperty(*func_name_str);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004371 i::Object* object_func;
4372 if (!result->ToObject(&object_func)) {
4373 return;
4374 }
4375
4376 if (object_func->IsJSFunction()) {
4377 i::Handle<i::JSFunction> func =
4378 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4379
4380 // Call ResetDateCache(0 but expect no exceptions:
4381 bool caught_exception = false;
Ben Murdoch8b112d22011-06-08 16:22:53 +01004382 i::Execution::TryCall(func,
4383 isolate->js_builtins_object(),
4384 0,
4385 NULL,
4386 &caught_exception);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004387 }
4388}
4389
4390
Ben Murdochf87a2032010-10-22 12:50:53 +01004391static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4392 char flags_buf[3];
4393 int num_flags = 0;
4394 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4395 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4396 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4397 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
Steve Block44f0eee2011-05-26 01:26:41 +01004398 return FACTORY->LookupSymbol(
Ben Murdochf87a2032010-10-22 12:50:53 +01004399 i::Vector<const char>(flags_buf, num_flags));
4400}
4401
4402
4403Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4404 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01004405 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
4406 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
4407 LOG_API(isolate, "RegExp::New");
4408 ENTER_V8(isolate);
4409 EXCEPTION_PREAMBLE(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01004410 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
4411 Utils::OpenHandle(*pattern),
4412 RegExpFlagsToString(flags),
4413 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004414 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01004415 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
4416}
4417
4418
4419Local<v8::String> v8::RegExp::GetSource() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004420 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4421 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
4422 return Local<v8::String>();
4423 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004424 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4425 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
4426}
4427
4428
4429// Assert that the static flags cast in GetFlags is valid.
4430#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
4431 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
4432 static_cast<int>(i::JSRegExp::internal_flag))
4433REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
4434REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
4435REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
4436REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
4437#undef REGEXP_FLAG_ASSERT_EQ
4438
4439v8::RegExp::Flags v8::RegExp::GetFlags() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004440 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
4441 return v8::RegExp::kNone;
4442 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004443 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4444 return static_cast<RegExp::Flags>(obj->GetFlags().value());
4445}
4446
4447
Steve Blocka7e24c12009-10-30 11:49:00 +00004448Local<v8::Array> v8::Array::New(int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004449 i::Isolate* isolate = i::Isolate::Current();
4450 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
4451 LOG_API(isolate, "Array::New");
4452 ENTER_V8(isolate);
4453 int real_length = length > 0 ? length : 0;
4454 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004455 i::Handle<i::Object> length_obj =
4456 isolate->factory()->NewNumberFromInt(real_length);
4457 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004458 return Utils::ToLocal(obj);
4459}
4460
4461
4462uint32_t v8::Array::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004463 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4464 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004465 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
4466 i::Object* length = obj->length();
4467 if (length->IsSmi()) {
4468 return i::Smi::cast(length)->value();
4469 } else {
4470 return static_cast<uint32_t>(length->Number());
4471 }
4472}
4473
4474
4475Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01004476 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4477 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004478 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
4479 if (!self->HasFastElements()) {
4480 return Local<Object>();
4481 }
4482 i::FixedArray* elms = i::FixedArray::cast(self->elements());
4483 i::Object* paragon = elms->get(index);
4484 if (!paragon->IsJSObject()) {
4485 return Local<Object>();
4486 }
4487 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01004488 EXCEPTION_PREAMBLE(isolate);
4489 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004490 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
4491 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01004492 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004493 return Utils::ToLocal(result);
4494}
4495
4496
4497Local<String> v8::String::NewSymbol(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004498 i::Isolate* isolate = i::Isolate::Current();
4499 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
4500 LOG_API(isolate, "String::NewSymbol(char)");
4501 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004502 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004503 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004504 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004505 return Utils::ToLocal(result);
4506}
4507
4508
4509Local<Number> v8::Number::New(double value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004510 i::Isolate* isolate = i::Isolate::Current();
4511 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
Steve Blockd0582a62009-12-15 09:54:21 +00004512 if (isnan(value)) {
4513 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4514 value = i::OS::nan_value();
4515 }
Steve Block44f0eee2011-05-26 01:26:41 +01004516 ENTER_V8(isolate);
4517 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004518 return Utils::NumberToLocal(result);
4519}
4520
4521
4522Local<Integer> v8::Integer::New(int32_t value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004523 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4524 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004525 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004526 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
4527 isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004528 }
Steve Block44f0eee2011-05-26 01:26:41 +01004529 ENTER_V8(isolate);
4530 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004531 return Utils::IntegerToLocal(result);
4532}
4533
4534
Steve Block3ce2e202009-11-05 08:53:23 +00004535Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
4536 bool fits_into_int32_t = (value & (1 << 31)) == 0;
4537 if (fits_into_int32_t) {
4538 return Integer::New(static_cast<int32_t>(value));
4539 }
Steve Block44f0eee2011-05-26 01:26:41 +01004540 i::Isolate* isolate = i::Isolate::Current();
4541 ENTER_V8(isolate);
4542 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00004543 return Utils::IntegerToLocal(result);
4544}
4545
4546
Steve Blocka7e24c12009-10-30 11:49:00 +00004547void V8::IgnoreOutOfMemoryException() {
Ben Murdoch257744e2011-11-30 15:57:28 +00004548 EnterIsolateIfNeeded()->handle_scope_implementer()->set_ignore_out_of_memory(
4549 true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004550}
4551
4552
4553bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004554 i::Isolate* isolate = i::Isolate::Current();
4555 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
4556 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
4557 ENTER_V8(isolate);
4558 i::HandleScope scope(isolate);
4559 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004560 NeanderObject obj(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00004561 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004562 obj.set(1, data.IsEmpty() ?
Steve Block44f0eee2011-05-26 01:26:41 +01004563 isolate->heap()->undefined_value() :
Steve Blocka7e24c12009-10-30 11:49:00 +00004564 *Utils::OpenHandle(*data));
4565 listeners.add(obj.value());
4566 return true;
4567}
4568
4569
4570void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01004571 i::Isolate* isolate = i::Isolate::Current();
4572 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
4573 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
4574 ENTER_V8(isolate);
4575 i::HandleScope scope(isolate);
4576 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004577 for (int i = 0; i < listeners.length(); i++) {
4578 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
4579
4580 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
Ben Murdoch257744e2011-11-30 15:57:28 +00004581 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
4582 if (callback_obj->address() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004583 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004584 }
4585 }
4586}
4587
4588
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004589void V8::SetCaptureStackTraceForUncaughtExceptions(
4590 bool capture,
4591 int frame_limit,
4592 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01004593 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004594 capture,
4595 frame_limit,
4596 options);
4597}
4598
4599
Steve Blocka7e24c12009-10-30 11:49:00 +00004600void V8::SetCounterFunction(CounterLookupCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004601 i::Isolate* isolate = EnterIsolateIfNeeded();
4602 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
4603 isolate->stats_table()->SetCounterFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004604}
4605
4606void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004607 i::Isolate* isolate = EnterIsolateIfNeeded();
4608 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
4609 isolate->stats_table()->SetCreateHistogramFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004610}
4611
4612void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004613 i::Isolate* isolate = EnterIsolateIfNeeded();
4614 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
4615 isolate->stats_table()->
4616 SetAddHistogramSampleFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004617}
4618
4619void V8::EnableSlidingStateWindow() {
Steve Block44f0eee2011-05-26 01:26:41 +01004620 i::Isolate* isolate = i::Isolate::Current();
4621 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
4622 isolate->logger()->EnableSlidingStateWindow();
Steve Blocka7e24c12009-10-30 11:49:00 +00004623}
4624
4625
4626void V8::SetFailedAccessCheckCallbackFunction(
4627 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004628 i::Isolate* isolate = i::Isolate::Current();
4629 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
4630 return;
4631 }
4632 isolate->SetFailedAccessCheckCallback(callback);
4633}
4634
4635void V8::AddObjectGroup(Persistent<Value>* objects,
4636 size_t length,
4637 RetainedObjectInfo* info) {
4638 i::Isolate* isolate = i::Isolate::Current();
4639 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
4640 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
4641 isolate->global_handles()->AddObjectGroup(
4642 reinterpret_cast<i::Object***>(objects), length, info);
Steve Blocka7e24c12009-10-30 11:49:00 +00004643}
4644
4645
Steve Block44f0eee2011-05-26 01:26:41 +01004646void V8::AddImplicitReferences(Persistent<Object> parent,
4647 Persistent<Value>* children,
4648 size_t length) {
4649 i::Isolate* isolate = i::Isolate::Current();
4650 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004651 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
Steve Block44f0eee2011-05-26 01:26:41 +01004652 isolate->global_handles()->AddImplicitReferences(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004653 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*parent)).location(),
Steve Block44f0eee2011-05-26 01:26:41 +01004654 reinterpret_cast<i::Object***>(children), length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004655}
4656
4657
4658int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
Steve Block44f0eee2011-05-26 01:26:41 +01004659 i::Isolate* isolate = i::Isolate::Current();
4660 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
4661 return 0;
4662 }
4663 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
4664 change_in_bytes);
Steve Blocka7e24c12009-10-30 11:49:00 +00004665}
4666
4667
4668void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004669 i::Isolate* isolate = i::Isolate::Current();
4670 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
4671 isolate->heap()->SetGlobalGCPrologueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004672}
4673
4674
4675void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004676 i::Isolate* isolate = i::Isolate::Current();
4677 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
4678 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004679}
4680
4681
Steve Block6ded16b2010-05-10 14:33:55 +01004682void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004683 i::Isolate* isolate = i::Isolate::Current();
4684 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
4685 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004686}
4687
4688
4689void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004690 i::Isolate* isolate = i::Isolate::Current();
4691 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
4692 isolate->heap()->RemoveGCPrologueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004693}
4694
4695
4696void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004697 i::Isolate* isolate = i::Isolate::Current();
4698 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
4699 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004700}
4701
4702
4703void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004704 i::Isolate* isolate = i::Isolate::Current();
4705 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
4706 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004707}
4708
4709
Iain Merrick9ac36c92010-09-13 15:29:50 +01004710void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
4711 ObjectSpace space,
4712 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01004713 i::Isolate* isolate = i::Isolate::Current();
4714 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
4715 isolate->memory_allocator()->AddMemoryAllocationCallback(
4716 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004717}
4718
4719
4720void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004721 i::Isolate* isolate = i::Isolate::Current();
4722 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
4723 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
4724 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004725}
4726
4727
Steve Blocka7e24c12009-10-30 11:49:00 +00004728void V8::PauseProfiler() {
4729#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004730 PauseProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004731#endif
4732}
4733
4734
4735void V8::ResumeProfiler() {
4736#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004737 ResumeProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004738#endif
4739}
4740
4741
4742bool V8::IsProfilerPaused() {
4743#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004744 return LOGGER->GetActiveProfilerModules() & PROFILER_MODULE_CPU;
Steve Blocka7e24c12009-10-30 11:49:00 +00004745#else
4746 return true;
4747#endif
4748}
4749
4750
Andrei Popescu402d9372010-02-26 13:31:12 +00004751void V8::ResumeProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004752#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004753 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004754 if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
4755 // Snapshot mode: resume modules, perform GC, then pause only
4756 // those modules which haven't been started prior to making a
4757 // snapshot.
4758
Steve Block6ded16b2010-05-10 14:33:55 +01004759 // Make a GC prior to taking a snapshot.
Steve Block44f0eee2011-05-26 01:26:41 +01004760 isolate->heap()->CollectAllGarbage(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004761 // Reset snapshot flag and CPU module flags.
4762 flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
Steve Block44f0eee2011-05-26 01:26:41 +01004763 const int current_flags = isolate->logger()->GetActiveProfilerModules();
4764 isolate->logger()->ResumeProfiler(flags, tag);
4765 isolate->heap()->CollectAllGarbage(false);
4766 isolate->logger()->PauseProfiler(~current_flags & flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004767 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004768 isolate->logger()->ResumeProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004769 }
4770#endif
4771}
4772
4773
Andrei Popescu402d9372010-02-26 13:31:12 +00004774void V8::PauseProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004775#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004776 LOGGER->PauseProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004777#endif
4778}
4779
4780
4781int V8::GetActiveProfilerModules() {
4782#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004783 return LOGGER->GetActiveProfilerModules();
Steve Blocka7e24c12009-10-30 11:49:00 +00004784#else
4785 return PROFILER_MODULE_NONE;
4786#endif
4787}
4788
4789
4790int V8::GetLogLines(int from_pos, char* dest_buf, int max_size) {
4791#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block6ded16b2010-05-10 14:33:55 +01004792 ASSERT(max_size >= kMinimumSizeForLogLinesBuffer);
Steve Block44f0eee2011-05-26 01:26:41 +01004793 return LOGGER->GetLogLines(from_pos, dest_buf, max_size);
Steve Blocka7e24c12009-10-30 11:49:00 +00004794#endif
4795 return 0;
4796}
4797
4798
4799int V8::GetCurrentThreadId() {
Steve Block44f0eee2011-05-26 01:26:41 +01004800 i::Isolate* isolate = i::Isolate::Current();
4801 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
Ben Murdoch8b112d22011-06-08 16:22:53 +01004802 return isolate->thread_id().ToInteger();
Steve Blocka7e24c12009-10-30 11:49:00 +00004803}
4804
4805
4806void V8::TerminateExecution(int thread_id) {
Steve Block44f0eee2011-05-26 01:26:41 +01004807 i::Isolate* isolate = i::Isolate::Current();
4808 if (!isolate->IsInitialized()) return;
4809 API_ENTRY_CHECK("V8::TerminateExecution()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004810 // If the thread_id identifies the current thread just terminate
4811 // execution right away. Otherwise, ask the thread manager to
4812 // terminate the thread with the given id if any.
Ben Murdoch8b112d22011-06-08 16:22:53 +01004813 i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
4814 if (isolate->thread_id().Equals(internal_tid)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004815 isolate->stack_guard()->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00004816 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +01004817 isolate->thread_manager()->TerminateExecution(internal_tid);
Steve Blocka7e24c12009-10-30 11:49:00 +00004818 }
4819}
4820
4821
Steve Block44f0eee2011-05-26 01:26:41 +01004822void V8::TerminateExecution(Isolate* isolate) {
4823 // If no isolate is supplied, use the default isolate.
4824 if (isolate != NULL) {
4825 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
4826 } else {
4827 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
4828 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004829}
4830
4831
Steve Block6ded16b2010-05-10 14:33:55 +01004832bool V8::IsExecutionTerminating() {
Steve Block44f0eee2011-05-26 01:26:41 +01004833 i::Isolate* isolate = i::Isolate::Current();
4834 return IsExecutionTerminatingCheck(isolate);
4835}
4836
4837
4838Isolate* Isolate::GetCurrent() {
4839 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4840 return reinterpret_cast<Isolate*>(isolate);
4841}
4842
4843
4844Isolate* Isolate::New() {
4845 i::Isolate* isolate = new i::Isolate();
4846 return reinterpret_cast<Isolate*>(isolate);
4847}
4848
4849
4850void Isolate::Dispose() {
4851 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4852 if (!ApiCheck(!isolate->IsInUse(),
4853 "v8::Isolate::Dispose()",
4854 "Disposing the isolate that is entered by a thread.")) {
4855 return;
Steve Block6ded16b2010-05-10 14:33:55 +01004856 }
Steve Block44f0eee2011-05-26 01:26:41 +01004857 isolate->TearDown();
4858}
4859
4860
4861void Isolate::Enter() {
4862 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4863 isolate->Enter();
4864}
4865
4866
4867void Isolate::Exit() {
4868 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4869 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01004870}
4871
4872
Ben Murdoch257744e2011-11-30 15:57:28 +00004873void Isolate::SetData(void* data) {
4874 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4875 isolate->SetData(data);
4876}
4877
4878void* Isolate::GetData() {
4879 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4880 return isolate->GetData();
4881}
4882
4883
4884String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
4885 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01004886 i::Isolate* isolate = i::Isolate::Current();
4887 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00004888 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01004889 ENTER_V8(isolate);
4890 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004891 TryCatch try_catch;
4892 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00004893 if (str.IsEmpty()) return;
4894 length_ = str->Utf8Length();
4895 str_ = i::NewArray<char>(length_ + 1);
4896 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00004897}
4898
4899
4900String::Utf8Value::~Utf8Value() {
4901 i::DeleteArray(str_);
4902}
4903
4904
Ben Murdoch257744e2011-11-30 15:57:28 +00004905String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
4906 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01004907 i::Isolate* isolate = i::Isolate::Current();
4908 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00004909 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01004910 ENTER_V8(isolate);
4911 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004912 TryCatch try_catch;
4913 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00004914 if (str.IsEmpty()) return;
4915 length_ = str->Length();
4916 str_ = i::NewArray<char>(length_ + 1);
4917 str->WriteAscii(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00004918}
4919
4920
4921String::AsciiValue::~AsciiValue() {
4922 i::DeleteArray(str_);
4923}
4924
4925
Ben Murdoch257744e2011-11-30 15:57:28 +00004926String::Value::Value(v8::Handle<v8::Value> obj)
4927 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01004928 i::Isolate* isolate = i::Isolate::Current();
4929 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00004930 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01004931 ENTER_V8(isolate);
4932 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004933 TryCatch try_catch;
4934 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00004935 if (str.IsEmpty()) return;
4936 length_ = str->Length();
4937 str_ = i::NewArray<uint16_t>(length_ + 1);
4938 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00004939}
4940
4941
4942String::Value::~Value() {
4943 i::DeleteArray(str_);
4944}
4945
4946Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004947 i::Isolate* isolate = i::Isolate::Current();
4948 LOG_API(isolate, "RangeError");
4949 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
4950 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004951 i::Object* error;
4952 {
Steve Block44f0eee2011-05-26 01:26:41 +01004953 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004954 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004955 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004956 error = *result;
4957 }
4958 i::Handle<i::Object> result(error);
4959 return Utils::ToLocal(result);
4960}
4961
4962Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004963 i::Isolate* isolate = i::Isolate::Current();
4964 LOG_API(isolate, "ReferenceError");
4965 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
4966 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004967 i::Object* error;
4968 {
Steve Block44f0eee2011-05-26 01:26:41 +01004969 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004970 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004971 i::Handle<i::Object> result =
4972 isolate->factory()->NewReferenceError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004973 error = *result;
4974 }
4975 i::Handle<i::Object> result(error);
4976 return Utils::ToLocal(result);
4977}
4978
4979Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004980 i::Isolate* isolate = i::Isolate::Current();
4981 LOG_API(isolate, "SyntaxError");
4982 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
4983 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004984 i::Object* error;
4985 {
Steve Block44f0eee2011-05-26 01:26:41 +01004986 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004987 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004988 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004989 error = *result;
4990 }
4991 i::Handle<i::Object> result(error);
4992 return Utils::ToLocal(result);
4993}
4994
4995Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004996 i::Isolate* isolate = i::Isolate::Current();
4997 LOG_API(isolate, "TypeError");
4998 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
4999 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005000 i::Object* error;
5001 {
Steve Block44f0eee2011-05-26 01:26:41 +01005002 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005003 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005004 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005005 error = *result;
5006 }
5007 i::Handle<i::Object> result(error);
5008 return Utils::ToLocal(result);
5009}
5010
5011Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005012 i::Isolate* isolate = i::Isolate::Current();
5013 LOG_API(isolate, "Error");
5014 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
5015 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005016 i::Object* error;
5017 {
Steve Block44f0eee2011-05-26 01:26:41 +01005018 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005019 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005020 i::Handle<i::Object> result = isolate->factory()->NewError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005021 error = *result;
5022 }
5023 i::Handle<i::Object> result(error);
5024 return Utils::ToLocal(result);
5025}
5026
5027
5028// --- D e b u g S u p p o r t ---
5029
5030#ifdef ENABLE_DEBUGGER_SUPPORT
Leon Clarkef7060e22010-06-03 12:02:55 +01005031
Leon Clarkef7060e22010-06-03 12:02:55 +01005032static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
Steve Block44f0eee2011-05-26 01:26:41 +01005033 i::Isolate* isolate = i::Isolate::Current();
5034 if (isolate->debug_event_callback() != NULL) {
5035 isolate->debug_event_callback()(event_details.GetEvent(),
5036 event_details.GetExecutionState(),
5037 event_details.GetEventData(),
5038 event_details.GetCallbackData());
Leon Clarkef7060e22010-06-03 12:02:55 +01005039 }
5040}
5041
5042
Steve Blocka7e24c12009-10-30 11:49:00 +00005043bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005044 i::Isolate* isolate = i::Isolate::Current();
5045 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
5046 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5047 ENTER_V8(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01005048
Steve Block44f0eee2011-05-26 01:26:41 +01005049 isolate->set_debug_event_callback(that);
Leon Clarkef7060e22010-06-03 12:02:55 +01005050
Steve Block44f0eee2011-05-26 01:26:41 +01005051 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005052 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Leon Clarkef7060e22010-06-03 12:02:55 +01005053 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005054 foreign =
5055 isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
Leon Clarkef7060e22010-06-03 12:02:55 +01005056 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005057 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Leon Clarkef7060e22010-06-03 12:02:55 +01005058 return true;
5059}
5060
5061
5062bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005063 i::Isolate* isolate = i::Isolate::Current();
5064 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
5065 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
5066 ENTER_V8(isolate);
5067 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005068 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00005069 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005070 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00005071 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005072 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005073 return true;
5074}
5075
5076
5077bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
5078 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005079 i::Isolate* isolate = i::Isolate::Current();
5080 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5081 ENTER_V8(isolate);
5082 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
5083 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005084 return true;
5085}
5086
5087
Steve Block44f0eee2011-05-26 01:26:41 +01005088void Debug::DebugBreak(Isolate* isolate) {
5089 // If no isolate is supplied, use the default isolate.
5090 if (isolate != NULL) {
5091 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
5092 } else {
5093 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
5094 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005095}
5096
5097
Steve Block44f0eee2011-05-26 01:26:41 +01005098void Debug::CancelDebugBreak(Isolate* isolate) {
5099 // If no isolate is supplied, use the default isolate.
5100 if (isolate != NULL) {
5101 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5102 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
5103 } else {
5104 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
5105 }
Ben Murdochf87a2032010-10-22 12:50:53 +01005106}
5107
5108
Steve Block44f0eee2011-05-26 01:26:41 +01005109void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
5110 // If no isolate is supplied, use the default isolate.
5111 if (isolate != NULL) {
5112 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5113 internal_isolate->debugger()->EnqueueDebugCommand(data);
5114 } else {
5115 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
5116 }
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005117}
5118
5119
Steve Blocka7e24c12009-10-30 11:49:00 +00005120static void MessageHandlerWrapper(const v8::Debug::Message& message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005121 i::Isolate* isolate = i::Isolate::Current();
5122 if (isolate->message_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005123 v8::String::Value json(message.GetJSON());
Steve Block44f0eee2011-05-26 01:26:41 +01005124 (isolate->message_handler())(*json, json.length(), message.GetClientData());
Steve Blocka7e24c12009-10-30 11:49:00 +00005125 }
5126}
5127
5128
5129void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
5130 bool message_handler_thread) {
Steve Block44f0eee2011-05-26 01:26:41 +01005131 i::Isolate* isolate = i::Isolate::Current();
5132 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5133 ENTER_V8(isolate);
5134
Steve Blocka7e24c12009-10-30 11:49:00 +00005135 // Message handler thread not supported any more. Parameter temporally left in
Steve Block44f0eee2011-05-26 01:26:41 +01005136 // the API for client compatibility reasons.
Steve Blocka7e24c12009-10-30 11:49:00 +00005137 CHECK(!message_handler_thread);
5138
5139 // TODO(sgjesse) support the old message handler API through a simple wrapper.
Steve Block44f0eee2011-05-26 01:26:41 +01005140 isolate->set_message_handler(handler);
5141 if (handler != NULL) {
5142 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
Steve Blocka7e24c12009-10-30 11:49:00 +00005143 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005144 isolate->debugger()->SetMessageHandler(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00005145 }
5146}
5147
5148
5149void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01005150 i::Isolate* isolate = i::Isolate::Current();
5151 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5152 ENTER_V8(isolate);
5153 isolate->debugger()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00005154}
5155
5156
5157void Debug::SendCommand(const uint16_t* command, int length,
Steve Block44f0eee2011-05-26 01:26:41 +01005158 ClientData* client_data,
5159 Isolate* isolate) {
5160 // If no isolate is supplied, use the default isolate.
5161 if (isolate != NULL) {
5162 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5163 internal_isolate->debugger()->ProcessCommand(
5164 i::Vector<const uint16_t>(command, length), client_data);
5165 } else {
5166 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
5167 i::Vector<const uint16_t>(command, length), client_data);
5168 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005169}
5170
5171
5172void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
5173 int period) {
Steve Block44f0eee2011-05-26 01:26:41 +01005174 i::Isolate* isolate = i::Isolate::Current();
5175 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
5176 ENTER_V8(isolate);
5177 isolate->debugger()->SetHostDispatchHandler(handler, period);
Steve Blocka7e24c12009-10-30 11:49:00 +00005178}
5179
5180
Steve Blockd0582a62009-12-15 09:54:21 +00005181void Debug::SetDebugMessageDispatchHandler(
Leon Clarkee46be812010-01-19 14:06:41 +00005182 DebugMessageDispatchHandler handler, bool provide_locker) {
Steve Block44f0eee2011-05-26 01:26:41 +01005183 i::Isolate* isolate = i::Isolate::Current();
5184 EnsureInitializedForIsolate(isolate,
5185 "v8::Debug::SetDebugMessageDispatchHandler");
5186 ENTER_V8(isolate);
5187 isolate->debugger()->SetDebugMessageDispatchHandler(
5188 handler, provide_locker);
Steve Blockd0582a62009-12-15 09:54:21 +00005189}
5190
5191
Steve Blocka7e24c12009-10-30 11:49:00 +00005192Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
5193 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005194 i::Isolate* isolate = i::Isolate::Current();
5195 if (!isolate->IsInitialized()) return Local<Value>();
5196 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
5197 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005198 i::Handle<i::Object> result;
Steve Block44f0eee2011-05-26 01:26:41 +01005199 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005200 if (data.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005201 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5202 isolate->factory()->undefined_value(),
5203 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005204 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005205 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5206 Utils::OpenHandle(*data),
5207 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005208 }
Steve Block44f0eee2011-05-26 01:26:41 +01005209 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005210 return Utils::ToLocal(result);
5211}
5212
5213
5214Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01005215 i::Isolate* isolate = i::Isolate::Current();
5216 if (!isolate->IsInitialized()) return Local<Value>();
5217 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
5218 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005219 v8::HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01005220 i::Debug* isolate_debug = isolate->debug();
5221 isolate_debug->Load();
5222 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5223 i::Handle<i::String> name =
5224 isolate->factory()->LookupAsciiSymbol("MakeMirror");
Steve Blocka7e24c12009-10-30 11:49:00 +00005225 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5226 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5227 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5228 const int kArgc = 1;
5229 v8::Handle<v8::Value> argv[kArgc] = { obj };
Steve Block44f0eee2011-05-26 01:26:41 +01005230 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005231 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5232 kArgc,
5233 argv);
Steve Block44f0eee2011-05-26 01:26:41 +01005234 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005235 return scope.Close(result);
5236}
5237
5238
Leon Clarkee46be812010-01-19 14:06:41 +00005239bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
Steve Block44f0eee2011-05-26 01:26:41 +01005240 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5241 wait_for_connection);
Steve Blocka7e24c12009-10-30 11:49:00 +00005242}
Leon Clarkee46be812010-01-19 14:06:41 +00005243
5244void Debug::ProcessDebugMessages() {
5245 i::Execution::ProcessDebugMesssages(true);
5246}
5247
Steve Block6ded16b2010-05-10 14:33:55 +01005248Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01005249 i::Isolate* isolate = i::Isolate::Current();
5250 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5251 ENTER_V8(isolate);
5252 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01005253}
5254
Steve Blocka7e24c12009-10-30 11:49:00 +00005255#endif // ENABLE_DEBUGGER_SUPPORT
5256
Steve Block6ded16b2010-05-10 14:33:55 +01005257
5258#ifdef ENABLE_LOGGING_AND_PROFILING
5259
5260Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005261 i::Isolate* isolate = i::Isolate::Current();
5262 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
Steve Block6ded16b2010-05-10 14:33:55 +01005263 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5264 const i::CodeEntry* entry = node->entry();
5265 if (!entry->has_name_prefix()) {
5266 return Handle<String>(ToApi<String>(
Steve Block44f0eee2011-05-26 01:26:41 +01005267 isolate->factory()->LookupAsciiSymbol(entry->name())));
Steve Block6ded16b2010-05-10 14:33:55 +01005268 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005269 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5270 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5271 isolate->factory()->LookupAsciiSymbol(entry->name()))));
Steve Block6ded16b2010-05-10 14:33:55 +01005272 }
5273}
5274
5275
5276Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005277 i::Isolate* isolate = i::Isolate::Current();
5278 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
Steve Block6ded16b2010-05-10 14:33:55 +01005279 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005280 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005281 node->entry()->resource_name())));
5282}
5283
5284
5285int CpuProfileNode::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005286 i::Isolate* isolate = i::Isolate::Current();
5287 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
Steve Block6ded16b2010-05-10 14:33:55 +01005288 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5289}
5290
5291
5292double CpuProfileNode::GetTotalTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005293 i::Isolate* isolate = i::Isolate::Current();
5294 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005295 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5296}
5297
5298
5299double CpuProfileNode::GetSelfTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005300 i::Isolate* isolate = i::Isolate::Current();
5301 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005302 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5303}
5304
5305
5306double CpuProfileNode::GetTotalSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005307 i::Isolate* isolate = i::Isolate::Current();
5308 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005309 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5310}
5311
5312
5313double CpuProfileNode::GetSelfSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005314 i::Isolate* isolate = i::Isolate::Current();
5315 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005316 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5317}
5318
5319
5320unsigned CpuProfileNode::GetCallUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005321 i::Isolate* isolate = i::Isolate::Current();
5322 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005323 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01005324}
5325
5326
5327int CpuProfileNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005328 i::Isolate* isolate = i::Isolate::Current();
5329 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005330 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5331}
5332
5333
5334const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005335 i::Isolate* isolate = i::Isolate::Current();
5336 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
Steve Block6ded16b2010-05-10 14:33:55 +01005337 const i::ProfileNode* child =
5338 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5339 return reinterpret_cast<const CpuProfileNode*>(child);
5340}
5341
5342
Steve Block44f0eee2011-05-26 01:26:41 +01005343void CpuProfile::Delete() {
5344 i::Isolate* isolate = i::Isolate::Current();
5345 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5346 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5347 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5348 !i::CpuProfiler::HasDetachedProfiles()) {
5349 // If this was the last profile, clean up all accessory data as well.
5350 i::CpuProfiler::DeleteAllProfiles();
5351 }
5352}
5353
5354
Steve Block6ded16b2010-05-10 14:33:55 +01005355unsigned CpuProfile::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005356 i::Isolate* isolate = i::Isolate::Current();
5357 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
Steve Block6ded16b2010-05-10 14:33:55 +01005358 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5359}
5360
5361
5362Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005363 i::Isolate* isolate = i::Isolate::Current();
5364 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
Steve Block6ded16b2010-05-10 14:33:55 +01005365 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005366 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005367 profile->title())));
5368}
5369
5370
5371const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005372 i::Isolate* isolate = i::Isolate::Current();
5373 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005374 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5375 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5376}
5377
5378
5379const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005380 i::Isolate* isolate = i::Isolate::Current();
5381 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005382 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5383 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5384}
5385
5386
5387int CpuProfiler::GetProfilesCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005388 i::Isolate* isolate = i::Isolate::Current();
5389 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005390 return i::CpuProfiler::GetProfilesCount();
5391}
5392
5393
Leon Clarkef7060e22010-06-03 12:02:55 +01005394const CpuProfile* CpuProfiler::GetProfile(int index,
5395 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005396 i::Isolate* isolate = i::Isolate::Current();
5397 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005398 return reinterpret_cast<const CpuProfile*>(
5399 i::CpuProfiler::GetProfile(
5400 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5401 index));
Steve Block6ded16b2010-05-10 14:33:55 +01005402}
5403
5404
Leon Clarkef7060e22010-06-03 12:02:55 +01005405const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5406 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005407 i::Isolate* isolate = i::Isolate::Current();
5408 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005409 return reinterpret_cast<const CpuProfile*>(
5410 i::CpuProfiler::FindProfile(
5411 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5412 uid));
Steve Block6ded16b2010-05-10 14:33:55 +01005413}
5414
5415
5416void CpuProfiler::StartProfiling(Handle<String> title) {
Steve Block44f0eee2011-05-26 01:26:41 +01005417 i::Isolate* isolate = i::Isolate::Current();
5418 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005419 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5420}
5421
5422
Leon Clarkef7060e22010-06-03 12:02:55 +01005423const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5424 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005425 i::Isolate* isolate = i::Isolate::Current();
5426 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005427 return reinterpret_cast<const CpuProfile*>(
Leon Clarkef7060e22010-06-03 12:02:55 +01005428 i::CpuProfiler::StopProfiling(
5429 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5430 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01005431}
5432
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005433
Steve Block44f0eee2011-05-26 01:26:41 +01005434void CpuProfiler::DeleteAllProfiles() {
5435 i::Isolate* isolate = i::Isolate::Current();
5436 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5437 i::CpuProfiler::DeleteAllProfiles();
5438}
5439
5440
Iain Merrick75681382010-08-19 15:07:18 +01005441static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5442 return const_cast<i::HeapGraphEdge*>(
5443 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5444}
5445
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005446HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005447 i::Isolate* isolate = i::Isolate::Current();
5448 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005449 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005450}
5451
5452
5453Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005454 i::Isolate* isolate = i::Isolate::Current();
5455 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
Iain Merrick75681382010-08-19 15:07:18 +01005456 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005457 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01005458 case i::HeapGraphEdge::kContextVariable:
5459 case i::HeapGraphEdge::kInternal:
5460 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005461 case i::HeapGraphEdge::kShortcut:
Steve Block44f0eee2011-05-26 01:26:41 +01005462 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005463 edge->name())));
Iain Merrick75681382010-08-19 15:07:18 +01005464 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005465 case i::HeapGraphEdge::kHidden:
Steve Block44f0eee2011-05-26 01:26:41 +01005466 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005467 edge->index())));
5468 default: UNREACHABLE();
5469 }
Steve Block44f0eee2011-05-26 01:26:41 +01005470 return v8::Undefined();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005471}
5472
5473
5474const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005475 i::Isolate* isolate = i::Isolate::Current();
5476 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
Iain Merrick75681382010-08-19 15:07:18 +01005477 const i::HeapEntry* from = ToInternal(this)->From();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005478 return reinterpret_cast<const HeapGraphNode*>(from);
5479}
5480
5481
5482const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005483 i::Isolate* isolate = i::Isolate::Current();
5484 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
Iain Merrick75681382010-08-19 15:07:18 +01005485 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005486 return reinterpret_cast<const HeapGraphNode*>(to);
5487}
5488
5489
Iain Merrick75681382010-08-19 15:07:18 +01005490static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5491 return const_cast<i::HeapEntry*>(
5492 reinterpret_cast<const i::HeapEntry*>(entry));
5493}
5494
5495
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005496HeapGraphNode::Type HeapGraphNode::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005497 i::Isolate* isolate = i::Isolate::Current();
5498 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005499 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005500}
5501
5502
5503Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005504 i::Isolate* isolate = i::Isolate::Current();
5505 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
5506 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005507 ToInternal(this)->name())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005508}
5509
5510
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005511uint64_t HeapGraphNode::GetId() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005512 i::Isolate* isolate = i::Isolate::Current();
5513 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
Steve Block791712a2010-08-27 10:21:07 +01005514 ASSERT(ToInternal(this)->snapshot()->type() != i::HeapSnapshot::kAggregated);
Iain Merrick75681382010-08-19 15:07:18 +01005515 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005516}
5517
5518
Steve Block791712a2010-08-27 10:21:07 +01005519int HeapGraphNode::GetInstancesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005520 i::Isolate* isolate = i::Isolate::Current();
5521 IsDeadCheck(isolate, "v8::HeapGraphNode::GetInstancesCount");
Steve Block791712a2010-08-27 10:21:07 +01005522 ASSERT(ToInternal(this)->snapshot()->type() == i::HeapSnapshot::kAggregated);
5523 return static_cast<int>(ToInternal(this)->id());
5524}
5525
5526
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005527int HeapGraphNode::GetSelfSize() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005528 i::Isolate* isolate = i::Isolate::Current();
5529 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
Iain Merrick75681382010-08-19 15:07:18 +01005530 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005531}
5532
5533
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005534int HeapGraphNode::GetRetainedSize(bool exact) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005535 i::Isolate* isolate = i::Isolate::Current();
5536 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005537 return ToInternal(this)->RetainedSize(exact);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005538}
5539
5540
5541int HeapGraphNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005542 i::Isolate* isolate = i::Isolate::Current();
5543 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
Iain Merrick75681382010-08-19 15:07:18 +01005544 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005545}
5546
5547
5548const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005549 i::Isolate* isolate = i::Isolate::Current();
5550 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005551 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005552 &ToInternal(this)->children()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005553}
5554
5555
5556int HeapGraphNode::GetRetainersCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005557 i::Isolate* isolate = i::Isolate::Current();
5558 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
Iain Merrick75681382010-08-19 15:07:18 +01005559 return ToInternal(this)->retainers().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005560}
5561
5562
5563const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005564 i::Isolate* isolate = i::Isolate::Current();
5565 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005566 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005567 ToInternal(this)->retainers()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005568}
5569
5570
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005571const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005572 i::Isolate* isolate = i::Isolate::Current();
5573 IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005574 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
5575}
5576
5577
Iain Merrick75681382010-08-19 15:07:18 +01005578static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5579 return const_cast<i::HeapSnapshot*>(
5580 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5581}
5582
5583
Steve Block44f0eee2011-05-26 01:26:41 +01005584void HeapSnapshot::Delete() {
5585 i::Isolate* isolate = i::Isolate::Current();
5586 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
5587 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
5588 ToInternal(this)->Delete();
5589 } else {
5590 // If this is the last snapshot, clean up all accessory data as well.
5591 i::HeapProfiler::DeleteAllSnapshots();
5592 }
5593}
5594
5595
Steve Block791712a2010-08-27 10:21:07 +01005596HeapSnapshot::Type HeapSnapshot::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005597 i::Isolate* isolate = i::Isolate::Current();
5598 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
Steve Block791712a2010-08-27 10:21:07 +01005599 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
5600}
5601
5602
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005603unsigned HeapSnapshot::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005604 i::Isolate* isolate = i::Isolate::Current();
5605 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
Iain Merrick75681382010-08-19 15:07:18 +01005606 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005607}
5608
5609
5610Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005611 i::Isolate* isolate = i::Isolate::Current();
5612 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
5613 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005614 ToInternal(this)->title())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005615}
5616
5617
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005618const HeapGraphNode* HeapSnapshot::GetRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005619 i::Isolate* isolate = i::Isolate::Current();
5620 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
Iain Merrick75681382010-08-19 15:07:18 +01005621 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005622}
5623
5624
Ben Murdochb0fe1622011-05-05 13:52:32 +01005625const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005626 i::Isolate* isolate = i::Isolate::Current();
5627 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
Ben Murdochb0fe1622011-05-05 13:52:32 +01005628 return reinterpret_cast<const HeapGraphNode*>(
5629 ToInternal(this)->GetEntryById(id));
5630}
5631
5632
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005633void HeapSnapshot::Serialize(OutputStream* stream,
5634 HeapSnapshot::SerializationFormat format) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005635 i::Isolate* isolate = i::Isolate::Current();
5636 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005637 ApiCheck(format == kJSON,
5638 "v8::HeapSnapshot::Serialize",
5639 "Unknown serialization format");
5640 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
5641 "v8::HeapSnapshot::Serialize",
5642 "Unsupported output encoding");
5643 ApiCheck(stream->GetChunkSize() > 0,
5644 "v8::HeapSnapshot::Serialize",
5645 "Invalid stream chunk size");
5646 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
5647 serializer.Serialize(stream);
5648}
5649
5650
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005651int HeapProfiler::GetSnapshotsCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005652 i::Isolate* isolate = i::Isolate::Current();
5653 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005654 return i::HeapProfiler::GetSnapshotsCount();
5655}
5656
5657
5658const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005659 i::Isolate* isolate = i::Isolate::Current();
5660 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005661 return reinterpret_cast<const HeapSnapshot*>(
5662 i::HeapProfiler::GetSnapshot(index));
5663}
5664
5665
5666const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
Steve Block44f0eee2011-05-26 01:26:41 +01005667 i::Isolate* isolate = i::Isolate::Current();
5668 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005669 return reinterpret_cast<const HeapSnapshot*>(
5670 i::HeapProfiler::FindSnapshot(uid));
5671}
5672
5673
Steve Block791712a2010-08-27 10:21:07 +01005674const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
Ben Murdochb0fe1622011-05-05 13:52:32 +01005675 HeapSnapshot::Type type,
5676 ActivityControl* control) {
Steve Block44f0eee2011-05-26 01:26:41 +01005677 i::Isolate* isolate = i::Isolate::Current();
5678 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
Steve Block791712a2010-08-27 10:21:07 +01005679 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
5680 switch (type) {
5681 case HeapSnapshot::kFull:
5682 internal_type = i::HeapSnapshot::kFull;
5683 break;
5684 case HeapSnapshot::kAggregated:
5685 internal_type = i::HeapSnapshot::kAggregated;
5686 break;
5687 default:
5688 UNREACHABLE();
5689 }
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005690 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb0fe1622011-05-05 13:52:32 +01005691 i::HeapProfiler::TakeSnapshot(
5692 *Utils::OpenHandle(*title), internal_type, control));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005693}
5694
Steve Block44f0eee2011-05-26 01:26:41 +01005695
5696void HeapProfiler::DeleteAllSnapshots() {
5697 i::Isolate* isolate = i::Isolate::Current();
5698 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5699 i::HeapProfiler::DeleteAllSnapshots();
5700}
5701
5702
5703void HeapProfiler::DefineWrapperClass(uint16_t class_id,
5704 WrapperInfoCallback callback) {
5705 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
5706 callback);
5707}
5708
Steve Block6ded16b2010-05-10 14:33:55 +01005709#endif // ENABLE_LOGGING_AND_PROFILING
5710
5711
Ben Murdochb0fe1622011-05-05 13:52:32 +01005712v8::Testing::StressType internal::Testing::stress_type_ =
5713 v8::Testing::kStressTypeOpt;
5714
5715
5716void Testing::SetStressRunType(Testing::StressType type) {
5717 internal::Testing::set_stress_type(type);
5718}
5719
5720int Testing::GetStressRuns() {
5721 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
5722#ifdef DEBUG
5723 // In debug mode the code runs much slower so stressing will only make two
5724 // runs.
5725 return 2;
5726#else
5727 return 5;
5728#endif
5729}
5730
5731
5732static void SetFlagsFromString(const char* flags) {
5733 V8::SetFlagsFromString(flags, i::StrLength(flags));
5734}
5735
5736
5737void Testing::PrepareStressRun(int run) {
5738 static const char* kLazyOptimizations =
5739 "--prepare-always-opt --nolimit-inlining "
5740 "--noalways-opt --noopt-eagerly";
5741 static const char* kEagerOptimizations = "--opt-eagerly";
5742 static const char* kForcedOptimizations = "--always-opt";
5743
5744 // If deoptimization stressed turn on frequent deoptimization. If no value
5745 // is spefified through --deopt-every-n-times use a default default value.
5746 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
5747 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
5748 internal::FLAG_deopt_every_n_times == 0) {
5749 SetFlagsFromString(kDeoptEvery13Times);
5750 }
5751
5752#ifdef DEBUG
5753 // As stressing in debug mode only make two runs skip the deopt stressing
5754 // here.
5755 if (run == GetStressRuns() - 1) {
5756 SetFlagsFromString(kForcedOptimizations);
5757 } else {
5758 SetFlagsFromString(kEagerOptimizations);
5759 SetFlagsFromString(kLazyOptimizations);
5760 }
5761#else
5762 if (run == GetStressRuns() - 1) {
5763 SetFlagsFromString(kForcedOptimizations);
5764 } else if (run == GetStressRuns() - 2) {
5765 SetFlagsFromString(kEagerOptimizations);
5766 } else {
5767 SetFlagsFromString(kLazyOptimizations);
5768 }
5769#endif
5770}
5771
5772
Steve Block44f0eee2011-05-26 01:26:41 +01005773void Testing::DeoptimizeAll() {
5774 internal::Deoptimizer::DeoptimizeAll();
Steve Blocka7e24c12009-10-30 11:49:00 +00005775}
5776
5777
Steve Block44f0eee2011-05-26 01:26:41 +01005778namespace internal {
5779
5780
Steve Blocka7e24c12009-10-30 11:49:00 +00005781void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01005782 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00005783}
5784
5785
5786char* HandleScopeImplementer::ArchiveThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005787 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00005788 isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00005789 handle_scope_data_ = *current;
5790 memcpy(storage, this, sizeof(*this));
5791
5792 ResetAfterArchive();
5793 current->Initialize();
5794
5795 return storage + ArchiveSpacePerThread();
5796}
5797
5798
5799int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01005800 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00005801}
5802
5803
5804char* HandleScopeImplementer::RestoreThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005805 memcpy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00005806 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00005807 return storage + ArchiveSpacePerThread();
5808}
5809
5810
5811void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
5812 // Iterate over all handles in the blocks except for the last.
5813 for (int i = blocks()->length() - 2; i >= 0; --i) {
5814 Object** block = blocks()->at(i);
5815 v->VisitPointers(block, &block[kHandleBlockSize]);
5816 }
5817
5818 // Iterate over live handles in the last block (if any).
5819 if (!blocks()->is_empty()) {
5820 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
5821 }
5822
5823 if (!saved_contexts_.is_empty()) {
5824 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
5825 v->VisitPointers(start, start + saved_contexts_.length());
5826 }
5827}
5828
5829
5830void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
5831 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00005832 isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01005833 handle_scope_data_ = *current;
5834 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005835}
5836
5837
5838char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01005839 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00005840 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01005841 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005842 return storage + ArchiveSpacePerThread();
5843}
5844
5845} } // namespace v8::internal