blob: 0d5e4f0685797865dabbdbac9bc11f36818057b4 [file] [log] [blame]
Ben Murdochf87a2032010-10-22 12:50:53 +01001// Copyright 2010 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "api.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010031
Steve Blocka7e24c12009-10-30 11:49:00 +000032#include "arguments.h"
33#include "bootstrapper.h"
34#include "compiler.h"
35#include "debug.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010036#include "deoptimizer.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037#include "execution.h"
38#include "global-handles.h"
Kristian Monsen9dcf7e22010-06-28 14:14:28 +010039#include "heap-profiler.h"
Steve Block6ded16b2010-05-10 14:33:55 +010040#include "messages.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010041#include "parser.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000042#include "platform.h"
Steve Block6ded16b2010-05-10 14:33:55 +010043#include "profile-generator-inl.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010044#include "runtime-profiler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000045#include "serialize.h"
46#include "snapshot.h"
47#include "v8threads.h"
48#include "version.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010049#include "vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000050
Steve Block6ded16b2010-05-10 14:33:55 +010051#include "../include/v8-profiler.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010052#include "../include/v8-testing.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000053
Steve Block44f0eee2011-05-26 01:26:41 +010054#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000055
Steve Block44f0eee2011-05-26 01:26:41 +010056// TODO(isolates): avoid repeated TLS reads in function prologues.
Leon Clarkef7060e22010-06-03 12:02:55 +010057#ifdef ENABLE_VMSTATE_TRACKING
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#else
Steve Block44f0eee2011-05-26 01:26:41 +010064#define ENTER_V8(isolate) ((void) 0)
65#define LEAVE_V8(isolate) ((void) 0)
Steve Blocka7e24c12009-10-30 11:49:00 +000066#endif
67
68namespace v8 {
69
Steve Block44f0eee2011-05-26 01:26:41 +010070#define ON_BAILOUT(isolate, location, code) \
71 if (IsDeadCheck(isolate, location) || \
72 IsExecutionTerminatingCheck(isolate)) { \
Leon Clarkef7060e22010-06-03 12:02:55 +010073 code; \
74 UNREACHABLE(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000075 }
76
77
Steve Block44f0eee2011-05-26 01:26:41 +010078#define EXCEPTION_PREAMBLE(isolate) \
79 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
80 ASSERT(!(isolate)->external_caught_exception()); \
Steve Blocka7e24c12009-10-30 11:49:00 +000081 bool has_pending_exception = false
82
83
Steve Block44f0eee2011-05-26 01:26:41 +010084#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
Steve Blocka7e24c12009-10-30 11:49:00 +000085 do { \
Steve Block44f0eee2011-05-26 01:26:41 +010086 i::HandleScopeImplementer* handle_scope_implementer = \
87 (isolate)->handle_scope_implementer(); \
88 handle_scope_implementer->DecrementCallDepth(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000089 if (has_pending_exception) { \
Steve Block44f0eee2011-05-26 01:26:41 +010090 if (handle_scope_implementer->CallDepthIsZero() && \
91 (isolate)->is_out_of_memory()) { \
92 if (!handle_scope_implementer->ignore_out_of_memory()) \
Steve Blocka7e24c12009-10-30 11:49:00 +000093 i::V8::FatalProcessOutOfMemory(NULL); \
94 } \
Steve Block44f0eee2011-05-26 01:26:41 +010095 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
96 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
Steve Blocka7e24c12009-10-30 11:49:00 +000097 return value; \
98 } \
99 } while (false)
100
Steve Block44f0eee2011-05-26 01:26:41 +0100101// TODO(isolates): Add a parameter to this macro for an isolate.
Steve Blocka7e24c12009-10-30 11:49:00 +0000102
103#define API_ENTRY_CHECK(msg) \
104 do { \
105 if (v8::Locker::IsActive()) { \
Steve Block44f0eee2011-05-26 01:26:41 +0100106 ApiCheck(i::Isolate::Current()->thread_manager()-> \
107 IsLockedByCurrentThread(), \
Steve Blocka7e24c12009-10-30 11:49:00 +0000108 msg, \
109 "Entering the V8 API without proper locking in place"); \
110 } \
111 } while (false)
112
Ben Murdochb0fe1622011-05-05 13:52:32 +0100113
Steve Blocka7e24c12009-10-30 11:49:00 +0000114// --- E x c e p t i o n B e h a v i o r ---
115
116
Steve Blocka7e24c12009-10-30 11:49:00 +0000117static void DefaultFatalErrorHandler(const char* location,
118 const char* message) {
Steve Block1e0659c2011-05-24 12:43:12 +0100119#ifdef ENABLE_VMSTATE_TRACKING
Steve Block44f0eee2011-05-26 01:26:41 +0100120 i::VMState __state__(i::Isolate::Current(), i::OTHER);
Steve Block1e0659c2011-05-24 12:43:12 +0100121#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 API_Fatal(location, message);
123}
124
125
Steve Block44f0eee2011-05-26 01:26:41 +0100126static FatalErrorCallback GetFatalErrorHandler() {
127 i::Isolate* isolate = i::Isolate::Current();
128 if (isolate->exception_behavior() == NULL) {
129 isolate->set_exception_behavior(DefaultFatalErrorHandler);
Steve Blocka7e24c12009-10-30 11:49:00 +0000130 }
Steve Block44f0eee2011-05-26 01:26:41 +0100131 return isolate->exception_behavior();
Steve Blocka7e24c12009-10-30 11:49:00 +0000132}
133
134
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800135void i::FatalProcessOutOfMemory(const char* location) {
136 i::V8::FatalProcessOutOfMemory(location, false);
137}
138
Steve Blocka7e24c12009-10-30 11:49:00 +0000139
140// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
141// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100142void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Steve Blockd0582a62009-12-15 09:54:21 +0000143 i::HeapStats heap_stats;
144 int start_marker;
145 heap_stats.start_marker = &start_marker;
146 int new_space_size;
147 heap_stats.new_space_size = &new_space_size;
148 int new_space_capacity;
149 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100150 intptr_t old_pointer_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000151 heap_stats.old_pointer_space_size = &old_pointer_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100152 intptr_t old_pointer_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000153 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100154 intptr_t old_data_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000155 heap_stats.old_data_space_size = &old_data_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100156 intptr_t old_data_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000157 heap_stats.old_data_space_capacity = &old_data_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100158 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000159 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100160 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000161 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100162 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000163 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100164 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000165 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100166 intptr_t cell_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000167 heap_stats.cell_space_size = &cell_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100168 intptr_t cell_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000169 heap_stats.cell_space_capacity = &cell_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100170 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000171 heap_stats.lo_space_size = &lo_space_size;
172 int global_handle_count;
173 heap_stats.global_handle_count = &global_handle_count;
174 int weak_global_handle_count;
175 heap_stats.weak_global_handle_count = &weak_global_handle_count;
176 int pending_global_handle_count;
177 heap_stats.pending_global_handle_count = &pending_global_handle_count;
178 int near_death_global_handle_count;
179 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
180 int destroyed_global_handle_count;
181 heap_stats.destroyed_global_handle_count = &destroyed_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100182 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100183 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100184 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100185 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
186 int objects_per_type[LAST_TYPE + 1] = {0};
187 heap_stats.objects_per_type = objects_per_type;
188 int size_per_type[LAST_TYPE + 1] = {0};
189 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100190 int os_error;
191 heap_stats.os_error = &os_error;
Steve Blockd0582a62009-12-15 09:54:21 +0000192 int end_marker;
193 heap_stats.end_marker = &end_marker;
Steve Block44f0eee2011-05-26 01:26:41 +0100194 i::Isolate* isolate = i::Isolate::Current();
195 isolate->heap()->RecordStats(&heap_stats, take_snapshot);
Steve Blocka7e24c12009-10-30 11:49:00 +0000196 i::V8::SetFatalError();
197 FatalErrorCallback callback = GetFatalErrorHandler();
198 {
Steve Block44f0eee2011-05-26 01:26:41 +0100199 LEAVE_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000200 callback(location, "Allocation failed - process out of memory");
201 }
202 // If the callback returns, we stop execution.
203 UNREACHABLE();
204}
205
206
Steve Blocka7e24c12009-10-30 11:49:00 +0000207bool Utils::ReportApiFailure(const char* location, const char* message) {
208 FatalErrorCallback callback = GetFatalErrorHandler();
209 callback(location, message);
210 i::V8::SetFatalError();
211 return false;
212}
213
214
215bool V8::IsDead() {
216 return i::V8::IsDead();
217}
218
219
220static inline bool ApiCheck(bool condition,
221 const char* location,
222 const char* message) {
223 return condition ? true : Utils::ReportApiFailure(location, message);
224}
225
226
227static bool ReportV8Dead(const char* location) {
228 FatalErrorCallback callback = GetFatalErrorHandler();
229 callback(location, "V8 is no longer usable");
230 return true;
231}
232
233
234static bool ReportEmptyHandle(const char* location) {
235 FatalErrorCallback callback = GetFatalErrorHandler();
236 callback(location, "Reading from empty handle");
237 return true;
238}
239
240
241/**
242 * IsDeadCheck checks that the vm is usable. If, for instance, the vm has been
243 * out of memory at some point this check will fail. It should be called on
244 * entry to all methods that touch anything in the heap, except destructors
245 * which you sometimes can't avoid calling after the vm has crashed. Functions
246 * that call EnsureInitialized or ON_BAILOUT don't have to also call
247 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you
248 * can arrange to return if the VM is dead. This is needed to ensure that no VM
249 * heap allocations are attempted on a dead VM. EnsureInitialized has the
250 * advantage over ON_BAILOUT that it actually initializes the VM if this has not
251 * yet been done.
252 */
Steve Block44f0eee2011-05-26 01:26:41 +0100253static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
254 return !isolate->IsInitialized()
Steve Blocka7e24c12009-10-30 11:49:00 +0000255 && i::V8::IsDead() ? ReportV8Dead(location) : false;
256}
257
258
Steve Block44f0eee2011-05-26 01:26:41 +0100259static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
260 if (!isolate->IsInitialized()) return false;
261 if (isolate->has_scheduled_exception()) {
262 return isolate->scheduled_exception() ==
263 isolate->heap()->termination_exception();
264 }
265 return false;
266}
267
268
Steve Blocka7e24c12009-10-30 11:49:00 +0000269static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
270 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
271}
272
273
274static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
275 return (obj == 0) ? ReportEmptyHandle(location) : false;
276}
277
278// --- S t a t i c s ---
279
280
Steve Block44f0eee2011-05-26 01:26:41 +0100281static bool InitializeHelper() {
282 if (i::Snapshot::Initialize()) return true;
283 return i::V8::Initialize(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000284}
285
286
Steve Block44f0eee2011-05-26 01:26:41 +0100287static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
288 const char* location) {
289 if (IsDeadCheck(isolate, location)) return false;
290 if (isolate != NULL) {
291 if (isolate->IsInitialized()) return true;
292 }
293 return ApiCheck(InitializeHelper(), location, "Error initializing V8");
294}
295
296// Some initializing API functions are called early and may be
297// called on a thread different from static initializer thread.
298// If Isolate API is used, Isolate::Enter() will initialize TLS so
299// Isolate::Current() works. If it's a legacy case, then the thread
300// may not have TLS initialized yet. However, in initializing APIs it
301// may be too early to call EnsureInitialized() - some pre-init
302// parameters still have to be configured.
303static inline i::Isolate* EnterIsolateIfNeeded() {
304 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
305 if (isolate != NULL)
306 return isolate;
307
308 i::Isolate::EnterDefaultIsolate();
309 isolate = i::Isolate::Current();
310 return isolate;
311}
312
313
314void V8::SetFatalErrorHandler(FatalErrorCallback that) {
315 i::Isolate* isolate = EnterIsolateIfNeeded();
316 isolate->set_exception_behavior(that);
Steve Blocka7e24c12009-10-30 11:49:00 +0000317}
318
319
320#ifdef DEBUG
321void ImplementationUtilities::ZapHandleRange(i::Object** begin,
322 i::Object** end) {
323 i::HandleScope::ZapRange(begin, end);
324}
325#endif
326
327
Steve Blocka7e24c12009-10-30 11:49:00 +0000328void V8::SetFlagsFromString(const char* str, int length) {
329 i::FlagList::SetFlagsFromString(str, length);
330}
331
332
333void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
334 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
335}
336
337
338v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100339 i::Isolate* isolate = i::Isolate::Current();
340 if (IsDeadCheck(isolate, "v8::ThrowException()")) {
341 return v8::Handle<Value>();
342 }
343 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000344 // If we're passed an empty handle, we throw an undefined exception
345 // to deal more gracefully with out of memory situations.
346 if (value.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100347 isolate->ScheduleThrow(isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000348 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100349 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +0000350 }
351 return v8::Undefined();
352}
353
354
355RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
356
357
358RegisteredExtension::RegisteredExtension(Extension* extension)
359 : extension_(extension), state_(UNVISITED) { }
360
361
362void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100363 that->next_ = first_extension_;
364 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000365}
366
367
368void RegisterExtension(Extension* that) {
369 RegisteredExtension* extension = new RegisteredExtension(that);
370 RegisteredExtension::Register(extension);
371}
372
373
374Extension::Extension(const char* name,
375 const char* source,
376 int dep_count,
377 const char** deps)
378 : name_(name),
379 source_(source),
380 dep_count_(dep_count),
381 deps_(deps),
382 auto_enable_(false) { }
383
384
385v8::Handle<Primitive> Undefined() {
Steve Block44f0eee2011-05-26 01:26:41 +0100386 i::Isolate* isolate = i::Isolate::Current();
387 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
388 return v8::Handle<v8::Primitive>();
389 }
390 return v8::Handle<Primitive>(ToApi<Primitive>(
391 isolate->factory()->undefined_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000392}
393
394
395v8::Handle<Primitive> Null() {
Steve Block44f0eee2011-05-26 01:26:41 +0100396 i::Isolate* isolate = i::Isolate::Current();
397 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
398 return v8::Handle<v8::Primitive>();
399 }
400 return v8::Handle<Primitive>(
401 ToApi<Primitive>(isolate->factory()->null_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000402}
403
404
405v8::Handle<Boolean> True() {
Steve Block44f0eee2011-05-26 01:26:41 +0100406 i::Isolate* isolate = i::Isolate::Current();
407 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
408 return v8::Handle<Boolean>();
409 }
410 return v8::Handle<Boolean>(
411 ToApi<Boolean>(isolate->factory()->true_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000412}
413
414
415v8::Handle<Boolean> False() {
Steve Block44f0eee2011-05-26 01:26:41 +0100416 i::Isolate* isolate = i::Isolate::Current();
417 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
418 return v8::Handle<Boolean>();
419 }
420 return v8::Handle<Boolean>(
421 ToApi<Boolean>(isolate->factory()->false_value()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000422}
423
424
425ResourceConstraints::ResourceConstraints()
426 : max_young_space_size_(0),
427 max_old_space_size_(0),
Russell Brenner90bac252010-11-18 13:33:46 -0800428 max_executable_size_(0),
Steve Blocka7e24c12009-10-30 11:49:00 +0000429 stack_limit_(NULL) { }
430
431
432bool SetResourceConstraints(ResourceConstraints* constraints) {
Steve Block44f0eee2011-05-26 01:26:41 +0100433 i::Isolate* isolate = EnterIsolateIfNeeded();
434
Steve Block3ce2e202009-11-05 08:53:23 +0000435 int young_space_size = constraints->max_young_space_size();
Steve Blocka7e24c12009-10-30 11:49:00 +0000436 int old_gen_size = constraints->max_old_space_size();
Russell Brenner90bac252010-11-18 13:33:46 -0800437 int max_executable_size = constraints->max_executable_size();
438 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100439 // After initialization it's too late to change Heap constraints.
440 ASSERT(!isolate->IsInitialized());
441 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
442 old_gen_size,
443 max_executable_size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000444 if (!result) return false;
445 }
446 if (constraints->stack_limit() != NULL) {
447 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
Steve Block44f0eee2011-05-26 01:26:41 +0100448 isolate->stack_guard()->SetStackLimit(limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000449 }
450 return true;
451}
452
453
454i::Object** V8::GlobalizeReference(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100455 i::Isolate* isolate = i::Isolate::Current();
456 if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
457 LOG_API(isolate, "Persistent::New");
Steve Blocka7e24c12009-10-30 11:49:00 +0000458 i::Handle<i::Object> result =
Steve Block44f0eee2011-05-26 01:26:41 +0100459 isolate->global_handles()->Create(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000460 return result.location();
461}
462
463
464void V8::MakeWeak(i::Object** object, void* parameters,
465 WeakReferenceCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +0100466 i::Isolate* isolate = i::Isolate::Current();
467 LOG_API(isolate, "MakeWeak");
468 isolate->global_handles()->MakeWeak(object, parameters,
469 callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000470}
471
472
473void V8::ClearWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100474 i::Isolate* isolate = i::Isolate::Current();
475 LOG_API(isolate, "ClearWeak");
476 isolate->global_handles()->ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000477}
478
479
480bool V8::IsGlobalNearDeath(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100481 i::Isolate* isolate = i::Isolate::Current();
482 LOG_API(isolate, "IsGlobalNearDeath");
483 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000484 return i::GlobalHandles::IsNearDeath(obj);
485}
486
487
488bool V8::IsGlobalWeak(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100489 i::Isolate* isolate = i::Isolate::Current();
490 LOG_API(isolate, "IsGlobalWeak");
491 if (!isolate->IsInitialized()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000492 return i::GlobalHandles::IsWeak(obj);
493}
494
495
496void V8::DisposeGlobal(i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100497 i::Isolate* isolate = i::Isolate::Current();
498 LOG_API(isolate, "DisposeGlobal");
499 if (!isolate->IsInitialized()) return;
500 isolate->global_handles()->Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000501}
502
503// --- H a n d l e s ---
504
505
Steve Block44f0eee2011-05-26 01:26:41 +0100506HandleScope::HandleScope() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000507 API_ENTRY_CHECK("HandleScope::HandleScope");
Steve Block44f0eee2011-05-26 01:26:41 +0100508 i::Isolate* isolate = i::Isolate::Current();
509 v8::ImplementationUtilities::HandleScopeData* current =
510 isolate->handle_scope_data();
511 isolate_ = isolate;
512 prev_next_ = current->next;
513 prev_limit_ = current->limit;
514 is_closed_ = false;
515 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000516}
517
518
519HandleScope::~HandleScope() {
520 if (!is_closed_) {
John Reck59135872010-11-02 12:39:01 -0700521 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000522 }
523}
524
525
John Reck59135872010-11-02 12:39:01 -0700526void HandleScope::Leave() {
Steve Block44f0eee2011-05-26 01:26:41 +0100527 ASSERT(isolate_ == i::Isolate::Current());
528 v8::ImplementationUtilities::HandleScopeData* current =
529 isolate_->handle_scope_data();
530 current->level--;
531 ASSERT(current->level >= 0);
532 current->next = prev_next_;
533 if (current->limit != prev_limit_) {
534 current->limit = prev_limit_;
535 i::HandleScope::DeleteExtensions(isolate_);
John Reck59135872010-11-02 12:39:01 -0700536 }
537
538#ifdef DEBUG
539 i::HandleScope::ZapRange(prev_next_, prev_limit_);
540#endif
541}
542
543
Steve Blocka7e24c12009-10-30 11:49:00 +0000544int HandleScope::NumberOfHandles() {
Steve Block44f0eee2011-05-26 01:26:41 +0100545 EnsureInitializedForIsolate(
546 i::Isolate::Current(), "HandleScope::NumberOfHandles");
Steve Blocka7e24c12009-10-30 11:49:00 +0000547 return i::HandleScope::NumberOfHandles();
548}
549
550
Steve Block44f0eee2011-05-26 01:26:41 +0100551i::Object** HandleScope::CreateHandle(i::Object* value) {
552 return i::HandleScope::CreateHandle(value, i::Isolate::Current());
553}
554
555
556i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
557 ASSERT(value->IsHeapObject());
558 return reinterpret_cast<i::Object**>(
559 i::HandleScope::CreateHandle(value, value->GetIsolate()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000560}
561
562
563void Context::Enter() {
Steve Block44f0eee2011-05-26 01:26:41 +0100564 // TODO(isolates): Context should have a pointer to isolate.
565 i::Isolate* isolate = i::Isolate::Current();
566 if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
567 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000568
Steve Block44f0eee2011-05-26 01:26:41 +0100569 i::Handle<i::Context> env = Utils::OpenHandle(this);
570 isolate->handle_scope_implementer()->EnterContext(env);
571
572 isolate->handle_scope_implementer()->SaveContext(isolate->context());
573 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000574}
575
576
577void Context::Exit() {
Steve Block44f0eee2011-05-26 01:26:41 +0100578 // TODO(isolates): Context should have a pointer to isolate.
579 i::Isolate* isolate = i::Isolate::Current();
580 if (!isolate->IsInitialized()) return;
581
582 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000583 "v8::Context::Exit()",
584 "Cannot exit non-entered context")) {
585 return;
586 }
587
588 // Content of 'last_context' could be NULL.
Steve Block44f0eee2011-05-26 01:26:41 +0100589 i::Context* last_context =
590 isolate->handle_scope_implementer()->RestoreContext();
591 isolate->set_context(last_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000592}
593
594
Steve Blockd0582a62009-12-15 09:54:21 +0000595void Context::SetData(v8::Handle<String> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100596 // TODO(isolates): Context should have a pointer to isolate.
597 i::Isolate* isolate = i::Isolate::Current();
598 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
599 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000600 {
Steve Block44f0eee2011-05-26 01:26:41 +0100601 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000602 i::Handle<i::Context> env = Utils::OpenHandle(this);
603 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
604 ASSERT(env->IsGlobalContext());
605 if (env->IsGlobalContext()) {
606 env->set_data(*raw_data);
607 }
608 }
609}
610
611
612v8::Local<v8::Value> Context::GetData() {
Steve Block44f0eee2011-05-26 01:26:41 +0100613 // TODO(isolates): Context should have a pointer to isolate.
614 i::Isolate* isolate = i::Isolate::Current();
615 if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
616 return v8::Local<Value>();
617 }
618 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000619 i::Object* raw_result = NULL;
620 {
Steve Block44f0eee2011-05-26 01:26:41 +0100621 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000622 i::Handle<i::Context> env = Utils::OpenHandle(this);
623 ASSERT(env->IsGlobalContext());
624 if (env->IsGlobalContext()) {
625 raw_result = env->data();
626 } else {
627 return Local<Value>();
628 }
629 }
630 i::Handle<i::Object> result(raw_result);
631 return Utils::ToLocal(result);
632}
633
634
635i::Object** v8::HandleScope::RawClose(i::Object** value) {
636 if (!ApiCheck(!is_closed_,
637 "v8::HandleScope::Close()",
638 "Local scope has already been closed")) {
639 return 0;
640 }
Steve Block44f0eee2011-05-26 01:26:41 +0100641 LOG_API(isolate_, "CloseHandleScope");
Steve Blocka7e24c12009-10-30 11:49:00 +0000642
643 // Read the result before popping the handle block.
Steve Block6ded16b2010-05-10 14:33:55 +0100644 i::Object* result = NULL;
645 if (value != NULL) {
646 result = *value;
647 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000648 is_closed_ = true;
John Reck59135872010-11-02 12:39:01 -0700649 Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +0000650
Steve Block6ded16b2010-05-10 14:33:55 +0100651 if (value == NULL) {
652 return NULL;
653 }
654
Steve Blocka7e24c12009-10-30 11:49:00 +0000655 // Allocate a new handle on the previous handle block.
656 i::Handle<i::Object> handle(result);
657 return handle.location();
658}
659
660
661// --- N e a n d e r ---
662
663
664// A constructor cannot easily return an error value, therefore it is necessary
665// to check for a dead VM with ON_BAILOUT before constructing any Neander
666// objects. To remind you about this there is no HandleScope in the
667// NeanderObject constructor. When you add one to the site calling the
668// constructor you should check that you ensured the VM was not dead first.
669NeanderObject::NeanderObject(int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100670 i::Isolate* isolate = i::Isolate::Current();
671 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
672 ENTER_V8(isolate);
673 value_ = isolate->factory()->NewNeanderObject();
674 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000675 value_->set_elements(*elements);
676}
677
678
679int NeanderObject::size() {
680 return i::FixedArray::cast(value_->elements())->length();
681}
682
683
684NeanderArray::NeanderArray() : obj_(2) {
685 obj_.set(0, i::Smi::FromInt(0));
686}
687
688
689int NeanderArray::length() {
690 return i::Smi::cast(obj_.get(0))->value();
691}
692
693
694i::Object* NeanderArray::get(int offset) {
695 ASSERT(0 <= offset);
696 ASSERT(offset < length());
697 return obj_.get(offset + 1);
698}
699
700
701// This method cannot easily return an error value, therefore it is necessary
702// to check for a dead VM with ON_BAILOUT before calling it. To remind you
703// about this there is no HandleScope in this method. When you add one to the
704// site calling this method you should check that you ensured the VM was not
705// dead first.
706void NeanderArray::add(i::Handle<i::Object> value) {
707 int length = this->length();
708 int size = obj_.size();
709 if (length == size - 1) {
Steve Block44f0eee2011-05-26 01:26:41 +0100710 i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000711 for (int i = 0; i < length; i++)
712 new_elms->set(i + 1, get(i));
713 obj_.value()->set_elements(*new_elms);
714 }
715 obj_.set(length + 1, *value);
716 obj_.set(0, i::Smi::FromInt(length + 1));
717}
718
719
720void NeanderArray::set(int index, i::Object* value) {
721 if (index < 0 || index >= this->length()) return;
722 obj_.set(index + 1, value);
723}
724
725
726// --- T e m p l a t e ---
727
728
729static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
730 that->set_tag(i::Smi::FromInt(type));
731}
732
733
734void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
735 v8::PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +0100736 i::Isolate* isolate = i::Isolate::Current();
737 if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
738 ENTER_V8(isolate);
739 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
741 if (list->IsUndefined()) {
742 list = NeanderArray().value();
743 Utils::OpenHandle(this)->set_property_list(*list);
744 }
745 NeanderArray array(list);
746 array.add(Utils::OpenHandle(*name));
747 array.add(Utils::OpenHandle(*value));
748 array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
749}
750
751
752// --- F u n c t i o n T e m p l a t e ---
753static void InitializeFunctionTemplate(
754 i::Handle<i::FunctionTemplateInfo> info) {
755 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
756 info->set_flag(0);
757}
758
759
760Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +0100761 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
762 if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000763 return Local<ObjectTemplate>();
764 }
Steve Block44f0eee2011-05-26 01:26:41 +0100765 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000766 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
767 if (result->IsUndefined()) {
768 result = Utils::OpenHandle(*ObjectTemplate::New());
769 Utils::OpenHandle(this)->set_prototype_template(*result);
770 }
771 return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
772}
773
774
775void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100776 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
777 if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
778 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000779 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
780}
781
782
Steve Blocka7e24c12009-10-30 11:49:00 +0000783Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
784 v8::Handle<Value> data, v8::Handle<Signature> signature) {
Steve Block44f0eee2011-05-26 01:26:41 +0100785 i::Isolate* isolate = i::Isolate::Current();
786 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
787 LOG_API(isolate, "FunctionTemplate::New");
788 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000789 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100790 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000791 i::Handle<i::FunctionTemplateInfo> obj =
792 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
793 InitializeFunctionTemplate(obj);
Steve Block44f0eee2011-05-26 01:26:41 +0100794 int next_serial_number = isolate->next_serial_number();
795 isolate->set_next_serial_number(next_serial_number + 1);
796 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +0000797 if (callback != 0) {
798 if (data.IsEmpty()) data = v8::Undefined();
799 Utils::ToLocal(obj)->SetCallHandler(callback, data);
800 }
801 obj->set_undetectable(false);
802 obj->set_needs_access_check(false);
803
804 if (!signature.IsEmpty())
805 obj->set_signature(*Utils::OpenHandle(*signature));
806 return Utils::ToLocal(obj);
807}
808
809
810Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
811 int argc, Handle<FunctionTemplate> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100812 i::Isolate* isolate = i::Isolate::Current();
813 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
814 LOG_API(isolate, "Signature::New");
815 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000816 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100817 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000818 i::Handle<i::SignatureInfo> obj =
819 i::Handle<i::SignatureInfo>::cast(struct_obj);
820 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
821 if (argc > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100822 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000823 for (int i = 0; i < argc; i++) {
824 if (!argv[i].IsEmpty())
825 args->set(i, *Utils::OpenHandle(*argv[i]));
826 }
827 obj->set_args(*args);
828 }
829 return Utils::ToLocal(obj);
830}
831
832
833Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
834 Handle<FunctionTemplate> types[1] = { type };
835 return TypeSwitch::New(1, types);
836}
837
838
839Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100840 i::Isolate* isolate = i::Isolate::Current();
841 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
842 LOG_API(isolate, "TypeSwitch::New");
843 ENTER_V8(isolate);
844 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000845 for (int i = 0; i < argc; i++)
846 vector->set(i, *Utils::OpenHandle(*types[i]));
847 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100848 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000849 i::Handle<i::TypeSwitchInfo> obj =
850 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
851 obj->set_types(*vector);
852 return Utils::ToLocal(obj);
853}
854
855
856int TypeSwitch::match(v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100857 i::Isolate* isolate = i::Isolate::Current();
858 LOG_API(isolate, "TypeSwitch::match");
Steve Blocka7e24c12009-10-30 11:49:00 +0000859 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
860 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
861 i::FixedArray* types = i::FixedArray::cast(info->types());
862 for (int i = 0; i < types->length(); i++) {
863 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
864 return i + 1;
865 }
866 return 0;
867}
868
869
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100870#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
871 i::Handle<i::Object> proxy = FromCData(cdata); \
872 (obj)->setter(*proxy); \
873 } while (false)
874
875
Steve Blocka7e24c12009-10-30 11:49:00 +0000876void FunctionTemplate::SetCallHandler(InvocationCallback callback,
877 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100878 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
879 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
880 ENTER_V8(isolate);
881 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000882 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100883 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000884 i::Handle<i::CallHandlerInfo> obj =
885 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100886 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000887 if (data.IsEmpty()) data = v8::Undefined();
888 obj->set_data(*Utils::OpenHandle(*data));
889 Utils::OpenHandle(this)->set_call_code(*obj);
890}
891
892
Leon Clarkef7060e22010-06-03 12:02:55 +0100893static i::Handle<i::AccessorInfo> MakeAccessorInfo(
894 v8::Handle<String> name,
895 AccessorGetter getter,
896 AccessorSetter setter,
897 v8::Handle<Value> data,
898 v8::AccessControl settings,
899 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +0100900 i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
Leon Clarkef7060e22010-06-03 12:02:55 +0100901 ASSERT(getter != NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100902 SET_FIELD_WRAPPED(obj, set_getter, getter);
903 SET_FIELD_WRAPPED(obj, set_setter, setter);
Leon Clarkef7060e22010-06-03 12:02:55 +0100904 if (data.IsEmpty()) data = v8::Undefined();
905 obj->set_data(*Utils::OpenHandle(*data));
906 obj->set_name(*Utils::OpenHandle(*name));
907 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
908 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
909 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
910 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
911 return obj;
912}
913
914
Steve Blocka7e24c12009-10-30 11:49:00 +0000915void FunctionTemplate::AddInstancePropertyAccessor(
916 v8::Handle<String> name,
917 AccessorGetter getter,
918 AccessorSetter setter,
919 v8::Handle<Value> data,
920 v8::AccessControl settings,
921 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +0100922 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
923 if (IsDeadCheck(isolate,
924 "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000925 return;
926 }
Steve Block44f0eee2011-05-26 01:26:41 +0100927 ENTER_V8(isolate);
928 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000929
Leon Clarkef7060e22010-06-03 12:02:55 +0100930 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
931 getter, setter, data,
932 settings, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000933 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
934 if (list->IsUndefined()) {
935 list = NeanderArray().value();
936 Utils::OpenHandle(this)->set_property_accessors(*list);
937 }
938 NeanderArray array(list);
939 array.add(obj);
940}
941
942
943Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +0100944 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
945 if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
Steve Blocka7e24c12009-10-30 11:49:00 +0000946 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
947 return Local<ObjectTemplate>();
Steve Block44f0eee2011-05-26 01:26:41 +0100948 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000949 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
950 Local<ObjectTemplate> templ =
951 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
952 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
953 }
954 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
955 Utils::OpenHandle(this)->instance_template()));
956 return Utils::ToLocal(result);
957}
958
959
960void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +0100961 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
962 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
963 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000964 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
965}
966
967
968void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100969 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
970 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
971 return;
972 }
973 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000974 Utils::OpenHandle(this)->set_hidden_prototype(value);
975}
976
977
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100978void FunctionTemplate::SetNamedInstancePropertyHandler(
Steve Blocka7e24c12009-10-30 11:49:00 +0000979 NamedPropertyGetter getter,
980 NamedPropertySetter setter,
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100981 NamedPropertyQuery query,
Steve Blocka7e24c12009-10-30 11:49:00 +0000982 NamedPropertyDeleter remover,
983 NamedPropertyEnumerator enumerator,
984 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100985 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
986 if (IsDeadCheck(isolate,
987 "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000988 return;
989 }
Steve Block44f0eee2011-05-26 01:26:41 +0100990 ENTER_V8(isolate);
991 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000992 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100993 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000994 i::Handle<i::InterceptorInfo> obj =
995 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100996
997 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
998 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
999 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1000 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1001 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1002
Steve Blocka7e24c12009-10-30 11:49:00 +00001003 if (data.IsEmpty()) data = v8::Undefined();
1004 obj->set_data(*Utils::OpenHandle(*data));
1005 Utils::OpenHandle(this)->set_named_property_handler(*obj);
1006}
1007
1008
1009void FunctionTemplate::SetIndexedInstancePropertyHandler(
1010 IndexedPropertyGetter getter,
1011 IndexedPropertySetter setter,
1012 IndexedPropertyQuery query,
1013 IndexedPropertyDeleter remover,
1014 IndexedPropertyEnumerator enumerator,
1015 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001016 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1017 if (IsDeadCheck(isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00001018 "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
1019 return;
1020 }
Steve Block44f0eee2011-05-26 01:26:41 +01001021 ENTER_V8(isolate);
1022 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001023 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001024 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001025 i::Handle<i::InterceptorInfo> obj =
1026 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001027
1028 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1029 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1030 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1031 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1032 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1033
Steve Blocka7e24c12009-10-30 11:49:00 +00001034 if (data.IsEmpty()) data = v8::Undefined();
1035 obj->set_data(*Utils::OpenHandle(*data));
1036 Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
1037}
1038
1039
1040void FunctionTemplate::SetInstanceCallAsFunctionHandler(
1041 InvocationCallback callback,
1042 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001043 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1044 if (IsDeadCheck(isolate,
1045 "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001046 return;
1047 }
Steve Block44f0eee2011-05-26 01:26:41 +01001048 ENTER_V8(isolate);
1049 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001050 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001051 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001052 i::Handle<i::CallHandlerInfo> obj =
1053 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001054 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001055 if (data.IsEmpty()) data = v8::Undefined();
1056 obj->set_data(*Utils::OpenHandle(*data));
1057 Utils::OpenHandle(this)->set_instance_call_handler(*obj);
1058}
1059
1060
1061// --- O b j e c t T e m p l a t e ---
1062
1063
1064Local<ObjectTemplate> ObjectTemplate::New() {
1065 return New(Local<FunctionTemplate>());
1066}
1067
1068
1069Local<ObjectTemplate> ObjectTemplate::New(
1070 v8::Handle<FunctionTemplate> constructor) {
Steve Block44f0eee2011-05-26 01:26:41 +01001071 i::Isolate* isolate = i::Isolate::Current();
1072 if (IsDeadCheck(isolate, "v8::ObjectTemplate::New()")) {
1073 return Local<ObjectTemplate>();
1074 }
1075 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1076 LOG_API(isolate, "ObjectTemplate::New");
1077 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001078 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001079 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001080 i::Handle<i::ObjectTemplateInfo> obj =
1081 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1082 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1083 if (!constructor.IsEmpty())
1084 obj->set_constructor(*Utils::OpenHandle(*constructor));
1085 obj->set_internal_field_count(i::Smi::FromInt(0));
1086 return Utils::ToLocal(obj);
1087}
1088
1089
1090// Ensure that the object template has a constructor. If no
1091// constructor is available we create one.
1092static void EnsureConstructor(ObjectTemplate* object_template) {
1093 if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
1094 Local<FunctionTemplate> templ = FunctionTemplate::New();
1095 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1096 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1097 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1098 }
1099}
1100
1101
1102void ObjectTemplate::SetAccessor(v8::Handle<String> name,
1103 AccessorGetter getter,
1104 AccessorSetter setter,
1105 v8::Handle<Value> data,
1106 AccessControl settings,
1107 PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +01001108 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1109 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
1110 ENTER_V8(isolate);
1111 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001112 EnsureConstructor(this);
1113 i::FunctionTemplateInfo* constructor =
1114 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1115 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1116 Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
1117 getter,
1118 setter,
1119 data,
1120 settings,
1121 attribute);
1122}
1123
1124
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001125void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
1126 NamedPropertySetter setter,
1127 NamedPropertyQuery query,
1128 NamedPropertyDeleter remover,
1129 NamedPropertyEnumerator enumerator,
1130 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001131 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1132 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
1133 return;
1134 }
1135 ENTER_V8(isolate);
1136 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001137 EnsureConstructor(this);
1138 i::FunctionTemplateInfo* constructor =
1139 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1140 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001141 Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
1142 setter,
1143 query,
1144 remover,
1145 enumerator,
1146 data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001147}
1148
1149
1150void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001151 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1152 if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
1153 ENTER_V8(isolate);
1154 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001155 EnsureConstructor(this);
1156 i::FunctionTemplateInfo* constructor =
1157 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1158 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1159 cons->set_undetectable(true);
1160}
1161
1162
1163void ObjectTemplate::SetAccessCheckCallbacks(
1164 NamedSecurityCallback named_callback,
1165 IndexedSecurityCallback indexed_callback,
1166 Handle<Value> data,
1167 bool turned_on_by_default) {
Steve Block44f0eee2011-05-26 01:26:41 +01001168 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1169 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
1170 return;
1171 }
1172 ENTER_V8(isolate);
1173 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001174 EnsureConstructor(this);
1175
1176 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001177 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001178 i::Handle<i::AccessCheckInfo> info =
1179 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001180
1181 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1182 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1183
Steve Blocka7e24c12009-10-30 11:49:00 +00001184 if (data.IsEmpty()) data = v8::Undefined();
1185 info->set_data(*Utils::OpenHandle(*data));
1186
1187 i::FunctionTemplateInfo* constructor =
1188 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1189 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1190 cons->set_access_check_info(*info);
1191 cons->set_needs_access_check(turned_on_by_default);
1192}
1193
1194
1195void ObjectTemplate::SetIndexedPropertyHandler(
1196 IndexedPropertyGetter getter,
1197 IndexedPropertySetter setter,
1198 IndexedPropertyQuery query,
1199 IndexedPropertyDeleter remover,
1200 IndexedPropertyEnumerator enumerator,
1201 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001202 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1203 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
1204 return;
1205 }
1206 ENTER_V8(isolate);
1207 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001208 EnsureConstructor(this);
1209 i::FunctionTemplateInfo* constructor =
1210 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1211 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1212 Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
1213 setter,
1214 query,
1215 remover,
1216 enumerator,
1217 data);
1218}
1219
1220
1221void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
1222 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001223 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1224 if (IsDeadCheck(isolate,
1225 "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
1226 return;
1227 }
1228 ENTER_V8(isolate);
1229 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001230 EnsureConstructor(this);
1231 i::FunctionTemplateInfo* constructor =
1232 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1233 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1234 Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
1235}
1236
1237
1238int ObjectTemplate::InternalFieldCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01001239 if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
1240 "v8::ObjectTemplate::InternalFieldCount()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001241 return 0;
1242 }
1243 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1244}
1245
1246
1247void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001248 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1249 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
1250 return;
1251 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001252 if (!ApiCheck(i::Smi::IsValid(value),
1253 "v8::ObjectTemplate::SetInternalFieldCount()",
1254 "Invalid internal field count")) {
1255 return;
1256 }
Steve Block44f0eee2011-05-26 01:26:41 +01001257 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001258 if (value > 0) {
1259 // The internal field count is set by the constructor function's
1260 // construct code, so we ensure that there is a constructor
1261 // function to do the setting.
1262 EnsureConstructor(this);
1263 }
1264 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1265}
1266
1267
1268// --- S c r i p t D a t a ---
1269
1270
1271ScriptData* ScriptData::PreCompile(const char* input, int length) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001272 i::Utf8ToUC16CharacterStream stream(
1273 reinterpret_cast<const unsigned char*>(input), length);
1274 return i::ParserApi::PreParse(&stream, NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00001275}
1276
1277
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001278ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1279 i::Handle<i::String> str = Utils::OpenHandle(*source);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001280 if (str->IsExternalTwoByteString()) {
1281 i::ExternalTwoByteStringUC16CharacterStream stream(
1282 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
1283 return i::ParserApi::PreParse(&stream, NULL);
1284 } else {
1285 i::GenericStringUC16CharacterStream stream(str, 0, str->length());
1286 return i::ParserApi::PreParse(&stream, NULL);
1287 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001288}
1289
1290
Leon Clarkef7060e22010-06-03 12:02:55 +01001291ScriptData* ScriptData::New(const char* data, int length) {
1292 // Return an empty ScriptData if the length is obviously invalid.
1293 if (length % sizeof(unsigned) != 0) {
Iain Merrick9ac36c92010-09-13 15:29:50 +01001294 return new i::ScriptDataImpl();
Leon Clarkef7060e22010-06-03 12:02:55 +01001295 }
1296
1297 // Copy the data to ensure it is properly aligned.
1298 int deserialized_data_length = length / sizeof(unsigned);
Iain Merrick9ac36c92010-09-13 15:29:50 +01001299 // If aligned, don't create a copy of the data.
1300 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1301 return new i::ScriptDataImpl(data, length);
1302 }
1303 // Copy the data to align it.
Leon Clarkef7060e22010-06-03 12:02:55 +01001304 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
Iain Merrick9ac36c92010-09-13 15:29:50 +01001305 i::MemCopy(deserialized_data, data, length);
Leon Clarkef7060e22010-06-03 12:02:55 +01001306
1307 return new i::ScriptDataImpl(
1308 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
Steve Blocka7e24c12009-10-30 11:49:00 +00001309}
1310
1311
1312// --- S c r i p t ---
1313
1314
1315Local<Script> Script::New(v8::Handle<String> source,
1316 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001317 v8::ScriptData* pre_data,
1318 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001319 i::Isolate* isolate = i::Isolate::Current();
1320 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1321 LOG_API(isolate, "Script::New");
1322 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001323 i::Handle<i::String> str = Utils::OpenHandle(*source);
1324 i::Handle<i::Object> name_obj;
1325 int line_offset = 0;
1326 int column_offset = 0;
1327 if (origin != NULL) {
1328 if (!origin->ResourceName().IsEmpty()) {
1329 name_obj = Utils::OpenHandle(*origin->ResourceName());
1330 }
1331 if (!origin->ResourceLineOffset().IsEmpty()) {
1332 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1333 }
1334 if (!origin->ResourceColumnOffset().IsEmpty()) {
1335 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
1336 }
1337 }
Steve Block44f0eee2011-05-26 01:26:41 +01001338 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001339 i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001340 // We assert that the pre-data is sane, even though we can actually
1341 // handle it if it turns out not to be in release mode.
Andrei Popescu402d9372010-02-26 13:31:12 +00001342 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
Steve Blocka7e24c12009-10-30 11:49:00 +00001343 // If the pre-data isn't sane we simply ignore it
Andrei Popescu402d9372010-02-26 13:31:12 +00001344 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1345 pre_data_impl = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001346 }
Steve Block6ded16b2010-05-10 14:33:55 +01001347 i::Handle<i::SharedFunctionInfo> result =
Andrei Popescu31002712010-02-23 13:46:05 +00001348 i::Compiler::Compile(str,
1349 name_obj,
1350 line_offset,
1351 column_offset,
1352 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001353 pre_data_impl,
1354 Utils::OpenHandle(*script_data),
Andrei Popescu31002712010-02-23 13:46:05 +00001355 i::NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001356 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01001357 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
Steve Block6ded16b2010-05-10 14:33:55 +01001358 return Local<Script>(ToApi<Script>(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00001359}
1360
1361
1362Local<Script> Script::New(v8::Handle<String> source,
1363 v8::Handle<Value> file_name) {
1364 ScriptOrigin origin(file_name);
1365 return New(source, &origin);
1366}
1367
1368
1369Local<Script> Script::Compile(v8::Handle<String> source,
1370 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001371 v8::ScriptData* pre_data,
1372 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001373 i::Isolate* isolate = i::Isolate::Current();
1374 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1375 LOG_API(isolate, "Script::Compile");
1376 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001377 Local<Script> generic = New(source, origin, pre_data, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001378 if (generic.IsEmpty())
1379 return generic;
Steve Block6ded16b2010-05-10 14:33:55 +01001380 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1381 i::Handle<i::SharedFunctionInfo> function =
1382 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
Steve Blocka7e24c12009-10-30 11:49:00 +00001383 i::Handle<i::JSFunction> result =
Steve Block44f0eee2011-05-26 01:26:41 +01001384 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1385 function,
1386 isolate->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001387 return Local<Script>(ToApi<Script>(result));
1388}
1389
1390
1391Local<Script> Script::Compile(v8::Handle<String> source,
Andrei Popescu402d9372010-02-26 13:31:12 +00001392 v8::Handle<Value> file_name,
1393 v8::Handle<String> script_data) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001394 ScriptOrigin origin(file_name);
Andrei Popescu402d9372010-02-26 13:31:12 +00001395 return Compile(source, &origin, 0, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001396}
1397
1398
1399Local<Value> Script::Run() {
Steve Block44f0eee2011-05-26 01:26:41 +01001400 i::Isolate* isolate = i::Isolate::Current();
1401 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1402 LOG_API(isolate, "Script::Run");
1403 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001404 i::Object* raw_result = NULL;
1405 {
Steve Block44f0eee2011-05-26 01:26:41 +01001406 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001407 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1408 i::Handle<i::JSFunction> fun;
1409 if (obj->IsSharedFunctionInfo()) {
1410 i::Handle<i::SharedFunctionInfo>
Steve Block44f0eee2011-05-26 01:26:41 +01001411 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
1412 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
1413 function_info, isolate->global_context());
Steve Block6ded16b2010-05-10 14:33:55 +01001414 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001415 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001416 }
Steve Block44f0eee2011-05-26 01:26:41 +01001417 EXCEPTION_PREAMBLE(isolate);
1418 i::Handle<i::Object> receiver(
1419 isolate->context()->global_proxy(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001420 i::Handle<i::Object> result =
1421 i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001422 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001423 raw_result = *result;
1424 }
Steve Block44f0eee2011-05-26 01:26:41 +01001425 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001426 return Utils::ToLocal(result);
1427}
1428
1429
Steve Block6ded16b2010-05-10 14:33:55 +01001430static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1431 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1432 i::Handle<i::SharedFunctionInfo> result;
1433 if (obj->IsSharedFunctionInfo()) {
1434 result =
1435 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1436 } else {
1437 result =
1438 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1439 }
1440 return result;
1441}
1442
1443
Steve Blocka7e24c12009-10-30 11:49:00 +00001444Local<Value> Script::Id() {
Steve Block44f0eee2011-05-26 01:26:41 +01001445 i::Isolate* isolate = i::Isolate::Current();
1446 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1447 LOG_API(isolate, "Script::Id");
Steve Blocka7e24c12009-10-30 11:49:00 +00001448 i::Object* raw_id = NULL;
1449 {
Steve Block44f0eee2011-05-26 01:26:41 +01001450 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001451 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1452 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001453 i::Handle<i::Object> id(script->id());
1454 raw_id = *id;
1455 }
1456 i::Handle<i::Object> id(raw_id);
1457 return Utils::ToLocal(id);
1458}
1459
1460
Steve Blockd0582a62009-12-15 09:54:21 +00001461void Script::SetData(v8::Handle<String> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001462 i::Isolate* isolate = i::Isolate::Current();
1463 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1464 LOG_API(isolate, "Script::SetData");
Steve Blocka7e24c12009-10-30 11:49:00 +00001465 {
Steve Block44f0eee2011-05-26 01:26:41 +01001466 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001467 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001468 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
Steve Block6ded16b2010-05-10 14:33:55 +01001469 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001470 script->set_data(*raw_data);
1471 }
1472}
1473
1474
1475// --- E x c e p t i o n s ---
1476
1477
1478v8::TryCatch::TryCatch()
Steve Block44f0eee2011-05-26 01:26:41 +01001479 : next_(i::Isolate::Current()->try_catch_handler_address()),
1480 exception_(HEAP->the_hole_value()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001481 message_(i::Smi::FromInt(0)),
1482 is_verbose_(false),
1483 can_continue_(true),
1484 capture_message_(true),
Steve Blockd0582a62009-12-15 09:54:21 +00001485 rethrow_(false) {
Steve Block44f0eee2011-05-26 01:26:41 +01001486 i::Isolate::Current()->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001487}
1488
1489
1490v8::TryCatch::~TryCatch() {
Steve Block44f0eee2011-05-26 01:26:41 +01001491 i::Isolate* isolate = i::Isolate::Current();
Steve Blockd0582a62009-12-15 09:54:21 +00001492 if (rethrow_) {
1493 v8::HandleScope scope;
1494 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
Steve Block44f0eee2011-05-26 01:26:41 +01001495 isolate->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001496 v8::ThrowException(exc);
1497 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001498 isolate->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001499 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001500}
1501
1502
1503bool v8::TryCatch::HasCaught() const {
1504 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1505}
1506
1507
1508bool v8::TryCatch::CanContinue() const {
1509 return can_continue_;
1510}
1511
1512
Steve Blockd0582a62009-12-15 09:54:21 +00001513v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1514 if (!HasCaught()) return v8::Local<v8::Value>();
1515 rethrow_ = true;
1516 return v8::Undefined();
1517}
1518
1519
Steve Blocka7e24c12009-10-30 11:49:00 +00001520v8::Local<Value> v8::TryCatch::Exception() const {
1521 if (HasCaught()) {
1522 // Check for out of memory exception.
1523 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
1524 return v8::Utils::ToLocal(i::Handle<i::Object>(exception));
1525 } else {
1526 return v8::Local<Value>();
1527 }
1528}
1529
1530
1531v8::Local<Value> v8::TryCatch::StackTrace() const {
1532 if (HasCaught()) {
1533 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1534 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
1535 v8::HandleScope scope;
1536 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj));
Steve Block44f0eee2011-05-26 01:26:41 +01001537 i::Handle<i::String> name = FACTORY->LookupAsciiSymbol("stack");
Steve Blocka7e24c12009-10-30 11:49:00 +00001538 if (!obj->HasProperty(*name))
1539 return v8::Local<Value>();
1540 return scope.Close(v8::Utils::ToLocal(i::GetProperty(obj, name)));
1541 } else {
1542 return v8::Local<Value>();
1543 }
1544}
1545
1546
1547v8::Local<v8::Message> v8::TryCatch::Message() const {
1548 if (HasCaught() && message_ != i::Smi::FromInt(0)) {
1549 i::Object* message = reinterpret_cast<i::Object*>(message_);
1550 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
1551 } else {
1552 return v8::Local<v8::Message>();
1553 }
1554}
1555
1556
1557void v8::TryCatch::Reset() {
Steve Block44f0eee2011-05-26 01:26:41 +01001558 exception_ = HEAP->the_hole_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00001559 message_ = i::Smi::FromInt(0);
1560}
1561
1562
1563void v8::TryCatch::SetVerbose(bool value) {
1564 is_verbose_ = value;
1565}
1566
1567
1568void v8::TryCatch::SetCaptureMessage(bool value) {
1569 capture_message_ = value;
1570}
1571
1572
1573// --- M e s s a g e ---
1574
1575
1576Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001577 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1578 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
1579 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001580 HandleScope scope;
1581 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1582 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
1583 Local<String> result = Utils::ToLocal(raw_result);
1584 return scope.Close(result);
1585}
1586
1587
1588v8::Handle<Value> Message::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001589 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1590 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001591 return Local<String>();
1592 }
Steve Block44f0eee2011-05-26 01:26:41 +01001593 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001594 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001595 i::Handle<i::JSMessageObject> message =
1596 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001597 // Return this.script.name.
1598 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001599 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001600 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
1601 return scope.Close(Utils::ToLocal(resource_name));
1602}
1603
1604
1605v8::Handle<Value> Message::GetScriptData() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001606 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1607 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001608 return Local<Value>();
1609 }
Steve Block44f0eee2011-05-26 01:26:41 +01001610 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001611 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001612 i::Handle<i::JSMessageObject> message =
1613 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001614 // Return this.script.data.
1615 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001616 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001617 i::Handle<i::Object> data(i::Script::cast(script->value())->data());
1618 return scope.Close(Utils::ToLocal(data));
1619}
1620
1621
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001622v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001623 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1624 if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001625 return Local<v8::StackTrace>();
1626 }
Steve Block44f0eee2011-05-26 01:26:41 +01001627 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001628 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001629 i::Handle<i::JSMessageObject> message =
1630 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1631 i::Handle<i::Object> stackFramesObj(message->stack_frames());
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001632 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
1633 i::Handle<i::JSArray> stackTrace =
1634 i::Handle<i::JSArray>::cast(stackFramesObj);
1635 return scope.Close(Utils::StackTraceToLocal(stackTrace));
1636}
1637
1638
Steve Blocka7e24c12009-10-30 11:49:00 +00001639static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1640 i::Handle<i::Object> recv,
1641 int argc,
1642 i::Object** argv[],
1643 bool* has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +01001644 i::Isolate* isolate = i::Isolate::Current();
1645 i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name);
John Reck59135872010-11-02 12:39:01 -07001646 i::Object* object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001647 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
Steve Blocka7e24c12009-10-30 11:49:00 +00001648 i::Handle<i::JSFunction> fun =
1649 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
1650 i::Handle<i::Object> value =
1651 i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
1652 return value;
1653}
1654
1655
1656static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1657 i::Handle<i::Object> data,
1658 bool* has_pending_exception) {
1659 i::Object** argv[1] = { data.location() };
1660 return CallV8HeapFunction(name,
Steve Block44f0eee2011-05-26 01:26:41 +01001661 i::Isolate::Current()->js_builtins_object(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001662 1,
1663 argv,
1664 has_pending_exception);
1665}
1666
1667
1668int Message::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001669 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1670 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
1671 ENTER_V8(isolate);
1672 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001673
Steve Block44f0eee2011-05-26 01:26:41 +01001674 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001675 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
1676 Utils::OpenHandle(this),
1677 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001678 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001679 return static_cast<int>(result->Number());
1680}
1681
1682
1683int Message::GetStartPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001684 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1685 if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
1686 ENTER_V8(isolate);
1687 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001688 i::Handle<i::JSMessageObject> message =
1689 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1690 return message->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001691}
1692
1693
1694int Message::GetEndPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001695 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1696 if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
1697 ENTER_V8(isolate);
1698 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001699 i::Handle<i::JSMessageObject> message =
1700 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1701 return message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001702}
1703
1704
1705int Message::GetStartColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001706 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1707 if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
1708 return kNoColumnInfo;
1709 }
1710 ENTER_V8(isolate);
1711 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001712 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001713 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001714 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1715 "GetPositionInLine",
1716 data_obj,
1717 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001718 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001719 return static_cast<int>(start_col_obj->Number());
1720}
1721
1722
1723int Message::GetEndColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001724 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1725 if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
1726 ENTER_V8(isolate);
1727 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001728 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001729 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001730 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1731 "GetPositionInLine",
1732 data_obj,
1733 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001734 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Block1e0659c2011-05-24 12:43:12 +01001735 i::Handle<i::JSMessageObject> message =
1736 i::Handle<i::JSMessageObject>::cast(data_obj);
1737 int start = message->start_position();
1738 int end = message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001739 return static_cast<int>(start_col_obj->Number()) + (end - start);
1740}
1741
1742
1743Local<String> Message::GetSourceLine() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001744 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1745 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
1746 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001747 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01001748 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001749 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
1750 Utils::OpenHandle(this),
1751 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001752 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001753 if (result->IsString()) {
1754 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
1755 } else {
1756 return Local<String>();
1757 }
1758}
1759
1760
1761void Message::PrintCurrentStackTrace(FILE* out) {
Steve Block44f0eee2011-05-26 01:26:41 +01001762 i::Isolate* isolate = i::Isolate::Current();
1763 if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
1764 ENTER_V8(isolate);
1765 isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00001766}
1767
1768
Kristian Monsen25f61362010-05-21 11:50:48 +01001769// --- S t a c k T r a c e ---
1770
1771Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01001772 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1773 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
1774 return Local<StackFrame>();
1775 }
1776 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001777 HandleScope scope;
1778 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
John Reck59135872010-11-02 12:39:01 -07001779 i::Object* raw_object = self->GetElementNoExceptionThrown(index);
1780 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001781 return scope.Close(Utils::StackFrameToLocal(obj));
1782}
1783
1784
1785int StackTrace::GetFrameCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001786 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1787 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
1788 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001789 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
1790}
1791
1792
1793Local<Array> StackTrace::AsArray() {
Steve Block44f0eee2011-05-26 01:26:41 +01001794 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1795 if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
1796 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001797 return Utils::ToLocal(Utils::OpenHandle(this));
1798}
1799
1800
1801Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
1802 StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01001803 i::Isolate* isolate = i::Isolate::Current();
1804 if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
1805 Local<StackTrace>();
1806 }
1807 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001808 i::Handle<i::JSArray> stackTrace =
Steve Block44f0eee2011-05-26 01:26:41 +01001809 isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001810 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01001811}
1812
1813
1814// --- S t a c k F r a m e ---
1815
1816int StackFrame::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001817 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1818 if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001819 return Message::kNoLineNumberInfo;
1820 }
Steve Block44f0eee2011-05-26 01:26:41 +01001821 ENTER_V8(isolate);
1822 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001823 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1824 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
1825 if (!line->IsSmi()) {
1826 return Message::kNoLineNumberInfo;
1827 }
1828 return i::Smi::cast(*line)->value();
1829}
1830
1831
1832int StackFrame::GetColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001833 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1834 if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001835 return Message::kNoColumnInfo;
1836 }
Steve Block44f0eee2011-05-26 01:26:41 +01001837 ENTER_V8(isolate);
1838 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001839 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1840 i::Handle<i::Object> column = GetProperty(self, "column");
1841 if (!column->IsSmi()) {
1842 return Message::kNoColumnInfo;
1843 }
1844 return i::Smi::cast(*column)->value();
1845}
1846
1847
1848Local<String> StackFrame::GetScriptName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001849 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1850 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
1851 return Local<String>();
1852 }
1853 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001854 HandleScope scope;
1855 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1856 i::Handle<i::Object> name = GetProperty(self, "scriptName");
1857 if (!name->IsString()) {
1858 return Local<String>();
1859 }
1860 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1861}
1862
1863
Ben Murdochf87a2032010-10-22 12:50:53 +01001864Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001865 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1866 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
Ben Murdochf87a2032010-10-22 12:50:53 +01001867 return Local<String>();
1868 }
Steve Block44f0eee2011-05-26 01:26:41 +01001869 ENTER_V8(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01001870 HandleScope scope;
1871 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1872 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
1873 if (!name->IsString()) {
1874 return Local<String>();
1875 }
1876 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1877}
1878
1879
Kristian Monsen25f61362010-05-21 11:50:48 +01001880Local<String> StackFrame::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001881 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1882 if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
1883 return Local<String>();
1884 }
1885 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001886 HandleScope scope;
1887 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1888 i::Handle<i::Object> name = GetProperty(self, "functionName");
1889 if (!name->IsString()) {
1890 return Local<String>();
1891 }
1892 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1893}
1894
1895
1896bool StackFrame::IsEval() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001897 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1898 if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
1899 ENTER_V8(isolate);
1900 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001901 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1902 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
1903 return is_eval->IsTrue();
1904}
1905
1906
1907bool StackFrame::IsConstructor() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001908 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1909 if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
1910 ENTER_V8(isolate);
1911 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001912 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1913 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
1914 return is_constructor->IsTrue();
1915}
1916
1917
Steve Blocka7e24c12009-10-30 11:49:00 +00001918// --- D a t a ---
1919
1920bool Value::IsUndefined() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001921 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
1922 return false;
1923 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001924 return Utils::OpenHandle(this)->IsUndefined();
1925}
1926
1927
1928bool Value::IsNull() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001929 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001930 return Utils::OpenHandle(this)->IsNull();
1931}
1932
1933
1934bool Value::IsTrue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001935 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001936 return Utils::OpenHandle(this)->IsTrue();
1937}
1938
1939
1940bool Value::IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001941 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001942 return Utils::OpenHandle(this)->IsFalse();
1943}
1944
1945
1946bool Value::IsFunction() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001947 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFunction()")) {
1948 return false;
1949 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001950 return Utils::OpenHandle(this)->IsJSFunction();
1951}
1952
1953
1954bool Value::FullIsString() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001955 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsString()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001956 bool result = Utils::OpenHandle(this)->IsString();
1957 ASSERT_EQ(result, QuickIsString());
1958 return result;
1959}
1960
1961
1962bool Value::IsArray() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001963 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001964 return Utils::OpenHandle(this)->IsJSArray();
1965}
1966
1967
1968bool Value::IsObject() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001969 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001970 return Utils::OpenHandle(this)->IsJSObject();
1971}
1972
1973
1974bool Value::IsNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001975 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001976 return Utils::OpenHandle(this)->IsNumber();
1977}
1978
1979
1980bool Value::IsBoolean() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001981 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsBoolean()")) {
1982 return false;
1983 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001984 return Utils::OpenHandle(this)->IsBoolean();
1985}
1986
1987
1988bool Value::IsExternal() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001989 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
1990 return false;
1991 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001992 return Utils::OpenHandle(this)->IsProxy();
1993}
1994
1995
1996bool Value::IsInt32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001997 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001998 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1999 if (obj->IsSmi()) return true;
2000 if (obj->IsNumber()) {
2001 double value = obj->Number();
2002 return i::FastI2D(i::FastD2I(value)) == value;
2003 }
2004 return false;
2005}
2006
2007
Steve Block6ded16b2010-05-10 14:33:55 +01002008bool Value::IsUint32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002009 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUint32()")) return false;
Steve Block6ded16b2010-05-10 14:33:55 +01002010 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2011 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2012 if (obj->IsNumber()) {
2013 double value = obj->Number();
2014 return i::FastUI2D(i::FastD2UI(value)) == value;
2015 }
2016 return false;
2017}
2018
2019
Steve Blocka7e24c12009-10-30 11:49:00 +00002020bool Value::IsDate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002021 i::Isolate* isolate = i::Isolate::Current();
2022 if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002023 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002024 return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00002025}
2026
2027
Iain Merrick75681382010-08-19 15:07:18 +01002028bool Value::IsRegExp() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002029 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
Iain Merrick75681382010-08-19 15:07:18 +01002030 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2031 return obj->IsJSRegExp();
2032}
2033
2034
Steve Blocka7e24c12009-10-30 11:49:00 +00002035Local<String> Value::ToString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002036 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2037 i::Handle<i::Object> str;
2038 if (obj->IsString()) {
2039 str = obj;
2040 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002041 i::Isolate* isolate = i::Isolate::Current();
2042 if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
2043 return Local<String>();
2044 }
2045 LOG_API(isolate, "ToString");
2046 ENTER_V8(isolate);
2047 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002048 str = i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002049 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002050 }
2051 return Local<String>(ToApi<String>(str));
2052}
2053
2054
2055Local<String> Value::ToDetailString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002056 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2057 i::Handle<i::Object> str;
2058 if (obj->IsString()) {
2059 str = obj;
2060 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002061 i::Isolate* isolate = i::Isolate::Current();
2062 if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
2063 return Local<String>();
2064 }
2065 LOG_API(isolate, "ToDetailString");
2066 ENTER_V8(isolate);
2067 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002068 str = i::Execution::ToDetailString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002069 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002070 }
2071 return Local<String>(ToApi<String>(str));
2072}
2073
2074
2075Local<v8::Object> Value::ToObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002076 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2077 i::Handle<i::Object> val;
2078 if (obj->IsJSObject()) {
2079 val = obj;
2080 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002081 i::Isolate* isolate = i::Isolate::Current();
2082 if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
2083 return Local<v8::Object>();
2084 }
2085 LOG_API(isolate, "ToObject");
2086 ENTER_V8(isolate);
2087 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002088 val = i::Execution::ToObject(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002089 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002090 }
2091 return Local<v8::Object>(ToApi<Object>(val));
2092}
2093
2094
2095Local<Boolean> Value::ToBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002096 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2097 if (obj->IsBoolean()) {
2098 return Local<Boolean>(ToApi<Boolean>(obj));
2099 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002100 i::Isolate* isolate = i::Isolate::Current();
2101 if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
2102 return Local<Boolean>();
2103 }
2104 LOG_API(isolate, "ToBoolean");
2105 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002106 i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
2107 return Local<Boolean>(ToApi<Boolean>(val));
2108 }
2109}
2110
2111
2112Local<Number> Value::ToNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002113 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2114 i::Handle<i::Object> num;
2115 if (obj->IsNumber()) {
2116 num = obj;
2117 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002118 i::Isolate* isolate = i::Isolate::Current();
2119 if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
2120 return Local<Number>();
2121 }
2122 LOG_API(isolate, "ToNumber");
2123 ENTER_V8(isolate);
2124 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002125 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002126 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002127 }
2128 return Local<Number>(ToApi<Number>(num));
2129}
2130
2131
2132Local<Integer> Value::ToInteger() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002133 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2134 i::Handle<i::Object> num;
2135 if (obj->IsSmi()) {
2136 num = obj;
2137 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002138 i::Isolate* isolate = i::Isolate::Current();
2139 if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
2140 LOG_API(isolate, "ToInteger");
2141 ENTER_V8(isolate);
2142 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002143 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002144 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002145 }
2146 return Local<Integer>(ToApi<Integer>(num));
2147}
2148
2149
2150void External::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002151 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002152 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2153 ApiCheck(obj->IsProxy(),
2154 "v8::External::Cast()",
2155 "Could not convert to external");
2156}
2157
2158
2159void v8::Object::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002160 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002161 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2162 ApiCheck(obj->IsJSObject(),
2163 "v8::Object::Cast()",
2164 "Could not convert to object");
2165}
2166
2167
2168void v8::Function::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002169 if (IsDeadCheck(i::Isolate::Current(), "v8::Function::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002170 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2171 ApiCheck(obj->IsJSFunction(),
2172 "v8::Function::Cast()",
2173 "Could not convert to function");
2174}
2175
2176
2177void v8::String::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002178 if (IsDeadCheck(i::Isolate::Current(), "v8::String::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002179 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2180 ApiCheck(obj->IsString(),
2181 "v8::String::Cast()",
2182 "Could not convert to string");
2183}
2184
2185
2186void v8::Number::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002187 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002188 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2189 ApiCheck(obj->IsNumber(),
2190 "v8::Number::Cast()",
2191 "Could not convert to number");
2192}
2193
2194
2195void v8::Integer::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002196 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002197 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2198 ApiCheck(obj->IsNumber(),
2199 "v8::Integer::Cast()",
2200 "Could not convert to number");
2201}
2202
2203
2204void v8::Array::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002205 if (IsDeadCheck(i::Isolate::Current(), "v8::Array::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002206 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2207 ApiCheck(obj->IsJSArray(),
2208 "v8::Array::Cast()",
2209 "Could not convert to array");
2210}
2211
2212
2213void v8::Date::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002214 i::Isolate* isolate = i::Isolate::Current();
2215 if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002216 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Steve Block44f0eee2011-05-26 01:26:41 +01002217 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
Steve Blocka7e24c12009-10-30 11:49:00 +00002218 "v8::Date::Cast()",
2219 "Could not convert to date");
2220}
2221
2222
Ben Murdochf87a2032010-10-22 12:50:53 +01002223void v8::RegExp::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002224 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
Ben Murdochf87a2032010-10-22 12:50:53 +01002225 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2226 ApiCheck(obj->IsJSRegExp(),
2227 "v8::RegExp::Cast()",
2228 "Could not convert to regular expression");
2229}
2230
2231
Steve Blocka7e24c12009-10-30 11:49:00 +00002232bool Value::BooleanValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002233 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2234 if (obj->IsBoolean()) {
2235 return obj->IsTrue();
2236 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002237 i::Isolate* isolate = i::Isolate::Current();
2238 if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
2239 LOG_API(isolate, "BooleanValue");
2240 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002241 i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
2242 return value->IsTrue();
2243 }
2244}
2245
2246
2247double Value::NumberValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002248 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2249 i::Handle<i::Object> num;
2250 if (obj->IsNumber()) {
2251 num = obj;
2252 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002253 i::Isolate* isolate = i::Isolate::Current();
2254 if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
2255 return i::OS::nan_value();
2256 }
2257 LOG_API(isolate, "NumberValue");
2258 ENTER_V8(isolate);
2259 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002260 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002261 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002262 }
2263 return num->Number();
2264}
2265
2266
2267int64_t Value::IntegerValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002268 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2269 i::Handle<i::Object> num;
2270 if (obj->IsNumber()) {
2271 num = obj;
2272 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002273 i::Isolate* isolate = i::Isolate::Current();
2274 if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
2275 LOG_API(isolate, "IntegerValue");
2276 ENTER_V8(isolate);
2277 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002278 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002279 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002280 }
2281 if (num->IsSmi()) {
2282 return i::Smi::cast(*num)->value();
2283 } else {
2284 return static_cast<int64_t>(num->Number());
2285 }
2286}
2287
2288
2289Local<Int32> Value::ToInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002290 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2291 i::Handle<i::Object> num;
2292 if (obj->IsSmi()) {
2293 num = obj;
2294 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002295 i::Isolate* isolate = i::Isolate::Current();
2296 if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
2297 LOG_API(isolate, "ToInt32");
2298 ENTER_V8(isolate);
2299 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002300 num = i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002301 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002302 }
2303 return Local<Int32>(ToApi<Int32>(num));
2304}
2305
2306
2307Local<Uint32> Value::ToUint32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002308 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2309 i::Handle<i::Object> num;
2310 if (obj->IsSmi()) {
2311 num = obj;
2312 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002313 i::Isolate* isolate = i::Isolate::Current();
2314 if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
2315 LOG_API(isolate, "ToUInt32");
2316 ENTER_V8(isolate);
2317 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002318 num = i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002319 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002320 }
2321 return Local<Uint32>(ToApi<Uint32>(num));
2322}
2323
2324
2325Local<Uint32> Value::ToArrayIndex() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002326 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2327 if (obj->IsSmi()) {
2328 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2329 return Local<Uint32>();
2330 }
Steve Block44f0eee2011-05-26 01:26:41 +01002331 i::Isolate* isolate = i::Isolate::Current();
2332 if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
2333 LOG_API(isolate, "ToArrayIndex");
2334 ENTER_V8(isolate);
2335 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002336 i::Handle<i::Object> string_obj =
2337 i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002338 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002339 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2340 uint32_t index;
2341 if (str->AsArrayIndex(&index)) {
2342 i::Handle<i::Object> value;
2343 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
2344 value = i::Handle<i::Object>(i::Smi::FromInt(index));
2345 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002346 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002347 }
2348 return Utils::Uint32ToLocal(value);
2349 }
2350 return Local<Uint32>();
2351}
2352
2353
2354int32_t Value::Int32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002355 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2356 if (obj->IsSmi()) {
2357 return i::Smi::cast(*obj)->value();
2358 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002359 i::Isolate* isolate = i::Isolate::Current();
2360 if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
2361 LOG_API(isolate, "Int32Value (slow)");
2362 ENTER_V8(isolate);
2363 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002364 i::Handle<i::Object> num =
2365 i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002366 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002367 if (num->IsSmi()) {
2368 return i::Smi::cast(*num)->value();
2369 } else {
2370 return static_cast<int32_t>(num->Number());
2371 }
2372 }
2373}
2374
2375
2376bool Value::Equals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002377 i::Isolate* isolate = i::Isolate::Current();
2378 if (IsDeadCheck(isolate, "v8::Value::Equals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002379 || EmptyCheck("v8::Value::Equals()", this)
2380 || EmptyCheck("v8::Value::Equals()", that)) {
2381 return false;
2382 }
Steve Block44f0eee2011-05-26 01:26:41 +01002383 LOG_API(isolate, "Equals");
2384 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002385 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2386 i::Handle<i::Object> other = Utils::OpenHandle(*that);
Steve Block1e0659c2011-05-24 12:43:12 +01002387 // If both obj and other are JSObjects, we'd better compare by identity
2388 // immediately when going into JS builtin. The reason is Invoke
2389 // would overwrite global object receiver with global proxy.
2390 if (obj->IsJSObject() && other->IsJSObject()) {
2391 return *obj == *other;
2392 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002393 i::Object** args[1] = { other.location() };
Steve Block44f0eee2011-05-26 01:26:41 +01002394 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002395 i::Handle<i::Object> result =
2396 CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002397 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002398 return *result == i::Smi::FromInt(i::EQUAL);
2399}
2400
2401
2402bool Value::StrictEquals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002403 i::Isolate* isolate = i::Isolate::Current();
2404 if (IsDeadCheck(isolate, "v8::Value::StrictEquals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002405 || EmptyCheck("v8::Value::StrictEquals()", this)
2406 || EmptyCheck("v8::Value::StrictEquals()", that)) {
2407 return false;
2408 }
Steve Block44f0eee2011-05-26 01:26:41 +01002409 LOG_API(isolate, "StrictEquals");
Steve Blocka7e24c12009-10-30 11:49:00 +00002410 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2411 i::Handle<i::Object> other = Utils::OpenHandle(*that);
2412 // Must check HeapNumber first, since NaN !== NaN.
2413 if (obj->IsHeapNumber()) {
2414 if (!other->IsNumber()) return false;
2415 double x = obj->Number();
2416 double y = other->Number();
2417 // Must check explicitly for NaN:s on Windows, but -0 works fine.
2418 return x == y && !isnan(x) && !isnan(y);
2419 } else if (*obj == *other) { // Also covers Booleans.
2420 return true;
2421 } else if (obj->IsSmi()) {
2422 return other->IsNumber() && obj->Number() == other->Number();
2423 } else if (obj->IsString()) {
2424 return other->IsString() &&
2425 i::String::cast(*obj)->Equals(i::String::cast(*other));
2426 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
2427 return other->IsUndefined() || other->IsUndetectableObject();
2428 } else {
2429 return false;
2430 }
2431}
2432
2433
2434uint32_t Value::Uint32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002435 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2436 if (obj->IsSmi()) {
2437 return i::Smi::cast(*obj)->value();
2438 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002439 i::Isolate* isolate = i::Isolate::Current();
2440 if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
2441 LOG_API(isolate, "Uint32Value");
2442 ENTER_V8(isolate);
2443 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002444 i::Handle<i::Object> num =
2445 i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002446 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002447 if (num->IsSmi()) {
2448 return i::Smi::cast(*num)->value();
2449 } else {
2450 return static_cast<uint32_t>(num->Number());
2451 }
2452 }
2453}
2454
2455
2456bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
2457 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002458 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2459 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2460 ENTER_V8(isolate);
2461 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002462 i::Handle<i::Object> self = Utils::OpenHandle(this);
2463 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2464 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002465 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002466 i::Handle<i::Object> obj = i::SetProperty(
2467 self,
2468 key_obj,
2469 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002470 static_cast<PropertyAttributes>(attribs),
2471 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002472 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002473 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002474 return true;
2475}
2476
2477
Steve Block6ded16b2010-05-10 14:33:55 +01002478bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002479 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2480 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2481 ENTER_V8(isolate);
2482 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002483 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2484 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002485 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002486 i::Handle<i::Object> obj = i::SetElement(
2487 self,
2488 index,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002489 value_obj,
2490 i::kNonStrictMode);
Steve Block6ded16b2010-05-10 14:33:55 +01002491 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002492 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Block6ded16b2010-05-10 14:33:55 +01002493 return true;
2494}
2495
2496
Steve Blocka7e24c12009-10-30 11:49:00 +00002497bool v8::Object::ForceSet(v8::Handle<Value> key,
2498 v8::Handle<Value> value,
2499 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002500 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2501 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
2502 ENTER_V8(isolate);
2503 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002504 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2505 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2506 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002507 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002508 i::Handle<i::Object> obj = i::ForceSetProperty(
2509 self,
2510 key_obj,
2511 value_obj,
2512 static_cast<PropertyAttributes>(attribs));
2513 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002514 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002515 return true;
2516}
2517
2518
2519bool v8::Object::ForceDelete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002520 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2521 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
2522 ENTER_V8(isolate);
2523 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002524 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2525 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002526
2527 // When turning on access checks for a global object deoptimize all functions
2528 // as optimized code does not always handle access checks.
2529 i::Deoptimizer::DeoptimizeGlobalObject(*self);
2530
Steve Block44f0eee2011-05-26 01:26:41 +01002531 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002532 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
2533 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002534 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002535 return obj->IsTrue();
2536}
2537
2538
2539Local<Value> v8::Object::Get(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002540 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2541 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2542 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002543 i::Handle<i::Object> self = Utils::OpenHandle(this);
2544 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002545 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002546 i::Handle<i::Object> result = i::GetProperty(self, key_obj);
2547 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002548 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002549 return Utils::ToLocal(result);
2550}
2551
2552
Steve Block6ded16b2010-05-10 14:33:55 +01002553Local<Value> v8::Object::Get(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002554 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2555 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2556 ENTER_V8(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002557 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002558 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002559 i::Handle<i::Object> result = i::GetElement(self, index);
2560 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002561 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Block6ded16b2010-05-10 14:33:55 +01002562 return Utils::ToLocal(result);
2563}
2564
2565
Steve Blocka7e24c12009-10-30 11:49:00 +00002566Local<Value> v8::Object::GetPrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01002567 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2568 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
2569 return Local<v8::Value>());
2570 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002571 i::Handle<i::Object> self = Utils::OpenHandle(this);
2572 i::Handle<i::Object> result = i::GetPrototype(self);
2573 return Utils::ToLocal(result);
2574}
2575
2576
Andrei Popescu402d9372010-02-26 13:31:12 +00002577bool v8::Object::SetPrototype(Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002578 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2579 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
2580 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002581 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2582 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002583 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002584 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2585 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002586 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00002587 return true;
2588}
2589
2590
Steve Blocka7e24c12009-10-30 11:49:00 +00002591Local<Object> v8::Object::FindInstanceInPrototypeChain(
2592 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01002593 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2594 ON_BAILOUT(isolate,
2595 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002596 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01002597 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002598 i::JSObject* object = *Utils::OpenHandle(this);
2599 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2600 while (!object->IsInstanceOf(tmpl_info)) {
2601 i::Object* prototype = object->GetPrototype();
2602 if (!prototype->IsJSObject()) return Local<Object>();
2603 object = i::JSObject::cast(prototype);
2604 }
2605 return Utils::ToLocal(i::Handle<i::JSObject>(object));
2606}
2607
2608
2609Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01002610 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2611 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
2612 return Local<v8::Array>());
2613 ENTER_V8(isolate);
2614 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002615 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2616 i::Handle<i::FixedArray> value =
2617 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
2618 // Because we use caching to speed up enumeration it is important
2619 // to never change the result of the basic enumeration function so
2620 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01002621 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2622 i::Handle<i::JSArray> result =
2623 isolate->factory()->NewJSArrayWithElements(elms);
2624 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00002625}
2626
2627
2628Local<String> v8::Object::ObjectProtoToString() {
Steve Block44f0eee2011-05-26 01:26:41 +01002629 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2630 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
2631 return Local<v8::String>());
2632 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002633 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2634
2635 i::Handle<i::Object> name(self->class_name());
2636
2637 // Native implementation of Object.prototype.toString (v8natives.js):
2638 // var c = %ClassOf(this);
2639 // if (c === 'Arguments') c = 'Object';
2640 // return "[object " + c + "]";
2641
2642 if (!name->IsString()) {
2643 return v8::String::New("[object ]");
2644
2645 } else {
2646 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
2647 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
2648 return v8::String::New("[object Object]");
2649
2650 } else {
2651 const char* prefix = "[object ";
2652 Local<String> str = Utils::ToLocal(class_name);
2653 const char* postfix = "]";
2654
Steve Blockd0582a62009-12-15 09:54:21 +00002655 int prefix_len = i::StrLength(prefix);
2656 int str_len = str->Length();
2657 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00002658
Steve Blockd0582a62009-12-15 09:54:21 +00002659 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01002660 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002661
2662 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01002663 char* ptr = buf.start();
Steve Blocka7e24c12009-10-30 11:49:00 +00002664 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
2665 ptr += prefix_len;
2666
2667 // Write real content.
2668 str->WriteAscii(ptr, 0, str_len);
2669 ptr += str_len;
2670
2671 // Write postfix.
2672 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
2673
2674 // Copy the buffer into a heap-allocated string and return it.
Kristian Monsen25f61362010-05-21 11:50:48 +01002675 Local<String> result = v8::String::New(buf.start(), buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002676 return result;
2677 }
2678 }
2679}
2680
2681
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002682Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01002683 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2684 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
2685 return Local<v8::String>());
2686 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002687 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2688 i::Handle<i::String> name(self->constructor_name());
2689 return Utils::ToLocal(name);
2690}
2691
2692
Steve Blocka7e24c12009-10-30 11:49:00 +00002693bool v8::Object::Delete(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002694 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2695 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
2696 ENTER_V8(isolate);
2697 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002698 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2699 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2700 return i::DeleteProperty(self, key_obj)->IsTrue();
2701}
2702
2703
2704bool v8::Object::Has(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002705 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2706 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
2707 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002708 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2709 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2710 return self->HasProperty(*key_obj);
2711}
2712
2713
2714bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002715 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2716 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
2717 return false);
2718 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002719 HandleScope scope;
2720 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2721 return i::DeleteElement(self, index)->IsTrue();
2722}
2723
2724
2725bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002726 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2727 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002728 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2729 return self->HasElement(index);
2730}
2731
2732
Leon Clarkef7060e22010-06-03 12:02:55 +01002733bool Object::SetAccessor(Handle<String> name,
2734 AccessorGetter getter,
2735 AccessorSetter setter,
2736 v8::Handle<Value> data,
2737 AccessControl settings,
2738 PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01002739 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2740 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
2741 ENTER_V8(isolate);
2742 i::HandleScope scope(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01002743 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
2744 getter, setter, data,
2745 settings, attributes);
2746 i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
2747 return !result.is_null() && !result->IsUndefined();
2748}
2749
2750
Steve Blocka7e24c12009-10-30 11:49:00 +00002751bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002752 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2753 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
2754 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002755 return Utils::OpenHandle(this)->HasRealNamedProperty(
2756 *Utils::OpenHandle(*key));
2757}
2758
2759
2760bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002761 ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
2762 "v8::Object::HasRealIndexedProperty()",
2763 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002764 return Utils::OpenHandle(this)->HasRealElementProperty(index);
2765}
2766
2767
2768bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002769 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2770 ON_BAILOUT(isolate,
2771 "v8::Object::HasRealNamedCallbackProperty()",
2772 return false);
2773 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002774 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
2775 *Utils::OpenHandle(*key));
2776}
2777
2778
2779bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002780 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2781 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
2782 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002783 return Utils::OpenHandle(this)->HasNamedInterceptor();
2784}
2785
2786
2787bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002788 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2789 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
2790 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002791 return Utils::OpenHandle(this)->HasIndexedInterceptor();
2792}
2793
2794
2795Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
2796 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002797 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2798 ON_BAILOUT(isolate,
2799 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002800 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01002801 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002802 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2803 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2804 i::LookupResult lookup;
2805 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00002806 if (lookup.IsProperty()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002807 PropertyAttributes attributes;
John Reck59135872010-11-02 12:39:01 -07002808 i::Object* property =
2809 self_obj->GetProperty(*self_obj,
2810 &lookup,
2811 *key_obj,
2812 &attributes)->ToObjectUnchecked();
2813 i::Handle<i::Object> result(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00002814 return Utils::ToLocal(result);
2815 }
2816 return Local<Value>(); // No real property was found in prototype chain.
2817}
2818
2819
2820Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002821 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2822 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
2823 return Local<Value>());
2824 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002825 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2826 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2827 i::LookupResult lookup;
2828 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00002829 if (lookup.IsProperty()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002830 PropertyAttributes attributes;
John Reck59135872010-11-02 12:39:01 -07002831 i::Object* property =
2832 self_obj->GetProperty(*self_obj,
2833 &lookup,
2834 *key_obj,
2835 &attributes)->ToObjectUnchecked();
2836 i::Handle<i::Object> result(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00002837 return Utils::ToLocal(result);
2838 }
2839 return Local<Value>(); // No real property was found in prototype chain.
2840}
2841
2842
2843// Turns on access checks by copying the map and setting the check flag.
2844// Because the object gets a new map, existing inline cache caching
2845// the old map of this object will fail.
2846void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01002847 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2848 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
2849 ENTER_V8(isolate);
2850 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002851 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
2852
Ben Murdochb0fe1622011-05-05 13:52:32 +01002853 // When turning on access checks for a global object deoptimize all functions
2854 // as optimized code does not always handle access checks.
2855 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
2856
Steve Blocka7e24c12009-10-30 11:49:00 +00002857 i::Handle<i::Map> new_map =
Steve Block44f0eee2011-05-26 01:26:41 +01002858 isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002859 new_map->set_is_access_check_needed(true);
2860 obj->set_map(*new_map);
2861}
2862
2863
2864bool v8::Object::IsDirty() {
2865 return Utils::OpenHandle(this)->IsDirty();
2866}
2867
2868
2869Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01002870 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2871 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
2872 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002873 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002874 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002875 i::Handle<i::JSObject> result = i::Copy(self);
2876 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002877 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002878 return Utils::ToLocal(result);
2879}
2880
2881
2882int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01002883 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2884 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
2885 ENTER_V8(isolate);
2886 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002887 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block1e0659c2011-05-24 12:43:12 +01002888 i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true));
2889 if (!hidden_props_obj->IsJSObject()) {
2890 // We failed to create hidden properties. That's a detached
2891 // global proxy.
2892 ASSERT(hidden_props_obj->IsUndefined());
2893 return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00002894 }
Steve Block1e0659c2011-05-24 12:43:12 +01002895 i::Handle<i::JSObject> hidden_props =
2896 i::Handle<i::JSObject>::cast(hidden_props_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002897 i::Handle<i::String> hash_symbol = isolate->factory()->identity_hash_symbol();
Steve Block1e0659c2011-05-24 12:43:12 +01002898 if (hidden_props->HasLocalProperty(*hash_symbol)) {
2899 i::Handle<i::Object> hash = i::GetProperty(hidden_props, hash_symbol);
2900 CHECK(!hash.is_null());
2901 CHECK(hash->IsSmi());
2902 return i::Smi::cast(*hash)->value();
2903 }
2904
2905 int hash_value;
2906 int attempts = 0;
2907 do {
2908 // Generate a random 32-bit hash value but limit range to fit
2909 // within a smi.
Steve Block44f0eee2011-05-26 01:26:41 +01002910 hash_value = i::V8::Random(self->GetIsolate()) & i::Smi::kMaxValue;
Steve Block1e0659c2011-05-24 12:43:12 +01002911 attempts++;
2912 } while (hash_value == 0 && attempts < 30);
2913 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
2914 CHECK(!i::SetLocalPropertyIgnoreAttributes(
2915 hidden_props,
2916 hash_symbol,
2917 i::Handle<i::Object>(i::Smi::FromInt(hash_value)),
2918 static_cast<PropertyAttributes>(None)).is_null());
2919
Steve Blocka7e24c12009-10-30 11:49:00 +00002920 return hash_value;
2921}
2922
2923
2924bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
2925 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002926 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2927 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
2928 ENTER_V8(isolate);
2929 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002930 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2931 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true));
2932 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2933 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002934 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002935 i::Handle<i::Object> obj = i::SetProperty(
2936 hidden_props,
2937 key_obj,
2938 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002939 static_cast<PropertyAttributes>(None),
2940 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002941 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002942 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002943 return true;
2944}
2945
2946
2947v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002948 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2949 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
2950 return Local<v8::Value>());
2951 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002952 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2953 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
2954 if (hidden_props->IsUndefined()) {
2955 return v8::Local<v8::Value>();
2956 }
2957 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002958 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002959 i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
2960 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002961 EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002962 if (result->IsUndefined()) {
2963 return v8::Local<v8::Value>();
2964 }
2965 return Utils::ToLocal(result);
2966}
2967
2968
2969bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002970 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2971 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
2972 ENTER_V8(isolate);
2973 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002974 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2975 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
2976 if (hidden_props->IsUndefined()) {
2977 return true;
2978 }
2979 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
2980 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2981 return i::DeleteProperty(js_obj, key_obj)->IsTrue();
2982}
2983
2984
Steve Block44f0eee2011-05-26 01:26:41 +01002985namespace {
2986
2987void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
2988 void* data,
2989 ExternalArrayType array_type,
2990 int length) {
2991 i::Isolate* isolate = object->GetIsolate();
2992 i::Handle<i::ExternalArray> array =
2993 isolate->factory()->NewExternalArray(length, array_type, data);
2994
2995 // If the object already has external elements, create a new, unique
2996 // map if the element type is now changing, because assumptions about
2997 // generated code based on the receiver's map will be invalid.
2998 i::Handle<i::HeapObject> elements(object->elements());
2999 bool cant_reuse_map =
3000 elements->map()->IsUndefined() ||
3001 !elements->map()->has_external_array_elements() ||
3002 elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
3003 if (cant_reuse_map) {
3004 i::Handle<i::Map> external_array_map =
3005 isolate->factory()->GetExternalArrayElementsMap(
3006 i::Handle<i::Map>(object->map()),
3007 array_type,
3008 object->HasFastProperties());
3009 object->set_map(*external_array_map);
3010 }
3011 object->set_elements(*array);
3012}
3013
3014} // namespace
3015
3016
Steve Blocka7e24c12009-10-30 11:49:00 +00003017void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003018 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3019 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3020 ENTER_V8(isolate);
3021 i::HandleScope scope(isolate);
3022 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
Steve Blocka7e24c12009-10-30 11:49:00 +00003023 "v8::Object::SetIndexedPropertiesToPixelData()",
3024 "length exceeds max acceptable value")) {
3025 return;
3026 }
3027 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3028 if (!ApiCheck(!self->IsJSArray(),
3029 "v8::Object::SetIndexedPropertiesToPixelData()",
3030 "JSArray is not supported")) {
3031 return;
3032 }
Steve Block44f0eee2011-05-26 01:26:41 +01003033 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003034}
3035
3036
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003037bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003038 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003039 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3040 return false);
3041 return self->HasExternalPixelElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003042}
3043
3044
3045uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003046 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003047 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3048 return NULL);
3049 if (self->HasExternalPixelElements()) {
3050 return i::ExternalPixelArray::cast(self->elements())->
3051 external_pixel_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003052 } else {
3053 return NULL;
3054 }
3055}
3056
3057
3058int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003059 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003060 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3061 return -1);
3062 if (self->HasExternalPixelElements()) {
3063 return i::ExternalPixelArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003064 } else {
3065 return -1;
3066 }
3067}
3068
Steve Block3ce2e202009-11-05 08:53:23 +00003069void v8::Object::SetIndexedPropertiesToExternalArrayData(
3070 void* data,
3071 ExternalArrayType array_type,
3072 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003073 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3074 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3075 ENTER_V8(isolate);
3076 i::HandleScope scope(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003077 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3078 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3079 "length exceeds max acceptable value")) {
3080 return;
3081 }
3082 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3083 if (!ApiCheck(!self->IsJSArray(),
3084 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3085 "JSArray is not supported")) {
3086 return;
3087 }
Steve Block44f0eee2011-05-26 01:26:41 +01003088 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003089}
3090
3091
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003092bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003093 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003094 ON_BAILOUT(self->GetIsolate(),
3095 "v8::HasIndexedPropertiesInExternalArrayData()",
3096 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003097 return self->HasExternalArrayElements();
3098}
3099
3100
3101void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003102 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003103 ON_BAILOUT(self->GetIsolate(),
3104 "v8::GetIndexedPropertiesExternalArrayData()",
3105 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003106 if (self->HasExternalArrayElements()) {
3107 return i::ExternalArray::cast(self->elements())->external_pointer();
3108 } else {
3109 return NULL;
3110 }
3111}
3112
3113
3114ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003115 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003116 ON_BAILOUT(self->GetIsolate(),
3117 "v8::GetIndexedPropertiesExternalArrayDataType()",
3118 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003119 switch (self->elements()->map()->instance_type()) {
3120 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3121 return kExternalByteArray;
3122 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3123 return kExternalUnsignedByteArray;
3124 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3125 return kExternalShortArray;
3126 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3127 return kExternalUnsignedShortArray;
3128 case i::EXTERNAL_INT_ARRAY_TYPE:
3129 return kExternalIntArray;
3130 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3131 return kExternalUnsignedIntArray;
3132 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3133 return kExternalFloatArray;
Steve Block44f0eee2011-05-26 01:26:41 +01003134 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3135 return kExternalPixelArray;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003136 default:
3137 return static_cast<ExternalArrayType>(-1);
3138 }
3139}
3140
3141
3142int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003143 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003144 ON_BAILOUT(self->GetIsolate(),
3145 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3146 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003147 if (self->HasExternalArrayElements()) {
3148 return i::ExternalArray::cast(self->elements())->length();
3149 } else {
3150 return -1;
3151 }
3152}
3153
3154
Steve Blocka7e24c12009-10-30 11:49:00 +00003155Local<v8::Object> Function::NewInstance() const {
3156 return NewInstance(0, NULL);
3157}
3158
3159
3160Local<v8::Object> Function::NewInstance(int argc,
3161 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003162 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3163 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3164 return Local<v8::Object>());
3165 LOG_API(isolate, "Function::NewInstance");
3166 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003167 HandleScope scope;
3168 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3169 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3170 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003171 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003172 i::Handle<i::Object> returned =
3173 i::Execution::New(function, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003174 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003175 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3176}
3177
3178
3179Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3180 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01003181 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3182 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3183 LOG_API(isolate, "Function::Call");
3184 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003185 i::Object* raw_result = NULL;
3186 {
Steve Block44f0eee2011-05-26 01:26:41 +01003187 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003188 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3189 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3190 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3191 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003192 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003193 i::Handle<i::Object> returned =
3194 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003195 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003196 raw_result = *returned;
3197 }
3198 i::Handle<i::Object> result(raw_result);
3199 return Utils::ToLocal(result);
3200}
3201
3202
3203void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01003204 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3205 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003206 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3207 func->shared()->set_name(*Utils::OpenHandle(*name));
3208}
3209
3210
3211Handle<Value> Function::GetName() const {
3212 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3213 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3214}
3215
3216
Andrei Popescu402d9372010-02-26 13:31:12 +00003217ScriptOrigin Function::GetScriptOrigin() const {
3218 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3219 if (func->shared()->script()->IsScript()) {
3220 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3221 v8::ScriptOrigin origin(
3222 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3223 v8::Integer::New(script->line_offset()->value()),
3224 v8::Integer::New(script->column_offset()->value()));
3225 return origin;
3226 }
3227 return v8::ScriptOrigin(Handle<Value>());
3228}
3229
3230
3231const int Function::kLineOffsetNotFound = -1;
3232
3233
3234int Function::GetScriptLineNumber() const {
3235 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3236 if (func->shared()->script()->IsScript()) {
3237 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3238 return i::GetScriptLineNumber(script, func->shared()->start_position());
3239 }
3240 return kLineOffsetNotFound;
3241}
3242
3243
Steve Blocka7e24c12009-10-30 11:49:00 +00003244int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003245 i::Handle<i::String> str = Utils::OpenHandle(this);
3246 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3247 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003248}
3249
3250
3251int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003252 i::Handle<i::String> str = Utils::OpenHandle(this);
3253 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
3254 return str->Utf8Length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003255}
3256
3257
Steve Block6ded16b2010-05-10 14:33:55 +01003258int String::WriteUtf8(char* buffer,
3259 int capacity,
3260 int* nchars_ref,
3261 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003262 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3263 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3264 LOG_API(isolate, "String::WriteUtf8");
3265 ENTER_V8(isolate);
3266 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003267 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003268 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003269 if (hints & HINT_MANY_WRITES_EXPECTED) {
3270 // Flatten the string for efficiency. This applies whether we are
3271 // using StringInputBuffer or Get(i) to access the characters.
3272 str->TryFlatten();
3273 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003274 write_input_buffer.Reset(0, *str);
3275 int len = str->length();
3276 // Encode the first K - 3 bytes directly into the buffer since we
3277 // know there's room for them. If no capacity is given we copy all
3278 // of them here.
3279 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3280 int i;
3281 int pos = 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003282 int nchars = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003283 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3284 i::uc32 c = write_input_buffer.GetNext();
3285 int written = unibrow::Utf8::Encode(buffer + pos, c);
3286 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003287 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003288 }
3289 if (i < len) {
3290 // For the last characters we need to check the length for each one
3291 // because they may be longer than the remaining space in the
3292 // buffer.
3293 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3294 for (; i < len && pos < capacity; i++) {
3295 i::uc32 c = write_input_buffer.GetNext();
3296 int written = unibrow::Utf8::Encode(intermediate, c);
3297 if (pos + written <= capacity) {
3298 for (int j = 0; j < written; j++)
3299 buffer[pos + j] = intermediate[j];
3300 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003301 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003302 } else {
3303 // We've reached the end of the buffer
3304 break;
3305 }
3306 }
3307 }
Steve Block6ded16b2010-05-10 14:33:55 +01003308 if (nchars_ref != NULL) *nchars_ref = nchars;
Steve Blocka7e24c12009-10-30 11:49:00 +00003309 if (i == len && (capacity == -1 || pos < capacity))
3310 buffer[pos++] = '\0';
3311 return pos;
3312}
3313
3314
Steve Block6ded16b2010-05-10 14:33:55 +01003315int String::WriteAscii(char* buffer,
3316 int start,
3317 int length,
3318 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003319 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3320 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3321 LOG_API(isolate, "String::WriteAscii");
3322 ENTER_V8(isolate);
3323 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003324 ASSERT(start >= 0 && length >= -1);
3325 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003326 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003327 if (hints & HINT_MANY_WRITES_EXPECTED) {
3328 // Flatten the string for efficiency. This applies whether we are
3329 // using StringInputBuffer or Get(i) to access the characters.
3330 str->TryFlatten();
3331 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003332 int end = length;
3333 if ( (length == -1) || (length > str->length() - start) )
3334 end = str->length() - start;
3335 if (end < 0) return 0;
3336 write_input_buffer.Reset(start, *str);
3337 int i;
3338 for (i = 0; i < end; i++) {
3339 char c = static_cast<char>(write_input_buffer.GetNext());
3340 if (c == '\0') c = ' ';
3341 buffer[i] = c;
3342 }
3343 if (length == -1 || i < length)
3344 buffer[i] = '\0';
3345 return i;
3346}
3347
3348
Steve Block6ded16b2010-05-10 14:33:55 +01003349int String::Write(uint16_t* buffer,
3350 int start,
3351 int length,
3352 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003353 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3354 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
3355 LOG_API(isolate, "String::Write");
3356 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003357 ASSERT(start >= 0 && length >= -1);
3358 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003359 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003360 if (hints & HINT_MANY_WRITES_EXPECTED) {
3361 // Flatten the string for efficiency. This applies whether we are
3362 // using StringInputBuffer or Get(i) to access the characters.
3363 str->TryFlatten();
3364 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003365 int end = start + length;
3366 if ((length == -1) || (length > str->length() - start) )
3367 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003368 if (end < 0) return 0;
3369 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003370 if (length == -1 || end - start < length) {
3371 buffer[end - start] = '\0';
3372 }
3373 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003374}
3375
3376
3377bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003378 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003379 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
3380 return false;
3381 }
3382 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
Steve Blocka7e24c12009-10-30 11:49:00 +00003383 return i::StringShape(*str).IsExternalTwoByte();
3384}
3385
3386
3387bool v8::String::IsExternalAscii() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003388 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003389 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
3390 return false;
3391 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003392 return i::StringShape(*str).IsExternalAscii();
3393}
3394
3395
3396void v8::String::VerifyExternalStringResource(
3397 v8::String::ExternalStringResource* value) const {
3398 i::Handle<i::String> str = Utils::OpenHandle(this);
3399 v8::String::ExternalStringResource* expected;
3400 if (i::StringShape(*str).IsExternalTwoByte()) {
3401 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
3402 expected = reinterpret_cast<ExternalStringResource*>(resource);
3403 } else {
3404 expected = NULL;
3405 }
3406 CHECK_EQ(expected, value);
3407}
3408
3409
3410v8::String::ExternalAsciiStringResource*
3411 v8::String::GetExternalAsciiStringResource() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003412 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003413 if (IsDeadCheck(str->GetIsolate(),
3414 "v8::String::GetExternalAsciiStringResource()")) {
3415 return NULL;
3416 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003417 if (i::StringShape(*str).IsExternalAscii()) {
3418 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
3419 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
3420 } else {
3421 return NULL;
3422 }
3423}
3424
3425
3426double Number::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003427 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003428 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3429 return obj->Number();
3430}
3431
3432
3433bool Boolean::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003434 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003435 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3436 return obj->IsTrue();
3437}
3438
3439
3440int64_t Integer::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003441 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003442 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3443 if (obj->IsSmi()) {
3444 return i::Smi::cast(*obj)->value();
3445 } else {
3446 return static_cast<int64_t>(obj->Number());
3447 }
3448}
3449
3450
3451int32_t Int32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003452 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003453 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3454 if (obj->IsSmi()) {
3455 return i::Smi::cast(*obj)->value();
3456 } else {
3457 return static_cast<int32_t>(obj->Number());
3458 }
3459}
3460
3461
Steve Block6ded16b2010-05-10 14:33:55 +01003462uint32_t Uint32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003463 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003464 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3465 if (obj->IsSmi()) {
3466 return i::Smi::cast(*obj)->value();
3467 } else {
3468 return static_cast<uint32_t>(obj->Number());
3469 }
3470}
3471
3472
Steve Blocka7e24c12009-10-30 11:49:00 +00003473int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003474 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003475 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
3476 return 0;
3477 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003478 return obj->GetInternalFieldCount();
3479}
3480
3481
3482Local<Value> v8::Object::CheckedGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003483 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003484 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
3485 return Local<Value>();
3486 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003487 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3488 "v8::Object::GetInternalField()",
3489 "Reading internal field out of bounds")) {
3490 return Local<Value>();
3491 }
3492 i::Handle<i::Object> value(obj->GetInternalField(index));
3493 Local<Value> result = Utils::ToLocal(value);
3494#ifdef DEBUG
3495 Local<Value> unchecked = UncheckedGetInternalField(index);
3496 ASSERT(unchecked.IsEmpty() || (unchecked == result));
3497#endif
3498 return result;
3499}
3500
3501
3502void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003503 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003504 i::Isolate* isolate = obj->GetIsolate();
3505 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
3506 return;
3507 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003508 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3509 "v8::Object::SetInternalField()",
3510 "Writing internal field out of bounds")) {
3511 return;
3512 }
Steve Block44f0eee2011-05-26 01:26:41 +01003513 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003514 i::Handle<i::Object> val = Utils::OpenHandle(*value);
3515 obj->SetInternalField(index, *val);
3516}
3517
3518
Ben Murdochb8e0da22011-05-16 14:20:40 +01003519static bool CanBeEncodedAsSmi(void* ptr) {
Steve Block1e0659c2011-05-24 12:43:12 +01003520 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003521 return ((address & i::kEncodablePointerMask) == 0);
3522}
3523
3524
3525static i::Smi* EncodeAsSmi(void* ptr) {
3526 ASSERT(CanBeEncodedAsSmi(ptr));
Steve Block1e0659c2011-05-24 12:43:12 +01003527 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003528 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
3529 ASSERT(i::Internals::HasSmiTag(result));
3530 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
3531 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
3532 return result;
3533}
3534
3535
Steve Blocka7e24c12009-10-30 11:49:00 +00003536void v8::Object::SetPointerInInternalField(int index, void* value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003537 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3538 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003539 if (CanBeEncodedAsSmi(value)) {
3540 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
3541 } else {
3542 HandleScope scope;
3543 i::Handle<i::Proxy> proxy =
Steve Block44f0eee2011-05-26 01:26:41 +01003544 isolate->factory()->NewProxy(
3545 reinterpret_cast<i::Address>(value), i::TENURED);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003546 if (!proxy.is_null())
3547 Utils::OpenHandle(this)->SetInternalField(index, *proxy);
Steve Block3ce2e202009-11-05 08:53:23 +00003548 }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003549 ASSERT_EQ(value, GetPointerFromInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003550}
3551
3552
3553// --- E n v i r o n m e n t ---
3554
Steve Block44f0eee2011-05-26 01:26:41 +01003555
Steve Blocka7e24c12009-10-30 11:49:00 +00003556bool v8::V8::Initialize() {
Steve Block44f0eee2011-05-26 01:26:41 +01003557 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
3558 if (isolate != NULL && isolate->IsInitialized()) {
3559 return true;
3560 }
3561 return InitializeHelper();
Steve Blocka7e24c12009-10-30 11:49:00 +00003562}
3563
3564
3565bool v8::V8::Dispose() {
Steve Block44f0eee2011-05-26 01:26:41 +01003566 i::Isolate* isolate = i::Isolate::Current();
3567 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
3568 "v8::V8::Dispose()",
3569 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
3570 return false;
3571 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003572 i::V8::TearDown();
3573 return true;
3574}
3575
3576
Russell Brenner90bac252010-11-18 13:33:46 -08003577HeapStatistics::HeapStatistics(): total_heap_size_(0),
3578 total_heap_size_executable_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01003579 used_heap_size_(0),
3580 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00003581
3582
3583void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
Steve Block44f0eee2011-05-26 01:26:41 +01003584 i::Heap* heap = i::Isolate::Current()->heap();
3585 heap_statistics->set_total_heap_size(heap->CommittedMemory());
Russell Brenner90bac252010-11-18 13:33:46 -08003586 heap_statistics->set_total_heap_size_executable(
Steve Block44f0eee2011-05-26 01:26:41 +01003587 heap->CommittedMemoryExecutable());
3588 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
3589 heap_statistics->set_heap_size_limit(heap->MaxReserved());
Steve Block3ce2e202009-11-05 08:53:23 +00003590}
3591
3592
3593bool v8::V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003594 // Returning true tells the caller that it need not
3595 // continue to call IdleNotification.
Steve Block44f0eee2011-05-26 01:26:41 +01003596 if (!i::Isolate::Current()->IsInitialized()) return true;
Steve Block3ce2e202009-11-05 08:53:23 +00003597 return i::V8::IdleNotification();
Steve Blocka7e24c12009-10-30 11:49:00 +00003598}
3599
3600
3601void v8::V8::LowMemoryNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003602 i::Isolate* isolate = i::Isolate::Current();
3603 if (!isolate->IsInitialized()) return;
3604 isolate->heap()->CollectAllGarbage(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003605}
3606
3607
Steve Block6ded16b2010-05-10 14:33:55 +01003608int v8::V8::ContextDisposedNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003609 i::Isolate* isolate = i::Isolate::Current();
3610 if (!isolate->IsInitialized()) return 0;
3611 return isolate->heap()->NotifyContextDisposed();
Steve Block6ded16b2010-05-10 14:33:55 +01003612}
3613
3614
Steve Blocka7e24c12009-10-30 11:49:00 +00003615const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01003616 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00003617}
3618
3619
3620static i::Handle<i::FunctionTemplateInfo>
3621 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
3622 if (templ->constructor()->IsUndefined()) {
3623 Local<FunctionTemplate> constructor = FunctionTemplate::New();
3624 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
3625 templ->set_constructor(*Utils::OpenHandle(*constructor));
3626 }
3627 return i::Handle<i::FunctionTemplateInfo>(
3628 i::FunctionTemplateInfo::cast(templ->constructor()));
3629}
3630
3631
3632Persistent<Context> v8::Context::New(
3633 v8::ExtensionConfiguration* extensions,
3634 v8::Handle<ObjectTemplate> global_template,
3635 v8::Handle<Value> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01003636 i::Isolate* isolate = i::Isolate::Current();
3637 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
3638 LOG_API(isolate, "Context::New");
3639 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003640
3641 // Enter V8 via an ENTER_V8 scope.
3642 i::Handle<i::Context> env;
3643 {
Steve Block44f0eee2011-05-26 01:26:41 +01003644 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003645 v8::Handle<ObjectTemplate> proxy_template = global_template;
3646 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
3647 i::Handle<i::FunctionTemplateInfo> global_constructor;
3648
3649 if (!global_template.IsEmpty()) {
3650 // Make sure that the global_template has a constructor.
3651 global_constructor =
3652 EnsureConstructor(Utils::OpenHandle(*global_template));
3653
3654 // Create a fresh template for the global proxy object.
3655 proxy_template = ObjectTemplate::New();
3656 proxy_constructor =
3657 EnsureConstructor(Utils::OpenHandle(*proxy_template));
3658
3659 // Set the global template to be the prototype template of
3660 // global proxy template.
3661 proxy_constructor->set_prototype_template(
3662 *Utils::OpenHandle(*global_template));
3663
3664 // Migrate security handlers from global_template to
3665 // proxy_template. Temporarily removing access check
3666 // information from the global template.
3667 if (!global_constructor->access_check_info()->IsUndefined()) {
3668 proxy_constructor->set_access_check_info(
3669 global_constructor->access_check_info());
3670 proxy_constructor->set_needs_access_check(
3671 global_constructor->needs_access_check());
3672 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01003673 global_constructor->set_access_check_info(
3674 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003675 }
3676 }
3677
3678 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01003679 env = isolate->bootstrapper()->CreateEnvironment(
Steve Blocka7e24c12009-10-30 11:49:00 +00003680 Utils::OpenHandle(*global_object),
3681 proxy_template,
3682 extensions);
3683
3684 // Restore the access check info on the global template.
3685 if (!global_template.IsEmpty()) {
3686 ASSERT(!global_constructor.is_null());
3687 ASSERT(!proxy_constructor.is_null());
3688 global_constructor->set_access_check_info(
3689 proxy_constructor->access_check_info());
3690 global_constructor->set_needs_access_check(
3691 proxy_constructor->needs_access_check());
3692 }
Steve Block44f0eee2011-05-26 01:26:41 +01003693 isolate->runtime_profiler()->Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +00003694 }
3695 // Leave V8.
3696
3697 if (env.is_null())
3698 return Persistent<Context>();
3699 return Persistent<Context>(Utils::ToLocal(env));
3700}
3701
3702
3703void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01003704 i::Isolate* isolate = i::Isolate::Current();
3705 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
3706 return;
3707 }
3708 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003709 i::Handle<i::Context> env = Utils::OpenHandle(this);
3710 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
3711 env->set_security_token(*token_handle);
3712}
3713
3714
3715void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003716 i::Isolate* isolate = i::Isolate::Current();
3717 if (IsDeadCheck(isolate,
3718 "v8::Context::UseDefaultSecurityToken()")) {
3719 return;
3720 }
3721 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003722 i::Handle<i::Context> env = Utils::OpenHandle(this);
3723 env->set_security_token(env->global());
3724}
3725
3726
3727Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003728 i::Isolate* isolate = i::Isolate::Current();
3729 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
3730 return Handle<Value>();
3731 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003732 i::Handle<i::Context> env = Utils::OpenHandle(this);
3733 i::Object* security_token = env->security_token();
3734 i::Handle<i::Object> token_handle(security_token);
3735 return Utils::ToLocal(token_handle);
3736}
3737
3738
3739bool Context::HasOutOfMemoryException() {
3740 i::Handle<i::Context> env = Utils::OpenHandle(this);
3741 return env->has_out_of_memory();
3742}
3743
3744
3745bool Context::InContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01003746 return i::Isolate::Current()->context() != NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00003747}
3748
3749
3750v8::Local<v8::Context> Context::GetEntered() {
Steve Block44f0eee2011-05-26 01:26:41 +01003751 i::Isolate* isolate = i::Isolate::Current();
3752 if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
3753 return Local<Context>();
3754 }
3755 i::Handle<i::Object> last =
3756 isolate->handle_scope_implementer()->LastEnteredContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003757 if (last.is_null()) return Local<Context>();
3758 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
3759 return Utils::ToLocal(context);
3760}
3761
3762
3763v8::Local<v8::Context> Context::GetCurrent() {
Steve Block44f0eee2011-05-26 01:26:41 +01003764 i::Isolate* isolate = i::Isolate::Current();
3765 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
3766 return Local<Context>();
3767 }
3768 i::Handle<i::Object> current = isolate->global_context();
Steve Block3ce2e202009-11-05 08:53:23 +00003769 if (current.is_null()) return Local<Context>();
3770 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
Steve Blocka7e24c12009-10-30 11:49:00 +00003771 return Utils::ToLocal(context);
3772}
3773
3774
3775v8::Local<v8::Context> Context::GetCalling() {
Steve Block44f0eee2011-05-26 01:26:41 +01003776 i::Isolate* isolate = i::Isolate::Current();
3777 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
3778 return Local<Context>();
3779 }
3780 i::Handle<i::Object> calling =
3781 isolate->GetCallingGlobalContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003782 if (calling.is_null()) return Local<Context>();
3783 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
3784 return Utils::ToLocal(context);
3785}
3786
3787
3788v8::Local<v8::Object> Context::Global() {
Steve Block44f0eee2011-05-26 01:26:41 +01003789 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
3790 return Local<v8::Object>();
3791 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003792 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3793 i::Handle<i::Context> context =
3794 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
3795 i::Handle<i::Object> global(context->global_proxy());
3796 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
3797}
3798
3799
3800void Context::DetachGlobal() {
Steve Block44f0eee2011-05-26 01:26:41 +01003801 i::Isolate* isolate = i::Isolate::Current();
3802 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
3803 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003804 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3805 i::Handle<i::Context> context =
3806 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01003807 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00003808}
3809
3810
Andrei Popescu74b3c142010-03-29 12:03:09 +01003811void Context::ReattachGlobal(Handle<Object> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01003812 i::Isolate* isolate = i::Isolate::Current();
3813 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
3814 ENTER_V8(isolate);
Andrei Popescu74b3c142010-03-29 12:03:09 +01003815 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3816 i::Handle<i::Context> context =
3817 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01003818 isolate->bootstrapper()->ReattachGlobal(
3819 context,
3820 Utils::OpenHandle(*global_object));
3821}
3822
3823
3824void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
3825 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
Andrei Popescu74b3c142010-03-29 12:03:09 +01003826}
3827
3828
Steve Blocka7e24c12009-10-30 11:49:00 +00003829Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01003830 i::Isolate* isolate = i::Isolate::Current();
3831 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
3832 return Local<v8::Object>());
3833 LOG_API(isolate, "ObjectTemplate::NewInstance");
3834 ENTER_V8(isolate);
3835 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003836 i::Handle<i::Object> obj =
3837 i::Execution::InstantiateObject(Utils::OpenHandle(this),
3838 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003839 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003840 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
3841}
3842
3843
3844Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01003845 i::Isolate* isolate = i::Isolate::Current();
3846 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003847 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01003848 LOG_API(isolate, "FunctionTemplate::GetFunction");
3849 ENTER_V8(isolate);
3850 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003851 i::Handle<i::Object> obj =
3852 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
3853 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003854 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003855 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
3856}
3857
3858
3859bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003860 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
3861 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003862 i::Object* obj = *Utils::OpenHandle(*value);
3863 return obj->IsInstanceOf(*Utils::OpenHandle(this));
3864}
3865
3866
3867static Local<External> ExternalNewImpl(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01003868 return Utils::ToLocal(FACTORY->NewProxy(static_cast<i::Address>(data)));
Steve Blocka7e24c12009-10-30 11:49:00 +00003869}
3870
3871static void* ExternalValueImpl(i::Handle<i::Object> obj) {
3872 return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy());
3873}
3874
3875
Steve Blocka7e24c12009-10-30 11:49:00 +00003876Local<Value> v8::External::Wrap(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01003877 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00003878 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01003879 LOG_API(isolate, "External::Wrap");
3880 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
3881 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003882
3883 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
3884 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
3885 : v8::Local<v8::Value>(ExternalNewImpl(data));
3886
3887 ASSERT_EQ(data, Unwrap(result));
3888 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003889}
3890
3891
Steve Block3ce2e202009-11-05 08:53:23 +00003892void* v8::Object::SlowGetPointerFromInternalField(int index) {
3893 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3894 i::Object* value = obj->GetInternalField(index);
3895 if (value->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01003896 return i::Internals::GetExternalPointerFromSmi(value);
Steve Block3ce2e202009-11-05 08:53:23 +00003897 } else if (value->IsProxy()) {
3898 return reinterpret_cast<void*>(i::Proxy::cast(value)->proxy());
3899 } else {
3900 return NULL;
3901 }
3902}
3903
3904
Steve Blocka7e24c12009-10-30 11:49:00 +00003905void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
Steve Block44f0eee2011-05-26 01:26:41 +01003906 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003907 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
3908 void* result;
3909 if (obj->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01003910 result = i::Internals::GetExternalPointerFromSmi(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00003911 } else if (obj->IsProxy()) {
3912 result = ExternalValueImpl(obj);
3913 } else {
3914 result = NULL;
3915 }
3916 ASSERT_EQ(result, QuickUnwrap(wrapper));
3917 return result;
3918}
3919
3920
3921Local<External> v8::External::New(void* data) {
3922 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01003923 i::Isolate* isolate = i::Isolate::Current();
3924 LOG_API(isolate, "External::New");
3925 EnsureInitializedForIsolate(isolate, "v8::External::New()");
3926 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003927 return ExternalNewImpl(data);
3928}
3929
3930
3931void* External::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003932 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003933 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3934 return ExternalValueImpl(obj);
3935}
3936
3937
3938Local<String> v8::String::Empty() {
Steve Block44f0eee2011-05-26 01:26:41 +01003939 i::Isolate* isolate = i::Isolate::Current();
3940 EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
3941 LOG_API(isolate, "String::Empty()");
3942 return Utils::ToLocal(isolate->factory()->empty_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00003943}
3944
3945
3946Local<String> v8::String::New(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003947 i::Isolate* isolate = i::Isolate::Current();
3948 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3949 LOG_API(isolate, "String::New(char)");
Steve Blocka7e24c12009-10-30 11:49:00 +00003950 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01003951 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00003952 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00003953 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01003954 isolate->factory()->NewStringFromUtf8(
3955 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00003956 return Utils::ToLocal(result);
3957}
3958
3959
Steve Block3ce2e202009-11-05 08:53:23 +00003960Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00003961 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01003962 i::Isolate* isolate = left_string->GetIsolate();
3963 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3964 LOG_API(isolate, "String::New(char)");
3965 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003966 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Steve Block44f0eee2011-05-26 01:26:41 +01003967 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
3968 right_string);
Steve Block3ce2e202009-11-05 08:53:23 +00003969 return Utils::ToLocal(result);
3970}
3971
3972
Steve Blocka7e24c12009-10-30 11:49:00 +00003973Local<String> v8::String::NewUndetectable(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003974 i::Isolate* isolate = i::Isolate::Current();
3975 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
3976 LOG_API(isolate, "String::NewUndetectable(char)");
3977 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00003978 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00003979 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01003980 isolate->factory()->NewStringFromUtf8(
3981 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00003982 result->MarkAsUndetectable();
3983 return Utils::ToLocal(result);
3984}
3985
3986
3987static int TwoByteStringLength(const uint16_t* data) {
3988 int length = 0;
3989 while (data[length] != '\0') length++;
3990 return length;
3991}
3992
3993
3994Local<String> v8::String::New(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003995 i::Isolate* isolate = i::Isolate::Current();
3996 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3997 LOG_API(isolate, "String::New(uint16_)");
Steve Blocka7e24c12009-10-30 11:49:00 +00003998 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01003999 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004000 if (length == -1) length = TwoByteStringLength(data);
4001 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004002 isolate->factory()->NewStringFromTwoByte(
4003 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004004 return Utils::ToLocal(result);
4005}
4006
4007
4008Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004009 i::Isolate* isolate = i::Isolate::Current();
4010 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4011 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4012 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004013 if (length == -1) length = TwoByteStringLength(data);
4014 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004015 isolate->factory()->NewStringFromTwoByte(
4016 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004017 result->MarkAsUndetectable();
4018 return Utils::ToLocal(result);
4019}
4020
4021
Steve Block44f0eee2011-05-26 01:26:41 +01004022i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004023 v8::String::ExternalStringResource* resource) {
4024 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004025 isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004026 return result;
4027}
4028
4029
Steve Block44f0eee2011-05-26 01:26:41 +01004030i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004031 v8::String::ExternalAsciiStringResource* resource) {
4032 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004033 isolate->factory()->NewExternalStringFromAscii(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004034 return result;
4035}
4036
4037
Steve Blocka7e24c12009-10-30 11:49:00 +00004038Local<String> v8::String::NewExternal(
4039 v8::String::ExternalStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004040 i::Isolate* isolate = i::Isolate::Current();
4041 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4042 LOG_API(isolate, "String::NewExternal");
4043 ENTER_V8(isolate);
4044 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4045 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004046 return Utils::ToLocal(result);
4047}
4048
4049
4050bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004051 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004052 i::Isolate* isolate = obj->GetIsolate();
4053 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4054 if (i::StringShape(*obj).IsExternalTwoByte()) {
4055 return false; // Already an external string.
4056 }
4057 ENTER_V8(isolate);
4058 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4059 return false;
4060 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004061 bool result = obj->MakeExternal(resource);
4062 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004063 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004064 }
4065 return result;
4066}
4067
4068
4069Local<String> v8::String::NewExternal(
4070 v8::String::ExternalAsciiStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004071 i::Isolate* isolate = i::Isolate::Current();
4072 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4073 LOG_API(isolate, "String::NewExternal");
4074 ENTER_V8(isolate);
4075 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4076 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004077 return Utils::ToLocal(result);
4078}
4079
4080
4081bool v8::String::MakeExternal(
4082 v8::String::ExternalAsciiStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004083 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004084 i::Isolate* isolate = obj->GetIsolate();
4085 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4086 if (i::StringShape(*obj).IsExternalTwoByte()) {
4087 return false; // Already an external string.
4088 }
4089 ENTER_V8(isolate);
4090 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4091 return false;
4092 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004093 bool result = obj->MakeExternal(resource);
4094 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004095 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004096 }
4097 return result;
4098}
4099
4100
4101bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004102 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004103 i::Isolate* isolate = obj->GetIsolate();
4104 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4105 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4106 return false;
4107 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004108 int size = obj->Size(); // Byte size of the original string.
4109 if (size < i::ExternalString::kSize)
4110 return false;
4111 i::StringShape shape(*obj);
4112 return !shape.IsExternal();
4113}
4114
4115
4116Local<v8::Object> v8::Object::New() {
Steve Block44f0eee2011-05-26 01:26:41 +01004117 i::Isolate* isolate = i::Isolate::Current();
4118 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4119 LOG_API(isolate, "Object::New");
4120 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004121 i::Handle<i::JSObject> obj =
Steve Block44f0eee2011-05-26 01:26:41 +01004122 isolate->factory()->NewJSObject(isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00004123 return Utils::ToLocal(obj);
4124}
4125
4126
4127Local<v8::Value> v8::Date::New(double time) {
Steve Block44f0eee2011-05-26 01:26:41 +01004128 i::Isolate* isolate = i::Isolate::Current();
4129 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4130 LOG_API(isolate, "Date::New");
Steve Blockd0582a62009-12-15 09:54:21 +00004131 if (isnan(time)) {
4132 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4133 time = i::OS::nan_value();
4134 }
Steve Block44f0eee2011-05-26 01:26:41 +01004135 ENTER_V8(isolate);
4136 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004137 i::Handle<i::Object> obj =
4138 i::Execution::NewDate(time, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004139 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004140 return Utils::ToLocal(obj);
4141}
4142
4143
4144double v8::Date::NumberValue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004145 i::Isolate* isolate = i::Isolate::Current();
4146 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4147 LOG_API(isolate, "Date::NumberValue");
Steve Blocka7e24c12009-10-30 11:49:00 +00004148 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4149 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4150 return jsvalue->value()->Number();
4151}
4152
4153
Ben Murdochb0fe1622011-05-05 13:52:32 +01004154void v8::Date::DateTimeConfigurationChangeNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004155 i::Isolate* isolate = i::Isolate::Current();
4156 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4157 return);
4158 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
4159 ENTER_V8(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004160
Steve Block44f0eee2011-05-26 01:26:41 +01004161 i::HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004162 // Get the function ResetDateCache (defined in date-delay.js).
4163 i::Handle<i::String> func_name_str =
Steve Block44f0eee2011-05-26 01:26:41 +01004164 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4165 i::MaybeObject* result =
4166 isolate->js_builtins_object()->GetProperty(*func_name_str);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004167 i::Object* object_func;
4168 if (!result->ToObject(&object_func)) {
4169 return;
4170 }
4171
4172 if (object_func->IsJSFunction()) {
4173 i::Handle<i::JSFunction> func =
4174 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4175
4176 // Call ResetDateCache(0 but expect no exceptions:
4177 bool caught_exception = false;
4178 i::Handle<i::Object> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004179 i::Execution::TryCall(func, isolate->js_builtins_object(), 0, NULL,
Ben Murdochb0fe1622011-05-05 13:52:32 +01004180 &caught_exception);
4181 }
4182}
4183
4184
Ben Murdochf87a2032010-10-22 12:50:53 +01004185static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4186 char flags_buf[3];
4187 int num_flags = 0;
4188 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4189 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4190 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4191 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
Steve Block44f0eee2011-05-26 01:26:41 +01004192 return FACTORY->LookupSymbol(
Ben Murdochf87a2032010-10-22 12:50:53 +01004193 i::Vector<const char>(flags_buf, num_flags));
4194}
4195
4196
4197Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4198 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01004199 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
4200 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
4201 LOG_API(isolate, "RegExp::New");
4202 ENTER_V8(isolate);
4203 EXCEPTION_PREAMBLE(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01004204 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
4205 Utils::OpenHandle(*pattern),
4206 RegExpFlagsToString(flags),
4207 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004208 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01004209 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
4210}
4211
4212
4213Local<v8::String> v8::RegExp::GetSource() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004214 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4215 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
4216 return Local<v8::String>();
4217 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004218 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4219 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
4220}
4221
4222
4223// Assert that the static flags cast in GetFlags is valid.
4224#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
4225 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
4226 static_cast<int>(i::JSRegExp::internal_flag))
4227REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
4228REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
4229REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
4230REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
4231#undef REGEXP_FLAG_ASSERT_EQ
4232
4233v8::RegExp::Flags v8::RegExp::GetFlags() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004234 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
4235 return v8::RegExp::kNone;
4236 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004237 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4238 return static_cast<RegExp::Flags>(obj->GetFlags().value());
4239}
4240
4241
Steve Blocka7e24c12009-10-30 11:49:00 +00004242Local<v8::Array> v8::Array::New(int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004243 i::Isolate* isolate = i::Isolate::Current();
4244 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
4245 LOG_API(isolate, "Array::New");
4246 ENTER_V8(isolate);
4247 int real_length = length > 0 ? length : 0;
4248 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
4249 obj->set_length(*isolate->factory()->NewNumberFromInt(real_length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004250 return Utils::ToLocal(obj);
4251}
4252
4253
4254uint32_t v8::Array::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004255 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4256 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004257 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
4258 i::Object* length = obj->length();
4259 if (length->IsSmi()) {
4260 return i::Smi::cast(length)->value();
4261 } else {
4262 return static_cast<uint32_t>(length->Number());
4263 }
4264}
4265
4266
4267Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01004268 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4269 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004270 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
4271 if (!self->HasFastElements()) {
4272 return Local<Object>();
4273 }
4274 i::FixedArray* elms = i::FixedArray::cast(self->elements());
4275 i::Object* paragon = elms->get(index);
4276 if (!paragon->IsJSObject()) {
4277 return Local<Object>();
4278 }
4279 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01004280 EXCEPTION_PREAMBLE(isolate);
4281 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004282 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
4283 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01004284 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004285 return Utils::ToLocal(result);
4286}
4287
4288
4289Local<String> v8::String::NewSymbol(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004290 i::Isolate* isolate = i::Isolate::Current();
4291 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
4292 LOG_API(isolate, "String::NewSymbol(char)");
4293 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004294 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004295 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004296 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004297 return Utils::ToLocal(result);
4298}
4299
4300
4301Local<Number> v8::Number::New(double value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004302 i::Isolate* isolate = i::Isolate::Current();
4303 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
Steve Blockd0582a62009-12-15 09:54:21 +00004304 if (isnan(value)) {
4305 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4306 value = i::OS::nan_value();
4307 }
Steve Block44f0eee2011-05-26 01:26:41 +01004308 ENTER_V8(isolate);
4309 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004310 return Utils::NumberToLocal(result);
4311}
4312
4313
4314Local<Integer> v8::Integer::New(int32_t value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004315 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4316 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004317 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004318 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
4319 isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004320 }
Steve Block44f0eee2011-05-26 01:26:41 +01004321 ENTER_V8(isolate);
4322 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004323 return Utils::IntegerToLocal(result);
4324}
4325
4326
Steve Block3ce2e202009-11-05 08:53:23 +00004327Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
4328 bool fits_into_int32_t = (value & (1 << 31)) == 0;
4329 if (fits_into_int32_t) {
4330 return Integer::New(static_cast<int32_t>(value));
4331 }
Steve Block44f0eee2011-05-26 01:26:41 +01004332 i::Isolate* isolate = i::Isolate::Current();
4333 ENTER_V8(isolate);
4334 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00004335 return Utils::IntegerToLocal(result);
4336}
4337
4338
Steve Blocka7e24c12009-10-30 11:49:00 +00004339void V8::IgnoreOutOfMemoryException() {
Steve Block44f0eee2011-05-26 01:26:41 +01004340 EnterIsolateIfNeeded()->handle_scope_implementer()->set_ignore_out_of_memory(
4341 true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004342}
4343
4344
4345bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004346 i::Isolate* isolate = i::Isolate::Current();
4347 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
4348 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
4349 ENTER_V8(isolate);
4350 i::HandleScope scope(isolate);
4351 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004352 NeanderObject obj(2);
Steve Block44f0eee2011-05-26 01:26:41 +01004353 obj.set(0, *isolate->factory()->NewProxy(FUNCTION_ADDR(that)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004354 obj.set(1, data.IsEmpty() ?
Steve Block44f0eee2011-05-26 01:26:41 +01004355 isolate->heap()->undefined_value() :
Steve Blocka7e24c12009-10-30 11:49:00 +00004356 *Utils::OpenHandle(*data));
4357 listeners.add(obj.value());
4358 return true;
4359}
4360
4361
4362void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01004363 i::Isolate* isolate = i::Isolate::Current();
4364 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
4365 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
4366 ENTER_V8(isolate);
4367 i::HandleScope scope(isolate);
4368 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004369 for (int i = 0; i < listeners.length(); i++) {
4370 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
4371
4372 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
4373 i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
4374 if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004375 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004376 }
4377 }
4378}
4379
4380
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004381void V8::SetCaptureStackTraceForUncaughtExceptions(
4382 bool capture,
4383 int frame_limit,
4384 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01004385 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004386 capture,
4387 frame_limit,
4388 options);
4389}
4390
4391
Steve Blocka7e24c12009-10-30 11:49:00 +00004392void V8::SetCounterFunction(CounterLookupCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004393 i::Isolate* isolate = EnterIsolateIfNeeded();
4394 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
4395 isolate->stats_table()->SetCounterFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004396}
4397
4398void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004399 i::Isolate* isolate = EnterIsolateIfNeeded();
4400 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
4401 isolate->stats_table()->SetCreateHistogramFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004402}
4403
4404void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004405 i::Isolate* isolate = EnterIsolateIfNeeded();
4406 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
4407 isolate->stats_table()->
4408 SetAddHistogramSampleFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004409}
4410
4411void V8::EnableSlidingStateWindow() {
Steve Block44f0eee2011-05-26 01:26:41 +01004412 i::Isolate* isolate = i::Isolate::Current();
4413 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
4414 isolate->logger()->EnableSlidingStateWindow();
Steve Blocka7e24c12009-10-30 11:49:00 +00004415}
4416
4417
4418void V8::SetFailedAccessCheckCallbackFunction(
4419 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004420 i::Isolate* isolate = i::Isolate::Current();
4421 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
4422 return;
4423 }
4424 isolate->SetFailedAccessCheckCallback(callback);
4425}
4426
4427void V8::AddObjectGroup(Persistent<Value>* objects,
4428 size_t length,
4429 RetainedObjectInfo* info) {
4430 i::Isolate* isolate = i::Isolate::Current();
4431 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
4432 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
4433 isolate->global_handles()->AddObjectGroup(
4434 reinterpret_cast<i::Object***>(objects), length, info);
Steve Blocka7e24c12009-10-30 11:49:00 +00004435}
4436
4437
Steve Block44f0eee2011-05-26 01:26:41 +01004438void V8::AddImplicitReferences(Persistent<Object> parent,
4439 Persistent<Value>* children,
4440 size_t length) {
4441 i::Isolate* isolate = i::Isolate::Current();
4442 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004443 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
Steve Block44f0eee2011-05-26 01:26:41 +01004444 isolate->global_handles()->AddImplicitReferences(
4445 *Utils::OpenHandle(*parent),
4446 reinterpret_cast<i::Object***>(children), length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004447}
4448
4449
4450int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
Steve Block44f0eee2011-05-26 01:26:41 +01004451 i::Isolate* isolate = i::Isolate::Current();
4452 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
4453 return 0;
4454 }
4455 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
4456 change_in_bytes);
Steve Blocka7e24c12009-10-30 11:49:00 +00004457}
4458
4459
4460void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004461 i::Isolate* isolate = i::Isolate::Current();
4462 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
4463 isolate->heap()->SetGlobalGCPrologueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004464}
4465
4466
4467void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004468 i::Isolate* isolate = i::Isolate::Current();
4469 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
4470 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004471}
4472
4473
Steve Block6ded16b2010-05-10 14:33:55 +01004474void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004475 i::Isolate* isolate = i::Isolate::Current();
4476 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
4477 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004478}
4479
4480
4481void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004482 i::Isolate* isolate = i::Isolate::Current();
4483 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
4484 isolate->heap()->RemoveGCPrologueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004485}
4486
4487
4488void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004489 i::Isolate* isolate = i::Isolate::Current();
4490 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
4491 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004492}
4493
4494
4495void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004496 i::Isolate* isolate = i::Isolate::Current();
4497 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
4498 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004499}
4500
4501
Iain Merrick9ac36c92010-09-13 15:29:50 +01004502void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
4503 ObjectSpace space,
4504 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01004505 i::Isolate* isolate = i::Isolate::Current();
4506 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
4507 isolate->memory_allocator()->AddMemoryAllocationCallback(
4508 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004509}
4510
4511
4512void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004513 i::Isolate* isolate = i::Isolate::Current();
4514 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
4515 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
4516 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004517}
4518
4519
Steve Blocka7e24c12009-10-30 11:49:00 +00004520void V8::PauseProfiler() {
4521#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004522 PauseProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004523#endif
4524}
4525
4526
4527void V8::ResumeProfiler() {
4528#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004529 ResumeProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004530#endif
4531}
4532
4533
4534bool V8::IsProfilerPaused() {
4535#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004536 return LOGGER->GetActiveProfilerModules() & PROFILER_MODULE_CPU;
Steve Blocka7e24c12009-10-30 11:49:00 +00004537#else
4538 return true;
4539#endif
4540}
4541
4542
Andrei Popescu402d9372010-02-26 13:31:12 +00004543void V8::ResumeProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004544#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004545 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004546 if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
4547 // Snapshot mode: resume modules, perform GC, then pause only
4548 // those modules which haven't been started prior to making a
4549 // snapshot.
4550
Steve Block6ded16b2010-05-10 14:33:55 +01004551 // Make a GC prior to taking a snapshot.
Steve Block44f0eee2011-05-26 01:26:41 +01004552 isolate->heap()->CollectAllGarbage(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004553 // Reset snapshot flag and CPU module flags.
4554 flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
Steve Block44f0eee2011-05-26 01:26:41 +01004555 const int current_flags = isolate->logger()->GetActiveProfilerModules();
4556 isolate->logger()->ResumeProfiler(flags, tag);
4557 isolate->heap()->CollectAllGarbage(false);
4558 isolate->logger()->PauseProfiler(~current_flags & flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004559 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004560 isolate->logger()->ResumeProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004561 }
4562#endif
4563}
4564
4565
Andrei Popescu402d9372010-02-26 13:31:12 +00004566void V8::PauseProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004567#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004568 LOGGER->PauseProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004569#endif
4570}
4571
4572
4573int V8::GetActiveProfilerModules() {
4574#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004575 return LOGGER->GetActiveProfilerModules();
Steve Blocka7e24c12009-10-30 11:49:00 +00004576#else
4577 return PROFILER_MODULE_NONE;
4578#endif
4579}
4580
4581
4582int V8::GetLogLines(int from_pos, char* dest_buf, int max_size) {
4583#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block6ded16b2010-05-10 14:33:55 +01004584 ASSERT(max_size >= kMinimumSizeForLogLinesBuffer);
Steve Block44f0eee2011-05-26 01:26:41 +01004585 return LOGGER->GetLogLines(from_pos, dest_buf, max_size);
Steve Blocka7e24c12009-10-30 11:49:00 +00004586#endif
4587 return 0;
4588}
4589
4590
4591int V8::GetCurrentThreadId() {
Steve Block44f0eee2011-05-26 01:26:41 +01004592 i::Isolate* isolate = i::Isolate::Current();
4593 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
4594 return isolate->thread_id();
Steve Blocka7e24c12009-10-30 11:49:00 +00004595}
4596
4597
4598void V8::TerminateExecution(int thread_id) {
Steve Block44f0eee2011-05-26 01:26:41 +01004599 i::Isolate* isolate = i::Isolate::Current();
4600 if (!isolate->IsInitialized()) return;
4601 API_ENTRY_CHECK("V8::TerminateExecution()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004602 // If the thread_id identifies the current thread just terminate
4603 // execution right away. Otherwise, ask the thread manager to
4604 // terminate the thread with the given id if any.
Steve Block44f0eee2011-05-26 01:26:41 +01004605 if (thread_id == isolate->thread_id()) {
4606 isolate->stack_guard()->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00004607 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004608 isolate->thread_manager()->TerminateExecution(thread_id);
Steve Blocka7e24c12009-10-30 11:49:00 +00004609 }
4610}
4611
4612
Steve Block44f0eee2011-05-26 01:26:41 +01004613void V8::TerminateExecution(Isolate* isolate) {
4614 // If no isolate is supplied, use the default isolate.
4615 if (isolate != NULL) {
4616 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
4617 } else {
4618 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
4619 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004620}
4621
4622
Steve Block6ded16b2010-05-10 14:33:55 +01004623bool V8::IsExecutionTerminating() {
Steve Block44f0eee2011-05-26 01:26:41 +01004624 i::Isolate* isolate = i::Isolate::Current();
4625 return IsExecutionTerminatingCheck(isolate);
4626}
4627
4628
4629Isolate* Isolate::GetCurrent() {
4630 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4631 return reinterpret_cast<Isolate*>(isolate);
4632}
4633
4634
4635Isolate* Isolate::New() {
4636 i::Isolate* isolate = new i::Isolate();
4637 return reinterpret_cast<Isolate*>(isolate);
4638}
4639
4640
4641void Isolate::Dispose() {
4642 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4643 if (!ApiCheck(!isolate->IsInUse(),
4644 "v8::Isolate::Dispose()",
4645 "Disposing the isolate that is entered by a thread.")) {
4646 return;
Steve Block6ded16b2010-05-10 14:33:55 +01004647 }
Steve Block44f0eee2011-05-26 01:26:41 +01004648 isolate->TearDown();
4649}
4650
4651
4652void Isolate::Enter() {
4653 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4654 isolate->Enter();
4655}
4656
4657
4658void Isolate::Exit() {
4659 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4660 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01004661}
4662
4663
Steve Blocka7e24c12009-10-30 11:49:00 +00004664String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004665 i::Isolate* isolate = i::Isolate::Current();
4666 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004667 if (obj.IsEmpty()) {
4668 str_ = NULL;
4669 length_ = 0;
4670 return;
4671 }
Steve Block44f0eee2011-05-26 01:26:41 +01004672 ENTER_V8(isolate);
4673 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004674 TryCatch try_catch;
4675 Handle<String> str = obj->ToString();
4676 if (str.IsEmpty()) {
4677 str_ = NULL;
4678 length_ = 0;
4679 } else {
4680 length_ = str->Utf8Length();
4681 str_ = i::NewArray<char>(length_ + 1);
4682 str->WriteUtf8(str_);
4683 }
4684}
4685
4686
4687String::Utf8Value::~Utf8Value() {
4688 i::DeleteArray(str_);
4689}
4690
4691
4692String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004693 i::Isolate* isolate = i::Isolate::Current();
4694 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004695 if (obj.IsEmpty()) {
4696 str_ = NULL;
4697 length_ = 0;
4698 return;
4699 }
Steve Block44f0eee2011-05-26 01:26:41 +01004700 ENTER_V8(isolate);
4701 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004702 TryCatch try_catch;
4703 Handle<String> str = obj->ToString();
4704 if (str.IsEmpty()) {
4705 str_ = NULL;
4706 length_ = 0;
4707 } else {
4708 length_ = str->Length();
4709 str_ = i::NewArray<char>(length_ + 1);
4710 str->WriteAscii(str_);
4711 }
4712}
4713
4714
4715String::AsciiValue::~AsciiValue() {
4716 i::DeleteArray(str_);
4717}
4718
4719
4720String::Value::Value(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004721 i::Isolate* isolate = i::Isolate::Current();
4722 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004723 if (obj.IsEmpty()) {
4724 str_ = NULL;
4725 length_ = 0;
4726 return;
4727 }
Steve Block44f0eee2011-05-26 01:26:41 +01004728 ENTER_V8(isolate);
4729 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004730 TryCatch try_catch;
4731 Handle<String> str = obj->ToString();
4732 if (str.IsEmpty()) {
4733 str_ = NULL;
4734 length_ = 0;
4735 } else {
4736 length_ = str->Length();
4737 str_ = i::NewArray<uint16_t>(length_ + 1);
4738 str->Write(str_);
4739 }
4740}
4741
4742
4743String::Value::~Value() {
4744 i::DeleteArray(str_);
4745}
4746
4747Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004748 i::Isolate* isolate = i::Isolate::Current();
4749 LOG_API(isolate, "RangeError");
4750 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
4751 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004752 i::Object* error;
4753 {
Steve Block44f0eee2011-05-26 01:26:41 +01004754 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004755 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004756 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004757 error = *result;
4758 }
4759 i::Handle<i::Object> result(error);
4760 return Utils::ToLocal(result);
4761}
4762
4763Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004764 i::Isolate* isolate = i::Isolate::Current();
4765 LOG_API(isolate, "ReferenceError");
4766 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
4767 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004768 i::Object* error;
4769 {
Steve Block44f0eee2011-05-26 01:26:41 +01004770 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004771 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004772 i::Handle<i::Object> result =
4773 isolate->factory()->NewReferenceError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004774 error = *result;
4775 }
4776 i::Handle<i::Object> result(error);
4777 return Utils::ToLocal(result);
4778}
4779
4780Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004781 i::Isolate* isolate = i::Isolate::Current();
4782 LOG_API(isolate, "SyntaxError");
4783 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
4784 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004785 i::Object* error;
4786 {
Steve Block44f0eee2011-05-26 01:26:41 +01004787 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004788 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004789 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004790 error = *result;
4791 }
4792 i::Handle<i::Object> result(error);
4793 return Utils::ToLocal(result);
4794}
4795
4796Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004797 i::Isolate* isolate = i::Isolate::Current();
4798 LOG_API(isolate, "TypeError");
4799 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
4800 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004801 i::Object* error;
4802 {
Steve Block44f0eee2011-05-26 01:26:41 +01004803 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004804 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004805 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004806 error = *result;
4807 }
4808 i::Handle<i::Object> result(error);
4809 return Utils::ToLocal(result);
4810}
4811
4812Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004813 i::Isolate* isolate = i::Isolate::Current();
4814 LOG_API(isolate, "Error");
4815 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
4816 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004817 i::Object* error;
4818 {
Steve Block44f0eee2011-05-26 01:26:41 +01004819 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004820 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004821 i::Handle<i::Object> result = isolate->factory()->NewError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004822 error = *result;
4823 }
4824 i::Handle<i::Object> result(error);
4825 return Utils::ToLocal(result);
4826}
4827
4828
4829// --- D e b u g S u p p o r t ---
4830
4831#ifdef ENABLE_DEBUGGER_SUPPORT
Leon Clarkef7060e22010-06-03 12:02:55 +01004832
Leon Clarkef7060e22010-06-03 12:02:55 +01004833static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
Steve Block44f0eee2011-05-26 01:26:41 +01004834 i::Isolate* isolate = i::Isolate::Current();
4835 if (isolate->debug_event_callback() != NULL) {
4836 isolate->debug_event_callback()(event_details.GetEvent(),
4837 event_details.GetExecutionState(),
4838 event_details.GetEventData(),
4839 event_details.GetCallbackData());
Leon Clarkef7060e22010-06-03 12:02:55 +01004840 }
4841}
4842
4843
Steve Blocka7e24c12009-10-30 11:49:00 +00004844bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004845 i::Isolate* isolate = i::Isolate::Current();
4846 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
4847 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
4848 ENTER_V8(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01004849
Steve Block44f0eee2011-05-26 01:26:41 +01004850 isolate->set_debug_event_callback(that);
Leon Clarkef7060e22010-06-03 12:02:55 +01004851
Steve Block44f0eee2011-05-26 01:26:41 +01004852 i::HandleScope scope(isolate);
4853 i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
Leon Clarkef7060e22010-06-03 12:02:55 +01004854 if (that != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01004855 proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(EventCallbackWrapper));
Leon Clarkef7060e22010-06-03 12:02:55 +01004856 }
Steve Block44f0eee2011-05-26 01:26:41 +01004857 isolate->debugger()->SetEventListener(proxy, Utils::OpenHandle(*data));
Leon Clarkef7060e22010-06-03 12:02:55 +01004858 return true;
4859}
4860
4861
4862bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004863 i::Isolate* isolate = i::Isolate::Current();
4864 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
4865 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
4866 ENTER_V8(isolate);
4867 i::HandleScope scope(isolate);
4868 i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00004869 if (that != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01004870 proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00004871 }
Steve Block44f0eee2011-05-26 01:26:41 +01004872 isolate->debugger()->SetEventListener(proxy,
4873 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00004874 return true;
4875}
4876
4877
4878bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
4879 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004880 i::Isolate* isolate = i::Isolate::Current();
4881 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
4882 ENTER_V8(isolate);
4883 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
4884 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00004885 return true;
4886}
4887
4888
Steve Block44f0eee2011-05-26 01:26:41 +01004889void Debug::DebugBreak(Isolate* isolate) {
4890 // If no isolate is supplied, use the default isolate.
4891 if (isolate != NULL) {
4892 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
4893 } else {
4894 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
4895 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004896}
4897
4898
Steve Block44f0eee2011-05-26 01:26:41 +01004899void Debug::CancelDebugBreak(Isolate* isolate) {
4900 // If no isolate is supplied, use the default isolate.
4901 if (isolate != NULL) {
4902 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4903 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
4904 } else {
4905 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
4906 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004907}
4908
4909
Steve Block44f0eee2011-05-26 01:26:41 +01004910void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
4911 // If no isolate is supplied, use the default isolate.
4912 if (isolate != NULL) {
4913 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4914 internal_isolate->debugger()->EnqueueDebugCommand(data);
4915 } else {
4916 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
4917 }
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004918}
4919
4920
Steve Blocka7e24c12009-10-30 11:49:00 +00004921static void MessageHandlerWrapper(const v8::Debug::Message& message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004922 i::Isolate* isolate = i::Isolate::Current();
4923 if (isolate->message_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004924 v8::String::Value json(message.GetJSON());
Steve Block44f0eee2011-05-26 01:26:41 +01004925 (isolate->message_handler())(*json, json.length(), message.GetClientData());
Steve Blocka7e24c12009-10-30 11:49:00 +00004926 }
4927}
4928
4929
4930void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
4931 bool message_handler_thread) {
Steve Block44f0eee2011-05-26 01:26:41 +01004932 i::Isolate* isolate = i::Isolate::Current();
4933 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
4934 ENTER_V8(isolate);
4935
Steve Blocka7e24c12009-10-30 11:49:00 +00004936 // Message handler thread not supported any more. Parameter temporally left in
Steve Block44f0eee2011-05-26 01:26:41 +01004937 // the API for client compatibility reasons.
Steve Blocka7e24c12009-10-30 11:49:00 +00004938 CHECK(!message_handler_thread);
4939
4940 // TODO(sgjesse) support the old message handler API through a simple wrapper.
Steve Block44f0eee2011-05-26 01:26:41 +01004941 isolate->set_message_handler(handler);
4942 if (handler != NULL) {
4943 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
Steve Blocka7e24c12009-10-30 11:49:00 +00004944 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004945 isolate->debugger()->SetMessageHandler(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00004946 }
4947}
4948
4949
4950void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01004951 i::Isolate* isolate = i::Isolate::Current();
4952 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
4953 ENTER_V8(isolate);
4954 isolate->debugger()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00004955}
4956
4957
4958void Debug::SendCommand(const uint16_t* command, int length,
Steve Block44f0eee2011-05-26 01:26:41 +01004959 ClientData* client_data,
4960 Isolate* isolate) {
4961 // If no isolate is supplied, use the default isolate.
4962 if (isolate != NULL) {
4963 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4964 internal_isolate->debugger()->ProcessCommand(
4965 i::Vector<const uint16_t>(command, length), client_data);
4966 } else {
4967 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
4968 i::Vector<const uint16_t>(command, length), client_data);
4969 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004970}
4971
4972
4973void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
4974 int period) {
Steve Block44f0eee2011-05-26 01:26:41 +01004975 i::Isolate* isolate = i::Isolate::Current();
4976 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
4977 ENTER_V8(isolate);
4978 isolate->debugger()->SetHostDispatchHandler(handler, period);
Steve Blocka7e24c12009-10-30 11:49:00 +00004979}
4980
4981
Steve Blockd0582a62009-12-15 09:54:21 +00004982void Debug::SetDebugMessageDispatchHandler(
Leon Clarkee46be812010-01-19 14:06:41 +00004983 DebugMessageDispatchHandler handler, bool provide_locker) {
Steve Block44f0eee2011-05-26 01:26:41 +01004984 i::Isolate* isolate = i::Isolate::Current();
4985 EnsureInitializedForIsolate(isolate,
4986 "v8::Debug::SetDebugMessageDispatchHandler");
4987 ENTER_V8(isolate);
4988 isolate->debugger()->SetDebugMessageDispatchHandler(
4989 handler, provide_locker);
Steve Blockd0582a62009-12-15 09:54:21 +00004990}
4991
4992
Steve Blocka7e24c12009-10-30 11:49:00 +00004993Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
4994 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004995 i::Isolate* isolate = i::Isolate::Current();
4996 if (!isolate->IsInitialized()) return Local<Value>();
4997 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
4998 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004999 i::Handle<i::Object> result;
Steve Block44f0eee2011-05-26 01:26:41 +01005000 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005001 if (data.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005002 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5003 isolate->factory()->undefined_value(),
5004 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005005 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005006 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5007 Utils::OpenHandle(*data),
5008 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005009 }
Steve Block44f0eee2011-05-26 01:26:41 +01005010 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005011 return Utils::ToLocal(result);
5012}
5013
5014
5015Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01005016 i::Isolate* isolate = i::Isolate::Current();
5017 if (!isolate->IsInitialized()) return Local<Value>();
5018 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
5019 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005020 v8::HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01005021 i::Debug* isolate_debug = isolate->debug();
5022 isolate_debug->Load();
5023 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5024 i::Handle<i::String> name =
5025 isolate->factory()->LookupAsciiSymbol("MakeMirror");
Steve Blocka7e24c12009-10-30 11:49:00 +00005026 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5027 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5028 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5029 const int kArgc = 1;
5030 v8::Handle<v8::Value> argv[kArgc] = { obj };
Steve Block44f0eee2011-05-26 01:26:41 +01005031 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005032 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5033 kArgc,
5034 argv);
Steve Block44f0eee2011-05-26 01:26:41 +01005035 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005036 return scope.Close(result);
5037}
5038
5039
Leon Clarkee46be812010-01-19 14:06:41 +00005040bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
Steve Block44f0eee2011-05-26 01:26:41 +01005041 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5042 wait_for_connection);
Steve Blocka7e24c12009-10-30 11:49:00 +00005043}
Leon Clarkee46be812010-01-19 14:06:41 +00005044
5045void Debug::ProcessDebugMessages() {
5046 i::Execution::ProcessDebugMesssages(true);
5047}
5048
Steve Block6ded16b2010-05-10 14:33:55 +01005049Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01005050 i::Isolate* isolate = i::Isolate::Current();
5051 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5052 ENTER_V8(isolate);
5053 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01005054}
5055
Steve Blocka7e24c12009-10-30 11:49:00 +00005056#endif // ENABLE_DEBUGGER_SUPPORT
5057
Steve Block6ded16b2010-05-10 14:33:55 +01005058
5059#ifdef ENABLE_LOGGING_AND_PROFILING
5060
5061Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005062 i::Isolate* isolate = i::Isolate::Current();
5063 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
Steve Block6ded16b2010-05-10 14:33:55 +01005064 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5065 const i::CodeEntry* entry = node->entry();
5066 if (!entry->has_name_prefix()) {
5067 return Handle<String>(ToApi<String>(
Steve Block44f0eee2011-05-26 01:26:41 +01005068 isolate->factory()->LookupAsciiSymbol(entry->name())));
Steve Block6ded16b2010-05-10 14:33:55 +01005069 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005070 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5071 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5072 isolate->factory()->LookupAsciiSymbol(entry->name()))));
Steve Block6ded16b2010-05-10 14:33:55 +01005073 }
5074}
5075
5076
5077Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005078 i::Isolate* isolate = i::Isolate::Current();
5079 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
Steve Block6ded16b2010-05-10 14:33:55 +01005080 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005081 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005082 node->entry()->resource_name())));
5083}
5084
5085
5086int CpuProfileNode::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005087 i::Isolate* isolate = i::Isolate::Current();
5088 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
Steve Block6ded16b2010-05-10 14:33:55 +01005089 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5090}
5091
5092
5093double CpuProfileNode::GetTotalTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005094 i::Isolate* isolate = i::Isolate::Current();
5095 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005096 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5097}
5098
5099
5100double CpuProfileNode::GetSelfTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005101 i::Isolate* isolate = i::Isolate::Current();
5102 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005103 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5104}
5105
5106
5107double CpuProfileNode::GetTotalSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005108 i::Isolate* isolate = i::Isolate::Current();
5109 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005110 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5111}
5112
5113
5114double CpuProfileNode::GetSelfSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005115 i::Isolate* isolate = i::Isolate::Current();
5116 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005117 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5118}
5119
5120
5121unsigned CpuProfileNode::GetCallUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005122 i::Isolate* isolate = i::Isolate::Current();
5123 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005124 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01005125}
5126
5127
5128int CpuProfileNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005129 i::Isolate* isolate = i::Isolate::Current();
5130 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005131 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5132}
5133
5134
5135const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005136 i::Isolate* isolate = i::Isolate::Current();
5137 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
Steve Block6ded16b2010-05-10 14:33:55 +01005138 const i::ProfileNode* child =
5139 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5140 return reinterpret_cast<const CpuProfileNode*>(child);
5141}
5142
5143
Steve Block44f0eee2011-05-26 01:26:41 +01005144void CpuProfile::Delete() {
5145 i::Isolate* isolate = i::Isolate::Current();
5146 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5147 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5148 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5149 !i::CpuProfiler::HasDetachedProfiles()) {
5150 // If this was the last profile, clean up all accessory data as well.
5151 i::CpuProfiler::DeleteAllProfiles();
5152 }
5153}
5154
5155
Steve Block6ded16b2010-05-10 14:33:55 +01005156unsigned CpuProfile::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005157 i::Isolate* isolate = i::Isolate::Current();
5158 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
Steve Block6ded16b2010-05-10 14:33:55 +01005159 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5160}
5161
5162
5163Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005164 i::Isolate* isolate = i::Isolate::Current();
5165 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
Steve Block6ded16b2010-05-10 14:33:55 +01005166 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005167 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005168 profile->title())));
5169}
5170
5171
5172const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005173 i::Isolate* isolate = i::Isolate::Current();
5174 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005175 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5176 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5177}
5178
5179
5180const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005181 i::Isolate* isolate = i::Isolate::Current();
5182 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005183 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5184 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5185}
5186
5187
5188int CpuProfiler::GetProfilesCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005189 i::Isolate* isolate = i::Isolate::Current();
5190 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005191 return i::CpuProfiler::GetProfilesCount();
5192}
5193
5194
Leon Clarkef7060e22010-06-03 12:02:55 +01005195const CpuProfile* CpuProfiler::GetProfile(int index,
5196 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005197 i::Isolate* isolate = i::Isolate::Current();
5198 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005199 return reinterpret_cast<const CpuProfile*>(
5200 i::CpuProfiler::GetProfile(
5201 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5202 index));
Steve Block6ded16b2010-05-10 14:33:55 +01005203}
5204
5205
Leon Clarkef7060e22010-06-03 12:02:55 +01005206const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5207 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005208 i::Isolate* isolate = i::Isolate::Current();
5209 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005210 return reinterpret_cast<const CpuProfile*>(
5211 i::CpuProfiler::FindProfile(
5212 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5213 uid));
Steve Block6ded16b2010-05-10 14:33:55 +01005214}
5215
5216
5217void CpuProfiler::StartProfiling(Handle<String> title) {
Steve Block44f0eee2011-05-26 01:26:41 +01005218 i::Isolate* isolate = i::Isolate::Current();
5219 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005220 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5221}
5222
5223
Leon Clarkef7060e22010-06-03 12:02:55 +01005224const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5225 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005226 i::Isolate* isolate = i::Isolate::Current();
5227 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005228 return reinterpret_cast<const CpuProfile*>(
Leon Clarkef7060e22010-06-03 12:02:55 +01005229 i::CpuProfiler::StopProfiling(
5230 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5231 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01005232}
5233
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005234
Steve Block44f0eee2011-05-26 01:26:41 +01005235void CpuProfiler::DeleteAllProfiles() {
5236 i::Isolate* isolate = i::Isolate::Current();
5237 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5238 i::CpuProfiler::DeleteAllProfiles();
5239}
5240
5241
Iain Merrick75681382010-08-19 15:07:18 +01005242static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5243 return const_cast<i::HeapGraphEdge*>(
5244 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5245}
5246
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005247HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005248 i::Isolate* isolate = i::Isolate::Current();
5249 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005250 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005251}
5252
5253
5254Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005255 i::Isolate* isolate = i::Isolate::Current();
5256 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
Iain Merrick75681382010-08-19 15:07:18 +01005257 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005258 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01005259 case i::HeapGraphEdge::kContextVariable:
5260 case i::HeapGraphEdge::kInternal:
5261 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005262 case i::HeapGraphEdge::kShortcut:
Steve Block44f0eee2011-05-26 01:26:41 +01005263 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005264 edge->name())));
Iain Merrick75681382010-08-19 15:07:18 +01005265 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005266 case i::HeapGraphEdge::kHidden:
Steve Block44f0eee2011-05-26 01:26:41 +01005267 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005268 edge->index())));
5269 default: UNREACHABLE();
5270 }
Steve Block44f0eee2011-05-26 01:26:41 +01005271 return v8::Undefined();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005272}
5273
5274
5275const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005276 i::Isolate* isolate = i::Isolate::Current();
5277 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
Iain Merrick75681382010-08-19 15:07:18 +01005278 const i::HeapEntry* from = ToInternal(this)->From();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005279 return reinterpret_cast<const HeapGraphNode*>(from);
5280}
5281
5282
5283const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005284 i::Isolate* isolate = i::Isolate::Current();
5285 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
Iain Merrick75681382010-08-19 15:07:18 +01005286 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005287 return reinterpret_cast<const HeapGraphNode*>(to);
5288}
5289
5290
Iain Merrick75681382010-08-19 15:07:18 +01005291static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5292 return const_cast<i::HeapEntry*>(
5293 reinterpret_cast<const i::HeapEntry*>(entry));
5294}
5295
5296
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005297HeapGraphNode::Type HeapGraphNode::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005298 i::Isolate* isolate = i::Isolate::Current();
5299 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005300 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005301}
5302
5303
5304Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005305 i::Isolate* isolate = i::Isolate::Current();
5306 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
5307 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005308 ToInternal(this)->name())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005309}
5310
5311
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005312uint64_t HeapGraphNode::GetId() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005313 i::Isolate* isolate = i::Isolate::Current();
5314 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
Steve Block791712a2010-08-27 10:21:07 +01005315 ASSERT(ToInternal(this)->snapshot()->type() != i::HeapSnapshot::kAggregated);
Iain Merrick75681382010-08-19 15:07:18 +01005316 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005317}
5318
5319
Steve Block791712a2010-08-27 10:21:07 +01005320int HeapGraphNode::GetInstancesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005321 i::Isolate* isolate = i::Isolate::Current();
5322 IsDeadCheck(isolate, "v8::HeapGraphNode::GetInstancesCount");
Steve Block791712a2010-08-27 10:21:07 +01005323 ASSERT(ToInternal(this)->snapshot()->type() == i::HeapSnapshot::kAggregated);
5324 return static_cast<int>(ToInternal(this)->id());
5325}
5326
5327
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005328int HeapGraphNode::GetSelfSize() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005329 i::Isolate* isolate = i::Isolate::Current();
5330 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
Iain Merrick75681382010-08-19 15:07:18 +01005331 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005332}
5333
5334
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005335int HeapGraphNode::GetRetainedSize(bool exact) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005336 i::Isolate* isolate = i::Isolate::Current();
5337 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005338 return ToInternal(this)->RetainedSize(exact);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005339}
5340
5341
5342int HeapGraphNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005343 i::Isolate* isolate = i::Isolate::Current();
5344 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
Iain Merrick75681382010-08-19 15:07:18 +01005345 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005346}
5347
5348
5349const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005350 i::Isolate* isolate = i::Isolate::Current();
5351 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005352 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005353 &ToInternal(this)->children()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005354}
5355
5356
5357int HeapGraphNode::GetRetainersCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005358 i::Isolate* isolate = i::Isolate::Current();
5359 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
Iain Merrick75681382010-08-19 15:07:18 +01005360 return ToInternal(this)->retainers().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005361}
5362
5363
5364const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005365 i::Isolate* isolate = i::Isolate::Current();
5366 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005367 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005368 ToInternal(this)->retainers()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005369}
5370
5371
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005372const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005373 i::Isolate* isolate = i::Isolate::Current();
5374 IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005375 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
5376}
5377
5378
Iain Merrick75681382010-08-19 15:07:18 +01005379static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5380 return const_cast<i::HeapSnapshot*>(
5381 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5382}
5383
5384
Steve Block44f0eee2011-05-26 01:26:41 +01005385void HeapSnapshot::Delete() {
5386 i::Isolate* isolate = i::Isolate::Current();
5387 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
5388 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
5389 ToInternal(this)->Delete();
5390 } else {
5391 // If this is the last snapshot, clean up all accessory data as well.
5392 i::HeapProfiler::DeleteAllSnapshots();
5393 }
5394}
5395
5396
Steve Block791712a2010-08-27 10:21:07 +01005397HeapSnapshot::Type HeapSnapshot::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005398 i::Isolate* isolate = i::Isolate::Current();
5399 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
Steve Block791712a2010-08-27 10:21:07 +01005400 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
5401}
5402
5403
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005404unsigned HeapSnapshot::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005405 i::Isolate* isolate = i::Isolate::Current();
5406 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
Iain Merrick75681382010-08-19 15:07:18 +01005407 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005408}
5409
5410
5411Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005412 i::Isolate* isolate = i::Isolate::Current();
5413 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
5414 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005415 ToInternal(this)->title())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005416}
5417
5418
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005419const HeapGraphNode* HeapSnapshot::GetRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005420 i::Isolate* isolate = i::Isolate::Current();
5421 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
Iain Merrick75681382010-08-19 15:07:18 +01005422 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005423}
5424
5425
Ben Murdochb0fe1622011-05-05 13:52:32 +01005426const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005427 i::Isolate* isolate = i::Isolate::Current();
5428 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
Ben Murdochb0fe1622011-05-05 13:52:32 +01005429 return reinterpret_cast<const HeapGraphNode*>(
5430 ToInternal(this)->GetEntryById(id));
5431}
5432
5433
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005434void HeapSnapshot::Serialize(OutputStream* stream,
5435 HeapSnapshot::SerializationFormat format) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005436 i::Isolate* isolate = i::Isolate::Current();
5437 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005438 ApiCheck(format == kJSON,
5439 "v8::HeapSnapshot::Serialize",
5440 "Unknown serialization format");
5441 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
5442 "v8::HeapSnapshot::Serialize",
5443 "Unsupported output encoding");
5444 ApiCheck(stream->GetChunkSize() > 0,
5445 "v8::HeapSnapshot::Serialize",
5446 "Invalid stream chunk size");
5447 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
5448 serializer.Serialize(stream);
5449}
5450
5451
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005452int HeapProfiler::GetSnapshotsCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005453 i::Isolate* isolate = i::Isolate::Current();
5454 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005455 return i::HeapProfiler::GetSnapshotsCount();
5456}
5457
5458
5459const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005460 i::Isolate* isolate = i::Isolate::Current();
5461 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005462 return reinterpret_cast<const HeapSnapshot*>(
5463 i::HeapProfiler::GetSnapshot(index));
5464}
5465
5466
5467const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
Steve Block44f0eee2011-05-26 01:26:41 +01005468 i::Isolate* isolate = i::Isolate::Current();
5469 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005470 return reinterpret_cast<const HeapSnapshot*>(
5471 i::HeapProfiler::FindSnapshot(uid));
5472}
5473
5474
Steve Block791712a2010-08-27 10:21:07 +01005475const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
Ben Murdochb0fe1622011-05-05 13:52:32 +01005476 HeapSnapshot::Type type,
5477 ActivityControl* control) {
Steve Block44f0eee2011-05-26 01:26:41 +01005478 i::Isolate* isolate = i::Isolate::Current();
5479 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
Steve Block791712a2010-08-27 10:21:07 +01005480 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
5481 switch (type) {
5482 case HeapSnapshot::kFull:
5483 internal_type = i::HeapSnapshot::kFull;
5484 break;
5485 case HeapSnapshot::kAggregated:
5486 internal_type = i::HeapSnapshot::kAggregated;
5487 break;
5488 default:
5489 UNREACHABLE();
5490 }
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005491 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb0fe1622011-05-05 13:52:32 +01005492 i::HeapProfiler::TakeSnapshot(
5493 *Utils::OpenHandle(*title), internal_type, control));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005494}
5495
Steve Block44f0eee2011-05-26 01:26:41 +01005496
5497void HeapProfiler::DeleteAllSnapshots() {
5498 i::Isolate* isolate = i::Isolate::Current();
5499 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5500 i::HeapProfiler::DeleteAllSnapshots();
5501}
5502
5503
5504void HeapProfiler::DefineWrapperClass(uint16_t class_id,
5505 WrapperInfoCallback callback) {
5506 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
5507 callback);
5508}
5509
Steve Block6ded16b2010-05-10 14:33:55 +01005510#endif // ENABLE_LOGGING_AND_PROFILING
5511
5512
Ben Murdochb0fe1622011-05-05 13:52:32 +01005513v8::Testing::StressType internal::Testing::stress_type_ =
5514 v8::Testing::kStressTypeOpt;
5515
5516
5517void Testing::SetStressRunType(Testing::StressType type) {
5518 internal::Testing::set_stress_type(type);
5519}
5520
5521int Testing::GetStressRuns() {
5522 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
5523#ifdef DEBUG
5524 // In debug mode the code runs much slower so stressing will only make two
5525 // runs.
5526 return 2;
5527#else
5528 return 5;
5529#endif
5530}
5531
5532
5533static void SetFlagsFromString(const char* flags) {
5534 V8::SetFlagsFromString(flags, i::StrLength(flags));
5535}
5536
5537
5538void Testing::PrepareStressRun(int run) {
5539 static const char* kLazyOptimizations =
5540 "--prepare-always-opt --nolimit-inlining "
5541 "--noalways-opt --noopt-eagerly";
5542 static const char* kEagerOptimizations = "--opt-eagerly";
5543 static const char* kForcedOptimizations = "--always-opt";
5544
5545 // If deoptimization stressed turn on frequent deoptimization. If no value
5546 // is spefified through --deopt-every-n-times use a default default value.
5547 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
5548 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
5549 internal::FLAG_deopt_every_n_times == 0) {
5550 SetFlagsFromString(kDeoptEvery13Times);
5551 }
5552
5553#ifdef DEBUG
5554 // As stressing in debug mode only make two runs skip the deopt stressing
5555 // here.
5556 if (run == GetStressRuns() - 1) {
5557 SetFlagsFromString(kForcedOptimizations);
5558 } else {
5559 SetFlagsFromString(kEagerOptimizations);
5560 SetFlagsFromString(kLazyOptimizations);
5561 }
5562#else
5563 if (run == GetStressRuns() - 1) {
5564 SetFlagsFromString(kForcedOptimizations);
5565 } else if (run == GetStressRuns() - 2) {
5566 SetFlagsFromString(kEagerOptimizations);
5567 } else {
5568 SetFlagsFromString(kLazyOptimizations);
5569 }
5570#endif
5571}
5572
5573
Steve Block44f0eee2011-05-26 01:26:41 +01005574void Testing::DeoptimizeAll() {
5575 internal::Deoptimizer::DeoptimizeAll();
Steve Blocka7e24c12009-10-30 11:49:00 +00005576}
5577
5578
Steve Block44f0eee2011-05-26 01:26:41 +01005579namespace internal {
5580
5581
Steve Blocka7e24c12009-10-30 11:49:00 +00005582void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01005583 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00005584}
5585
5586
5587char* HandleScopeImplementer::ArchiveThread(char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01005588 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00005589 v8::ImplementationUtilities::HandleScopeData* current =
Steve Block44f0eee2011-05-26 01:26:41 +01005590 isolate->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00005591 handle_scope_data_ = *current;
5592 memcpy(storage, this, sizeof(*this));
5593
5594 ResetAfterArchive();
5595 current->Initialize();
5596
5597 return storage + ArchiveSpacePerThread();
5598}
5599
5600
5601int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01005602 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00005603}
5604
5605
5606char* HandleScopeImplementer::RestoreThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005607 memcpy(this, storage, sizeof(*this));
Steve Block44f0eee2011-05-26 01:26:41 +01005608 *Isolate::Current()->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00005609 return storage + ArchiveSpacePerThread();
5610}
5611
5612
5613void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
5614 // Iterate over all handles in the blocks except for the last.
5615 for (int i = blocks()->length() - 2; i >= 0; --i) {
5616 Object** block = blocks()->at(i);
5617 v->VisitPointers(block, &block[kHandleBlockSize]);
5618 }
5619
5620 // Iterate over live handles in the last block (if any).
5621 if (!blocks()->is_empty()) {
5622 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
5623 }
5624
5625 if (!saved_contexts_.is_empty()) {
5626 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
5627 v->VisitPointers(start, start + saved_contexts_.length());
5628 }
5629}
5630
5631
5632void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
5633 v8::ImplementationUtilities::HandleScopeData* current =
Steve Block44f0eee2011-05-26 01:26:41 +01005634 Isolate::Current()->handle_scope_data();
5635 handle_scope_data_ = *current;
5636 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005637}
5638
5639
5640char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01005641 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00005642 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01005643 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005644 return storage + ArchiveSpacePerThread();
5645}
5646
5647} } // namespace v8::internal