blob: 2bfa598c38679ac8c5fab52af388224325f23f25 [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 Blockfa4227f2011-06-01 17:21:15 +0100859 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000860 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
861 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
862 i::FixedArray* types = i::FixedArray::cast(info->types());
863 for (int i = 0; i < types->length(); i++) {
864 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
865 return i + 1;
866 }
867 return 0;
868}
869
870
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100871#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
872 i::Handle<i::Object> proxy = FromCData(cdata); \
873 (obj)->setter(*proxy); \
874 } while (false)
875
876
Steve Blocka7e24c12009-10-30 11:49:00 +0000877void FunctionTemplate::SetCallHandler(InvocationCallback callback,
878 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100879 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
880 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
881 ENTER_V8(isolate);
882 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000883 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100884 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000885 i::Handle<i::CallHandlerInfo> obj =
886 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100887 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000888 if (data.IsEmpty()) data = v8::Undefined();
889 obj->set_data(*Utils::OpenHandle(*data));
890 Utils::OpenHandle(this)->set_call_code(*obj);
891}
892
893
Leon Clarkef7060e22010-06-03 12:02:55 +0100894static i::Handle<i::AccessorInfo> MakeAccessorInfo(
895 v8::Handle<String> name,
896 AccessorGetter getter,
897 AccessorSetter setter,
898 v8::Handle<Value> data,
899 v8::AccessControl settings,
900 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +0100901 i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
Leon Clarkef7060e22010-06-03 12:02:55 +0100902 ASSERT(getter != NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100903 SET_FIELD_WRAPPED(obj, set_getter, getter);
904 SET_FIELD_WRAPPED(obj, set_setter, setter);
Leon Clarkef7060e22010-06-03 12:02:55 +0100905 if (data.IsEmpty()) data = v8::Undefined();
906 obj->set_data(*Utils::OpenHandle(*data));
907 obj->set_name(*Utils::OpenHandle(*name));
908 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
909 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
910 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
911 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
912 return obj;
913}
914
915
Steve Blocka7e24c12009-10-30 11:49:00 +0000916void FunctionTemplate::AddInstancePropertyAccessor(
917 v8::Handle<String> name,
918 AccessorGetter getter,
919 AccessorSetter setter,
920 v8::Handle<Value> data,
921 v8::AccessControl settings,
922 v8::PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +0100923 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
924 if (IsDeadCheck(isolate,
925 "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000926 return;
927 }
Steve Block44f0eee2011-05-26 01:26:41 +0100928 ENTER_V8(isolate);
929 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000930
Leon Clarkef7060e22010-06-03 12:02:55 +0100931 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
932 getter, setter, data,
933 settings, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000934 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
935 if (list->IsUndefined()) {
936 list = NeanderArray().value();
937 Utils::OpenHandle(this)->set_property_accessors(*list);
938 }
939 NeanderArray array(list);
940 array.add(obj);
941}
942
943
944Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Steve Block44f0eee2011-05-26 01:26:41 +0100945 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
946 if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
Steve Blocka7e24c12009-10-30 11:49:00 +0000947 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
948 return Local<ObjectTemplate>();
Steve Block44f0eee2011-05-26 01:26:41 +0100949 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000950 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
951 Local<ObjectTemplate> templ =
952 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
953 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
954 }
955 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
956 Utils::OpenHandle(this)->instance_template()));
957 return Utils::ToLocal(result);
958}
959
960
961void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +0100962 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
963 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
964 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000965 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
966}
967
968
969void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100970 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
971 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
972 return;
973 }
974 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000975 Utils::OpenHandle(this)->set_hidden_prototype(value);
976}
977
978
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100979void FunctionTemplate::SetNamedInstancePropertyHandler(
Steve Blocka7e24c12009-10-30 11:49:00 +0000980 NamedPropertyGetter getter,
981 NamedPropertySetter setter,
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100982 NamedPropertyQuery query,
Steve Blocka7e24c12009-10-30 11:49:00 +0000983 NamedPropertyDeleter remover,
984 NamedPropertyEnumerator enumerator,
985 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100986 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
987 if (IsDeadCheck(isolate,
988 "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000989 return;
990 }
Steve Block44f0eee2011-05-26 01:26:41 +0100991 ENTER_V8(isolate);
992 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000993 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100994 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000995 i::Handle<i::InterceptorInfo> obj =
996 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100997
998 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
999 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1000 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1001 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1002 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1003
Steve Blocka7e24c12009-10-30 11:49:00 +00001004 if (data.IsEmpty()) data = v8::Undefined();
1005 obj->set_data(*Utils::OpenHandle(*data));
1006 Utils::OpenHandle(this)->set_named_property_handler(*obj);
1007}
1008
1009
1010void FunctionTemplate::SetIndexedInstancePropertyHandler(
1011 IndexedPropertyGetter getter,
1012 IndexedPropertySetter setter,
1013 IndexedPropertyQuery query,
1014 IndexedPropertyDeleter remover,
1015 IndexedPropertyEnumerator enumerator,
1016 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001017 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1018 if (IsDeadCheck(isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00001019 "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
1020 return;
1021 }
Steve Block44f0eee2011-05-26 01:26:41 +01001022 ENTER_V8(isolate);
1023 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001024 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001025 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001026 i::Handle<i::InterceptorInfo> obj =
1027 i::Handle<i::InterceptorInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001028
1029 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1030 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1031 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1032 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1033 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1034
Steve Blocka7e24c12009-10-30 11:49:00 +00001035 if (data.IsEmpty()) data = v8::Undefined();
1036 obj->set_data(*Utils::OpenHandle(*data));
1037 Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
1038}
1039
1040
1041void FunctionTemplate::SetInstanceCallAsFunctionHandler(
1042 InvocationCallback callback,
1043 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001044 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1045 if (IsDeadCheck(isolate,
1046 "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001047 return;
1048 }
Steve Block44f0eee2011-05-26 01:26:41 +01001049 ENTER_V8(isolate);
1050 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001051 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001052 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001053 i::Handle<i::CallHandlerInfo> obj =
1054 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001055 SET_FIELD_WRAPPED(obj, set_callback, callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00001056 if (data.IsEmpty()) data = v8::Undefined();
1057 obj->set_data(*Utils::OpenHandle(*data));
1058 Utils::OpenHandle(this)->set_instance_call_handler(*obj);
1059}
1060
1061
1062// --- O b j e c t T e m p l a t e ---
1063
1064
1065Local<ObjectTemplate> ObjectTemplate::New() {
1066 return New(Local<FunctionTemplate>());
1067}
1068
1069
1070Local<ObjectTemplate> ObjectTemplate::New(
1071 v8::Handle<FunctionTemplate> constructor) {
Steve Block44f0eee2011-05-26 01:26:41 +01001072 i::Isolate* isolate = i::Isolate::Current();
1073 if (IsDeadCheck(isolate, "v8::ObjectTemplate::New()")) {
1074 return Local<ObjectTemplate>();
1075 }
1076 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1077 LOG_API(isolate, "ObjectTemplate::New");
1078 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001079 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001080 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001081 i::Handle<i::ObjectTemplateInfo> obj =
1082 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1083 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1084 if (!constructor.IsEmpty())
1085 obj->set_constructor(*Utils::OpenHandle(*constructor));
1086 obj->set_internal_field_count(i::Smi::FromInt(0));
1087 return Utils::ToLocal(obj);
1088}
1089
1090
1091// Ensure that the object template has a constructor. If no
1092// constructor is available we create one.
1093static void EnsureConstructor(ObjectTemplate* object_template) {
1094 if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
1095 Local<FunctionTemplate> templ = FunctionTemplate::New();
1096 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1097 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1098 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1099 }
1100}
1101
1102
1103void ObjectTemplate::SetAccessor(v8::Handle<String> name,
1104 AccessorGetter getter,
1105 AccessorSetter setter,
1106 v8::Handle<Value> data,
1107 AccessControl settings,
1108 PropertyAttribute attribute) {
Steve Block44f0eee2011-05-26 01:26:41 +01001109 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1110 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
1111 ENTER_V8(isolate);
1112 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001113 EnsureConstructor(this);
1114 i::FunctionTemplateInfo* constructor =
1115 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1116 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1117 Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
1118 getter,
1119 setter,
1120 data,
1121 settings,
1122 attribute);
1123}
1124
1125
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001126void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
1127 NamedPropertySetter setter,
1128 NamedPropertyQuery query,
1129 NamedPropertyDeleter remover,
1130 NamedPropertyEnumerator enumerator,
1131 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001132 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1133 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
1134 return;
1135 }
1136 ENTER_V8(isolate);
1137 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001138 EnsureConstructor(this);
1139 i::FunctionTemplateInfo* constructor =
1140 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1141 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001142 Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
1143 setter,
1144 query,
1145 remover,
1146 enumerator,
1147 data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001148}
1149
1150
1151void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001152 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1153 if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
1154 ENTER_V8(isolate);
1155 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001156 EnsureConstructor(this);
1157 i::FunctionTemplateInfo* constructor =
1158 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1159 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1160 cons->set_undetectable(true);
1161}
1162
1163
1164void ObjectTemplate::SetAccessCheckCallbacks(
1165 NamedSecurityCallback named_callback,
1166 IndexedSecurityCallback indexed_callback,
1167 Handle<Value> data,
1168 bool turned_on_by_default) {
Steve Block44f0eee2011-05-26 01:26:41 +01001169 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1170 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
1171 return;
1172 }
1173 ENTER_V8(isolate);
1174 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001175 EnsureConstructor(this);
1176
1177 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001178 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001179 i::Handle<i::AccessCheckInfo> info =
1180 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001181
1182 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1183 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1184
Steve Blocka7e24c12009-10-30 11:49:00 +00001185 if (data.IsEmpty()) data = v8::Undefined();
1186 info->set_data(*Utils::OpenHandle(*data));
1187
1188 i::FunctionTemplateInfo* constructor =
1189 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1190 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1191 cons->set_access_check_info(*info);
1192 cons->set_needs_access_check(turned_on_by_default);
1193}
1194
1195
1196void ObjectTemplate::SetIndexedPropertyHandler(
1197 IndexedPropertyGetter getter,
1198 IndexedPropertySetter setter,
1199 IndexedPropertyQuery query,
1200 IndexedPropertyDeleter remover,
1201 IndexedPropertyEnumerator enumerator,
1202 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001203 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1204 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
1205 return;
1206 }
1207 ENTER_V8(isolate);
1208 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001209 EnsureConstructor(this);
1210 i::FunctionTemplateInfo* constructor =
1211 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1212 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1213 Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
1214 setter,
1215 query,
1216 remover,
1217 enumerator,
1218 data);
1219}
1220
1221
1222void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
1223 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001224 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1225 if (IsDeadCheck(isolate,
1226 "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
1227 return;
1228 }
1229 ENTER_V8(isolate);
1230 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001231 EnsureConstructor(this);
1232 i::FunctionTemplateInfo* constructor =
1233 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1234 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1235 Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
1236}
1237
1238
1239int ObjectTemplate::InternalFieldCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01001240 if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
1241 "v8::ObjectTemplate::InternalFieldCount()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001242 return 0;
1243 }
1244 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1245}
1246
1247
1248void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001249 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1250 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
1251 return;
1252 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001253 if (!ApiCheck(i::Smi::IsValid(value),
1254 "v8::ObjectTemplate::SetInternalFieldCount()",
1255 "Invalid internal field count")) {
1256 return;
1257 }
Steve Block44f0eee2011-05-26 01:26:41 +01001258 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001259 if (value > 0) {
1260 // The internal field count is set by the constructor function's
1261 // construct code, so we ensure that there is a constructor
1262 // function to do the setting.
1263 EnsureConstructor(this);
1264 }
1265 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1266}
1267
1268
1269// --- S c r i p t D a t a ---
1270
1271
1272ScriptData* ScriptData::PreCompile(const char* input, int length) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001273 i::Utf8ToUC16CharacterStream stream(
1274 reinterpret_cast<const unsigned char*>(input), length);
1275 return i::ParserApi::PreParse(&stream, NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00001276}
1277
1278
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001279ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1280 i::Handle<i::String> str = Utils::OpenHandle(*source);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001281 if (str->IsExternalTwoByteString()) {
1282 i::ExternalTwoByteStringUC16CharacterStream stream(
1283 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
1284 return i::ParserApi::PreParse(&stream, NULL);
1285 } else {
1286 i::GenericStringUC16CharacterStream stream(str, 0, str->length());
1287 return i::ParserApi::PreParse(&stream, NULL);
1288 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001289}
1290
1291
Leon Clarkef7060e22010-06-03 12:02:55 +01001292ScriptData* ScriptData::New(const char* data, int length) {
1293 // Return an empty ScriptData if the length is obviously invalid.
1294 if (length % sizeof(unsigned) != 0) {
Iain Merrick9ac36c92010-09-13 15:29:50 +01001295 return new i::ScriptDataImpl();
Leon Clarkef7060e22010-06-03 12:02:55 +01001296 }
1297
1298 // Copy the data to ensure it is properly aligned.
1299 int deserialized_data_length = length / sizeof(unsigned);
Iain Merrick9ac36c92010-09-13 15:29:50 +01001300 // If aligned, don't create a copy of the data.
1301 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1302 return new i::ScriptDataImpl(data, length);
1303 }
1304 // Copy the data to align it.
Leon Clarkef7060e22010-06-03 12:02:55 +01001305 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
Iain Merrick9ac36c92010-09-13 15:29:50 +01001306 i::MemCopy(deserialized_data, data, length);
Leon Clarkef7060e22010-06-03 12:02:55 +01001307
1308 return new i::ScriptDataImpl(
1309 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
Steve Blocka7e24c12009-10-30 11:49:00 +00001310}
1311
1312
1313// --- S c r i p t ---
1314
1315
1316Local<Script> Script::New(v8::Handle<String> source,
1317 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001318 v8::ScriptData* pre_data,
1319 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001320 i::Isolate* isolate = i::Isolate::Current();
1321 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1322 LOG_API(isolate, "Script::New");
1323 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001324 i::Handle<i::String> str = Utils::OpenHandle(*source);
1325 i::Handle<i::Object> name_obj;
1326 int line_offset = 0;
1327 int column_offset = 0;
1328 if (origin != NULL) {
1329 if (!origin->ResourceName().IsEmpty()) {
1330 name_obj = Utils::OpenHandle(*origin->ResourceName());
1331 }
1332 if (!origin->ResourceLineOffset().IsEmpty()) {
1333 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1334 }
1335 if (!origin->ResourceColumnOffset().IsEmpty()) {
1336 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
1337 }
1338 }
Steve Block44f0eee2011-05-26 01:26:41 +01001339 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001340 i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001341 // We assert that the pre-data is sane, even though we can actually
1342 // handle it if it turns out not to be in release mode.
Andrei Popescu402d9372010-02-26 13:31:12 +00001343 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
Steve Blocka7e24c12009-10-30 11:49:00 +00001344 // If the pre-data isn't sane we simply ignore it
Andrei Popescu402d9372010-02-26 13:31:12 +00001345 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1346 pre_data_impl = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001347 }
Steve Block6ded16b2010-05-10 14:33:55 +01001348 i::Handle<i::SharedFunctionInfo> result =
Andrei Popescu31002712010-02-23 13:46:05 +00001349 i::Compiler::Compile(str,
1350 name_obj,
1351 line_offset,
1352 column_offset,
1353 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001354 pre_data_impl,
1355 Utils::OpenHandle(*script_data),
Andrei Popescu31002712010-02-23 13:46:05 +00001356 i::NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001357 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01001358 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
Steve Block6ded16b2010-05-10 14:33:55 +01001359 return Local<Script>(ToApi<Script>(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00001360}
1361
1362
1363Local<Script> Script::New(v8::Handle<String> source,
1364 v8::Handle<Value> file_name) {
1365 ScriptOrigin origin(file_name);
1366 return New(source, &origin);
1367}
1368
1369
1370Local<Script> Script::Compile(v8::Handle<String> source,
1371 v8::ScriptOrigin* origin,
Andrei Popescu402d9372010-02-26 13:31:12 +00001372 v8::ScriptData* pre_data,
1373 v8::Handle<String> script_data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001374 i::Isolate* isolate = i::Isolate::Current();
1375 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1376 LOG_API(isolate, "Script::Compile");
1377 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00001378 Local<Script> generic = New(source, origin, pre_data, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001379 if (generic.IsEmpty())
1380 return generic;
Steve Block6ded16b2010-05-10 14:33:55 +01001381 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1382 i::Handle<i::SharedFunctionInfo> function =
1383 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
Steve Blocka7e24c12009-10-30 11:49:00 +00001384 i::Handle<i::JSFunction> result =
Steve Block44f0eee2011-05-26 01:26:41 +01001385 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1386 function,
1387 isolate->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001388 return Local<Script>(ToApi<Script>(result));
1389}
1390
1391
1392Local<Script> Script::Compile(v8::Handle<String> source,
Andrei Popescu402d9372010-02-26 13:31:12 +00001393 v8::Handle<Value> file_name,
1394 v8::Handle<String> script_data) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001395 ScriptOrigin origin(file_name);
Andrei Popescu402d9372010-02-26 13:31:12 +00001396 return Compile(source, &origin, 0, script_data);
Steve Blocka7e24c12009-10-30 11:49:00 +00001397}
1398
1399
1400Local<Value> Script::Run() {
Steve Block44f0eee2011-05-26 01:26:41 +01001401 i::Isolate* isolate = i::Isolate::Current();
1402 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1403 LOG_API(isolate, "Script::Run");
1404 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001405 i::Object* raw_result = NULL;
1406 {
Steve Block44f0eee2011-05-26 01:26:41 +01001407 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001408 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1409 i::Handle<i::JSFunction> fun;
1410 if (obj->IsSharedFunctionInfo()) {
1411 i::Handle<i::SharedFunctionInfo>
Steve Block44f0eee2011-05-26 01:26:41 +01001412 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
1413 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
1414 function_info, isolate->global_context());
Steve Block6ded16b2010-05-10 14:33:55 +01001415 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001416 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001417 }
Steve Block44f0eee2011-05-26 01:26:41 +01001418 EXCEPTION_PREAMBLE(isolate);
1419 i::Handle<i::Object> receiver(
1420 isolate->context()->global_proxy(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001421 i::Handle<i::Object> result =
1422 i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001423 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001424 raw_result = *result;
1425 }
Steve Block44f0eee2011-05-26 01:26:41 +01001426 i::Handle<i::Object> result(raw_result, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001427 return Utils::ToLocal(result);
1428}
1429
1430
Steve Block6ded16b2010-05-10 14:33:55 +01001431static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1432 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1433 i::Handle<i::SharedFunctionInfo> result;
1434 if (obj->IsSharedFunctionInfo()) {
1435 result =
1436 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1437 } else {
1438 result =
1439 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1440 }
1441 return result;
1442}
1443
1444
Steve Blocka7e24c12009-10-30 11:49:00 +00001445Local<Value> Script::Id() {
Steve Block44f0eee2011-05-26 01:26:41 +01001446 i::Isolate* isolate = i::Isolate::Current();
1447 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1448 LOG_API(isolate, "Script::Id");
Steve Blocka7e24c12009-10-30 11:49:00 +00001449 i::Object* raw_id = NULL;
1450 {
Steve Block44f0eee2011-05-26 01:26:41 +01001451 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001452 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1453 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001454 i::Handle<i::Object> id(script->id());
1455 raw_id = *id;
1456 }
1457 i::Handle<i::Object> id(raw_id);
1458 return Utils::ToLocal(id);
1459}
1460
1461
Steve Blockd0582a62009-12-15 09:54:21 +00001462void Script::SetData(v8::Handle<String> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001463 i::Isolate* isolate = i::Isolate::Current();
1464 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1465 LOG_API(isolate, "Script::SetData");
Steve Blocka7e24c12009-10-30 11:49:00 +00001466 {
Steve Block44f0eee2011-05-26 01:26:41 +01001467 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001468 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001469 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
Steve Block6ded16b2010-05-10 14:33:55 +01001470 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001471 script->set_data(*raw_data);
1472 }
1473}
1474
1475
1476// --- E x c e p t i o n s ---
1477
1478
1479v8::TryCatch::TryCatch()
Steve Block44f0eee2011-05-26 01:26:41 +01001480 : next_(i::Isolate::Current()->try_catch_handler_address()),
1481 exception_(HEAP->the_hole_value()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001482 message_(i::Smi::FromInt(0)),
1483 is_verbose_(false),
1484 can_continue_(true),
1485 capture_message_(true),
Steve Blockd0582a62009-12-15 09:54:21 +00001486 rethrow_(false) {
Steve Block44f0eee2011-05-26 01:26:41 +01001487 i::Isolate::Current()->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001488}
1489
1490
1491v8::TryCatch::~TryCatch() {
Steve Block44f0eee2011-05-26 01:26:41 +01001492 i::Isolate* isolate = i::Isolate::Current();
Steve Blockd0582a62009-12-15 09:54:21 +00001493 if (rethrow_) {
1494 v8::HandleScope scope;
1495 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
Steve Block44f0eee2011-05-26 01:26:41 +01001496 isolate->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001497 v8::ThrowException(exc);
1498 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01001499 isolate->UnregisterTryCatchHandler(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001500 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001501}
1502
1503
1504bool v8::TryCatch::HasCaught() const {
1505 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1506}
1507
1508
1509bool v8::TryCatch::CanContinue() const {
1510 return can_continue_;
1511}
1512
1513
Steve Blockd0582a62009-12-15 09:54:21 +00001514v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1515 if (!HasCaught()) return v8::Local<v8::Value>();
1516 rethrow_ = true;
1517 return v8::Undefined();
1518}
1519
1520
Steve Blocka7e24c12009-10-30 11:49:00 +00001521v8::Local<Value> v8::TryCatch::Exception() const {
1522 if (HasCaught()) {
1523 // Check for out of memory exception.
1524 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
1525 return v8::Utils::ToLocal(i::Handle<i::Object>(exception));
1526 } else {
1527 return v8::Local<Value>();
1528 }
1529}
1530
1531
1532v8::Local<Value> v8::TryCatch::StackTrace() const {
1533 if (HasCaught()) {
1534 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1535 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
1536 v8::HandleScope scope;
1537 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj));
Steve Block44f0eee2011-05-26 01:26:41 +01001538 i::Handle<i::String> name = FACTORY->LookupAsciiSymbol("stack");
Steve Blocka7e24c12009-10-30 11:49:00 +00001539 if (!obj->HasProperty(*name))
1540 return v8::Local<Value>();
1541 return scope.Close(v8::Utils::ToLocal(i::GetProperty(obj, name)));
1542 } else {
1543 return v8::Local<Value>();
1544 }
1545}
1546
1547
1548v8::Local<v8::Message> v8::TryCatch::Message() const {
1549 if (HasCaught() && message_ != i::Smi::FromInt(0)) {
1550 i::Object* message = reinterpret_cast<i::Object*>(message_);
1551 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
1552 } else {
1553 return v8::Local<v8::Message>();
1554 }
1555}
1556
1557
1558void v8::TryCatch::Reset() {
Steve Block44f0eee2011-05-26 01:26:41 +01001559 exception_ = HEAP->the_hole_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00001560 message_ = i::Smi::FromInt(0);
1561}
1562
1563
1564void v8::TryCatch::SetVerbose(bool value) {
1565 is_verbose_ = value;
1566}
1567
1568
1569void v8::TryCatch::SetCaptureMessage(bool value) {
1570 capture_message_ = value;
1571}
1572
1573
1574// --- M e s s a g e ---
1575
1576
1577Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001578 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1579 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
1580 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001581 HandleScope scope;
1582 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1583 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
1584 Local<String> result = Utils::ToLocal(raw_result);
1585 return scope.Close(result);
1586}
1587
1588
1589v8::Handle<Value> Message::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001590 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1591 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001592 return Local<String>();
1593 }
Steve Block44f0eee2011-05-26 01:26:41 +01001594 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001595 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001596 i::Handle<i::JSMessageObject> message =
1597 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001598 // Return this.script.name.
1599 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001600 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001601 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
1602 return scope.Close(Utils::ToLocal(resource_name));
1603}
1604
1605
1606v8::Handle<Value> Message::GetScriptData() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001607 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1608 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001609 return Local<Value>();
1610 }
Steve Block44f0eee2011-05-26 01:26:41 +01001611 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001612 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001613 i::Handle<i::JSMessageObject> message =
1614 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00001615 // Return this.script.data.
1616 i::Handle<i::JSValue> script =
Steve Block1e0659c2011-05-24 12:43:12 +01001617 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001618 i::Handle<i::Object> data(i::Script::cast(script->value())->data());
1619 return scope.Close(Utils::ToLocal(data));
1620}
1621
1622
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001623v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001624 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1625 if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001626 return Local<v8::StackTrace>();
1627 }
Steve Block44f0eee2011-05-26 01:26:41 +01001628 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001629 HandleScope scope;
Steve Block1e0659c2011-05-24 12:43:12 +01001630 i::Handle<i::JSMessageObject> message =
1631 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1632 i::Handle<i::Object> stackFramesObj(message->stack_frames());
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001633 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
1634 i::Handle<i::JSArray> stackTrace =
1635 i::Handle<i::JSArray>::cast(stackFramesObj);
1636 return scope.Close(Utils::StackTraceToLocal(stackTrace));
1637}
1638
1639
Steve Blocka7e24c12009-10-30 11:49:00 +00001640static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1641 i::Handle<i::Object> recv,
1642 int argc,
1643 i::Object** argv[],
1644 bool* has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +01001645 i::Isolate* isolate = i::Isolate::Current();
1646 i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name);
John Reck59135872010-11-02 12:39:01 -07001647 i::Object* object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001648 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
Steve Blocka7e24c12009-10-30 11:49:00 +00001649 i::Handle<i::JSFunction> fun =
1650 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
1651 i::Handle<i::Object> value =
1652 i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
1653 return value;
1654}
1655
1656
1657static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1658 i::Handle<i::Object> data,
1659 bool* has_pending_exception) {
1660 i::Object** argv[1] = { data.location() };
1661 return CallV8HeapFunction(name,
Steve Block44f0eee2011-05-26 01:26:41 +01001662 i::Isolate::Current()->js_builtins_object(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001663 1,
1664 argv,
1665 has_pending_exception);
1666}
1667
1668
1669int Message::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001670 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1671 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
1672 ENTER_V8(isolate);
1673 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001674
Steve Block44f0eee2011-05-26 01:26:41 +01001675 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001676 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
1677 Utils::OpenHandle(this),
1678 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001679 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001680 return static_cast<int>(result->Number());
1681}
1682
1683
1684int Message::GetStartPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001685 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1686 if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
1687 ENTER_V8(isolate);
1688 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001689 i::Handle<i::JSMessageObject> message =
1690 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1691 return message->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001692}
1693
1694
1695int Message::GetEndPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001696 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1697 if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
1698 ENTER_V8(isolate);
1699 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01001700 i::Handle<i::JSMessageObject> message =
1701 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1702 return message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001703}
1704
1705
1706int Message::GetStartColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001707 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1708 if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
1709 return kNoColumnInfo;
1710 }
1711 ENTER_V8(isolate);
1712 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001713 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001714 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001715 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1716 "GetPositionInLine",
1717 data_obj,
1718 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001719 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001720 return static_cast<int>(start_col_obj->Number());
1721}
1722
1723
1724int Message::GetEndColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001725 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1726 if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
1727 ENTER_V8(isolate);
1728 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001729 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001730 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001731 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1732 "GetPositionInLine",
1733 data_obj,
1734 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001735 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Block1e0659c2011-05-24 12:43:12 +01001736 i::Handle<i::JSMessageObject> message =
1737 i::Handle<i::JSMessageObject>::cast(data_obj);
1738 int start = message->start_position();
1739 int end = message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001740 return static_cast<int>(start_col_obj->Number()) + (end - start);
1741}
1742
1743
1744Local<String> Message::GetSourceLine() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001745 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1746 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
1747 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001748 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01001749 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001750 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
1751 Utils::OpenHandle(this),
1752 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01001753 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001754 if (result->IsString()) {
1755 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
1756 } else {
1757 return Local<String>();
1758 }
1759}
1760
1761
1762void Message::PrintCurrentStackTrace(FILE* out) {
Steve Block44f0eee2011-05-26 01:26:41 +01001763 i::Isolate* isolate = i::Isolate::Current();
1764 if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
1765 ENTER_V8(isolate);
1766 isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00001767}
1768
1769
Kristian Monsen25f61362010-05-21 11:50:48 +01001770// --- S t a c k T r a c e ---
1771
1772Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01001773 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1774 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
1775 return Local<StackFrame>();
1776 }
1777 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001778 HandleScope scope;
1779 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
John Reck59135872010-11-02 12:39:01 -07001780 i::Object* raw_object = self->GetElementNoExceptionThrown(index);
1781 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001782 return scope.Close(Utils::StackFrameToLocal(obj));
1783}
1784
1785
1786int StackTrace::GetFrameCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001787 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1788 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
1789 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001790 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
1791}
1792
1793
1794Local<Array> StackTrace::AsArray() {
Steve Block44f0eee2011-05-26 01:26:41 +01001795 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1796 if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
1797 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001798 return Utils::ToLocal(Utils::OpenHandle(this));
1799}
1800
1801
1802Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
1803 StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01001804 i::Isolate* isolate = i::Isolate::Current();
1805 if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
1806 Local<StackTrace>();
1807 }
1808 ENTER_V8(isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001809 i::Handle<i::JSArray> stackTrace =
Steve Block44f0eee2011-05-26 01:26:41 +01001810 isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001811 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01001812}
1813
1814
1815// --- S t a c k F r a m e ---
1816
1817int StackFrame::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001818 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1819 if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001820 return Message::kNoLineNumberInfo;
1821 }
Steve Block44f0eee2011-05-26 01:26:41 +01001822 ENTER_V8(isolate);
1823 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001824 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1825 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
1826 if (!line->IsSmi()) {
1827 return Message::kNoLineNumberInfo;
1828 }
1829 return i::Smi::cast(*line)->value();
1830}
1831
1832
1833int StackFrame::GetColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001834 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1835 if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
Kristian Monsen25f61362010-05-21 11:50:48 +01001836 return Message::kNoColumnInfo;
1837 }
Steve Block44f0eee2011-05-26 01:26:41 +01001838 ENTER_V8(isolate);
1839 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001840 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1841 i::Handle<i::Object> column = GetProperty(self, "column");
1842 if (!column->IsSmi()) {
1843 return Message::kNoColumnInfo;
1844 }
1845 return i::Smi::cast(*column)->value();
1846}
1847
1848
1849Local<String> StackFrame::GetScriptName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001850 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1851 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
1852 return Local<String>();
1853 }
1854 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001855 HandleScope scope;
1856 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1857 i::Handle<i::Object> name = GetProperty(self, "scriptName");
1858 if (!name->IsString()) {
1859 return Local<String>();
1860 }
1861 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1862}
1863
1864
Ben Murdochf87a2032010-10-22 12:50:53 +01001865Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001866 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1867 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
Ben Murdochf87a2032010-10-22 12:50:53 +01001868 return Local<String>();
1869 }
Steve Block44f0eee2011-05-26 01:26:41 +01001870 ENTER_V8(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01001871 HandleScope scope;
1872 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1873 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
1874 if (!name->IsString()) {
1875 return Local<String>();
1876 }
1877 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1878}
1879
1880
Kristian Monsen25f61362010-05-21 11:50:48 +01001881Local<String> StackFrame::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001882 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1883 if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
1884 return Local<String>();
1885 }
1886 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001887 HandleScope scope;
1888 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1889 i::Handle<i::Object> name = GetProperty(self, "functionName");
1890 if (!name->IsString()) {
1891 return Local<String>();
1892 }
1893 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
1894}
1895
1896
1897bool StackFrame::IsEval() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001898 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1899 if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
1900 ENTER_V8(isolate);
1901 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001902 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1903 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
1904 return is_eval->IsTrue();
1905}
1906
1907
1908bool StackFrame::IsConstructor() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001909 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1910 if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
1911 ENTER_V8(isolate);
1912 i::HandleScope scope(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01001913 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
1914 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
1915 return is_constructor->IsTrue();
1916}
1917
1918
Steve Blocka7e24c12009-10-30 11:49:00 +00001919// --- D a t a ---
1920
1921bool Value::IsUndefined() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001922 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
1923 return false;
1924 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001925 return Utils::OpenHandle(this)->IsUndefined();
1926}
1927
1928
1929bool Value::IsNull() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001930 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001931 return Utils::OpenHandle(this)->IsNull();
1932}
1933
1934
1935bool Value::IsTrue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001936 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001937 return Utils::OpenHandle(this)->IsTrue();
1938}
1939
1940
1941bool Value::IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001942 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001943 return Utils::OpenHandle(this)->IsFalse();
1944}
1945
1946
1947bool Value::IsFunction() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001948 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFunction()")) {
1949 return false;
1950 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001951 return Utils::OpenHandle(this)->IsJSFunction();
1952}
1953
1954
1955bool Value::FullIsString() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001956 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsString()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001957 bool result = Utils::OpenHandle(this)->IsString();
1958 ASSERT_EQ(result, QuickIsString());
1959 return result;
1960}
1961
1962
1963bool Value::IsArray() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001964 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001965 return Utils::OpenHandle(this)->IsJSArray();
1966}
1967
1968
1969bool Value::IsObject() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001970 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001971 return Utils::OpenHandle(this)->IsJSObject();
1972}
1973
1974
1975bool Value::IsNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001976 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001977 return Utils::OpenHandle(this)->IsNumber();
1978}
1979
1980
1981bool Value::IsBoolean() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001982 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsBoolean()")) {
1983 return false;
1984 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001985 return Utils::OpenHandle(this)->IsBoolean();
1986}
1987
1988
1989bool Value::IsExternal() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001990 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
1991 return false;
1992 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001993 return Utils::OpenHandle(this)->IsProxy();
1994}
1995
1996
1997bool Value::IsInt32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001998 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001999 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2000 if (obj->IsSmi()) return true;
2001 if (obj->IsNumber()) {
2002 double value = obj->Number();
2003 return i::FastI2D(i::FastD2I(value)) == value;
2004 }
2005 return false;
2006}
2007
2008
Steve Block6ded16b2010-05-10 14:33:55 +01002009bool Value::IsUint32() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002010 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUint32()")) return false;
Steve Block6ded16b2010-05-10 14:33:55 +01002011 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2012 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2013 if (obj->IsNumber()) {
2014 double value = obj->Number();
2015 return i::FastUI2D(i::FastD2UI(value)) == value;
2016 }
2017 return false;
2018}
2019
2020
Steve Blocka7e24c12009-10-30 11:49:00 +00002021bool Value::IsDate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002022 i::Isolate* isolate = i::Isolate::Current();
2023 if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002024 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002025 return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00002026}
2027
2028
Iain Merrick75681382010-08-19 15:07:18 +01002029bool Value::IsRegExp() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002030 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
Iain Merrick75681382010-08-19 15:07:18 +01002031 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2032 return obj->IsJSRegExp();
2033}
2034
2035
Steve Blocka7e24c12009-10-30 11:49:00 +00002036Local<String> Value::ToString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002037 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2038 i::Handle<i::Object> str;
2039 if (obj->IsString()) {
2040 str = obj;
2041 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002042 i::Isolate* isolate = i::Isolate::Current();
2043 if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
2044 return Local<String>();
2045 }
2046 LOG_API(isolate, "ToString");
2047 ENTER_V8(isolate);
2048 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002049 str = i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002050 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002051 }
2052 return Local<String>(ToApi<String>(str));
2053}
2054
2055
2056Local<String> Value::ToDetailString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002057 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2058 i::Handle<i::Object> str;
2059 if (obj->IsString()) {
2060 str = obj;
2061 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002062 i::Isolate* isolate = i::Isolate::Current();
2063 if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
2064 return Local<String>();
2065 }
2066 LOG_API(isolate, "ToDetailString");
2067 ENTER_V8(isolate);
2068 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002069 str = i::Execution::ToDetailString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002070 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002071 }
2072 return Local<String>(ToApi<String>(str));
2073}
2074
2075
2076Local<v8::Object> Value::ToObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002077 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2078 i::Handle<i::Object> val;
2079 if (obj->IsJSObject()) {
2080 val = obj;
2081 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002082 i::Isolate* isolate = i::Isolate::Current();
2083 if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
2084 return Local<v8::Object>();
2085 }
2086 LOG_API(isolate, "ToObject");
2087 ENTER_V8(isolate);
2088 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002089 val = i::Execution::ToObject(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002090 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002091 }
2092 return Local<v8::Object>(ToApi<Object>(val));
2093}
2094
2095
2096Local<Boolean> Value::ToBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002097 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2098 if (obj->IsBoolean()) {
2099 return Local<Boolean>(ToApi<Boolean>(obj));
2100 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002101 i::Isolate* isolate = i::Isolate::Current();
2102 if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
2103 return Local<Boolean>();
2104 }
2105 LOG_API(isolate, "ToBoolean");
2106 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002107 i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
2108 return Local<Boolean>(ToApi<Boolean>(val));
2109 }
2110}
2111
2112
2113Local<Number> Value::ToNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002114 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2115 i::Handle<i::Object> num;
2116 if (obj->IsNumber()) {
2117 num = obj;
2118 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002119 i::Isolate* isolate = i::Isolate::Current();
2120 if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
2121 return Local<Number>();
2122 }
2123 LOG_API(isolate, "ToNumber");
2124 ENTER_V8(isolate);
2125 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002126 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002127 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002128 }
2129 return Local<Number>(ToApi<Number>(num));
2130}
2131
2132
2133Local<Integer> Value::ToInteger() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002134 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2135 i::Handle<i::Object> num;
2136 if (obj->IsSmi()) {
2137 num = obj;
2138 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002139 i::Isolate* isolate = i::Isolate::Current();
2140 if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
2141 LOG_API(isolate, "ToInteger");
2142 ENTER_V8(isolate);
2143 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002144 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002145 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002146 }
2147 return Local<Integer>(ToApi<Integer>(num));
2148}
2149
2150
2151void External::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002152 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002153 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2154 ApiCheck(obj->IsProxy(),
2155 "v8::External::Cast()",
2156 "Could not convert to external");
2157}
2158
2159
2160void v8::Object::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002161 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002162 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2163 ApiCheck(obj->IsJSObject(),
2164 "v8::Object::Cast()",
2165 "Could not convert to object");
2166}
2167
2168
2169void v8::Function::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002170 if (IsDeadCheck(i::Isolate::Current(), "v8::Function::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002171 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2172 ApiCheck(obj->IsJSFunction(),
2173 "v8::Function::Cast()",
2174 "Could not convert to function");
2175}
2176
2177
2178void v8::String::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002179 if (IsDeadCheck(i::Isolate::Current(), "v8::String::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002180 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2181 ApiCheck(obj->IsString(),
2182 "v8::String::Cast()",
2183 "Could not convert to string");
2184}
2185
2186
2187void v8::Number::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002188 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002189 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2190 ApiCheck(obj->IsNumber(),
2191 "v8::Number::Cast()",
2192 "Could not convert to number");
2193}
2194
2195
2196void v8::Integer::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002197 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002198 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2199 ApiCheck(obj->IsNumber(),
2200 "v8::Integer::Cast()",
2201 "Could not convert to number");
2202}
2203
2204
2205void v8::Array::CheckCast(Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002206 if (IsDeadCheck(i::Isolate::Current(), "v8::Array::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002207 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2208 ApiCheck(obj->IsJSArray(),
2209 "v8::Array::Cast()",
2210 "Could not convert to array");
2211}
2212
2213
2214void v8::Date::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002215 i::Isolate* isolate = i::Isolate::Current();
2216 if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002217 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Steve Block44f0eee2011-05-26 01:26:41 +01002218 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
Steve Blocka7e24c12009-10-30 11:49:00 +00002219 "v8::Date::Cast()",
2220 "Could not convert to date");
2221}
2222
2223
Ben Murdochf87a2032010-10-22 12:50:53 +01002224void v8::RegExp::CheckCast(v8::Value* that) {
Steve Block44f0eee2011-05-26 01:26:41 +01002225 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
Ben Murdochf87a2032010-10-22 12:50:53 +01002226 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2227 ApiCheck(obj->IsJSRegExp(),
2228 "v8::RegExp::Cast()",
2229 "Could not convert to regular expression");
2230}
2231
2232
Steve Blocka7e24c12009-10-30 11:49:00 +00002233bool Value::BooleanValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002234 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2235 if (obj->IsBoolean()) {
2236 return obj->IsTrue();
2237 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002238 i::Isolate* isolate = i::Isolate::Current();
2239 if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
2240 LOG_API(isolate, "BooleanValue");
2241 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002242 i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
2243 return value->IsTrue();
2244 }
2245}
2246
2247
2248double Value::NumberValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002249 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2250 i::Handle<i::Object> num;
2251 if (obj->IsNumber()) {
2252 num = obj;
2253 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002254 i::Isolate* isolate = i::Isolate::Current();
2255 if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
2256 return i::OS::nan_value();
2257 }
2258 LOG_API(isolate, "NumberValue");
2259 ENTER_V8(isolate);
2260 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002261 num = i::Execution::ToNumber(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002262 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002263 }
2264 return num->Number();
2265}
2266
2267
2268int64_t Value::IntegerValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002269 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2270 i::Handle<i::Object> num;
2271 if (obj->IsNumber()) {
2272 num = obj;
2273 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002274 i::Isolate* isolate = i::Isolate::Current();
2275 if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
2276 LOG_API(isolate, "IntegerValue");
2277 ENTER_V8(isolate);
2278 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002279 num = i::Execution::ToInteger(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002280 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002281 }
2282 if (num->IsSmi()) {
2283 return i::Smi::cast(*num)->value();
2284 } else {
2285 return static_cast<int64_t>(num->Number());
2286 }
2287}
2288
2289
2290Local<Int32> Value::ToInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002291 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2292 i::Handle<i::Object> num;
2293 if (obj->IsSmi()) {
2294 num = obj;
2295 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002296 i::Isolate* isolate = i::Isolate::Current();
2297 if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
2298 LOG_API(isolate, "ToInt32");
2299 ENTER_V8(isolate);
2300 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002301 num = i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002302 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002303 }
2304 return Local<Int32>(ToApi<Int32>(num));
2305}
2306
2307
2308Local<Uint32> Value::ToUint32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002309 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2310 i::Handle<i::Object> num;
2311 if (obj->IsSmi()) {
2312 num = obj;
2313 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002314 i::Isolate* isolate = i::Isolate::Current();
2315 if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
2316 LOG_API(isolate, "ToUInt32");
2317 ENTER_V8(isolate);
2318 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002319 num = i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002320 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002321 }
2322 return Local<Uint32>(ToApi<Uint32>(num));
2323}
2324
2325
2326Local<Uint32> Value::ToArrayIndex() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002327 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2328 if (obj->IsSmi()) {
2329 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2330 return Local<Uint32>();
2331 }
Steve Block44f0eee2011-05-26 01:26:41 +01002332 i::Isolate* isolate = i::Isolate::Current();
2333 if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
2334 LOG_API(isolate, "ToArrayIndex");
2335 ENTER_V8(isolate);
2336 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002337 i::Handle<i::Object> string_obj =
2338 i::Execution::ToString(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002339 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002340 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2341 uint32_t index;
2342 if (str->AsArrayIndex(&index)) {
2343 i::Handle<i::Object> value;
2344 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
2345 value = i::Handle<i::Object>(i::Smi::FromInt(index));
2346 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002347 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002348 }
2349 return Utils::Uint32ToLocal(value);
2350 }
2351 return Local<Uint32>();
2352}
2353
2354
2355int32_t Value::Int32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002356 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2357 if (obj->IsSmi()) {
2358 return i::Smi::cast(*obj)->value();
2359 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002360 i::Isolate* isolate = i::Isolate::Current();
2361 if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
2362 LOG_API(isolate, "Int32Value (slow)");
2363 ENTER_V8(isolate);
2364 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002365 i::Handle<i::Object> num =
2366 i::Execution::ToInt32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002367 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002368 if (num->IsSmi()) {
2369 return i::Smi::cast(*num)->value();
2370 } else {
2371 return static_cast<int32_t>(num->Number());
2372 }
2373 }
2374}
2375
2376
2377bool Value::Equals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002378 i::Isolate* isolate = i::Isolate::Current();
2379 if (IsDeadCheck(isolate, "v8::Value::Equals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002380 || EmptyCheck("v8::Value::Equals()", this)
2381 || EmptyCheck("v8::Value::Equals()", that)) {
2382 return false;
2383 }
Steve Block44f0eee2011-05-26 01:26:41 +01002384 LOG_API(isolate, "Equals");
2385 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002386 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2387 i::Handle<i::Object> other = Utils::OpenHandle(*that);
Steve Block1e0659c2011-05-24 12:43:12 +01002388 // If both obj and other are JSObjects, we'd better compare by identity
2389 // immediately when going into JS builtin. The reason is Invoke
2390 // would overwrite global object receiver with global proxy.
2391 if (obj->IsJSObject() && other->IsJSObject()) {
2392 return *obj == *other;
2393 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002394 i::Object** args[1] = { other.location() };
Steve Block44f0eee2011-05-26 01:26:41 +01002395 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002396 i::Handle<i::Object> result =
2397 CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002398 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002399 return *result == i::Smi::FromInt(i::EQUAL);
2400}
2401
2402
2403bool Value::StrictEquals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002404 i::Isolate* isolate = i::Isolate::Current();
2405 if (IsDeadCheck(isolate, "v8::Value::StrictEquals()")
Steve Blocka7e24c12009-10-30 11:49:00 +00002406 || EmptyCheck("v8::Value::StrictEquals()", this)
2407 || EmptyCheck("v8::Value::StrictEquals()", that)) {
2408 return false;
2409 }
Steve Block44f0eee2011-05-26 01:26:41 +01002410 LOG_API(isolate, "StrictEquals");
Steve Blocka7e24c12009-10-30 11:49:00 +00002411 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2412 i::Handle<i::Object> other = Utils::OpenHandle(*that);
2413 // Must check HeapNumber first, since NaN !== NaN.
2414 if (obj->IsHeapNumber()) {
2415 if (!other->IsNumber()) return false;
2416 double x = obj->Number();
2417 double y = other->Number();
2418 // Must check explicitly for NaN:s on Windows, but -0 works fine.
2419 return x == y && !isnan(x) && !isnan(y);
2420 } else if (*obj == *other) { // Also covers Booleans.
2421 return true;
2422 } else if (obj->IsSmi()) {
2423 return other->IsNumber() && obj->Number() == other->Number();
2424 } else if (obj->IsString()) {
2425 return other->IsString() &&
2426 i::String::cast(*obj)->Equals(i::String::cast(*other));
2427 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
2428 return other->IsUndefined() || other->IsUndetectableObject();
2429 } else {
2430 return false;
2431 }
2432}
2433
2434
2435uint32_t Value::Uint32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002436 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2437 if (obj->IsSmi()) {
2438 return i::Smi::cast(*obj)->value();
2439 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002440 i::Isolate* isolate = i::Isolate::Current();
2441 if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
2442 LOG_API(isolate, "Uint32Value");
2443 ENTER_V8(isolate);
2444 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002445 i::Handle<i::Object> num =
2446 i::Execution::ToUint32(obj, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01002447 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002448 if (num->IsSmi()) {
2449 return i::Smi::cast(*num)->value();
2450 } else {
2451 return static_cast<uint32_t>(num->Number());
2452 }
2453 }
2454}
2455
2456
2457bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
2458 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002459 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2460 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2461 ENTER_V8(isolate);
2462 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002463 i::Handle<i::Object> self = Utils::OpenHandle(this);
2464 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2465 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002466 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002467 i::Handle<i::Object> obj = i::SetProperty(
2468 self,
2469 key_obj,
2470 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002471 static_cast<PropertyAttributes>(attribs),
2472 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002473 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002474 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002475 return true;
2476}
2477
2478
Steve Block6ded16b2010-05-10 14:33:55 +01002479bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002480 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2481 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
2482 ENTER_V8(isolate);
2483 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002484 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2485 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002486 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002487 i::Handle<i::Object> obj = i::SetElement(
2488 self,
2489 index,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002490 value_obj,
2491 i::kNonStrictMode);
Steve Block6ded16b2010-05-10 14:33:55 +01002492 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002493 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Block6ded16b2010-05-10 14:33:55 +01002494 return true;
2495}
2496
2497
Steve Blocka7e24c12009-10-30 11:49:00 +00002498bool v8::Object::ForceSet(v8::Handle<Value> key,
2499 v8::Handle<Value> value,
2500 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01002501 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2502 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
2503 ENTER_V8(isolate);
2504 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002505 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2506 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2507 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002508 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002509 i::Handle<i::Object> obj = i::ForceSetProperty(
2510 self,
2511 key_obj,
2512 value_obj,
2513 static_cast<PropertyAttributes>(attribs));
2514 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002515 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002516 return true;
2517}
2518
2519
2520bool v8::Object::ForceDelete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002521 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2522 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
2523 ENTER_V8(isolate);
2524 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002525 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2526 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002527
2528 // When turning on access checks for a global object deoptimize all functions
2529 // as optimized code does not always handle access checks.
2530 i::Deoptimizer::DeoptimizeGlobalObject(*self);
2531
Steve Block44f0eee2011-05-26 01:26:41 +01002532 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002533 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
2534 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002535 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002536 return obj->IsTrue();
2537}
2538
2539
2540Local<Value> v8::Object::Get(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002541 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2542 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2543 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002544 i::Handle<i::Object> self = Utils::OpenHandle(this);
2545 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002546 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002547 i::Handle<i::Object> result = i::GetProperty(self, key_obj);
2548 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002549 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002550 return Utils::ToLocal(result);
2551}
2552
2553
Steve Block6ded16b2010-05-10 14:33:55 +01002554Local<Value> v8::Object::Get(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002555 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2556 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
2557 ENTER_V8(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002558 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002559 EXCEPTION_PREAMBLE(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002560 i::Handle<i::Object> result = i::GetElement(self, index);
2561 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002562 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Block6ded16b2010-05-10 14:33:55 +01002563 return Utils::ToLocal(result);
2564}
2565
2566
Steve Blocka7e24c12009-10-30 11:49:00 +00002567Local<Value> v8::Object::GetPrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01002568 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2569 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
2570 return Local<v8::Value>());
2571 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002572 i::Handle<i::Object> self = Utils::OpenHandle(this);
2573 i::Handle<i::Object> result = i::GetPrototype(self);
2574 return Utils::ToLocal(result);
2575}
2576
2577
Andrei Popescu402d9372010-02-26 13:31:12 +00002578bool v8::Object::SetPrototype(Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002579 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2580 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
2581 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002582 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2583 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002584 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002585 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2586 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002587 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00002588 return true;
2589}
2590
2591
Steve Blocka7e24c12009-10-30 11:49:00 +00002592Local<Object> v8::Object::FindInstanceInPrototypeChain(
2593 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01002594 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2595 ON_BAILOUT(isolate,
2596 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002597 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01002598 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002599 i::JSObject* object = *Utils::OpenHandle(this);
2600 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2601 while (!object->IsInstanceOf(tmpl_info)) {
2602 i::Object* prototype = object->GetPrototype();
2603 if (!prototype->IsJSObject()) return Local<Object>();
2604 object = i::JSObject::cast(prototype);
2605 }
2606 return Utils::ToLocal(i::Handle<i::JSObject>(object));
2607}
2608
2609
2610Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01002611 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2612 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
2613 return Local<v8::Array>());
2614 ENTER_V8(isolate);
2615 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002616 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2617 i::Handle<i::FixedArray> value =
2618 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
2619 // Because we use caching to speed up enumeration it is important
2620 // to never change the result of the basic enumeration function so
2621 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01002622 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2623 i::Handle<i::JSArray> result =
2624 isolate->factory()->NewJSArrayWithElements(elms);
2625 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00002626}
2627
2628
2629Local<String> v8::Object::ObjectProtoToString() {
Steve Block44f0eee2011-05-26 01:26:41 +01002630 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2631 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
2632 return Local<v8::String>());
2633 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002634 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2635
2636 i::Handle<i::Object> name(self->class_name());
2637
2638 // Native implementation of Object.prototype.toString (v8natives.js):
2639 // var c = %ClassOf(this);
2640 // if (c === 'Arguments') c = 'Object';
2641 // return "[object " + c + "]";
2642
2643 if (!name->IsString()) {
2644 return v8::String::New("[object ]");
2645
2646 } else {
2647 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
2648 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
2649 return v8::String::New("[object Object]");
2650
2651 } else {
2652 const char* prefix = "[object ";
2653 Local<String> str = Utils::ToLocal(class_name);
2654 const char* postfix = "]";
2655
Steve Blockd0582a62009-12-15 09:54:21 +00002656 int prefix_len = i::StrLength(prefix);
2657 int str_len = str->Length();
2658 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00002659
Steve Blockd0582a62009-12-15 09:54:21 +00002660 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01002661 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002662
2663 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01002664 char* ptr = buf.start();
Steve Blocka7e24c12009-10-30 11:49:00 +00002665 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
2666 ptr += prefix_len;
2667
2668 // Write real content.
2669 str->WriteAscii(ptr, 0, str_len);
2670 ptr += str_len;
2671
2672 // Write postfix.
2673 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
2674
2675 // Copy the buffer into a heap-allocated string and return it.
Kristian Monsen25f61362010-05-21 11:50:48 +01002676 Local<String> result = v8::String::New(buf.start(), buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002677 return result;
2678 }
2679 }
2680}
2681
2682
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002683Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01002684 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2685 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
2686 return Local<v8::String>());
2687 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002688 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2689 i::Handle<i::String> name(self->constructor_name());
2690 return Utils::ToLocal(name);
2691}
2692
2693
Steve Blocka7e24c12009-10-30 11:49:00 +00002694bool v8::Object::Delete(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002695 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2696 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
2697 ENTER_V8(isolate);
2698 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002699 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2700 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2701 return i::DeleteProperty(self, key_obj)->IsTrue();
2702}
2703
2704
2705bool v8::Object::Has(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002706 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2707 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
2708 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002709 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2710 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2711 return self->HasProperty(*key_obj);
2712}
2713
2714
2715bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002716 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2717 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
2718 return false);
2719 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002720 HandleScope scope;
2721 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2722 return i::DeleteElement(self, index)->IsTrue();
2723}
2724
2725
2726bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002727 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2728 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002729 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2730 return self->HasElement(index);
2731}
2732
2733
Leon Clarkef7060e22010-06-03 12:02:55 +01002734bool Object::SetAccessor(Handle<String> name,
2735 AccessorGetter getter,
2736 AccessorSetter setter,
2737 v8::Handle<Value> data,
2738 AccessControl settings,
2739 PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01002740 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2741 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
2742 ENTER_V8(isolate);
2743 i::HandleScope scope(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01002744 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
2745 getter, setter, data,
2746 settings, attributes);
2747 i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
2748 return !result.is_null() && !result->IsUndefined();
2749}
2750
2751
Steve Blocka7e24c12009-10-30 11:49:00 +00002752bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002753 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2754 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
2755 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002756 return Utils::OpenHandle(this)->HasRealNamedProperty(
2757 *Utils::OpenHandle(*key));
2758}
2759
2760
2761bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002762 ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
2763 "v8::Object::HasRealIndexedProperty()",
2764 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002765 return Utils::OpenHandle(this)->HasRealElementProperty(index);
2766}
2767
2768
2769bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002770 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2771 ON_BAILOUT(isolate,
2772 "v8::Object::HasRealNamedCallbackProperty()",
2773 return false);
2774 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002775 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
2776 *Utils::OpenHandle(*key));
2777}
2778
2779
2780bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002781 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2782 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
2783 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002784 return Utils::OpenHandle(this)->HasNamedInterceptor();
2785}
2786
2787
2788bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002789 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2790 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
2791 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002792 return Utils::OpenHandle(this)->HasIndexedInterceptor();
2793}
2794
2795
2796Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
2797 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002798 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2799 ON_BAILOUT(isolate,
2800 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002801 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01002802 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002803 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2804 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2805 i::LookupResult lookup;
2806 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00002807 if (lookup.IsProperty()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002808 PropertyAttributes attributes;
John Reck59135872010-11-02 12:39:01 -07002809 i::Object* property =
2810 self_obj->GetProperty(*self_obj,
2811 &lookup,
2812 *key_obj,
2813 &attributes)->ToObjectUnchecked();
2814 i::Handle<i::Object> result(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00002815 return Utils::ToLocal(result);
2816 }
2817 return Local<Value>(); // No real property was found in prototype chain.
2818}
2819
2820
2821Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002822 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2823 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
2824 return Local<Value>());
2825 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002826 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2827 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2828 i::LookupResult lookup;
2829 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00002830 if (lookup.IsProperty()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002831 PropertyAttributes attributes;
John Reck59135872010-11-02 12:39:01 -07002832 i::Object* property =
2833 self_obj->GetProperty(*self_obj,
2834 &lookup,
2835 *key_obj,
2836 &attributes)->ToObjectUnchecked();
2837 i::Handle<i::Object> result(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00002838 return Utils::ToLocal(result);
2839 }
2840 return Local<Value>(); // No real property was found in prototype chain.
2841}
2842
2843
2844// Turns on access checks by copying the map and setting the check flag.
2845// Because the object gets a new map, existing inline cache caching
2846// the old map of this object will fail.
2847void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01002848 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2849 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
2850 ENTER_V8(isolate);
2851 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002852 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
2853
Ben Murdochb0fe1622011-05-05 13:52:32 +01002854 // When turning on access checks for a global object deoptimize all functions
2855 // as optimized code does not always handle access checks.
2856 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
2857
Steve Blocka7e24c12009-10-30 11:49:00 +00002858 i::Handle<i::Map> new_map =
Steve Block44f0eee2011-05-26 01:26:41 +01002859 isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002860 new_map->set_is_access_check_needed(true);
2861 obj->set_map(*new_map);
2862}
2863
2864
2865bool v8::Object::IsDirty() {
2866 return Utils::OpenHandle(this)->IsDirty();
2867}
2868
2869
2870Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01002871 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2872 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
2873 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002874 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002875 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002876 i::Handle<i::JSObject> result = i::Copy(self);
2877 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002878 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002879 return Utils::ToLocal(result);
2880}
2881
2882
2883int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01002884 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2885 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
2886 ENTER_V8(isolate);
2887 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002888 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block1e0659c2011-05-24 12:43:12 +01002889 i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true));
2890 if (!hidden_props_obj->IsJSObject()) {
2891 // We failed to create hidden properties. That's a detached
2892 // global proxy.
2893 ASSERT(hidden_props_obj->IsUndefined());
2894 return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00002895 }
Steve Block1e0659c2011-05-24 12:43:12 +01002896 i::Handle<i::JSObject> hidden_props =
2897 i::Handle<i::JSObject>::cast(hidden_props_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002898 i::Handle<i::String> hash_symbol = isolate->factory()->identity_hash_symbol();
Steve Block1e0659c2011-05-24 12:43:12 +01002899 if (hidden_props->HasLocalProperty(*hash_symbol)) {
2900 i::Handle<i::Object> hash = i::GetProperty(hidden_props, hash_symbol);
2901 CHECK(!hash.is_null());
2902 CHECK(hash->IsSmi());
2903 return i::Smi::cast(*hash)->value();
2904 }
2905
2906 int hash_value;
2907 int attempts = 0;
2908 do {
2909 // Generate a random 32-bit hash value but limit range to fit
2910 // within a smi.
Steve Block44f0eee2011-05-26 01:26:41 +01002911 hash_value = i::V8::Random(self->GetIsolate()) & i::Smi::kMaxValue;
Steve Block1e0659c2011-05-24 12:43:12 +01002912 attempts++;
2913 } while (hash_value == 0 && attempts < 30);
2914 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
2915 CHECK(!i::SetLocalPropertyIgnoreAttributes(
2916 hidden_props,
2917 hash_symbol,
2918 i::Handle<i::Object>(i::Smi::FromInt(hash_value)),
2919 static_cast<PropertyAttributes>(None)).is_null());
2920
Steve Blocka7e24c12009-10-30 11:49:00 +00002921 return hash_value;
2922}
2923
2924
2925bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
2926 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002927 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2928 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
2929 ENTER_V8(isolate);
2930 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002931 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2932 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true));
2933 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2934 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002935 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002936 i::Handle<i::Object> obj = i::SetProperty(
2937 hidden_props,
2938 key_obj,
2939 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002940 static_cast<PropertyAttributes>(None),
2941 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002942 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002943 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002944 return true;
2945}
2946
2947
2948v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002949 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2950 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
2951 return Local<v8::Value>());
2952 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002953 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2954 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
2955 if (hidden_props->IsUndefined()) {
2956 return v8::Local<v8::Value>();
2957 }
2958 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002959 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002960 i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
2961 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002962 EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002963 if (result->IsUndefined()) {
2964 return v8::Local<v8::Value>();
2965 }
2966 return Utils::ToLocal(result);
2967}
2968
2969
2970bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002971 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2972 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
2973 ENTER_V8(isolate);
2974 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002975 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2976 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
2977 if (hidden_props->IsUndefined()) {
2978 return true;
2979 }
2980 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
2981 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2982 return i::DeleteProperty(js_obj, key_obj)->IsTrue();
2983}
2984
2985
Steve Block44f0eee2011-05-26 01:26:41 +01002986namespace {
2987
2988void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
2989 void* data,
2990 ExternalArrayType array_type,
2991 int length) {
2992 i::Isolate* isolate = object->GetIsolate();
2993 i::Handle<i::ExternalArray> array =
2994 isolate->factory()->NewExternalArray(length, array_type, data);
2995
2996 // If the object already has external elements, create a new, unique
2997 // map if the element type is now changing, because assumptions about
2998 // generated code based on the receiver's map will be invalid.
2999 i::Handle<i::HeapObject> elements(object->elements());
3000 bool cant_reuse_map =
3001 elements->map()->IsUndefined() ||
3002 !elements->map()->has_external_array_elements() ||
3003 elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
3004 if (cant_reuse_map) {
3005 i::Handle<i::Map> external_array_map =
3006 isolate->factory()->GetExternalArrayElementsMap(
3007 i::Handle<i::Map>(object->map()),
3008 array_type,
3009 object->HasFastProperties());
3010 object->set_map(*external_array_map);
3011 }
3012 object->set_elements(*array);
3013}
3014
3015} // namespace
3016
3017
Steve Blocka7e24c12009-10-30 11:49:00 +00003018void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003019 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3020 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3021 ENTER_V8(isolate);
3022 i::HandleScope scope(isolate);
3023 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
Steve Blocka7e24c12009-10-30 11:49:00 +00003024 "v8::Object::SetIndexedPropertiesToPixelData()",
3025 "length exceeds max acceptable value")) {
3026 return;
3027 }
3028 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3029 if (!ApiCheck(!self->IsJSArray(),
3030 "v8::Object::SetIndexedPropertiesToPixelData()",
3031 "JSArray is not supported")) {
3032 return;
3033 }
Steve Block44f0eee2011-05-26 01:26:41 +01003034 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003035}
3036
3037
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003038bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003039 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003040 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3041 return false);
3042 return self->HasExternalPixelElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003043}
3044
3045
3046uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003047 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003048 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3049 return NULL);
3050 if (self->HasExternalPixelElements()) {
3051 return i::ExternalPixelArray::cast(self->elements())->
3052 external_pixel_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003053 } else {
3054 return NULL;
3055 }
3056}
3057
3058
3059int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003060 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003061 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3062 return -1);
3063 if (self->HasExternalPixelElements()) {
3064 return i::ExternalPixelArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003065 } else {
3066 return -1;
3067 }
3068}
3069
Steve Block3ce2e202009-11-05 08:53:23 +00003070void v8::Object::SetIndexedPropertiesToExternalArrayData(
3071 void* data,
3072 ExternalArrayType array_type,
3073 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003074 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3075 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3076 ENTER_V8(isolate);
3077 i::HandleScope scope(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003078 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3079 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3080 "length exceeds max acceptable value")) {
3081 return;
3082 }
3083 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3084 if (!ApiCheck(!self->IsJSArray(),
3085 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3086 "JSArray is not supported")) {
3087 return;
3088 }
Steve Block44f0eee2011-05-26 01:26:41 +01003089 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003090}
3091
3092
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003093bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003094 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003095 ON_BAILOUT(self->GetIsolate(),
3096 "v8::HasIndexedPropertiesInExternalArrayData()",
3097 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003098 return self->HasExternalArrayElements();
3099}
3100
3101
3102void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003103 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003104 ON_BAILOUT(self->GetIsolate(),
3105 "v8::GetIndexedPropertiesExternalArrayData()",
3106 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003107 if (self->HasExternalArrayElements()) {
3108 return i::ExternalArray::cast(self->elements())->external_pointer();
3109 } else {
3110 return NULL;
3111 }
3112}
3113
3114
3115ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003116 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003117 ON_BAILOUT(self->GetIsolate(),
3118 "v8::GetIndexedPropertiesExternalArrayDataType()",
3119 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003120 switch (self->elements()->map()->instance_type()) {
3121 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3122 return kExternalByteArray;
3123 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3124 return kExternalUnsignedByteArray;
3125 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3126 return kExternalShortArray;
3127 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3128 return kExternalUnsignedShortArray;
3129 case i::EXTERNAL_INT_ARRAY_TYPE:
3130 return kExternalIntArray;
3131 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3132 return kExternalUnsignedIntArray;
3133 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3134 return kExternalFloatArray;
Steve Block44f0eee2011-05-26 01:26:41 +01003135 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3136 return kExternalPixelArray;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003137 default:
3138 return static_cast<ExternalArrayType>(-1);
3139 }
3140}
3141
3142
3143int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003144 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003145 ON_BAILOUT(self->GetIsolate(),
3146 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3147 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003148 if (self->HasExternalArrayElements()) {
3149 return i::ExternalArray::cast(self->elements())->length();
3150 } else {
3151 return -1;
3152 }
3153}
3154
3155
Steve Blocka7e24c12009-10-30 11:49:00 +00003156Local<v8::Object> Function::NewInstance() const {
3157 return NewInstance(0, NULL);
3158}
3159
3160
3161Local<v8::Object> Function::NewInstance(int argc,
3162 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003163 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3164 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3165 return Local<v8::Object>());
3166 LOG_API(isolate, "Function::NewInstance");
3167 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003168 HandleScope scope;
3169 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3170 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3171 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003172 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003173 i::Handle<i::Object> returned =
3174 i::Execution::New(function, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003175 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003176 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3177}
3178
3179
3180Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3181 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01003182 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3183 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3184 LOG_API(isolate, "Function::Call");
3185 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003186 i::Object* raw_result = NULL;
3187 {
Steve Block44f0eee2011-05-26 01:26:41 +01003188 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003189 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3190 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3191 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3192 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003193 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003194 i::Handle<i::Object> returned =
3195 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003196 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003197 raw_result = *returned;
3198 }
3199 i::Handle<i::Object> result(raw_result);
3200 return Utils::ToLocal(result);
3201}
3202
3203
3204void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01003205 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3206 ENTER_V8(isolate);
Steve Blockfa4227f2011-06-01 17:21:15 +01003207 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003208 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3209 func->shared()->set_name(*Utils::OpenHandle(*name));
3210}
3211
3212
3213Handle<Value> Function::GetName() const {
3214 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3215 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3216}
3217
3218
Andrei Popescu402d9372010-02-26 13:31:12 +00003219ScriptOrigin Function::GetScriptOrigin() const {
3220 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3221 if (func->shared()->script()->IsScript()) {
3222 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3223 v8::ScriptOrigin origin(
3224 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3225 v8::Integer::New(script->line_offset()->value()),
3226 v8::Integer::New(script->column_offset()->value()));
3227 return origin;
3228 }
3229 return v8::ScriptOrigin(Handle<Value>());
3230}
3231
3232
3233const int Function::kLineOffsetNotFound = -1;
3234
3235
3236int Function::GetScriptLineNumber() const {
3237 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3238 if (func->shared()->script()->IsScript()) {
3239 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3240 return i::GetScriptLineNumber(script, func->shared()->start_position());
3241 }
3242 return kLineOffsetNotFound;
3243}
3244
3245
Steve Blocka7e24c12009-10-30 11:49:00 +00003246int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003247 i::Handle<i::String> str = Utils::OpenHandle(this);
3248 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3249 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003250}
3251
3252
3253int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003254 i::Handle<i::String> str = Utils::OpenHandle(this);
3255 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
3256 return str->Utf8Length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003257}
3258
3259
Steve Block6ded16b2010-05-10 14:33:55 +01003260int String::WriteUtf8(char* buffer,
3261 int capacity,
3262 int* nchars_ref,
3263 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003264 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3265 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3266 LOG_API(isolate, "String::WriteUtf8");
3267 ENTER_V8(isolate);
3268 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003269 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003270 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003271 if (hints & HINT_MANY_WRITES_EXPECTED) {
3272 // Flatten the string for efficiency. This applies whether we are
3273 // using StringInputBuffer or Get(i) to access the characters.
3274 str->TryFlatten();
3275 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003276 write_input_buffer.Reset(0, *str);
3277 int len = str->length();
3278 // Encode the first K - 3 bytes directly into the buffer since we
3279 // know there's room for them. If no capacity is given we copy all
3280 // of them here.
3281 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3282 int i;
3283 int pos = 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003284 int nchars = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003285 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3286 i::uc32 c = write_input_buffer.GetNext();
3287 int written = unibrow::Utf8::Encode(buffer + pos, c);
3288 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003289 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003290 }
3291 if (i < len) {
3292 // For the last characters we need to check the length for each one
3293 // because they may be longer than the remaining space in the
3294 // buffer.
3295 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3296 for (; i < len && pos < capacity; i++) {
3297 i::uc32 c = write_input_buffer.GetNext();
3298 int written = unibrow::Utf8::Encode(intermediate, c);
3299 if (pos + written <= capacity) {
3300 for (int j = 0; j < written; j++)
3301 buffer[pos + j] = intermediate[j];
3302 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003303 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003304 } else {
3305 // We've reached the end of the buffer
3306 break;
3307 }
3308 }
3309 }
Steve Block6ded16b2010-05-10 14:33:55 +01003310 if (nchars_ref != NULL) *nchars_ref = nchars;
Steve Blocka7e24c12009-10-30 11:49:00 +00003311 if (i == len && (capacity == -1 || pos < capacity))
3312 buffer[pos++] = '\0';
3313 return pos;
3314}
3315
3316
Steve Block6ded16b2010-05-10 14:33:55 +01003317int String::WriteAscii(char* buffer,
3318 int start,
3319 int length,
3320 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003321 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3322 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3323 LOG_API(isolate, "String::WriteAscii");
3324 ENTER_V8(isolate);
3325 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003326 ASSERT(start >= 0 && length >= -1);
3327 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003328 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003329 if (hints & HINT_MANY_WRITES_EXPECTED) {
3330 // Flatten the string for efficiency. This applies whether we are
3331 // using StringInputBuffer or Get(i) to access the characters.
3332 str->TryFlatten();
3333 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003334 int end = length;
3335 if ( (length == -1) || (length > str->length() - start) )
3336 end = str->length() - start;
3337 if (end < 0) return 0;
3338 write_input_buffer.Reset(start, *str);
3339 int i;
3340 for (i = 0; i < end; i++) {
3341 char c = static_cast<char>(write_input_buffer.GetNext());
3342 if (c == '\0') c = ' ';
3343 buffer[i] = c;
3344 }
3345 if (length == -1 || i < length)
3346 buffer[i] = '\0';
3347 return i;
3348}
3349
3350
Steve Block6ded16b2010-05-10 14:33:55 +01003351int String::Write(uint16_t* buffer,
3352 int start,
3353 int length,
3354 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003355 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3356 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
3357 LOG_API(isolate, "String::Write");
3358 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003359 ASSERT(start >= 0 && length >= -1);
3360 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003361 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003362 if (hints & HINT_MANY_WRITES_EXPECTED) {
3363 // Flatten the string for efficiency. This applies whether we are
3364 // using StringInputBuffer or Get(i) to access the characters.
3365 str->TryFlatten();
3366 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003367 int end = start + length;
3368 if ((length == -1) || (length > str->length() - start) )
3369 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003370 if (end < 0) return 0;
3371 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003372 if (length == -1 || end - start < length) {
3373 buffer[end - start] = '\0';
3374 }
3375 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003376}
3377
3378
3379bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003380 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003381 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
3382 return false;
3383 }
3384 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
Steve Blocka7e24c12009-10-30 11:49:00 +00003385 return i::StringShape(*str).IsExternalTwoByte();
3386}
3387
3388
3389bool v8::String::IsExternalAscii() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003390 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003391 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
3392 return false;
3393 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003394 return i::StringShape(*str).IsExternalAscii();
3395}
3396
3397
3398void v8::String::VerifyExternalStringResource(
3399 v8::String::ExternalStringResource* value) const {
3400 i::Handle<i::String> str = Utils::OpenHandle(this);
3401 v8::String::ExternalStringResource* expected;
3402 if (i::StringShape(*str).IsExternalTwoByte()) {
3403 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
3404 expected = reinterpret_cast<ExternalStringResource*>(resource);
3405 } else {
3406 expected = NULL;
3407 }
3408 CHECK_EQ(expected, value);
3409}
3410
3411
3412v8::String::ExternalAsciiStringResource*
3413 v8::String::GetExternalAsciiStringResource() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003414 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003415 if (IsDeadCheck(str->GetIsolate(),
3416 "v8::String::GetExternalAsciiStringResource()")) {
3417 return NULL;
3418 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003419 if (i::StringShape(*str).IsExternalAscii()) {
3420 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
3421 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
3422 } else {
3423 return NULL;
3424 }
3425}
3426
3427
3428double Number::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003429 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003430 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3431 return obj->Number();
3432}
3433
3434
3435bool Boolean::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003436 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003437 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3438 return obj->IsTrue();
3439}
3440
3441
3442int64_t Integer::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003443 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003444 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3445 if (obj->IsSmi()) {
3446 return i::Smi::cast(*obj)->value();
3447 } else {
3448 return static_cast<int64_t>(obj->Number());
3449 }
3450}
3451
3452
3453int32_t Int32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003454 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003455 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3456 if (obj->IsSmi()) {
3457 return i::Smi::cast(*obj)->value();
3458 } else {
3459 return static_cast<int32_t>(obj->Number());
3460 }
3461}
3462
3463
Steve Block6ded16b2010-05-10 14:33:55 +01003464uint32_t Uint32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003465 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003466 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3467 if (obj->IsSmi()) {
3468 return i::Smi::cast(*obj)->value();
3469 } else {
3470 return static_cast<uint32_t>(obj->Number());
3471 }
3472}
3473
3474
Steve Blocka7e24c12009-10-30 11:49:00 +00003475int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003476 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003477 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
3478 return 0;
3479 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003480 return obj->GetInternalFieldCount();
3481}
3482
3483
3484Local<Value> v8::Object::CheckedGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003485 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003486 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
3487 return Local<Value>();
3488 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003489 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3490 "v8::Object::GetInternalField()",
3491 "Reading internal field out of bounds")) {
3492 return Local<Value>();
3493 }
3494 i::Handle<i::Object> value(obj->GetInternalField(index));
3495 Local<Value> result = Utils::ToLocal(value);
3496#ifdef DEBUG
3497 Local<Value> unchecked = UncheckedGetInternalField(index);
3498 ASSERT(unchecked.IsEmpty() || (unchecked == result));
3499#endif
3500 return result;
3501}
3502
3503
3504void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003505 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003506 i::Isolate* isolate = obj->GetIsolate();
3507 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
3508 return;
3509 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003510 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3511 "v8::Object::SetInternalField()",
3512 "Writing internal field out of bounds")) {
3513 return;
3514 }
Steve Block44f0eee2011-05-26 01:26:41 +01003515 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003516 i::Handle<i::Object> val = Utils::OpenHandle(*value);
3517 obj->SetInternalField(index, *val);
3518}
3519
3520
Ben Murdochb8e0da22011-05-16 14:20:40 +01003521static bool CanBeEncodedAsSmi(void* ptr) {
Steve Block1e0659c2011-05-24 12:43:12 +01003522 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003523 return ((address & i::kEncodablePointerMask) == 0);
3524}
3525
3526
3527static i::Smi* EncodeAsSmi(void* ptr) {
3528 ASSERT(CanBeEncodedAsSmi(ptr));
Steve Block1e0659c2011-05-24 12:43:12 +01003529 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003530 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
3531 ASSERT(i::Internals::HasSmiTag(result));
3532 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
3533 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
3534 return result;
3535}
3536
3537
Steve Blocka7e24c12009-10-30 11:49:00 +00003538void v8::Object::SetPointerInInternalField(int index, void* value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003539 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3540 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003541 if (CanBeEncodedAsSmi(value)) {
3542 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
3543 } else {
3544 HandleScope scope;
3545 i::Handle<i::Proxy> proxy =
Steve Block44f0eee2011-05-26 01:26:41 +01003546 isolate->factory()->NewProxy(
3547 reinterpret_cast<i::Address>(value), i::TENURED);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003548 if (!proxy.is_null())
3549 Utils::OpenHandle(this)->SetInternalField(index, *proxy);
Steve Block3ce2e202009-11-05 08:53:23 +00003550 }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003551 ASSERT_EQ(value, GetPointerFromInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003552}
3553
3554
3555// --- E n v i r o n m e n t ---
3556
Steve Block44f0eee2011-05-26 01:26:41 +01003557
Steve Blocka7e24c12009-10-30 11:49:00 +00003558bool v8::V8::Initialize() {
Steve Block44f0eee2011-05-26 01:26:41 +01003559 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
3560 if (isolate != NULL && isolate->IsInitialized()) {
3561 return true;
3562 }
3563 return InitializeHelper();
Steve Blocka7e24c12009-10-30 11:49:00 +00003564}
3565
3566
3567bool v8::V8::Dispose() {
Steve Block44f0eee2011-05-26 01:26:41 +01003568 i::Isolate* isolate = i::Isolate::Current();
3569 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
3570 "v8::V8::Dispose()",
3571 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
3572 return false;
3573 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003574 i::V8::TearDown();
3575 return true;
3576}
3577
3578
Russell Brenner90bac252010-11-18 13:33:46 -08003579HeapStatistics::HeapStatistics(): total_heap_size_(0),
3580 total_heap_size_executable_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01003581 used_heap_size_(0),
3582 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00003583
3584
3585void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
Steve Block44f0eee2011-05-26 01:26:41 +01003586 i::Heap* heap = i::Isolate::Current()->heap();
3587 heap_statistics->set_total_heap_size(heap->CommittedMemory());
Russell Brenner90bac252010-11-18 13:33:46 -08003588 heap_statistics->set_total_heap_size_executable(
Steve Block44f0eee2011-05-26 01:26:41 +01003589 heap->CommittedMemoryExecutable());
3590 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
3591 heap_statistics->set_heap_size_limit(heap->MaxReserved());
Steve Block3ce2e202009-11-05 08:53:23 +00003592}
3593
3594
3595bool v8::V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003596 // Returning true tells the caller that it need not
3597 // continue to call IdleNotification.
Steve Block44f0eee2011-05-26 01:26:41 +01003598 if (!i::Isolate::Current()->IsInitialized()) return true;
Steve Block3ce2e202009-11-05 08:53:23 +00003599 return i::V8::IdleNotification();
Steve Blocka7e24c12009-10-30 11:49:00 +00003600}
3601
3602
3603void v8::V8::LowMemoryNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003604 i::Isolate* isolate = i::Isolate::Current();
3605 if (!isolate->IsInitialized()) return;
3606 isolate->heap()->CollectAllGarbage(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003607}
3608
3609
Steve Block6ded16b2010-05-10 14:33:55 +01003610int v8::V8::ContextDisposedNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003611 i::Isolate* isolate = i::Isolate::Current();
3612 if (!isolate->IsInitialized()) return 0;
3613 return isolate->heap()->NotifyContextDisposed();
Steve Block6ded16b2010-05-10 14:33:55 +01003614}
3615
3616
Steve Blocka7e24c12009-10-30 11:49:00 +00003617const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01003618 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00003619}
3620
3621
3622static i::Handle<i::FunctionTemplateInfo>
3623 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
3624 if (templ->constructor()->IsUndefined()) {
3625 Local<FunctionTemplate> constructor = FunctionTemplate::New();
3626 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
3627 templ->set_constructor(*Utils::OpenHandle(*constructor));
3628 }
3629 return i::Handle<i::FunctionTemplateInfo>(
3630 i::FunctionTemplateInfo::cast(templ->constructor()));
3631}
3632
3633
3634Persistent<Context> v8::Context::New(
3635 v8::ExtensionConfiguration* extensions,
3636 v8::Handle<ObjectTemplate> global_template,
3637 v8::Handle<Value> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01003638 i::Isolate* isolate = i::Isolate::Current();
3639 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
3640 LOG_API(isolate, "Context::New");
3641 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003642
3643 // Enter V8 via an ENTER_V8 scope.
3644 i::Handle<i::Context> env;
3645 {
Steve Block44f0eee2011-05-26 01:26:41 +01003646 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003647 v8::Handle<ObjectTemplate> proxy_template = global_template;
3648 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
3649 i::Handle<i::FunctionTemplateInfo> global_constructor;
3650
3651 if (!global_template.IsEmpty()) {
3652 // Make sure that the global_template has a constructor.
3653 global_constructor =
3654 EnsureConstructor(Utils::OpenHandle(*global_template));
3655
3656 // Create a fresh template for the global proxy object.
3657 proxy_template = ObjectTemplate::New();
3658 proxy_constructor =
3659 EnsureConstructor(Utils::OpenHandle(*proxy_template));
3660
3661 // Set the global template to be the prototype template of
3662 // global proxy template.
3663 proxy_constructor->set_prototype_template(
3664 *Utils::OpenHandle(*global_template));
3665
3666 // Migrate security handlers from global_template to
3667 // proxy_template. Temporarily removing access check
3668 // information from the global template.
3669 if (!global_constructor->access_check_info()->IsUndefined()) {
3670 proxy_constructor->set_access_check_info(
3671 global_constructor->access_check_info());
3672 proxy_constructor->set_needs_access_check(
3673 global_constructor->needs_access_check());
3674 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01003675 global_constructor->set_access_check_info(
3676 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003677 }
3678 }
3679
3680 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01003681 env = isolate->bootstrapper()->CreateEnvironment(
Steve Blocka7e24c12009-10-30 11:49:00 +00003682 Utils::OpenHandle(*global_object),
3683 proxy_template,
3684 extensions);
3685
3686 // Restore the access check info on the global template.
3687 if (!global_template.IsEmpty()) {
3688 ASSERT(!global_constructor.is_null());
3689 ASSERT(!proxy_constructor.is_null());
3690 global_constructor->set_access_check_info(
3691 proxy_constructor->access_check_info());
3692 global_constructor->set_needs_access_check(
3693 proxy_constructor->needs_access_check());
3694 }
Steve Block44f0eee2011-05-26 01:26:41 +01003695 isolate->runtime_profiler()->Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +00003696 }
3697 // Leave V8.
3698
3699 if (env.is_null())
3700 return Persistent<Context>();
3701 return Persistent<Context>(Utils::ToLocal(env));
3702}
3703
3704
3705void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01003706 i::Isolate* isolate = i::Isolate::Current();
3707 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
3708 return;
3709 }
3710 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003711 i::Handle<i::Context> env = Utils::OpenHandle(this);
3712 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
3713 env->set_security_token(*token_handle);
3714}
3715
3716
3717void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003718 i::Isolate* isolate = i::Isolate::Current();
3719 if (IsDeadCheck(isolate,
3720 "v8::Context::UseDefaultSecurityToken()")) {
3721 return;
3722 }
3723 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003724 i::Handle<i::Context> env = Utils::OpenHandle(this);
3725 env->set_security_token(env->global());
3726}
3727
3728
3729Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003730 i::Isolate* isolate = i::Isolate::Current();
3731 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
3732 return Handle<Value>();
3733 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003734 i::Handle<i::Context> env = Utils::OpenHandle(this);
3735 i::Object* security_token = env->security_token();
3736 i::Handle<i::Object> token_handle(security_token);
3737 return Utils::ToLocal(token_handle);
3738}
3739
3740
3741bool Context::HasOutOfMemoryException() {
3742 i::Handle<i::Context> env = Utils::OpenHandle(this);
3743 return env->has_out_of_memory();
3744}
3745
3746
3747bool Context::InContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01003748 return i::Isolate::Current()->context() != NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00003749}
3750
3751
3752v8::Local<v8::Context> Context::GetEntered() {
Steve Block44f0eee2011-05-26 01:26:41 +01003753 i::Isolate* isolate = i::Isolate::Current();
3754 if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
3755 return Local<Context>();
3756 }
3757 i::Handle<i::Object> last =
3758 isolate->handle_scope_implementer()->LastEnteredContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003759 if (last.is_null()) return Local<Context>();
3760 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
3761 return Utils::ToLocal(context);
3762}
3763
3764
3765v8::Local<v8::Context> Context::GetCurrent() {
Steve Block44f0eee2011-05-26 01:26:41 +01003766 i::Isolate* isolate = i::Isolate::Current();
3767 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
3768 return Local<Context>();
3769 }
3770 i::Handle<i::Object> current = isolate->global_context();
Steve Block3ce2e202009-11-05 08:53:23 +00003771 if (current.is_null()) return Local<Context>();
3772 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
Steve Blocka7e24c12009-10-30 11:49:00 +00003773 return Utils::ToLocal(context);
3774}
3775
3776
3777v8::Local<v8::Context> Context::GetCalling() {
Steve Block44f0eee2011-05-26 01:26:41 +01003778 i::Isolate* isolate = i::Isolate::Current();
3779 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
3780 return Local<Context>();
3781 }
3782 i::Handle<i::Object> calling =
3783 isolate->GetCallingGlobalContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003784 if (calling.is_null()) return Local<Context>();
3785 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
3786 return Utils::ToLocal(context);
3787}
3788
3789
3790v8::Local<v8::Object> Context::Global() {
Steve Block44f0eee2011-05-26 01:26:41 +01003791 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
3792 return Local<v8::Object>();
3793 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003794 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3795 i::Handle<i::Context> context =
3796 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
3797 i::Handle<i::Object> global(context->global_proxy());
3798 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
3799}
3800
3801
3802void Context::DetachGlobal() {
Steve Block44f0eee2011-05-26 01:26:41 +01003803 i::Isolate* isolate = i::Isolate::Current();
3804 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
3805 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003806 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3807 i::Handle<i::Context> context =
3808 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01003809 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00003810}
3811
3812
Andrei Popescu74b3c142010-03-29 12:03:09 +01003813void Context::ReattachGlobal(Handle<Object> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01003814 i::Isolate* isolate = i::Isolate::Current();
3815 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
3816 ENTER_V8(isolate);
Andrei Popescu74b3c142010-03-29 12:03:09 +01003817 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3818 i::Handle<i::Context> context =
3819 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01003820 isolate->bootstrapper()->ReattachGlobal(
3821 context,
3822 Utils::OpenHandle(*global_object));
3823}
3824
3825
3826void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
3827 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
Andrei Popescu74b3c142010-03-29 12:03:09 +01003828}
3829
3830
Steve Blocka7e24c12009-10-30 11:49:00 +00003831Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01003832 i::Isolate* isolate = i::Isolate::Current();
3833 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
3834 return Local<v8::Object>());
3835 LOG_API(isolate, "ObjectTemplate::NewInstance");
3836 ENTER_V8(isolate);
3837 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003838 i::Handle<i::Object> obj =
3839 i::Execution::InstantiateObject(Utils::OpenHandle(this),
3840 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003841 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003842 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
3843}
3844
3845
3846Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01003847 i::Isolate* isolate = i::Isolate::Current();
3848 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003849 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01003850 LOG_API(isolate, "FunctionTemplate::GetFunction");
3851 ENTER_V8(isolate);
3852 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003853 i::Handle<i::Object> obj =
3854 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
3855 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003856 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003857 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
3858}
3859
3860
3861bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003862 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
3863 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003864 i::Object* obj = *Utils::OpenHandle(*value);
3865 return obj->IsInstanceOf(*Utils::OpenHandle(this));
3866}
3867
3868
3869static Local<External> ExternalNewImpl(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01003870 return Utils::ToLocal(FACTORY->NewProxy(static_cast<i::Address>(data)));
Steve Blocka7e24c12009-10-30 11:49:00 +00003871}
3872
3873static void* ExternalValueImpl(i::Handle<i::Object> obj) {
3874 return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy());
3875}
3876
3877
Steve Blocka7e24c12009-10-30 11:49:00 +00003878Local<Value> v8::External::Wrap(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01003879 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00003880 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01003881 LOG_API(isolate, "External::Wrap");
3882 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
3883 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003884
3885 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
3886 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
3887 : v8::Local<v8::Value>(ExternalNewImpl(data));
3888
3889 ASSERT_EQ(data, Unwrap(result));
3890 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003891}
3892
3893
Steve Block3ce2e202009-11-05 08:53:23 +00003894void* v8::Object::SlowGetPointerFromInternalField(int index) {
3895 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3896 i::Object* value = obj->GetInternalField(index);
3897 if (value->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01003898 return i::Internals::GetExternalPointerFromSmi(value);
Steve Block3ce2e202009-11-05 08:53:23 +00003899 } else if (value->IsProxy()) {
3900 return reinterpret_cast<void*>(i::Proxy::cast(value)->proxy());
3901 } else {
3902 return NULL;
3903 }
3904}
3905
3906
Steve Blocka7e24c12009-10-30 11:49:00 +00003907void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
Steve Block44f0eee2011-05-26 01:26:41 +01003908 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003909 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
3910 void* result;
3911 if (obj->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01003912 result = i::Internals::GetExternalPointerFromSmi(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00003913 } else if (obj->IsProxy()) {
3914 result = ExternalValueImpl(obj);
3915 } else {
3916 result = NULL;
3917 }
3918 ASSERT_EQ(result, QuickUnwrap(wrapper));
3919 return result;
3920}
3921
3922
3923Local<External> v8::External::New(void* data) {
3924 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01003925 i::Isolate* isolate = i::Isolate::Current();
3926 LOG_API(isolate, "External::New");
3927 EnsureInitializedForIsolate(isolate, "v8::External::New()");
3928 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003929 return ExternalNewImpl(data);
3930}
3931
3932
3933void* External::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003934 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003935 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3936 return ExternalValueImpl(obj);
3937}
3938
3939
3940Local<String> v8::String::Empty() {
Steve Block44f0eee2011-05-26 01:26:41 +01003941 i::Isolate* isolate = i::Isolate::Current();
3942 EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
3943 LOG_API(isolate, "String::Empty()");
3944 return Utils::ToLocal(isolate->factory()->empty_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00003945}
3946
3947
3948Local<String> v8::String::New(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003949 i::Isolate* isolate = i::Isolate::Current();
3950 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3951 LOG_API(isolate, "String::New(char)");
Steve Blocka7e24c12009-10-30 11:49:00 +00003952 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01003953 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00003954 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00003955 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01003956 isolate->factory()->NewStringFromUtf8(
3957 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00003958 return Utils::ToLocal(result);
3959}
3960
3961
Steve Block3ce2e202009-11-05 08:53:23 +00003962Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00003963 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01003964 i::Isolate* isolate = left_string->GetIsolate();
3965 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3966 LOG_API(isolate, "String::New(char)");
3967 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003968 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Steve Block44f0eee2011-05-26 01:26:41 +01003969 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
3970 right_string);
Steve Block3ce2e202009-11-05 08:53:23 +00003971 return Utils::ToLocal(result);
3972}
3973
3974
Steve Blocka7e24c12009-10-30 11:49:00 +00003975Local<String> v8::String::NewUndetectable(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003976 i::Isolate* isolate = i::Isolate::Current();
3977 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
3978 LOG_API(isolate, "String::NewUndetectable(char)");
3979 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00003980 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00003981 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01003982 isolate->factory()->NewStringFromUtf8(
3983 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00003984 result->MarkAsUndetectable();
3985 return Utils::ToLocal(result);
3986}
3987
3988
3989static int TwoByteStringLength(const uint16_t* data) {
3990 int length = 0;
3991 while (data[length] != '\0') length++;
3992 return length;
3993}
3994
3995
3996Local<String> v8::String::New(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003997 i::Isolate* isolate = i::Isolate::Current();
3998 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3999 LOG_API(isolate, "String::New(uint16_)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004000 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004001 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004002 if (length == -1) length = TwoByteStringLength(data);
4003 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004004 isolate->factory()->NewStringFromTwoByte(
4005 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004006 return Utils::ToLocal(result);
4007}
4008
4009
4010Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004011 i::Isolate* isolate = i::Isolate::Current();
4012 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4013 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4014 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004015 if (length == -1) length = TwoByteStringLength(data);
4016 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004017 isolate->factory()->NewStringFromTwoByte(
4018 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004019 result->MarkAsUndetectable();
4020 return Utils::ToLocal(result);
4021}
4022
4023
Steve Block44f0eee2011-05-26 01:26:41 +01004024i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004025 v8::String::ExternalStringResource* resource) {
4026 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004027 isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004028 return result;
4029}
4030
4031
Steve Block44f0eee2011-05-26 01:26:41 +01004032i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004033 v8::String::ExternalAsciiStringResource* resource) {
4034 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004035 isolate->factory()->NewExternalStringFromAscii(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004036 return result;
4037}
4038
4039
Steve Blocka7e24c12009-10-30 11:49:00 +00004040Local<String> v8::String::NewExternal(
4041 v8::String::ExternalStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004042 i::Isolate* isolate = i::Isolate::Current();
4043 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4044 LOG_API(isolate, "String::NewExternal");
4045 ENTER_V8(isolate);
4046 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4047 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004048 return Utils::ToLocal(result);
4049}
4050
4051
4052bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004053 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004054 i::Isolate* isolate = obj->GetIsolate();
4055 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4056 if (i::StringShape(*obj).IsExternalTwoByte()) {
4057 return false; // Already an external string.
4058 }
4059 ENTER_V8(isolate);
4060 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4061 return false;
4062 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004063 bool result = obj->MakeExternal(resource);
4064 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004065 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004066 }
4067 return result;
4068}
4069
4070
4071Local<String> v8::String::NewExternal(
4072 v8::String::ExternalAsciiStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004073 i::Isolate* isolate = i::Isolate::Current();
4074 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4075 LOG_API(isolate, "String::NewExternal");
4076 ENTER_V8(isolate);
4077 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4078 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004079 return Utils::ToLocal(result);
4080}
4081
4082
4083bool v8::String::MakeExternal(
4084 v8::String::ExternalAsciiStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004085 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004086 i::Isolate* isolate = obj->GetIsolate();
4087 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4088 if (i::StringShape(*obj).IsExternalTwoByte()) {
4089 return false; // Already an external string.
4090 }
4091 ENTER_V8(isolate);
4092 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4093 return false;
4094 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004095 bool result = obj->MakeExternal(resource);
4096 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004097 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004098 }
4099 return result;
4100}
4101
4102
4103bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004104 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004105 i::Isolate* isolate = obj->GetIsolate();
4106 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4107 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4108 return false;
4109 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004110 int size = obj->Size(); // Byte size of the original string.
4111 if (size < i::ExternalString::kSize)
4112 return false;
4113 i::StringShape shape(*obj);
4114 return !shape.IsExternal();
4115}
4116
4117
4118Local<v8::Object> v8::Object::New() {
Steve Block44f0eee2011-05-26 01:26:41 +01004119 i::Isolate* isolate = i::Isolate::Current();
4120 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4121 LOG_API(isolate, "Object::New");
4122 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004123 i::Handle<i::JSObject> obj =
Steve Block44f0eee2011-05-26 01:26:41 +01004124 isolate->factory()->NewJSObject(isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00004125 return Utils::ToLocal(obj);
4126}
4127
4128
4129Local<v8::Value> v8::Date::New(double time) {
Steve Block44f0eee2011-05-26 01:26:41 +01004130 i::Isolate* isolate = i::Isolate::Current();
4131 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4132 LOG_API(isolate, "Date::New");
Steve Blockd0582a62009-12-15 09:54:21 +00004133 if (isnan(time)) {
4134 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4135 time = i::OS::nan_value();
4136 }
Steve Block44f0eee2011-05-26 01:26:41 +01004137 ENTER_V8(isolate);
4138 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004139 i::Handle<i::Object> obj =
4140 i::Execution::NewDate(time, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004141 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004142 return Utils::ToLocal(obj);
4143}
4144
4145
4146double v8::Date::NumberValue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004147 i::Isolate* isolate = i::Isolate::Current();
4148 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4149 LOG_API(isolate, "Date::NumberValue");
Steve Blocka7e24c12009-10-30 11:49:00 +00004150 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4151 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4152 return jsvalue->value()->Number();
4153}
4154
4155
Ben Murdochb0fe1622011-05-05 13:52:32 +01004156void v8::Date::DateTimeConfigurationChangeNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004157 i::Isolate* isolate = i::Isolate::Current();
4158 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4159 return);
4160 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
4161 ENTER_V8(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004162
Steve Block44f0eee2011-05-26 01:26:41 +01004163 i::HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004164 // Get the function ResetDateCache (defined in date-delay.js).
4165 i::Handle<i::String> func_name_str =
Steve Block44f0eee2011-05-26 01:26:41 +01004166 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4167 i::MaybeObject* result =
4168 isolate->js_builtins_object()->GetProperty(*func_name_str);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004169 i::Object* object_func;
4170 if (!result->ToObject(&object_func)) {
4171 return;
4172 }
4173
4174 if (object_func->IsJSFunction()) {
4175 i::Handle<i::JSFunction> func =
4176 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4177
4178 // Call ResetDateCache(0 but expect no exceptions:
4179 bool caught_exception = false;
4180 i::Handle<i::Object> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004181 i::Execution::TryCall(func, isolate->js_builtins_object(), 0, NULL,
Ben Murdochb0fe1622011-05-05 13:52:32 +01004182 &caught_exception);
4183 }
4184}
4185
4186
Ben Murdochf87a2032010-10-22 12:50:53 +01004187static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4188 char flags_buf[3];
4189 int num_flags = 0;
4190 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4191 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4192 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4193 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
Steve Block44f0eee2011-05-26 01:26:41 +01004194 return FACTORY->LookupSymbol(
Ben Murdochf87a2032010-10-22 12:50:53 +01004195 i::Vector<const char>(flags_buf, num_flags));
4196}
4197
4198
4199Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4200 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01004201 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
4202 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
4203 LOG_API(isolate, "RegExp::New");
4204 ENTER_V8(isolate);
4205 EXCEPTION_PREAMBLE(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01004206 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
4207 Utils::OpenHandle(*pattern),
4208 RegExpFlagsToString(flags),
4209 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004210 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01004211 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
4212}
4213
4214
4215Local<v8::String> v8::RegExp::GetSource() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004216 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4217 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
4218 return Local<v8::String>();
4219 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004220 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4221 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
4222}
4223
4224
4225// Assert that the static flags cast in GetFlags is valid.
4226#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
4227 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
4228 static_cast<int>(i::JSRegExp::internal_flag))
4229REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
4230REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
4231REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
4232REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
4233#undef REGEXP_FLAG_ASSERT_EQ
4234
4235v8::RegExp::Flags v8::RegExp::GetFlags() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004236 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
4237 return v8::RegExp::kNone;
4238 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004239 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4240 return static_cast<RegExp::Flags>(obj->GetFlags().value());
4241}
4242
4243
Steve Blocka7e24c12009-10-30 11:49:00 +00004244Local<v8::Array> v8::Array::New(int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004245 i::Isolate* isolate = i::Isolate::Current();
4246 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
4247 LOG_API(isolate, "Array::New");
4248 ENTER_V8(isolate);
4249 int real_length = length > 0 ? length : 0;
4250 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
4251 obj->set_length(*isolate->factory()->NewNumberFromInt(real_length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004252 return Utils::ToLocal(obj);
4253}
4254
4255
4256uint32_t v8::Array::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004257 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4258 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004259 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
4260 i::Object* length = obj->length();
4261 if (length->IsSmi()) {
4262 return i::Smi::cast(length)->value();
4263 } else {
4264 return static_cast<uint32_t>(length->Number());
4265 }
4266}
4267
4268
4269Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01004270 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4271 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004272 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
4273 if (!self->HasFastElements()) {
4274 return Local<Object>();
4275 }
4276 i::FixedArray* elms = i::FixedArray::cast(self->elements());
4277 i::Object* paragon = elms->get(index);
4278 if (!paragon->IsJSObject()) {
4279 return Local<Object>();
4280 }
4281 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01004282 EXCEPTION_PREAMBLE(isolate);
4283 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004284 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
4285 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01004286 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004287 return Utils::ToLocal(result);
4288}
4289
4290
4291Local<String> v8::String::NewSymbol(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004292 i::Isolate* isolate = i::Isolate::Current();
4293 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
4294 LOG_API(isolate, "String::NewSymbol(char)");
4295 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004296 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004297 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004298 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004299 return Utils::ToLocal(result);
4300}
4301
4302
4303Local<Number> v8::Number::New(double value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004304 i::Isolate* isolate = i::Isolate::Current();
4305 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
Steve Blockd0582a62009-12-15 09:54:21 +00004306 if (isnan(value)) {
4307 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4308 value = i::OS::nan_value();
4309 }
Steve Block44f0eee2011-05-26 01:26:41 +01004310 ENTER_V8(isolate);
4311 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004312 return Utils::NumberToLocal(result);
4313}
4314
4315
4316Local<Integer> v8::Integer::New(int32_t value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004317 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4318 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004319 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004320 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
4321 isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004322 }
Steve Block44f0eee2011-05-26 01:26:41 +01004323 ENTER_V8(isolate);
4324 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004325 return Utils::IntegerToLocal(result);
4326}
4327
4328
Steve Block3ce2e202009-11-05 08:53:23 +00004329Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
4330 bool fits_into_int32_t = (value & (1 << 31)) == 0;
4331 if (fits_into_int32_t) {
4332 return Integer::New(static_cast<int32_t>(value));
4333 }
Steve Block44f0eee2011-05-26 01:26:41 +01004334 i::Isolate* isolate = i::Isolate::Current();
4335 ENTER_V8(isolate);
4336 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00004337 return Utils::IntegerToLocal(result);
4338}
4339
4340
Steve Blocka7e24c12009-10-30 11:49:00 +00004341void V8::IgnoreOutOfMemoryException() {
Steve Block44f0eee2011-05-26 01:26:41 +01004342 EnterIsolateIfNeeded()->handle_scope_implementer()->set_ignore_out_of_memory(
4343 true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004344}
4345
4346
4347bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004348 i::Isolate* isolate = i::Isolate::Current();
4349 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
4350 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
4351 ENTER_V8(isolate);
4352 i::HandleScope scope(isolate);
4353 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004354 NeanderObject obj(2);
Steve Block44f0eee2011-05-26 01:26:41 +01004355 obj.set(0, *isolate->factory()->NewProxy(FUNCTION_ADDR(that)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004356 obj.set(1, data.IsEmpty() ?
Steve Block44f0eee2011-05-26 01:26:41 +01004357 isolate->heap()->undefined_value() :
Steve Blocka7e24c12009-10-30 11:49:00 +00004358 *Utils::OpenHandle(*data));
4359 listeners.add(obj.value());
4360 return true;
4361}
4362
4363
4364void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01004365 i::Isolate* isolate = i::Isolate::Current();
4366 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
4367 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
4368 ENTER_V8(isolate);
4369 i::HandleScope scope(isolate);
4370 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004371 for (int i = 0; i < listeners.length(); i++) {
4372 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
4373
4374 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
4375 i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
4376 if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004377 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004378 }
4379 }
4380}
4381
4382
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004383void V8::SetCaptureStackTraceForUncaughtExceptions(
4384 bool capture,
4385 int frame_limit,
4386 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01004387 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004388 capture,
4389 frame_limit,
4390 options);
4391}
4392
4393
Steve Blocka7e24c12009-10-30 11:49:00 +00004394void V8::SetCounterFunction(CounterLookupCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004395 i::Isolate* isolate = EnterIsolateIfNeeded();
4396 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
4397 isolate->stats_table()->SetCounterFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004398}
4399
4400void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004401 i::Isolate* isolate = EnterIsolateIfNeeded();
4402 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
4403 isolate->stats_table()->SetCreateHistogramFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004404}
4405
4406void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004407 i::Isolate* isolate = EnterIsolateIfNeeded();
4408 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
4409 isolate->stats_table()->
4410 SetAddHistogramSampleFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004411}
4412
4413void V8::EnableSlidingStateWindow() {
Steve Block44f0eee2011-05-26 01:26:41 +01004414 i::Isolate* isolate = i::Isolate::Current();
4415 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
4416 isolate->logger()->EnableSlidingStateWindow();
Steve Blocka7e24c12009-10-30 11:49:00 +00004417}
4418
4419
4420void V8::SetFailedAccessCheckCallbackFunction(
4421 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004422 i::Isolate* isolate = i::Isolate::Current();
4423 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
4424 return;
4425 }
4426 isolate->SetFailedAccessCheckCallback(callback);
4427}
4428
4429void V8::AddObjectGroup(Persistent<Value>* objects,
4430 size_t length,
4431 RetainedObjectInfo* info) {
4432 i::Isolate* isolate = i::Isolate::Current();
4433 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
4434 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
4435 isolate->global_handles()->AddObjectGroup(
4436 reinterpret_cast<i::Object***>(objects), length, info);
Steve Blocka7e24c12009-10-30 11:49:00 +00004437}
4438
4439
Steve Block44f0eee2011-05-26 01:26:41 +01004440void V8::AddImplicitReferences(Persistent<Object> parent,
4441 Persistent<Value>* children,
4442 size_t length) {
4443 i::Isolate* isolate = i::Isolate::Current();
4444 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004445 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
Steve Block44f0eee2011-05-26 01:26:41 +01004446 isolate->global_handles()->AddImplicitReferences(
4447 *Utils::OpenHandle(*parent),
4448 reinterpret_cast<i::Object***>(children), length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004449}
4450
4451
4452int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
Steve Block44f0eee2011-05-26 01:26:41 +01004453 i::Isolate* isolate = i::Isolate::Current();
4454 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
4455 return 0;
4456 }
4457 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
4458 change_in_bytes);
Steve Blocka7e24c12009-10-30 11:49:00 +00004459}
4460
4461
4462void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004463 i::Isolate* isolate = i::Isolate::Current();
4464 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
4465 isolate->heap()->SetGlobalGCPrologueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004466}
4467
4468
4469void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004470 i::Isolate* isolate = i::Isolate::Current();
4471 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
4472 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004473}
4474
4475
Steve Block6ded16b2010-05-10 14:33:55 +01004476void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004477 i::Isolate* isolate = i::Isolate::Current();
4478 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
4479 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004480}
4481
4482
4483void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004484 i::Isolate* isolate = i::Isolate::Current();
4485 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
4486 isolate->heap()->RemoveGCPrologueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004487}
4488
4489
4490void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004491 i::Isolate* isolate = i::Isolate::Current();
4492 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
4493 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004494}
4495
4496
4497void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004498 i::Isolate* isolate = i::Isolate::Current();
4499 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
4500 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004501}
4502
4503
Iain Merrick9ac36c92010-09-13 15:29:50 +01004504void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
4505 ObjectSpace space,
4506 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01004507 i::Isolate* isolate = i::Isolate::Current();
4508 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
4509 isolate->memory_allocator()->AddMemoryAllocationCallback(
4510 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004511}
4512
4513
4514void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004515 i::Isolate* isolate = i::Isolate::Current();
4516 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
4517 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
4518 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004519}
4520
4521
Steve Blocka7e24c12009-10-30 11:49:00 +00004522void V8::PauseProfiler() {
4523#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004524 PauseProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004525#endif
4526}
4527
4528
4529void V8::ResumeProfiler() {
4530#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004531 ResumeProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004532#endif
4533}
4534
4535
4536bool V8::IsProfilerPaused() {
4537#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004538 return LOGGER->GetActiveProfilerModules() & PROFILER_MODULE_CPU;
Steve Blocka7e24c12009-10-30 11:49:00 +00004539#else
4540 return true;
4541#endif
4542}
4543
4544
Andrei Popescu402d9372010-02-26 13:31:12 +00004545void V8::ResumeProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004546#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004547 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004548 if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
4549 // Snapshot mode: resume modules, perform GC, then pause only
4550 // those modules which haven't been started prior to making a
4551 // snapshot.
4552
Steve Block6ded16b2010-05-10 14:33:55 +01004553 // Make a GC prior to taking a snapshot.
Steve Block44f0eee2011-05-26 01:26:41 +01004554 isolate->heap()->CollectAllGarbage(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004555 // Reset snapshot flag and CPU module flags.
4556 flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
Steve Block44f0eee2011-05-26 01:26:41 +01004557 const int current_flags = isolate->logger()->GetActiveProfilerModules();
4558 isolate->logger()->ResumeProfiler(flags, tag);
4559 isolate->heap()->CollectAllGarbage(false);
4560 isolate->logger()->PauseProfiler(~current_flags & flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004561 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004562 isolate->logger()->ResumeProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004563 }
4564#endif
4565}
4566
4567
Andrei Popescu402d9372010-02-26 13:31:12 +00004568void V8::PauseProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004569#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004570 LOGGER->PauseProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004571#endif
4572}
4573
4574
4575int V8::GetActiveProfilerModules() {
4576#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004577 return LOGGER->GetActiveProfilerModules();
Steve Blocka7e24c12009-10-30 11:49:00 +00004578#else
4579 return PROFILER_MODULE_NONE;
4580#endif
4581}
4582
4583
4584int V8::GetLogLines(int from_pos, char* dest_buf, int max_size) {
4585#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block6ded16b2010-05-10 14:33:55 +01004586 ASSERT(max_size >= kMinimumSizeForLogLinesBuffer);
Steve Block44f0eee2011-05-26 01:26:41 +01004587 return LOGGER->GetLogLines(from_pos, dest_buf, max_size);
Steve Blocka7e24c12009-10-30 11:49:00 +00004588#endif
4589 return 0;
4590}
4591
4592
4593int V8::GetCurrentThreadId() {
Steve Block44f0eee2011-05-26 01:26:41 +01004594 i::Isolate* isolate = i::Isolate::Current();
4595 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
4596 return isolate->thread_id();
Steve Blocka7e24c12009-10-30 11:49:00 +00004597}
4598
4599
4600void V8::TerminateExecution(int thread_id) {
Steve Block44f0eee2011-05-26 01:26:41 +01004601 i::Isolate* isolate = i::Isolate::Current();
4602 if (!isolate->IsInitialized()) return;
4603 API_ENTRY_CHECK("V8::TerminateExecution()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004604 // If the thread_id identifies the current thread just terminate
4605 // execution right away. Otherwise, ask the thread manager to
4606 // terminate the thread with the given id if any.
Steve Block44f0eee2011-05-26 01:26:41 +01004607 if (thread_id == isolate->thread_id()) {
4608 isolate->stack_guard()->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00004609 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004610 isolate->thread_manager()->TerminateExecution(thread_id);
Steve Blocka7e24c12009-10-30 11:49:00 +00004611 }
4612}
4613
4614
Steve Block44f0eee2011-05-26 01:26:41 +01004615void V8::TerminateExecution(Isolate* isolate) {
4616 // If no isolate is supplied, use the default isolate.
4617 if (isolate != NULL) {
4618 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
4619 } else {
4620 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
4621 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004622}
4623
4624
Steve Block6ded16b2010-05-10 14:33:55 +01004625bool V8::IsExecutionTerminating() {
Steve Block44f0eee2011-05-26 01:26:41 +01004626 i::Isolate* isolate = i::Isolate::Current();
4627 return IsExecutionTerminatingCheck(isolate);
4628}
4629
4630
4631Isolate* Isolate::GetCurrent() {
4632 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4633 return reinterpret_cast<Isolate*>(isolate);
4634}
4635
4636
4637Isolate* Isolate::New() {
4638 i::Isolate* isolate = new i::Isolate();
4639 return reinterpret_cast<Isolate*>(isolate);
4640}
4641
4642
4643void Isolate::Dispose() {
4644 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4645 if (!ApiCheck(!isolate->IsInUse(),
4646 "v8::Isolate::Dispose()",
4647 "Disposing the isolate that is entered by a thread.")) {
4648 return;
Steve Block6ded16b2010-05-10 14:33:55 +01004649 }
Steve Block44f0eee2011-05-26 01:26:41 +01004650 isolate->TearDown();
4651}
4652
4653
4654void Isolate::Enter() {
4655 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4656 isolate->Enter();
4657}
4658
4659
4660void Isolate::Exit() {
4661 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4662 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01004663}
4664
4665
Steve Blocka7e24c12009-10-30 11:49:00 +00004666String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004667 i::Isolate* isolate = i::Isolate::Current();
4668 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004669 if (obj.IsEmpty()) {
4670 str_ = NULL;
4671 length_ = 0;
4672 return;
4673 }
Steve Block44f0eee2011-05-26 01:26:41 +01004674 ENTER_V8(isolate);
4675 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004676 TryCatch try_catch;
4677 Handle<String> str = obj->ToString();
4678 if (str.IsEmpty()) {
4679 str_ = NULL;
4680 length_ = 0;
4681 } else {
4682 length_ = str->Utf8Length();
4683 str_ = i::NewArray<char>(length_ + 1);
4684 str->WriteUtf8(str_);
4685 }
4686}
4687
4688
4689String::Utf8Value::~Utf8Value() {
4690 i::DeleteArray(str_);
4691}
4692
4693
4694String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004695 i::Isolate* isolate = i::Isolate::Current();
4696 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004697 if (obj.IsEmpty()) {
4698 str_ = NULL;
4699 length_ = 0;
4700 return;
4701 }
Steve Block44f0eee2011-05-26 01:26:41 +01004702 ENTER_V8(isolate);
4703 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004704 TryCatch try_catch;
4705 Handle<String> str = obj->ToString();
4706 if (str.IsEmpty()) {
4707 str_ = NULL;
4708 length_ = 0;
4709 } else {
4710 length_ = str->Length();
4711 str_ = i::NewArray<char>(length_ + 1);
4712 str->WriteAscii(str_);
4713 }
4714}
4715
4716
4717String::AsciiValue::~AsciiValue() {
4718 i::DeleteArray(str_);
4719}
4720
4721
4722String::Value::Value(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004723 i::Isolate* isolate = i::Isolate::Current();
4724 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004725 if (obj.IsEmpty()) {
4726 str_ = NULL;
4727 length_ = 0;
4728 return;
4729 }
Steve Block44f0eee2011-05-26 01:26:41 +01004730 ENTER_V8(isolate);
4731 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004732 TryCatch try_catch;
4733 Handle<String> str = obj->ToString();
4734 if (str.IsEmpty()) {
4735 str_ = NULL;
4736 length_ = 0;
4737 } else {
4738 length_ = str->Length();
4739 str_ = i::NewArray<uint16_t>(length_ + 1);
4740 str->Write(str_);
4741 }
4742}
4743
4744
4745String::Value::~Value() {
4746 i::DeleteArray(str_);
4747}
4748
4749Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004750 i::Isolate* isolate = i::Isolate::Current();
4751 LOG_API(isolate, "RangeError");
4752 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
4753 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004754 i::Object* error;
4755 {
Steve Block44f0eee2011-05-26 01:26:41 +01004756 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004757 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004758 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004759 error = *result;
4760 }
4761 i::Handle<i::Object> result(error);
4762 return Utils::ToLocal(result);
4763}
4764
4765Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004766 i::Isolate* isolate = i::Isolate::Current();
4767 LOG_API(isolate, "ReferenceError");
4768 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
4769 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004770 i::Object* error;
4771 {
Steve Block44f0eee2011-05-26 01:26:41 +01004772 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004773 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004774 i::Handle<i::Object> result =
4775 isolate->factory()->NewReferenceError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004776 error = *result;
4777 }
4778 i::Handle<i::Object> result(error);
4779 return Utils::ToLocal(result);
4780}
4781
4782Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004783 i::Isolate* isolate = i::Isolate::Current();
4784 LOG_API(isolate, "SyntaxError");
4785 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
4786 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004787 i::Object* error;
4788 {
Steve Block44f0eee2011-05-26 01:26:41 +01004789 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004790 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004791 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004792 error = *result;
4793 }
4794 i::Handle<i::Object> result(error);
4795 return Utils::ToLocal(result);
4796}
4797
4798Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004799 i::Isolate* isolate = i::Isolate::Current();
4800 LOG_API(isolate, "TypeError");
4801 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
4802 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004803 i::Object* error;
4804 {
Steve Block44f0eee2011-05-26 01:26:41 +01004805 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004806 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004807 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004808 error = *result;
4809 }
4810 i::Handle<i::Object> result(error);
4811 return Utils::ToLocal(result);
4812}
4813
4814Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004815 i::Isolate* isolate = i::Isolate::Current();
4816 LOG_API(isolate, "Error");
4817 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
4818 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004819 i::Object* error;
4820 {
Steve Block44f0eee2011-05-26 01:26:41 +01004821 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004822 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004823 i::Handle<i::Object> result = isolate->factory()->NewError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004824 error = *result;
4825 }
4826 i::Handle<i::Object> result(error);
4827 return Utils::ToLocal(result);
4828}
4829
4830
4831// --- D e b u g S u p p o r t ---
4832
4833#ifdef ENABLE_DEBUGGER_SUPPORT
Leon Clarkef7060e22010-06-03 12:02:55 +01004834
Leon Clarkef7060e22010-06-03 12:02:55 +01004835static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
Steve Block44f0eee2011-05-26 01:26:41 +01004836 i::Isolate* isolate = i::Isolate::Current();
4837 if (isolate->debug_event_callback() != NULL) {
4838 isolate->debug_event_callback()(event_details.GetEvent(),
4839 event_details.GetExecutionState(),
4840 event_details.GetEventData(),
4841 event_details.GetCallbackData());
Leon Clarkef7060e22010-06-03 12:02:55 +01004842 }
4843}
4844
4845
Steve Blocka7e24c12009-10-30 11:49:00 +00004846bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004847 i::Isolate* isolate = i::Isolate::Current();
4848 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
4849 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
4850 ENTER_V8(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01004851
Steve Block44f0eee2011-05-26 01:26:41 +01004852 isolate->set_debug_event_callback(that);
Leon Clarkef7060e22010-06-03 12:02:55 +01004853
Steve Block44f0eee2011-05-26 01:26:41 +01004854 i::HandleScope scope(isolate);
4855 i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
Leon Clarkef7060e22010-06-03 12:02:55 +01004856 if (that != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01004857 proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(EventCallbackWrapper));
Leon Clarkef7060e22010-06-03 12:02:55 +01004858 }
Steve Block44f0eee2011-05-26 01:26:41 +01004859 isolate->debugger()->SetEventListener(proxy, Utils::OpenHandle(*data));
Leon Clarkef7060e22010-06-03 12:02:55 +01004860 return true;
4861}
4862
4863
4864bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004865 i::Isolate* isolate = i::Isolate::Current();
4866 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
4867 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
4868 ENTER_V8(isolate);
4869 i::HandleScope scope(isolate);
4870 i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00004871 if (that != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01004872 proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00004873 }
Steve Block44f0eee2011-05-26 01:26:41 +01004874 isolate->debugger()->SetEventListener(proxy,
4875 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00004876 return true;
4877}
4878
4879
4880bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
4881 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004882 i::Isolate* isolate = i::Isolate::Current();
4883 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
4884 ENTER_V8(isolate);
4885 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
4886 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00004887 return true;
4888}
4889
4890
Steve Block44f0eee2011-05-26 01:26:41 +01004891void Debug::DebugBreak(Isolate* isolate) {
4892 // If no isolate is supplied, use the default isolate.
4893 if (isolate != NULL) {
4894 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
4895 } else {
4896 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
4897 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004898}
4899
4900
Steve Block44f0eee2011-05-26 01:26:41 +01004901void Debug::CancelDebugBreak(Isolate* isolate) {
4902 // If no isolate is supplied, use the default isolate.
4903 if (isolate != NULL) {
4904 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4905 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
4906 } else {
4907 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
4908 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004909}
4910
4911
Steve Block44f0eee2011-05-26 01:26:41 +01004912void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
4913 // If no isolate is supplied, use the default isolate.
4914 if (isolate != NULL) {
4915 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4916 internal_isolate->debugger()->EnqueueDebugCommand(data);
4917 } else {
4918 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
4919 }
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004920}
4921
4922
Steve Blocka7e24c12009-10-30 11:49:00 +00004923static void MessageHandlerWrapper(const v8::Debug::Message& message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004924 i::Isolate* isolate = i::Isolate::Current();
4925 if (isolate->message_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004926 v8::String::Value json(message.GetJSON());
Steve Block44f0eee2011-05-26 01:26:41 +01004927 (isolate->message_handler())(*json, json.length(), message.GetClientData());
Steve Blocka7e24c12009-10-30 11:49:00 +00004928 }
4929}
4930
4931
4932void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
4933 bool message_handler_thread) {
Steve Block44f0eee2011-05-26 01:26:41 +01004934 i::Isolate* isolate = i::Isolate::Current();
4935 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
4936 ENTER_V8(isolate);
4937
Steve Blocka7e24c12009-10-30 11:49:00 +00004938 // Message handler thread not supported any more. Parameter temporally left in
Steve Block44f0eee2011-05-26 01:26:41 +01004939 // the API for client compatibility reasons.
Steve Blocka7e24c12009-10-30 11:49:00 +00004940 CHECK(!message_handler_thread);
4941
4942 // TODO(sgjesse) support the old message handler API through a simple wrapper.
Steve Block44f0eee2011-05-26 01:26:41 +01004943 isolate->set_message_handler(handler);
4944 if (handler != NULL) {
4945 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
Steve Blocka7e24c12009-10-30 11:49:00 +00004946 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004947 isolate->debugger()->SetMessageHandler(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00004948 }
4949}
4950
4951
4952void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01004953 i::Isolate* isolate = i::Isolate::Current();
4954 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
4955 ENTER_V8(isolate);
4956 isolate->debugger()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00004957}
4958
4959
4960void Debug::SendCommand(const uint16_t* command, int length,
Steve Block44f0eee2011-05-26 01:26:41 +01004961 ClientData* client_data,
4962 Isolate* isolate) {
4963 // If no isolate is supplied, use the default isolate.
4964 if (isolate != NULL) {
4965 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4966 internal_isolate->debugger()->ProcessCommand(
4967 i::Vector<const uint16_t>(command, length), client_data);
4968 } else {
4969 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
4970 i::Vector<const uint16_t>(command, length), client_data);
4971 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004972}
4973
4974
4975void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
4976 int period) {
Steve Block44f0eee2011-05-26 01:26:41 +01004977 i::Isolate* isolate = i::Isolate::Current();
4978 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
4979 ENTER_V8(isolate);
4980 isolate->debugger()->SetHostDispatchHandler(handler, period);
Steve Blocka7e24c12009-10-30 11:49:00 +00004981}
4982
4983
Steve Blockd0582a62009-12-15 09:54:21 +00004984void Debug::SetDebugMessageDispatchHandler(
Leon Clarkee46be812010-01-19 14:06:41 +00004985 DebugMessageDispatchHandler handler, bool provide_locker) {
Steve Block44f0eee2011-05-26 01:26:41 +01004986 i::Isolate* isolate = i::Isolate::Current();
4987 EnsureInitializedForIsolate(isolate,
4988 "v8::Debug::SetDebugMessageDispatchHandler");
4989 ENTER_V8(isolate);
4990 isolate->debugger()->SetDebugMessageDispatchHandler(
4991 handler, provide_locker);
Steve Blockd0582a62009-12-15 09:54:21 +00004992}
4993
4994
Steve Blocka7e24c12009-10-30 11:49:00 +00004995Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
4996 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004997 i::Isolate* isolate = i::Isolate::Current();
4998 if (!isolate->IsInitialized()) return Local<Value>();
4999 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
5000 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005001 i::Handle<i::Object> result;
Steve Block44f0eee2011-05-26 01:26:41 +01005002 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005003 if (data.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005004 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5005 isolate->factory()->undefined_value(),
5006 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005007 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005008 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5009 Utils::OpenHandle(*data),
5010 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005011 }
Steve Block44f0eee2011-05-26 01:26:41 +01005012 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005013 return Utils::ToLocal(result);
5014}
5015
5016
5017Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01005018 i::Isolate* isolate = i::Isolate::Current();
5019 if (!isolate->IsInitialized()) return Local<Value>();
5020 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
5021 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005022 v8::HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01005023 i::Debug* isolate_debug = isolate->debug();
5024 isolate_debug->Load();
5025 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5026 i::Handle<i::String> name =
5027 isolate->factory()->LookupAsciiSymbol("MakeMirror");
Steve Blocka7e24c12009-10-30 11:49:00 +00005028 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5029 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5030 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5031 const int kArgc = 1;
5032 v8::Handle<v8::Value> argv[kArgc] = { obj };
Steve Block44f0eee2011-05-26 01:26:41 +01005033 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005034 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5035 kArgc,
5036 argv);
Steve Block44f0eee2011-05-26 01:26:41 +01005037 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005038 return scope.Close(result);
5039}
5040
5041
Leon Clarkee46be812010-01-19 14:06:41 +00005042bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
Steve Block44f0eee2011-05-26 01:26:41 +01005043 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5044 wait_for_connection);
Steve Blocka7e24c12009-10-30 11:49:00 +00005045}
Leon Clarkee46be812010-01-19 14:06:41 +00005046
5047void Debug::ProcessDebugMessages() {
5048 i::Execution::ProcessDebugMesssages(true);
5049}
5050
Steve Block6ded16b2010-05-10 14:33:55 +01005051Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01005052 i::Isolate* isolate = i::Isolate::Current();
5053 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5054 ENTER_V8(isolate);
5055 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01005056}
5057
Steve Blocka7e24c12009-10-30 11:49:00 +00005058#endif // ENABLE_DEBUGGER_SUPPORT
5059
Steve Block6ded16b2010-05-10 14:33:55 +01005060
5061#ifdef ENABLE_LOGGING_AND_PROFILING
5062
5063Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005064 i::Isolate* isolate = i::Isolate::Current();
5065 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
Steve Block6ded16b2010-05-10 14:33:55 +01005066 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5067 const i::CodeEntry* entry = node->entry();
5068 if (!entry->has_name_prefix()) {
5069 return Handle<String>(ToApi<String>(
Steve Block44f0eee2011-05-26 01:26:41 +01005070 isolate->factory()->LookupAsciiSymbol(entry->name())));
Steve Block6ded16b2010-05-10 14:33:55 +01005071 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005072 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5073 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5074 isolate->factory()->LookupAsciiSymbol(entry->name()))));
Steve Block6ded16b2010-05-10 14:33:55 +01005075 }
5076}
5077
5078
5079Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005080 i::Isolate* isolate = i::Isolate::Current();
5081 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
Steve Block6ded16b2010-05-10 14:33:55 +01005082 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005083 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005084 node->entry()->resource_name())));
5085}
5086
5087
5088int CpuProfileNode::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005089 i::Isolate* isolate = i::Isolate::Current();
5090 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
Steve Block6ded16b2010-05-10 14:33:55 +01005091 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5092}
5093
5094
5095double CpuProfileNode::GetTotalTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005096 i::Isolate* isolate = i::Isolate::Current();
5097 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005098 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5099}
5100
5101
5102double CpuProfileNode::GetSelfTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005103 i::Isolate* isolate = i::Isolate::Current();
5104 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005105 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5106}
5107
5108
5109double CpuProfileNode::GetTotalSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005110 i::Isolate* isolate = i::Isolate::Current();
5111 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005112 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5113}
5114
5115
5116double CpuProfileNode::GetSelfSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005117 i::Isolate* isolate = i::Isolate::Current();
5118 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005119 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5120}
5121
5122
5123unsigned CpuProfileNode::GetCallUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005124 i::Isolate* isolate = i::Isolate::Current();
5125 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005126 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01005127}
5128
5129
5130int CpuProfileNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005131 i::Isolate* isolate = i::Isolate::Current();
5132 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005133 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5134}
5135
5136
5137const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005138 i::Isolate* isolate = i::Isolate::Current();
5139 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
Steve Block6ded16b2010-05-10 14:33:55 +01005140 const i::ProfileNode* child =
5141 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5142 return reinterpret_cast<const CpuProfileNode*>(child);
5143}
5144
5145
Steve Block44f0eee2011-05-26 01:26:41 +01005146void CpuProfile::Delete() {
5147 i::Isolate* isolate = i::Isolate::Current();
5148 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5149 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5150 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5151 !i::CpuProfiler::HasDetachedProfiles()) {
5152 // If this was the last profile, clean up all accessory data as well.
5153 i::CpuProfiler::DeleteAllProfiles();
5154 }
5155}
5156
5157
Steve Block6ded16b2010-05-10 14:33:55 +01005158unsigned CpuProfile::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005159 i::Isolate* isolate = i::Isolate::Current();
5160 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
Steve Block6ded16b2010-05-10 14:33:55 +01005161 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5162}
5163
5164
5165Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005166 i::Isolate* isolate = i::Isolate::Current();
5167 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
Steve Block6ded16b2010-05-10 14:33:55 +01005168 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005169 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005170 profile->title())));
5171}
5172
5173
5174const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005175 i::Isolate* isolate = i::Isolate::Current();
5176 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005177 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5178 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5179}
5180
5181
5182const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005183 i::Isolate* isolate = i::Isolate::Current();
5184 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005185 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5186 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5187}
5188
5189
5190int CpuProfiler::GetProfilesCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005191 i::Isolate* isolate = i::Isolate::Current();
5192 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005193 return i::CpuProfiler::GetProfilesCount();
5194}
5195
5196
Leon Clarkef7060e22010-06-03 12:02:55 +01005197const CpuProfile* CpuProfiler::GetProfile(int index,
5198 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005199 i::Isolate* isolate = i::Isolate::Current();
5200 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005201 return reinterpret_cast<const CpuProfile*>(
5202 i::CpuProfiler::GetProfile(
5203 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5204 index));
Steve Block6ded16b2010-05-10 14:33:55 +01005205}
5206
5207
Leon Clarkef7060e22010-06-03 12:02:55 +01005208const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5209 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005210 i::Isolate* isolate = i::Isolate::Current();
5211 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005212 return reinterpret_cast<const CpuProfile*>(
5213 i::CpuProfiler::FindProfile(
5214 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5215 uid));
Steve Block6ded16b2010-05-10 14:33:55 +01005216}
5217
5218
5219void CpuProfiler::StartProfiling(Handle<String> title) {
Steve Block44f0eee2011-05-26 01:26:41 +01005220 i::Isolate* isolate = i::Isolate::Current();
5221 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005222 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5223}
5224
5225
Leon Clarkef7060e22010-06-03 12:02:55 +01005226const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5227 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005228 i::Isolate* isolate = i::Isolate::Current();
5229 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005230 return reinterpret_cast<const CpuProfile*>(
Leon Clarkef7060e22010-06-03 12:02:55 +01005231 i::CpuProfiler::StopProfiling(
5232 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5233 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01005234}
5235
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005236
Steve Block44f0eee2011-05-26 01:26:41 +01005237void CpuProfiler::DeleteAllProfiles() {
5238 i::Isolate* isolate = i::Isolate::Current();
5239 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5240 i::CpuProfiler::DeleteAllProfiles();
5241}
5242
5243
Iain Merrick75681382010-08-19 15:07:18 +01005244static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5245 return const_cast<i::HeapGraphEdge*>(
5246 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5247}
5248
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005249HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005250 i::Isolate* isolate = i::Isolate::Current();
5251 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005252 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005253}
5254
5255
5256Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005257 i::Isolate* isolate = i::Isolate::Current();
5258 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
Iain Merrick75681382010-08-19 15:07:18 +01005259 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005260 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01005261 case i::HeapGraphEdge::kContextVariable:
5262 case i::HeapGraphEdge::kInternal:
5263 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005264 case i::HeapGraphEdge::kShortcut:
Steve Block44f0eee2011-05-26 01:26:41 +01005265 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005266 edge->name())));
Iain Merrick75681382010-08-19 15:07:18 +01005267 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005268 case i::HeapGraphEdge::kHidden:
Steve Block44f0eee2011-05-26 01:26:41 +01005269 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005270 edge->index())));
5271 default: UNREACHABLE();
5272 }
Steve Block44f0eee2011-05-26 01:26:41 +01005273 return v8::Undefined();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005274}
5275
5276
5277const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005278 i::Isolate* isolate = i::Isolate::Current();
5279 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
Iain Merrick75681382010-08-19 15:07:18 +01005280 const i::HeapEntry* from = ToInternal(this)->From();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005281 return reinterpret_cast<const HeapGraphNode*>(from);
5282}
5283
5284
5285const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005286 i::Isolate* isolate = i::Isolate::Current();
5287 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
Iain Merrick75681382010-08-19 15:07:18 +01005288 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005289 return reinterpret_cast<const HeapGraphNode*>(to);
5290}
5291
5292
Iain Merrick75681382010-08-19 15:07:18 +01005293static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5294 return const_cast<i::HeapEntry*>(
5295 reinterpret_cast<const i::HeapEntry*>(entry));
5296}
5297
5298
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005299HeapGraphNode::Type HeapGraphNode::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005300 i::Isolate* isolate = i::Isolate::Current();
5301 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005302 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005303}
5304
5305
5306Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005307 i::Isolate* isolate = i::Isolate::Current();
5308 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
5309 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005310 ToInternal(this)->name())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005311}
5312
5313
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005314uint64_t HeapGraphNode::GetId() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005315 i::Isolate* isolate = i::Isolate::Current();
5316 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
Steve Block791712a2010-08-27 10:21:07 +01005317 ASSERT(ToInternal(this)->snapshot()->type() != i::HeapSnapshot::kAggregated);
Iain Merrick75681382010-08-19 15:07:18 +01005318 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005319}
5320
5321
Steve Block791712a2010-08-27 10:21:07 +01005322int HeapGraphNode::GetInstancesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005323 i::Isolate* isolate = i::Isolate::Current();
5324 IsDeadCheck(isolate, "v8::HeapGraphNode::GetInstancesCount");
Steve Block791712a2010-08-27 10:21:07 +01005325 ASSERT(ToInternal(this)->snapshot()->type() == i::HeapSnapshot::kAggregated);
5326 return static_cast<int>(ToInternal(this)->id());
5327}
5328
5329
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005330int HeapGraphNode::GetSelfSize() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005331 i::Isolate* isolate = i::Isolate::Current();
5332 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
Iain Merrick75681382010-08-19 15:07:18 +01005333 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005334}
5335
5336
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005337int HeapGraphNode::GetRetainedSize(bool exact) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005338 i::Isolate* isolate = i::Isolate::Current();
5339 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005340 return ToInternal(this)->RetainedSize(exact);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005341}
5342
5343
5344int HeapGraphNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005345 i::Isolate* isolate = i::Isolate::Current();
5346 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
Iain Merrick75681382010-08-19 15:07:18 +01005347 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005348}
5349
5350
5351const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005352 i::Isolate* isolate = i::Isolate::Current();
5353 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005354 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005355 &ToInternal(this)->children()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005356}
5357
5358
5359int HeapGraphNode::GetRetainersCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005360 i::Isolate* isolate = i::Isolate::Current();
5361 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
Iain Merrick75681382010-08-19 15:07:18 +01005362 return ToInternal(this)->retainers().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005363}
5364
5365
5366const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005367 i::Isolate* isolate = i::Isolate::Current();
5368 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005369 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005370 ToInternal(this)->retainers()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005371}
5372
5373
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005374const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005375 i::Isolate* isolate = i::Isolate::Current();
5376 IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005377 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
5378}
5379
5380
Iain Merrick75681382010-08-19 15:07:18 +01005381static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5382 return const_cast<i::HeapSnapshot*>(
5383 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5384}
5385
5386
Steve Block44f0eee2011-05-26 01:26:41 +01005387void HeapSnapshot::Delete() {
5388 i::Isolate* isolate = i::Isolate::Current();
5389 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
5390 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
5391 ToInternal(this)->Delete();
5392 } else {
5393 // If this is the last snapshot, clean up all accessory data as well.
5394 i::HeapProfiler::DeleteAllSnapshots();
5395 }
5396}
5397
5398
Steve Block791712a2010-08-27 10:21:07 +01005399HeapSnapshot::Type HeapSnapshot::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005400 i::Isolate* isolate = i::Isolate::Current();
5401 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
Steve Block791712a2010-08-27 10:21:07 +01005402 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
5403}
5404
5405
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005406unsigned HeapSnapshot::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005407 i::Isolate* isolate = i::Isolate::Current();
5408 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
Iain Merrick75681382010-08-19 15:07:18 +01005409 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005410}
5411
5412
5413Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005414 i::Isolate* isolate = i::Isolate::Current();
5415 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
5416 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005417 ToInternal(this)->title())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005418}
5419
5420
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005421const HeapGraphNode* HeapSnapshot::GetRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005422 i::Isolate* isolate = i::Isolate::Current();
5423 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
Iain Merrick75681382010-08-19 15:07:18 +01005424 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005425}
5426
5427
Ben Murdochb0fe1622011-05-05 13:52:32 +01005428const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005429 i::Isolate* isolate = i::Isolate::Current();
5430 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
Ben Murdochb0fe1622011-05-05 13:52:32 +01005431 return reinterpret_cast<const HeapGraphNode*>(
5432 ToInternal(this)->GetEntryById(id));
5433}
5434
5435
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005436void HeapSnapshot::Serialize(OutputStream* stream,
5437 HeapSnapshot::SerializationFormat format) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005438 i::Isolate* isolate = i::Isolate::Current();
5439 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005440 ApiCheck(format == kJSON,
5441 "v8::HeapSnapshot::Serialize",
5442 "Unknown serialization format");
5443 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
5444 "v8::HeapSnapshot::Serialize",
5445 "Unsupported output encoding");
5446 ApiCheck(stream->GetChunkSize() > 0,
5447 "v8::HeapSnapshot::Serialize",
5448 "Invalid stream chunk size");
5449 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
5450 serializer.Serialize(stream);
5451}
5452
5453
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005454int HeapProfiler::GetSnapshotsCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005455 i::Isolate* isolate = i::Isolate::Current();
5456 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005457 return i::HeapProfiler::GetSnapshotsCount();
5458}
5459
5460
5461const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005462 i::Isolate* isolate = i::Isolate::Current();
5463 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005464 return reinterpret_cast<const HeapSnapshot*>(
5465 i::HeapProfiler::GetSnapshot(index));
5466}
5467
5468
5469const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
Steve Block44f0eee2011-05-26 01:26:41 +01005470 i::Isolate* isolate = i::Isolate::Current();
5471 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005472 return reinterpret_cast<const HeapSnapshot*>(
5473 i::HeapProfiler::FindSnapshot(uid));
5474}
5475
5476
Steve Block791712a2010-08-27 10:21:07 +01005477const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
Ben Murdochb0fe1622011-05-05 13:52:32 +01005478 HeapSnapshot::Type type,
5479 ActivityControl* control) {
Steve Block44f0eee2011-05-26 01:26:41 +01005480 i::Isolate* isolate = i::Isolate::Current();
5481 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
Steve Block791712a2010-08-27 10:21:07 +01005482 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
5483 switch (type) {
5484 case HeapSnapshot::kFull:
5485 internal_type = i::HeapSnapshot::kFull;
5486 break;
5487 case HeapSnapshot::kAggregated:
5488 internal_type = i::HeapSnapshot::kAggregated;
5489 break;
5490 default:
5491 UNREACHABLE();
5492 }
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005493 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb0fe1622011-05-05 13:52:32 +01005494 i::HeapProfiler::TakeSnapshot(
5495 *Utils::OpenHandle(*title), internal_type, control));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005496}
5497
Steve Block44f0eee2011-05-26 01:26:41 +01005498
5499void HeapProfiler::DeleteAllSnapshots() {
5500 i::Isolate* isolate = i::Isolate::Current();
5501 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5502 i::HeapProfiler::DeleteAllSnapshots();
5503}
5504
5505
5506void HeapProfiler::DefineWrapperClass(uint16_t class_id,
5507 WrapperInfoCallback callback) {
5508 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
5509 callback);
5510}
5511
Steve Block6ded16b2010-05-10 14:33:55 +01005512#endif // ENABLE_LOGGING_AND_PROFILING
5513
5514
Ben Murdochb0fe1622011-05-05 13:52:32 +01005515v8::Testing::StressType internal::Testing::stress_type_ =
5516 v8::Testing::kStressTypeOpt;
5517
5518
5519void Testing::SetStressRunType(Testing::StressType type) {
5520 internal::Testing::set_stress_type(type);
5521}
5522
5523int Testing::GetStressRuns() {
5524 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
5525#ifdef DEBUG
5526 // In debug mode the code runs much slower so stressing will only make two
5527 // runs.
5528 return 2;
5529#else
5530 return 5;
5531#endif
5532}
5533
5534
5535static void SetFlagsFromString(const char* flags) {
5536 V8::SetFlagsFromString(flags, i::StrLength(flags));
5537}
5538
5539
5540void Testing::PrepareStressRun(int run) {
5541 static const char* kLazyOptimizations =
5542 "--prepare-always-opt --nolimit-inlining "
5543 "--noalways-opt --noopt-eagerly";
5544 static const char* kEagerOptimizations = "--opt-eagerly";
5545 static const char* kForcedOptimizations = "--always-opt";
5546
5547 // If deoptimization stressed turn on frequent deoptimization. If no value
5548 // is spefified through --deopt-every-n-times use a default default value.
5549 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
5550 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
5551 internal::FLAG_deopt_every_n_times == 0) {
5552 SetFlagsFromString(kDeoptEvery13Times);
5553 }
5554
5555#ifdef DEBUG
5556 // As stressing in debug mode only make two runs skip the deopt stressing
5557 // here.
5558 if (run == GetStressRuns() - 1) {
5559 SetFlagsFromString(kForcedOptimizations);
5560 } else {
5561 SetFlagsFromString(kEagerOptimizations);
5562 SetFlagsFromString(kLazyOptimizations);
5563 }
5564#else
5565 if (run == GetStressRuns() - 1) {
5566 SetFlagsFromString(kForcedOptimizations);
5567 } else if (run == GetStressRuns() - 2) {
5568 SetFlagsFromString(kEagerOptimizations);
5569 } else {
5570 SetFlagsFromString(kLazyOptimizations);
5571 }
5572#endif
5573}
5574
5575
Steve Block44f0eee2011-05-26 01:26:41 +01005576void Testing::DeoptimizeAll() {
5577 internal::Deoptimizer::DeoptimizeAll();
Steve Blocka7e24c12009-10-30 11:49:00 +00005578}
5579
5580
Steve Block44f0eee2011-05-26 01:26:41 +01005581namespace internal {
5582
5583
Steve Blocka7e24c12009-10-30 11:49:00 +00005584void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01005585 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00005586}
5587
5588
5589char* HandleScopeImplementer::ArchiveThread(char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01005590 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00005591 v8::ImplementationUtilities::HandleScopeData* current =
Steve Block44f0eee2011-05-26 01:26:41 +01005592 isolate->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00005593 handle_scope_data_ = *current;
5594 memcpy(storage, this, sizeof(*this));
5595
5596 ResetAfterArchive();
5597 current->Initialize();
5598
5599 return storage + ArchiveSpacePerThread();
5600}
5601
5602
5603int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01005604 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00005605}
5606
5607
5608char* HandleScopeImplementer::RestoreThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005609 memcpy(this, storage, sizeof(*this));
Steve Block44f0eee2011-05-26 01:26:41 +01005610 *Isolate::Current()->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00005611 return storage + ArchiveSpacePerThread();
5612}
5613
5614
5615void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
5616 // Iterate over all handles in the blocks except for the last.
5617 for (int i = blocks()->length() - 2; i >= 0; --i) {
5618 Object** block = blocks()->at(i);
5619 v->VisitPointers(block, &block[kHandleBlockSize]);
5620 }
5621
5622 // Iterate over live handles in the last block (if any).
5623 if (!blocks()->is_empty()) {
5624 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
5625 }
5626
5627 if (!saved_contexts_.is_empty()) {
5628 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
5629 v->VisitPointers(start, start + saved_contexts_.length());
5630 }
5631}
5632
5633
5634void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
5635 v8::ImplementationUtilities::HandleScopeData* current =
Steve Block44f0eee2011-05-26 01:26:41 +01005636 Isolate::Current()->handle_scope_data();
5637 handle_scope_data_ = *current;
5638 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005639}
5640
5641
5642char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01005643 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00005644 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01005645 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005646 return storage + ArchiveSpacePerThread();
5647}
5648
5649} } // namespace v8::internal