blob: 5bda7253b95926c6a6d50dc0faa4cebaaba2a2dc [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "api.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010031
Steve Blocka7e24c12009-10-30 11:49:00 +000032#include "arguments.h"
33#include "bootstrapper.h"
34#include "compiler.h"
35#include "debug.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010036#include "deoptimizer.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037#include "execution.h"
Ben Murdoch69a99ed2011-11-30 16:03:39 +000038#include "flags.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000039#include "global-handles.h"
Kristian Monsen9dcf7e22010-06-28 14:14:28 +010040#include "heap-profiler.h"
Steve Block6ded16b2010-05-10 14:33:55 +010041#include "messages.h"
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000042#include "natives.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010043#include "parser.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000044#include "platform.h"
Steve Block6ded16b2010-05-10 14:33:55 +010045#include "profile-generator-inl.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010046#include "runtime-profiler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000047#include "serialize.h"
48#include "snapshot.h"
49#include "v8threads.h"
50#include "version.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010051#include "vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000052
Steve Block6ded16b2010-05-10 14:33:55 +010053#include "../include/v8-profiler.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010054#include "../include/v8-testing.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000055
Steve Block44f0eee2011-05-26 01:26:41 +010056#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000057
Steve Block44f0eee2011-05-26 01:26:41 +010058#define ENTER_V8(isolate) \
59 ASSERT((isolate)->IsInitialized()); \
60 i::VMState __state__((isolate), i::OTHER)
61#define LEAVE_V8(isolate) \
62 i::VMState __state__((isolate), i::EXTERNAL)
Steve Blocka7e24c12009-10-30 11:49:00 +000063
64namespace v8 {
65
Steve Block44f0eee2011-05-26 01:26:41 +010066#define ON_BAILOUT(isolate, location, code) \
67 if (IsDeadCheck(isolate, location) || \
68 IsExecutionTerminatingCheck(isolate)) { \
Leon Clarkef7060e22010-06-03 12:02:55 +010069 code; \
70 UNREACHABLE(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000071 }
72
73
Steve Block44f0eee2011-05-26 01:26:41 +010074#define EXCEPTION_PREAMBLE(isolate) \
75 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
76 ASSERT(!(isolate)->external_caught_exception()); \
Steve Blocka7e24c12009-10-30 11:49:00 +000077 bool has_pending_exception = false
78
79
Steve Block44f0eee2011-05-26 01:26:41 +010080#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
Steve Blocka7e24c12009-10-30 11:49:00 +000081 do { \
Steve Block44f0eee2011-05-26 01:26:41 +010082 i::HandleScopeImplementer* handle_scope_implementer = \
83 (isolate)->handle_scope_implementer(); \
84 handle_scope_implementer->DecrementCallDepth(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000085 if (has_pending_exception) { \
Steve Block44f0eee2011-05-26 01:26:41 +010086 if (handle_scope_implementer->CallDepthIsZero() && \
87 (isolate)->is_out_of_memory()) { \
Ben Murdoch69a99ed2011-11-30 16:03:39 +000088 if (!(isolate)->ignore_out_of_memory()) \
Steve Blocka7e24c12009-10-30 11:49:00 +000089 i::V8::FatalProcessOutOfMemory(NULL); \
90 } \
Steve Block44f0eee2011-05-26 01:26:41 +010091 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
92 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
Steve Blocka7e24c12009-10-30 11:49:00 +000093 return value; \
94 } \
95 } while (false)
96
97
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000098#define API_ENTRY_CHECK(isolate, msg) \
Steve Blocka7e24c12009-10-30 11:49:00 +000099 do { \
100 if (v8::Locker::IsActive()) { \
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000101 ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(), \
Steve Blocka7e24c12009-10-30 11:49:00 +0000102 msg, \
103 "Entering the V8 API without proper locking in place"); \
104 } \
105 } while (false)
106
Ben Murdochb0fe1622011-05-05 13:52:32 +0100107
Steve Blocka7e24c12009-10-30 11:49:00 +0000108// --- E x c e p t i o n B e h a v i o r ---
109
110
Steve Blocka7e24c12009-10-30 11:49:00 +0000111static void DefaultFatalErrorHandler(const char* location,
112 const char* message) {
Steve Block44f0eee2011-05-26 01:26:41 +0100113 i::VMState __state__(i::Isolate::Current(), i::OTHER);
Steve Blocka7e24c12009-10-30 11:49:00 +0000114 API_Fatal(location, message);
115}
116
117
Steve Block44f0eee2011-05-26 01:26:41 +0100118static FatalErrorCallback GetFatalErrorHandler() {
119 i::Isolate* isolate = i::Isolate::Current();
120 if (isolate->exception_behavior() == NULL) {
121 isolate->set_exception_behavior(DefaultFatalErrorHandler);
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 }
Steve Block44f0eee2011-05-26 01:26:41 +0100123 return isolate->exception_behavior();
Steve Blocka7e24c12009-10-30 11:49:00 +0000124}
125
126
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800127void i::FatalProcessOutOfMemory(const char* location) {
128 i::V8::FatalProcessOutOfMemory(location, false);
129}
130
Steve Blocka7e24c12009-10-30 11:49:00 +0000131
132// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
133// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100134void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Steve Blockd0582a62009-12-15 09:54:21 +0000135 i::HeapStats heap_stats;
136 int start_marker;
137 heap_stats.start_marker = &start_marker;
138 int new_space_size;
139 heap_stats.new_space_size = &new_space_size;
140 int new_space_capacity;
141 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100142 intptr_t old_pointer_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000143 heap_stats.old_pointer_space_size = &old_pointer_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100144 intptr_t old_pointer_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000145 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100146 intptr_t old_data_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000147 heap_stats.old_data_space_size = &old_data_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100148 intptr_t old_data_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000149 heap_stats.old_data_space_capacity = &old_data_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100150 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000151 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100152 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000153 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100154 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000155 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100156 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000157 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100158 intptr_t cell_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000159 heap_stats.cell_space_size = &cell_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100160 intptr_t cell_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000161 heap_stats.cell_space_capacity = &cell_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100162 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000163 heap_stats.lo_space_size = &lo_space_size;
164 int global_handle_count;
165 heap_stats.global_handle_count = &global_handle_count;
166 int weak_global_handle_count;
167 heap_stats.weak_global_handle_count = &weak_global_handle_count;
168 int pending_global_handle_count;
169 heap_stats.pending_global_handle_count = &pending_global_handle_count;
170 int near_death_global_handle_count;
171 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000172 int free_global_handle_count;
173 heap_stats.free_global_handle_count = &free_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100174 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100175 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100176 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100177 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
178 int objects_per_type[LAST_TYPE + 1] = {0};
179 heap_stats.objects_per_type = objects_per_type;
180 int size_per_type[LAST_TYPE + 1] = {0};
181 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100182 int os_error;
183 heap_stats.os_error = &os_error;
Steve Blockd0582a62009-12-15 09:54:21 +0000184 int end_marker;
185 heap_stats.end_marker = &end_marker;
Steve Block44f0eee2011-05-26 01:26:41 +0100186 i::Isolate* isolate = i::Isolate::Current();
187 isolate->heap()->RecordStats(&heap_stats, take_snapshot);
Steve Blocka7e24c12009-10-30 11:49:00 +0000188 i::V8::SetFatalError();
189 FatalErrorCallback callback = GetFatalErrorHandler();
190 {
Steve Block44f0eee2011-05-26 01:26:41 +0100191 LEAVE_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000192 callback(location, "Allocation failed - process out of memory");
193 }
194 // If the callback returns, we stop execution.
195 UNREACHABLE();
196}
197
198
Steve Blocka7e24c12009-10-30 11:49:00 +0000199bool Utils::ReportApiFailure(const char* location, const char* message) {
200 FatalErrorCallback callback = GetFatalErrorHandler();
201 callback(location, message);
202 i::V8::SetFatalError();
203 return false;
204}
205
206
207bool V8::IsDead() {
208 return i::V8::IsDead();
209}
210
211
212static inline bool ApiCheck(bool condition,
213 const char* location,
214 const char* message) {
215 return condition ? true : Utils::ReportApiFailure(location, message);
216}
217
218
219static bool ReportV8Dead(const char* location) {
220 FatalErrorCallback callback = GetFatalErrorHandler();
221 callback(location, "V8 is no longer usable");
222 return true;
223}
224
225
226static bool ReportEmptyHandle(const char* location) {
227 FatalErrorCallback callback = GetFatalErrorHandler();
228 callback(location, "Reading from empty handle");
229 return true;
230}
231
232
233/**
234 * IsDeadCheck checks that the vm is usable. If, for instance, the vm has been
235 * out of memory at some point this check will fail. It should be called on
236 * entry to all methods that touch anything in the heap, except destructors
237 * which you sometimes can't avoid calling after the vm has crashed. Functions
238 * that call EnsureInitialized or ON_BAILOUT don't have to also call
239 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you
240 * can arrange to return if the VM is dead. This is needed to ensure that no VM
241 * heap allocations are attempted on a dead VM. EnsureInitialized has the
242 * advantage over ON_BAILOUT that it actually initializes the VM if this has not
243 * yet been done.
244 */
Steve Block44f0eee2011-05-26 01:26:41 +0100245static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
246 return !isolate->IsInitialized()
Steve Blocka7e24c12009-10-30 11:49:00 +0000247 && i::V8::IsDead() ? ReportV8Dead(location) : false;
248}
249
250
Steve Block44f0eee2011-05-26 01:26:41 +0100251static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
252 if (!isolate->IsInitialized()) return false;
253 if (isolate->has_scheduled_exception()) {
254 return isolate->scheduled_exception() ==
255 isolate->heap()->termination_exception();
256 }
257 return false;
258}
259
260
Steve Blocka7e24c12009-10-30 11:49:00 +0000261static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
262 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
263}
264
265
266static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
267 return (obj == 0) ? ReportEmptyHandle(location) : false;
268}
269
270// --- S t a t i c s ---
271
272
Steve Block44f0eee2011-05-26 01:26:41 +0100273static bool InitializeHelper() {
274 if (i::Snapshot::Initialize()) return true;
275 return i::V8::Initialize(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000276}
277
278
Steve Block44f0eee2011-05-26 01:26:41 +0100279static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
280 const char* location) {
281 if (IsDeadCheck(isolate, location)) return false;
282 if (isolate != NULL) {
283 if (isolate->IsInitialized()) return true;
284 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000285 ASSERT(isolate == i::Isolate::Current());
Steve Block44f0eee2011-05-26 01:26:41 +0100286 return ApiCheck(InitializeHelper(), location, "Error initializing V8");
287}
288
289// Some initializing API functions are called early and may be
290// called on a thread different from static initializer thread.
291// If Isolate API is used, Isolate::Enter() will initialize TLS so
292// Isolate::Current() works. If it's a legacy case, then the thread
293// may not have TLS initialized yet. However, in initializing APIs it
294// may be too early to call EnsureInitialized() - some pre-init
295// parameters still have to be configured.
296static inline i::Isolate* EnterIsolateIfNeeded() {
297 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
298 if (isolate != NULL)
299 return isolate;
300
301 i::Isolate::EnterDefaultIsolate();
302 isolate = i::Isolate::Current();
303 return isolate;
304}
305
306
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000307StartupDataDecompressor::StartupDataDecompressor()
308 : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
309 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
310 raw_data[i] = NULL;
311 }
312}
313
314
315StartupDataDecompressor::~StartupDataDecompressor() {
316 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
317 i::DeleteArray(raw_data[i]);
318 }
319 i::DeleteArray(raw_data);
320}
321
322
323int StartupDataDecompressor::Decompress() {
324 int compressed_data_count = V8::GetCompressedStartupDataCount();
325 StartupData* compressed_data =
326 i::NewArray<StartupData>(compressed_data_count);
327 V8::GetCompressedStartupData(compressed_data);
328 for (int i = 0; i < compressed_data_count; ++i) {
329 char* decompressed = raw_data[i] =
330 i::NewArray<char>(compressed_data[i].raw_size);
331 if (compressed_data[i].compressed_size != 0) {
332 int result = DecompressData(decompressed,
333 &compressed_data[i].raw_size,
334 compressed_data[i].data,
335 compressed_data[i].compressed_size);
336 if (result != 0) return result;
337 } else {
338 ASSERT_EQ(0, compressed_data[i].raw_size);
339 }
340 compressed_data[i].data = decompressed;
341 }
342 V8::SetDecompressedStartupData(compressed_data);
343 return 0;
344}
345
346
Ben Murdoch257744e2011-11-30 15:57:28 +0000347StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
348#ifdef COMPRESS_STARTUP_DATA_BZ2
349 return StartupData::kBZip2;
350#else
351 return StartupData::kUncompressed;
352#endif
353}
354
355
356enum CompressedStartupDataItems {
357 kSnapshot = 0,
358 kSnapshotContext,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000359 kLibraries,
360 kExperimentalLibraries,
Ben Murdoch257744e2011-11-30 15:57:28 +0000361 kCompressedStartupDataCount
362};
363
364int V8::GetCompressedStartupDataCount() {
365#ifdef COMPRESS_STARTUP_DATA_BZ2
366 return kCompressedStartupDataCount;
367#else
368 return 0;
369#endif
370}
371
372
373void V8::GetCompressedStartupData(StartupData* compressed_data) {
374#ifdef COMPRESS_STARTUP_DATA_BZ2
375 compressed_data[kSnapshot].data =
376 reinterpret_cast<const char*>(i::Snapshot::data());
377 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
378 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
379
380 compressed_data[kSnapshotContext].data =
381 reinterpret_cast<const char*>(i::Snapshot::context_data());
382 compressed_data[kSnapshotContext].compressed_size =
383 i::Snapshot::context_size();
384 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000385
386 i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
387 compressed_data[kLibraries].data =
388 reinterpret_cast<const char*>(libraries_source.start());
389 compressed_data[kLibraries].compressed_size = libraries_source.length();
390 compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
391
392 i::Vector<const i::byte> exp_libraries_source =
393 i::ExperimentalNatives::GetScriptsSource();
394 compressed_data[kExperimentalLibraries].data =
395 reinterpret_cast<const char*>(exp_libraries_source.start());
396 compressed_data[kExperimentalLibraries].compressed_size =
397 exp_libraries_source.length();
398 compressed_data[kExperimentalLibraries].raw_size =
399 i::ExperimentalNatives::GetRawScriptsSize();
Ben Murdoch257744e2011-11-30 15:57:28 +0000400#endif
401}
402
403
404void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
405#ifdef COMPRESS_STARTUP_DATA_BZ2
406 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
407 i::Snapshot::set_raw_data(
408 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
409
410 ASSERT_EQ(i::Snapshot::context_raw_size(),
411 decompressed_data[kSnapshotContext].raw_size);
412 i::Snapshot::set_context_raw_data(
413 reinterpret_cast<const i::byte*>(
414 decompressed_data[kSnapshotContext].data));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000415
416 ASSERT_EQ(i::Natives::GetRawScriptsSize(),
417 decompressed_data[kLibraries].raw_size);
418 i::Vector<const char> libraries_source(
419 decompressed_data[kLibraries].data,
420 decompressed_data[kLibraries].raw_size);
421 i::Natives::SetRawScriptsSource(libraries_source);
422
423 ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
424 decompressed_data[kExperimentalLibraries].raw_size);
425 i::Vector<const char> exp_libraries_source(
426 decompressed_data[kExperimentalLibraries].data,
427 decompressed_data[kExperimentalLibraries].raw_size);
428 i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
Ben Murdoch257744e2011-11-30 15:57:28 +0000429#endif
430}
431
432
Steve Block44f0eee2011-05-26 01:26:41 +0100433void V8::SetFatalErrorHandler(FatalErrorCallback that) {
434 i::Isolate* isolate = EnterIsolateIfNeeded();
435 isolate->set_exception_behavior(that);
Steve Blocka7e24c12009-10-30 11:49:00 +0000436}
437
438
Ben Murdoch257744e2011-11-30 15:57:28 +0000439void V8::SetAllowCodeGenerationFromStringsCallback(
440 AllowCodeGenerationFromStringsCallback callback) {
441 i::Isolate* isolate = EnterIsolateIfNeeded();
442 isolate->set_allow_code_gen_callback(callback);
443}
444
445
Steve Blocka7e24c12009-10-30 11:49:00 +0000446#ifdef DEBUG
447void ImplementationUtilities::ZapHandleRange(i::Object** begin,
448 i::Object** end) {
449 i::HandleScope::ZapRange(begin, end);
450}
451#endif
452
453
Steve Blocka7e24c12009-10-30 11:49:00 +0000454void V8::SetFlagsFromString(const char* str, int length) {
455 i::FlagList::SetFlagsFromString(str, length);
456}
457
458
459void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
460 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
461}
462
463
464v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100465 i::Isolate* isolate = i::Isolate::Current();
466 if (IsDeadCheck(isolate, "v8::ThrowException()")) {
467 return v8::Handle<Value>();
468 }
469 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000470 // If we're passed an empty handle, we throw an undefined exception
471 // to deal more gracefully with out of memory situations.
472 if (value.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100473 isolate->ScheduleThrow(isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000474 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100475 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +0000476 }
477 return v8::Undefined();
478}
479
480
481RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
482
483
484RegisteredExtension::RegisteredExtension(Extension* extension)
485 : extension_(extension), state_(UNVISITED) { }
486
487
488void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100489 that->next_ = first_extension_;
490 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000491}
492
493
494void RegisterExtension(Extension* that) {
495 RegisteredExtension* extension = new RegisteredExtension(that);
496 RegisteredExtension::Register(extension);
497}
498
499
500Extension::Extension(const char* name,
501 const char* source,
502 int dep_count,
503 const char** deps)
504 : name_(name),
505 source_(source),
506 dep_count_(dep_count),
507 deps_(deps),
508 auto_enable_(false) { }
509
510
511v8::Handle<Primitive> Undefined() {
Steve Block44f0eee2011-05-26 01:26:41 +0100512 i::Isolate* isolate = i::Isolate::Current();
513 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
514 return v8::Handle<v8::Primitive>();
515 }
516 return v8::Handle<Primitive>(ToApi<Primitive>(
517 isolate->factory()->undefined_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000518}
519
520
521v8::Handle<Primitive> Null() {
Steve Block44f0eee2011-05-26 01:26:41 +0100522 i::Isolate* isolate = i::Isolate::Current();
523 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
524 return v8::Handle<v8::Primitive>();
525 }
526 return v8::Handle<Primitive>(
527 ToApi<Primitive>(isolate->factory()->null_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000528}
529
530
531v8::Handle<Boolean> True() {
Steve Block44f0eee2011-05-26 01:26:41 +0100532 i::Isolate* isolate = i::Isolate::Current();
533 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
534 return v8::Handle<Boolean>();
535 }
536 return v8::Handle<Boolean>(
537 ToApi<Boolean>(isolate->factory()->true_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000538}
539
540
541v8::Handle<Boolean> False() {
Steve Block44f0eee2011-05-26 01:26:41 +0100542 i::Isolate* isolate = i::Isolate::Current();
543 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
544 return v8::Handle<Boolean>();
545 }
546 return v8::Handle<Boolean>(
547 ToApi<Boolean>(isolate->factory()->false_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000548}
549
550
551ResourceConstraints::ResourceConstraints()
552 : max_young_space_size_(0),
553 max_old_space_size_(0),
Russell Brenner90bac252010-11-18 13:33:46 -0800554 max_executable_size_(0),
Steve Blocka7e24c12009-10-30 11:49:00 +0000555 stack_limit_(NULL) { }
556
557
558bool SetResourceConstraints(ResourceConstraints* constraints) {
Steve Block44f0eee2011-05-26 01:26:41 +0100559 i::Isolate* isolate = EnterIsolateIfNeeded();
560
Steve Block3ce2e202009-11-05 08:53:23 +0000561 int young_space_size = constraints->max_young_space_size();
Steve Blocka7e24c12009-10-30 11:49:00 +0000562 int old_gen_size = constraints->max_old_space_size();
Russell Brenner90bac252010-11-18 13:33:46 -0800563 int max_executable_size = constraints->max_executable_size();
564 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100565 // After initialization it's too late to change Heap constraints.
566 ASSERT(!isolate->IsInitialized());
567 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
568 old_gen_size,
569 max_executable_size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000570 if (!result) return false;
571 }
572 if (constraints->stack_limit() != NULL) {
573 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
Steve Block44f0eee2011-05-26 01:26:41 +0100574 isolate->stack_guard()->SetStackLimit(limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000575 }
576 return true;
577}
578
579
580i::Object** V8::GlobalizeReference(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100581 i::Isolate* isolate = i::Isolate::Current();
582 if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
583 LOG_API(isolate, "Persistent::New");
Steve Blocka7e24c12009-10-30 11:49:00 +0000584 i::Handle<i::Object> result =
Steve Block44f0eee2011-05-26 01:26:41 +0100585 isolate->global_handles()->Create(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000586 return result.location();
587}
588
589
590void V8::MakeWeak(i::Object** object, void* parameters,
591 WeakReferenceCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +0100592 i::Isolate* isolate = i::Isolate::Current();
593 LOG_API(isolate, "MakeWeak");
594 isolate->global_handles()->MakeWeak(object, parameters,
595 callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000596}
597
598
599void V8::ClearWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100600 i::Isolate* isolate = i::Isolate::Current();
601 LOG_API(isolate, "ClearWeak");
602 isolate->global_handles()->ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000603}
604
605
Ben Murdoch257744e2011-11-30 15:57:28 +0000606void V8::MarkIndependent(i::Object** object) {
607 i::Isolate* isolate = i::Isolate::Current();
608 LOG_API(isolate, "MakeIndependent");
609 isolate->global_handles()->MarkIndependent(object);
610}
611
612
Steve Blocka7e24c12009-10-30 11:49:00 +0000613bool V8::IsGlobalNearDeath(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100614 i::Isolate* isolate = i::Isolate::Current();
615 LOG_API(isolate, "IsGlobalNearDeath");
616 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000617 return i::GlobalHandles::IsNearDeath(obj);
618}
619
620
621bool V8::IsGlobalWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100622 i::Isolate* isolate = i::Isolate::Current();
623 LOG_API(isolate, "IsGlobalWeak");
624 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000625 return i::GlobalHandles::IsWeak(obj);
626}
627
628
629void V8::DisposeGlobal(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100630 i::Isolate* isolate = i::Isolate::Current();
631 LOG_API(isolate, "DisposeGlobal");
632 if (!isolate->IsInitialized()) return;
633 isolate->global_handles()->Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000634}
635
636// --- H a n d l e s ---
637
638
Steve Block44f0eee2011-05-26 01:26:41 +0100639HandleScope::HandleScope() {
Steve Block44f0eee2011-05-26 01:26:41 +0100640 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000641 API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
Steve Block44f0eee2011-05-26 01:26:41 +0100642 v8::ImplementationUtilities::HandleScopeData* current =
643 isolate->handle_scope_data();
644 isolate_ = isolate;
645 prev_next_ = current->next;
646 prev_limit_ = current->limit;
647 is_closed_ = false;
648 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000649}
650
651
652HandleScope::~HandleScope() {
653 if (!is_closed_) {
John Reck59135872010-11-02 12:39:01 -0700654 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000655 }
656}
657
658
John Reck59135872010-11-02 12:39:01 -0700659void HandleScope::Leave() {
Steve Block44f0eee2011-05-26 01:26:41 +0100660 ASSERT(isolate_ == i::Isolate::Current());
661 v8::ImplementationUtilities::HandleScopeData* current =
662 isolate_->handle_scope_data();
663 current->level--;
664 ASSERT(current->level >= 0);
665 current->next = prev_next_;
666 if (current->limit != prev_limit_) {
667 current->limit = prev_limit_;
668 i::HandleScope::DeleteExtensions(isolate_);
John Reck59135872010-11-02 12:39:01 -0700669 }
670
671#ifdef DEBUG
672 i::HandleScope::ZapRange(prev_next_, prev_limit_);
673#endif
674}
675
676
Steve Blocka7e24c12009-10-30 11:49:00 +0000677int HandleScope::NumberOfHandles() {
Steve Block44f0eee2011-05-26 01:26:41 +0100678 EnsureInitializedForIsolate(
679 i::Isolate::Current(), "HandleScope::NumberOfHandles");
Steve Blocka7e24c12009-10-30 11:49:00 +0000680 return i::HandleScope::NumberOfHandles();
681}
682
683
Steve Block44f0eee2011-05-26 01:26:41 +0100684i::Object** HandleScope::CreateHandle(i::Object* value) {
685 return i::HandleScope::CreateHandle(value, i::Isolate::Current());
686}
687
688
689i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
690 ASSERT(value->IsHeapObject());
691 return reinterpret_cast<i::Object**>(
692 i::HandleScope::CreateHandle(value, value->GetIsolate()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000693}
694
695
696void Context::Enter() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000697 i::Handle<i::Context> env = Utils::OpenHandle(this);
698 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100699 if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
700 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000701
Steve Block44f0eee2011-05-26 01:26:41 +0100702 isolate->handle_scope_implementer()->EnterContext(env);
703
704 isolate->handle_scope_implementer()->SaveContext(isolate->context());
705 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000706}
707
708
709void Context::Exit() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000710 // Exit is essentially a static function and doesn't use the
711 // receiver, so we have to get the current isolate from the thread
712 // local.
Steve Block44f0eee2011-05-26 01:26:41 +0100713 i::Isolate* isolate = i::Isolate::Current();
714 if (!isolate->IsInitialized()) return;
715
716 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000717 "v8::Context::Exit()",
718 "Cannot exit non-entered context")) {
719 return;
720 }
721
722 // Content of 'last_context' could be NULL.
Steve Block44f0eee2011-05-26 01:26:41 +0100723 i::Context* last_context =
724 isolate->handle_scope_implementer()->RestoreContext();
725 isolate->set_context(last_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000726}
727
728
Steve Blockd0582a62009-12-15 09:54:21 +0000729void Context::SetData(v8::Handle<String> data) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000730 i::Handle<i::Context> env = Utils::OpenHandle(this);
731 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100732 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000733 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
734 ASSERT(env->IsGlobalContext());
735 if (env->IsGlobalContext()) {
736 env->set_data(*raw_data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000737 }
738}
739
740
741v8::Local<v8::Value> Context::GetData() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000742 i::Handle<i::Context> env = Utils::OpenHandle(this);
743 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100744 if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
745 return v8::Local<Value>();
746 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000747 i::Object* raw_result = NULL;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000748 ASSERT(env->IsGlobalContext());
749 if (env->IsGlobalContext()) {
750 raw_result = env->data();
751 } else {
752 return Local<Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000753 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000754 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000755 return Utils::ToLocal(result);
756}
757
758
759i::Object** v8::HandleScope::RawClose(i::Object** value) {
760 if (!ApiCheck(!is_closed_,
761 "v8::HandleScope::Close()",
762 "Local scope has already been closed")) {
763 return 0;
764 }
Steve Block44f0eee2011-05-26 01:26:41 +0100765 LOG_API(isolate_, "CloseHandleScope");
Steve Blocka7e24c12009-10-30 11:49:00 +0000766
767 // Read the result before popping the handle block.
Steve Block6ded16b2010-05-10 14:33:55 +0100768 i::Object* result = NULL;
769 if (value != NULL) {
770 result = *value;
771 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000772 is_closed_ = true;
John Reck59135872010-11-02 12:39:01 -0700773 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000774
Steve Block6ded16b2010-05-10 14:33:55 +0100775 if (value == NULL) {
776 return NULL;
777 }
778
Steve Blocka7e24c12009-10-30 11:49:00 +0000779 // Allocate a new handle on the previous handle block.
780 i::Handle<i::Object> handle(result);
781 return handle.location();
782}
783
784
785// --- N e a n d e r ---
786
787
788// A constructor cannot easily return an error value, therefore it is necessary
789// to check for a dead VM with ON_BAILOUT before constructing any Neander
790// objects. To remind you about this there is no HandleScope in the
791// NeanderObject constructor. When you add one to the site calling the
792// constructor you should check that you ensured the VM was not dead first.
793NeanderObject::NeanderObject(int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100794 i::Isolate* isolate = i::Isolate::Current();
795 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
796 ENTER_V8(isolate);
797 value_ = isolate->factory()->NewNeanderObject();
798 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000799 value_->set_elements(*elements);
800}
801
802
803int NeanderObject::size() {
804 return i::FixedArray::cast(value_->elements())->length();
805}
806
807
808NeanderArray::NeanderArray() : obj_(2) {
809 obj_.set(0, i::Smi::FromInt(0));
810}
811
812
813int NeanderArray::length() {
814 return i::Smi::cast(obj_.get(0))->value();
815}
816
817
818i::Object* NeanderArray::get(int offset) {
819 ASSERT(0 <= offset);
820 ASSERT(offset < length());
821 return obj_.get(offset + 1);
822}
823
824
825// This method cannot easily return an error value, therefore it is necessary
826// to check for a dead VM with ON_BAILOUT before calling it. To remind you
827// about this there is no HandleScope in this method. When you add one to the
828// site calling this method you should check that you ensured the VM was not
829// dead first.
830void NeanderArray::add(i::Handle<i::Object> value) {
831 int length = this->length();
832 int size = obj_.size();
833 if (length == size - 1) {
Steve Block44f0eee2011-05-26 01:26:41 +0100834 i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000835 for (int i = 0; i < length; i++)
836 new_elms->set(i + 1, get(i));
837 obj_.value()->set_elements(*new_elms);
838 }
839 obj_.set(length + 1, *value);
840 obj_.set(0, i::Smi::FromInt(length + 1));
841}
842
843
844void NeanderArray::set(int index, i::Object* value) {
845 if (index < 0 || index >= this->length()) return;
846 obj_.set(index + 1, value);
847}
848
849
850// --- T e m p l a t e ---
851
852
853static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
854 that->set_tag(i::Smi::FromInt(type));
855}
856
857
858void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
859 v8::PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +0100860 i::Isolate* isolate = i::Isolate::Current();
861 if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
862 ENTER_V8(isolate);
863 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000864 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
865 if (list->IsUndefined()) {
866 list = NeanderArray().value();
867 Utils::OpenHandle(this)->set_property_list(*list);
868 }
869 NeanderArray array(list);
870 array.add(Utils::OpenHandle(*name));
871 array.add(Utils::OpenHandle(*value));
872 array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
873}
874
875
876// --- F u n c t i o n T e m p l a t e ---
877static void InitializeFunctionTemplate(
878 i::Handle<i::FunctionTemplateInfo> info) {
879 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
880 info->set_flag(0);
881}
882
883
884Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +0100885 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
886 if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000887 return Local<ObjectTemplate>();
888 }
Steve Block44f0eee2011-05-26 01:26:41 +0100889 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000890 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
891 if (result->IsUndefined()) {
892 result = Utils::OpenHandle(*ObjectTemplate::New());
893 Utils::OpenHandle(this)->set_prototype_template(*result);
894 }
895 return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
896}
897
898
899void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100900 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
901 if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
902 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000903 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
904}
905
906
Steve Blocka7e24c12009-10-30 11:49:00 +0000907Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
908 v8::Handle<Value> data, v8::Handle<Signature> signature) {
Steve Block44f0eee2011-05-26 01:26:41 +0100909 i::Isolate* isolate = i::Isolate::Current();
910 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
911 LOG_API(isolate, "FunctionTemplate::New");
912 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000913 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100914 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000915 i::Handle<i::FunctionTemplateInfo> obj =
916 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
917 InitializeFunctionTemplate(obj);
Steve Block44f0eee2011-05-26 01:26:41 +0100918 int next_serial_number = isolate->next_serial_number();
919 isolate->set_next_serial_number(next_serial_number + 1);
920 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +0000921 if (callback != 0) {
922 if (data.IsEmpty()) data = v8::Undefined();
923 Utils::ToLocal(obj)->SetCallHandler(callback, data);
924 }
925 obj->set_undetectable(false);
926 obj->set_needs_access_check(false);
927
928 if (!signature.IsEmpty())
929 obj->set_signature(*Utils::OpenHandle(*signature));
930 return Utils::ToLocal(obj);
931}
932
933
934Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
935 int argc, Handle<FunctionTemplate> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100936 i::Isolate* isolate = i::Isolate::Current();
937 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
938 LOG_API(isolate, "Signature::New");
939 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000940 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100941 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000942 i::Handle<i::SignatureInfo> obj =
943 i::Handle<i::SignatureInfo>::cast(struct_obj);
944 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
945 if (argc > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100946 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000947 for (int i = 0; i < argc; i++) {
948 if (!argv[i].IsEmpty())
949 args->set(i, *Utils::OpenHandle(*argv[i]));
950 }
951 obj->set_args(*args);
952 }
953 return Utils::ToLocal(obj);
954}
955
956
957Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
958 Handle<FunctionTemplate> types[1] = { type };
959 return TypeSwitch::New(1, types);
960}
961
962
963Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100964 i::Isolate* isolate = i::Isolate::Current();
965 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
966 LOG_API(isolate, "TypeSwitch::New");
967 ENTER_V8(isolate);
968 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000969 for (int i = 0; i < argc; i++)
970 vector->set(i, *Utils::OpenHandle(*types[i]));
971 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100972 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000973 i::Handle<i::TypeSwitchInfo> obj =
974 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
975 obj->set_types(*vector);
976 return Utils::ToLocal(obj);
977}
978
979
980int TypeSwitch::match(v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100981 i::Isolate* isolate = i::Isolate::Current();
982 LOG_API(isolate, "TypeSwitch::match");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000983 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000984 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
985 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
986 i::FixedArray* types = i::FixedArray::cast(info->types());
987 for (int i = 0; i < types->length(); i++) {
988 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
989 return i + 1;
990 }
991 return 0;
992}
993
994
Ben Murdoch257744e2011-11-30 15:57:28 +0000995#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
996 i::Handle<i::Object> foreign = FromCData(cdata); \
997 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100998 } while (false)
999
1000
Steve Blocka7e24c12009-10-30 11:49:00 +00001001void FunctionTemplate::SetCallHandler(InvocationCallback callback,
1002 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001003 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1004 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
1005 ENTER_V8(isolate);
1006 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001007 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001008 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001009 i::Handle<i::CallHandlerInfo> obj =
1010 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001011 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001012 if (data.IsEmpty()) data = v8::Undefined();
1013 obj->set_data(*Utils::OpenHandle(*data));
1014 Utils::OpenHandle(this)->set_call_code(*obj);
1015}
1016
1017
Leon Clarkef7060e22010-06-03 12:02:55 +01001018static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1019 v8::Handle<String> name,
1020 AccessorGetter getter,
1021 AccessorSetter setter,
1022 v8::Handle<Value> data,
1023 v8::AccessControl settings,
1024 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01001025 i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
Leon Clarkef7060e22010-06-03 12:02:55 +01001026 ASSERT(getter != NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001027 SET_FIELD_WRAPPED(obj, set_getter, getter);
1028 SET_FIELD_WRAPPED(obj, set_setter, setter);
Leon Clarkef7060e22010-06-03 12:02:55 +01001029 if (data.IsEmpty()) data = v8::Undefined();
1030 obj->set_data(*Utils::OpenHandle(*data));
1031 obj->set_name(*Utils::OpenHandle(*name));
1032 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1033 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1034 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
1035 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
1036 return obj;
1037}
1038
1039
Steve Blocka7e24c12009-10-30 11:49:00 +00001040void FunctionTemplate::AddInstancePropertyAccessor(
1041 v8::Handle<String> name,
1042 AccessorGetter getter,
1043 AccessorSetter setter,
1044 v8::Handle<Value> data,
1045 v8::AccessControl settings,
1046 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01001047 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1048 if (IsDeadCheck(isolate,
1049 "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001050 return;
1051 }
Steve Block44f0eee2011-05-26 01:26:41 +01001052 ENTER_V8(isolate);
1053 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001054
Leon Clarkef7060e22010-06-03 12:02:55 +01001055 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
1056 getter, setter, data,
1057 settings, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00001058 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
1059 if (list->IsUndefined()) {
1060 list = NeanderArray().value();
1061 Utils::OpenHandle(this)->set_property_accessors(*list);
1062 }
1063 NeanderArray array(list);
1064 array.add(obj);
1065}
1066
1067
1068Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +01001069 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1070 if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
Steve Blocka7e24c12009-10-30 11:49:00 +00001071 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
1072 return Local<ObjectTemplate>();
Steve Block44f0eee2011-05-26 01:26:41 +01001073 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001074 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
1075 Local<ObjectTemplate> templ =
1076 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
1077 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
1078 }
1079 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
1080 Utils::OpenHandle(this)->instance_template()));
1081 return Utils::ToLocal(result);
1082}
1083
1084
1085void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01001086 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1087 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
1088 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001089 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1090}
1091
1092
1093void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001094 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1095 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
1096 return;
1097 }
1098 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001099 Utils::OpenHandle(this)->set_hidden_prototype(value);
1100}
1101
1102
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001103void FunctionTemplate::ReadOnlyPrototype() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001104 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1105 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
1106 return;
1107 }
1108 ENTER_V8(isolate);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001109 Utils::OpenHandle(this)->set_read_only_prototype(true);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001110}
1111
1112
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001113void FunctionTemplate::SetNamedInstancePropertyHandler(
Steve Blocka7e24c12009-10-30 11:49:00 +00001114 NamedPropertyGetter getter,
1115 NamedPropertySetter setter,
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001116 NamedPropertyQuery query,
Steve Blocka7e24c12009-10-30 11:49:00 +00001117 NamedPropertyDeleter remover,
1118 NamedPropertyEnumerator enumerator,
1119 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001120 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1121 if (IsDeadCheck(isolate,
1122 "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001123 return;
1124 }
Steve Block44f0eee2011-05-26 01:26:41 +01001125 ENTER_V8(isolate);
1126 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001127 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001128 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001129 i::Handle<i::InterceptorInfo> obj =
1130 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001131
1132 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1133 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1134 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1135 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1136 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1137
Steve Blocka7e24c12009-10-30 11:49:00 +00001138 if (data.IsEmpty()) data = v8::Undefined();
1139 obj->set_data(*Utils::OpenHandle(*data));
1140 Utils::OpenHandle(this)->set_named_property_handler(*obj);
1141}
1142
1143
1144void FunctionTemplate::SetIndexedInstancePropertyHandler(
1145 IndexedPropertyGetter getter,
1146 IndexedPropertySetter setter,
1147 IndexedPropertyQuery query,
1148 IndexedPropertyDeleter remover,
1149 IndexedPropertyEnumerator enumerator,
1150 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001151 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1152 if (IsDeadCheck(isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00001153 "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
1154 return;
1155 }
Steve Block44f0eee2011-05-26 01:26:41 +01001156 ENTER_V8(isolate);
1157 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001158 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001159 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001160 i::Handle<i::InterceptorInfo> obj =
1161 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001162
1163 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1164 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1165 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1166 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1167 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1168
Steve Blocka7e24c12009-10-30 11:49:00 +00001169 if (data.IsEmpty()) data = v8::Undefined();
1170 obj->set_data(*Utils::OpenHandle(*data));
1171 Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
1172}
1173
1174
1175void FunctionTemplate::SetInstanceCallAsFunctionHandler(
1176 InvocationCallback callback,
1177 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001178 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1179 if (IsDeadCheck(isolate,
1180 "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001181 return;
1182 }
Steve Block44f0eee2011-05-26 01:26:41 +01001183 ENTER_V8(isolate);
1184 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001185 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001186 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001187 i::Handle<i::CallHandlerInfo> obj =
1188 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001189 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001190 if (data.IsEmpty()) data = v8::Undefined();
1191 obj->set_data(*Utils::OpenHandle(*data));
1192 Utils::OpenHandle(this)->set_instance_call_handler(*obj);
1193}
1194
1195
1196// --- O b j e c t T e m p l a t e ---
1197
1198
1199Local<ObjectTemplate> ObjectTemplate::New() {
1200 return New(Local<FunctionTemplate>());
1201}
1202
1203
1204Local<ObjectTemplate> ObjectTemplate::New(
1205 v8::Handle<FunctionTemplate> constructor) {
Steve Block44f0eee2011-05-26 01:26:41 +01001206 i::Isolate* isolate = i::Isolate::Current();
1207 if (IsDeadCheck(isolate, "v8::ObjectTemplate::New()")) {
1208 return Local<ObjectTemplate>();
1209 }
1210 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1211 LOG_API(isolate, "ObjectTemplate::New");
1212 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001213 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001214 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001215 i::Handle<i::ObjectTemplateInfo> obj =
1216 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1217 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1218 if (!constructor.IsEmpty())
1219 obj->set_constructor(*Utils::OpenHandle(*constructor));
1220 obj->set_internal_field_count(i::Smi::FromInt(0));
1221 return Utils::ToLocal(obj);
1222}
1223
1224
1225// Ensure that the object template has a constructor. If no
1226// constructor is available we create one.
1227static void EnsureConstructor(ObjectTemplate* object_template) {
1228 if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
1229 Local<FunctionTemplate> templ = FunctionTemplate::New();
1230 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1231 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1232 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1233 }
1234}
1235
1236
1237void ObjectTemplate::SetAccessor(v8::Handle<String> name,
1238 AccessorGetter getter,
1239 AccessorSetter setter,
1240 v8::Handle<Value> data,
1241 AccessControl settings,
1242 PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +01001243 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1244 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
1245 ENTER_V8(isolate);
1246 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001247 EnsureConstructor(this);
1248 i::FunctionTemplateInfo* constructor =
1249 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1250 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1251 Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
1252 getter,
1253 setter,
1254 data,
1255 settings,
1256 attribute);
1257}
1258
1259
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001260void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
1261 NamedPropertySetter setter,
1262 NamedPropertyQuery query,
1263 NamedPropertyDeleter remover,
1264 NamedPropertyEnumerator enumerator,
1265 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001266 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1267 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
1268 return;
1269 }
1270 ENTER_V8(isolate);
1271 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001272 EnsureConstructor(this);
1273 i::FunctionTemplateInfo* constructor =
1274 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1275 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001276 Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
1277 setter,
1278 query,
1279 remover,
1280 enumerator,
1281 data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001282}
1283
1284
1285void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001286 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1287 if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
1288 ENTER_V8(isolate);
1289 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001290 EnsureConstructor(this);
1291 i::FunctionTemplateInfo* constructor =
1292 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1293 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1294 cons->set_undetectable(true);
1295}
1296
1297
1298void ObjectTemplate::SetAccessCheckCallbacks(
1299 NamedSecurityCallback named_callback,
1300 IndexedSecurityCallback indexed_callback,
1301 Handle<Value> data,
1302 bool turned_on_by_default) {
Steve Block44f0eee2011-05-26 01:26:41 +01001303 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1304 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
1305 return;
1306 }
1307 ENTER_V8(isolate);
1308 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001309 EnsureConstructor(this);
1310
1311 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001312 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001313 i::Handle<i::AccessCheckInfo> info =
1314 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001315
1316 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1317 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1318
Steve Blocka7e24c12009-10-30 11:49:00 +00001319 if (data.IsEmpty()) data = v8::Undefined();
1320 info->set_data(*Utils::OpenHandle(*data));
1321
1322 i::FunctionTemplateInfo* constructor =
1323 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1324 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1325 cons->set_access_check_info(*info);
1326 cons->set_needs_access_check(turned_on_by_default);
1327}
1328
1329
1330void ObjectTemplate::SetIndexedPropertyHandler(
1331 IndexedPropertyGetter getter,
1332 IndexedPropertySetter setter,
1333 IndexedPropertyQuery query,
1334 IndexedPropertyDeleter remover,
1335 IndexedPropertyEnumerator enumerator,
1336 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001337 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1338 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
1339 return;
1340 }
1341 ENTER_V8(isolate);
1342 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001343 EnsureConstructor(this);
1344 i::FunctionTemplateInfo* constructor =
1345 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1346 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1347 Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
1348 setter,
1349 query,
1350 remover,
1351 enumerator,
1352 data);
1353}
1354
1355
1356void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
1357 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001358 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1359 if (IsDeadCheck(isolate,
1360 "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
1361 return;
1362 }
1363 ENTER_V8(isolate);
1364 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001365 EnsureConstructor(this);
1366 i::FunctionTemplateInfo* constructor =
1367 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1368 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1369 Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
1370}
1371
1372
1373int ObjectTemplate::InternalFieldCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01001374 if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
1375 "v8::ObjectTemplate::InternalFieldCount()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001376 return 0;
1377 }
1378 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1379}
1380
1381
1382void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001383 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1384 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
1385 return;
1386 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001387 if (!ApiCheck(i::Smi::IsValid(value),
1388 "v8::ObjectTemplate::SetInternalFieldCount()",
1389 "Invalid internal field count")) {
1390 return;
1391 }
Steve Block44f0eee2011-05-26 01:26:41 +01001392 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001393 if (value > 0) {
1394 // The internal field count is set by the constructor function's
1395 // construct code, so we ensure that there is a constructor
1396 // function to do the setting.
1397 EnsureConstructor(this);
1398 }
1399 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1400}
1401
1402
1403// --- S c r i p t D a t a ---
1404
1405
1406ScriptData* ScriptData::PreCompile(const char* input, int length) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001407 i::Utf8ToUC16CharacterStream stream(
1408 reinterpret_cast<const unsigned char*>(input), length);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001409 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping);
Steve Blocka7e24c12009-10-30 11:49:00 +00001410}
1411
1412
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001413ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1414 i::Handle<i::String> str = Utils::OpenHandle(*source);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001415 if (str->IsExternalTwoByteString()) {
1416 i::ExternalTwoByteStringUC16CharacterStream stream(
1417 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001418 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001419 } else {
1420 i::GenericStringUC16CharacterStream stream(str, 0, str->length());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001421 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001422 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001423}
1424
1425
Leon Clarkef7060e22010-06-03 12:02:55 +01001426ScriptData* ScriptData::New(const char* data, int length) {
1427 // Return an empty ScriptData if the length is obviously invalid.
1428 if (length % sizeof(unsigned) != 0) {
Iain Merrick9ac36c92010-09-13 15:29:50 +01001429 return new i::ScriptDataImpl();
Leon Clarkef7060e22010-06-03 12:02:55 +01001430 }
1431
1432 // Copy the data to ensure it is properly aligned.
1433 int deserialized_data_length = length / sizeof(unsigned);
Iain Merrick9ac36c92010-09-13 15:29:50 +01001434 // If aligned, don't create a copy of the data.
1435 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1436 return new i::ScriptDataImpl(data, length);
1437 }
1438 // Copy the data to align it.
Leon Clarkef7060e22010-06-03 12:02:55 +01001439 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001440 i::OS::MemCopy(deserialized_data, data, length);
Leon Clarkef7060e22010-06-03 12:02:55 +01001441
1442 return new i::ScriptDataImpl(
1443 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
Steve Blocka7e24c12009-10-30 11:49:00 +00001444}
1445
1446
1447// --- S c r i p t ---
1448
1449
1450Local<Script> Script::New(v8::Handle<String> source,
1451 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001452 v8::ScriptData* pre_data,
1453 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001454 i::Isolate* isolate = i::Isolate::Current();
1455 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1456 LOG_API(isolate, "Script::New");
1457 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001458 i::Handle<i::String> str = Utils::OpenHandle(*source);
1459 i::Handle<i::Object> name_obj;
1460 int line_offset = 0;
1461 int column_offset = 0;
1462 if (origin != NULL) {
1463 if (!origin->ResourceName().IsEmpty()) {
1464 name_obj = Utils::OpenHandle(*origin->ResourceName());
1465 }
1466 if (!origin->ResourceLineOffset().IsEmpty()) {
1467 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1468 }
1469 if (!origin->ResourceColumnOffset().IsEmpty()) {
1470 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
1471 }
1472 }
Steve Block44f0eee2011-05-26 01:26:41 +01001473 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001474 i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001475 // We assert that the pre-data is sane, even though we can actually
1476 // handle it if it turns out not to be in release mode.
Andrei Popescu402d9372010-02-26 13:31:12 +00001477 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
Steve Blocka7e24c12009-10-30 11:49:00 +00001478 // If the pre-data isn't sane we simply ignore it
Andrei Popescu402d9372010-02-26 13:31:12 +00001479 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1480 pre_data_impl = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001481 }
Steve Block6ded16b2010-05-10 14:33:55 +01001482 i::Handle<i::SharedFunctionInfo> result =
Andrei Popescu31002712010-02-23 13:46:05 +00001483 i::Compiler::Compile(str,
1484 name_obj,
1485 line_offset,
1486 column_offset,
1487 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001488 pre_data_impl,
1489 Utils::OpenHandle(*script_data),
Andrei Popescu31002712010-02-23 13:46:05 +00001490 i::NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001491 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01001492 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
Steve Block6ded16b2010-05-10 14:33:55 +01001493 return Local<Script>(ToApi<Script>(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00001494}
1495
1496
1497Local<Script> Script::New(v8::Handle<String> source,
1498 v8::Handle<Value> file_name) {
1499 ScriptOrigin origin(file_name);
1500 return New(source, &origin);
1501}
1502
1503
1504Local<Script> Script::Compile(v8::Handle<String> source,
1505 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001506 v8::ScriptData* pre_data,
1507 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001508 i::Isolate* isolate = i::Isolate::Current();
1509 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1510 LOG_API(isolate, "Script::Compile");
1511 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001512 Local<Script> generic = New(source, origin, pre_data, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001513 if (generic.IsEmpty())
1514 return generic;
Steve Block6ded16b2010-05-10 14:33:55 +01001515 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1516 i::Handle<i::SharedFunctionInfo> function =
1517 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
Steve Blocka7e24c12009-10-30 11:49:00 +00001518 i::Handle<i::JSFunction> result =
Steve Block44f0eee2011-05-26 01:26:41 +01001519 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1520 function,
1521 isolate->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001522 return Local<Script>(ToApi<Script>(result));
1523}
1524
1525
1526Local<Script> Script::Compile(v8::Handle<String> source,
Andrei Popescu402d9372010-02-26 13:31:12 +00001527 v8::Handle<Value> file_name,
1528 v8::Handle<String> script_data) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001529 ScriptOrigin origin(file_name);
Andrei Popescu402d9372010-02-26 13:31:12 +00001530 return Compile(source, &origin, 0, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001531}
1532
1533
1534Local<Value> Script::Run() {
Steve Block44f0eee2011-05-26 01:26:41 +01001535 i::Isolate* isolate = i::Isolate::Current();
1536 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1537 LOG_API(isolate, "Script::Run");
1538 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001539 i::Object* raw_result = NULL;
1540 {
Steve Block44f0eee2011-05-26 01:26:41 +01001541 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001542 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1543 i::Handle<i::JSFunction> fun;
1544 if (obj->IsSharedFunctionInfo()) {
1545 i::Handle<i::SharedFunctionInfo>
Steve Block44f0eee2011-05-26 01:26:41 +01001546 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
1547 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
1548 function_info, isolate->global_context());
Steve Block6ded16b2010-05-10 14:33:55 +01001549 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001550 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001551 }
Steve Block44f0eee2011-05-26 01:26:41 +01001552 EXCEPTION_PREAMBLE(isolate);
1553 i::Handle<i::Object> receiver(
1554 isolate->context()->global_proxy(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001555 i::Handle<i::Object> result =
1556 i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001557 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001558 raw_result = *result;
1559 }
Steve Block44f0eee2011-05-26 01:26:41 +01001560 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001561 return Utils::ToLocal(result);
1562}
1563
1564
Steve Block6ded16b2010-05-10 14:33:55 +01001565static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1566 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1567 i::Handle<i::SharedFunctionInfo> result;
1568 if (obj->IsSharedFunctionInfo()) {
1569 result =
1570 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1571 } else {
1572 result =
1573 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1574 }
1575 return result;
1576}
1577
1578
Steve Blocka7e24c12009-10-30 11:49:00 +00001579Local<Value> Script::Id() {
Steve Block44f0eee2011-05-26 01:26:41 +01001580 i::Isolate* isolate = i::Isolate::Current();
1581 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1582 LOG_API(isolate, "Script::Id");
Steve Blocka7e24c12009-10-30 11:49:00 +00001583 i::Object* raw_id = NULL;
1584 {
Steve Block44f0eee2011-05-26 01:26:41 +01001585 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001586 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1587 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001588 i::Handle<i::Object> id(script->id());
1589 raw_id = *id;
1590 }
1591 i::Handle<i::Object> id(raw_id);
1592 return Utils::ToLocal(id);
1593}
1594
1595
Steve Blockd0582a62009-12-15 09:54:21 +00001596void Script::SetData(v8::Handle<String> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001597 i::Isolate* isolate = i::Isolate::Current();
1598 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1599 LOG_API(isolate, "Script::SetData");
Steve Blocka7e24c12009-10-30 11:49:00 +00001600 {
Steve Block44f0eee2011-05-26 01:26:41 +01001601 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001602 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001603 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
Steve Block6ded16b2010-05-10 14:33:55 +01001604 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001605 script->set_data(*raw_data);
1606 }
1607}
1608
1609
1610// --- E x c e p t i o n s ---
1611
1612
1613v8::TryCatch::TryCatch()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001614 : isolate_(i::Isolate::Current()),
1615 next_(isolate_->try_catch_handler_address()),
1616 exception_(isolate_->heap()->the_hole_value()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001617 message_(i::Smi::FromInt(0)),
1618 is_verbose_(false),
1619 can_continue_(true),
1620 capture_message_(true),
Steve Blockd0582a62009-12-15 09:54:21 +00001621 rethrow_(false) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001622 isolate_->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001623}
1624
1625
1626v8::TryCatch::~TryCatch() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001627 ASSERT(isolate_ == i::Isolate::Current());
Steve Blockd0582a62009-12-15 09:54:21 +00001628 if (rethrow_) {
1629 v8::HandleScope scope;
1630 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001631 isolate_->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001632 v8::ThrowException(exc);
1633 } else {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001634 isolate_->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001635 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001636}
1637
1638
1639bool v8::TryCatch::HasCaught() const {
1640 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1641}
1642
1643
1644bool v8::TryCatch::CanContinue() const {
1645 return can_continue_;
1646}
1647
1648
Steve Blockd0582a62009-12-15 09:54:21 +00001649v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1650 if (!HasCaught()) return v8::Local<v8::Value>();
1651 rethrow_ = true;
1652 return v8::Undefined();
1653}
1654
1655
Steve Blocka7e24c12009-10-30 11:49:00 +00001656v8::Local<Value> v8::TryCatch::Exception() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001657 ASSERT(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001658 if (HasCaught()) {
1659 // Check for out of memory exception.
1660 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001661 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001662 } else {
1663 return v8::Local<Value>();
1664 }
1665}
1666
1667
1668v8::Local<Value> v8::TryCatch::StackTrace() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001669 ASSERT(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001670 if (HasCaught()) {
1671 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1672 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001673 i::HandleScope scope(isolate_);
1674 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
1675 i::Handle<i::String> name = isolate_->factory()->LookupAsciiSymbol("stack");
1676 if (!obj->HasProperty(*name)) return v8::Local<Value>();
1677 i::Handle<i::Object> value = i::GetProperty(obj, name);
1678 if (value.is_null()) return v8::Local<Value>();
1679 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001680 } else {
1681 return v8::Local<Value>();
1682 }
1683}
1684
1685
1686v8::Local<v8::Message> v8::TryCatch::Message() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001687 ASSERT(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001688 if (HasCaught() && message_ != i::Smi::FromInt(0)) {
1689 i::Object* message = reinterpret_cast<i::Object*>(message_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001690 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001691 } else {
1692 return v8::Local<v8::Message>();
1693 }
1694}
1695
1696
1697void v8::TryCatch::Reset() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001698 ASSERT(isolate_ == i::Isolate::Current());
1699 exception_ = isolate_->heap()->the_hole_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00001700 message_ = i::Smi::FromInt(0);
1701}
1702
1703
1704void v8::TryCatch::SetVerbose(bool value) {
1705 is_verbose_ = value;
1706}
1707
1708
1709void v8::TryCatch::SetCaptureMessage(bool value) {
1710 capture_message_ = value;
1711}
1712
1713
1714// --- M e s s a g e ---
1715
1716
1717Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001718 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1719 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
1720 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001721 HandleScope scope;
1722 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1723 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
1724 Local<String> result = Utils::ToLocal(raw_result);
1725 return scope.Close(result);
1726}
1727
1728
1729v8::Handle<Value> Message::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001730 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1731 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001732 return Local<String>();
1733 }
Steve Block44f0eee2011-05-26 01:26:41 +01001734 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001735 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001736 i::Handle<i::JSMessageObject> message =
1737 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001738 // Return this.script.name.
1739 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001740 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001741 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
1742 return scope.Close(Utils::ToLocal(resource_name));
1743}
1744
1745
1746v8::Handle<Value> Message::GetScriptData() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001747 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1748 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001749 return Local<Value>();
1750 }
Steve Block44f0eee2011-05-26 01:26:41 +01001751 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001752 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001753 i::Handle<i::JSMessageObject> message =
1754 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001755 // Return this.script.data.
1756 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001757 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001758 i::Handle<i::Object> data(i::Script::cast(script->value())->data());
1759 return scope.Close(Utils::ToLocal(data));
1760}
1761
1762
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001763v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001764 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1765 if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001766 return Local<v8::StackTrace>();
1767 }
Steve Block44f0eee2011-05-26 01:26:41 +01001768 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001769 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001770 i::Handle<i::JSMessageObject> message =
1771 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1772 i::Handle<i::Object> stackFramesObj(message->stack_frames());
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001773 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
1774 i::Handle<i::JSArray> stackTrace =
1775 i::Handle<i::JSArray>::cast(stackFramesObj);
1776 return scope.Close(Utils::StackTraceToLocal(stackTrace));
1777}
1778
1779
Steve Blocka7e24c12009-10-30 11:49:00 +00001780static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1781 i::Handle<i::Object> recv,
1782 int argc,
1783 i::Object** argv[],
1784 bool* has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +01001785 i::Isolate* isolate = i::Isolate::Current();
1786 i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name);
John Reck59135872010-11-02 12:39:01 -07001787 i::Object* object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001788 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
Steve Blocka7e24c12009-10-30 11:49:00 +00001789 i::Handle<i::JSFunction> fun =
1790 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
1791 i::Handle<i::Object> value =
1792 i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
1793 return value;
1794}
1795
1796
1797static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1798 i::Handle<i::Object> data,
1799 bool* has_pending_exception) {
1800 i::Object** argv[1] = { data.location() };
1801 return CallV8HeapFunction(name,
Steve Block44f0eee2011-05-26 01:26:41 +01001802 i::Isolate::Current()->js_builtins_object(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001803 1,
1804 argv,
1805 has_pending_exception);
1806}
1807
1808
1809int Message::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001810 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1811 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
1812 ENTER_V8(isolate);
1813 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001814
Steve Block44f0eee2011-05-26 01:26:41 +01001815 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001816 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
1817 Utils::OpenHandle(this),
1818 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001819 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001820 return static_cast<int>(result->Number());
1821}
1822
1823
1824int Message::GetStartPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001825 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1826 if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
1827 ENTER_V8(isolate);
1828 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001829 i::Handle<i::JSMessageObject> message =
1830 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1831 return message->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001832}
1833
1834
1835int Message::GetEndPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001836 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1837 if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
1838 ENTER_V8(isolate);
1839 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001840 i::Handle<i::JSMessageObject> message =
1841 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1842 return message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001843}
1844
1845
1846int Message::GetStartColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001847 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1848 if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
1849 return kNoColumnInfo;
1850 }
1851 ENTER_V8(isolate);
1852 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001853 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001854 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001855 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1856 "GetPositionInLine",
1857 data_obj,
1858 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001859 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001860 return static_cast<int>(start_col_obj->Number());
1861}
1862
1863
1864int Message::GetEndColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001865 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1866 if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
1867 ENTER_V8(isolate);
1868 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001869 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001870 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001871 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1872 "GetPositionInLine",
1873 data_obj,
1874 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001875 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Block1e0659c2011-05-24 12:43:12 +01001876 i::Handle<i::JSMessageObject> message =
1877 i::Handle<i::JSMessageObject>::cast(data_obj);
1878 int start = message->start_position();
1879 int end = message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001880 return static_cast<int>(start_col_obj->Number()) + (end - start);
1881}
1882
1883
1884Local<String> Message::GetSourceLine() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001885 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1886 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
1887 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001888 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01001889 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001890 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
1891 Utils::OpenHandle(this),
1892 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001893 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001894 if (result->IsString()) {
1895 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
1896 } else {
1897 return Local<String>();
1898 }
1899}
1900
1901
1902void Message::PrintCurrentStackTrace(FILE* out) {
Steve Block44f0eee2011-05-26 01:26:41 +01001903 i::Isolate* isolate = i::Isolate::Current();
1904 if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
1905 ENTER_V8(isolate);
1906 isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00001907}
1908
1909
Kristian Monsen25f61362010-05-21 11:50:48 +01001910// --- S t a c k T r a c e ---
1911
1912Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01001913 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1914 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
1915 return Local<StackFrame>();
1916 }
1917 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001918 HandleScope scope;
1919 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
John Reck59135872010-11-02 12:39:01 -07001920 i::Object* raw_object = self->GetElementNoExceptionThrown(index);
1921 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001922 return scope.Close(Utils::StackFrameToLocal(obj));
1923}
1924
1925
1926int StackTrace::GetFrameCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001927 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1928 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
1929 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001930 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
1931}
1932
1933
1934Local<Array> StackTrace::AsArray() {
Steve Block44f0eee2011-05-26 01:26:41 +01001935 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1936 if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
1937 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001938 return Utils::ToLocal(Utils::OpenHandle(this));
1939}
1940
1941
1942Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
1943 StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01001944 i::Isolate* isolate = i::Isolate::Current();
1945 if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
1946 Local<StackTrace>();
1947 }
1948 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001949 i::Handle<i::JSArray> stackTrace =
Steve Block44f0eee2011-05-26 01:26:41 +01001950 isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001951 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01001952}
1953
1954
1955// --- S t a c k F r a m e ---
1956
1957int StackFrame::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001958 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1959 if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001960 return Message::kNoLineNumberInfo;
1961 }
Steve Block44f0eee2011-05-26 01:26:41 +01001962 ENTER_V8(isolate);
1963 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001964 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1965 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
1966 if (!line->IsSmi()) {
1967 return Message::kNoLineNumberInfo;
1968 }
1969 return i::Smi::cast(*line)->value();
1970}
1971
1972
1973int StackFrame::GetColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001974 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1975 if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001976 return Message::kNoColumnInfo;
1977 }
Steve Block44f0eee2011-05-26 01:26:41 +01001978 ENTER_V8(isolate);
1979 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001980 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1981 i::Handle<i::Object> column = GetProperty(self, "column");
1982 if (!column->IsSmi()) {
1983 return Message::kNoColumnInfo;
1984 }
1985 return i::Smi::cast(*column)->value();
1986}
1987
1988
1989Local<String> StackFrame::GetScriptName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001990 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1991 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
1992 return Local<String>();
1993 }
1994 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001995 HandleScope scope;
1996 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1997 i::Handle<i::Object> name = GetProperty(self, "scriptName");
1998 if (!name->IsString()) {
1999 return Local<String>();
2000 }
2001 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2002}
2003
2004
Ben Murdochf87a2032010-10-22 12:50:53 +01002005Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002006 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2007 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
Ben Murdochf87a2032010-10-22 12:50:53 +01002008 return Local<String>();
2009 }
Steve Block44f0eee2011-05-26 01:26:41 +01002010 ENTER_V8(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01002011 HandleScope scope;
2012 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2013 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
2014 if (!name->IsString()) {
2015 return Local<String>();
2016 }
2017 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2018}
2019
2020
Kristian Monsen25f61362010-05-21 11:50:48 +01002021Local<String> StackFrame::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002022 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2023 if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
2024 return Local<String>();
2025 }
2026 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002027 HandleScope scope;
2028 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2029 i::Handle<i::Object> name = GetProperty(self, "functionName");
2030 if (!name->IsString()) {
2031 return Local<String>();
2032 }
2033 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2034}
2035
2036
2037bool StackFrame::IsEval() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002038 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2039 if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
2040 ENTER_V8(isolate);
2041 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002042 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2043 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
2044 return is_eval->IsTrue();
2045}
2046
2047
2048bool StackFrame::IsConstructor() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002049 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2050 if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
2051 ENTER_V8(isolate);
2052 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002053 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2054 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
2055 return is_constructor->IsTrue();
2056}
2057
2058
Steve Blocka7e24c12009-10-30 11:49:00 +00002059// --- D a t a ---
2060
2061bool Value::IsUndefined() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002062 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
2063 return false;
2064 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002065 return Utils::OpenHandle(this)->IsUndefined();
2066}
2067
2068
2069bool Value::IsNull() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002070 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002071 return Utils::OpenHandle(this)->IsNull();
2072}
2073
2074
2075bool Value::IsTrue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002076 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002077 return Utils::OpenHandle(this)->IsTrue();
2078}
2079
2080
2081bool Value::IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002082 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002083 return Utils::OpenHandle(this)->IsFalse();
2084}
2085
2086
2087bool Value::IsFunction() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002088 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFunction()")) {
2089 return false;
2090 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002091 return Utils::OpenHandle(this)->IsJSFunction();
2092}
2093
2094
2095bool Value::FullIsString() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002096 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsString()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002097 bool result = Utils::OpenHandle(this)->IsString();
2098 ASSERT_EQ(result, QuickIsString());
2099 return result;
2100}
2101
2102
2103bool Value::IsArray() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002104 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002105 return Utils::OpenHandle(this)->IsJSArray();
2106}
2107
2108
2109bool Value::IsObject() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002110 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002111 return Utils::OpenHandle(this)->IsJSObject();
2112}
2113
2114
2115bool Value::IsNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002116 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002117 return Utils::OpenHandle(this)->IsNumber();
2118}
2119
2120
2121bool Value::IsBoolean() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002122 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsBoolean()")) {
2123 return false;
2124 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002125 return Utils::OpenHandle(this)->IsBoolean();
2126}
2127
2128
2129bool Value::IsExternal() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002130 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
2131 return false;
2132 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002133 return Utils::OpenHandle(this)->IsForeign();
Steve Blocka7e24c12009-10-30 11:49:00 +00002134}
2135
2136
2137bool Value::IsInt32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002138 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002139 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2140 if (obj->IsSmi()) return true;
2141 if (obj->IsNumber()) {
2142 double value = obj->Number();
2143 return i::FastI2D(i::FastD2I(value)) == value;
2144 }
2145 return false;
2146}
2147
2148
Steve Block6ded16b2010-05-10 14:33:55 +01002149bool Value::IsUint32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002150 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUint32()")) return false;
Steve Block6ded16b2010-05-10 14:33:55 +01002151 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2152 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2153 if (obj->IsNumber()) {
2154 double value = obj->Number();
2155 return i::FastUI2D(i::FastD2UI(value)) == value;
2156 }
2157 return false;
2158}
2159
2160
Steve Blocka7e24c12009-10-30 11:49:00 +00002161bool Value::IsDate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002162 i::Isolate* isolate = i::Isolate::Current();
2163 if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002164 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002165 return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00002166}
2167
2168
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002169bool Value::IsStringObject() const {
2170 i::Isolate* isolate = i::Isolate::Current();
2171 if (IsDeadCheck(isolate, "v8::Value::IsStringObject()")) return false;
2172 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2173 return obj->HasSpecificClassOf(isolate->heap()->String_symbol());
2174}
2175
2176
2177bool Value::IsNumberObject() const {
2178 i::Isolate* isolate = i::Isolate::Current();
2179 if (IsDeadCheck(isolate, "v8::Value::IsNumberObject()")) return false;
2180 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2181 return obj->HasSpecificClassOf(isolate->heap()->Number_symbol());
2182}
2183
2184
2185static i::Object* LookupBuiltin(i::Isolate* isolate,
2186 const char* builtin_name) {
2187 i::Handle<i::String> symbol =
2188 isolate->factory()->LookupAsciiSymbol(builtin_name);
2189 i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
2190 return builtins->GetPropertyNoExceptionThrown(*symbol);
2191}
2192
2193
2194static bool CheckConstructor(i::Isolate* isolate,
2195 i::Handle<i::JSObject> obj,
2196 const char* class_name) {
2197 return obj->map()->constructor() == LookupBuiltin(isolate, class_name);
2198}
2199
2200
2201bool Value::IsNativeError() const {
2202 i::Isolate* isolate = i::Isolate::Current();
2203 if (IsDeadCheck(isolate, "v8::Value::IsNativeError()")) return false;
2204 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2205 if (obj->IsJSObject()) {
2206 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
2207 return CheckConstructor(isolate, js_obj, "$Error") ||
2208 CheckConstructor(isolate, js_obj, "$EvalError") ||
2209 CheckConstructor(isolate, js_obj, "$RangeError") ||
2210 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2211 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2212 CheckConstructor(isolate, js_obj, "$TypeError") ||
2213 CheckConstructor(isolate, js_obj, "$URIError");
2214 } else {
2215 return false;
2216 }
2217}
2218
2219
2220bool Value::IsBooleanObject() const {
2221 i::Isolate* isolate = i::Isolate::Current();
2222 if (IsDeadCheck(isolate, "v8::Value::IsBooleanObject()")) return false;
2223 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2224 return obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol());
2225}
2226
2227
Iain Merrick75681382010-08-19 15:07:18 +01002228bool Value::IsRegExp() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002229 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
Iain Merrick75681382010-08-19 15:07:18 +01002230 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2231 return obj->IsJSRegExp();
2232}
2233
2234
Steve Blocka7e24c12009-10-30 11:49:00 +00002235Local<String> Value::ToString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002236 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2237 i::Handle<i::Object> str;
2238 if (obj->IsString()) {
2239 str = obj;
2240 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002241 i::Isolate* isolate = i::Isolate::Current();
2242 if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
2243 return Local<String>();
2244 }
2245 LOG_API(isolate, "ToString");
2246 ENTER_V8(isolate);
2247 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002248 str = i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002249 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002250 }
2251 return Local<String>(ToApi<String>(str));
2252}
2253
2254
2255Local<String> Value::ToDetailString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002256 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2257 i::Handle<i::Object> str;
2258 if (obj->IsString()) {
2259 str = obj;
2260 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002261 i::Isolate* isolate = i::Isolate::Current();
2262 if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
2263 return Local<String>();
2264 }
2265 LOG_API(isolate, "ToDetailString");
2266 ENTER_V8(isolate);
2267 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002268 str = i::Execution::ToDetailString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002269 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002270 }
2271 return Local<String>(ToApi<String>(str));
2272}
2273
2274
2275Local<v8::Object> Value::ToObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002276 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2277 i::Handle<i::Object> val;
2278 if (obj->IsJSObject()) {
2279 val = obj;
2280 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002281 i::Isolate* isolate = i::Isolate::Current();
2282 if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
2283 return Local<v8::Object>();
2284 }
2285 LOG_API(isolate, "ToObject");
2286 ENTER_V8(isolate);
2287 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002288 val = i::Execution::ToObject(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002289 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002290 }
2291 return Local<v8::Object>(ToApi<Object>(val));
2292}
2293
2294
2295Local<Boolean> Value::ToBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002296 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2297 if (obj->IsBoolean()) {
2298 return Local<Boolean>(ToApi<Boolean>(obj));
2299 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002300 i::Isolate* isolate = i::Isolate::Current();
2301 if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
2302 return Local<Boolean>();
2303 }
2304 LOG_API(isolate, "ToBoolean");
2305 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002306 i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
2307 return Local<Boolean>(ToApi<Boolean>(val));
2308 }
2309}
2310
2311
2312Local<Number> Value::ToNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002313 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2314 i::Handle<i::Object> num;
2315 if (obj->IsNumber()) {
2316 num = obj;
2317 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002318 i::Isolate* isolate = i::Isolate::Current();
2319 if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
2320 return Local<Number>();
2321 }
2322 LOG_API(isolate, "ToNumber");
2323 ENTER_V8(isolate);
2324 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002325 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002326 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002327 }
2328 return Local<Number>(ToApi<Number>(num));
2329}
2330
2331
2332Local<Integer> Value::ToInteger() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002333 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2334 i::Handle<i::Object> num;
2335 if (obj->IsSmi()) {
2336 num = obj;
2337 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002338 i::Isolate* isolate = i::Isolate::Current();
2339 if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
2340 LOG_API(isolate, "ToInteger");
2341 ENTER_V8(isolate);
2342 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002343 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002344 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002345 }
2346 return Local<Integer>(ToApi<Integer>(num));
2347}
2348
2349
2350void External::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002351 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002352 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch257744e2011-11-30 15:57:28 +00002353 ApiCheck(obj->IsForeign(),
Steve Blocka7e24c12009-10-30 11:49:00 +00002354 "v8::External::Cast()",
2355 "Could not convert to external");
2356}
2357
2358
2359void v8::Object::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002360 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002361 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2362 ApiCheck(obj->IsJSObject(),
2363 "v8::Object::Cast()",
2364 "Could not convert to object");
2365}
2366
2367
2368void v8::Function::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002369 if (IsDeadCheck(i::Isolate::Current(), "v8::Function::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002370 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2371 ApiCheck(obj->IsJSFunction(),
2372 "v8::Function::Cast()",
2373 "Could not convert to function");
2374}
2375
2376
2377void v8::String::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002378 if (IsDeadCheck(i::Isolate::Current(), "v8::String::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002379 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2380 ApiCheck(obj->IsString(),
2381 "v8::String::Cast()",
2382 "Could not convert to string");
2383}
2384
2385
2386void v8::Number::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002387 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002388 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2389 ApiCheck(obj->IsNumber(),
2390 "v8::Number::Cast()",
2391 "Could not convert to number");
2392}
2393
2394
2395void v8::Integer::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002396 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002397 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2398 ApiCheck(obj->IsNumber(),
2399 "v8::Integer::Cast()",
2400 "Could not convert to number");
2401}
2402
2403
2404void v8::Array::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002405 if (IsDeadCheck(i::Isolate::Current(), "v8::Array::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002406 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2407 ApiCheck(obj->IsJSArray(),
2408 "v8::Array::Cast()",
2409 "Could not convert to array");
2410}
2411
2412
2413void v8::Date::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002414 i::Isolate* isolate = i::Isolate::Current();
2415 if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002416 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Steve Block44f0eee2011-05-26 01:26:41 +01002417 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
Steve Blocka7e24c12009-10-30 11:49:00 +00002418 "v8::Date::Cast()",
2419 "Could not convert to date");
2420}
2421
2422
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002423void v8::StringObject::CheckCast(v8::Value* that) {
2424 i::Isolate* isolate = i::Isolate::Current();
2425 if (IsDeadCheck(isolate, "v8::StringObject::Cast()")) return;
2426 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2427 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_symbol()),
2428 "v8::StringObject::Cast()",
2429 "Could not convert to StringObject");
2430}
2431
2432
2433void v8::NumberObject::CheckCast(v8::Value* that) {
2434 i::Isolate* isolate = i::Isolate::Current();
2435 if (IsDeadCheck(isolate, "v8::NumberObject::Cast()")) return;
2436 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2437 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_symbol()),
2438 "v8::NumberObject::Cast()",
2439 "Could not convert to NumberObject");
2440}
2441
2442
2443void v8::BooleanObject::CheckCast(v8::Value* that) {
2444 i::Isolate* isolate = i::Isolate::Current();
2445 if (IsDeadCheck(isolate, "v8::BooleanObject::Cast()")) return;
2446 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2447 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol()),
2448 "v8::BooleanObject::Cast()",
2449 "Could not convert to BooleanObject");
2450}
2451
2452
Ben Murdochf87a2032010-10-22 12:50:53 +01002453void v8::RegExp::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002454 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
Ben Murdochf87a2032010-10-22 12:50:53 +01002455 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2456 ApiCheck(obj->IsJSRegExp(),
2457 "v8::RegExp::Cast()",
2458 "Could not convert to regular expression");
2459}
2460
2461
Steve Blocka7e24c12009-10-30 11:49:00 +00002462bool Value::BooleanValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002463 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2464 if (obj->IsBoolean()) {
2465 return obj->IsTrue();
2466 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002467 i::Isolate* isolate = i::Isolate::Current();
2468 if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
2469 LOG_API(isolate, "BooleanValue");
2470 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002471 i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
2472 return value->IsTrue();
2473 }
2474}
2475
2476
2477double Value::NumberValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002478 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2479 i::Handle<i::Object> num;
2480 if (obj->IsNumber()) {
2481 num = obj;
2482 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002483 i::Isolate* isolate = i::Isolate::Current();
2484 if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
2485 return i::OS::nan_value();
2486 }
2487 LOG_API(isolate, "NumberValue");
2488 ENTER_V8(isolate);
2489 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002490 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002491 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002492 }
2493 return num->Number();
2494}
2495
2496
2497int64_t Value::IntegerValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002498 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2499 i::Handle<i::Object> num;
2500 if (obj->IsNumber()) {
2501 num = obj;
2502 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002503 i::Isolate* isolate = i::Isolate::Current();
2504 if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
2505 LOG_API(isolate, "IntegerValue");
2506 ENTER_V8(isolate);
2507 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002508 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002509 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002510 }
2511 if (num->IsSmi()) {
2512 return i::Smi::cast(*num)->value();
2513 } else {
2514 return static_cast<int64_t>(num->Number());
2515 }
2516}
2517
2518
2519Local<Int32> Value::ToInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002520 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2521 i::Handle<i::Object> num;
2522 if (obj->IsSmi()) {
2523 num = obj;
2524 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002525 i::Isolate* isolate = i::Isolate::Current();
2526 if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
2527 LOG_API(isolate, "ToInt32");
2528 ENTER_V8(isolate);
2529 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002530 num = i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002531 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002532 }
2533 return Local<Int32>(ToApi<Int32>(num));
2534}
2535
2536
2537Local<Uint32> Value::ToUint32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002538 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2539 i::Handle<i::Object> num;
2540 if (obj->IsSmi()) {
2541 num = obj;
2542 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002543 i::Isolate* isolate = i::Isolate::Current();
2544 if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
2545 LOG_API(isolate, "ToUInt32");
2546 ENTER_V8(isolate);
2547 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002548 num = i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002549 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002550 }
2551 return Local<Uint32>(ToApi<Uint32>(num));
2552}
2553
2554
2555Local<Uint32> Value::ToArrayIndex() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002556 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2557 if (obj->IsSmi()) {
2558 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2559 return Local<Uint32>();
2560 }
Steve Block44f0eee2011-05-26 01:26:41 +01002561 i::Isolate* isolate = i::Isolate::Current();
2562 if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
2563 LOG_API(isolate, "ToArrayIndex");
2564 ENTER_V8(isolate);
2565 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002566 i::Handle<i::Object> string_obj =
2567 i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002568 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002569 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2570 uint32_t index;
2571 if (str->AsArrayIndex(&index)) {
2572 i::Handle<i::Object> value;
2573 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
2574 value = i::Handle<i::Object>(i::Smi::FromInt(index));
2575 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002576 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002577 }
2578 return Utils::Uint32ToLocal(value);
2579 }
2580 return Local<Uint32>();
2581}
2582
2583
2584int32_t Value::Int32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002585 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2586 if (obj->IsSmi()) {
2587 return i::Smi::cast(*obj)->value();
2588 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002589 i::Isolate* isolate = i::Isolate::Current();
2590 if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
2591 LOG_API(isolate, "Int32Value (slow)");
2592 ENTER_V8(isolate);
2593 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002594 i::Handle<i::Object> num =
2595 i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002596 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002597 if (num->IsSmi()) {
2598 return i::Smi::cast(*num)->value();
2599 } else {
2600 return static_cast<int32_t>(num->Number());
2601 }
2602 }
2603}
2604
2605
2606bool Value::Equals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002607 i::Isolate* isolate = i::Isolate::Current();
2608 if (IsDeadCheck(isolate, "v8::Value::Equals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002609 || EmptyCheck("v8::Value::Equals()", this)
2610 || EmptyCheck("v8::Value::Equals()", that)) {
2611 return false;
2612 }
Steve Block44f0eee2011-05-26 01:26:41 +01002613 LOG_API(isolate, "Equals");
2614 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002615 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2616 i::Handle<i::Object> other = Utils::OpenHandle(*that);
Steve Block1e0659c2011-05-24 12:43:12 +01002617 // If both obj and other are JSObjects, we'd better compare by identity
2618 // immediately when going into JS builtin. The reason is Invoke
2619 // would overwrite global object receiver with global proxy.
2620 if (obj->IsJSObject() && other->IsJSObject()) {
2621 return *obj == *other;
2622 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002623 i::Object** args[1] = { other.location() };
Steve Block44f0eee2011-05-26 01:26:41 +01002624 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002625 i::Handle<i::Object> result =
2626 CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002627 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002628 return *result == i::Smi::FromInt(i::EQUAL);
2629}
2630
2631
2632bool Value::StrictEquals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002633 i::Isolate* isolate = i::Isolate::Current();
2634 if (IsDeadCheck(isolate, "v8::Value::StrictEquals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002635 || EmptyCheck("v8::Value::StrictEquals()", this)
2636 || EmptyCheck("v8::Value::StrictEquals()", that)) {
2637 return false;
2638 }
Steve Block44f0eee2011-05-26 01:26:41 +01002639 LOG_API(isolate, "StrictEquals");
Steve Blocka7e24c12009-10-30 11:49:00 +00002640 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2641 i::Handle<i::Object> other = Utils::OpenHandle(*that);
2642 // Must check HeapNumber first, since NaN !== NaN.
2643 if (obj->IsHeapNumber()) {
2644 if (!other->IsNumber()) return false;
2645 double x = obj->Number();
2646 double y = other->Number();
2647 // Must check explicitly for NaN:s on Windows, but -0 works fine.
2648 return x == y && !isnan(x) && !isnan(y);
2649 } else if (*obj == *other) { // Also covers Booleans.
2650 return true;
2651 } else if (obj->IsSmi()) {
2652 return other->IsNumber() && obj->Number() == other->Number();
2653 } else if (obj->IsString()) {
2654 return other->IsString() &&
2655 i::String::cast(*obj)->Equals(i::String::cast(*other));
2656 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
2657 return other->IsUndefined() || other->IsUndetectableObject();
2658 } else {
2659 return false;
2660 }
2661}
2662
2663
2664uint32_t Value::Uint32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002665 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2666 if (obj->IsSmi()) {
2667 return i::Smi::cast(*obj)->value();
2668 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002669 i::Isolate* isolate = i::Isolate::Current();
2670 if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
2671 LOG_API(isolate, "Uint32Value");
2672 ENTER_V8(isolate);
2673 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002674 i::Handle<i::Object> num =
2675 i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002676 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002677 if (num->IsSmi()) {
2678 return i::Smi::cast(*num)->value();
2679 } else {
2680 return static_cast<uint32_t>(num->Number());
2681 }
2682 }
2683}
2684
2685
2686bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
2687 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002688 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2689 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2690 ENTER_V8(isolate);
2691 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002692 i::Handle<i::Object> self = Utils::OpenHandle(this);
2693 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2694 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002695 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002696 i::Handle<i::Object> obj = i::SetProperty(
2697 self,
2698 key_obj,
2699 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002700 static_cast<PropertyAttributes>(attribs),
2701 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002702 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002703 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002704 return true;
2705}
2706
2707
Steve Block6ded16b2010-05-10 14:33:55 +01002708bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002709 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2710 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2711 ENTER_V8(isolate);
2712 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002713 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2714 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002715 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002716 i::Handle<i::Object> obj = i::SetElement(
2717 self,
2718 index,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002719 value_obj,
2720 i::kNonStrictMode);
Steve Block6ded16b2010-05-10 14:33:55 +01002721 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002722 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Block6ded16b2010-05-10 14:33:55 +01002723 return true;
2724}
2725
2726
Steve Blocka7e24c12009-10-30 11:49:00 +00002727bool v8::Object::ForceSet(v8::Handle<Value> key,
2728 v8::Handle<Value> value,
2729 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002730 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2731 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
2732 ENTER_V8(isolate);
2733 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002734 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2735 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2736 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002737 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002738 i::Handle<i::Object> obj = i::ForceSetProperty(
2739 self,
2740 key_obj,
2741 value_obj,
2742 static_cast<PropertyAttributes>(attribs));
2743 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002744 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002745 return true;
2746}
2747
2748
2749bool v8::Object::ForceDelete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002750 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2751 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
2752 ENTER_V8(isolate);
2753 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002754 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2755 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002756
2757 // When turning on access checks for a global object deoptimize all functions
2758 // as optimized code does not always handle access checks.
2759 i::Deoptimizer::DeoptimizeGlobalObject(*self);
2760
Steve Block44f0eee2011-05-26 01:26:41 +01002761 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002762 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
2763 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002764 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002765 return obj->IsTrue();
2766}
2767
2768
2769Local<Value> v8::Object::Get(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002770 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2771 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2772 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002773 i::Handle<i::Object> self = Utils::OpenHandle(this);
2774 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002775 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002776 i::Handle<i::Object> result = i::GetProperty(self, key_obj);
2777 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002778 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002779 return Utils::ToLocal(result);
2780}
2781
2782
Steve Block6ded16b2010-05-10 14:33:55 +01002783Local<Value> v8::Object::Get(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002784 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2785 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2786 ENTER_V8(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002787 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002788 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002789 i::Handle<i::Object> result = i::GetElement(self, index);
2790 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002791 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Block6ded16b2010-05-10 14:33:55 +01002792 return Utils::ToLocal(result);
2793}
2794
2795
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002796PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
2797 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2798 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
2799 return static_cast<PropertyAttribute>(NONE));
2800 ENTER_V8(isolate);
2801 i::HandleScope scope(isolate);
2802 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2803 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2804 if (!key_obj->IsString()) {
2805 EXCEPTION_PREAMBLE(isolate);
2806 key_obj = i::Execution::ToString(key_obj, &has_pending_exception);
2807 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
2808 }
2809 i::Handle<i::String> key_string = i::Handle<i::String>::cast(key_obj);
2810 PropertyAttributes result = self->GetPropertyAttribute(*key_string);
2811 if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
2812 return static_cast<PropertyAttribute>(result);
2813}
2814
2815
Steve Blocka7e24c12009-10-30 11:49:00 +00002816Local<Value> v8::Object::GetPrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01002817 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2818 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
2819 return Local<v8::Value>());
2820 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002821 i::Handle<i::Object> self = Utils::OpenHandle(this);
2822 i::Handle<i::Object> result = i::GetPrototype(self);
2823 return Utils::ToLocal(result);
2824}
2825
2826
Andrei Popescu402d9372010-02-26 13:31:12 +00002827bool v8::Object::SetPrototype(Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002828 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2829 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
2830 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002831 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2832 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002833 // We do not allow exceptions thrown while setting the prototype
2834 // to propagate outside.
2835 TryCatch try_catch;
Steve Block44f0eee2011-05-26 01:26:41 +01002836 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002837 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2838 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002839 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00002840 return true;
2841}
2842
2843
Steve Blocka7e24c12009-10-30 11:49:00 +00002844Local<Object> v8::Object::FindInstanceInPrototypeChain(
2845 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01002846 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2847 ON_BAILOUT(isolate,
2848 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002849 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01002850 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002851 i::JSObject* object = *Utils::OpenHandle(this);
2852 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2853 while (!object->IsInstanceOf(tmpl_info)) {
2854 i::Object* prototype = object->GetPrototype();
2855 if (!prototype->IsJSObject()) return Local<Object>();
2856 object = i::JSObject::cast(prototype);
2857 }
2858 return Utils::ToLocal(i::Handle<i::JSObject>(object));
2859}
2860
2861
2862Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01002863 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2864 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
2865 return Local<v8::Array>());
2866 ENTER_V8(isolate);
2867 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002868 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2869 i::Handle<i::FixedArray> value =
2870 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
2871 // Because we use caching to speed up enumeration it is important
2872 // to never change the result of the basic enumeration function so
2873 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01002874 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2875 i::Handle<i::JSArray> result =
2876 isolate->factory()->NewJSArrayWithElements(elms);
2877 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00002878}
2879
2880
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002881Local<Array> v8::Object::GetOwnPropertyNames() {
2882 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2883 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
2884 return Local<v8::Array>());
2885 ENTER_V8(isolate);
2886 i::HandleScope scope(isolate);
2887 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2888 i::Handle<i::FixedArray> value =
2889 i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY);
2890 // Because we use caching to speed up enumeration it is important
2891 // to never change the result of the basic enumeration function so
2892 // we clone the result.
2893 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2894 i::Handle<i::JSArray> result =
2895 isolate->factory()->NewJSArrayWithElements(elms);
2896 return Utils::ToLocal(scope.CloseAndEscape(result));
2897}
2898
2899
Steve Blocka7e24c12009-10-30 11:49:00 +00002900Local<String> v8::Object::ObjectProtoToString() {
Steve Block44f0eee2011-05-26 01:26:41 +01002901 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2902 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
2903 return Local<v8::String>());
2904 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002905 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2906
2907 i::Handle<i::Object> name(self->class_name());
2908
2909 // Native implementation of Object.prototype.toString (v8natives.js):
2910 // var c = %ClassOf(this);
2911 // if (c === 'Arguments') c = 'Object';
2912 // return "[object " + c + "]";
2913
2914 if (!name->IsString()) {
2915 return v8::String::New("[object ]");
2916
2917 } else {
2918 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
2919 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
2920 return v8::String::New("[object Object]");
2921
2922 } else {
2923 const char* prefix = "[object ";
2924 Local<String> str = Utils::ToLocal(class_name);
2925 const char* postfix = "]";
2926
Steve Blockd0582a62009-12-15 09:54:21 +00002927 int prefix_len = i::StrLength(prefix);
2928 int str_len = str->Length();
2929 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00002930
Steve Blockd0582a62009-12-15 09:54:21 +00002931 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01002932 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002933
2934 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01002935 char* ptr = buf.start();
Steve Blocka7e24c12009-10-30 11:49:00 +00002936 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
2937 ptr += prefix_len;
2938
2939 // Write real content.
2940 str->WriteAscii(ptr, 0, str_len);
2941 ptr += str_len;
2942
2943 // Write postfix.
2944 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
2945
2946 // Copy the buffer into a heap-allocated string and return it.
Kristian Monsen25f61362010-05-21 11:50:48 +01002947 Local<String> result = v8::String::New(buf.start(), buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002948 return result;
2949 }
2950 }
2951}
2952
2953
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002954Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01002955 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2956 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
2957 return Local<v8::String>());
2958 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002959 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2960 i::Handle<i::String> name(self->constructor_name());
2961 return Utils::ToLocal(name);
2962}
2963
2964
Steve Blocka7e24c12009-10-30 11:49:00 +00002965bool v8::Object::Delete(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002966 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2967 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
2968 ENTER_V8(isolate);
2969 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002970 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2971 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2972 return i::DeleteProperty(self, key_obj)->IsTrue();
2973}
2974
2975
2976bool v8::Object::Has(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002977 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2978 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
2979 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002980 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2981 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2982 return self->HasProperty(*key_obj);
2983}
2984
2985
2986bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002987 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2988 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
2989 return false);
2990 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002991 HandleScope scope;
2992 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2993 return i::DeleteElement(self, index)->IsTrue();
2994}
2995
2996
2997bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002998 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2999 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003000 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3001 return self->HasElement(index);
3002}
3003
3004
Leon Clarkef7060e22010-06-03 12:02:55 +01003005bool Object::SetAccessor(Handle<String> name,
3006 AccessorGetter getter,
3007 AccessorSetter setter,
3008 v8::Handle<Value> data,
3009 AccessControl settings,
3010 PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01003011 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3012 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3013 ENTER_V8(isolate);
3014 i::HandleScope scope(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01003015 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
3016 getter, setter, data,
3017 settings, attributes);
3018 i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
3019 return !result.is_null() && !result->IsUndefined();
3020}
3021
3022
Ben Murdoch257744e2011-11-30 15:57:28 +00003023bool v8::Object::HasOwnProperty(Handle<String> key) {
3024 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3025 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3026 return false);
3027 return Utils::OpenHandle(this)->HasLocalProperty(
3028 *Utils::OpenHandle(*key));
3029}
3030
3031
Steve Blocka7e24c12009-10-30 11:49:00 +00003032bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003033 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3034 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
3035 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003036 return Utils::OpenHandle(this)->HasRealNamedProperty(
3037 *Utils::OpenHandle(*key));
3038}
3039
3040
3041bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01003042 ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
3043 "v8::Object::HasRealIndexedProperty()",
3044 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003045 return Utils::OpenHandle(this)->HasRealElementProperty(index);
3046}
3047
3048
3049bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003050 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3051 ON_BAILOUT(isolate,
3052 "v8::Object::HasRealNamedCallbackProperty()",
3053 return false);
3054 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003055 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
3056 *Utils::OpenHandle(*key));
3057}
3058
3059
3060bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003061 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3062 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
3063 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003064 return Utils::OpenHandle(this)->HasNamedInterceptor();
3065}
3066
3067
3068bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003069 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3070 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
3071 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003072 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3073}
3074
3075
Ben Murdoch8b112d22011-06-08 16:22:53 +01003076static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
3077 i::Handle<i::JSObject> receiver,
3078 i::Handle<i::String> name,
3079 i::LookupResult* lookup) {
3080 if (!lookup->IsProperty()) {
3081 // No real property was found.
3082 return Local<Value>();
3083 }
3084
3085 // If the property being looked up is a callback, it can throw
3086 // an exception.
3087 EXCEPTION_PREAMBLE(isolate);
3088 i::Handle<i::Object> result = i::GetProperty(receiver, name, lookup);
3089 has_pending_exception = result.is_null();
3090 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3091
3092 return Utils::ToLocal(result);
3093}
3094
3095
Steve Blocka7e24c12009-10-30 11:49:00 +00003096Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
3097 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003098 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3099 ON_BAILOUT(isolate,
3100 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003101 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01003102 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003103 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3104 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3105 i::LookupResult lookup;
3106 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003107 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00003108}
3109
3110
3111Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003112 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3113 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
3114 return Local<Value>());
3115 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003116 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3117 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3118 i::LookupResult lookup;
3119 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003120 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00003121}
3122
3123
3124// Turns on access checks by copying the map and setting the check flag.
3125// Because the object gets a new map, existing inline cache caching
3126// the old map of this object will fail.
3127void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01003128 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3129 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
3130 ENTER_V8(isolate);
3131 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003132 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3133
Ben Murdochb0fe1622011-05-05 13:52:32 +01003134 // When turning on access checks for a global object deoptimize all functions
3135 // as optimized code does not always handle access checks.
3136 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3137
Steve Blocka7e24c12009-10-30 11:49:00 +00003138 i::Handle<i::Map> new_map =
Steve Block44f0eee2011-05-26 01:26:41 +01003139 isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003140 new_map->set_is_access_check_needed(true);
3141 obj->set_map(*new_map);
3142}
3143
3144
3145bool v8::Object::IsDirty() {
3146 return Utils::OpenHandle(this)->IsDirty();
3147}
3148
3149
3150Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01003151 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3152 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
3153 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003154 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003155 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003156 i::Handle<i::JSObject> result = i::Copy(self);
3157 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003158 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003159 return Utils::ToLocal(result);
3160}
3161
3162
Ben Murdoch8b112d22011-06-08 16:22:53 +01003163static i::Context* GetCreationContext(i::JSObject* object) {
3164 i::Object* constructor = object->map()->constructor();
3165 i::JSFunction* function;
3166 if (!constructor->IsJSFunction()) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003167 // Functions have null as a constructor,
Ben Murdoch8b112d22011-06-08 16:22:53 +01003168 // but any JSFunction knows its context immediately.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003169 ASSERT(object->IsJSFunction());
Ben Murdoch8b112d22011-06-08 16:22:53 +01003170 function = i::JSFunction::cast(object);
3171 } else {
3172 function = i::JSFunction::cast(constructor);
3173 }
3174 return function->context()->global_context();
3175}
3176
3177
3178Local<v8::Context> v8::Object::CreationContext() {
3179 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3180 ON_BAILOUT(isolate,
3181 "v8::Object::CreationContext()", return Local<v8::Context>());
3182 ENTER_V8(isolate);
3183 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3184 i::Context* context = GetCreationContext(*self);
3185 return Utils::ToLocal(i::Handle<i::Context>(context));
3186}
3187
3188
Steve Blocka7e24c12009-10-30 11:49:00 +00003189int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01003190 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3191 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
3192 ENTER_V8(isolate);
3193 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003194 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003195 return i::GetIdentityHash(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00003196}
3197
3198
3199bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3200 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003201 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3202 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
3203 ENTER_V8(isolate);
3204 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003205 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003206 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
3207 self,
3208 i::JSObject::ALLOW_CREATION));
Steve Blocka7e24c12009-10-30 11:49:00 +00003209 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3210 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003211 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003212 i::Handle<i::Object> obj = i::SetProperty(
3213 hidden_props,
3214 key_obj,
3215 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01003216 static_cast<PropertyAttributes>(None),
3217 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003218 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003219 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003220 return true;
3221}
3222
3223
3224v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003225 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3226 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3227 return Local<v8::Value>());
3228 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003229 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003230 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
3231 self,
3232 i::JSObject::OMIT_CREATION));
Steve Blocka7e24c12009-10-30 11:49:00 +00003233 if (hidden_props->IsUndefined()) {
3234 return v8::Local<v8::Value>();
3235 }
3236 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01003237 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003238 i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
3239 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003240 EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003241 if (result->IsUndefined()) {
3242 return v8::Local<v8::Value>();
3243 }
3244 return Utils::ToLocal(result);
3245}
3246
3247
3248bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003249 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3250 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
3251 ENTER_V8(isolate);
3252 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003253 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003254 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
3255 self,
3256 i::JSObject::OMIT_CREATION));
Steve Blocka7e24c12009-10-30 11:49:00 +00003257 if (hidden_props->IsUndefined()) {
3258 return true;
3259 }
3260 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
3261 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3262 return i::DeleteProperty(js_obj, key_obj)->IsTrue();
3263}
3264
3265
Steve Block44f0eee2011-05-26 01:26:41 +01003266namespace {
3267
3268void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3269 void* data,
3270 ExternalArrayType array_type,
3271 int length) {
3272 i::Isolate* isolate = object->GetIsolate();
3273 i::Handle<i::ExternalArray> array =
3274 isolate->factory()->NewExternalArray(length, array_type, data);
3275
3276 // If the object already has external elements, create a new, unique
3277 // map if the element type is now changing, because assumptions about
3278 // generated code based on the receiver's map will be invalid.
3279 i::Handle<i::HeapObject> elements(object->elements());
3280 bool cant_reuse_map =
3281 elements->map()->IsUndefined() ||
3282 !elements->map()->has_external_array_elements() ||
3283 elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
3284 if (cant_reuse_map) {
3285 i::Handle<i::Map> external_array_map =
3286 isolate->factory()->GetExternalArrayElementsMap(
3287 i::Handle<i::Map>(object->map()),
3288 array_type,
3289 object->HasFastProperties());
3290 object->set_map(*external_array_map);
3291 }
3292 object->set_elements(*array);
3293}
3294
3295} // namespace
3296
3297
Steve Blocka7e24c12009-10-30 11:49:00 +00003298void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003299 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3300 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3301 ENTER_V8(isolate);
3302 i::HandleScope scope(isolate);
3303 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
Steve Blocka7e24c12009-10-30 11:49:00 +00003304 "v8::Object::SetIndexedPropertiesToPixelData()",
3305 "length exceeds max acceptable value")) {
3306 return;
3307 }
3308 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3309 if (!ApiCheck(!self->IsJSArray(),
3310 "v8::Object::SetIndexedPropertiesToPixelData()",
3311 "JSArray is not supported")) {
3312 return;
3313 }
Steve Block44f0eee2011-05-26 01:26:41 +01003314 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003315}
3316
3317
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003318bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003319 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003320 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3321 return false);
3322 return self->HasExternalPixelElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003323}
3324
3325
3326uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003327 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003328 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3329 return NULL);
3330 if (self->HasExternalPixelElements()) {
3331 return i::ExternalPixelArray::cast(self->elements())->
3332 external_pixel_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003333 } else {
3334 return NULL;
3335 }
3336}
3337
3338
3339int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003340 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003341 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3342 return -1);
3343 if (self->HasExternalPixelElements()) {
3344 return i::ExternalPixelArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003345 } else {
3346 return -1;
3347 }
3348}
3349
Steve Block3ce2e202009-11-05 08:53:23 +00003350void v8::Object::SetIndexedPropertiesToExternalArrayData(
3351 void* data,
3352 ExternalArrayType array_type,
3353 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003354 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3355 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3356 ENTER_V8(isolate);
3357 i::HandleScope scope(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003358 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3359 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3360 "length exceeds max acceptable value")) {
3361 return;
3362 }
3363 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3364 if (!ApiCheck(!self->IsJSArray(),
3365 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3366 "JSArray is not supported")) {
3367 return;
3368 }
Steve Block44f0eee2011-05-26 01:26:41 +01003369 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003370}
3371
3372
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003373bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003374 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003375 ON_BAILOUT(self->GetIsolate(),
3376 "v8::HasIndexedPropertiesInExternalArrayData()",
3377 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003378 return self->HasExternalArrayElements();
3379}
3380
3381
3382void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003383 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003384 ON_BAILOUT(self->GetIsolate(),
3385 "v8::GetIndexedPropertiesExternalArrayData()",
3386 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003387 if (self->HasExternalArrayElements()) {
3388 return i::ExternalArray::cast(self->elements())->external_pointer();
3389 } else {
3390 return NULL;
3391 }
3392}
3393
3394
3395ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003396 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003397 ON_BAILOUT(self->GetIsolate(),
3398 "v8::GetIndexedPropertiesExternalArrayDataType()",
3399 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003400 switch (self->elements()->map()->instance_type()) {
3401 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3402 return kExternalByteArray;
3403 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3404 return kExternalUnsignedByteArray;
3405 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3406 return kExternalShortArray;
3407 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3408 return kExternalUnsignedShortArray;
3409 case i::EXTERNAL_INT_ARRAY_TYPE:
3410 return kExternalIntArray;
3411 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3412 return kExternalUnsignedIntArray;
3413 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3414 return kExternalFloatArray;
Ben Murdoch257744e2011-11-30 15:57:28 +00003415 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3416 return kExternalDoubleArray;
Steve Block44f0eee2011-05-26 01:26:41 +01003417 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3418 return kExternalPixelArray;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003419 default:
3420 return static_cast<ExternalArrayType>(-1);
3421 }
3422}
3423
3424
3425int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003426 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003427 ON_BAILOUT(self->GetIsolate(),
3428 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3429 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003430 if (self->HasExternalArrayElements()) {
3431 return i::ExternalArray::cast(self->elements())->length();
3432 } else {
3433 return -1;
3434 }
3435}
3436
3437
Ben Murdoch257744e2011-11-30 15:57:28 +00003438bool v8::Object::IsCallable() {
3439 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3440 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3441 ENTER_V8(isolate);
3442 i::HandleScope scope(isolate);
3443 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3444 if (obj->IsJSFunction()) return true;
3445 return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
3446}
3447
3448
3449Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
3450 v8::Handle<v8::Value> argv[]) {
3451 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3452 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3453 return Local<v8::Value>());
3454 LOG_API(isolate, "Object::CallAsFunction");
3455 ENTER_V8(isolate);
3456 i::HandleScope scope(isolate);
3457 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3458 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3459 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3460 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3461 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3462 if (obj->IsJSFunction()) {
3463 fun = i::Handle<i::JSFunction>::cast(obj);
3464 } else {
3465 EXCEPTION_PREAMBLE(isolate);
3466 i::Handle<i::Object> delegate =
3467 i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
3468 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3469 fun = i::Handle<i::JSFunction>::cast(delegate);
3470 recv_obj = obj;
3471 }
3472 EXCEPTION_PREAMBLE(isolate);
3473 i::Handle<i::Object> returned =
3474 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
3475 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3476 return Utils::ToLocal(scope.CloseAndEscape(returned));
3477}
3478
3479
3480Local<v8::Value> Object::CallAsConstructor(int argc,
3481 v8::Handle<v8::Value> argv[]) {
3482 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3483 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3484 return Local<v8::Object>());
3485 LOG_API(isolate, "Object::CallAsConstructor");
3486 ENTER_V8(isolate);
3487 i::HandleScope scope(isolate);
3488 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3489 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3490 i::Object*** args = reinterpret_cast<i::Object***>(argv);
3491 if (obj->IsJSFunction()) {
3492 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
3493 EXCEPTION_PREAMBLE(isolate);
3494 i::Handle<i::Object> returned =
3495 i::Execution::New(fun, argc, args, &has_pending_exception);
3496 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3497 return Utils::ToLocal(scope.CloseAndEscape(
3498 i::Handle<i::JSObject>::cast(returned)));
3499 }
3500 EXCEPTION_PREAMBLE(isolate);
3501 i::Handle<i::Object> delegate =
3502 i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
3503 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3504 if (!delegate->IsUndefined()) {
3505 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
3506 EXCEPTION_PREAMBLE(isolate);
3507 i::Handle<i::Object> returned =
3508 i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
3509 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3510 ASSERT(!delegate->IsUndefined());
3511 return Utils::ToLocal(scope.CloseAndEscape(returned));
3512 }
3513 return Local<v8::Object>();
3514}
3515
3516
Steve Blocka7e24c12009-10-30 11:49:00 +00003517Local<v8::Object> Function::NewInstance() const {
3518 return NewInstance(0, NULL);
3519}
3520
3521
3522Local<v8::Object> Function::NewInstance(int argc,
3523 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003524 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3525 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3526 return Local<v8::Object>());
3527 LOG_API(isolate, "Function::NewInstance");
3528 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003529 HandleScope scope;
3530 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3531 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3532 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003533 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003534 i::Handle<i::Object> returned =
3535 i::Execution::New(function, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003536 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003537 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3538}
3539
3540
3541Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3542 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01003543 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3544 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3545 LOG_API(isolate, "Function::Call");
3546 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003547 i::Object* raw_result = NULL;
3548 {
Steve Block44f0eee2011-05-26 01:26:41 +01003549 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003550 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3551 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3552 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3553 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003554 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003555 i::Handle<i::Object> returned =
3556 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003557 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003558 raw_result = *returned;
3559 }
3560 i::Handle<i::Object> result(raw_result);
3561 return Utils::ToLocal(result);
3562}
3563
3564
3565void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01003566 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3567 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003568 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003569 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3570 func->shared()->set_name(*Utils::OpenHandle(*name));
3571}
3572
3573
3574Handle<Value> Function::GetName() const {
3575 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3576 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3577}
3578
3579
Andrei Popescu402d9372010-02-26 13:31:12 +00003580ScriptOrigin Function::GetScriptOrigin() const {
3581 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3582 if (func->shared()->script()->IsScript()) {
3583 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3584 v8::ScriptOrigin origin(
3585 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3586 v8::Integer::New(script->line_offset()->value()),
3587 v8::Integer::New(script->column_offset()->value()));
3588 return origin;
3589 }
3590 return v8::ScriptOrigin(Handle<Value>());
3591}
3592
3593
3594const int Function::kLineOffsetNotFound = -1;
3595
3596
3597int Function::GetScriptLineNumber() const {
3598 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3599 if (func->shared()->script()->IsScript()) {
3600 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3601 return i::GetScriptLineNumber(script, func->shared()->start_position());
3602 }
3603 return kLineOffsetNotFound;
3604}
3605
3606
Steve Blocka7e24c12009-10-30 11:49:00 +00003607int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003608 i::Handle<i::String> str = Utils::OpenHandle(this);
3609 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3610 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003611}
3612
3613
3614int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003615 i::Handle<i::String> str = Utils::OpenHandle(this);
3616 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
3617 return str->Utf8Length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003618}
3619
3620
Steve Block6ded16b2010-05-10 14:33:55 +01003621int String::WriteUtf8(char* buffer,
3622 int capacity,
3623 int* nchars_ref,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003624 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003625 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3626 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3627 LOG_API(isolate, "String::WriteUtf8");
3628 ENTER_V8(isolate);
3629 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003630 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003631 isolate->string_tracker()->RecordWrite(str);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003632 if (options & HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01003633 // Flatten the string for efficiency. This applies whether we are
3634 // using StringInputBuffer or Get(i) to access the characters.
3635 str->TryFlatten();
3636 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003637 write_input_buffer.Reset(0, *str);
3638 int len = str->length();
3639 // Encode the first K - 3 bytes directly into the buffer since we
3640 // know there's room for them. If no capacity is given we copy all
3641 // of them here.
3642 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3643 int i;
3644 int pos = 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003645 int nchars = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003646 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3647 i::uc32 c = write_input_buffer.GetNext();
3648 int written = unibrow::Utf8::Encode(buffer + pos, c);
3649 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003650 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003651 }
3652 if (i < len) {
3653 // For the last characters we need to check the length for each one
3654 // because they may be longer than the remaining space in the
3655 // buffer.
3656 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3657 for (; i < len && pos < capacity; i++) {
3658 i::uc32 c = write_input_buffer.GetNext();
3659 int written = unibrow::Utf8::Encode(intermediate, c);
3660 if (pos + written <= capacity) {
3661 for (int j = 0; j < written; j++)
3662 buffer[pos + j] = intermediate[j];
3663 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003664 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003665 } else {
3666 // We've reached the end of the buffer
3667 break;
3668 }
3669 }
3670 }
Steve Block6ded16b2010-05-10 14:33:55 +01003671 if (nchars_ref != NULL) *nchars_ref = nchars;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003672 if (!(options & NO_NULL_TERMINATION) &&
3673 (i == len && (capacity == -1 || pos < capacity)))
Steve Blocka7e24c12009-10-30 11:49:00 +00003674 buffer[pos++] = '\0';
3675 return pos;
3676}
3677
3678
Steve Block6ded16b2010-05-10 14:33:55 +01003679int String::WriteAscii(char* buffer,
3680 int start,
3681 int length,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003682 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003683 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3684 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3685 LOG_API(isolate, "String::WriteAscii");
3686 ENTER_V8(isolate);
3687 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003688 ASSERT(start >= 0 && length >= -1);
3689 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003690 isolate->string_tracker()->RecordWrite(str);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003691 if (options & HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01003692 // Flatten the string for efficiency. This applies whether we are
3693 // using StringInputBuffer or Get(i) to access the characters.
3694 str->TryFlatten();
3695 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003696 int end = length;
3697 if ( (length == -1) || (length > str->length() - start) )
3698 end = str->length() - start;
3699 if (end < 0) return 0;
3700 write_input_buffer.Reset(start, *str);
3701 int i;
3702 for (i = 0; i < end; i++) {
3703 char c = static_cast<char>(write_input_buffer.GetNext());
3704 if (c == '\0') c = ' ';
3705 buffer[i] = c;
3706 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003707 if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length))
Steve Blocka7e24c12009-10-30 11:49:00 +00003708 buffer[i] = '\0';
3709 return i;
3710}
3711
3712
Steve Block6ded16b2010-05-10 14:33:55 +01003713int String::Write(uint16_t* buffer,
3714 int start,
3715 int length,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003716 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003717 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3718 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
3719 LOG_API(isolate, "String::Write");
3720 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003721 ASSERT(start >= 0 && length >= -1);
3722 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003723 isolate->string_tracker()->RecordWrite(str);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003724 if (options & HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01003725 // Flatten the string for efficiency. This applies whether we are
3726 // using StringInputBuffer or Get(i) to access the characters.
3727 str->TryFlatten();
3728 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003729 int end = start + length;
3730 if ((length == -1) || (length > str->length() - start) )
3731 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003732 if (end < 0) return 0;
3733 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003734 if (!(options & NO_NULL_TERMINATION) &&
3735 (length == -1 || end - start < length)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01003736 buffer[end - start] = '\0';
3737 }
3738 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003739}
3740
3741
3742bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003743 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003744 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
3745 return false;
3746 }
3747 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
Steve Blocka7e24c12009-10-30 11:49:00 +00003748 return i::StringShape(*str).IsExternalTwoByte();
3749}
3750
3751
3752bool v8::String::IsExternalAscii() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003753 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003754 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
3755 return false;
3756 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003757 return i::StringShape(*str).IsExternalAscii();
3758}
3759
3760
3761void v8::String::VerifyExternalStringResource(
3762 v8::String::ExternalStringResource* value) const {
3763 i::Handle<i::String> str = Utils::OpenHandle(this);
3764 v8::String::ExternalStringResource* expected;
3765 if (i::StringShape(*str).IsExternalTwoByte()) {
3766 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
3767 expected = reinterpret_cast<ExternalStringResource*>(resource);
3768 } else {
3769 expected = NULL;
3770 }
3771 CHECK_EQ(expected, value);
3772}
3773
3774
3775v8::String::ExternalAsciiStringResource*
3776 v8::String::GetExternalAsciiStringResource() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003777 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003778 if (IsDeadCheck(str->GetIsolate(),
3779 "v8::String::GetExternalAsciiStringResource()")) {
3780 return NULL;
3781 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003782 if (i::StringShape(*str).IsExternalAscii()) {
3783 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
3784 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
3785 } else {
3786 return NULL;
3787 }
3788}
3789
3790
3791double Number::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003792 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003793 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3794 return obj->Number();
3795}
3796
3797
3798bool Boolean::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003799 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003800 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3801 return obj->IsTrue();
3802}
3803
3804
3805int64_t Integer::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003806 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003807 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3808 if (obj->IsSmi()) {
3809 return i::Smi::cast(*obj)->value();
3810 } else {
3811 return static_cast<int64_t>(obj->Number());
3812 }
3813}
3814
3815
3816int32_t Int32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003817 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003818 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3819 if (obj->IsSmi()) {
3820 return i::Smi::cast(*obj)->value();
3821 } else {
3822 return static_cast<int32_t>(obj->Number());
3823 }
3824}
3825
3826
Steve Block6ded16b2010-05-10 14:33:55 +01003827uint32_t Uint32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003828 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003829 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3830 if (obj->IsSmi()) {
3831 return i::Smi::cast(*obj)->value();
3832 } else {
3833 return static_cast<uint32_t>(obj->Number());
3834 }
3835}
3836
3837
Steve Blocka7e24c12009-10-30 11:49:00 +00003838int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003839 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003840 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
3841 return 0;
3842 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003843 return obj->GetInternalFieldCount();
3844}
3845
3846
3847Local<Value> v8::Object::CheckedGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003848 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003849 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
3850 return Local<Value>();
3851 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003852 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3853 "v8::Object::GetInternalField()",
3854 "Reading internal field out of bounds")) {
3855 return Local<Value>();
3856 }
3857 i::Handle<i::Object> value(obj->GetInternalField(index));
3858 Local<Value> result = Utils::ToLocal(value);
3859#ifdef DEBUG
3860 Local<Value> unchecked = UncheckedGetInternalField(index);
3861 ASSERT(unchecked.IsEmpty() || (unchecked == result));
3862#endif
3863 return result;
3864}
3865
3866
3867void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003868 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003869 i::Isolate* isolate = obj->GetIsolate();
3870 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
3871 return;
3872 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003873 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3874 "v8::Object::SetInternalField()",
3875 "Writing internal field out of bounds")) {
3876 return;
3877 }
Steve Block44f0eee2011-05-26 01:26:41 +01003878 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003879 i::Handle<i::Object> val = Utils::OpenHandle(*value);
3880 obj->SetInternalField(index, *val);
3881}
3882
3883
Ben Murdochb8e0da22011-05-16 14:20:40 +01003884static bool CanBeEncodedAsSmi(void* ptr) {
Steve Block1e0659c2011-05-24 12:43:12 +01003885 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003886 return ((address & i::kEncodablePointerMask) == 0);
3887}
3888
3889
3890static i::Smi* EncodeAsSmi(void* ptr) {
3891 ASSERT(CanBeEncodedAsSmi(ptr));
Steve Block1e0659c2011-05-24 12:43:12 +01003892 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003893 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
3894 ASSERT(i::Internals::HasSmiTag(result));
3895 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
3896 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
3897 return result;
3898}
3899
3900
Steve Blocka7e24c12009-10-30 11:49:00 +00003901void v8::Object::SetPointerInInternalField(int index, void* value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003902 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3903 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003904 if (CanBeEncodedAsSmi(value)) {
3905 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
3906 } else {
3907 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00003908 i::Handle<i::Foreign> foreign =
3909 isolate->factory()->NewForeign(
Steve Block44f0eee2011-05-26 01:26:41 +01003910 reinterpret_cast<i::Address>(value), i::TENURED);
Ben Murdoch257744e2011-11-30 15:57:28 +00003911 if (!foreign.is_null())
3912 Utils::OpenHandle(this)->SetInternalField(index, *foreign);
Steve Block3ce2e202009-11-05 08:53:23 +00003913 }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003914 ASSERT_EQ(value, GetPointerFromInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003915}
3916
3917
3918// --- E n v i r o n m e n t ---
3919
Steve Block44f0eee2011-05-26 01:26:41 +01003920
Steve Blocka7e24c12009-10-30 11:49:00 +00003921bool v8::V8::Initialize() {
Steve Block44f0eee2011-05-26 01:26:41 +01003922 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
3923 if (isolate != NULL && isolate->IsInitialized()) {
3924 return true;
3925 }
3926 return InitializeHelper();
Steve Blocka7e24c12009-10-30 11:49:00 +00003927}
3928
3929
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003930void v8::V8::SetEntropySource(EntropySource source) {
3931 i::V8::SetEntropySource(source);
3932}
3933
3934
Steve Blocka7e24c12009-10-30 11:49:00 +00003935bool v8::V8::Dispose() {
Steve Block44f0eee2011-05-26 01:26:41 +01003936 i::Isolate* isolate = i::Isolate::Current();
3937 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
3938 "v8::V8::Dispose()",
3939 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
3940 return false;
3941 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003942 i::V8::TearDown();
3943 return true;
3944}
3945
3946
Russell Brenner90bac252010-11-18 13:33:46 -08003947HeapStatistics::HeapStatistics(): total_heap_size_(0),
3948 total_heap_size_executable_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01003949 used_heap_size_(0),
3950 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00003951
3952
3953void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
Steve Block44f0eee2011-05-26 01:26:41 +01003954 i::Heap* heap = i::Isolate::Current()->heap();
3955 heap_statistics->set_total_heap_size(heap->CommittedMemory());
Russell Brenner90bac252010-11-18 13:33:46 -08003956 heap_statistics->set_total_heap_size_executable(
Steve Block44f0eee2011-05-26 01:26:41 +01003957 heap->CommittedMemoryExecutable());
3958 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
3959 heap_statistics->set_heap_size_limit(heap->MaxReserved());
Steve Block3ce2e202009-11-05 08:53:23 +00003960}
3961
3962
3963bool v8::V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003964 // Returning true tells the caller that it need not
3965 // continue to call IdleNotification.
Steve Block44f0eee2011-05-26 01:26:41 +01003966 if (!i::Isolate::Current()->IsInitialized()) return true;
Steve Block3ce2e202009-11-05 08:53:23 +00003967 return i::V8::IdleNotification();
Steve Blocka7e24c12009-10-30 11:49:00 +00003968}
3969
3970
3971void v8::V8::LowMemoryNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003972 i::Isolate* isolate = i::Isolate::Current();
3973 if (!isolate->IsInitialized()) return;
3974 isolate->heap()->CollectAllGarbage(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003975}
3976
3977
Steve Block6ded16b2010-05-10 14:33:55 +01003978int v8::V8::ContextDisposedNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003979 i::Isolate* isolate = i::Isolate::Current();
3980 if (!isolate->IsInitialized()) return 0;
3981 return isolate->heap()->NotifyContextDisposed();
Steve Block6ded16b2010-05-10 14:33:55 +01003982}
3983
3984
Steve Blocka7e24c12009-10-30 11:49:00 +00003985const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01003986 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00003987}
3988
3989
3990static i::Handle<i::FunctionTemplateInfo>
3991 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
3992 if (templ->constructor()->IsUndefined()) {
3993 Local<FunctionTemplate> constructor = FunctionTemplate::New();
3994 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
3995 templ->set_constructor(*Utils::OpenHandle(*constructor));
3996 }
3997 return i::Handle<i::FunctionTemplateInfo>(
3998 i::FunctionTemplateInfo::cast(templ->constructor()));
3999}
4000
4001
4002Persistent<Context> v8::Context::New(
4003 v8::ExtensionConfiguration* extensions,
4004 v8::Handle<ObjectTemplate> global_template,
4005 v8::Handle<Value> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01004006 i::Isolate* isolate = i::Isolate::Current();
4007 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
4008 LOG_API(isolate, "Context::New");
4009 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004010
4011 // Enter V8 via an ENTER_V8 scope.
4012 i::Handle<i::Context> env;
4013 {
Steve Block44f0eee2011-05-26 01:26:41 +01004014 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004015 v8::Handle<ObjectTemplate> proxy_template = global_template;
4016 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
4017 i::Handle<i::FunctionTemplateInfo> global_constructor;
4018
4019 if (!global_template.IsEmpty()) {
4020 // Make sure that the global_template has a constructor.
4021 global_constructor =
4022 EnsureConstructor(Utils::OpenHandle(*global_template));
4023
4024 // Create a fresh template for the global proxy object.
4025 proxy_template = ObjectTemplate::New();
4026 proxy_constructor =
4027 EnsureConstructor(Utils::OpenHandle(*proxy_template));
4028
4029 // Set the global template to be the prototype template of
4030 // global proxy template.
4031 proxy_constructor->set_prototype_template(
4032 *Utils::OpenHandle(*global_template));
4033
4034 // Migrate security handlers from global_template to
4035 // proxy_template. Temporarily removing access check
4036 // information from the global template.
4037 if (!global_constructor->access_check_info()->IsUndefined()) {
4038 proxy_constructor->set_access_check_info(
4039 global_constructor->access_check_info());
4040 proxy_constructor->set_needs_access_check(
4041 global_constructor->needs_access_check());
4042 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01004043 global_constructor->set_access_check_info(
4044 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004045 }
4046 }
4047
4048 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01004049 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdoch257744e2011-11-30 15:57:28 +00004050 isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004051 Utils::OpenHandle(*global_object),
4052 proxy_template,
4053 extensions);
4054
4055 // Restore the access check info on the global template.
4056 if (!global_template.IsEmpty()) {
4057 ASSERT(!global_constructor.is_null());
4058 ASSERT(!proxy_constructor.is_null());
4059 global_constructor->set_access_check_info(
4060 proxy_constructor->access_check_info());
4061 global_constructor->set_needs_access_check(
4062 proxy_constructor->needs_access_check());
4063 }
Steve Block44f0eee2011-05-26 01:26:41 +01004064 isolate->runtime_profiler()->Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +00004065 }
4066 // Leave V8.
4067
4068 if (env.is_null())
4069 return Persistent<Context>();
4070 return Persistent<Context>(Utils::ToLocal(env));
4071}
4072
4073
4074void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01004075 i::Isolate* isolate = i::Isolate::Current();
4076 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
4077 return;
4078 }
4079 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004080 i::Handle<i::Context> env = Utils::OpenHandle(this);
4081 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
4082 env->set_security_token(*token_handle);
4083}
4084
4085
4086void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01004087 i::Isolate* isolate = i::Isolate::Current();
4088 if (IsDeadCheck(isolate,
4089 "v8::Context::UseDefaultSecurityToken()")) {
4090 return;
4091 }
4092 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004093 i::Handle<i::Context> env = Utils::OpenHandle(this);
4094 env->set_security_token(env->global());
4095}
4096
4097
4098Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01004099 i::Isolate* isolate = i::Isolate::Current();
4100 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
4101 return Handle<Value>();
4102 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004103 i::Handle<i::Context> env = Utils::OpenHandle(this);
4104 i::Object* security_token = env->security_token();
4105 i::Handle<i::Object> token_handle(security_token);
4106 return Utils::ToLocal(token_handle);
4107}
4108
4109
4110bool Context::HasOutOfMemoryException() {
4111 i::Handle<i::Context> env = Utils::OpenHandle(this);
4112 return env->has_out_of_memory();
4113}
4114
4115
4116bool Context::InContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01004117 return i::Isolate::Current()->context() != NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00004118}
4119
4120
4121v8::Local<v8::Context> Context::GetEntered() {
Steve Block44f0eee2011-05-26 01:26:41 +01004122 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004123 if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
Steve Block44f0eee2011-05-26 01:26:41 +01004124 return Local<Context>();
4125 }
4126 i::Handle<i::Object> last =
4127 isolate->handle_scope_implementer()->LastEnteredContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00004128 if (last.is_null()) return Local<Context>();
4129 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
4130 return Utils::ToLocal(context);
4131}
4132
4133
4134v8::Local<v8::Context> Context::GetCurrent() {
Steve Block44f0eee2011-05-26 01:26:41 +01004135 i::Isolate* isolate = i::Isolate::Current();
4136 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
4137 return Local<Context>();
4138 }
4139 i::Handle<i::Object> current = isolate->global_context();
Steve Block3ce2e202009-11-05 08:53:23 +00004140 if (current.is_null()) return Local<Context>();
4141 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
Steve Blocka7e24c12009-10-30 11:49:00 +00004142 return Utils::ToLocal(context);
4143}
4144
4145
4146v8::Local<v8::Context> Context::GetCalling() {
Steve Block44f0eee2011-05-26 01:26:41 +01004147 i::Isolate* isolate = i::Isolate::Current();
4148 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
4149 return Local<Context>();
4150 }
4151 i::Handle<i::Object> calling =
4152 isolate->GetCallingGlobalContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00004153 if (calling.is_null()) return Local<Context>();
4154 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
4155 return Utils::ToLocal(context);
4156}
4157
4158
4159v8::Local<v8::Object> Context::Global() {
Steve Block44f0eee2011-05-26 01:26:41 +01004160 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
4161 return Local<v8::Object>();
4162 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004163 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4164 i::Handle<i::Context> context =
4165 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4166 i::Handle<i::Object> global(context->global_proxy());
4167 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
4168}
4169
4170
4171void Context::DetachGlobal() {
Steve Block44f0eee2011-05-26 01:26:41 +01004172 i::Isolate* isolate = i::Isolate::Current();
4173 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
4174 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004175 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4176 i::Handle<i::Context> context =
4177 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01004178 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00004179}
4180
4181
Andrei Popescu74b3c142010-03-29 12:03:09 +01004182void Context::ReattachGlobal(Handle<Object> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01004183 i::Isolate* isolate = i::Isolate::Current();
4184 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
4185 ENTER_V8(isolate);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004186 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4187 i::Handle<i::Context> context =
4188 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01004189 isolate->bootstrapper()->ReattachGlobal(
4190 context,
4191 Utils::OpenHandle(*global_object));
4192}
4193
4194
Ben Murdoch257744e2011-11-30 15:57:28 +00004195void Context::AllowCodeGenerationFromStrings(bool allow) {
4196 i::Isolate* isolate = i::Isolate::Current();
4197 if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
4198 return;
4199 }
4200 ENTER_V8(isolate);
4201 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4202 i::Handle<i::Context> context =
4203 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4204 context->set_allow_code_gen_from_strings(
4205 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
4206}
4207
4208
Steve Block44f0eee2011-05-26 01:26:41 +01004209void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
4210 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
Andrei Popescu74b3c142010-03-29 12:03:09 +01004211}
4212
4213
Steve Blocka7e24c12009-10-30 11:49:00 +00004214Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01004215 i::Isolate* isolate = i::Isolate::Current();
4216 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
4217 return Local<v8::Object>());
4218 LOG_API(isolate, "ObjectTemplate::NewInstance");
4219 ENTER_V8(isolate);
4220 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004221 i::Handle<i::Object> obj =
4222 i::Execution::InstantiateObject(Utils::OpenHandle(this),
4223 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004224 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004225 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
4226}
4227
4228
4229Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01004230 i::Isolate* isolate = i::Isolate::Current();
4231 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00004232 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01004233 LOG_API(isolate, "FunctionTemplate::GetFunction");
4234 ENTER_V8(isolate);
4235 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004236 i::Handle<i::Object> obj =
4237 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
4238 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004239 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004240 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
4241}
4242
4243
4244bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004245 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
4246 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004247 i::Object* obj = *Utils::OpenHandle(*value);
4248 return obj->IsInstanceOf(*Utils::OpenHandle(this));
4249}
4250
4251
4252static Local<External> ExternalNewImpl(void* data) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004253 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004254}
4255
4256static void* ExternalValueImpl(i::Handle<i::Object> obj) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004257 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->address());
Steve Blocka7e24c12009-10-30 11:49:00 +00004258}
4259
4260
Steve Blocka7e24c12009-10-30 11:49:00 +00004261Local<Value> v8::External::Wrap(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004262 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004263 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Ben Murdoch257744e2011-11-30 15:57:28 +00004264 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004265 LOG_API(isolate, "External::Wrap");
Steve Block44f0eee2011-05-26 01:26:41 +01004266 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004267
4268 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
4269 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
4270 : v8::Local<v8::Value>(ExternalNewImpl(data));
4271
4272 ASSERT_EQ(data, Unwrap(result));
4273 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004274}
4275
4276
Steve Block3ce2e202009-11-05 08:53:23 +00004277void* v8::Object::SlowGetPointerFromInternalField(int index) {
4278 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4279 i::Object* value = obj->GetInternalField(index);
4280 if (value->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004281 return i::Internals::GetExternalPointerFromSmi(value);
Ben Murdoch257744e2011-11-30 15:57:28 +00004282 } else if (value->IsForeign()) {
4283 return reinterpret_cast<void*>(i::Foreign::cast(value)->address());
Steve Block3ce2e202009-11-05 08:53:23 +00004284 } else {
4285 return NULL;
4286 }
4287}
4288
4289
Steve Blocka7e24c12009-10-30 11:49:00 +00004290void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
Steve Block44f0eee2011-05-26 01:26:41 +01004291 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004292 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
4293 void* result;
4294 if (obj->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01004295 result = i::Internals::GetExternalPointerFromSmi(*obj);
Ben Murdoch257744e2011-11-30 15:57:28 +00004296 } else if (obj->IsForeign()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004297 result = ExternalValueImpl(obj);
4298 } else {
4299 result = NULL;
4300 }
4301 ASSERT_EQ(result, QuickUnwrap(wrapper));
4302 return result;
4303}
4304
4305
4306Local<External> v8::External::New(void* data) {
4307 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01004308 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00004309 EnsureInitializedForIsolate(isolate, "v8::External::New()");
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004310 LOG_API(isolate, "External::New");
Steve Block44f0eee2011-05-26 01:26:41 +01004311 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004312 return ExternalNewImpl(data);
4313}
4314
4315
4316void* External::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004317 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004318 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4319 return ExternalValueImpl(obj);
4320}
4321
4322
4323Local<String> v8::String::Empty() {
Steve Block44f0eee2011-05-26 01:26:41 +01004324 i::Isolate* isolate = i::Isolate::Current();
4325 EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
4326 LOG_API(isolate, "String::Empty()");
4327 return Utils::ToLocal(isolate->factory()->empty_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00004328}
4329
4330
4331Local<String> v8::String::New(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004332 i::Isolate* isolate = i::Isolate::Current();
4333 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4334 LOG_API(isolate, "String::New(char)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004335 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004336 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004337 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004338 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004339 isolate->factory()->NewStringFromUtf8(
4340 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004341 return Utils::ToLocal(result);
4342}
4343
4344
Steve Block3ce2e202009-11-05 08:53:23 +00004345Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00004346 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01004347 i::Isolate* isolate = left_string->GetIsolate();
4348 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4349 LOG_API(isolate, "String::New(char)");
4350 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00004351 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Steve Block44f0eee2011-05-26 01:26:41 +01004352 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
4353 right_string);
Steve Block3ce2e202009-11-05 08:53:23 +00004354 return Utils::ToLocal(result);
4355}
4356
4357
Steve Blocka7e24c12009-10-30 11:49:00 +00004358Local<String> v8::String::NewUndetectable(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004359 i::Isolate* isolate = i::Isolate::Current();
4360 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4361 LOG_API(isolate, "String::NewUndetectable(char)");
4362 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004363 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004364 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004365 isolate->factory()->NewStringFromUtf8(
4366 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004367 result->MarkAsUndetectable();
4368 return Utils::ToLocal(result);
4369}
4370
4371
4372static int TwoByteStringLength(const uint16_t* data) {
4373 int length = 0;
4374 while (data[length] != '\0') length++;
4375 return length;
4376}
4377
4378
4379Local<String> v8::String::New(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004380 i::Isolate* isolate = i::Isolate::Current();
4381 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4382 LOG_API(isolate, "String::New(uint16_)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004383 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004384 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004385 if (length == -1) length = TwoByteStringLength(data);
4386 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004387 isolate->factory()->NewStringFromTwoByte(
4388 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004389 return Utils::ToLocal(result);
4390}
4391
4392
4393Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004394 i::Isolate* isolate = i::Isolate::Current();
4395 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4396 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4397 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004398 if (length == -1) length = TwoByteStringLength(data);
4399 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004400 isolate->factory()->NewStringFromTwoByte(
4401 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004402 result->MarkAsUndetectable();
4403 return Utils::ToLocal(result);
4404}
4405
4406
Steve Block44f0eee2011-05-26 01:26:41 +01004407i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004408 v8::String::ExternalStringResource* resource) {
4409 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004410 isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004411 return result;
4412}
4413
4414
Steve Block44f0eee2011-05-26 01:26:41 +01004415i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004416 v8::String::ExternalAsciiStringResource* resource) {
4417 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004418 isolate->factory()->NewExternalStringFromAscii(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004419 return result;
4420}
4421
4422
Steve Blocka7e24c12009-10-30 11:49:00 +00004423Local<String> v8::String::NewExternal(
4424 v8::String::ExternalStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004425 i::Isolate* isolate = i::Isolate::Current();
4426 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4427 LOG_API(isolate, "String::NewExternal");
4428 ENTER_V8(isolate);
4429 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4430 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004431 return Utils::ToLocal(result);
4432}
4433
4434
4435bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004436 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004437 i::Isolate* isolate = obj->GetIsolate();
4438 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4439 if (i::StringShape(*obj).IsExternalTwoByte()) {
4440 return false; // Already an external string.
4441 }
4442 ENTER_V8(isolate);
4443 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4444 return false;
4445 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004446 if (isolate->heap()->IsInGCPostProcessing()) {
4447 return false;
4448 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004449 bool result = obj->MakeExternal(resource);
4450 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004451 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004452 }
4453 return result;
4454}
4455
4456
4457Local<String> v8::String::NewExternal(
4458 v8::String::ExternalAsciiStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004459 i::Isolate* isolate = i::Isolate::Current();
4460 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4461 LOG_API(isolate, "String::NewExternal");
4462 ENTER_V8(isolate);
4463 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4464 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004465 return Utils::ToLocal(result);
4466}
4467
4468
4469bool v8::String::MakeExternal(
4470 v8::String::ExternalAsciiStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004471 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004472 i::Isolate* isolate = obj->GetIsolate();
4473 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4474 if (i::StringShape(*obj).IsExternalTwoByte()) {
4475 return false; // Already an external string.
4476 }
4477 ENTER_V8(isolate);
4478 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4479 return false;
4480 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004481 if (isolate->heap()->IsInGCPostProcessing()) {
4482 return false;
4483 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004484 bool result = obj->MakeExternal(resource);
4485 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004486 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004487 }
4488 return result;
4489}
4490
4491
4492bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004493 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004494 i::Isolate* isolate = obj->GetIsolate();
4495 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4496 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4497 return false;
4498 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004499 int size = obj->Size(); // Byte size of the original string.
4500 if (size < i::ExternalString::kSize)
4501 return false;
4502 i::StringShape shape(*obj);
4503 return !shape.IsExternal();
4504}
4505
4506
4507Local<v8::Object> v8::Object::New() {
Steve Block44f0eee2011-05-26 01:26:41 +01004508 i::Isolate* isolate = i::Isolate::Current();
4509 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4510 LOG_API(isolate, "Object::New");
4511 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004512 i::Handle<i::JSObject> obj =
Steve Block44f0eee2011-05-26 01:26:41 +01004513 isolate->factory()->NewJSObject(isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00004514 return Utils::ToLocal(obj);
4515}
4516
4517
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004518Local<v8::Value> v8::NumberObject::New(double value) {
4519 i::Isolate* isolate = i::Isolate::Current();
4520 EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
4521 LOG_API(isolate, "NumberObject::New");
4522 ENTER_V8(isolate);
4523 i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
4524 i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
4525 return Utils::ToLocal(obj);
4526}
4527
4528
4529double v8::NumberObject::NumberValue() const {
4530 i::Isolate* isolate = i::Isolate::Current();
4531 if (IsDeadCheck(isolate, "v8::NumberObject::NumberValue()")) return 0;
4532 LOG_API(isolate, "NumberObject::NumberValue");
4533 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4534 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4535 return jsvalue->value()->Number();
4536}
4537
4538
4539Local<v8::Value> v8::BooleanObject::New(bool value) {
4540 i::Isolate* isolate = i::Isolate::Current();
4541 EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
4542 LOG_API(isolate, "BooleanObject::New");
4543 ENTER_V8(isolate);
4544 i::Handle<i::Object> boolean(value ? isolate->heap()->true_value()
4545 : isolate->heap()->false_value());
4546 i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
4547 return Utils::ToLocal(obj);
4548}
4549
4550
4551bool v8::BooleanObject::BooleanValue() const {
4552 i::Isolate* isolate = i::Isolate::Current();
4553 if (IsDeadCheck(isolate, "v8::BooleanObject::BooleanValue()")) return 0;
4554 LOG_API(isolate, "BooleanObject::BooleanValue");
4555 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4556 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4557 return jsvalue->value()->IsTrue();
4558}
4559
4560
4561Local<v8::Value> v8::StringObject::New(Handle<String> value) {
4562 i::Isolate* isolate = i::Isolate::Current();
4563 EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
4564 LOG_API(isolate, "StringObject::New");
4565 ENTER_V8(isolate);
4566 i::Handle<i::Object> obj =
4567 isolate->factory()->ToObject(Utils::OpenHandle(*value));
4568 return Utils::ToLocal(obj);
4569}
4570
4571
4572Local<v8::String> v8::StringObject::StringValue() const {
4573 i::Isolate* isolate = i::Isolate::Current();
4574 if (IsDeadCheck(isolate, "v8::StringObject::StringValue()")) {
4575 return Local<v8::String>();
4576 }
4577 LOG_API(isolate, "StringObject::StringValue");
4578 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4579 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4580 return Utils::ToLocal(
4581 i::Handle<i::String>(i::String::cast(jsvalue->value())));
4582}
4583
4584
Steve Blocka7e24c12009-10-30 11:49:00 +00004585Local<v8::Value> v8::Date::New(double time) {
Steve Block44f0eee2011-05-26 01:26:41 +01004586 i::Isolate* isolate = i::Isolate::Current();
4587 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4588 LOG_API(isolate, "Date::New");
Steve Blockd0582a62009-12-15 09:54:21 +00004589 if (isnan(time)) {
4590 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4591 time = i::OS::nan_value();
4592 }
Steve Block44f0eee2011-05-26 01:26:41 +01004593 ENTER_V8(isolate);
4594 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004595 i::Handle<i::Object> obj =
4596 i::Execution::NewDate(time, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004597 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004598 return Utils::ToLocal(obj);
4599}
4600
4601
4602double v8::Date::NumberValue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004603 i::Isolate* isolate = i::Isolate::Current();
4604 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4605 LOG_API(isolate, "Date::NumberValue");
Steve Blocka7e24c12009-10-30 11:49:00 +00004606 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4607 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4608 return jsvalue->value()->Number();
4609}
4610
4611
Ben Murdochb0fe1622011-05-05 13:52:32 +01004612void v8::Date::DateTimeConfigurationChangeNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004613 i::Isolate* isolate = i::Isolate::Current();
4614 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4615 return);
4616 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
4617 ENTER_V8(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004618
Steve Block44f0eee2011-05-26 01:26:41 +01004619 i::HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004620 // Get the function ResetDateCache (defined in date-delay.js).
4621 i::Handle<i::String> func_name_str =
Steve Block44f0eee2011-05-26 01:26:41 +01004622 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4623 i::MaybeObject* result =
4624 isolate->js_builtins_object()->GetProperty(*func_name_str);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004625 i::Object* object_func;
4626 if (!result->ToObject(&object_func)) {
4627 return;
4628 }
4629
4630 if (object_func->IsJSFunction()) {
4631 i::Handle<i::JSFunction> func =
4632 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4633
4634 // Call ResetDateCache(0 but expect no exceptions:
4635 bool caught_exception = false;
Ben Murdoch8b112d22011-06-08 16:22:53 +01004636 i::Execution::TryCall(func,
4637 isolate->js_builtins_object(),
4638 0,
4639 NULL,
4640 &caught_exception);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004641 }
4642}
4643
4644
Ben Murdochf87a2032010-10-22 12:50:53 +01004645static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4646 char flags_buf[3];
4647 int num_flags = 0;
4648 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4649 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4650 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4651 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
Steve Block44f0eee2011-05-26 01:26:41 +01004652 return FACTORY->LookupSymbol(
Ben Murdochf87a2032010-10-22 12:50:53 +01004653 i::Vector<const char>(flags_buf, num_flags));
4654}
4655
4656
4657Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4658 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01004659 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
4660 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
4661 LOG_API(isolate, "RegExp::New");
4662 ENTER_V8(isolate);
4663 EXCEPTION_PREAMBLE(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01004664 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
4665 Utils::OpenHandle(*pattern),
4666 RegExpFlagsToString(flags),
4667 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004668 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01004669 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
4670}
4671
4672
4673Local<v8::String> v8::RegExp::GetSource() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004674 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4675 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
4676 return Local<v8::String>();
4677 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004678 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4679 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
4680}
4681
4682
4683// Assert that the static flags cast in GetFlags is valid.
4684#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
4685 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
4686 static_cast<int>(i::JSRegExp::internal_flag))
4687REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
4688REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
4689REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
4690REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
4691#undef REGEXP_FLAG_ASSERT_EQ
4692
4693v8::RegExp::Flags v8::RegExp::GetFlags() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004694 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
4695 return v8::RegExp::kNone;
4696 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004697 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4698 return static_cast<RegExp::Flags>(obj->GetFlags().value());
4699}
4700
4701
Steve Blocka7e24c12009-10-30 11:49:00 +00004702Local<v8::Array> v8::Array::New(int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004703 i::Isolate* isolate = i::Isolate::Current();
4704 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
4705 LOG_API(isolate, "Array::New");
4706 ENTER_V8(isolate);
4707 int real_length = length > 0 ? length : 0;
4708 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004709 i::Handle<i::Object> length_obj =
4710 isolate->factory()->NewNumberFromInt(real_length);
4711 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004712 return Utils::ToLocal(obj);
4713}
4714
4715
4716uint32_t v8::Array::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004717 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4718 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004719 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
4720 i::Object* length = obj->length();
4721 if (length->IsSmi()) {
4722 return i::Smi::cast(length)->value();
4723 } else {
4724 return static_cast<uint32_t>(length->Number());
4725 }
4726}
4727
4728
4729Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01004730 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4731 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004732 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
4733 if (!self->HasFastElements()) {
4734 return Local<Object>();
4735 }
4736 i::FixedArray* elms = i::FixedArray::cast(self->elements());
4737 i::Object* paragon = elms->get(index);
4738 if (!paragon->IsJSObject()) {
4739 return Local<Object>();
4740 }
4741 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01004742 EXCEPTION_PREAMBLE(isolate);
4743 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004744 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
4745 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01004746 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004747 return Utils::ToLocal(result);
4748}
4749
4750
4751Local<String> v8::String::NewSymbol(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004752 i::Isolate* isolate = i::Isolate::Current();
4753 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
4754 LOG_API(isolate, "String::NewSymbol(char)");
4755 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004756 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004757 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004758 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004759 return Utils::ToLocal(result);
4760}
4761
4762
4763Local<Number> v8::Number::New(double value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004764 i::Isolate* isolate = i::Isolate::Current();
4765 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
Steve Blockd0582a62009-12-15 09:54:21 +00004766 if (isnan(value)) {
4767 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4768 value = i::OS::nan_value();
4769 }
Steve Block44f0eee2011-05-26 01:26:41 +01004770 ENTER_V8(isolate);
4771 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004772 return Utils::NumberToLocal(result);
4773}
4774
4775
4776Local<Integer> v8::Integer::New(int32_t value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004777 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4778 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004779 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004780 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
4781 isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004782 }
Steve Block44f0eee2011-05-26 01:26:41 +01004783 ENTER_V8(isolate);
4784 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004785 return Utils::IntegerToLocal(result);
4786}
4787
4788
Steve Block3ce2e202009-11-05 08:53:23 +00004789Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
4790 bool fits_into_int32_t = (value & (1 << 31)) == 0;
4791 if (fits_into_int32_t) {
4792 return Integer::New(static_cast<int32_t>(value));
4793 }
Steve Block44f0eee2011-05-26 01:26:41 +01004794 i::Isolate* isolate = i::Isolate::Current();
4795 ENTER_V8(isolate);
4796 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00004797 return Utils::IntegerToLocal(result);
4798}
4799
4800
Steve Blocka7e24c12009-10-30 11:49:00 +00004801void V8::IgnoreOutOfMemoryException() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004802 EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004803}
4804
4805
4806bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004807 i::Isolate* isolate = i::Isolate::Current();
4808 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
4809 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
4810 ENTER_V8(isolate);
4811 i::HandleScope scope(isolate);
4812 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004813 NeanderObject obj(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00004814 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004815 obj.set(1, data.IsEmpty() ?
Steve Block44f0eee2011-05-26 01:26:41 +01004816 isolate->heap()->undefined_value() :
Steve Blocka7e24c12009-10-30 11:49:00 +00004817 *Utils::OpenHandle(*data));
4818 listeners.add(obj.value());
4819 return true;
4820}
4821
4822
4823void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01004824 i::Isolate* isolate = i::Isolate::Current();
4825 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
4826 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
4827 ENTER_V8(isolate);
4828 i::HandleScope scope(isolate);
4829 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004830 for (int i = 0; i < listeners.length(); i++) {
4831 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
4832
4833 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
Ben Murdoch257744e2011-11-30 15:57:28 +00004834 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
4835 if (callback_obj->address() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004836 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004837 }
4838 }
4839}
4840
4841
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004842void V8::SetCaptureStackTraceForUncaughtExceptions(
4843 bool capture,
4844 int frame_limit,
4845 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01004846 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004847 capture,
4848 frame_limit,
4849 options);
4850}
4851
4852
Steve Blocka7e24c12009-10-30 11:49:00 +00004853void V8::SetCounterFunction(CounterLookupCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004854 i::Isolate* isolate = EnterIsolateIfNeeded();
4855 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
4856 isolate->stats_table()->SetCounterFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004857}
4858
4859void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004860 i::Isolate* isolate = EnterIsolateIfNeeded();
4861 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
4862 isolate->stats_table()->SetCreateHistogramFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004863}
4864
4865void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004866 i::Isolate* isolate = EnterIsolateIfNeeded();
4867 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
4868 isolate->stats_table()->
4869 SetAddHistogramSampleFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004870}
4871
4872void V8::EnableSlidingStateWindow() {
Steve Block44f0eee2011-05-26 01:26:41 +01004873 i::Isolate* isolate = i::Isolate::Current();
4874 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
4875 isolate->logger()->EnableSlidingStateWindow();
Steve Blocka7e24c12009-10-30 11:49:00 +00004876}
4877
4878
4879void V8::SetFailedAccessCheckCallbackFunction(
4880 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004881 i::Isolate* isolate = i::Isolate::Current();
4882 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
4883 return;
4884 }
4885 isolate->SetFailedAccessCheckCallback(callback);
4886}
4887
4888void V8::AddObjectGroup(Persistent<Value>* objects,
4889 size_t length,
4890 RetainedObjectInfo* info) {
4891 i::Isolate* isolate = i::Isolate::Current();
4892 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
4893 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
4894 isolate->global_handles()->AddObjectGroup(
4895 reinterpret_cast<i::Object***>(objects), length, info);
Steve Blocka7e24c12009-10-30 11:49:00 +00004896}
4897
4898
Steve Block44f0eee2011-05-26 01:26:41 +01004899void V8::AddImplicitReferences(Persistent<Object> parent,
4900 Persistent<Value>* children,
4901 size_t length) {
4902 i::Isolate* isolate = i::Isolate::Current();
4903 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004904 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
Steve Block44f0eee2011-05-26 01:26:41 +01004905 isolate->global_handles()->AddImplicitReferences(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004906 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*parent)).location(),
Steve Block44f0eee2011-05-26 01:26:41 +01004907 reinterpret_cast<i::Object***>(children), length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004908}
4909
4910
4911int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
Steve Block44f0eee2011-05-26 01:26:41 +01004912 i::Isolate* isolate = i::Isolate::Current();
4913 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
4914 return 0;
4915 }
4916 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
4917 change_in_bytes);
Steve Blocka7e24c12009-10-30 11:49:00 +00004918}
4919
4920
4921void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004922 i::Isolate* isolate = i::Isolate::Current();
4923 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
4924 isolate->heap()->SetGlobalGCPrologueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004925}
4926
4927
4928void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004929 i::Isolate* isolate = i::Isolate::Current();
4930 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
4931 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004932}
4933
4934
Steve Block6ded16b2010-05-10 14:33:55 +01004935void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004936 i::Isolate* isolate = i::Isolate::Current();
4937 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
4938 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004939}
4940
4941
4942void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004943 i::Isolate* isolate = i::Isolate::Current();
4944 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
4945 isolate->heap()->RemoveGCPrologueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004946}
4947
4948
4949void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004950 i::Isolate* isolate = i::Isolate::Current();
4951 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
4952 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004953}
4954
4955
4956void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004957 i::Isolate* isolate = i::Isolate::Current();
4958 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
4959 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004960}
4961
4962
Iain Merrick9ac36c92010-09-13 15:29:50 +01004963void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
4964 ObjectSpace space,
4965 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01004966 i::Isolate* isolate = i::Isolate::Current();
4967 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
4968 isolate->memory_allocator()->AddMemoryAllocationCallback(
4969 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004970}
4971
4972
4973void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004974 i::Isolate* isolate = i::Isolate::Current();
4975 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
4976 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
4977 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004978}
4979
4980
Steve Blocka7e24c12009-10-30 11:49:00 +00004981void V8::PauseProfiler() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004982 i::Isolate* isolate = i::Isolate::Current();
4983 isolate->logger()->PauseProfiler();
Steve Blocka7e24c12009-10-30 11:49:00 +00004984}
4985
4986
4987void V8::ResumeProfiler() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004988 i::Isolate* isolate = i::Isolate::Current();
4989 isolate->logger()->ResumeProfiler();
Steve Blocka7e24c12009-10-30 11:49:00 +00004990}
4991
4992
4993bool V8::IsProfilerPaused() {
Steve Block44f0eee2011-05-26 01:26:41 +01004994 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004995 return isolate->logger()->IsProfilerPaused();
Steve Blocka7e24c12009-10-30 11:49:00 +00004996}
4997
4998
4999int V8::GetCurrentThreadId() {
Steve Block44f0eee2011-05-26 01:26:41 +01005000 i::Isolate* isolate = i::Isolate::Current();
5001 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
Ben Murdoch8b112d22011-06-08 16:22:53 +01005002 return isolate->thread_id().ToInteger();
Steve Blocka7e24c12009-10-30 11:49:00 +00005003}
5004
5005
5006void V8::TerminateExecution(int thread_id) {
Steve Block44f0eee2011-05-26 01:26:41 +01005007 i::Isolate* isolate = i::Isolate::Current();
5008 if (!isolate->IsInitialized()) return;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005009 API_ENTRY_CHECK(isolate, "V8::TerminateExecution()");
Steve Blocka7e24c12009-10-30 11:49:00 +00005010 // If the thread_id identifies the current thread just terminate
5011 // execution right away. Otherwise, ask the thread manager to
5012 // terminate the thread with the given id if any.
Ben Murdoch8b112d22011-06-08 16:22:53 +01005013 i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
5014 if (isolate->thread_id().Equals(internal_tid)) {
Steve Block44f0eee2011-05-26 01:26:41 +01005015 isolate->stack_guard()->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00005016 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +01005017 isolate->thread_manager()->TerminateExecution(internal_tid);
Steve Blocka7e24c12009-10-30 11:49:00 +00005018 }
5019}
5020
5021
Steve Block44f0eee2011-05-26 01:26:41 +01005022void V8::TerminateExecution(Isolate* isolate) {
5023 // If no isolate is supplied, use the default isolate.
5024 if (isolate != NULL) {
5025 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
5026 } else {
5027 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
5028 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005029}
5030
5031
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005032bool V8::IsExecutionTerminating(Isolate* isolate) {
5033 i::Isolate* i_isolate = isolate != NULL ?
5034 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
5035 return IsExecutionTerminatingCheck(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005036}
5037
5038
5039Isolate* Isolate::GetCurrent() {
5040 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
5041 return reinterpret_cast<Isolate*>(isolate);
5042}
5043
5044
5045Isolate* Isolate::New() {
5046 i::Isolate* isolate = new i::Isolate();
5047 return reinterpret_cast<Isolate*>(isolate);
5048}
5049
5050
5051void Isolate::Dispose() {
5052 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5053 if (!ApiCheck(!isolate->IsInUse(),
5054 "v8::Isolate::Dispose()",
5055 "Disposing the isolate that is entered by a thread.")) {
5056 return;
Steve Block6ded16b2010-05-10 14:33:55 +01005057 }
Steve Block44f0eee2011-05-26 01:26:41 +01005058 isolate->TearDown();
5059}
5060
5061
5062void Isolate::Enter() {
5063 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5064 isolate->Enter();
5065}
5066
5067
5068void Isolate::Exit() {
5069 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5070 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01005071}
5072
5073
Ben Murdoch257744e2011-11-30 15:57:28 +00005074void Isolate::SetData(void* data) {
5075 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5076 isolate->SetData(data);
5077}
5078
5079void* Isolate::GetData() {
5080 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5081 return isolate->GetData();
5082}
5083
5084
5085String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
5086 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005087 i::Isolate* isolate = i::Isolate::Current();
5088 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005089 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005090 ENTER_V8(isolate);
5091 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005092 TryCatch try_catch;
5093 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005094 if (str.IsEmpty()) return;
5095 length_ = str->Utf8Length();
5096 str_ = i::NewArray<char>(length_ + 1);
5097 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005098}
5099
5100
5101String::Utf8Value::~Utf8Value() {
5102 i::DeleteArray(str_);
5103}
5104
5105
Ben Murdoch257744e2011-11-30 15:57:28 +00005106String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
5107 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005108 i::Isolate* isolate = i::Isolate::Current();
5109 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005110 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005111 ENTER_V8(isolate);
5112 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005113 TryCatch try_catch;
5114 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005115 if (str.IsEmpty()) return;
5116 length_ = str->Length();
5117 str_ = i::NewArray<char>(length_ + 1);
5118 str->WriteAscii(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005119}
5120
5121
5122String::AsciiValue::~AsciiValue() {
5123 i::DeleteArray(str_);
5124}
5125
5126
Ben Murdoch257744e2011-11-30 15:57:28 +00005127String::Value::Value(v8::Handle<v8::Value> obj)
5128 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01005129 i::Isolate* isolate = i::Isolate::Current();
5130 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00005131 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01005132 ENTER_V8(isolate);
5133 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005134 TryCatch try_catch;
5135 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00005136 if (str.IsEmpty()) return;
5137 length_ = str->Length();
5138 str_ = i::NewArray<uint16_t>(length_ + 1);
5139 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00005140}
5141
5142
5143String::Value::~Value() {
5144 i::DeleteArray(str_);
5145}
5146
5147Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005148 i::Isolate* isolate = i::Isolate::Current();
5149 LOG_API(isolate, "RangeError");
5150 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
5151 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005152 i::Object* error;
5153 {
Steve Block44f0eee2011-05-26 01:26:41 +01005154 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005155 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005156 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005157 error = *result;
5158 }
5159 i::Handle<i::Object> result(error);
5160 return Utils::ToLocal(result);
5161}
5162
5163Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005164 i::Isolate* isolate = i::Isolate::Current();
5165 LOG_API(isolate, "ReferenceError");
5166 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
5167 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005168 i::Object* error;
5169 {
Steve Block44f0eee2011-05-26 01:26:41 +01005170 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005171 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005172 i::Handle<i::Object> result =
5173 isolate->factory()->NewReferenceError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005174 error = *result;
5175 }
5176 i::Handle<i::Object> result(error);
5177 return Utils::ToLocal(result);
5178}
5179
5180Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005181 i::Isolate* isolate = i::Isolate::Current();
5182 LOG_API(isolate, "SyntaxError");
5183 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
5184 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005185 i::Object* error;
5186 {
Steve Block44f0eee2011-05-26 01:26:41 +01005187 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005188 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005189 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005190 error = *result;
5191 }
5192 i::Handle<i::Object> result(error);
5193 return Utils::ToLocal(result);
5194}
5195
5196Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005197 i::Isolate* isolate = i::Isolate::Current();
5198 LOG_API(isolate, "TypeError");
5199 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
5200 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005201 i::Object* error;
5202 {
Steve Block44f0eee2011-05-26 01:26:41 +01005203 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005204 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005205 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005206 error = *result;
5207 }
5208 i::Handle<i::Object> result(error);
5209 return Utils::ToLocal(result);
5210}
5211
5212Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005213 i::Isolate* isolate = i::Isolate::Current();
5214 LOG_API(isolate, "Error");
5215 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
5216 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005217 i::Object* error;
5218 {
Steve Block44f0eee2011-05-26 01:26:41 +01005219 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005220 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01005221 i::Handle<i::Object> result = isolate->factory()->NewError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00005222 error = *result;
5223 }
5224 i::Handle<i::Object> result(error);
5225 return Utils::ToLocal(result);
5226}
5227
5228
5229// --- D e b u g S u p p o r t ---
5230
5231#ifdef ENABLE_DEBUGGER_SUPPORT
Leon Clarkef7060e22010-06-03 12:02:55 +01005232
Leon Clarkef7060e22010-06-03 12:02:55 +01005233static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
Steve Block44f0eee2011-05-26 01:26:41 +01005234 i::Isolate* isolate = i::Isolate::Current();
5235 if (isolate->debug_event_callback() != NULL) {
5236 isolate->debug_event_callback()(event_details.GetEvent(),
5237 event_details.GetExecutionState(),
5238 event_details.GetEventData(),
5239 event_details.GetCallbackData());
Leon Clarkef7060e22010-06-03 12:02:55 +01005240 }
5241}
5242
5243
Steve Blocka7e24c12009-10-30 11:49:00 +00005244bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005245 i::Isolate* isolate = i::Isolate::Current();
5246 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
5247 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5248 ENTER_V8(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01005249
Steve Block44f0eee2011-05-26 01:26:41 +01005250 isolate->set_debug_event_callback(that);
Leon Clarkef7060e22010-06-03 12:02:55 +01005251
Steve Block44f0eee2011-05-26 01:26:41 +01005252 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005253 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Leon Clarkef7060e22010-06-03 12:02:55 +01005254 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005255 foreign =
5256 isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
Leon Clarkef7060e22010-06-03 12:02:55 +01005257 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005258 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Leon Clarkef7060e22010-06-03 12:02:55 +01005259 return true;
5260}
5261
5262
5263bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005264 i::Isolate* isolate = i::Isolate::Current();
5265 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
5266 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
5267 ENTER_V8(isolate);
5268 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005269 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00005270 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005271 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00005272 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005273 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005274 return true;
5275}
5276
5277
5278bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
5279 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005280 i::Isolate* isolate = i::Isolate::Current();
5281 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
5282 ENTER_V8(isolate);
5283 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
5284 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00005285 return true;
5286}
5287
5288
Steve Block44f0eee2011-05-26 01:26:41 +01005289void Debug::DebugBreak(Isolate* isolate) {
5290 // If no isolate is supplied, use the default isolate.
5291 if (isolate != NULL) {
5292 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
5293 } else {
5294 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
5295 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005296}
5297
5298
Steve Block44f0eee2011-05-26 01:26:41 +01005299void Debug::CancelDebugBreak(Isolate* isolate) {
5300 // If no isolate is supplied, use the default isolate.
5301 if (isolate != NULL) {
5302 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5303 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
5304 } else {
5305 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
5306 }
Ben Murdochf87a2032010-10-22 12:50:53 +01005307}
5308
5309
Steve Block44f0eee2011-05-26 01:26:41 +01005310void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
5311 // If no isolate is supplied, use the default isolate.
5312 if (isolate != NULL) {
5313 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5314 internal_isolate->debugger()->EnqueueDebugCommand(data);
5315 } else {
5316 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
5317 }
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005318}
5319
5320
Steve Blocka7e24c12009-10-30 11:49:00 +00005321static void MessageHandlerWrapper(const v8::Debug::Message& message) {
Steve Block44f0eee2011-05-26 01:26:41 +01005322 i::Isolate* isolate = i::Isolate::Current();
5323 if (isolate->message_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005324 v8::String::Value json(message.GetJSON());
Steve Block44f0eee2011-05-26 01:26:41 +01005325 (isolate->message_handler())(*json, json.length(), message.GetClientData());
Steve Blocka7e24c12009-10-30 11:49:00 +00005326 }
5327}
5328
5329
5330void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
5331 bool message_handler_thread) {
Steve Block44f0eee2011-05-26 01:26:41 +01005332 i::Isolate* isolate = i::Isolate::Current();
5333 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5334 ENTER_V8(isolate);
5335
Steve Blocka7e24c12009-10-30 11:49:00 +00005336 // Message handler thread not supported any more. Parameter temporally left in
Steve Block44f0eee2011-05-26 01:26:41 +01005337 // the API for client compatibility reasons.
Steve Blocka7e24c12009-10-30 11:49:00 +00005338 CHECK(!message_handler_thread);
5339
5340 // TODO(sgjesse) support the old message handler API through a simple wrapper.
Steve Block44f0eee2011-05-26 01:26:41 +01005341 isolate->set_message_handler(handler);
5342 if (handler != NULL) {
5343 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
Steve Blocka7e24c12009-10-30 11:49:00 +00005344 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005345 isolate->debugger()->SetMessageHandler(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00005346 }
5347}
5348
5349
5350void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01005351 i::Isolate* isolate = i::Isolate::Current();
5352 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5353 ENTER_V8(isolate);
5354 isolate->debugger()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00005355}
5356
5357
5358void Debug::SendCommand(const uint16_t* command, int length,
Steve Block44f0eee2011-05-26 01:26:41 +01005359 ClientData* client_data,
5360 Isolate* isolate) {
5361 // If no isolate is supplied, use the default isolate.
5362 if (isolate != NULL) {
5363 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5364 internal_isolate->debugger()->ProcessCommand(
5365 i::Vector<const uint16_t>(command, length), client_data);
5366 } else {
5367 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
5368 i::Vector<const uint16_t>(command, length), client_data);
5369 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005370}
5371
5372
5373void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
5374 int period) {
Steve Block44f0eee2011-05-26 01:26:41 +01005375 i::Isolate* isolate = i::Isolate::Current();
5376 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
5377 ENTER_V8(isolate);
5378 isolate->debugger()->SetHostDispatchHandler(handler, period);
Steve Blocka7e24c12009-10-30 11:49:00 +00005379}
5380
5381
Steve Blockd0582a62009-12-15 09:54:21 +00005382void Debug::SetDebugMessageDispatchHandler(
Leon Clarkee46be812010-01-19 14:06:41 +00005383 DebugMessageDispatchHandler handler, bool provide_locker) {
Steve Block44f0eee2011-05-26 01:26:41 +01005384 i::Isolate* isolate = i::Isolate::Current();
5385 EnsureInitializedForIsolate(isolate,
5386 "v8::Debug::SetDebugMessageDispatchHandler");
5387 ENTER_V8(isolate);
5388 isolate->debugger()->SetDebugMessageDispatchHandler(
5389 handler, provide_locker);
Steve Blockd0582a62009-12-15 09:54:21 +00005390}
5391
5392
Steve Blocka7e24c12009-10-30 11:49:00 +00005393Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
5394 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005395 i::Isolate* isolate = i::Isolate::Current();
5396 if (!isolate->IsInitialized()) return Local<Value>();
5397 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
5398 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005399 i::Handle<i::Object> result;
Steve Block44f0eee2011-05-26 01:26:41 +01005400 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005401 if (data.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005402 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5403 isolate->factory()->undefined_value(),
5404 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005405 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005406 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5407 Utils::OpenHandle(*data),
5408 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005409 }
Steve Block44f0eee2011-05-26 01:26:41 +01005410 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005411 return Utils::ToLocal(result);
5412}
5413
5414
5415Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01005416 i::Isolate* isolate = i::Isolate::Current();
5417 if (!isolate->IsInitialized()) return Local<Value>();
5418 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
5419 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005420 v8::HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01005421 i::Debug* isolate_debug = isolate->debug();
5422 isolate_debug->Load();
5423 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5424 i::Handle<i::String> name =
5425 isolate->factory()->LookupAsciiSymbol("MakeMirror");
Steve Blocka7e24c12009-10-30 11:49:00 +00005426 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5427 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5428 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5429 const int kArgc = 1;
5430 v8::Handle<v8::Value> argv[kArgc] = { obj };
Steve Block44f0eee2011-05-26 01:26:41 +01005431 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005432 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5433 kArgc,
5434 argv);
Steve Block44f0eee2011-05-26 01:26:41 +01005435 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005436 return scope.Close(result);
5437}
5438
5439
Leon Clarkee46be812010-01-19 14:06:41 +00005440bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
Steve Block44f0eee2011-05-26 01:26:41 +01005441 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5442 wait_for_connection);
Steve Blocka7e24c12009-10-30 11:49:00 +00005443}
Leon Clarkee46be812010-01-19 14:06:41 +00005444
5445void Debug::ProcessDebugMessages() {
5446 i::Execution::ProcessDebugMesssages(true);
5447}
5448
Steve Block6ded16b2010-05-10 14:33:55 +01005449Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01005450 i::Isolate* isolate = i::Isolate::Current();
5451 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5452 ENTER_V8(isolate);
5453 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01005454}
5455
Steve Blocka7e24c12009-10-30 11:49:00 +00005456#endif // ENABLE_DEBUGGER_SUPPORT
5457
Steve Block6ded16b2010-05-10 14:33:55 +01005458
Steve Block6ded16b2010-05-10 14:33:55 +01005459Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005460 i::Isolate* isolate = i::Isolate::Current();
5461 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
Steve Block6ded16b2010-05-10 14:33:55 +01005462 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5463 const i::CodeEntry* entry = node->entry();
5464 if (!entry->has_name_prefix()) {
5465 return Handle<String>(ToApi<String>(
Steve Block44f0eee2011-05-26 01:26:41 +01005466 isolate->factory()->LookupAsciiSymbol(entry->name())));
Steve Block6ded16b2010-05-10 14:33:55 +01005467 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005468 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5469 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5470 isolate->factory()->LookupAsciiSymbol(entry->name()))));
Steve Block6ded16b2010-05-10 14:33:55 +01005471 }
5472}
5473
5474
5475Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005476 i::Isolate* isolate = i::Isolate::Current();
5477 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
Steve Block6ded16b2010-05-10 14:33:55 +01005478 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005479 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005480 node->entry()->resource_name())));
5481}
5482
5483
5484int CpuProfileNode::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005485 i::Isolate* isolate = i::Isolate::Current();
5486 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
Steve Block6ded16b2010-05-10 14:33:55 +01005487 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5488}
5489
5490
5491double CpuProfileNode::GetTotalTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005492 i::Isolate* isolate = i::Isolate::Current();
5493 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005494 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5495}
5496
5497
5498double CpuProfileNode::GetSelfTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005499 i::Isolate* isolate = i::Isolate::Current();
5500 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005501 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5502}
5503
5504
5505double CpuProfileNode::GetTotalSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005506 i::Isolate* isolate = i::Isolate::Current();
5507 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005508 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5509}
5510
5511
5512double CpuProfileNode::GetSelfSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005513 i::Isolate* isolate = i::Isolate::Current();
5514 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005515 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5516}
5517
5518
5519unsigned CpuProfileNode::GetCallUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005520 i::Isolate* isolate = i::Isolate::Current();
5521 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005522 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01005523}
5524
5525
5526int CpuProfileNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005527 i::Isolate* isolate = i::Isolate::Current();
5528 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005529 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5530}
5531
5532
5533const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005534 i::Isolate* isolate = i::Isolate::Current();
5535 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
Steve Block6ded16b2010-05-10 14:33:55 +01005536 const i::ProfileNode* child =
5537 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5538 return reinterpret_cast<const CpuProfileNode*>(child);
5539}
5540
5541
Steve Block44f0eee2011-05-26 01:26:41 +01005542void CpuProfile::Delete() {
5543 i::Isolate* isolate = i::Isolate::Current();
5544 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5545 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5546 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5547 !i::CpuProfiler::HasDetachedProfiles()) {
5548 // If this was the last profile, clean up all accessory data as well.
5549 i::CpuProfiler::DeleteAllProfiles();
5550 }
5551}
5552
5553
Steve Block6ded16b2010-05-10 14:33:55 +01005554unsigned CpuProfile::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005555 i::Isolate* isolate = i::Isolate::Current();
5556 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
Steve Block6ded16b2010-05-10 14:33:55 +01005557 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5558}
5559
5560
5561Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005562 i::Isolate* isolate = i::Isolate::Current();
5563 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
Steve Block6ded16b2010-05-10 14:33:55 +01005564 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005565 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005566 profile->title())));
5567}
5568
5569
5570const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005571 i::Isolate* isolate = i::Isolate::Current();
5572 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005573 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5574 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5575}
5576
5577
5578const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005579 i::Isolate* isolate = i::Isolate::Current();
5580 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005581 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5582 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5583}
5584
5585
5586int CpuProfiler::GetProfilesCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005587 i::Isolate* isolate = i::Isolate::Current();
5588 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005589 return i::CpuProfiler::GetProfilesCount();
5590}
5591
5592
Leon Clarkef7060e22010-06-03 12:02:55 +01005593const CpuProfile* CpuProfiler::GetProfile(int index,
5594 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005595 i::Isolate* isolate = i::Isolate::Current();
5596 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005597 return reinterpret_cast<const CpuProfile*>(
5598 i::CpuProfiler::GetProfile(
5599 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5600 index));
Steve Block6ded16b2010-05-10 14:33:55 +01005601}
5602
5603
Leon Clarkef7060e22010-06-03 12:02:55 +01005604const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5605 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005606 i::Isolate* isolate = i::Isolate::Current();
5607 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005608 return reinterpret_cast<const CpuProfile*>(
5609 i::CpuProfiler::FindProfile(
5610 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5611 uid));
Steve Block6ded16b2010-05-10 14:33:55 +01005612}
5613
5614
5615void CpuProfiler::StartProfiling(Handle<String> title) {
Steve Block44f0eee2011-05-26 01:26:41 +01005616 i::Isolate* isolate = i::Isolate::Current();
5617 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005618 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5619}
5620
5621
Leon Clarkef7060e22010-06-03 12:02:55 +01005622const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5623 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005624 i::Isolate* isolate = i::Isolate::Current();
5625 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005626 return reinterpret_cast<const CpuProfile*>(
Leon Clarkef7060e22010-06-03 12:02:55 +01005627 i::CpuProfiler::StopProfiling(
5628 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5629 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01005630}
5631
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005632
Steve Block44f0eee2011-05-26 01:26:41 +01005633void CpuProfiler::DeleteAllProfiles() {
5634 i::Isolate* isolate = i::Isolate::Current();
5635 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5636 i::CpuProfiler::DeleteAllProfiles();
5637}
5638
5639
Iain Merrick75681382010-08-19 15:07:18 +01005640static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5641 return const_cast<i::HeapGraphEdge*>(
5642 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5643}
5644
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005645
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005646HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005647 i::Isolate* isolate = i::Isolate::Current();
5648 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005649 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005650}
5651
5652
5653Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005654 i::Isolate* isolate = i::Isolate::Current();
5655 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
Iain Merrick75681382010-08-19 15:07:18 +01005656 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005657 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01005658 case i::HeapGraphEdge::kContextVariable:
5659 case i::HeapGraphEdge::kInternal:
5660 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005661 case i::HeapGraphEdge::kShortcut:
Steve Block44f0eee2011-05-26 01:26:41 +01005662 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005663 edge->name())));
Iain Merrick75681382010-08-19 15:07:18 +01005664 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005665 case i::HeapGraphEdge::kHidden:
Steve Block44f0eee2011-05-26 01:26:41 +01005666 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005667 edge->index())));
5668 default: UNREACHABLE();
5669 }
Steve Block44f0eee2011-05-26 01:26:41 +01005670 return v8::Undefined();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005671}
5672
5673
5674const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005675 i::Isolate* isolate = i::Isolate::Current();
5676 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
Iain Merrick75681382010-08-19 15:07:18 +01005677 const i::HeapEntry* from = ToInternal(this)->From();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005678 return reinterpret_cast<const HeapGraphNode*>(from);
5679}
5680
5681
5682const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005683 i::Isolate* isolate = i::Isolate::Current();
5684 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
Iain Merrick75681382010-08-19 15:07:18 +01005685 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005686 return reinterpret_cast<const HeapGraphNode*>(to);
5687}
5688
5689
Iain Merrick75681382010-08-19 15:07:18 +01005690static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5691 return const_cast<i::HeapEntry*>(
5692 reinterpret_cast<const i::HeapEntry*>(entry));
5693}
5694
5695
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005696HeapGraphNode::Type HeapGraphNode::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005697 i::Isolate* isolate = i::Isolate::Current();
5698 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005699 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005700}
5701
5702
5703Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005704 i::Isolate* isolate = i::Isolate::Current();
5705 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
5706 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005707 ToInternal(this)->name())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005708}
5709
5710
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005711uint64_t HeapGraphNode::GetId() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005712 i::Isolate* isolate = i::Isolate::Current();
5713 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
Iain Merrick75681382010-08-19 15:07:18 +01005714 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005715}
5716
5717
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005718int HeapGraphNode::GetSelfSize() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005719 i::Isolate* isolate = i::Isolate::Current();
5720 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
Iain Merrick75681382010-08-19 15:07:18 +01005721 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005722}
5723
5724
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005725int HeapGraphNode::GetRetainedSize(bool exact) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005726 i::Isolate* isolate = i::Isolate::Current();
5727 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005728 return ToInternal(this)->RetainedSize(exact);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005729}
5730
5731
5732int HeapGraphNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005733 i::Isolate* isolate = i::Isolate::Current();
5734 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
Iain Merrick75681382010-08-19 15:07:18 +01005735 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005736}
5737
5738
5739const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005740 i::Isolate* isolate = i::Isolate::Current();
5741 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005742 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005743 &ToInternal(this)->children()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005744}
5745
5746
5747int HeapGraphNode::GetRetainersCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005748 i::Isolate* isolate = i::Isolate::Current();
5749 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
Iain Merrick75681382010-08-19 15:07:18 +01005750 return ToInternal(this)->retainers().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005751}
5752
5753
5754const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005755 i::Isolate* isolate = i::Isolate::Current();
5756 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005757 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005758 ToInternal(this)->retainers()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005759}
5760
5761
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005762const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005763 i::Isolate* isolate = i::Isolate::Current();
5764 IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005765 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
5766}
5767
5768
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005769v8::Handle<v8::Value> HeapGraphNode::GetHeapValue() const {
5770 i::Isolate* isolate = i::Isolate::Current();
5771 IsDeadCheck(isolate, "v8::HeapGraphNode::GetHeapValue");
5772 i::Handle<i::HeapObject> object = ToInternal(this)->GetHeapObject();
5773 return v8::Handle<Value>(!object.is_null() ?
5774 ToApi<Value>(object) : ToApi<Value>(
5775 isolate->factory()->undefined_value()));
5776}
5777
5778
Iain Merrick75681382010-08-19 15:07:18 +01005779static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5780 return const_cast<i::HeapSnapshot*>(
5781 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5782}
5783
5784
Steve Block44f0eee2011-05-26 01:26:41 +01005785void HeapSnapshot::Delete() {
5786 i::Isolate* isolate = i::Isolate::Current();
5787 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
5788 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
5789 ToInternal(this)->Delete();
5790 } else {
5791 // If this is the last snapshot, clean up all accessory data as well.
5792 i::HeapProfiler::DeleteAllSnapshots();
5793 }
5794}
5795
5796
Steve Block791712a2010-08-27 10:21:07 +01005797HeapSnapshot::Type HeapSnapshot::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005798 i::Isolate* isolate = i::Isolate::Current();
5799 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
Steve Block791712a2010-08-27 10:21:07 +01005800 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
5801}
5802
5803
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005804unsigned HeapSnapshot::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005805 i::Isolate* isolate = i::Isolate::Current();
5806 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
Iain Merrick75681382010-08-19 15:07:18 +01005807 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005808}
5809
5810
5811Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005812 i::Isolate* isolate = i::Isolate::Current();
5813 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
5814 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005815 ToInternal(this)->title())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005816}
5817
5818
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005819const HeapGraphNode* HeapSnapshot::GetRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005820 i::Isolate* isolate = i::Isolate::Current();
5821 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
Iain Merrick75681382010-08-19 15:07:18 +01005822 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005823}
5824
5825
Ben Murdochb0fe1622011-05-05 13:52:32 +01005826const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005827 i::Isolate* isolate = i::Isolate::Current();
5828 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
Ben Murdochb0fe1622011-05-05 13:52:32 +01005829 return reinterpret_cast<const HeapGraphNode*>(
5830 ToInternal(this)->GetEntryById(id));
5831}
5832
5833
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005834int HeapSnapshot::GetNodesCount() const {
5835 i::Isolate* isolate = i::Isolate::Current();
5836 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
5837 return ToInternal(this)->entries()->length();
5838}
5839
5840
5841const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
5842 i::Isolate* isolate = i::Isolate::Current();
5843 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
5844 return reinterpret_cast<const HeapGraphNode*>(
5845 ToInternal(this)->entries()->at(index));
5846}
5847
5848
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005849void HeapSnapshot::Serialize(OutputStream* stream,
5850 HeapSnapshot::SerializationFormat format) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005851 i::Isolate* isolate = i::Isolate::Current();
5852 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005853 ApiCheck(format == kJSON,
5854 "v8::HeapSnapshot::Serialize",
5855 "Unknown serialization format");
5856 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
5857 "v8::HeapSnapshot::Serialize",
5858 "Unsupported output encoding");
5859 ApiCheck(stream->GetChunkSize() > 0,
5860 "v8::HeapSnapshot::Serialize",
5861 "Invalid stream chunk size");
5862 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
5863 serializer.Serialize(stream);
5864}
5865
5866
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005867int HeapProfiler::GetSnapshotsCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005868 i::Isolate* isolate = i::Isolate::Current();
5869 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005870 return i::HeapProfiler::GetSnapshotsCount();
5871}
5872
5873
5874const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005875 i::Isolate* isolate = i::Isolate::Current();
5876 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005877 return reinterpret_cast<const HeapSnapshot*>(
5878 i::HeapProfiler::GetSnapshot(index));
5879}
5880
5881
5882const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
Steve Block44f0eee2011-05-26 01:26:41 +01005883 i::Isolate* isolate = i::Isolate::Current();
5884 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005885 return reinterpret_cast<const HeapSnapshot*>(
5886 i::HeapProfiler::FindSnapshot(uid));
5887}
5888
5889
Steve Block791712a2010-08-27 10:21:07 +01005890const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
Ben Murdochb0fe1622011-05-05 13:52:32 +01005891 HeapSnapshot::Type type,
5892 ActivityControl* control) {
Steve Block44f0eee2011-05-26 01:26:41 +01005893 i::Isolate* isolate = i::Isolate::Current();
5894 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
Steve Block791712a2010-08-27 10:21:07 +01005895 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
5896 switch (type) {
5897 case HeapSnapshot::kFull:
5898 internal_type = i::HeapSnapshot::kFull;
5899 break;
Steve Block791712a2010-08-27 10:21:07 +01005900 default:
5901 UNREACHABLE();
5902 }
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005903 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb0fe1622011-05-05 13:52:32 +01005904 i::HeapProfiler::TakeSnapshot(
5905 *Utils::OpenHandle(*title), internal_type, control));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005906}
5907
Steve Block44f0eee2011-05-26 01:26:41 +01005908
5909void HeapProfiler::DeleteAllSnapshots() {
5910 i::Isolate* isolate = i::Isolate::Current();
5911 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5912 i::HeapProfiler::DeleteAllSnapshots();
5913}
5914
5915
5916void HeapProfiler::DefineWrapperClass(uint16_t class_id,
5917 WrapperInfoCallback callback) {
5918 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
5919 callback);
5920}
5921
Steve Block6ded16b2010-05-10 14:33:55 +01005922
5923
Ben Murdochb0fe1622011-05-05 13:52:32 +01005924v8::Testing::StressType internal::Testing::stress_type_ =
5925 v8::Testing::kStressTypeOpt;
5926
5927
5928void Testing::SetStressRunType(Testing::StressType type) {
5929 internal::Testing::set_stress_type(type);
5930}
5931
5932int Testing::GetStressRuns() {
5933 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
5934#ifdef DEBUG
5935 // In debug mode the code runs much slower so stressing will only make two
5936 // runs.
5937 return 2;
5938#else
5939 return 5;
5940#endif
5941}
5942
5943
5944static void SetFlagsFromString(const char* flags) {
5945 V8::SetFlagsFromString(flags, i::StrLength(flags));
5946}
5947
5948
5949void Testing::PrepareStressRun(int run) {
5950 static const char* kLazyOptimizations =
5951 "--prepare-always-opt --nolimit-inlining "
5952 "--noalways-opt --noopt-eagerly";
5953 static const char* kEagerOptimizations = "--opt-eagerly";
5954 static const char* kForcedOptimizations = "--always-opt";
5955
5956 // If deoptimization stressed turn on frequent deoptimization. If no value
5957 // is spefified through --deopt-every-n-times use a default default value.
5958 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
5959 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
5960 internal::FLAG_deopt_every_n_times == 0) {
5961 SetFlagsFromString(kDeoptEvery13Times);
5962 }
5963
5964#ifdef DEBUG
5965 // As stressing in debug mode only make two runs skip the deopt stressing
5966 // here.
5967 if (run == GetStressRuns() - 1) {
5968 SetFlagsFromString(kForcedOptimizations);
5969 } else {
5970 SetFlagsFromString(kEagerOptimizations);
5971 SetFlagsFromString(kLazyOptimizations);
5972 }
5973#else
5974 if (run == GetStressRuns() - 1) {
5975 SetFlagsFromString(kForcedOptimizations);
5976 } else if (run == GetStressRuns() - 2) {
5977 SetFlagsFromString(kEagerOptimizations);
5978 } else {
5979 SetFlagsFromString(kLazyOptimizations);
5980 }
5981#endif
5982}
5983
5984
Steve Block44f0eee2011-05-26 01:26:41 +01005985void Testing::DeoptimizeAll() {
5986 internal::Deoptimizer::DeoptimizeAll();
Steve Blocka7e24c12009-10-30 11:49:00 +00005987}
5988
5989
Steve Block44f0eee2011-05-26 01:26:41 +01005990namespace internal {
5991
5992
Steve Blocka7e24c12009-10-30 11:49:00 +00005993void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01005994 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00005995}
5996
5997
5998char* HandleScopeImplementer::ArchiveThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005999 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00006000 isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00006001 handle_scope_data_ = *current;
6002 memcpy(storage, this, sizeof(*this));
6003
6004 ResetAfterArchive();
6005 current->Initialize();
6006
6007 return storage + ArchiveSpacePerThread();
6008}
6009
6010
6011int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01006012 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00006013}
6014
6015
6016char* HandleScopeImplementer::RestoreThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006017 memcpy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00006018 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00006019 return storage + ArchiveSpacePerThread();
6020}
6021
6022
6023void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
6024 // Iterate over all handles in the blocks except for the last.
6025 for (int i = blocks()->length() - 2; i >= 0; --i) {
6026 Object** block = blocks()->at(i);
6027 v->VisitPointers(block, &block[kHandleBlockSize]);
6028 }
6029
6030 // Iterate over live handles in the last block (if any).
6031 if (!blocks()->is_empty()) {
6032 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
6033 }
6034
6035 if (!saved_contexts_.is_empty()) {
6036 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
6037 v->VisitPointers(start, start + saved_contexts_.length());
6038 }
6039}
6040
6041
6042void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
6043 v8::ImplementationUtilities::HandleScopeData* current =
Ben Murdoch257744e2011-11-30 15:57:28 +00006044 isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01006045 handle_scope_data_ = *current;
6046 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00006047}
6048
6049
6050char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01006051 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00006052 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01006053 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00006054 return storage + ArchiveSpacePerThread();
6055}
6056
6057} } // namespace v8::internal