blob: c3684f77a68475e80b77e55b52571c38dbff8faf [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);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001306 i::OS::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);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002584 // We do not allow exceptions thrown while setting the prototype
2585 // to propagate outside.
2586 TryCatch try_catch;
Steve Block44f0eee2011-05-26 01:26:41 +01002587 EXCEPTION_PREAMBLE(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00002588 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2589 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002590 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00002591 return true;
2592}
2593
2594
Steve Blocka7e24c12009-10-30 11:49:00 +00002595Local<Object> v8::Object::FindInstanceInPrototypeChain(
2596 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01002597 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2598 ON_BAILOUT(isolate,
2599 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002600 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01002601 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002602 i::JSObject* object = *Utils::OpenHandle(this);
2603 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2604 while (!object->IsInstanceOf(tmpl_info)) {
2605 i::Object* prototype = object->GetPrototype();
2606 if (!prototype->IsJSObject()) return Local<Object>();
2607 object = i::JSObject::cast(prototype);
2608 }
2609 return Utils::ToLocal(i::Handle<i::JSObject>(object));
2610}
2611
2612
2613Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01002614 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2615 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
2616 return Local<v8::Array>());
2617 ENTER_V8(isolate);
2618 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002619 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2620 i::Handle<i::FixedArray> value =
2621 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
2622 // Because we use caching to speed up enumeration it is important
2623 // to never change the result of the basic enumeration function so
2624 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01002625 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2626 i::Handle<i::JSArray> result =
2627 isolate->factory()->NewJSArrayWithElements(elms);
2628 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00002629}
2630
2631
2632Local<String> v8::Object::ObjectProtoToString() {
Steve Block44f0eee2011-05-26 01:26:41 +01002633 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2634 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
2635 return Local<v8::String>());
2636 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002637 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2638
2639 i::Handle<i::Object> name(self->class_name());
2640
2641 // Native implementation of Object.prototype.toString (v8natives.js):
2642 // var c = %ClassOf(this);
2643 // if (c === 'Arguments') c = 'Object';
2644 // return "[object " + c + "]";
2645
2646 if (!name->IsString()) {
2647 return v8::String::New("[object ]");
2648
2649 } else {
2650 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
2651 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
2652 return v8::String::New("[object Object]");
2653
2654 } else {
2655 const char* prefix = "[object ";
2656 Local<String> str = Utils::ToLocal(class_name);
2657 const char* postfix = "]";
2658
Steve Blockd0582a62009-12-15 09:54:21 +00002659 int prefix_len = i::StrLength(prefix);
2660 int str_len = str->Length();
2661 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00002662
Steve Blockd0582a62009-12-15 09:54:21 +00002663 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01002664 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002665
2666 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01002667 char* ptr = buf.start();
Steve Blocka7e24c12009-10-30 11:49:00 +00002668 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
2669 ptr += prefix_len;
2670
2671 // Write real content.
2672 str->WriteAscii(ptr, 0, str_len);
2673 ptr += str_len;
2674
2675 // Write postfix.
2676 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
2677
2678 // Copy the buffer into a heap-allocated string and return it.
Kristian Monsen25f61362010-05-21 11:50:48 +01002679 Local<String> result = v8::String::New(buf.start(), buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00002680 return result;
2681 }
2682 }
2683}
2684
2685
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002686Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01002687 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2688 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
2689 return Local<v8::String>());
2690 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002691 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2692 i::Handle<i::String> name(self->constructor_name());
2693 return Utils::ToLocal(name);
2694}
2695
2696
Steve Blocka7e24c12009-10-30 11:49:00 +00002697bool v8::Object::Delete(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002698 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2699 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
2700 ENTER_V8(isolate);
2701 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002702 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2703 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2704 return i::DeleteProperty(self, key_obj)->IsTrue();
2705}
2706
2707
2708bool v8::Object::Has(v8::Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002709 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2710 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
2711 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002712 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2713 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2714 return self->HasProperty(*key_obj);
2715}
2716
2717
2718bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002719 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2720 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
2721 return false);
2722 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002723 HandleScope scope;
2724 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2725 return i::DeleteElement(self, index)->IsTrue();
2726}
2727
2728
2729bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002730 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2731 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002732 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2733 return self->HasElement(index);
2734}
2735
2736
Leon Clarkef7060e22010-06-03 12:02:55 +01002737bool Object::SetAccessor(Handle<String> name,
2738 AccessorGetter getter,
2739 AccessorSetter setter,
2740 v8::Handle<Value> data,
2741 AccessControl settings,
2742 PropertyAttribute attributes) {
Steve Block44f0eee2011-05-26 01:26:41 +01002743 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2744 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
2745 ENTER_V8(isolate);
2746 i::HandleScope scope(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01002747 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
2748 getter, setter, data,
2749 settings, attributes);
2750 i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
2751 return !result.is_null() && !result->IsUndefined();
2752}
2753
2754
Steve Blocka7e24c12009-10-30 11:49:00 +00002755bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002756 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2757 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
2758 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002759 return Utils::OpenHandle(this)->HasRealNamedProperty(
2760 *Utils::OpenHandle(*key));
2761}
2762
2763
2764bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01002765 ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
2766 "v8::Object::HasRealIndexedProperty()",
2767 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002768 return Utils::OpenHandle(this)->HasRealElementProperty(index);
2769}
2770
2771
2772bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002773 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2774 ON_BAILOUT(isolate,
2775 "v8::Object::HasRealNamedCallbackProperty()",
2776 return false);
2777 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002778 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
2779 *Utils::OpenHandle(*key));
2780}
2781
2782
2783bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002784 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2785 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
2786 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002787 return Utils::OpenHandle(this)->HasNamedInterceptor();
2788}
2789
2790
2791bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01002792 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2793 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
2794 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002795 return Utils::OpenHandle(this)->HasIndexedInterceptor();
2796}
2797
2798
Ben Murdoch8b112d22011-06-08 16:22:53 +01002799static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
2800 i::Handle<i::JSObject> receiver,
2801 i::Handle<i::String> name,
2802 i::LookupResult* lookup) {
2803 if (!lookup->IsProperty()) {
2804 // No real property was found.
2805 return Local<Value>();
2806 }
2807
2808 // If the property being looked up is a callback, it can throw
2809 // an exception.
2810 EXCEPTION_PREAMBLE(isolate);
2811 i::Handle<i::Object> result = i::GetProperty(receiver, name, lookup);
2812 has_pending_exception = result.is_null();
2813 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
2814
2815 return Utils::ToLocal(result);
2816}
2817
2818
Steve Blocka7e24c12009-10-30 11:49:00 +00002819Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
2820 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002821 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2822 ON_BAILOUT(isolate,
2823 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00002824 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01002825 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->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002830 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00002831}
2832
2833
2834Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002835 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2836 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
2837 return Local<Value>());
2838 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002839 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2840 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2841 i::LookupResult lookup;
2842 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002843 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
Steve Blocka7e24c12009-10-30 11:49:00 +00002844}
2845
2846
2847// Turns on access checks by copying the map and setting the check flag.
2848// Because the object gets a new map, existing inline cache caching
2849// the old map of this object will fail.
2850void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01002851 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2852 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
2853 ENTER_V8(isolate);
2854 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002855 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
2856
Ben Murdochb0fe1622011-05-05 13:52:32 +01002857 // When turning on access checks for a global object deoptimize all functions
2858 // as optimized code does not always handle access checks.
2859 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
2860
Steve Blocka7e24c12009-10-30 11:49:00 +00002861 i::Handle<i::Map> new_map =
Steve Block44f0eee2011-05-26 01:26:41 +01002862 isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002863 new_map->set_is_access_check_needed(true);
2864 obj->set_map(*new_map);
2865}
2866
2867
2868bool v8::Object::IsDirty() {
2869 return Utils::OpenHandle(this)->IsDirty();
2870}
2871
2872
2873Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01002874 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2875 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
2876 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002877 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002878 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002879 i::Handle<i::JSObject> result = i::Copy(self);
2880 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002881 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002882 return Utils::ToLocal(result);
2883}
2884
2885
Ben Murdoch8b112d22011-06-08 16:22:53 +01002886static i::Context* GetCreationContext(i::JSObject* object) {
2887 i::Object* constructor = object->map()->constructor();
2888 i::JSFunction* function;
2889 if (!constructor->IsJSFunction()) {
2890 // API functions have null as a constructor,
2891 // but any JSFunction knows its context immediately.
2892 ASSERT(object->IsJSFunction() &&
2893 i::JSFunction::cast(object)->shared()->IsApiFunction());
2894 function = i::JSFunction::cast(object);
2895 } else {
2896 function = i::JSFunction::cast(constructor);
2897 }
2898 return function->context()->global_context();
2899}
2900
2901
2902Local<v8::Context> v8::Object::CreationContext() {
2903 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2904 ON_BAILOUT(isolate,
2905 "v8::Object::CreationContext()", return Local<v8::Context>());
2906 ENTER_V8(isolate);
2907 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2908 i::Context* context = GetCreationContext(*self);
2909 return Utils::ToLocal(i::Handle<i::Context>(context));
2910}
2911
2912
Steve Blocka7e24c12009-10-30 11:49:00 +00002913int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01002914 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2915 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
2916 ENTER_V8(isolate);
2917 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002918 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block1e0659c2011-05-24 12:43:12 +01002919 i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true));
2920 if (!hidden_props_obj->IsJSObject()) {
2921 // We failed to create hidden properties. That's a detached
2922 // global proxy.
2923 ASSERT(hidden_props_obj->IsUndefined());
2924 return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00002925 }
Steve Block1e0659c2011-05-24 12:43:12 +01002926 i::Handle<i::JSObject> hidden_props =
2927 i::Handle<i::JSObject>::cast(hidden_props_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002928 i::Handle<i::String> hash_symbol = isolate->factory()->identity_hash_symbol();
Steve Block1e0659c2011-05-24 12:43:12 +01002929 if (hidden_props->HasLocalProperty(*hash_symbol)) {
2930 i::Handle<i::Object> hash = i::GetProperty(hidden_props, hash_symbol);
2931 CHECK(!hash.is_null());
2932 CHECK(hash->IsSmi());
2933 return i::Smi::cast(*hash)->value();
2934 }
2935
2936 int hash_value;
2937 int attempts = 0;
2938 do {
2939 // Generate a random 32-bit hash value but limit range to fit
2940 // within a smi.
Steve Block44f0eee2011-05-26 01:26:41 +01002941 hash_value = i::V8::Random(self->GetIsolate()) & i::Smi::kMaxValue;
Steve Block1e0659c2011-05-24 12:43:12 +01002942 attempts++;
2943 } while (hash_value == 0 && attempts < 30);
2944 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
2945 CHECK(!i::SetLocalPropertyIgnoreAttributes(
2946 hidden_props,
2947 hash_symbol,
2948 i::Handle<i::Object>(i::Smi::FromInt(hash_value)),
2949 static_cast<PropertyAttributes>(None)).is_null());
2950
Steve Blocka7e24c12009-10-30 11:49:00 +00002951 return hash_value;
2952}
2953
2954
2955bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
2956 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01002957 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2958 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
2959 ENTER_V8(isolate);
2960 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002961 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2962 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true));
2963 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2964 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01002965 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002966 i::Handle<i::Object> obj = i::SetProperty(
2967 hidden_props,
2968 key_obj,
2969 value_obj,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002970 static_cast<PropertyAttributes>(None),
2971 i::kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002972 has_pending_exception = obj.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002973 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002974 return true;
2975}
2976
2977
2978v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002979 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2980 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
2981 return Local<v8::Value>());
2982 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002983 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2984 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
2985 if (hidden_props->IsUndefined()) {
2986 return v8::Local<v8::Value>();
2987 }
2988 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01002989 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002990 i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
2991 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01002992 EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002993 if (result->IsUndefined()) {
2994 return v8::Local<v8::Value>();
2995 }
2996 return Utils::ToLocal(result);
2997}
2998
2999
3000bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003001 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3002 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
3003 ENTER_V8(isolate);
3004 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003005 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3006 i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
3007 if (hidden_props->IsUndefined()) {
3008 return true;
3009 }
3010 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
3011 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3012 return i::DeleteProperty(js_obj, key_obj)->IsTrue();
3013}
3014
3015
Steve Block44f0eee2011-05-26 01:26:41 +01003016namespace {
3017
3018void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3019 void* data,
3020 ExternalArrayType array_type,
3021 int length) {
3022 i::Isolate* isolate = object->GetIsolate();
3023 i::Handle<i::ExternalArray> array =
3024 isolate->factory()->NewExternalArray(length, array_type, data);
3025
3026 // If the object already has external elements, create a new, unique
3027 // map if the element type is now changing, because assumptions about
3028 // generated code based on the receiver's map will be invalid.
3029 i::Handle<i::HeapObject> elements(object->elements());
3030 bool cant_reuse_map =
3031 elements->map()->IsUndefined() ||
3032 !elements->map()->has_external_array_elements() ||
3033 elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
3034 if (cant_reuse_map) {
3035 i::Handle<i::Map> external_array_map =
3036 isolate->factory()->GetExternalArrayElementsMap(
3037 i::Handle<i::Map>(object->map()),
3038 array_type,
3039 object->HasFastProperties());
3040 object->set_map(*external_array_map);
3041 }
3042 object->set_elements(*array);
3043}
3044
3045} // namespace
3046
3047
Steve Blocka7e24c12009-10-30 11:49:00 +00003048void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003049 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3050 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3051 ENTER_V8(isolate);
3052 i::HandleScope scope(isolate);
3053 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
Steve Blocka7e24c12009-10-30 11:49:00 +00003054 "v8::Object::SetIndexedPropertiesToPixelData()",
3055 "length exceeds max acceptable value")) {
3056 return;
3057 }
3058 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3059 if (!ApiCheck(!self->IsJSArray(),
3060 "v8::Object::SetIndexedPropertiesToPixelData()",
3061 "JSArray is not supported")) {
3062 return;
3063 }
Steve Block44f0eee2011-05-26 01:26:41 +01003064 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003065}
3066
3067
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003068bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003069 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003070 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3071 return false);
3072 return self->HasExternalPixelElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003073}
3074
3075
3076uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003077 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003078 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3079 return NULL);
3080 if (self->HasExternalPixelElements()) {
3081 return i::ExternalPixelArray::cast(self->elements())->
3082 external_pixel_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003083 } else {
3084 return NULL;
3085 }
3086}
3087
3088
3089int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003090 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003091 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3092 return -1);
3093 if (self->HasExternalPixelElements()) {
3094 return i::ExternalPixelArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003095 } else {
3096 return -1;
3097 }
3098}
3099
Steve Block3ce2e202009-11-05 08:53:23 +00003100void v8::Object::SetIndexedPropertiesToExternalArrayData(
3101 void* data,
3102 ExternalArrayType array_type,
3103 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003104 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3105 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3106 ENTER_V8(isolate);
3107 i::HandleScope scope(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003108 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3109 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3110 "length exceeds max acceptable value")) {
3111 return;
3112 }
3113 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3114 if (!ApiCheck(!self->IsJSArray(),
3115 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3116 "JSArray is not supported")) {
3117 return;
3118 }
Steve Block44f0eee2011-05-26 01:26:41 +01003119 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003120}
3121
3122
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003123bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003124 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003125 ON_BAILOUT(self->GetIsolate(),
3126 "v8::HasIndexedPropertiesInExternalArrayData()",
3127 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003128 return self->HasExternalArrayElements();
3129}
3130
3131
3132void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003133 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003134 ON_BAILOUT(self->GetIsolate(),
3135 "v8::GetIndexedPropertiesExternalArrayData()",
3136 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003137 if (self->HasExternalArrayElements()) {
3138 return i::ExternalArray::cast(self->elements())->external_pointer();
3139 } else {
3140 return NULL;
3141 }
3142}
3143
3144
3145ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003146 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003147 ON_BAILOUT(self->GetIsolate(),
3148 "v8::GetIndexedPropertiesExternalArrayDataType()",
3149 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003150 switch (self->elements()->map()->instance_type()) {
3151 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3152 return kExternalByteArray;
3153 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3154 return kExternalUnsignedByteArray;
3155 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3156 return kExternalShortArray;
3157 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3158 return kExternalUnsignedShortArray;
3159 case i::EXTERNAL_INT_ARRAY_TYPE:
3160 return kExternalIntArray;
3161 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3162 return kExternalUnsignedIntArray;
3163 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3164 return kExternalFloatArray;
Steve Block44f0eee2011-05-26 01:26:41 +01003165 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3166 return kExternalPixelArray;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003167 default:
3168 return static_cast<ExternalArrayType>(-1);
3169 }
3170}
3171
3172
3173int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003174 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003175 ON_BAILOUT(self->GetIsolate(),
3176 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3177 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003178 if (self->HasExternalArrayElements()) {
3179 return i::ExternalArray::cast(self->elements())->length();
3180 } else {
3181 return -1;
3182 }
3183}
3184
3185
Steve Blocka7e24c12009-10-30 11:49:00 +00003186Local<v8::Object> Function::NewInstance() const {
3187 return NewInstance(0, NULL);
3188}
3189
3190
3191Local<v8::Object> Function::NewInstance(int argc,
3192 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003193 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3194 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3195 return Local<v8::Object>());
3196 LOG_API(isolate, "Function::NewInstance");
3197 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003198 HandleScope scope;
3199 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3200 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3201 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003202 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003203 i::Handle<i::Object> returned =
3204 i::Execution::New(function, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003205 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003206 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3207}
3208
3209
3210Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3211 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01003212 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3213 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3214 LOG_API(isolate, "Function::Call");
3215 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003216 i::Object* raw_result = NULL;
3217 {
Steve Block44f0eee2011-05-26 01:26:41 +01003218 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003219 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3220 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3221 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
3222 i::Object*** args = reinterpret_cast<i::Object***>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01003223 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003224 i::Handle<i::Object> returned =
3225 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003226 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003227 raw_result = *returned;
3228 }
3229 i::Handle<i::Object> result(raw_result);
3230 return Utils::ToLocal(result);
3231}
3232
3233
3234void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01003235 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3236 ENTER_V8(isolate);
Steve Blockfa4227f2011-06-01 17:21:15 +01003237 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003238 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3239 func->shared()->set_name(*Utils::OpenHandle(*name));
3240}
3241
3242
3243Handle<Value> Function::GetName() const {
3244 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3245 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3246}
3247
3248
Andrei Popescu402d9372010-02-26 13:31:12 +00003249ScriptOrigin Function::GetScriptOrigin() const {
3250 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3251 if (func->shared()->script()->IsScript()) {
3252 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3253 v8::ScriptOrigin origin(
3254 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3255 v8::Integer::New(script->line_offset()->value()),
3256 v8::Integer::New(script->column_offset()->value()));
3257 return origin;
3258 }
3259 return v8::ScriptOrigin(Handle<Value>());
3260}
3261
3262
3263const int Function::kLineOffsetNotFound = -1;
3264
3265
3266int Function::GetScriptLineNumber() const {
3267 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3268 if (func->shared()->script()->IsScript()) {
3269 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3270 return i::GetScriptLineNumber(script, func->shared()->start_position());
3271 }
3272 return kLineOffsetNotFound;
3273}
3274
3275
Steve Blocka7e24c12009-10-30 11:49:00 +00003276int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003277 i::Handle<i::String> str = Utils::OpenHandle(this);
3278 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3279 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003280}
3281
3282
3283int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003284 i::Handle<i::String> str = Utils::OpenHandle(this);
3285 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
3286 return str->Utf8Length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003287}
3288
3289
Steve Block6ded16b2010-05-10 14:33:55 +01003290int String::WriteUtf8(char* buffer,
3291 int capacity,
3292 int* nchars_ref,
3293 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003294 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3295 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3296 LOG_API(isolate, "String::WriteUtf8");
3297 ENTER_V8(isolate);
3298 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003299 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003300 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003301 if (hints & HINT_MANY_WRITES_EXPECTED) {
3302 // Flatten the string for efficiency. This applies whether we are
3303 // using StringInputBuffer or Get(i) to access the characters.
3304 str->TryFlatten();
3305 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003306 write_input_buffer.Reset(0, *str);
3307 int len = str->length();
3308 // Encode the first K - 3 bytes directly into the buffer since we
3309 // know there's room for them. If no capacity is given we copy all
3310 // of them here.
3311 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3312 int i;
3313 int pos = 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003314 int nchars = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003315 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3316 i::uc32 c = write_input_buffer.GetNext();
3317 int written = unibrow::Utf8::Encode(buffer + pos, c);
3318 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003319 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003320 }
3321 if (i < len) {
3322 // For the last characters we need to check the length for each one
3323 // because they may be longer than the remaining space in the
3324 // buffer.
3325 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3326 for (; i < len && pos < capacity; i++) {
3327 i::uc32 c = write_input_buffer.GetNext();
3328 int written = unibrow::Utf8::Encode(intermediate, c);
3329 if (pos + written <= capacity) {
3330 for (int j = 0; j < written; j++)
3331 buffer[pos + j] = intermediate[j];
3332 pos += written;
Steve Block6ded16b2010-05-10 14:33:55 +01003333 nchars++;
Steve Blocka7e24c12009-10-30 11:49:00 +00003334 } else {
3335 // We've reached the end of the buffer
3336 break;
3337 }
3338 }
3339 }
Steve Block6ded16b2010-05-10 14:33:55 +01003340 if (nchars_ref != NULL) *nchars_ref = nchars;
Steve Blocka7e24c12009-10-30 11:49:00 +00003341 if (i == len && (capacity == -1 || pos < capacity))
3342 buffer[pos++] = '\0';
3343 return pos;
3344}
3345
3346
Steve Block6ded16b2010-05-10 14:33:55 +01003347int String::WriteAscii(char* buffer,
3348 int start,
3349 int length,
3350 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003351 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3352 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3353 LOG_API(isolate, "String::WriteAscii");
3354 ENTER_V8(isolate);
3355 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
Steve Blocka7e24c12009-10-30 11:49:00 +00003356 ASSERT(start >= 0 && length >= -1);
3357 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003358 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003359 if (hints & HINT_MANY_WRITES_EXPECTED) {
3360 // Flatten the string for efficiency. This applies whether we are
3361 // using StringInputBuffer or Get(i) to access the characters.
3362 str->TryFlatten();
3363 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003364 int end = length;
3365 if ( (length == -1) || (length > str->length() - start) )
3366 end = str->length() - start;
3367 if (end < 0) return 0;
3368 write_input_buffer.Reset(start, *str);
3369 int i;
3370 for (i = 0; i < end; i++) {
3371 char c = static_cast<char>(write_input_buffer.GetNext());
3372 if (c == '\0') c = ' ';
3373 buffer[i] = c;
3374 }
3375 if (length == -1 || i < length)
3376 buffer[i] = '\0';
3377 return i;
3378}
3379
3380
Steve Block6ded16b2010-05-10 14:33:55 +01003381int String::Write(uint16_t* buffer,
3382 int start,
3383 int length,
3384 WriteHints hints) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003385 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3386 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
3387 LOG_API(isolate, "String::Write");
3388 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003389 ASSERT(start >= 0 && length >= -1);
3390 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003391 isolate->string_tracker()->RecordWrite(str);
Steve Block6ded16b2010-05-10 14:33:55 +01003392 if (hints & HINT_MANY_WRITES_EXPECTED) {
3393 // Flatten the string for efficiency. This applies whether we are
3394 // using StringInputBuffer or Get(i) to access the characters.
3395 str->TryFlatten();
3396 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003397 int end = start + length;
3398 if ((length == -1) || (length > str->length() - start) )
3399 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00003400 if (end < 0) return 0;
3401 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003402 if (length == -1 || end - start < length) {
3403 buffer[end - start] = '\0';
3404 }
3405 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003406}
3407
3408
3409bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003410 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003411 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
3412 return false;
3413 }
3414 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
Steve Blocka7e24c12009-10-30 11:49:00 +00003415 return i::StringShape(*str).IsExternalTwoByte();
3416}
3417
3418
3419bool v8::String::IsExternalAscii() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003420 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003421 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
3422 return false;
3423 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003424 return i::StringShape(*str).IsExternalAscii();
3425}
3426
3427
3428void v8::String::VerifyExternalStringResource(
3429 v8::String::ExternalStringResource* value) const {
3430 i::Handle<i::String> str = Utils::OpenHandle(this);
3431 v8::String::ExternalStringResource* expected;
3432 if (i::StringShape(*str).IsExternalTwoByte()) {
3433 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
3434 expected = reinterpret_cast<ExternalStringResource*>(resource);
3435 } else {
3436 expected = NULL;
3437 }
3438 CHECK_EQ(expected, value);
3439}
3440
3441
3442v8::String::ExternalAsciiStringResource*
3443 v8::String::GetExternalAsciiStringResource() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003444 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003445 if (IsDeadCheck(str->GetIsolate(),
3446 "v8::String::GetExternalAsciiStringResource()")) {
3447 return NULL;
3448 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003449 if (i::StringShape(*str).IsExternalAscii()) {
3450 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
3451 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
3452 } else {
3453 return NULL;
3454 }
3455}
3456
3457
3458double Number::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003459 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003460 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3461 return obj->Number();
3462}
3463
3464
3465bool Boolean::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003466 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003467 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3468 return obj->IsTrue();
3469}
3470
3471
3472int64_t Integer::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003473 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003474 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3475 if (obj->IsSmi()) {
3476 return i::Smi::cast(*obj)->value();
3477 } else {
3478 return static_cast<int64_t>(obj->Number());
3479 }
3480}
3481
3482
3483int32_t Int32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003484 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003485 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3486 if (obj->IsSmi()) {
3487 return i::Smi::cast(*obj)->value();
3488 } else {
3489 return static_cast<int32_t>(obj->Number());
3490 }
3491}
3492
3493
Steve Block6ded16b2010-05-10 14:33:55 +01003494uint32_t Uint32::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003495 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
Steve Block6ded16b2010-05-10 14:33:55 +01003496 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3497 if (obj->IsSmi()) {
3498 return i::Smi::cast(*obj)->value();
3499 } else {
3500 return static_cast<uint32_t>(obj->Number());
3501 }
3502}
3503
3504
Steve Blocka7e24c12009-10-30 11:49:00 +00003505int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003506 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003507 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
3508 return 0;
3509 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003510 return obj->GetInternalFieldCount();
3511}
3512
3513
3514Local<Value> v8::Object::CheckedGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003515 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003516 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
3517 return Local<Value>();
3518 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003519 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3520 "v8::Object::GetInternalField()",
3521 "Reading internal field out of bounds")) {
3522 return Local<Value>();
3523 }
3524 i::Handle<i::Object> value(obj->GetInternalField(index));
3525 Local<Value> result = Utils::ToLocal(value);
3526#ifdef DEBUG
3527 Local<Value> unchecked = UncheckedGetInternalField(index);
3528 ASSERT(unchecked.IsEmpty() || (unchecked == result));
3529#endif
3530 return result;
3531}
3532
3533
3534void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003535 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003536 i::Isolate* isolate = obj->GetIsolate();
3537 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
3538 return;
3539 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003540 if (!ApiCheck(index < obj->GetInternalFieldCount(),
3541 "v8::Object::SetInternalField()",
3542 "Writing internal field out of bounds")) {
3543 return;
3544 }
Steve Block44f0eee2011-05-26 01:26:41 +01003545 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003546 i::Handle<i::Object> val = Utils::OpenHandle(*value);
3547 obj->SetInternalField(index, *val);
3548}
3549
3550
Ben Murdochb8e0da22011-05-16 14:20:40 +01003551static bool CanBeEncodedAsSmi(void* ptr) {
Steve Block1e0659c2011-05-24 12:43:12 +01003552 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003553 return ((address & i::kEncodablePointerMask) == 0);
3554}
3555
3556
3557static i::Smi* EncodeAsSmi(void* ptr) {
3558 ASSERT(CanBeEncodedAsSmi(ptr));
Steve Block1e0659c2011-05-24 12:43:12 +01003559 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003560 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
3561 ASSERT(i::Internals::HasSmiTag(result));
3562 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
3563 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
3564 return result;
3565}
3566
3567
Steve Blocka7e24c12009-10-30 11:49:00 +00003568void v8::Object::SetPointerInInternalField(int index, void* value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003569 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3570 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003571 if (CanBeEncodedAsSmi(value)) {
3572 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
3573 } else {
3574 HandleScope scope;
3575 i::Handle<i::Proxy> proxy =
Steve Block44f0eee2011-05-26 01:26:41 +01003576 isolate->factory()->NewProxy(
3577 reinterpret_cast<i::Address>(value), i::TENURED);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003578 if (!proxy.is_null())
3579 Utils::OpenHandle(this)->SetInternalField(index, *proxy);
Steve Block3ce2e202009-11-05 08:53:23 +00003580 }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003581 ASSERT_EQ(value, GetPointerFromInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003582}
3583
3584
3585// --- E n v i r o n m e n t ---
3586
Steve Block44f0eee2011-05-26 01:26:41 +01003587
Steve Blocka7e24c12009-10-30 11:49:00 +00003588bool v8::V8::Initialize() {
Steve Block44f0eee2011-05-26 01:26:41 +01003589 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
3590 if (isolate != NULL && isolate->IsInitialized()) {
3591 return true;
3592 }
3593 return InitializeHelper();
Steve Blocka7e24c12009-10-30 11:49:00 +00003594}
3595
3596
3597bool v8::V8::Dispose() {
Steve Block44f0eee2011-05-26 01:26:41 +01003598 i::Isolate* isolate = i::Isolate::Current();
3599 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
3600 "v8::V8::Dispose()",
3601 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
3602 return false;
3603 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003604 i::V8::TearDown();
3605 return true;
3606}
3607
3608
Russell Brenner90bac252010-11-18 13:33:46 -08003609HeapStatistics::HeapStatistics(): total_heap_size_(0),
3610 total_heap_size_executable_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01003611 used_heap_size_(0),
3612 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00003613
3614
3615void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
Steve Block44f0eee2011-05-26 01:26:41 +01003616 i::Heap* heap = i::Isolate::Current()->heap();
3617 heap_statistics->set_total_heap_size(heap->CommittedMemory());
Russell Brenner90bac252010-11-18 13:33:46 -08003618 heap_statistics->set_total_heap_size_executable(
Steve Block44f0eee2011-05-26 01:26:41 +01003619 heap->CommittedMemoryExecutable());
3620 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
3621 heap_statistics->set_heap_size_limit(heap->MaxReserved());
Steve Block3ce2e202009-11-05 08:53:23 +00003622}
3623
3624
3625bool v8::V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003626 // Returning true tells the caller that it need not
3627 // continue to call IdleNotification.
Steve Block44f0eee2011-05-26 01:26:41 +01003628 if (!i::Isolate::Current()->IsInitialized()) return true;
Steve Block3ce2e202009-11-05 08:53:23 +00003629 return i::V8::IdleNotification();
Steve Blocka7e24c12009-10-30 11:49:00 +00003630}
3631
3632
3633void v8::V8::LowMemoryNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003634 i::Isolate* isolate = i::Isolate::Current();
3635 if (!isolate->IsInitialized()) return;
3636 isolate->heap()->CollectAllGarbage(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003637}
3638
3639
Steve Block6ded16b2010-05-10 14:33:55 +01003640int v8::V8::ContextDisposedNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01003641 i::Isolate* isolate = i::Isolate::Current();
3642 if (!isolate->IsInitialized()) return 0;
3643 return isolate->heap()->NotifyContextDisposed();
Steve Block6ded16b2010-05-10 14:33:55 +01003644}
3645
3646
Steve Blocka7e24c12009-10-30 11:49:00 +00003647const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01003648 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00003649}
3650
3651
3652static i::Handle<i::FunctionTemplateInfo>
3653 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
3654 if (templ->constructor()->IsUndefined()) {
3655 Local<FunctionTemplate> constructor = FunctionTemplate::New();
3656 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
3657 templ->set_constructor(*Utils::OpenHandle(*constructor));
3658 }
3659 return i::Handle<i::FunctionTemplateInfo>(
3660 i::FunctionTemplateInfo::cast(templ->constructor()));
3661}
3662
3663
3664Persistent<Context> v8::Context::New(
3665 v8::ExtensionConfiguration* extensions,
3666 v8::Handle<ObjectTemplate> global_template,
3667 v8::Handle<Value> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01003668 i::Isolate* isolate = i::Isolate::Current();
3669 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
3670 LOG_API(isolate, "Context::New");
3671 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003672
3673 // Enter V8 via an ENTER_V8 scope.
3674 i::Handle<i::Context> env;
3675 {
Steve Block44f0eee2011-05-26 01:26:41 +01003676 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003677 v8::Handle<ObjectTemplate> proxy_template = global_template;
3678 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
3679 i::Handle<i::FunctionTemplateInfo> global_constructor;
3680
3681 if (!global_template.IsEmpty()) {
3682 // Make sure that the global_template has a constructor.
3683 global_constructor =
3684 EnsureConstructor(Utils::OpenHandle(*global_template));
3685
3686 // Create a fresh template for the global proxy object.
3687 proxy_template = ObjectTemplate::New();
3688 proxy_constructor =
3689 EnsureConstructor(Utils::OpenHandle(*proxy_template));
3690
3691 // Set the global template to be the prototype template of
3692 // global proxy template.
3693 proxy_constructor->set_prototype_template(
3694 *Utils::OpenHandle(*global_template));
3695
3696 // Migrate security handlers from global_template to
3697 // proxy_template. Temporarily removing access check
3698 // information from the global template.
3699 if (!global_constructor->access_check_info()->IsUndefined()) {
3700 proxy_constructor->set_access_check_info(
3701 global_constructor->access_check_info());
3702 proxy_constructor->set_needs_access_check(
3703 global_constructor->needs_access_check());
3704 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01003705 global_constructor->set_access_check_info(
3706 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003707 }
3708 }
3709
3710 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01003711 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdoch8b112d22011-06-08 16:22:53 +01003712 isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00003713 Utils::OpenHandle(*global_object),
3714 proxy_template,
3715 extensions);
3716
3717 // Restore the access check info on the global template.
3718 if (!global_template.IsEmpty()) {
3719 ASSERT(!global_constructor.is_null());
3720 ASSERT(!proxy_constructor.is_null());
3721 global_constructor->set_access_check_info(
3722 proxy_constructor->access_check_info());
3723 global_constructor->set_needs_access_check(
3724 proxy_constructor->needs_access_check());
3725 }
Steve Block44f0eee2011-05-26 01:26:41 +01003726 isolate->runtime_profiler()->Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +00003727 }
3728 // Leave V8.
3729
3730 if (env.is_null())
3731 return Persistent<Context>();
3732 return Persistent<Context>(Utils::ToLocal(env));
3733}
3734
3735
3736void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01003737 i::Isolate* isolate = i::Isolate::Current();
3738 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
3739 return;
3740 }
3741 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003742 i::Handle<i::Context> env = Utils::OpenHandle(this);
3743 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
3744 env->set_security_token(*token_handle);
3745}
3746
3747
3748void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003749 i::Isolate* isolate = i::Isolate::Current();
3750 if (IsDeadCheck(isolate,
3751 "v8::Context::UseDefaultSecurityToken()")) {
3752 return;
3753 }
3754 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003755 i::Handle<i::Context> env = Utils::OpenHandle(this);
3756 env->set_security_token(env->global());
3757}
3758
3759
3760Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01003761 i::Isolate* isolate = i::Isolate::Current();
3762 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
3763 return Handle<Value>();
3764 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003765 i::Handle<i::Context> env = Utils::OpenHandle(this);
3766 i::Object* security_token = env->security_token();
3767 i::Handle<i::Object> token_handle(security_token);
3768 return Utils::ToLocal(token_handle);
3769}
3770
3771
3772bool Context::HasOutOfMemoryException() {
3773 i::Handle<i::Context> env = Utils::OpenHandle(this);
3774 return env->has_out_of_memory();
3775}
3776
3777
3778bool Context::InContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01003779 return i::Isolate::Current()->context() != NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00003780}
3781
3782
3783v8::Local<v8::Context> Context::GetEntered() {
Steve Block44f0eee2011-05-26 01:26:41 +01003784 i::Isolate* isolate = i::Isolate::Current();
3785 if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
3786 return Local<Context>();
3787 }
3788 i::Handle<i::Object> last =
3789 isolate->handle_scope_implementer()->LastEnteredContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003790 if (last.is_null()) return Local<Context>();
3791 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
3792 return Utils::ToLocal(context);
3793}
3794
3795
3796v8::Local<v8::Context> Context::GetCurrent() {
Steve Block44f0eee2011-05-26 01:26:41 +01003797 i::Isolate* isolate = i::Isolate::Current();
3798 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
3799 return Local<Context>();
3800 }
3801 i::Handle<i::Object> current = isolate->global_context();
Steve Block3ce2e202009-11-05 08:53:23 +00003802 if (current.is_null()) return Local<Context>();
3803 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
Steve Blocka7e24c12009-10-30 11:49:00 +00003804 return Utils::ToLocal(context);
3805}
3806
3807
3808v8::Local<v8::Context> Context::GetCalling() {
Steve Block44f0eee2011-05-26 01:26:41 +01003809 i::Isolate* isolate = i::Isolate::Current();
3810 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
3811 return Local<Context>();
3812 }
3813 i::Handle<i::Object> calling =
3814 isolate->GetCallingGlobalContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00003815 if (calling.is_null()) return Local<Context>();
3816 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
3817 return Utils::ToLocal(context);
3818}
3819
3820
3821v8::Local<v8::Object> Context::Global() {
Steve Block44f0eee2011-05-26 01:26:41 +01003822 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
3823 return Local<v8::Object>();
3824 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003825 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3826 i::Handle<i::Context> context =
3827 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
3828 i::Handle<i::Object> global(context->global_proxy());
3829 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
3830}
3831
3832
3833void Context::DetachGlobal() {
Steve Block44f0eee2011-05-26 01:26:41 +01003834 i::Isolate* isolate = i::Isolate::Current();
3835 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
3836 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003837 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3838 i::Handle<i::Context> context =
3839 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01003840 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00003841}
3842
3843
Andrei Popescu74b3c142010-03-29 12:03:09 +01003844void Context::ReattachGlobal(Handle<Object> global_object) {
Steve Block44f0eee2011-05-26 01:26:41 +01003845 i::Isolate* isolate = i::Isolate::Current();
3846 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
3847 ENTER_V8(isolate);
Andrei Popescu74b3c142010-03-29 12:03:09 +01003848 i::Object** ctx = reinterpret_cast<i::Object**>(this);
3849 i::Handle<i::Context> context =
3850 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
Steve Block44f0eee2011-05-26 01:26:41 +01003851 isolate->bootstrapper()->ReattachGlobal(
3852 context,
3853 Utils::OpenHandle(*global_object));
3854}
3855
3856
3857void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
3858 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
Andrei Popescu74b3c142010-03-29 12:03:09 +01003859}
3860
3861
Steve Blocka7e24c12009-10-30 11:49:00 +00003862Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01003863 i::Isolate* isolate = i::Isolate::Current();
3864 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
3865 return Local<v8::Object>());
3866 LOG_API(isolate, "ObjectTemplate::NewInstance");
3867 ENTER_V8(isolate);
3868 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003869 i::Handle<i::Object> obj =
3870 i::Execution::InstantiateObject(Utils::OpenHandle(this),
3871 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003872 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003873 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
3874}
3875
3876
3877Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01003878 i::Isolate* isolate = i::Isolate::Current();
3879 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003880 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01003881 LOG_API(isolate, "FunctionTemplate::GetFunction");
3882 ENTER_V8(isolate);
3883 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003884 i::Handle<i::Object> obj =
3885 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
3886 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01003887 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003888 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
3889}
3890
3891
3892bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003893 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
3894 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003895 i::Object* obj = *Utils::OpenHandle(*value);
3896 return obj->IsInstanceOf(*Utils::OpenHandle(this));
3897}
3898
3899
3900static Local<External> ExternalNewImpl(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01003901 return Utils::ToLocal(FACTORY->NewProxy(static_cast<i::Address>(data)));
Steve Blocka7e24c12009-10-30 11:49:00 +00003902}
3903
3904static void* ExternalValueImpl(i::Handle<i::Object> obj) {
3905 return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy());
3906}
3907
3908
Steve Blocka7e24c12009-10-30 11:49:00 +00003909Local<Value> v8::External::Wrap(void* data) {
Steve Block44f0eee2011-05-26 01:26:41 +01003910 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00003911 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01003912 LOG_API(isolate, "External::Wrap");
3913 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
3914 ENTER_V8(isolate);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003915
3916 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
3917 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
3918 : v8::Local<v8::Value>(ExternalNewImpl(data));
3919
3920 ASSERT_EQ(data, Unwrap(result));
3921 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003922}
3923
3924
Steve Block3ce2e202009-11-05 08:53:23 +00003925void* v8::Object::SlowGetPointerFromInternalField(int index) {
3926 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3927 i::Object* value = obj->GetInternalField(index);
3928 if (value->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01003929 return i::Internals::GetExternalPointerFromSmi(value);
Steve Block3ce2e202009-11-05 08:53:23 +00003930 } else if (value->IsProxy()) {
3931 return reinterpret_cast<void*>(i::Proxy::cast(value)->proxy());
3932 } else {
3933 return NULL;
3934 }
3935}
3936
3937
Steve Blocka7e24c12009-10-30 11:49:00 +00003938void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
Steve Block44f0eee2011-05-26 01:26:41 +01003939 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003940 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
3941 void* result;
3942 if (obj->IsSmi()) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01003943 result = i::Internals::GetExternalPointerFromSmi(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00003944 } else if (obj->IsProxy()) {
3945 result = ExternalValueImpl(obj);
3946 } else {
3947 result = NULL;
3948 }
3949 ASSERT_EQ(result, QuickUnwrap(wrapper));
3950 return result;
3951}
3952
3953
3954Local<External> v8::External::New(void* data) {
3955 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
Steve Block44f0eee2011-05-26 01:26:41 +01003956 i::Isolate* isolate = i::Isolate::Current();
3957 LOG_API(isolate, "External::New");
3958 EnsureInitializedForIsolate(isolate, "v8::External::New()");
3959 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003960 return ExternalNewImpl(data);
3961}
3962
3963
3964void* External::Value() const {
Steve Block44f0eee2011-05-26 01:26:41 +01003965 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003966 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3967 return ExternalValueImpl(obj);
3968}
3969
3970
3971Local<String> v8::String::Empty() {
Steve Block44f0eee2011-05-26 01:26:41 +01003972 i::Isolate* isolate = i::Isolate::Current();
3973 EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
3974 LOG_API(isolate, "String::Empty()");
3975 return Utils::ToLocal(isolate->factory()->empty_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +00003976}
3977
3978
3979Local<String> v8::String::New(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003980 i::Isolate* isolate = i::Isolate::Current();
3981 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3982 LOG_API(isolate, "String::New(char)");
Steve Blocka7e24c12009-10-30 11:49:00 +00003983 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01003984 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00003985 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00003986 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01003987 isolate->factory()->NewStringFromUtf8(
3988 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00003989 return Utils::ToLocal(result);
3990}
3991
3992
Steve Block3ce2e202009-11-05 08:53:23 +00003993Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00003994 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01003995 i::Isolate* isolate = left_string->GetIsolate();
3996 EnsureInitializedForIsolate(isolate, "v8::String::New()");
3997 LOG_API(isolate, "String::New(char)");
3998 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00003999 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Steve Block44f0eee2011-05-26 01:26:41 +01004000 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
4001 right_string);
Steve Block3ce2e202009-11-05 08:53:23 +00004002 return Utils::ToLocal(result);
4003}
4004
4005
Steve Blocka7e24c12009-10-30 11:49:00 +00004006Local<String> v8::String::NewUndetectable(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004007 i::Isolate* isolate = i::Isolate::Current();
4008 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4009 LOG_API(isolate, "String::NewUndetectable(char)");
4010 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004011 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004012 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004013 isolate->factory()->NewStringFromUtf8(
4014 i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004015 result->MarkAsUndetectable();
4016 return Utils::ToLocal(result);
4017}
4018
4019
4020static int TwoByteStringLength(const uint16_t* data) {
4021 int length = 0;
4022 while (data[length] != '\0') length++;
4023 return length;
4024}
4025
4026
4027Local<String> v8::String::New(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004028 i::Isolate* isolate = i::Isolate::Current();
4029 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4030 LOG_API(isolate, "String::New(uint16_)");
Steve Blocka7e24c12009-10-30 11:49:00 +00004031 if (length == 0) return Empty();
Steve Block44f0eee2011-05-26 01:26:41 +01004032 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004033 if (length == -1) length = TwoByteStringLength(data);
4034 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004035 isolate->factory()->NewStringFromTwoByte(
4036 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004037 return Utils::ToLocal(result);
4038}
4039
4040
4041Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004042 i::Isolate* isolate = i::Isolate::Current();
4043 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4044 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4045 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004046 if (length == -1) length = TwoByteStringLength(data);
4047 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004048 isolate->factory()->NewStringFromTwoByte(
4049 i::Vector<const uint16_t>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004050 result->MarkAsUndetectable();
4051 return Utils::ToLocal(result);
4052}
4053
4054
Steve Block44f0eee2011-05-26 01:26:41 +01004055i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004056 v8::String::ExternalStringResource* resource) {
4057 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004058 isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004059 return result;
4060}
4061
4062
Steve Block44f0eee2011-05-26 01:26:41 +01004063i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00004064 v8::String::ExternalAsciiStringResource* resource) {
4065 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004066 isolate->factory()->NewExternalStringFromAscii(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004067 return result;
4068}
4069
4070
Steve Blocka7e24c12009-10-30 11:49:00 +00004071Local<String> v8::String::NewExternal(
4072 v8::String::ExternalStringResource* 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 = NewExternalStringHandle(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(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004084 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004085 i::Isolate* isolate = obj->GetIsolate();
4086 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4087 if (i::StringShape(*obj).IsExternalTwoByte()) {
4088 return false; // Already an external string.
4089 }
4090 ENTER_V8(isolate);
4091 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4092 return false;
4093 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004094 bool result = obj->MakeExternal(resource);
4095 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004096 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004097 }
4098 return result;
4099}
4100
4101
4102Local<String> v8::String::NewExternal(
4103 v8::String::ExternalAsciiStringResource* resource) {
Steve Block44f0eee2011-05-26 01:26:41 +01004104 i::Isolate* isolate = i::Isolate::Current();
4105 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4106 LOG_API(isolate, "String::NewExternal");
4107 ENTER_V8(isolate);
4108 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4109 isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004110 return Utils::ToLocal(result);
4111}
4112
4113
4114bool v8::String::MakeExternal(
4115 v8::String::ExternalAsciiStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004116 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004117 i::Isolate* isolate = obj->GetIsolate();
4118 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4119 if (i::StringShape(*obj).IsExternalTwoByte()) {
4120 return false; // Already an external string.
4121 }
4122 ENTER_V8(isolate);
4123 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4124 return false;
4125 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004126 bool result = obj->MakeExternal(resource);
4127 if (result && !obj->IsSymbol()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004128 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004129 }
4130 return result;
4131}
4132
4133
4134bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004135 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004136 i::Isolate* isolate = obj->GetIsolate();
4137 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4138 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4139 return false;
4140 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004141 int size = obj->Size(); // Byte size of the original string.
4142 if (size < i::ExternalString::kSize)
4143 return false;
4144 i::StringShape shape(*obj);
4145 return !shape.IsExternal();
4146}
4147
4148
4149Local<v8::Object> v8::Object::New() {
Steve Block44f0eee2011-05-26 01:26:41 +01004150 i::Isolate* isolate = i::Isolate::Current();
4151 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4152 LOG_API(isolate, "Object::New");
4153 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004154 i::Handle<i::JSObject> obj =
Steve Block44f0eee2011-05-26 01:26:41 +01004155 isolate->factory()->NewJSObject(isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00004156 return Utils::ToLocal(obj);
4157}
4158
4159
4160Local<v8::Value> v8::Date::New(double time) {
Steve Block44f0eee2011-05-26 01:26:41 +01004161 i::Isolate* isolate = i::Isolate::Current();
4162 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4163 LOG_API(isolate, "Date::New");
Steve Blockd0582a62009-12-15 09:54:21 +00004164 if (isnan(time)) {
4165 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4166 time = i::OS::nan_value();
4167 }
Steve Block44f0eee2011-05-26 01:26:41 +01004168 ENTER_V8(isolate);
4169 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004170 i::Handle<i::Object> obj =
4171 i::Execution::NewDate(time, &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004172 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004173 return Utils::ToLocal(obj);
4174}
4175
4176
4177double v8::Date::NumberValue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004178 i::Isolate* isolate = i::Isolate::Current();
4179 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4180 LOG_API(isolate, "Date::NumberValue");
Steve Blocka7e24c12009-10-30 11:49:00 +00004181 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4182 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4183 return jsvalue->value()->Number();
4184}
4185
4186
Ben Murdochb0fe1622011-05-05 13:52:32 +01004187void v8::Date::DateTimeConfigurationChangeNotification() {
Steve Block44f0eee2011-05-26 01:26:41 +01004188 i::Isolate* isolate = i::Isolate::Current();
4189 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4190 return);
4191 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
4192 ENTER_V8(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004193
Steve Block44f0eee2011-05-26 01:26:41 +01004194 i::HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004195 // Get the function ResetDateCache (defined in date-delay.js).
4196 i::Handle<i::String> func_name_str =
Steve Block44f0eee2011-05-26 01:26:41 +01004197 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4198 i::MaybeObject* result =
4199 isolate->js_builtins_object()->GetProperty(*func_name_str);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004200 i::Object* object_func;
4201 if (!result->ToObject(&object_func)) {
4202 return;
4203 }
4204
4205 if (object_func->IsJSFunction()) {
4206 i::Handle<i::JSFunction> func =
4207 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4208
4209 // Call ResetDateCache(0 but expect no exceptions:
4210 bool caught_exception = false;
Ben Murdoch8b112d22011-06-08 16:22:53 +01004211 i::Execution::TryCall(func,
4212 isolate->js_builtins_object(),
4213 0,
4214 NULL,
4215 &caught_exception);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004216 }
4217}
4218
4219
Ben Murdochf87a2032010-10-22 12:50:53 +01004220static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4221 char flags_buf[3];
4222 int num_flags = 0;
4223 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4224 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4225 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4226 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
Steve Block44f0eee2011-05-26 01:26:41 +01004227 return FACTORY->LookupSymbol(
Ben Murdochf87a2032010-10-22 12:50:53 +01004228 i::Vector<const char>(flags_buf, num_flags));
4229}
4230
4231
4232Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4233 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01004234 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
4235 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
4236 LOG_API(isolate, "RegExp::New");
4237 ENTER_V8(isolate);
4238 EXCEPTION_PREAMBLE(isolate);
Ben Murdochf87a2032010-10-22 12:50:53 +01004239 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
4240 Utils::OpenHandle(*pattern),
4241 RegExpFlagsToString(flags),
4242 &has_pending_exception);
Steve Block44f0eee2011-05-26 01:26:41 +01004243 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01004244 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
4245}
4246
4247
4248Local<v8::String> v8::RegExp::GetSource() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004249 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4250 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
4251 return Local<v8::String>();
4252 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004253 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4254 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
4255}
4256
4257
4258// Assert that the static flags cast in GetFlags is valid.
4259#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
4260 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
4261 static_cast<int>(i::JSRegExp::internal_flag))
4262REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
4263REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
4264REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
4265REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
4266#undef REGEXP_FLAG_ASSERT_EQ
4267
4268v8::RegExp::Flags v8::RegExp::GetFlags() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004269 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
4270 return v8::RegExp::kNone;
4271 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004272 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
4273 return static_cast<RegExp::Flags>(obj->GetFlags().value());
4274}
4275
4276
Steve Blocka7e24c12009-10-30 11:49:00 +00004277Local<v8::Array> v8::Array::New(int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004278 i::Isolate* isolate = i::Isolate::Current();
4279 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
4280 LOG_API(isolate, "Array::New");
4281 ENTER_V8(isolate);
4282 int real_length = length > 0 ? length : 0;
4283 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004284 i::Handle<i::Object> length_obj =
4285 isolate->factory()->NewNumberFromInt(real_length);
4286 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00004287 return Utils::ToLocal(obj);
4288}
4289
4290
4291uint32_t v8::Array::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004292 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4293 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004294 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
4295 i::Object* length = obj->length();
4296 if (length->IsSmi()) {
4297 return i::Smi::cast(length)->value();
4298 } else {
4299 return static_cast<uint32_t>(length->Number());
4300 }
4301}
4302
4303
4304Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01004305 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4306 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004307 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
4308 if (!self->HasFastElements()) {
4309 return Local<Object>();
4310 }
4311 i::FixedArray* elms = i::FixedArray::cast(self->elements());
4312 i::Object* paragon = elms->get(index);
4313 if (!paragon->IsJSObject()) {
4314 return Local<Object>();
4315 }
4316 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01004317 EXCEPTION_PREAMBLE(isolate);
4318 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004319 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
4320 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01004321 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00004322 return Utils::ToLocal(result);
4323}
4324
4325
4326Local<String> v8::String::NewSymbol(const char* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01004327 i::Isolate* isolate = i::Isolate::Current();
4328 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
4329 LOG_API(isolate, "String::NewSymbol(char)");
4330 ENTER_V8(isolate);
Steve Blockd0582a62009-12-15 09:54:21 +00004331 if (length == -1) length = i::StrLength(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00004332 i::Handle<i::String> result =
Steve Block44f0eee2011-05-26 01:26:41 +01004333 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
Steve Blocka7e24c12009-10-30 11:49:00 +00004334 return Utils::ToLocal(result);
4335}
4336
4337
4338Local<Number> v8::Number::New(double value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004339 i::Isolate* isolate = i::Isolate::Current();
4340 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
Steve Blockd0582a62009-12-15 09:54:21 +00004341 if (isnan(value)) {
4342 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4343 value = i::OS::nan_value();
4344 }
Steve Block44f0eee2011-05-26 01:26:41 +01004345 ENTER_V8(isolate);
4346 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004347 return Utils::NumberToLocal(result);
4348}
4349
4350
4351Local<Integer> v8::Integer::New(int32_t value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004352 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4353 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004354 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004355 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
4356 isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004357 }
Steve Block44f0eee2011-05-26 01:26:41 +01004358 ENTER_V8(isolate);
4359 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004360 return Utils::IntegerToLocal(result);
4361}
4362
4363
Steve Block3ce2e202009-11-05 08:53:23 +00004364Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
4365 bool fits_into_int32_t = (value & (1 << 31)) == 0;
4366 if (fits_into_int32_t) {
4367 return Integer::New(static_cast<int32_t>(value));
4368 }
Steve Block44f0eee2011-05-26 01:26:41 +01004369 i::Isolate* isolate = i::Isolate::Current();
4370 ENTER_V8(isolate);
4371 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00004372 return Utils::IntegerToLocal(result);
4373}
4374
4375
Steve Blocka7e24c12009-10-30 11:49:00 +00004376void V8::IgnoreOutOfMemoryException() {
Steve Block44f0eee2011-05-26 01:26:41 +01004377 EnterIsolateIfNeeded()->handle_scope_implementer()->set_ignore_out_of_memory(
4378 true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004379}
4380
4381
4382bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004383 i::Isolate* isolate = i::Isolate::Current();
4384 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
4385 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
4386 ENTER_V8(isolate);
4387 i::HandleScope scope(isolate);
4388 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004389 NeanderObject obj(2);
Steve Block44f0eee2011-05-26 01:26:41 +01004390 obj.set(0, *isolate->factory()->NewProxy(FUNCTION_ADDR(that)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004391 obj.set(1, data.IsEmpty() ?
Steve Block44f0eee2011-05-26 01:26:41 +01004392 isolate->heap()->undefined_value() :
Steve Blocka7e24c12009-10-30 11:49:00 +00004393 *Utils::OpenHandle(*data));
4394 listeners.add(obj.value());
4395 return true;
4396}
4397
4398
4399void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01004400 i::Isolate* isolate = i::Isolate::Current();
4401 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
4402 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
4403 ENTER_V8(isolate);
4404 i::HandleScope scope(isolate);
4405 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00004406 for (int i = 0; i < listeners.length(); i++) {
4407 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
4408
4409 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
4410 i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
4411 if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004412 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004413 }
4414 }
4415}
4416
4417
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004418void V8::SetCaptureStackTraceForUncaughtExceptions(
4419 bool capture,
4420 int frame_limit,
4421 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01004422 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004423 capture,
4424 frame_limit,
4425 options);
4426}
4427
4428
Steve Blocka7e24c12009-10-30 11:49:00 +00004429void V8::SetCounterFunction(CounterLookupCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004430 i::Isolate* isolate = EnterIsolateIfNeeded();
4431 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
4432 isolate->stats_table()->SetCounterFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004433}
4434
4435void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004436 i::Isolate* isolate = EnterIsolateIfNeeded();
4437 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
4438 isolate->stats_table()->SetCreateHistogramFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004439}
4440
4441void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004442 i::Isolate* isolate = EnterIsolateIfNeeded();
4443 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
4444 isolate->stats_table()->
4445 SetAddHistogramSampleFunction(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004446}
4447
4448void V8::EnableSlidingStateWindow() {
Steve Block44f0eee2011-05-26 01:26:41 +01004449 i::Isolate* isolate = i::Isolate::Current();
4450 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
4451 isolate->logger()->EnableSlidingStateWindow();
Steve Blocka7e24c12009-10-30 11:49:00 +00004452}
4453
4454
4455void V8::SetFailedAccessCheckCallbackFunction(
4456 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004457 i::Isolate* isolate = i::Isolate::Current();
4458 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
4459 return;
4460 }
4461 isolate->SetFailedAccessCheckCallback(callback);
4462}
4463
4464void V8::AddObjectGroup(Persistent<Value>* objects,
4465 size_t length,
4466 RetainedObjectInfo* info) {
4467 i::Isolate* isolate = i::Isolate::Current();
4468 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
4469 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
4470 isolate->global_handles()->AddObjectGroup(
4471 reinterpret_cast<i::Object***>(objects), length, info);
Steve Blocka7e24c12009-10-30 11:49:00 +00004472}
4473
4474
Steve Block44f0eee2011-05-26 01:26:41 +01004475void V8::AddImplicitReferences(Persistent<Object> parent,
4476 Persistent<Value>* children,
4477 size_t length) {
4478 i::Isolate* isolate = i::Isolate::Current();
4479 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004480 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
Steve Block44f0eee2011-05-26 01:26:41 +01004481 isolate->global_handles()->AddImplicitReferences(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004482 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*parent)).location(),
Steve Block44f0eee2011-05-26 01:26:41 +01004483 reinterpret_cast<i::Object***>(children), length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004484}
4485
4486
4487int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
Steve Block44f0eee2011-05-26 01:26:41 +01004488 i::Isolate* isolate = i::Isolate::Current();
4489 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
4490 return 0;
4491 }
4492 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
4493 change_in_bytes);
Steve Blocka7e24c12009-10-30 11:49:00 +00004494}
4495
4496
4497void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004498 i::Isolate* isolate = i::Isolate::Current();
4499 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
4500 isolate->heap()->SetGlobalGCPrologueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004501}
4502
4503
4504void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004505 i::Isolate* isolate = i::Isolate::Current();
4506 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
4507 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00004508}
4509
4510
Steve Block6ded16b2010-05-10 14:33:55 +01004511void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004512 i::Isolate* isolate = i::Isolate::Current();
4513 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
4514 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004515}
4516
4517
4518void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004519 i::Isolate* isolate = i::Isolate::Current();
4520 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
4521 isolate->heap()->RemoveGCPrologueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004522}
4523
4524
4525void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004526 i::Isolate* isolate = i::Isolate::Current();
4527 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
4528 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
Steve Block6ded16b2010-05-10 14:33:55 +01004529}
4530
4531
4532void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004533 i::Isolate* isolate = i::Isolate::Current();
4534 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
4535 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Block6ded16b2010-05-10 14:33:55 +01004536}
4537
4538
Iain Merrick9ac36c92010-09-13 15:29:50 +01004539void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
4540 ObjectSpace space,
4541 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01004542 i::Isolate* isolate = i::Isolate::Current();
4543 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
4544 isolate->memory_allocator()->AddMemoryAllocationCallback(
4545 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004546}
4547
4548
4549void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01004550 i::Isolate* isolate = i::Isolate::Current();
4551 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
4552 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
4553 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004554}
4555
4556
Steve Blocka7e24c12009-10-30 11:49:00 +00004557void V8::PauseProfiler() {
4558#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004559 PauseProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004560#endif
4561}
4562
4563
4564void V8::ResumeProfiler() {
4565#ifdef ENABLE_LOGGING_AND_PROFILING
Andrei Popescu402d9372010-02-26 13:31:12 +00004566 ResumeProfilerEx(PROFILER_MODULE_CPU);
Steve Blocka7e24c12009-10-30 11:49:00 +00004567#endif
4568}
4569
4570
4571bool V8::IsProfilerPaused() {
4572#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004573 return LOGGER->GetActiveProfilerModules() & PROFILER_MODULE_CPU;
Steve Blocka7e24c12009-10-30 11:49:00 +00004574#else
4575 return true;
4576#endif
4577}
4578
4579
Andrei Popescu402d9372010-02-26 13:31:12 +00004580void V8::ResumeProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004581#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004582 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00004583 if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
4584 // Snapshot mode: resume modules, perform GC, then pause only
4585 // those modules which haven't been started prior to making a
4586 // snapshot.
4587
Steve Block6ded16b2010-05-10 14:33:55 +01004588 // Make a GC prior to taking a snapshot.
Steve Block44f0eee2011-05-26 01:26:41 +01004589 isolate->heap()->CollectAllGarbage(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004590 // Reset snapshot flag and CPU module flags.
4591 flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
Steve Block44f0eee2011-05-26 01:26:41 +01004592 const int current_flags = isolate->logger()->GetActiveProfilerModules();
4593 isolate->logger()->ResumeProfiler(flags, tag);
4594 isolate->heap()->CollectAllGarbage(false);
4595 isolate->logger()->PauseProfiler(~current_flags & flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004596 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004597 isolate->logger()->ResumeProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004598 }
4599#endif
4600}
4601
4602
Andrei Popescu402d9372010-02-26 13:31:12 +00004603void V8::PauseProfilerEx(int flags, int tag) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004604#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004605 LOGGER->PauseProfiler(flags, tag);
Steve Blocka7e24c12009-10-30 11:49:00 +00004606#endif
4607}
4608
4609
4610int V8::GetActiveProfilerModules() {
4611#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block44f0eee2011-05-26 01:26:41 +01004612 return LOGGER->GetActiveProfilerModules();
Steve Blocka7e24c12009-10-30 11:49:00 +00004613#else
4614 return PROFILER_MODULE_NONE;
4615#endif
4616}
4617
4618
4619int V8::GetLogLines(int from_pos, char* dest_buf, int max_size) {
4620#ifdef ENABLE_LOGGING_AND_PROFILING
Steve Block6ded16b2010-05-10 14:33:55 +01004621 ASSERT(max_size >= kMinimumSizeForLogLinesBuffer);
Steve Block44f0eee2011-05-26 01:26:41 +01004622 return LOGGER->GetLogLines(from_pos, dest_buf, max_size);
Steve Blocka7e24c12009-10-30 11:49:00 +00004623#endif
4624 return 0;
4625}
4626
4627
4628int V8::GetCurrentThreadId() {
Steve Block44f0eee2011-05-26 01:26:41 +01004629 i::Isolate* isolate = i::Isolate::Current();
4630 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
Ben Murdoch8b112d22011-06-08 16:22:53 +01004631 return isolate->thread_id().ToInteger();
Steve Blocka7e24c12009-10-30 11:49:00 +00004632}
4633
4634
4635void V8::TerminateExecution(int thread_id) {
Steve Block44f0eee2011-05-26 01:26:41 +01004636 i::Isolate* isolate = i::Isolate::Current();
4637 if (!isolate->IsInitialized()) return;
4638 API_ENTRY_CHECK("V8::TerminateExecution()");
Steve Blocka7e24c12009-10-30 11:49:00 +00004639 // If the thread_id identifies the current thread just terminate
4640 // execution right away. Otherwise, ask the thread manager to
4641 // terminate the thread with the given id if any.
Ben Murdoch8b112d22011-06-08 16:22:53 +01004642 i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
4643 if (isolate->thread_id().Equals(internal_tid)) {
Steve Block44f0eee2011-05-26 01:26:41 +01004644 isolate->stack_guard()->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00004645 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +01004646 isolate->thread_manager()->TerminateExecution(internal_tid);
Steve Blocka7e24c12009-10-30 11:49:00 +00004647 }
4648}
4649
4650
Steve Block44f0eee2011-05-26 01:26:41 +01004651void V8::TerminateExecution(Isolate* isolate) {
4652 // If no isolate is supplied, use the default isolate.
4653 if (isolate != NULL) {
4654 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
4655 } else {
4656 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
4657 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004658}
4659
4660
Steve Block6ded16b2010-05-10 14:33:55 +01004661bool V8::IsExecutionTerminating() {
Steve Block44f0eee2011-05-26 01:26:41 +01004662 i::Isolate* isolate = i::Isolate::Current();
4663 return IsExecutionTerminatingCheck(isolate);
4664}
4665
4666
4667Isolate* Isolate::GetCurrent() {
4668 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4669 return reinterpret_cast<Isolate*>(isolate);
4670}
4671
4672
4673Isolate* Isolate::New() {
4674 i::Isolate* isolate = new i::Isolate();
4675 return reinterpret_cast<Isolate*>(isolate);
4676}
4677
4678
4679void Isolate::Dispose() {
4680 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4681 if (!ApiCheck(!isolate->IsInUse(),
4682 "v8::Isolate::Dispose()",
4683 "Disposing the isolate that is entered by a thread.")) {
4684 return;
Steve Block6ded16b2010-05-10 14:33:55 +01004685 }
Steve Block44f0eee2011-05-26 01:26:41 +01004686 isolate->TearDown();
4687}
4688
4689
4690void Isolate::Enter() {
4691 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4692 isolate->Enter();
4693}
4694
4695
4696void Isolate::Exit() {
4697 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
4698 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01004699}
4700
4701
Steve Blocka7e24c12009-10-30 11:49:00 +00004702String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004703 i::Isolate* isolate = i::Isolate::Current();
4704 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004705 if (obj.IsEmpty()) {
4706 str_ = NULL;
4707 length_ = 0;
4708 return;
4709 }
Steve Block44f0eee2011-05-26 01:26:41 +01004710 ENTER_V8(isolate);
4711 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004712 TryCatch try_catch;
4713 Handle<String> str = obj->ToString();
4714 if (str.IsEmpty()) {
4715 str_ = NULL;
4716 length_ = 0;
4717 } else {
4718 length_ = str->Utf8Length();
4719 str_ = i::NewArray<char>(length_ + 1);
4720 str->WriteUtf8(str_);
4721 }
4722}
4723
4724
4725String::Utf8Value::~Utf8Value() {
4726 i::DeleteArray(str_);
4727}
4728
4729
4730String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004731 i::Isolate* isolate = i::Isolate::Current();
4732 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004733 if (obj.IsEmpty()) {
4734 str_ = NULL;
4735 length_ = 0;
4736 return;
4737 }
Steve Block44f0eee2011-05-26 01:26:41 +01004738 ENTER_V8(isolate);
4739 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004740 TryCatch try_catch;
4741 Handle<String> str = obj->ToString();
4742 if (str.IsEmpty()) {
4743 str_ = NULL;
4744 length_ = 0;
4745 } else {
4746 length_ = str->Length();
4747 str_ = i::NewArray<char>(length_ + 1);
4748 str->WriteAscii(str_);
4749 }
4750}
4751
4752
4753String::AsciiValue::~AsciiValue() {
4754 i::DeleteArray(str_);
4755}
4756
4757
4758String::Value::Value(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01004759 i::Isolate* isolate = i::Isolate::Current();
4760 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00004761 if (obj.IsEmpty()) {
4762 str_ = NULL;
4763 length_ = 0;
4764 return;
4765 }
Steve Block44f0eee2011-05-26 01:26:41 +01004766 ENTER_V8(isolate);
4767 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004768 TryCatch try_catch;
4769 Handle<String> str = obj->ToString();
4770 if (str.IsEmpty()) {
4771 str_ = NULL;
4772 length_ = 0;
4773 } else {
4774 length_ = str->Length();
4775 str_ = i::NewArray<uint16_t>(length_ + 1);
4776 str->Write(str_);
4777 }
4778}
4779
4780
4781String::Value::~Value() {
4782 i::DeleteArray(str_);
4783}
4784
4785Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004786 i::Isolate* isolate = i::Isolate::Current();
4787 LOG_API(isolate, "RangeError");
4788 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
4789 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004790 i::Object* error;
4791 {
Steve Block44f0eee2011-05-26 01:26:41 +01004792 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004793 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004794 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004795 error = *result;
4796 }
4797 i::Handle<i::Object> result(error);
4798 return Utils::ToLocal(result);
4799}
4800
4801Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004802 i::Isolate* isolate = i::Isolate::Current();
4803 LOG_API(isolate, "ReferenceError");
4804 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
4805 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004806 i::Object* error;
4807 {
Steve Block44f0eee2011-05-26 01:26:41 +01004808 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004809 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004810 i::Handle<i::Object> result =
4811 isolate->factory()->NewReferenceError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004812 error = *result;
4813 }
4814 i::Handle<i::Object> result(error);
4815 return Utils::ToLocal(result);
4816}
4817
4818Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004819 i::Isolate* isolate = i::Isolate::Current();
4820 LOG_API(isolate, "SyntaxError");
4821 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
4822 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004823 i::Object* error;
4824 {
Steve Block44f0eee2011-05-26 01:26:41 +01004825 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004826 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004827 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004828 error = *result;
4829 }
4830 i::Handle<i::Object> result(error);
4831 return Utils::ToLocal(result);
4832}
4833
4834Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004835 i::Isolate* isolate = i::Isolate::Current();
4836 LOG_API(isolate, "TypeError");
4837 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
4838 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004839 i::Object* error;
4840 {
Steve Block44f0eee2011-05-26 01:26:41 +01004841 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004842 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004843 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004844 error = *result;
4845 }
4846 i::Handle<i::Object> result(error);
4847 return Utils::ToLocal(result);
4848}
4849
4850Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004851 i::Isolate* isolate = i::Isolate::Current();
4852 LOG_API(isolate, "Error");
4853 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
4854 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004855 i::Object* error;
4856 {
Steve Block44f0eee2011-05-26 01:26:41 +01004857 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004858 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
Steve Block44f0eee2011-05-26 01:26:41 +01004859 i::Handle<i::Object> result = isolate->factory()->NewError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +00004860 error = *result;
4861 }
4862 i::Handle<i::Object> result(error);
4863 return Utils::ToLocal(result);
4864}
4865
4866
4867// --- D e b u g S u p p o r t ---
4868
4869#ifdef ENABLE_DEBUGGER_SUPPORT
Leon Clarkef7060e22010-06-03 12:02:55 +01004870
Leon Clarkef7060e22010-06-03 12:02:55 +01004871static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
Steve Block44f0eee2011-05-26 01:26:41 +01004872 i::Isolate* isolate = i::Isolate::Current();
4873 if (isolate->debug_event_callback() != NULL) {
4874 isolate->debug_event_callback()(event_details.GetEvent(),
4875 event_details.GetExecutionState(),
4876 event_details.GetEventData(),
4877 event_details.GetCallbackData());
Leon Clarkef7060e22010-06-03 12:02:55 +01004878 }
4879}
4880
4881
Steve Blocka7e24c12009-10-30 11:49:00 +00004882bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004883 i::Isolate* isolate = i::Isolate::Current();
4884 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
4885 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
4886 ENTER_V8(isolate);
Leon Clarkef7060e22010-06-03 12:02:55 +01004887
Steve Block44f0eee2011-05-26 01:26:41 +01004888 isolate->set_debug_event_callback(that);
Leon Clarkef7060e22010-06-03 12:02:55 +01004889
Steve Block44f0eee2011-05-26 01:26:41 +01004890 i::HandleScope scope(isolate);
4891 i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
Leon Clarkef7060e22010-06-03 12:02:55 +01004892 if (that != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01004893 proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(EventCallbackWrapper));
Leon Clarkef7060e22010-06-03 12:02:55 +01004894 }
Steve Block44f0eee2011-05-26 01:26:41 +01004895 isolate->debugger()->SetEventListener(proxy, Utils::OpenHandle(*data));
Leon Clarkef7060e22010-06-03 12:02:55 +01004896 return true;
4897}
4898
4899
4900bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004901 i::Isolate* isolate = i::Isolate::Current();
4902 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
4903 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
4904 ENTER_V8(isolate);
4905 i::HandleScope scope(isolate);
4906 i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00004907 if (that != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01004908 proxy = isolate->factory()->NewProxy(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00004909 }
Steve Block44f0eee2011-05-26 01:26:41 +01004910 isolate->debugger()->SetEventListener(proxy,
4911 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00004912 return true;
4913}
4914
4915
4916bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
4917 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01004918 i::Isolate* isolate = i::Isolate::Current();
4919 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
4920 ENTER_V8(isolate);
4921 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
4922 Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00004923 return true;
4924}
4925
4926
Steve Block44f0eee2011-05-26 01:26:41 +01004927void Debug::DebugBreak(Isolate* isolate) {
4928 // If no isolate is supplied, use the default isolate.
4929 if (isolate != NULL) {
4930 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
4931 } else {
4932 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
4933 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004934}
4935
4936
Steve Block44f0eee2011-05-26 01:26:41 +01004937void Debug::CancelDebugBreak(Isolate* isolate) {
4938 // If no isolate is supplied, use the default isolate.
4939 if (isolate != NULL) {
4940 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4941 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
4942 } else {
4943 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
4944 }
Ben Murdochf87a2032010-10-22 12:50:53 +01004945}
4946
4947
Steve Block44f0eee2011-05-26 01:26:41 +01004948void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
4949 // If no isolate is supplied, use the default isolate.
4950 if (isolate != NULL) {
4951 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
4952 internal_isolate->debugger()->EnqueueDebugCommand(data);
4953 } else {
4954 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
4955 }
Ben Murdoch3bec4d22010-07-22 14:51:16 +01004956}
4957
4958
Steve Blocka7e24c12009-10-30 11:49:00 +00004959static void MessageHandlerWrapper(const v8::Debug::Message& message) {
Steve Block44f0eee2011-05-26 01:26:41 +01004960 i::Isolate* isolate = i::Isolate::Current();
4961 if (isolate->message_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004962 v8::String::Value json(message.GetJSON());
Steve Block44f0eee2011-05-26 01:26:41 +01004963 (isolate->message_handler())(*json, json.length(), message.GetClientData());
Steve Blocka7e24c12009-10-30 11:49:00 +00004964 }
4965}
4966
4967
4968void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
4969 bool message_handler_thread) {
Steve Block44f0eee2011-05-26 01:26:41 +01004970 i::Isolate* isolate = i::Isolate::Current();
4971 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
4972 ENTER_V8(isolate);
4973
Steve Blocka7e24c12009-10-30 11:49:00 +00004974 // Message handler thread not supported any more. Parameter temporally left in
Steve Block44f0eee2011-05-26 01:26:41 +01004975 // the API for client compatibility reasons.
Steve Blocka7e24c12009-10-30 11:49:00 +00004976 CHECK(!message_handler_thread);
4977
4978 // TODO(sgjesse) support the old message handler API through a simple wrapper.
Steve Block44f0eee2011-05-26 01:26:41 +01004979 isolate->set_message_handler(handler);
4980 if (handler != NULL) {
4981 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
Steve Blocka7e24c12009-10-30 11:49:00 +00004982 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01004983 isolate->debugger()->SetMessageHandler(NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00004984 }
4985}
4986
4987
4988void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01004989 i::Isolate* isolate = i::Isolate::Current();
4990 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
4991 ENTER_V8(isolate);
4992 isolate->debugger()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00004993}
4994
4995
4996void Debug::SendCommand(const uint16_t* command, int length,
Steve Block44f0eee2011-05-26 01:26:41 +01004997 ClientData* client_data,
4998 Isolate* isolate) {
4999 // If no isolate is supplied, use the default isolate.
5000 if (isolate != NULL) {
5001 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5002 internal_isolate->debugger()->ProcessCommand(
5003 i::Vector<const uint16_t>(command, length), client_data);
5004 } else {
5005 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
5006 i::Vector<const uint16_t>(command, length), client_data);
5007 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005008}
5009
5010
5011void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
5012 int period) {
Steve Block44f0eee2011-05-26 01:26:41 +01005013 i::Isolate* isolate = i::Isolate::Current();
5014 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
5015 ENTER_V8(isolate);
5016 isolate->debugger()->SetHostDispatchHandler(handler, period);
Steve Blocka7e24c12009-10-30 11:49:00 +00005017}
5018
5019
Steve Blockd0582a62009-12-15 09:54:21 +00005020void Debug::SetDebugMessageDispatchHandler(
Leon Clarkee46be812010-01-19 14:06:41 +00005021 DebugMessageDispatchHandler handler, bool provide_locker) {
Steve Block44f0eee2011-05-26 01:26:41 +01005022 i::Isolate* isolate = i::Isolate::Current();
5023 EnsureInitializedForIsolate(isolate,
5024 "v8::Debug::SetDebugMessageDispatchHandler");
5025 ENTER_V8(isolate);
5026 isolate->debugger()->SetDebugMessageDispatchHandler(
5027 handler, provide_locker);
Steve Blockd0582a62009-12-15 09:54:21 +00005028}
5029
5030
Steve Blocka7e24c12009-10-30 11:49:00 +00005031Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
5032 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01005033 i::Isolate* isolate = i::Isolate::Current();
5034 if (!isolate->IsInitialized()) return Local<Value>();
5035 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
5036 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005037 i::Handle<i::Object> result;
Steve Block44f0eee2011-05-26 01:26:41 +01005038 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005039 if (data.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005040 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5041 isolate->factory()->undefined_value(),
5042 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005043 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005044 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5045 Utils::OpenHandle(*data),
5046 &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00005047 }
Steve Block44f0eee2011-05-26 01:26:41 +01005048 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005049 return Utils::ToLocal(result);
5050}
5051
5052
5053Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01005054 i::Isolate* isolate = i::Isolate::Current();
5055 if (!isolate->IsInitialized()) return Local<Value>();
5056 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
5057 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005058 v8::HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01005059 i::Debug* isolate_debug = isolate->debug();
5060 isolate_debug->Load();
5061 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5062 i::Handle<i::String> name =
5063 isolate->factory()->LookupAsciiSymbol("MakeMirror");
Steve Blocka7e24c12009-10-30 11:49:00 +00005064 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5065 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5066 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5067 const int kArgc = 1;
5068 v8::Handle<v8::Value> argv[kArgc] = { obj };
Steve Block44f0eee2011-05-26 01:26:41 +01005069 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005070 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5071 kArgc,
5072 argv);
Steve Block44f0eee2011-05-26 01:26:41 +01005073 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005074 return scope.Close(result);
5075}
5076
5077
Leon Clarkee46be812010-01-19 14:06:41 +00005078bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
Steve Block44f0eee2011-05-26 01:26:41 +01005079 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5080 wait_for_connection);
Steve Blocka7e24c12009-10-30 11:49:00 +00005081}
Leon Clarkee46be812010-01-19 14:06:41 +00005082
5083void Debug::ProcessDebugMessages() {
5084 i::Execution::ProcessDebugMesssages(true);
5085}
5086
Steve Block6ded16b2010-05-10 14:33:55 +01005087Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01005088 i::Isolate* isolate = i::Isolate::Current();
5089 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5090 ENTER_V8(isolate);
5091 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01005092}
5093
Steve Blocka7e24c12009-10-30 11:49:00 +00005094#endif // ENABLE_DEBUGGER_SUPPORT
5095
Steve Block6ded16b2010-05-10 14:33:55 +01005096
5097#ifdef ENABLE_LOGGING_AND_PROFILING
5098
5099Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005100 i::Isolate* isolate = i::Isolate::Current();
5101 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
Steve Block6ded16b2010-05-10 14:33:55 +01005102 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5103 const i::CodeEntry* entry = node->entry();
5104 if (!entry->has_name_prefix()) {
5105 return Handle<String>(ToApi<String>(
Steve Block44f0eee2011-05-26 01:26:41 +01005106 isolate->factory()->LookupAsciiSymbol(entry->name())));
Steve Block6ded16b2010-05-10 14:33:55 +01005107 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01005108 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5109 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5110 isolate->factory()->LookupAsciiSymbol(entry->name()))));
Steve Block6ded16b2010-05-10 14:33:55 +01005111 }
5112}
5113
5114
5115Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005116 i::Isolate* isolate = i::Isolate::Current();
5117 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
Steve Block6ded16b2010-05-10 14:33:55 +01005118 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005119 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005120 node->entry()->resource_name())));
5121}
5122
5123
5124int CpuProfileNode::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005125 i::Isolate* isolate = i::Isolate::Current();
5126 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
Steve Block6ded16b2010-05-10 14:33:55 +01005127 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5128}
5129
5130
5131double CpuProfileNode::GetTotalTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005132 i::Isolate* isolate = i::Isolate::Current();
5133 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005134 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5135}
5136
5137
5138double CpuProfileNode::GetSelfTime() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005139 i::Isolate* isolate = i::Isolate::Current();
5140 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
Steve Block6ded16b2010-05-10 14:33:55 +01005141 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5142}
5143
5144
5145double CpuProfileNode::GetTotalSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005146 i::Isolate* isolate = i::Isolate::Current();
5147 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005148 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5149}
5150
5151
5152double CpuProfileNode::GetSelfSamplesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005153 i::Isolate* isolate = i::Isolate::Current();
5154 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005155 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5156}
5157
5158
5159unsigned CpuProfileNode::GetCallUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005160 i::Isolate* isolate = i::Isolate::Current();
5161 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005162 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01005163}
5164
5165
5166int CpuProfileNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005167 i::Isolate* isolate = i::Isolate::Current();
5168 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005169 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5170}
5171
5172
5173const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005174 i::Isolate* isolate = i::Isolate::Current();
5175 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
Steve Block6ded16b2010-05-10 14:33:55 +01005176 const i::ProfileNode* child =
5177 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5178 return reinterpret_cast<const CpuProfileNode*>(child);
5179}
5180
5181
Steve Block44f0eee2011-05-26 01:26:41 +01005182void CpuProfile::Delete() {
5183 i::Isolate* isolate = i::Isolate::Current();
5184 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5185 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5186 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5187 !i::CpuProfiler::HasDetachedProfiles()) {
5188 // If this was the last profile, clean up all accessory data as well.
5189 i::CpuProfiler::DeleteAllProfiles();
5190 }
5191}
5192
5193
Steve Block6ded16b2010-05-10 14:33:55 +01005194unsigned CpuProfile::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005195 i::Isolate* isolate = i::Isolate::Current();
5196 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
Steve Block6ded16b2010-05-10 14:33:55 +01005197 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5198}
5199
5200
5201Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005202 i::Isolate* isolate = i::Isolate::Current();
5203 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
Steve Block6ded16b2010-05-10 14:33:55 +01005204 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005205 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Steve Block6ded16b2010-05-10 14:33:55 +01005206 profile->title())));
5207}
5208
5209
5210const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005211 i::Isolate* isolate = i::Isolate::Current();
5212 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005213 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5214 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5215}
5216
5217
5218const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005219 i::Isolate* isolate = i::Isolate::Current();
5220 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
Steve Block6ded16b2010-05-10 14:33:55 +01005221 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5222 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5223}
5224
5225
5226int CpuProfiler::GetProfilesCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005227 i::Isolate* isolate = i::Isolate::Current();
5228 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
Steve Block6ded16b2010-05-10 14:33:55 +01005229 return i::CpuProfiler::GetProfilesCount();
5230}
5231
5232
Leon Clarkef7060e22010-06-03 12:02:55 +01005233const CpuProfile* CpuProfiler::GetProfile(int index,
5234 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005235 i::Isolate* isolate = i::Isolate::Current();
5236 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005237 return reinterpret_cast<const CpuProfile*>(
5238 i::CpuProfiler::GetProfile(
5239 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5240 index));
Steve Block6ded16b2010-05-10 14:33:55 +01005241}
5242
5243
Leon Clarkef7060e22010-06-03 12:02:55 +01005244const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5245 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005246 i::Isolate* isolate = i::Isolate::Current();
5247 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
Leon Clarkef7060e22010-06-03 12:02:55 +01005248 return reinterpret_cast<const CpuProfile*>(
5249 i::CpuProfiler::FindProfile(
5250 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5251 uid));
Steve Block6ded16b2010-05-10 14:33:55 +01005252}
5253
5254
5255void CpuProfiler::StartProfiling(Handle<String> title) {
Steve Block44f0eee2011-05-26 01:26:41 +01005256 i::Isolate* isolate = i::Isolate::Current();
5257 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005258 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5259}
5260
5261
Leon Clarkef7060e22010-06-03 12:02:55 +01005262const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5263 Handle<Value> security_token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005264 i::Isolate* isolate = i::Isolate::Current();
5265 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
Steve Block6ded16b2010-05-10 14:33:55 +01005266 return reinterpret_cast<const CpuProfile*>(
Leon Clarkef7060e22010-06-03 12:02:55 +01005267 i::CpuProfiler::StopProfiling(
5268 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5269 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01005270}
5271
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005272
Steve Block44f0eee2011-05-26 01:26:41 +01005273void CpuProfiler::DeleteAllProfiles() {
5274 i::Isolate* isolate = i::Isolate::Current();
5275 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5276 i::CpuProfiler::DeleteAllProfiles();
5277}
5278
5279
Iain Merrick75681382010-08-19 15:07:18 +01005280static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5281 return const_cast<i::HeapGraphEdge*>(
5282 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5283}
5284
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005285HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005286 i::Isolate* isolate = i::Isolate::Current();
5287 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005288 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005289}
5290
5291
5292Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005293 i::Isolate* isolate = i::Isolate::Current();
5294 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
Iain Merrick75681382010-08-19 15:07:18 +01005295 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005296 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01005297 case i::HeapGraphEdge::kContextVariable:
5298 case i::HeapGraphEdge::kInternal:
5299 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005300 case i::HeapGraphEdge::kShortcut:
Steve Block44f0eee2011-05-26 01:26:41 +01005301 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005302 edge->name())));
Iain Merrick75681382010-08-19 15:07:18 +01005303 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005304 case i::HeapGraphEdge::kHidden:
Steve Block44f0eee2011-05-26 01:26:41 +01005305 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005306 edge->index())));
5307 default: UNREACHABLE();
5308 }
Steve Block44f0eee2011-05-26 01:26:41 +01005309 return v8::Undefined();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005310}
5311
5312
5313const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005314 i::Isolate* isolate = i::Isolate::Current();
5315 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
Iain Merrick75681382010-08-19 15:07:18 +01005316 const i::HeapEntry* from = ToInternal(this)->From();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005317 return reinterpret_cast<const HeapGraphNode*>(from);
5318}
5319
5320
5321const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005322 i::Isolate* isolate = i::Isolate::Current();
5323 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
Iain Merrick75681382010-08-19 15:07:18 +01005324 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005325 return reinterpret_cast<const HeapGraphNode*>(to);
5326}
5327
5328
Iain Merrick75681382010-08-19 15:07:18 +01005329static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
5330 return const_cast<i::HeapEntry*>(
5331 reinterpret_cast<const i::HeapEntry*>(entry));
5332}
5333
5334
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005335HeapGraphNode::Type HeapGraphNode::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005336 i::Isolate* isolate = i::Isolate::Current();
5337 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
Iain Merrick75681382010-08-19 15:07:18 +01005338 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005339}
5340
5341
5342Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005343 i::Isolate* isolate = i::Isolate::Current();
5344 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
5345 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005346 ToInternal(this)->name())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005347}
5348
5349
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005350uint64_t HeapGraphNode::GetId() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005351 i::Isolate* isolate = i::Isolate::Current();
5352 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
Steve Block791712a2010-08-27 10:21:07 +01005353 ASSERT(ToInternal(this)->snapshot()->type() != i::HeapSnapshot::kAggregated);
Iain Merrick75681382010-08-19 15:07:18 +01005354 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005355}
5356
5357
Steve Block791712a2010-08-27 10:21:07 +01005358int HeapGraphNode::GetInstancesCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005359 i::Isolate* isolate = i::Isolate::Current();
5360 IsDeadCheck(isolate, "v8::HeapGraphNode::GetInstancesCount");
Steve Block791712a2010-08-27 10:21:07 +01005361 ASSERT(ToInternal(this)->snapshot()->type() == i::HeapSnapshot::kAggregated);
5362 return static_cast<int>(ToInternal(this)->id());
5363}
5364
5365
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005366int HeapGraphNode::GetSelfSize() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005367 i::Isolate* isolate = i::Isolate::Current();
5368 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
Iain Merrick75681382010-08-19 15:07:18 +01005369 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005370}
5371
5372
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005373int HeapGraphNode::GetRetainedSize(bool exact) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005374 i::Isolate* isolate = i::Isolate::Current();
5375 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005376 return ToInternal(this)->RetainedSize(exact);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005377}
5378
5379
5380int HeapGraphNode::GetChildrenCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005381 i::Isolate* isolate = i::Isolate::Current();
5382 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
Iain Merrick75681382010-08-19 15:07:18 +01005383 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005384}
5385
5386
5387const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005388 i::Isolate* isolate = i::Isolate::Current();
5389 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005390 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005391 &ToInternal(this)->children()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005392}
5393
5394
5395int HeapGraphNode::GetRetainersCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005396 i::Isolate* isolate = i::Isolate::Current();
5397 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
Iain Merrick75681382010-08-19 15:07:18 +01005398 return ToInternal(this)->retainers().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005399}
5400
5401
5402const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005403 i::Isolate* isolate = i::Isolate::Current();
5404 IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005405 return reinterpret_cast<const HeapGraphEdge*>(
Iain Merrick75681382010-08-19 15:07:18 +01005406 ToInternal(this)->retainers()[index]);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005407}
5408
5409
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005410const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005411 i::Isolate* isolate = i::Isolate::Current();
5412 IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005413 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
5414}
5415
5416
Iain Merrick75681382010-08-19 15:07:18 +01005417static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
5418 return const_cast<i::HeapSnapshot*>(
5419 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
5420}
5421
5422
Steve Block44f0eee2011-05-26 01:26:41 +01005423void HeapSnapshot::Delete() {
5424 i::Isolate* isolate = i::Isolate::Current();
5425 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
5426 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
5427 ToInternal(this)->Delete();
5428 } else {
5429 // If this is the last snapshot, clean up all accessory data as well.
5430 i::HeapProfiler::DeleteAllSnapshots();
5431 }
5432}
5433
5434
Steve Block791712a2010-08-27 10:21:07 +01005435HeapSnapshot::Type HeapSnapshot::GetType() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005436 i::Isolate* isolate = i::Isolate::Current();
5437 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
Steve Block791712a2010-08-27 10:21:07 +01005438 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
5439}
5440
5441
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005442unsigned HeapSnapshot::GetUid() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005443 i::Isolate* isolate = i::Isolate::Current();
5444 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
Iain Merrick75681382010-08-19 15:07:18 +01005445 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005446}
5447
5448
5449Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005450 i::Isolate* isolate = i::Isolate::Current();
5451 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
5452 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
Iain Merrick75681382010-08-19 15:07:18 +01005453 ToInternal(this)->title())));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005454}
5455
5456
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005457const HeapGraphNode* HeapSnapshot::GetRoot() const {
Steve Block44f0eee2011-05-26 01:26:41 +01005458 i::Isolate* isolate = i::Isolate::Current();
5459 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
Iain Merrick75681382010-08-19 15:07:18 +01005460 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005461}
5462
5463
Ben Murdochb0fe1622011-05-05 13:52:32 +01005464const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005465 i::Isolate* isolate = i::Isolate::Current();
5466 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
Ben Murdochb0fe1622011-05-05 13:52:32 +01005467 return reinterpret_cast<const HeapGraphNode*>(
5468 ToInternal(this)->GetEntryById(id));
5469}
5470
5471
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005472void HeapSnapshot::Serialize(OutputStream* stream,
5473 HeapSnapshot::SerializationFormat format) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005474 i::Isolate* isolate = i::Isolate::Current();
5475 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005476 ApiCheck(format == kJSON,
5477 "v8::HeapSnapshot::Serialize",
5478 "Unknown serialization format");
5479 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
5480 "v8::HeapSnapshot::Serialize",
5481 "Unsupported output encoding");
5482 ApiCheck(stream->GetChunkSize() > 0,
5483 "v8::HeapSnapshot::Serialize",
5484 "Invalid stream chunk size");
5485 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
5486 serializer.Serialize(stream);
5487}
5488
5489
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005490int HeapProfiler::GetSnapshotsCount() {
Steve Block44f0eee2011-05-26 01:26:41 +01005491 i::Isolate* isolate = i::Isolate::Current();
5492 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005493 return i::HeapProfiler::GetSnapshotsCount();
5494}
5495
5496
5497const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005498 i::Isolate* isolate = i::Isolate::Current();
5499 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005500 return reinterpret_cast<const HeapSnapshot*>(
5501 i::HeapProfiler::GetSnapshot(index));
5502}
5503
5504
5505const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
Steve Block44f0eee2011-05-26 01:26:41 +01005506 i::Isolate* isolate = i::Isolate::Current();
5507 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005508 return reinterpret_cast<const HeapSnapshot*>(
5509 i::HeapProfiler::FindSnapshot(uid));
5510}
5511
5512
Steve Block791712a2010-08-27 10:21:07 +01005513const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
Ben Murdochb0fe1622011-05-05 13:52:32 +01005514 HeapSnapshot::Type type,
5515 ActivityControl* control) {
Steve Block44f0eee2011-05-26 01:26:41 +01005516 i::Isolate* isolate = i::Isolate::Current();
5517 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
Steve Block791712a2010-08-27 10:21:07 +01005518 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
5519 switch (type) {
5520 case HeapSnapshot::kFull:
5521 internal_type = i::HeapSnapshot::kFull;
5522 break;
5523 case HeapSnapshot::kAggregated:
5524 internal_type = i::HeapSnapshot::kAggregated;
5525 break;
5526 default:
5527 UNREACHABLE();
5528 }
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005529 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb0fe1622011-05-05 13:52:32 +01005530 i::HeapProfiler::TakeSnapshot(
5531 *Utils::OpenHandle(*title), internal_type, control));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01005532}
5533
Steve Block44f0eee2011-05-26 01:26:41 +01005534
5535void HeapProfiler::DeleteAllSnapshots() {
5536 i::Isolate* isolate = i::Isolate::Current();
5537 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
5538 i::HeapProfiler::DeleteAllSnapshots();
5539}
5540
5541
5542void HeapProfiler::DefineWrapperClass(uint16_t class_id,
5543 WrapperInfoCallback callback) {
5544 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
5545 callback);
5546}
5547
Steve Block6ded16b2010-05-10 14:33:55 +01005548#endif // ENABLE_LOGGING_AND_PROFILING
5549
5550
Ben Murdochb0fe1622011-05-05 13:52:32 +01005551v8::Testing::StressType internal::Testing::stress_type_ =
5552 v8::Testing::kStressTypeOpt;
5553
5554
5555void Testing::SetStressRunType(Testing::StressType type) {
5556 internal::Testing::set_stress_type(type);
5557}
5558
5559int Testing::GetStressRuns() {
5560 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
5561#ifdef DEBUG
5562 // In debug mode the code runs much slower so stressing will only make two
5563 // runs.
5564 return 2;
5565#else
5566 return 5;
5567#endif
5568}
5569
5570
5571static void SetFlagsFromString(const char* flags) {
5572 V8::SetFlagsFromString(flags, i::StrLength(flags));
5573}
5574
5575
5576void Testing::PrepareStressRun(int run) {
5577 static const char* kLazyOptimizations =
5578 "--prepare-always-opt --nolimit-inlining "
5579 "--noalways-opt --noopt-eagerly";
5580 static const char* kEagerOptimizations = "--opt-eagerly";
5581 static const char* kForcedOptimizations = "--always-opt";
5582
5583 // If deoptimization stressed turn on frequent deoptimization. If no value
5584 // is spefified through --deopt-every-n-times use a default default value.
5585 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
5586 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
5587 internal::FLAG_deopt_every_n_times == 0) {
5588 SetFlagsFromString(kDeoptEvery13Times);
5589 }
5590
5591#ifdef DEBUG
5592 // As stressing in debug mode only make two runs skip the deopt stressing
5593 // here.
5594 if (run == GetStressRuns() - 1) {
5595 SetFlagsFromString(kForcedOptimizations);
5596 } else {
5597 SetFlagsFromString(kEagerOptimizations);
5598 SetFlagsFromString(kLazyOptimizations);
5599 }
5600#else
5601 if (run == GetStressRuns() - 1) {
5602 SetFlagsFromString(kForcedOptimizations);
5603 } else if (run == GetStressRuns() - 2) {
5604 SetFlagsFromString(kEagerOptimizations);
5605 } else {
5606 SetFlagsFromString(kLazyOptimizations);
5607 }
5608#endif
5609}
5610
5611
Steve Block44f0eee2011-05-26 01:26:41 +01005612void Testing::DeoptimizeAll() {
5613 internal::Deoptimizer::DeoptimizeAll();
Steve Blocka7e24c12009-10-30 11:49:00 +00005614}
5615
5616
Steve Block44f0eee2011-05-26 01:26:41 +01005617namespace internal {
5618
5619
Steve Blocka7e24c12009-10-30 11:49:00 +00005620void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01005621 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00005622}
5623
5624
5625char* HandleScopeImplementer::ArchiveThread(char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01005626 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00005627 v8::ImplementationUtilities::HandleScopeData* current =
Steve Block44f0eee2011-05-26 01:26:41 +01005628 isolate->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00005629 handle_scope_data_ = *current;
5630 memcpy(storage, this, sizeof(*this));
5631
5632 ResetAfterArchive();
5633 current->Initialize();
5634
5635 return storage + ArchiveSpacePerThread();
5636}
5637
5638
5639int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01005640 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00005641}
5642
5643
5644char* HandleScopeImplementer::RestoreThread(char* storage) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005645 memcpy(this, storage, sizeof(*this));
Steve Block44f0eee2011-05-26 01:26:41 +01005646 *Isolate::Current()->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00005647 return storage + ArchiveSpacePerThread();
5648}
5649
5650
5651void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
5652 // Iterate over all handles in the blocks except for the last.
5653 for (int i = blocks()->length() - 2; i >= 0; --i) {
5654 Object** block = blocks()->at(i);
5655 v->VisitPointers(block, &block[kHandleBlockSize]);
5656 }
5657
5658 // Iterate over live handles in the last block (if any).
5659 if (!blocks()->is_empty()) {
5660 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
5661 }
5662
5663 if (!saved_contexts_.is_empty()) {
5664 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
5665 v->VisitPointers(start, start + saved_contexts_.length());
5666 }
5667}
5668
5669
5670void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
5671 v8::ImplementationUtilities::HandleScopeData* current =
Steve Block44f0eee2011-05-26 01:26:41 +01005672 Isolate::Current()->handle_scope_data();
5673 handle_scope_data_ = *current;
5674 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005675}
5676
5677
5678char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01005679 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00005680 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01005681 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00005682 return storage + ArchiveSpacePerThread();
5683}
5684
5685} } // namespace v8::internal