blob: 8218ad43c3a6c7dcfeb8b448a0d4b15aaaf0ccf1 [file] [log] [blame]
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000028#include "api.h"
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000029
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000030#include <math.h> // For isnan.
31#include <string.h> // For memcpy, strlen.
32#include "../include/v8-debug.h"
33#include "../include/v8-profiler.h"
34#include "../include/v8-testing.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000035#include "bootstrapper.h"
verwaest@chromium.org753aee42012-07-17 16:15:42 +000036#include "code-stubs.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037#include "compiler.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000038#include "conversions-inl.h"
39#include "counters.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "debug.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000041#include "deoptimizer.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042#include "execution.h"
43#include "global-handles.h"
whesse@chromium.org2c186ca2010-06-16 11:32:39 +000044#include "heap-profiler.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000045#include "messages.h"
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +000046#ifdef COMPRESS_STARTUP_DATA_BZ2
47#include "natives.h"
48#endif
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000049#include "parser.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000050#include "platform.h"
ager@chromium.org357bf652010-04-12 11:30:10 +000051#include "profile-generator-inl.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000052#include "property-details.h"
53#include "property.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054#include "runtime-profiler.h"
ricow@chromium.org55ee8072011-09-08 16:33:10 +000055#include "scanner-character-streams.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000056#include "snapshot.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000057#include "unicode-inl.h"
ager@chromium.orgddb913d2009-01-27 10:01:48 +000058#include "v8threads.h"
ager@chromium.org5ec48922009-05-05 07:25:34 +000059#include "version.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000060#include "vm-state-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000061
62
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000063#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000064
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000065#define ENTER_V8(isolate) \
66 ASSERT((isolate)->IsInitialized()); \
67 i::VMState __state__((isolate), i::OTHER)
68#define LEAVE_V8(isolate) \
69 i::VMState __state__((isolate), i::EXTERNAL)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000070
71namespace v8 {
72
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000073#define ON_BAILOUT(isolate, location, code) \
74 if (IsDeadCheck(isolate, location) || \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000075 IsExecutionTerminatingCheck(isolate)) { \
kmillikin@chromium.org9155e252010-05-26 13:27:57 +000076 code; \
77 UNREACHABLE(); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 }
79
80
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000081#define EXCEPTION_PREAMBLE(isolate) \
82 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
83 ASSERT(!(isolate)->external_caught_exception()); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084 bool has_pending_exception = false
85
86
rossberg@chromium.orgfab14982012-01-05 15:02:15 +000087#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000088 do { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000089 i::HandleScopeImplementer* handle_scope_implementer = \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000090 (isolate)->handle_scope_implementer(); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000091 handle_scope_implementer->DecrementCallDepth(); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 if (has_pending_exception) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000093 if (handle_scope_implementer->CallDepthIsZero() && \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000094 (isolate)->is_out_of_memory()) { \
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000095 if (!(isolate)->ignore_out_of_memory()) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000096 i::V8::FatalProcessOutOfMemory(NULL); \
97 } \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000098 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000099 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000100 do_callback \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 return value; \
102 } \
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000103 do_callback \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000104 } while (false)
105
106
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000107#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
108 EXCEPTION_BAILOUT_CHECK_GENERIC( \
109 isolate, value, i::V8::FireCallCompletedCallback(isolate);)
110
111
112#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
113 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
114
115
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000116#define API_ENTRY_CHECK(isolate, msg) \
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000117 do { \
118 if (v8::Locker::IsActive()) { \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000119 ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(), \
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000120 msg, \
121 "Entering the V8 API without proper locking in place"); \
122 } \
123 } while (false)
124
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000126// --- E x c e p t i o n B e h a v i o r ---
127
128
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000129static void DefaultFatalErrorHandler(const char* location,
130 const char* message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000131 i::VMState __state__(i::Isolate::Current(), i::OTHER);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000132 API_Fatal(location, message);
133}
134
135
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000136static FatalErrorCallback GetFatalErrorHandler() {
137 i::Isolate* isolate = i::Isolate::Current();
138 if (isolate->exception_behavior() == NULL) {
139 isolate->set_exception_behavior(DefaultFatalErrorHandler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000141 return isolate->exception_behavior();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000142}
143
144
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000145void i::FatalProcessOutOfMemory(const char* location) {
146 i::V8::FatalProcessOutOfMemory(location, false);
147}
148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000149
150// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
151// The default fatal error handler is called and execution is stopped.
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000152void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000153 i::HeapStats heap_stats;
154 int start_marker;
155 heap_stats.start_marker = &start_marker;
156 int new_space_size;
157 heap_stats.new_space_size = &new_space_size;
158 int new_space_capacity;
159 heap_stats.new_space_capacity = &new_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000160 intptr_t old_pointer_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000161 heap_stats.old_pointer_space_size = &old_pointer_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000162 intptr_t old_pointer_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000163 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000164 intptr_t old_data_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000165 heap_stats.old_data_space_size = &old_data_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000166 intptr_t old_data_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000167 heap_stats.old_data_space_capacity = &old_data_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000168 intptr_t code_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000169 heap_stats.code_space_size = &code_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000170 intptr_t code_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000171 heap_stats.code_space_capacity = &code_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000172 intptr_t map_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000173 heap_stats.map_space_size = &map_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000174 intptr_t map_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000175 heap_stats.map_space_capacity = &map_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000176 intptr_t cell_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000177 heap_stats.cell_space_size = &cell_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000178 intptr_t cell_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000179 heap_stats.cell_space_capacity = &cell_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000180 intptr_t lo_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000181 heap_stats.lo_space_size = &lo_space_size;
182 int global_handle_count;
183 heap_stats.global_handle_count = &global_handle_count;
184 int weak_global_handle_count;
185 heap_stats.weak_global_handle_count = &weak_global_handle_count;
186 int pending_global_handle_count;
187 heap_stats.pending_global_handle_count = &pending_global_handle_count;
188 int near_death_global_handle_count;
189 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000190 int free_global_handle_count;
191 heap_stats.free_global_handle_count = &free_global_handle_count;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000192 intptr_t memory_allocator_size;
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000193 heap_stats.memory_allocator_size = &memory_allocator_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000194 intptr_t memory_allocator_capacity;
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000195 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
196 int objects_per_type[LAST_TYPE + 1] = {0};
197 heap_stats.objects_per_type = objects_per_type;
198 int size_per_type[LAST_TYPE + 1] = {0};
199 heap_stats.size_per_type = size_per_type;
ager@chromium.orgea4f62e2010-08-16 16:28:43 +0000200 int os_error;
201 heap_stats.os_error = &os_error;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000202 int end_marker;
203 heap_stats.end_marker = &end_marker;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000204 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000205 // BUG(1718):
206 // Don't use the take_snapshot since we don't support HeapIterator here
207 // without doing a special GC.
208 isolate->heap()->RecordStats(&heap_stats, false);
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000209 i::V8::SetFatalError();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210 FatalErrorCallback callback = GetFatalErrorHandler();
ager@chromium.org71daaf62009-04-01 07:22:49 +0000211 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000212 LEAVE_V8(isolate);
ager@chromium.org71daaf62009-04-01 07:22:49 +0000213 callback(location, "Allocation failed - process out of memory");
214 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215 // If the callback returns, we stop execution.
216 UNREACHABLE();
217}
218
219
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000220bool Utils::ReportApiFailure(const char* location, const char* message) {
221 FatalErrorCallback callback = GetFatalErrorHandler();
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000222 callback(location, message);
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000223 i::V8::SetFatalError();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224 return false;
225}
226
227
228bool V8::IsDead() {
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000229 return i::V8::IsDead();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230}
231
232
233static inline bool ApiCheck(bool condition,
234 const char* location,
235 const char* message) {
236 return condition ? true : Utils::ReportApiFailure(location, message);
237}
238
239
240static bool ReportV8Dead(const char* location) {
241 FatalErrorCallback callback = GetFatalErrorHandler();
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000242 callback(location, "V8 is no longer usable");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243 return true;
244}
245
246
247static bool ReportEmptyHandle(const char* location) {
248 FatalErrorCallback callback = GetFatalErrorHandler();
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000249 callback(location, "Reading from empty handle");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250 return true;
251}
252
253
254/**
ager@chromium.org32912102009-01-16 10:38:43 +0000255 * IsDeadCheck checks that the vm is usable. If, for instance, the vm has been
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000256 * out of memory at some point this check will fail. It should be called on
257 * entry to all methods that touch anything in the heap, except destructors
258 * which you sometimes can't avoid calling after the vm has crashed. Functions
259 * that call EnsureInitialized or ON_BAILOUT don't have to also call
260 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you
261 * can arrange to return if the VM is dead. This is needed to ensure that no VM
262 * heap allocations are attempted on a dead VM. EnsureInitialized has the
263 * advantage over ON_BAILOUT that it actually initializes the VM if this has not
264 * yet been done.
265 */
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000266static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
267 return !isolate->IsInitialized()
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000268 && i::V8::IsDead() ? ReportV8Dead(location) : false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000269}
270
271
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000272static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
273 if (!isolate->IsInitialized()) return false;
274 if (isolate->has_scheduled_exception()) {
275 return isolate->scheduled_exception() ==
276 isolate->heap()->termination_exception();
277 }
278 return false;
279}
280
281
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000282static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
283 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
284}
285
286
ager@chromium.org32912102009-01-16 10:38:43 +0000287static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000288 return (obj == 0) ? ReportEmptyHandle(location) : false;
289}
290
291// --- S t a t i c s ---
292
293
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000294static bool InitializeHelper() {
295 if (i::Snapshot::Initialize()) return true;
296 return i::V8::Initialize(NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000297}
298
299
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000300static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
301 const char* location) {
302 if (IsDeadCheck(isolate, location)) return false;
303 if (isolate != NULL) {
304 if (isolate->IsInitialized()) return true;
305 }
lrn@chromium.org1c092762011-05-09 09:42:16 +0000306 ASSERT(isolate == i::Isolate::Current());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000307 return ApiCheck(InitializeHelper(), location, "Error initializing V8");
308}
309
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000310// Some initializing API functions are called early and may be
311// called on a thread different from static initializer thread.
312// If Isolate API is used, Isolate::Enter() will initialize TLS so
313// Isolate::Current() works. If it's a legacy case, then the thread
314// may not have TLS initialized yet. However, in initializing APIs it
315// may be too early to call EnsureInitialized() - some pre-init
316// parameters still have to be configured.
317static inline i::Isolate* EnterIsolateIfNeeded() {
318 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
319 if (isolate != NULL)
320 return isolate;
321
322 i::Isolate::EnterDefaultIsolate();
323 isolate = i::Isolate::Current();
324 return isolate;
325}
326
327
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000328StartupDataDecompressor::StartupDataDecompressor()
329 : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
330 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
331 raw_data[i] = NULL;
332 }
333}
334
335
336StartupDataDecompressor::~StartupDataDecompressor() {
337 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
338 i::DeleteArray(raw_data[i]);
339 }
340 i::DeleteArray(raw_data);
341}
342
343
344int StartupDataDecompressor::Decompress() {
345 int compressed_data_count = V8::GetCompressedStartupDataCount();
346 StartupData* compressed_data =
347 i::NewArray<StartupData>(compressed_data_count);
348 V8::GetCompressedStartupData(compressed_data);
349 for (int i = 0; i < compressed_data_count; ++i) {
350 char* decompressed = raw_data[i] =
351 i::NewArray<char>(compressed_data[i].raw_size);
352 if (compressed_data[i].compressed_size != 0) {
353 int result = DecompressData(decompressed,
354 &compressed_data[i].raw_size,
355 compressed_data[i].data,
356 compressed_data[i].compressed_size);
357 if (result != 0) return result;
358 } else {
359 ASSERT_EQ(0, compressed_data[i].raw_size);
360 }
361 compressed_data[i].data = decompressed;
362 }
363 V8::SetDecompressedStartupData(compressed_data);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000364 i::DeleteArray(compressed_data);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000365 return 0;
366}
367
368
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000369StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
370#ifdef COMPRESS_STARTUP_DATA_BZ2
371 return StartupData::kBZip2;
372#else
373 return StartupData::kUncompressed;
374#endif
375}
376
377
378enum CompressedStartupDataItems {
379 kSnapshot = 0,
380 kSnapshotContext,
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000381 kLibraries,
382 kExperimentalLibraries,
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000383 kCompressedStartupDataCount
384};
385
386int V8::GetCompressedStartupDataCount() {
387#ifdef COMPRESS_STARTUP_DATA_BZ2
388 return kCompressedStartupDataCount;
389#else
390 return 0;
391#endif
392}
393
394
395void V8::GetCompressedStartupData(StartupData* compressed_data) {
396#ifdef COMPRESS_STARTUP_DATA_BZ2
397 compressed_data[kSnapshot].data =
398 reinterpret_cast<const char*>(i::Snapshot::data());
399 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
400 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
401
402 compressed_data[kSnapshotContext].data =
403 reinterpret_cast<const char*>(i::Snapshot::context_data());
404 compressed_data[kSnapshotContext].compressed_size =
405 i::Snapshot::context_size();
406 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000407
408 i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
409 compressed_data[kLibraries].data =
410 reinterpret_cast<const char*>(libraries_source.start());
411 compressed_data[kLibraries].compressed_size = libraries_source.length();
412 compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
413
414 i::Vector<const i::byte> exp_libraries_source =
415 i::ExperimentalNatives::GetScriptsSource();
416 compressed_data[kExperimentalLibraries].data =
417 reinterpret_cast<const char*>(exp_libraries_source.start());
418 compressed_data[kExperimentalLibraries].compressed_size =
419 exp_libraries_source.length();
420 compressed_data[kExperimentalLibraries].raw_size =
421 i::ExperimentalNatives::GetRawScriptsSize();
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000422#endif
423}
424
425
426void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
427#ifdef COMPRESS_STARTUP_DATA_BZ2
428 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
429 i::Snapshot::set_raw_data(
430 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
431
432 ASSERT_EQ(i::Snapshot::context_raw_size(),
433 decompressed_data[kSnapshotContext].raw_size);
434 i::Snapshot::set_context_raw_data(
435 reinterpret_cast<const i::byte*>(
436 decompressed_data[kSnapshotContext].data));
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000437
438 ASSERT_EQ(i::Natives::GetRawScriptsSize(),
439 decompressed_data[kLibraries].raw_size);
440 i::Vector<const char> libraries_source(
441 decompressed_data[kLibraries].data,
442 decompressed_data[kLibraries].raw_size);
443 i::Natives::SetRawScriptsSource(libraries_source);
444
445 ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
446 decompressed_data[kExperimentalLibraries].raw_size);
447 i::Vector<const char> exp_libraries_source(
448 decompressed_data[kExperimentalLibraries].data,
449 decompressed_data[kExperimentalLibraries].raw_size);
450 i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000451#endif
452}
453
454
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000455void V8::SetFatalErrorHandler(FatalErrorCallback that) {
456 i::Isolate* isolate = EnterIsolateIfNeeded();
457 isolate->set_exception_behavior(that);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000458}
459
460
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000461void V8::SetAllowCodeGenerationFromStringsCallback(
462 AllowCodeGenerationFromStringsCallback callback) {
463 i::Isolate* isolate = EnterIsolateIfNeeded();
464 isolate->set_allow_code_gen_callback(callback);
465}
466
467
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000468#ifdef DEBUG
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000469void ImplementationUtilities::ZapHandleRange(i::Object** begin,
470 i::Object** end) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000471 i::HandleScope::ZapRange(begin, end);
472}
473#endif
474
475
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476void V8::SetFlagsFromString(const char* str, int length) {
477 i::FlagList::SetFlagsFromString(str, length);
478}
479
480
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000481void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
482 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
483}
484
485
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000486v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000487 i::Isolate* isolate = i::Isolate::Current();
488 if (IsDeadCheck(isolate, "v8::ThrowException()")) {
489 return v8::Handle<Value>();
490 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000491 ENTER_V8(isolate);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000492 // If we're passed an empty handle, we throw an undefined exception
493 // to deal more gracefully with out of memory situations.
494 if (value.IsEmpty()) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000495 isolate->ScheduleThrow(isolate->heap()->undefined_value());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000496 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000497 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000498 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000499 return v8::Undefined();
500}
501
502
503RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
504
505
506RegisteredExtension::RegisteredExtension(Extension* extension)
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000507 : extension_(extension) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000508
509
510void RegisteredExtension::Register(RegisteredExtension* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000511 that->next_ = first_extension_;
512 first_extension_ = that;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000513}
514
515
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000516void RegisteredExtension::UnregisterAll() {
517 RegisteredExtension* re = first_extension_;
518 while (re != NULL) {
519 RegisteredExtension* next = re->next();
520 delete re;
521 re = next;
522 }
523}
524
525
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000526void RegisterExtension(Extension* that) {
527 RegisteredExtension* extension = new RegisteredExtension(that);
528 RegisteredExtension::Register(extension);
529}
530
531
532Extension::Extension(const char* name,
533 const char* source,
534 int dep_count,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000535 const char** deps,
536 int source_length)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000537 : name_(name),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000538 source_length_(source_length >= 0 ?
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000539 source_length :
540 (source ? static_cast<int>(strlen(source)) : 0)),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000541 source_(source, source_length_),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 dep_count_(dep_count),
543 deps_(deps),
544 auto_enable_(false) { }
545
546
547v8::Handle<Primitive> Undefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000548 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000549 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
550 return v8::Handle<v8::Primitive>();
551 }
552 return v8::Handle<Primitive>(ToApi<Primitive>(
553 isolate->factory()->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000554}
555
556
557v8::Handle<Primitive> Null() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000558 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000559 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
560 return v8::Handle<v8::Primitive>();
561 }
562 return v8::Handle<Primitive>(
563 ToApi<Primitive>(isolate->factory()->null_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000564}
565
566
567v8::Handle<Boolean> True() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000568 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000569 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
570 return v8::Handle<Boolean>();
571 }
572 return v8::Handle<Boolean>(
573 ToApi<Boolean>(isolate->factory()->true_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000574}
575
576
577v8::Handle<Boolean> False() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000578 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000579 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
580 return v8::Handle<Boolean>();
581 }
582 return v8::Handle<Boolean>(
583 ToApi<Boolean>(isolate->factory()->false_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000584}
585
586
587ResourceConstraints::ResourceConstraints()
588 : max_young_space_size_(0),
589 max_old_space_size_(0),
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000590 max_executable_size_(0),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000591 stack_limit_(NULL) { }
592
593
594bool SetResourceConstraints(ResourceConstraints* constraints) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000595 i::Isolate* isolate = EnterIsolateIfNeeded();
596
ager@chromium.org3811b432009-10-28 14:53:37 +0000597 int young_space_size = constraints->max_young_space_size();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000598 int old_gen_size = constraints->max_old_space_size();
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000599 int max_executable_size = constraints->max_executable_size();
600 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000601 // After initialization it's too late to change Heap constraints.
602 ASSERT(!isolate->IsInitialized());
603 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
604 old_gen_size,
605 max_executable_size);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000606 if (!result) return false;
607 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608 if (constraints->stack_limit() != NULL) {
609 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000610 isolate->stack_guard()->SetStackLimit(limit);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000611 }
612 return true;
613}
614
615
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000616i::Object** V8::GlobalizeReference(i::Object** obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000617 i::Isolate* isolate = i::Isolate::Current();
618 if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
619 LOG_API(isolate, "Persistent::New");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 i::Handle<i::Object> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000621 isolate->global_handles()->Create(*obj);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000622 return result.location();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000626void V8::MakeWeak(i::Object** object, void* parameters,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627 WeakReferenceCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000628 i::Isolate* isolate = i::Isolate::Current();
629 LOG_API(isolate, "MakeWeak");
630 isolate->global_handles()->MakeWeak(object, parameters,
631 callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000635void V8::ClearWeak(i::Object** obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000636 i::Isolate* isolate = i::Isolate::Current();
637 LOG_API(isolate, "ClearWeak");
638 isolate->global_handles()->ClearWeakness(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000639}
640
641
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000642void V8::MarkIndependent(i::Object** object) {
643 i::Isolate* isolate = i::Isolate::Current();
644 LOG_API(isolate, "MakeIndependent");
645 isolate->global_handles()->MarkIndependent(object);
646}
647
648
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000649bool V8::IsGlobalNearDeath(i::Object** obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000650 i::Isolate* isolate = i::Isolate::Current();
651 LOG_API(isolate, "IsGlobalNearDeath");
652 if (!isolate->IsInitialized()) return false;
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000653 return i::GlobalHandles::IsNearDeath(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000654}
655
656
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000657bool V8::IsGlobalWeak(i::Object** obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000658 i::Isolate* isolate = i::Isolate::Current();
659 LOG_API(isolate, "IsGlobalWeak");
660 if (!isolate->IsInitialized()) return false;
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000661 return i::GlobalHandles::IsWeak(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000662}
663
664
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000665void V8::DisposeGlobal(i::Object** obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000666 i::Isolate* isolate = i::Isolate::Current();
667 LOG_API(isolate, "DisposeGlobal");
668 if (!isolate->IsInitialized()) return;
669 isolate->global_handles()->Destroy(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670}
671
672// --- H a n d l e s ---
673
674
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000675HandleScope::HandleScope() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000676 i::Isolate* isolate = i::Isolate::Current();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000677 API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000678 v8::ImplementationUtilities::HandleScopeData* current =
679 isolate->handle_scope_data();
680 isolate_ = isolate;
681 prev_next_ = current->next;
682 prev_limit_ = current->limit;
683 is_closed_ = false;
684 current->level++;
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000685}
686
687
688HandleScope::~HandleScope() {
689 if (!is_closed_) {
lrn@chromium.org303ada72010-10-27 09:33:13 +0000690 Leave();
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000691 }
692}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000693
694
lrn@chromium.org303ada72010-10-27 09:33:13 +0000695void HandleScope::Leave() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000696 ASSERT(isolate_ == i::Isolate::Current());
697 v8::ImplementationUtilities::HandleScopeData* current =
698 isolate_->handle_scope_data();
699 current->level--;
700 ASSERT(current->level >= 0);
701 current->next = prev_next_;
702 if (current->limit != prev_limit_) {
703 current->limit = prev_limit_;
704 i::HandleScope::DeleteExtensions(isolate_);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000705 }
706
707#ifdef DEBUG
708 i::HandleScope::ZapRange(prev_next_, prev_limit_);
709#endif
710}
711
712
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713int HandleScope::NumberOfHandles() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000714 EnsureInitializedForIsolate(
715 i::Isolate::Current(), "HandleScope::NumberOfHandles");
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000716 return i::HandleScope::NumberOfHandles();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000717}
718
719
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000720i::Object** HandleScope::CreateHandle(i::Object* value) {
721 return i::HandleScope::CreateHandle(value, i::Isolate::Current());
722}
723
724
725i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
726 ASSERT(value->IsHeapObject());
727 return reinterpret_cast<i::Object**>(
728 i::HandleScope::CreateHandle(value, value->GetIsolate()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000729}
730
731
732void Context::Enter() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000733 i::Handle<i::Context> env = Utils::OpenHandle(this);
734 i::Isolate* isolate = env->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000735 if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000736 ENTER_V8(isolate);
737
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000738 isolate->handle_scope_implementer()->EnterContext(env);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000739
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000740 isolate->handle_scope_implementer()->SaveContext(isolate->context());
741 isolate->set_context(*env);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742}
743
744
745void Context::Exit() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000746 // Exit is essentially a static function and doesn't use the
747 // receiver, so we have to get the current isolate from the thread
748 // local.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000749 i::Isolate* isolate = i::Isolate::Current();
750 if (!isolate->IsInitialized()) return;
751
752 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(),
kasper.lund44510672008-07-25 07:37:58 +0000753 "v8::Context::Exit()",
754 "Cannot exit non-entered context")) {
755 return;
756 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000758 // Content of 'last_context' could be NULL.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000759 i::Context* last_context =
760 isolate->handle_scope_implementer()->RestoreContext();
761 isolate->set_context(last_context);
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000762 isolate->set_context_exit_happened(true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000763}
764
765
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +0000766void Context::SetData(v8::Handle<String> data) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000767 i::Handle<i::Context> env = Utils::OpenHandle(this);
768 i::Isolate* isolate = env->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000769 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000770 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
771 ASSERT(env->IsGlobalContext());
772 if (env->IsGlobalContext()) {
773 env->set_data(*raw_data);
ager@chromium.org9085a012009-05-11 19:22:57 +0000774 }
775}
776
777
778v8::Local<v8::Value> Context::GetData() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000779 i::Handle<i::Context> env = Utils::OpenHandle(this);
780 i::Isolate* isolate = env->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
782 return v8::Local<Value>();
783 }
ager@chromium.org9085a012009-05-11 19:22:57 +0000784 i::Object* raw_result = NULL;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000785 ASSERT(env->IsGlobalContext());
786 if (env->IsGlobalContext()) {
787 raw_result = env->data();
788 } else {
789 return Local<Value>();
ager@chromium.org9085a012009-05-11 19:22:57 +0000790 }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000791 i::Handle<i::Object> result(raw_result, isolate);
ager@chromium.org9085a012009-05-11 19:22:57 +0000792 return Utils::ToLocal(result);
793}
794
795
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000796i::Object** v8::HandleScope::RawClose(i::Object** value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000797 if (!ApiCheck(!is_closed_,
798 "v8::HandleScope::Close()",
799 "Local scope has already been closed")) {
800 return 0;
801 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000802 LOG_API(isolate_, "CloseHandleScope");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000803
804 // Read the result before popping the handle block.
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000805 i::Object* result = NULL;
806 if (value != NULL) {
807 result = *value;
808 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809 is_closed_ = true;
lrn@chromium.org303ada72010-10-27 09:33:13 +0000810 Leave();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000811
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000812 if (value == NULL) {
813 return NULL;
814 }
815
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 // Allocate a new handle on the previous handle block.
817 i::Handle<i::Object> handle(result);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000818 return handle.location();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000819}
820
821
822// --- N e a n d e r ---
823
824
825// A constructor cannot easily return an error value, therefore it is necessary
826// to check for a dead VM with ON_BAILOUT before constructing any Neander
827// objects. To remind you about this there is no HandleScope in the
828// NeanderObject constructor. When you add one to the site calling the
829// constructor you should check that you ensured the VM was not dead first.
830NeanderObject::NeanderObject(int size) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000831 i::Isolate* isolate = i::Isolate::Current();
832 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
833 ENTER_V8(isolate);
834 value_ = isolate->factory()->NewNeanderObject();
835 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 value_->set_elements(*elements);
837}
838
839
840int NeanderObject::size() {
841 return i::FixedArray::cast(value_->elements())->length();
842}
843
844
845NeanderArray::NeanderArray() : obj_(2) {
846 obj_.set(0, i::Smi::FromInt(0));
847}
848
849
850int NeanderArray::length() {
851 return i::Smi::cast(obj_.get(0))->value();
852}
853
854
855i::Object* NeanderArray::get(int offset) {
856 ASSERT(0 <= offset);
857 ASSERT(offset < length());
858 return obj_.get(offset + 1);
859}
860
861
862// This method cannot easily return an error value, therefore it is necessary
863// to check for a dead VM with ON_BAILOUT before calling it. To remind you
864// about this there is no HandleScope in this method. When you add one to the
865// site calling this method you should check that you ensured the VM was not
866// dead first.
867void NeanderArray::add(i::Handle<i::Object> value) {
868 int length = this->length();
869 int size = obj_.size();
870 if (length == size - 1) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000871 i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000872 for (int i = 0; i < length; i++)
873 new_elms->set(i + 1, get(i));
874 obj_.value()->set_elements(*new_elms);
875 }
876 obj_.set(length + 1, *value);
877 obj_.set(0, i::Smi::FromInt(length + 1));
878}
879
880
881void NeanderArray::set(int index, i::Object* value) {
882 if (index < 0 || index >= this->length()) return;
883 obj_.set(index + 1, value);
884}
885
886
887// --- T e m p l a t e ---
888
889
890static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
891 that->set_tag(i::Smi::FromInt(type));
892}
893
894
895void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
896 v8::PropertyAttribute attribute) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000897 i::Isolate* isolate = i::Isolate::Current();
898 if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000899 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000900 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000901 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
902 if (list->IsUndefined()) {
903 list = NeanderArray().value();
904 Utils::OpenHandle(this)->set_property_list(*list);
905 }
906 NeanderArray array(list);
907 array.add(Utils::OpenHandle(*name));
908 array.add(Utils::OpenHandle(*value));
909 array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
910}
911
912
913// --- F u n c t i o n T e m p l a t e ---
914static void InitializeFunctionTemplate(
915 i::Handle<i::FunctionTemplateInfo> info) {
916 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
917 info->set_flag(0);
918}
919
920
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000921Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000922 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000923 if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000924 return Local<ObjectTemplate>();
925 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000926 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000927 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
928 if (result->IsUndefined()) {
929 result = Utils::OpenHandle(*ObjectTemplate::New());
930 Utils::OpenHandle(this)->set_prototype_template(*result);
931 }
932 return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
933}
934
935
936void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000937 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000938 if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000939 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000940 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
941}
942
943
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000944Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
945 v8::Handle<Value> data, v8::Handle<Signature> signature) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000946 i::Isolate* isolate = i::Isolate::Current();
947 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
948 LOG_API(isolate, "FunctionTemplate::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000949 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000950 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000951 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952 i::Handle<i::FunctionTemplateInfo> obj =
953 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
954 InitializeFunctionTemplate(obj);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000955 int next_serial_number = isolate->next_serial_number();
956 isolate->set_next_serial_number(next_serial_number + 1);
957 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958 if (callback != 0) {
959 if (data.IsEmpty()) data = v8::Undefined();
960 Utils::ToLocal(obj)->SetCallHandler(callback, data);
961 }
962 obj->set_undetectable(false);
963 obj->set_needs_access_check(false);
964
965 if (!signature.IsEmpty())
966 obj->set_signature(*Utils::OpenHandle(*signature));
967 return Utils::ToLocal(obj);
968}
969
970
971Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
972 int argc, Handle<FunctionTemplate> argv[]) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000973 i::Isolate* isolate = i::Isolate::Current();
974 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
975 LOG_API(isolate, "Signature::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000976 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000977 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000978 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000979 i::Handle<i::SignatureInfo> obj =
980 i::Handle<i::SignatureInfo>::cast(struct_obj);
981 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
982 if (argc > 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000983 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000984 for (int i = 0; i < argc; i++) {
985 if (!argv[i].IsEmpty())
986 args->set(i, *Utils::OpenHandle(*argv[i]));
987 }
988 obj->set_args(*args);
989 }
990 return Utils::ToLocal(obj);
991}
992
993
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000994Local<AccessorSignature> AccessorSignature::New(
995 Handle<FunctionTemplate> receiver) {
996 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
997}
998
999
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001000Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
1001 Handle<FunctionTemplate> types[1] = { type };
1002 return TypeSwitch::New(1, types);
1003}
1004
1005
1006Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001007 i::Isolate* isolate = i::Isolate::Current();
1008 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
1009 LOG_API(isolate, "TypeSwitch::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001010 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001011 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001012 for (int i = 0; i < argc; i++)
1013 vector->set(i, *Utils::OpenHandle(*types[i]));
1014 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001015 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001016 i::Handle<i::TypeSwitchInfo> obj =
1017 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
1018 obj->set_types(*vector);
1019 return Utils::ToLocal(obj);
1020}
1021
1022
1023int TypeSwitch::match(v8::Handle<Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001024 i::Isolate* isolate = i::Isolate::Current();
1025 LOG_API(isolate, "TypeSwitch::match");
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001026 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001027 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
1028 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
1029 i::FixedArray* types = i::FixedArray::cast(info->types());
1030 for (int i = 0; i < types->length(); i++) {
1031 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
1032 return i + 1;
1033 }
1034 return 0;
1035}
1036
1037
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001038#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
1039 i::Handle<i::Object> foreign = FromCData(cdata); \
1040 (obj)->setter(*foreign); \
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001041 } while (false)
1042
1043
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001044void FunctionTemplate::SetCallHandler(InvocationCallback callback,
1045 v8::Handle<Value> data) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001046 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001047 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001048 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001049 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001050 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001051 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052 i::Handle<i::CallHandlerInfo> obj =
1053 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001054 SET_FIELD_WRAPPED(obj, set_callback, callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001055 if (data.IsEmpty()) data = v8::Undefined();
1056 obj->set_data(*Utils::OpenHandle(*data));
1057 Utils::OpenHandle(this)->set_call_code(*obj);
1058}
1059
1060
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001061static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1062 v8::Handle<String> name,
1063 AccessorGetter getter,
1064 AccessorSetter setter,
1065 v8::Handle<Value> data,
1066 v8::AccessControl settings,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001067 v8::PropertyAttribute attributes,
1068 v8::Handle<AccessorSignature> signature) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001069 i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001070 ASSERT(getter != NULL);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001071 SET_FIELD_WRAPPED(obj, set_getter, getter);
1072 SET_FIELD_WRAPPED(obj, set_setter, setter);
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001073 if (data.IsEmpty()) data = v8::Undefined();
1074 obj->set_data(*Utils::OpenHandle(*data));
1075 obj->set_name(*Utils::OpenHandle(*name));
1076 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1077 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1078 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
1079 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001080 if (!signature.IsEmpty()) {
1081 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1082 }
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001083 return obj;
1084}
1085
1086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001087void FunctionTemplate::AddInstancePropertyAccessor(
1088 v8::Handle<String> name,
1089 AccessorGetter getter,
1090 AccessorSetter setter,
1091 v8::Handle<Value> data,
1092 v8::AccessControl settings,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001093 v8::PropertyAttribute attributes,
1094 v8::Handle<AccessorSignature> signature) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001095 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001096 if (IsDeadCheck(isolate,
1097 "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001098 return;
1099 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001100 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001101 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001103 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name, getter, setter, data,
1104 settings, attributes,
1105 signature);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001106 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
1107 if (list->IsUndefined()) {
1108 list = NeanderArray().value();
1109 Utils::OpenHandle(this)->set_property_accessors(*list);
1110 }
1111 NeanderArray array(list);
1112 array.add(obj);
1113}
1114
1115
1116Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001117 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001118 if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001119 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
1120 return Local<ObjectTemplate>();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001121 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001122 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
1123 Local<ObjectTemplate> templ =
1124 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
1125 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
1126 }
1127 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
1128 Utils::OpenHandle(this)->instance_template()));
1129 return Utils::ToLocal(result);
1130}
1131
1132
kasper.lund212ac232008-07-16 07:07:30 +00001133void FunctionTemplate::SetClassName(Handle<String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001134 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001135 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001136 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001137 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1138}
1139
1140
1141void FunctionTemplate::SetHiddenPrototype(bool value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001142 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001143 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
1144 return;
1145 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001146 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001147 Utils::OpenHandle(this)->set_hidden_prototype(value);
1148}
1149
1150
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001151void FunctionTemplate::ReadOnlyPrototype() {
ager@chromium.org04921a82011-06-27 13:21:41 +00001152 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1153 if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
1154 return;
1155 }
1156 ENTER_V8(isolate);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001157 Utils::OpenHandle(this)->set_read_only_prototype(true);
ager@chromium.org04921a82011-06-27 13:21:41 +00001158}
1159
1160
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00001161void FunctionTemplate::SetNamedInstancePropertyHandler(
kasper.lund212ac232008-07-16 07:07:30 +00001162 NamedPropertyGetter getter,
1163 NamedPropertySetter setter,
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00001164 NamedPropertyQuery query,
kasper.lund212ac232008-07-16 07:07:30 +00001165 NamedPropertyDeleter remover,
1166 NamedPropertyEnumerator enumerator,
1167 Handle<Value> data) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001168 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001169 if (IsDeadCheck(isolate,
1170 "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
kasper.lund212ac232008-07-16 07:07:30 +00001171 return;
1172 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001173 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001174 i::HandleScope scope(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001175 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001176 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
kasper.lund212ac232008-07-16 07:07:30 +00001177 i::Handle<i::InterceptorInfo> obj =
1178 i::Handle<i::InterceptorInfo>::cast(struct_obj);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001179
1180 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1181 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1182 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1183 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1184 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1185
kasper.lund212ac232008-07-16 07:07:30 +00001186 if (data.IsEmpty()) data = v8::Undefined();
1187 obj->set_data(*Utils::OpenHandle(*data));
1188 Utils::OpenHandle(this)->set_named_property_handler(*obj);
1189}
1190
1191
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001192void FunctionTemplate::SetIndexedInstancePropertyHandler(
kasper.lund212ac232008-07-16 07:07:30 +00001193 IndexedPropertyGetter getter,
1194 IndexedPropertySetter setter,
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001195 IndexedPropertyQuery query,
kasper.lund212ac232008-07-16 07:07:30 +00001196 IndexedPropertyDeleter remover,
1197 IndexedPropertyEnumerator enumerator,
1198 Handle<Value> data) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001199 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001200 if (IsDeadCheck(isolate,
kasper.lund212ac232008-07-16 07:07:30 +00001201 "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
1202 return;
1203 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001204 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001205 i::HandleScope scope(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001206 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001207 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
kasper.lund212ac232008-07-16 07:07:30 +00001208 i::Handle<i::InterceptorInfo> obj =
1209 i::Handle<i::InterceptorInfo>::cast(struct_obj);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001210
1211 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1212 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1213 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1214 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1215 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1216
kasper.lund212ac232008-07-16 07:07:30 +00001217 if (data.IsEmpty()) data = v8::Undefined();
1218 obj->set_data(*Utils::OpenHandle(*data));
1219 Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
1220}
1221
1222
1223void FunctionTemplate::SetInstanceCallAsFunctionHandler(
1224 InvocationCallback callback,
1225 Handle<Value> data) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001226 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001227 if (IsDeadCheck(isolate,
1228 "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
kasper.lund212ac232008-07-16 07:07:30 +00001229 return;
1230 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001231 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001232 i::HandleScope scope(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001233 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001234 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
kasper.lund212ac232008-07-16 07:07:30 +00001235 i::Handle<i::CallHandlerInfo> obj =
1236 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001237 SET_FIELD_WRAPPED(obj, set_callback, callback);
kasper.lund212ac232008-07-16 07:07:30 +00001238 if (data.IsEmpty()) data = v8::Undefined();
1239 obj->set_data(*Utils::OpenHandle(*data));
1240 Utils::OpenHandle(this)->set_instance_call_handler(*obj);
1241}
1242
1243
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244// --- O b j e c t T e m p l a t e ---
1245
1246
1247Local<ObjectTemplate> ObjectTemplate::New() {
1248 return New(Local<FunctionTemplate>());
1249}
1250
1251
1252Local<ObjectTemplate> ObjectTemplate::New(
1253 v8::Handle<FunctionTemplate> constructor) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001254 i::Isolate* isolate = i::Isolate::Current();
1255 if (IsDeadCheck(isolate, "v8::ObjectTemplate::New()")) {
1256 return Local<ObjectTemplate>();
1257 }
1258 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1259 LOG_API(isolate, "ObjectTemplate::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001260 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001261 i::Handle<i::Struct> struct_obj =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001262 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001263 i::Handle<i::ObjectTemplateInfo> obj =
1264 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1265 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1266 if (!constructor.IsEmpty())
1267 obj->set_constructor(*Utils::OpenHandle(*constructor));
kasper.lund212ac232008-07-16 07:07:30 +00001268 obj->set_internal_field_count(i::Smi::FromInt(0));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269 return Utils::ToLocal(obj);
1270}
1271
1272
1273// Ensure that the object template has a constructor. If no
1274// constructor is available we create one.
1275static void EnsureConstructor(ObjectTemplate* object_template) {
1276 if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
1277 Local<FunctionTemplate> templ = FunctionTemplate::New();
1278 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1279 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1280 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1281 }
1282}
1283
1284
1285void ObjectTemplate::SetAccessor(v8::Handle<String> name,
1286 AccessorGetter getter,
1287 AccessorSetter setter,
1288 v8::Handle<Value> data,
1289 AccessControl settings,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001290 PropertyAttribute attribute,
1291 v8::Handle<AccessorSignature> signature) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001292 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001293 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001294 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001295 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001296 EnsureConstructor(this);
1297 i::FunctionTemplateInfo* constructor =
1298 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1299 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1300 Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
1301 getter,
1302 setter,
1303 data,
1304 settings,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001305 attribute,
1306 signature);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307}
1308
1309
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00001310void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
1311 NamedPropertySetter setter,
1312 NamedPropertyQuery query,
1313 NamedPropertyDeleter remover,
1314 NamedPropertyEnumerator enumerator,
1315 Handle<Value> data) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001316 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001317 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
1318 return;
1319 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001320 ENTER_V8(isolate);
1321 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001322 EnsureConstructor(this);
1323 i::FunctionTemplateInfo* constructor =
1324 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1325 i::Handle<i::FunctionTemplateInfo> cons(constructor);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00001326 Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
1327 setter,
1328 query,
1329 remover,
1330 enumerator,
1331 data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001332}
1333
1334
1335void ObjectTemplate::MarkAsUndetectable() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001336 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001337 if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001338 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001339 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001340 EnsureConstructor(this);
1341 i::FunctionTemplateInfo* constructor =
1342 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1343 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1344 cons->set_undetectable(true);
1345}
1346
1347
1348void ObjectTemplate::SetAccessCheckCallbacks(
1349 NamedSecurityCallback named_callback,
1350 IndexedSecurityCallback indexed_callback,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001351 Handle<Value> data,
1352 bool turned_on_by_default) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001353 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001354 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
1355 return;
1356 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001357 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001358 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001359 EnsureConstructor(this);
1360
1361 i::Handle<i::Struct> struct_info =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001362 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001363 i::Handle<i::AccessCheckInfo> info =
1364 i::Handle<i::AccessCheckInfo>::cast(struct_info);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001365
1366 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1367 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1368
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001369 if (data.IsEmpty()) data = v8::Undefined();
1370 info->set_data(*Utils::OpenHandle(*data));
1371
1372 i::FunctionTemplateInfo* constructor =
1373 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1374 i::Handle<i::FunctionTemplateInfo> cons(constructor);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001375 cons->set_access_check_info(*info);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001376 cons->set_needs_access_check(turned_on_by_default);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001377}
1378
1379
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001380void ObjectTemplate::SetIndexedPropertyHandler(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001381 IndexedPropertyGetter getter,
1382 IndexedPropertySetter setter,
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001383 IndexedPropertyQuery query,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384 IndexedPropertyDeleter remover,
1385 IndexedPropertyEnumerator enumerator,
1386 Handle<Value> data) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001387 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001388 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
1389 return;
1390 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001391 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001392 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001393 EnsureConstructor(this);
1394 i::FunctionTemplateInfo* constructor =
1395 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1396 i::Handle<i::FunctionTemplateInfo> cons(constructor);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001397 Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
1398 setter,
1399 query,
1400 remover,
1401 enumerator,
1402 data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001403}
1404
1405
1406void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
1407 Handle<Value> data) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001408 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001409 if (IsDeadCheck(isolate,
1410 "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
1411 return;
1412 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001413 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001414 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001415 EnsureConstructor(this);
1416 i::FunctionTemplateInfo* constructor =
1417 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1418 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1419 Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
1420}
1421
1422
kasper.lund212ac232008-07-16 07:07:30 +00001423int ObjectTemplate::InternalFieldCount() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001424 if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001425 "v8::ObjectTemplate::InternalFieldCount()")) {
kasper.lund212ac232008-07-16 07:07:30 +00001426 return 0;
1427 }
1428 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001429}
1430
1431
kasper.lund212ac232008-07-16 07:07:30 +00001432void ObjectTemplate::SetInternalFieldCount(int value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001433 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001434 if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
1435 return;
1436 }
kasper.lund212ac232008-07-16 07:07:30 +00001437 if (!ApiCheck(i::Smi::IsValid(value),
1438 "v8::ObjectTemplate::SetInternalFieldCount()",
1439 "Invalid internal field count")) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440 return;
1441 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001442 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001443 if (value > 0) {
1444 // The internal field count is set by the constructor function's
1445 // construct code, so we ensure that there is a constructor
1446 // function to do the setting.
1447 EnsureConstructor(this);
1448 }
kasper.lund212ac232008-07-16 07:07:30 +00001449 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450}
1451
1452
kasper.lund212ac232008-07-16 07:07:30 +00001453// --- S c r i p t D a t a ---
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001454
1455
1456ScriptData* ScriptData::PreCompile(const char* input, int length) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001457 i::Utf8ToUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001458 reinterpret_cast<const unsigned char*>(input), length);
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00001459 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460}
1461
1462
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001463ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1464 i::Handle<i::String> str = Utils::OpenHandle(*source);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001465 if (str->IsExternalTwoByteString()) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001466 i::ExternalTwoByteStringUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001467 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00001468 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001469 } else {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001470 i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00001471 return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001472 }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001473}
1474
1475
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001476ScriptData* ScriptData::New(const char* data, int length) {
1477 // Return an empty ScriptData if the length is obviously invalid.
1478 if (length % sizeof(unsigned) != 0) {
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001479 return new i::ScriptDataImpl();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001480 }
1481
1482 // Copy the data to ensure it is properly aligned.
1483 int deserialized_data_length = length / sizeof(unsigned);
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001484 // If aligned, don't create a copy of the data.
1485 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1486 return new i::ScriptDataImpl(data, length);
1487 }
1488 // Copy the data to align it.
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001489 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001490 i::OS::MemCopy(deserialized_data, data, length);
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001491
1492 return new i::ScriptDataImpl(
1493 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494}
1495
1496
1497// --- S c r i p t ---
1498
1499
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001500Local<Script> Script::New(v8::Handle<String> source,
1501 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001502 v8::ScriptData* pre_data,
1503 v8::Handle<String> script_data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001504 i::Isolate* isolate = i::Isolate::Current();
1505 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1506 LOG_API(isolate, "Script::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001507 ENTER_V8(isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001508 i::SharedFunctionInfo* raw_result = NULL;
1509 { i::HandleScope scope(isolate);
1510 i::Handle<i::String> str = Utils::OpenHandle(*source);
1511 i::Handle<i::Object> name_obj;
1512 int line_offset = 0;
1513 int column_offset = 0;
1514 if (origin != NULL) {
1515 if (!origin->ResourceName().IsEmpty()) {
1516 name_obj = Utils::OpenHandle(*origin->ResourceName());
1517 }
1518 if (!origin->ResourceLineOffset().IsEmpty()) {
1519 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1520 }
1521 if (!origin->ResourceColumnOffset().IsEmpty()) {
1522 column_offset =
1523 static_cast<int>(origin->ResourceColumnOffset()->Value());
1524 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001525 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001526 EXCEPTION_PREAMBLE(isolate);
1527 i::ScriptDataImpl* pre_data_impl =
1528 static_cast<i::ScriptDataImpl*>(pre_data);
1529 // We assert that the pre-data is sane, even though we can actually
1530 // handle it if it turns out not to be in release mode.
1531 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
1532 // If the pre-data isn't sane we simply ignore it
1533 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1534 pre_data_impl = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001535 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001536 i::Handle<i::SharedFunctionInfo> result =
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001537 i::Compiler::Compile(str,
1538 name_obj,
1539 line_offset,
1540 column_offset,
1541 NULL,
1542 pre_data_impl,
1543 Utils::OpenHandle(*script_data),
1544 i::NOT_NATIVES_CODE);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001545 has_pending_exception = result.is_null();
1546 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
1547 raw_result = *result;
1548 }
1549 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001550 return Local<Script>(ToApi<Script>(result));
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001551}
1552
1553
1554Local<Script> Script::New(v8::Handle<String> source,
1555 v8::Handle<Value> file_name) {
1556 ScriptOrigin origin(file_name);
1557 return New(source, &origin);
1558}
1559
1560
1561Local<Script> Script::Compile(v8::Handle<String> source,
1562 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001563 v8::ScriptData* pre_data,
1564 v8::Handle<String> script_data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001565 i::Isolate* isolate = i::Isolate::Current();
1566 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1567 LOG_API(isolate, "Script::Compile");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001568 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00001569 Local<Script> generic = New(source, origin, pre_data, script_data);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001570 if (generic.IsEmpty())
1571 return generic;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001572 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1573 i::Handle<i::SharedFunctionInfo> function =
1574 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001575 i::Handle<i::JSFunction> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001576 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1577 function,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001578 isolate->global_context());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579 return Local<Script>(ToApi<Script>(result));
1580}
1581
1582
mads.s.agercbaa0602008-08-14 13:41:48 +00001583Local<Script> Script::Compile(v8::Handle<String> source,
ager@chromium.org5c838252010-02-19 08:53:10 +00001584 v8::Handle<Value> file_name,
1585 v8::Handle<String> script_data) {
mads.s.agercbaa0602008-08-14 13:41:48 +00001586 ScriptOrigin origin(file_name);
ager@chromium.org5c838252010-02-19 08:53:10 +00001587 return Compile(source, &origin, 0, script_data);
mads.s.agercbaa0602008-08-14 13:41:48 +00001588}
1589
1590
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001591Local<Value> Script::Run() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001592 i::Isolate* isolate = i::Isolate::Current();
1593 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1594 LOG_API(isolate, "Script::Run");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001595 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596 i::Object* raw_result = NULL;
1597 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001598 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001599 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1600 i::Handle<i::JSFunction> fun;
1601 if (obj->IsSharedFunctionInfo()) {
1602 i::Handle<i::SharedFunctionInfo>
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001603 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001604 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001605 function_info, isolate->global_context());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001606 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001607 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001608 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001609 EXCEPTION_PREAMBLE(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001610 i::Handle<i::Object> receiver(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001611 isolate->context()->global_proxy(), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612 i::Handle<i::Object> result =
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001613 i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00001614 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001615 raw_result = *result;
1616 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001617 i::Handle<i::Object> result(raw_result, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001618 return Utils::ToLocal(result);
1619}
1620
1621
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001622static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1623 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1624 i::Handle<i::SharedFunctionInfo> result;
1625 if (obj->IsSharedFunctionInfo()) {
1626 result =
1627 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1628 } else {
1629 result =
1630 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1631 }
1632 return result;
1633}
1634
1635
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001636Local<Value> Script::Id() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001637 i::Isolate* isolate = i::Isolate::Current();
1638 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1639 LOG_API(isolate, "Script::Id");
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001640 i::Object* raw_id = NULL;
1641 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001642 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001643 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1644 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001645 i::Handle<i::Object> id(script->id());
1646 raw_id = *id;
1647 }
1648 i::Handle<i::Object> id(raw_id);
1649 return Utils::ToLocal(id);
1650}
1651
1652
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00001653void Script::SetData(v8::Handle<String> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001654 i::Isolate* isolate = i::Isolate::Current();
1655 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1656 LOG_API(isolate, "Script::SetData");
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001657 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001658 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001659 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001660 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001661 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001662 script->set_data(*raw_data);
1663 }
1664}
1665
1666
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667// --- E x c e p t i o n s ---
1668
1669
1670v8::TryCatch::TryCatch()
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001671 : isolate_(i::Isolate::Current()),
1672 next_(isolate_->try_catch_handler_address()),
1673 exception_(isolate_->heap()->the_hole_value()),
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001674 message_(i::Smi::FromInt(0)),
1675 is_verbose_(false),
ager@chromium.org68e7ab72009-09-23 09:40:39 +00001676 can_continue_(true),
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001677 capture_message_(true),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001678 rethrow_(false) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001679 isolate_->RegisterTryCatchHandler(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001680}
1681
1682
1683v8::TryCatch::~TryCatch() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001684 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001685 if (rethrow_) {
1686 v8::HandleScope scope;
1687 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001688 isolate_->UnregisterTryCatchHandler(this);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001689 v8::ThrowException(exc);
1690 } else {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001691 isolate_->UnregisterTryCatchHandler(this);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001692 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001693}
1694
1695
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001696bool v8::TryCatch::HasCaught() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001697 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1698}
1699
1700
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001701bool v8::TryCatch::CanContinue() const {
1702 return can_continue_;
1703}
1704
1705
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001706v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1707 if (!HasCaught()) return v8::Local<v8::Value>();
1708 rethrow_ = true;
1709 return v8::Undefined();
1710}
1711
1712
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001713v8::Local<Value> v8::TryCatch::Exception() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001714 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715 if (HasCaught()) {
1716 // Check for out of memory exception.
1717 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001718 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001719 } else {
1720 return v8::Local<Value>();
1721 }
1722}
1723
1724
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001725v8::Local<Value> v8::TryCatch::StackTrace() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001726 ASSERT(isolate_ == i::Isolate::Current());
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001727 if (HasCaught()) {
1728 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1729 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001730 i::HandleScope scope(isolate_);
1731 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
1732 i::Handle<i::String> name = isolate_->factory()->LookupAsciiSymbol("stack");
1733 if (!obj->HasProperty(*name)) return v8::Local<Value>();
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001734 i::Handle<i::Object> value = i::GetProperty(obj, name);
1735 if (value.is_null()) return v8::Local<Value>();
1736 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001737 } else {
1738 return v8::Local<Value>();
1739 }
1740}
1741
1742
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001743v8::Local<v8::Message> v8::TryCatch::Message() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001744 ASSERT(isolate_ == i::Isolate::Current());
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001745 if (HasCaught() && message_ != i::Smi::FromInt(0)) {
1746 i::Object* message = reinterpret_cast<i::Object*>(message_);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001747 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001748 } else {
1749 return v8::Local<v8::Message>();
1750 }
1751}
1752
1753
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754void v8::TryCatch::Reset() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001755 ASSERT(isolate_ == i::Isolate::Current());
1756 exception_ = isolate_->heap()->the_hole_value();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001757 message_ = i::Smi::FromInt(0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001758}
1759
1760
1761void v8::TryCatch::SetVerbose(bool value) {
1762 is_verbose_ = value;
1763}
1764
1765
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001766void v8::TryCatch::SetCaptureMessage(bool value) {
1767 capture_message_ = value;
1768}
1769
1770
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771// --- M e s s a g e ---
1772
1773
ager@chromium.org32912102009-01-16 10:38:43 +00001774Local<String> Message::Get() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001775 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001776 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001777 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778 HandleScope scope;
1779 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1780 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
1781 Local<String> result = Utils::ToLocal(raw_result);
1782 return scope.Close(result);
1783}
1784
1785
ager@chromium.org32912102009-01-16 10:38:43 +00001786v8::Handle<Value> Message::GetScriptResourceName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001787 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001788 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001789 return Local<String>();
1790 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001791 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792 HandleScope scope;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001793 i::Handle<i::JSMessageObject> message =
1794 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001795 // Return this.script.name.
1796 i::Handle<i::JSValue> script =
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001797 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001799 return scope.Close(Utils::ToLocal(resource_name));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800}
1801
1802
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001803v8::Handle<Value> Message::GetScriptData() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001804 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001805 if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001806 return Local<Value>();
1807 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001808 ENTER_V8(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001809 HandleScope scope;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001810 i::Handle<i::JSMessageObject> message =
1811 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001812 // Return this.script.data.
1813 i::Handle<i::JSValue> script =
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001814 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script()));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001815 i::Handle<i::Object> data(i::Script::cast(script->value())->data());
1816 return scope.Close(Utils::ToLocal(data));
1817}
1818
1819
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00001820v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001821 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00001823 return Local<v8::StackTrace>();
1824 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001825 ENTER_V8(isolate);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00001826 HandleScope scope;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001827 i::Handle<i::JSMessageObject> message =
1828 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1829 i::Handle<i::Object> stackFramesObj(message->stack_frames());
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00001830 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
1831 i::Handle<i::JSArray> stackTrace =
1832 i::Handle<i::JSArray>::cast(stackFramesObj);
1833 return scope.Close(Utils::StackTraceToLocal(stackTrace));
1834}
1835
1836
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1838 i::Handle<i::Object> recv,
1839 int argc,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001840 i::Handle<i::Object> argv[],
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001841 bool* has_pending_exception) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 i::Isolate* isolate = i::Isolate::Current();
1843 i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name);
lrn@chromium.org303ada72010-10-27 09:33:13 +00001844 i::Object* object_fun =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001845 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001846 i::Handle<i::JSFunction> fun =
1847 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
1848 i::Handle<i::Object> value =
1849 i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
1850 return value;
1851}
1852
1853
1854static i::Handle<i::Object> CallV8HeapFunction(const char* name,
1855 i::Handle<i::Object> data,
1856 bool* has_pending_exception) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001857 i::Handle<i::Object> argv[] = { data };
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001858 return CallV8HeapFunction(name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001859 i::Isolate::Current()->js_builtins_object(),
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001860 ARRAY_SIZE(argv),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001861 argv,
1862 has_pending_exception);
1863}
1864
1865
ager@chromium.org32912102009-01-16 10:38:43 +00001866int Message::GetLineNumber() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001867 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001868 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001869 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001870 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001871
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001872 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001873 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
1874 Utils::OpenHandle(this),
1875 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001876 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877 return static_cast<int>(result->Number());
1878}
1879
1880
ager@chromium.org32912102009-01-16 10:38:43 +00001881int Message::GetStartPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001882 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001883 if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001884 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001885 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001886 i::Handle<i::JSMessageObject> message =
1887 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1888 return message->start_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001889}
1890
1891
ager@chromium.org32912102009-01-16 10:38:43 +00001892int Message::GetEndPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001893 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001894 if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001895 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001896 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001897 i::Handle<i::JSMessageObject> message =
1898 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
1899 return message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001900}
1901
1902
ager@chromium.org32912102009-01-16 10:38:43 +00001903int Message::GetStartColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001904 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001905 if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
1906 return kNoColumnInfo;
1907 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001908 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001909 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001910 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001911 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001912 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1913 "GetPositionInLine",
1914 data_obj,
1915 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001916 EXCEPTION_BAILOUT_CHECK(isolate, 0);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001917 return static_cast<int>(start_col_obj->Number());
1918}
1919
1920
ager@chromium.org32912102009-01-16 10:38:43 +00001921int Message::GetEndColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001922 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001923 if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001924 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001925 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001926 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001927 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001928 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
1929 "GetPositionInLine",
1930 data_obj,
1931 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001932 EXCEPTION_BAILOUT_CHECK(isolate, 0);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001933 i::Handle<i::JSMessageObject> message =
1934 i::Handle<i::JSMessageObject>::cast(data_obj);
1935 int start = message->start_position();
1936 int end = message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001937 return static_cast<int>(start_col_obj->Number()) + (end - start);
1938}
1939
1940
ager@chromium.org32912102009-01-16 10:38:43 +00001941Local<String> Message::GetSourceLine() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001942 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001943 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001944 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001945 HandleScope scope;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001946 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
1948 Utils::OpenHandle(this),
1949 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001950 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001951 if (result->IsString()) {
1952 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
1953 } else {
1954 return Local<String>();
1955 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001956}
1957
1958
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001959void Message::PrintCurrentStackTrace(FILE* out) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001960 i::Isolate* isolate = i::Isolate::Current();
1961 if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001962 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001963 isolate->PrintCurrentStackTrace(out);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001964}
1965
1966
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001967// --- S t a c k T r a c e ---
1968
1969Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001970 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001971 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
1972 return Local<StackFrame>();
1973 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001974 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001975 HandleScope scope;
1976 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
lrn@chromium.org303ada72010-10-27 09:33:13 +00001977 i::Object* raw_object = self->GetElementNoExceptionThrown(index);
1978 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001979 return scope.Close(Utils::StackFrameToLocal(obj));
1980}
1981
1982
1983int StackTrace::GetFrameCount() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001984 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001985 if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001986 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001987 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
1988}
1989
1990
1991Local<Array> StackTrace::AsArray() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001992 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001993 if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001994 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001995 return Utils::ToLocal(Utils::OpenHandle(this));
1996}
1997
1998
1999Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
2000 StackTraceOptions options) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002001 i::Isolate* isolate = i::Isolate::Current();
2002 if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
2003 Local<StackTrace>();
2004 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002005 ENTER_V8(isolate);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002006 i::Handle<i::JSArray> stackTrace =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002007 isolate->CaptureCurrentStackTrace(frame_limit, options);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002008 return Utils::StackTraceToLocal(stackTrace);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002009}
2010
2011
2012// --- S t a c k F r a m e ---
2013
2014int StackFrame::GetLineNumber() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002015 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002016 if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002017 return Message::kNoLineNumberInfo;
2018 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002019 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002020 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002021 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2022 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
2023 if (!line->IsSmi()) {
2024 return Message::kNoLineNumberInfo;
2025 }
2026 return i::Smi::cast(*line)->value();
2027}
2028
2029
2030int StackFrame::GetColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002031 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002032 if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002033 return Message::kNoColumnInfo;
2034 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002035 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002036 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002037 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2038 i::Handle<i::Object> column = GetProperty(self, "column");
2039 if (!column->IsSmi()) {
2040 return Message::kNoColumnInfo;
2041 }
2042 return i::Smi::cast(*column)->value();
2043}
2044
2045
2046Local<String> StackFrame::GetScriptName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002047 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002048 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
2049 return Local<String>();
2050 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002051 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002052 HandleScope scope;
2053 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2054 i::Handle<i::Object> name = GetProperty(self, "scriptName");
2055 if (!name->IsString()) {
2056 return Local<String>();
2057 }
2058 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2059}
2060
2061
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002062Local<String> StackFrame::GetScriptNameOrSourceURL() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002063 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002064 if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002065 return Local<String>();
2066 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002067 ENTER_V8(isolate);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002068 HandleScope scope;
2069 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2070 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
2071 if (!name->IsString()) {
2072 return Local<String>();
2073 }
2074 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2075}
2076
2077
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002078Local<String> StackFrame::GetFunctionName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002079 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002080 if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
2081 return Local<String>();
2082 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002083 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002084 HandleScope scope;
2085 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2086 i::Handle<i::Object> name = GetProperty(self, "functionName");
2087 if (!name->IsString()) {
2088 return Local<String>();
2089 }
2090 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2091}
2092
2093
2094bool StackFrame::IsEval() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002095 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002096 if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002097 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002098 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002099 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2100 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
2101 return is_eval->IsTrue();
2102}
2103
2104
2105bool StackFrame::IsConstructor() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002106 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002107 if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002108 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002109 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002110 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2111 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
2112 return is_constructor->IsTrue();
2113}
2114
2115
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002116// --- D a t a ---
2117
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002118bool Value::FullIsUndefined() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002119 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
2120 return false;
2121 }
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002122 bool result = Utils::OpenHandle(this)->IsUndefined();
2123 ASSERT_EQ(result, QuickIsUndefined());
2124 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002125}
2126
2127
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002128bool Value::FullIsNull() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002129 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002130 bool result = Utils::OpenHandle(this)->IsNull();
2131 ASSERT_EQ(result, QuickIsNull());
2132 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133}
2134
2135
ager@chromium.org32912102009-01-16 10:38:43 +00002136bool Value::IsTrue() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002137 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsTrue()")) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138 return Utils::OpenHandle(this)->IsTrue();
2139}
2140
2141
ager@chromium.org32912102009-01-16 10:38:43 +00002142bool Value::IsFalse() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002143 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFalse()")) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144 return Utils::OpenHandle(this)->IsFalse();
2145}
2146
2147
ager@chromium.org32912102009-01-16 10:38:43 +00002148bool Value::IsFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002149 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsFunction()")) {
2150 return false;
2151 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002152 return Utils::OpenHandle(this)->IsJSFunction();
2153}
2154
2155
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002156bool Value::FullIsString() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002157 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsString()")) return false;
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002158 bool result = Utils::OpenHandle(this)->IsString();
2159 ASSERT_EQ(result, QuickIsString());
2160 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161}
2162
2163
ager@chromium.org32912102009-01-16 10:38:43 +00002164bool Value::IsArray() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002165 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArray()")) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002166 return Utils::OpenHandle(this)->IsJSArray();
2167}
2168
2169
ager@chromium.org32912102009-01-16 10:38:43 +00002170bool Value::IsObject() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002171 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsObject()")) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002172 return Utils::OpenHandle(this)->IsJSObject();
2173}
2174
2175
ager@chromium.org32912102009-01-16 10:38:43 +00002176bool Value::IsNumber() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002177 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNumber()")) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002178 return Utils::OpenHandle(this)->IsNumber();
2179}
2180
2181
ager@chromium.org32912102009-01-16 10:38:43 +00002182bool Value::IsBoolean() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002183 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsBoolean()")) {
2184 return false;
2185 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002186 return Utils::OpenHandle(this)->IsBoolean();
2187}
2188
2189
ager@chromium.org32912102009-01-16 10:38:43 +00002190bool Value::IsExternal() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002191 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
2192 return false;
2193 }
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002194 return Utils::OpenHandle(this)->IsForeign();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195}
2196
2197
ager@chromium.org32912102009-01-16 10:38:43 +00002198bool Value::IsInt32() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002199 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2201 if (obj->IsSmi()) return true;
2202 if (obj->IsNumber()) {
2203 double value = obj->Number();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002204 static const i::DoubleRepresentation minus_zero(-0.0);
2205 i::DoubleRepresentation rep(value);
2206 if (rep.bits == minus_zero.bits) {
2207 return false;
2208 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002209 return i::FastI2D(i::FastD2I(value)) == value;
2210 }
2211 return false;
2212}
2213
2214
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002215bool Value::IsUint32() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002216 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUint32()")) return false;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002217 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2218 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2219 if (obj->IsNumber()) {
2220 double value = obj->Number();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002221 static const i::DoubleRepresentation minus_zero(-0.0);
2222 i::DoubleRepresentation rep(value);
2223 if (rep.bits == minus_zero.bits) {
2224 return false;
2225 }
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002226 return i::FastUI2D(i::FastD2UI(value)) == value;
2227 }
2228 return false;
2229}
2230
2231
ager@chromium.org32912102009-01-16 10:38:43 +00002232bool Value::IsDate() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002233 i::Isolate* isolate = i::Isolate::Current();
2234 if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002235 i::Handle<i::Object> obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002236 return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002237}
2238
2239
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002240bool Value::IsStringObject() const {
2241 i::Isolate* isolate = i::Isolate::Current();
2242 if (IsDeadCheck(isolate, "v8::Value::IsStringObject()")) return false;
2243 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2244 return obj->HasSpecificClassOf(isolate->heap()->String_symbol());
2245}
2246
2247
2248bool Value::IsNumberObject() const {
2249 i::Isolate* isolate = i::Isolate::Current();
2250 if (IsDeadCheck(isolate, "v8::Value::IsNumberObject()")) return false;
2251 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2252 return obj->HasSpecificClassOf(isolate->heap()->Number_symbol());
2253}
2254
2255
2256static i::Object* LookupBuiltin(i::Isolate* isolate,
2257 const char* builtin_name) {
2258 i::Handle<i::String> symbol =
2259 isolate->factory()->LookupAsciiSymbol(builtin_name);
2260 i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
2261 return builtins->GetPropertyNoExceptionThrown(*symbol);
2262}
2263
2264
2265static bool CheckConstructor(i::Isolate* isolate,
2266 i::Handle<i::JSObject> obj,
2267 const char* class_name) {
2268 return obj->map()->constructor() == LookupBuiltin(isolate, class_name);
2269}
2270
2271
2272bool Value::IsNativeError() const {
2273 i::Isolate* isolate = i::Isolate::Current();
2274 if (IsDeadCheck(isolate, "v8::Value::IsNativeError()")) return false;
2275 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2276 if (obj->IsJSObject()) {
2277 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
2278 return CheckConstructor(isolate, js_obj, "$Error") ||
2279 CheckConstructor(isolate, js_obj, "$EvalError") ||
2280 CheckConstructor(isolate, js_obj, "$RangeError") ||
2281 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2282 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2283 CheckConstructor(isolate, js_obj, "$TypeError") ||
2284 CheckConstructor(isolate, js_obj, "$URIError");
2285 } else {
2286 return false;
2287 }
2288}
2289
2290
2291bool Value::IsBooleanObject() const {
2292 i::Isolate* isolate = i::Isolate::Current();
2293 if (IsDeadCheck(isolate, "v8::Value::IsBooleanObject()")) return false;
2294 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2295 return obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol());
2296}
2297
2298
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002299bool Value::IsRegExp() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002300 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002301 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2302 return obj->IsJSRegExp();
2303}
2304
2305
ager@chromium.org32912102009-01-16 10:38:43 +00002306Local<String> Value::ToString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2308 i::Handle<i::Object> str;
2309 if (obj->IsString()) {
2310 str = obj;
2311 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002312 i::Isolate* isolate = i::Isolate::Current();
2313 if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
2314 return Local<String>();
2315 }
2316 LOG_API(isolate, "ToString");
2317 ENTER_V8(isolate);
2318 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002319 str = i::Execution::ToString(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002320 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002321 }
2322 return Local<String>(ToApi<String>(str));
2323}
2324
2325
ager@chromium.org32912102009-01-16 10:38:43 +00002326Local<String> Value::ToDetailString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002327 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2328 i::Handle<i::Object> str;
2329 if (obj->IsString()) {
2330 str = obj;
2331 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002332 i::Isolate* isolate = i::Isolate::Current();
2333 if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
2334 return Local<String>();
2335 }
2336 LOG_API(isolate, "ToDetailString");
2337 ENTER_V8(isolate);
2338 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002339 str = i::Execution::ToDetailString(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002340 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002341 }
2342 return Local<String>(ToApi<String>(str));
2343}
2344
2345
ager@chromium.org32912102009-01-16 10:38:43 +00002346Local<v8::Object> Value::ToObject() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2348 i::Handle<i::Object> val;
2349 if (obj->IsJSObject()) {
2350 val = obj;
2351 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002352 i::Isolate* isolate = i::Isolate::Current();
2353 if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
2354 return Local<v8::Object>();
2355 }
2356 LOG_API(isolate, "ToObject");
2357 ENTER_V8(isolate);
2358 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359 val = i::Execution::ToObject(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002360 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361 }
2362 return Local<v8::Object>(ToApi<Object>(val));
2363}
2364
2365
ager@chromium.org32912102009-01-16 10:38:43 +00002366Local<Boolean> Value::ToBoolean() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002367 i::Handle<i::Object> obj = Utils::OpenHandle(this);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002368 if (obj->IsBoolean()) {
2369 return Local<Boolean>(ToApi<Boolean>(obj));
2370 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002371 i::Isolate* isolate = i::Isolate::Current();
2372 if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
2373 return Local<Boolean>();
2374 }
2375 LOG_API(isolate, "ToBoolean");
2376 ENTER_V8(isolate);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002377 i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
2378 return Local<Boolean>(ToApi<Boolean>(val));
2379 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380}
2381
2382
ager@chromium.org32912102009-01-16 10:38:43 +00002383Local<Number> Value::ToNumber() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2385 i::Handle<i::Object> num;
2386 if (obj->IsNumber()) {
2387 num = obj;
2388 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002389 i::Isolate* isolate = i::Isolate::Current();
2390 if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
2391 return Local<Number>();
2392 }
2393 LOG_API(isolate, "ToNumber");
2394 ENTER_V8(isolate);
2395 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002396 num = i::Execution::ToNumber(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002397 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398 }
2399 return Local<Number>(ToApi<Number>(num));
2400}
2401
2402
ager@chromium.org32912102009-01-16 10:38:43 +00002403Local<Integer> Value::ToInteger() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002404 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2405 i::Handle<i::Object> num;
2406 if (obj->IsSmi()) {
2407 num = obj;
2408 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002409 i::Isolate* isolate = i::Isolate::Current();
2410 if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
2411 LOG_API(isolate, "ToInteger");
2412 ENTER_V8(isolate);
2413 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414 num = i::Execution::ToInteger(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002415 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002416 }
2417 return Local<Integer>(ToApi<Integer>(num));
2418}
2419
2420
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002421void External::CheckCast(v8::Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002422 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002423 i::Handle<i::Object> obj = Utils::OpenHandle(that);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002424 ApiCheck(obj->IsForeign(),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425 "v8::External::Cast()",
2426 "Could not convert to external");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427}
2428
2429
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002430void v8::Object::CheckCast(Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002431 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002432 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2433 ApiCheck(obj->IsJSObject(),
2434 "v8::Object::Cast()",
2435 "Could not convert to object");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002436}
2437
2438
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002439void v8::Function::CheckCast(Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002440 if (IsDeadCheck(i::Isolate::Current(), "v8::Function::Cast()")) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2442 ApiCheck(obj->IsJSFunction(),
2443 "v8::Function::Cast()",
2444 "Could not convert to function");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002445}
2446
2447
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002448void v8::String::CheckCast(v8::Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002449 if (IsDeadCheck(i::Isolate::Current(), "v8::String::Cast()")) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002450 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2451 ApiCheck(obj->IsString(),
2452 "v8::String::Cast()",
2453 "Could not convert to string");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002454}
2455
2456
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002457void v8::Number::CheckCast(v8::Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002458 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Cast()")) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2460 ApiCheck(obj->IsNumber(),
2461 "v8::Number::Cast()",
2462 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002463}
2464
2465
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002466void v8::Integer::CheckCast(v8::Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002467 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Cast()")) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002468 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2469 ApiCheck(obj->IsNumber(),
2470 "v8::Integer::Cast()",
2471 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002472}
2473
2474
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002475void v8::Array::CheckCast(Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002476 if (IsDeadCheck(i::Isolate::Current(), "v8::Array::Cast()")) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002477 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2478 ApiCheck(obj->IsJSArray(),
2479 "v8::Array::Cast()",
2480 "Could not convert to array");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002481}
2482
2483
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002484void v8::Date::CheckCast(v8::Value* that) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002485 i::Isolate* isolate = i::Isolate::Current();
2486 if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002487 i::Handle<i::Object> obj = Utils::OpenHandle(that);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002488 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002489 "v8::Date::Cast()",
2490 "Could not convert to date");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002491}
2492
2493
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002494void v8::StringObject::CheckCast(v8::Value* that) {
2495 i::Isolate* isolate = i::Isolate::Current();
2496 if (IsDeadCheck(isolate, "v8::StringObject::Cast()")) return;
2497 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2498 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_symbol()),
2499 "v8::StringObject::Cast()",
2500 "Could not convert to StringObject");
2501}
2502
2503
2504void v8::NumberObject::CheckCast(v8::Value* that) {
2505 i::Isolate* isolate = i::Isolate::Current();
2506 if (IsDeadCheck(isolate, "v8::NumberObject::Cast()")) return;
2507 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2508 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_symbol()),
2509 "v8::NumberObject::Cast()",
2510 "Could not convert to NumberObject");
2511}
2512
2513
2514void v8::BooleanObject::CheckCast(v8::Value* that) {
2515 i::Isolate* isolate = i::Isolate::Current();
2516 if (IsDeadCheck(isolate, "v8::BooleanObject::Cast()")) return;
2517 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2518 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol()),
2519 "v8::BooleanObject::Cast()",
2520 "Could not convert to BooleanObject");
2521}
2522
2523
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002524void v8::RegExp::CheckCast(v8::Value* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002525 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002526 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2527 ApiCheck(obj->IsJSRegExp(),
2528 "v8::RegExp::Cast()",
2529 "Could not convert to regular expression");
2530}
2531
2532
ager@chromium.org32912102009-01-16 10:38:43 +00002533bool Value::BooleanValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002534 i::Handle<i::Object> obj = Utils::OpenHandle(this);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002535 if (obj->IsBoolean()) {
2536 return obj->IsTrue();
2537 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002538 i::Isolate* isolate = i::Isolate::Current();
2539 if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
2540 LOG_API(isolate, "BooleanValue");
2541 ENTER_V8(isolate);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002542 i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
2543 return value->IsTrue();
2544 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002545}
2546
2547
ager@chromium.org32912102009-01-16 10:38:43 +00002548double Value::NumberValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002549 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2550 i::Handle<i::Object> num;
2551 if (obj->IsNumber()) {
2552 num = obj;
2553 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002554 i::Isolate* isolate = i::Isolate::Current();
2555 if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
2556 return i::OS::nan_value();
2557 }
2558 LOG_API(isolate, "NumberValue");
2559 ENTER_V8(isolate);
2560 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002561 num = i::Execution::ToNumber(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002562 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002563 }
2564 return num->Number();
2565}
2566
2567
ager@chromium.org32912102009-01-16 10:38:43 +00002568int64_t Value::IntegerValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002569 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2570 i::Handle<i::Object> num;
2571 if (obj->IsNumber()) {
2572 num = obj;
2573 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002574 i::Isolate* isolate = i::Isolate::Current();
2575 if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
2576 LOG_API(isolate, "IntegerValue");
2577 ENTER_V8(isolate);
2578 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002579 num = i::Execution::ToInteger(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002580 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002581 }
2582 if (num->IsSmi()) {
2583 return i::Smi::cast(*num)->value();
2584 } else {
2585 return static_cast<int64_t>(num->Number());
2586 }
2587}
2588
2589
ager@chromium.org32912102009-01-16 10:38:43 +00002590Local<Int32> Value::ToInt32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002591 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2592 i::Handle<i::Object> num;
2593 if (obj->IsSmi()) {
2594 num = obj;
2595 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002596 i::Isolate* isolate = i::Isolate::Current();
2597 if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
2598 LOG_API(isolate, "ToInt32");
2599 ENTER_V8(isolate);
2600 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002601 num = i::Execution::ToInt32(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002602 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603 }
2604 return Local<Int32>(ToApi<Int32>(num));
2605}
2606
2607
ager@chromium.org32912102009-01-16 10:38:43 +00002608Local<Uint32> Value::ToUint32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002609 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2610 i::Handle<i::Object> num;
2611 if (obj->IsSmi()) {
2612 num = obj;
2613 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002614 i::Isolate* isolate = i::Isolate::Current();
2615 if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
2616 LOG_API(isolate, "ToUInt32");
2617 ENTER_V8(isolate);
2618 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002619 num = i::Execution::ToUint32(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002620 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002621 }
2622 return Local<Uint32>(ToApi<Uint32>(num));
2623}
2624
2625
ager@chromium.org32912102009-01-16 10:38:43 +00002626Local<Uint32> Value::ToArrayIndex() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002627 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2628 if (obj->IsSmi()) {
2629 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2630 return Local<Uint32>();
2631 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002632 i::Isolate* isolate = i::Isolate::Current();
2633 if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
2634 LOG_API(isolate, "ToArrayIndex");
2635 ENTER_V8(isolate);
2636 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002637 i::Handle<i::Object> string_obj =
2638 i::Execution::ToString(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002639 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002640 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2641 uint32_t index;
2642 if (str->AsArrayIndex(&index)) {
2643 i::Handle<i::Object> value;
2644 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
2645 value = i::Handle<i::Object>(i::Smi::FromInt(index));
2646 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002647 value = isolate->factory()->NewNumber(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002648 }
2649 return Utils::Uint32ToLocal(value);
2650 }
2651 return Local<Uint32>();
2652}
2653
2654
ager@chromium.org32912102009-01-16 10:38:43 +00002655int32_t Value::Int32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002656 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2657 if (obj->IsSmi()) {
2658 return i::Smi::cast(*obj)->value();
2659 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002660 i::Isolate* isolate = i::Isolate::Current();
2661 if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002662 LOG_API(isolate, "Int32Value (slow)");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002663 ENTER_V8(isolate);
2664 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665 i::Handle<i::Object> num =
2666 i::Execution::ToInt32(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002667 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002668 if (num->IsSmi()) {
2669 return i::Smi::cast(*num)->value();
2670 } else {
2671 return static_cast<int32_t>(num->Number());
2672 }
2673 }
2674}
2675
2676
ager@chromium.org32912102009-01-16 10:38:43 +00002677bool Value::Equals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002678 i::Isolate* isolate = i::Isolate::Current();
2679 if (IsDeadCheck(isolate, "v8::Value::Equals()")
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002680 || EmptyCheck("v8::Value::Equals()", this)
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002681 || EmptyCheck("v8::Value::Equals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002682 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002683 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002684 LOG_API(isolate, "Equals");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002685 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002686 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2687 i::Handle<i::Object> other = Utils::OpenHandle(*that);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002688 // If both obj and other are JSObjects, we'd better compare by identity
2689 // immediately when going into JS builtin. The reason is Invoke
2690 // would overwrite global object receiver with global proxy.
2691 if (obj->IsJSObject() && other->IsJSObject()) {
2692 return *obj == *other;
2693 }
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002694 i::Handle<i::Object> args[] = { other };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002695 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002696 i::Handle<i::Object> result =
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002697 CallV8HeapFunction("EQUALS", obj, ARRAY_SIZE(args), args,
2698 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002699 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002700 return *result == i::Smi::FromInt(i::EQUAL);
2701}
2702
2703
ager@chromium.org32912102009-01-16 10:38:43 +00002704bool Value::StrictEquals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002705 i::Isolate* isolate = i::Isolate::Current();
2706 if (IsDeadCheck(isolate, "v8::Value::StrictEquals()")
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002707 || EmptyCheck("v8::Value::StrictEquals()", this)
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002708 || EmptyCheck("v8::Value::StrictEquals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002709 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002710 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002711 LOG_API(isolate, "StrictEquals");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002712 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2713 i::Handle<i::Object> other = Utils::OpenHandle(*that);
2714 // Must check HeapNumber first, since NaN !== NaN.
2715 if (obj->IsHeapNumber()) {
2716 if (!other->IsNumber()) return false;
2717 double x = obj->Number();
2718 double y = other->Number();
2719 // Must check explicitly for NaN:s on Windows, but -0 works fine.
2720 return x == y && !isnan(x) && !isnan(y);
2721 } else if (*obj == *other) { // Also covers Booleans.
2722 return true;
2723 } else if (obj->IsSmi()) {
2724 return other->IsNumber() && obj->Number() == other->Number();
2725 } else if (obj->IsString()) {
2726 return other->IsString() &&
2727 i::String::cast(*obj)->Equals(i::String::cast(*other));
2728 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
2729 return other->IsUndefined() || other->IsUndetectableObject();
2730 } else {
2731 return false;
2732 }
2733}
2734
2735
ager@chromium.org32912102009-01-16 10:38:43 +00002736uint32_t Value::Uint32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002737 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2738 if (obj->IsSmi()) {
2739 return i::Smi::cast(*obj)->value();
2740 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002741 i::Isolate* isolate = i::Isolate::Current();
2742 if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
2743 LOG_API(isolate, "Uint32Value");
2744 ENTER_V8(isolate);
2745 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002746 i::Handle<i::Object> num =
2747 i::Execution::ToUint32(obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002748 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002749 if (num->IsSmi()) {
2750 return i::Smi::cast(*num)->value();
2751 } else {
2752 return static_cast<uint32_t>(num->Number());
2753 }
2754 }
2755}
2756
2757
2758bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002759 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002760 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002761 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002762 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002763 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002764 i::Handle<i::Object> self = Utils::OpenHandle(this);
2765 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2766 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002767 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002768 i::Handle<i::Object> obj = i::SetProperty(
2769 self,
2770 key_obj,
2771 value_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002772 static_cast<PropertyAttributes>(attribs),
2773 i::kNonStrictMode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002774 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002775 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002776 return true;
2777}
2778
2779
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002780bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002781 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002782 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002783 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002784 i::HandleScope scope(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002785 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2786 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002787 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002788 i::Handle<i::Object> obj = i::JSObject::SetElement(
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002789 self,
2790 index,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00002791 value_obj,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00002792 NONE,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00002793 i::kNonStrictMode);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002794 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002795 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002796 return true;
2797}
2798
2799
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002800bool v8::Object::ForceSet(v8::Handle<Value> key,
2801 v8::Handle<Value> value,
2802 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002803 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002804 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002805 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002806 i::HandleScope scope(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002807 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2808 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2809 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002810 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002811 i::Handle<i::Object> obj = i::ForceSetProperty(
2812 self,
2813 key_obj,
2814 value_obj,
2815 static_cast<PropertyAttributes>(attribs));
2816 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002817 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002818 return true;
2819}
2820
2821
ager@chromium.orge2902be2009-06-08 12:21:35 +00002822bool v8::Object::ForceDelete(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002823 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002824 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002825 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002826 i::HandleScope scope(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00002827 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2828 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002829
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00002830 // When deleting a property on the global object using ForceDelete
2831 // deoptimize all functions as optimized code does not check for the hole
2832 // value with DontDelete properties. We have to deoptimize all contexts
2833 // because of possible cross-context inlined functions.
2834 if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
2835 i::Deoptimizer::DeoptimizeAll();
2836 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002837
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002838 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00002839 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
2840 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002841 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orge2902be2009-06-08 12:21:35 +00002842 return obj->IsTrue();
2843}
2844
2845
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002846Local<Value> v8::Object::Get(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002847 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002848 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002849 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002850 i::Handle<i::Object> self = Utils::OpenHandle(this);
2851 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002852 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002853 i::Handle<i::Object> result = i::GetProperty(self, key_obj);
2854 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002855 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002856 return Utils::ToLocal(result);
2857}
2858
2859
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002860Local<Value> v8::Object::Get(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002861 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002862 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002863 ENTER_V8(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002864 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002865 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002866 i::Handle<i::Object> result = i::Object::GetElement(self, index);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002867 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002868 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002869 return Utils::ToLocal(result);
2870}
2871
2872
rossberg@chromium.org717967f2011-07-20 13:44:42 +00002873PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
2874 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2875 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
2876 return static_cast<PropertyAttribute>(NONE));
2877 ENTER_V8(isolate);
2878 i::HandleScope scope(isolate);
2879 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2880 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
2881 if (!key_obj->IsString()) {
2882 EXCEPTION_PREAMBLE(isolate);
2883 key_obj = i::Execution::ToString(key_obj, &has_pending_exception);
2884 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
2885 }
2886 i::Handle<i::String> key_string = i::Handle<i::String>::cast(key_obj);
2887 PropertyAttributes result = self->GetPropertyAttribute(*key_string);
2888 if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
2889 return static_cast<PropertyAttribute>(result);
2890}
2891
2892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002893Local<Value> v8::Object::GetPrototype() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002894 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2895 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002896 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002897 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002898 i::Handle<i::Object> self = Utils::OpenHandle(this);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002899 i::Handle<i::Object> result(self->GetPrototype());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002900 return Utils::ToLocal(result);
2901}
2902
2903
ager@chromium.org5c838252010-02-19 08:53:10 +00002904bool v8::Object::SetPrototype(Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002905 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002906 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002907 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00002908 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2909 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002910 // We do not allow exceptions thrown while setting the prototype
2911 // to propagate outside.
2912 TryCatch try_catch;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002913 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00002914 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2915 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002916 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org5c838252010-02-19 08:53:10 +00002917 return true;
2918}
2919
2920
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00002921Local<Object> v8::Object::FindInstanceInPrototypeChain(
2922 v8::Handle<FunctionTemplate> tmpl) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002923 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2924 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002925 "v8::Object::FindInstanceInPrototypeChain()",
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00002926 return Local<v8::Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002927 ENTER_V8(isolate);
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00002928 i::JSObject* object = *Utils::OpenHandle(this);
2929 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2930 while (!object->IsInstanceOf(tmpl_info)) {
2931 i::Object* prototype = object->GetPrototype();
2932 if (!prototype->IsJSObject()) return Local<Object>();
2933 object = i::JSObject::cast(prototype);
2934 }
2935 return Utils::ToLocal(i::Handle<i::JSObject>(object));
2936}
2937
2938
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002939Local<Array> v8::Object::GetPropertyNames() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002940 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002941 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
2942 return Local<v8::Array>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002943 ENTER_V8(isolate);
2944 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002945 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002946 bool threw = false;
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00002947 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002948 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS, &threw);
2949 if (threw) return Local<v8::Array>();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002950 // Because we use caching to speed up enumeration it is important
2951 // to never change the result of the basic enumeration function so
2952 // we clone the result.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002953 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2954 i::Handle<i::JSArray> result =
2955 isolate->factory()->NewJSArrayWithElements(elms);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002956 return Utils::ToLocal(scope.CloseAndEscape(result));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002957}
2958
2959
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002960Local<Array> v8::Object::GetOwnPropertyNames() {
2961 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2962 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
2963 return Local<v8::Array>());
2964 ENTER_V8(isolate);
2965 i::HandleScope scope(isolate);
2966 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002967 bool threw = false;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002968 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002969 i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY, &threw);
2970 if (threw) return Local<v8::Array>();
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002971 // Because we use caching to speed up enumeration it is important
2972 // to never change the result of the basic enumeration function so
2973 // we clone the result.
2974 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
2975 i::Handle<i::JSArray> result =
2976 isolate->factory()->NewJSArrayWithElements(elms);
2977 return Utils::ToLocal(scope.CloseAndEscape(result));
2978}
2979
2980
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002981Local<String> v8::Object::ObjectProtoToString() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002982 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2983 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002984 return Local<v8::String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002985 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2987
2988 i::Handle<i::Object> name(self->class_name());
2989
2990 // Native implementation of Object.prototype.toString (v8natives.js):
2991 // var c = %ClassOf(this);
2992 // if (c === 'Arguments') c = 'Object';
2993 // return "[object " + c + "]";
2994
2995 if (!name->IsString()) {
2996 return v8::String::New("[object ]");
2997
2998 } else {
2999 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
3000 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
3001 return v8::String::New("[object Object]");
3002
3003 } else {
3004 const char* prefix = "[object ";
3005 Local<String> str = Utils::ToLocal(class_name);
3006 const char* postfix = "]";
3007
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003008 int prefix_len = i::StrLength(prefix);
3009 int str_len = str->Length();
3010 int postfix_len = i::StrLength(postfix);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003011
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003012 int buf_len = prefix_len + str_len + postfix_len;
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003013 i::ScopedVector<char> buf(buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003014
3015 // Write prefix.
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003016 char* ptr = buf.start();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003017 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
3018 ptr += prefix_len;
3019
3020 // Write real content.
3021 str->WriteAscii(ptr, 0, str_len);
3022 ptr += str_len;
3023
3024 // Write postfix.
3025 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
3026
3027 // Copy the buffer into a heap-allocated string and return it.
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003028 Local<String> result = v8::String::New(buf.start(), buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003029 return result;
3030 }
3031 }
3032}
3033
3034
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00003035Local<Value> v8::Object::GetConstructor() {
3036 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3037 ON_BAILOUT(isolate, "v8::Object::GetConstructor()",
3038 return Local<v8::Function>());
3039 ENTER_V8(isolate);
3040 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3041 i::Handle<i::Object> constructor(self->GetConstructor());
3042 return Utils::ToLocal(constructor);
3043}
3044
3045
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003046Local<String> v8::Object::GetConstructorName() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003047 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003048 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
3049 return Local<v8::String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003050 ENTER_V8(isolate);
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003051 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3052 i::Handle<i::String> name(self->constructor_name());
3053 return Utils::ToLocal(name);
3054}
3055
3056
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003057bool v8::Object::Delete(v8::Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003058 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003059 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003060 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003061 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003062 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3063 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003064 return i::JSObject::DeleteProperty(self, key_obj)->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003065}
3066
3067
3068bool v8::Object::Has(v8::Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003069 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3070 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
3071 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003072 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3073 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3074 return self->HasProperty(*key_obj);
3075}
3076
3077
3078bool v8::Object::Delete(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003079 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3080 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003081 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003082 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003083 HandleScope scope;
3084 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003085 return i::JSObject::DeleteElement(self, index)->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086}
3087
3088
3089bool v8::Object::Has(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003090 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3091 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003092 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3093 return self->HasElement(index);
3094}
3095
3096
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003097bool Object::SetAccessor(Handle<String> name,
3098 AccessorGetter getter,
3099 AccessorSetter setter,
3100 v8::Handle<Value> data,
3101 AccessControl settings,
3102 PropertyAttribute attributes) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003103 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003104 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003105 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003106 i::HandleScope scope(isolate);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003107 v8::Handle<AccessorSignature> signature;
3108 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name, getter, setter, data,
3109 settings, attributes,
3110 signature);
danno@chromium.org88aa0582012-03-23 15:11:57 +00003111 bool fast = Utils::OpenHandle(this)->HasFastProperties();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003112 i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(this), info);
danno@chromium.org88aa0582012-03-23 15:11:57 +00003113 if (result.is_null() || result->IsUndefined()) return false;
3114 if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(this), 0);
3115 return true;
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003116}
3117
3118
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003119bool v8::Object::HasOwnProperty(Handle<String> key) {
3120 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3121 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3122 return false);
3123 return Utils::OpenHandle(this)->HasLocalProperty(
3124 *Utils::OpenHandle(*key));
3125}
3126
3127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003128bool v8::Object::HasRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003129 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3130 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003131 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003132 return Utils::OpenHandle(this)->HasRealNamedProperty(
3133 *Utils::OpenHandle(*key));
3134}
3135
3136
3137bool v8::Object::HasRealIndexedProperty(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003138 ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
3139 "v8::Object::HasRealIndexedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003140 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003141 return Utils::OpenHandle(this)->HasRealElementProperty(index);
3142}
3143
3144
3145bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003146 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3147 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003148 "v8::Object::HasRealNamedCallbackProperty()",
3149 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003150 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003151 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
3152 *Utils::OpenHandle(*key));
3153}
3154
3155
3156bool v8::Object::HasNamedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003157 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3158 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003159 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003160 return Utils::OpenHandle(this)->HasNamedInterceptor();
3161}
3162
3163
3164bool v8::Object::HasIndexedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003165 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3166 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003167 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003168 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3169}
3170
3171
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003172static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
3173 i::Handle<i::JSObject> receiver,
3174 i::Handle<i::String> name,
3175 i::LookupResult* lookup) {
3176 if (!lookup->IsProperty()) {
3177 // No real property was found.
3178 return Local<Value>();
3179 }
3180
3181 // If the property being looked up is a callback, it can throw
3182 // an exception.
3183 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003184 PropertyAttributes ignored;
3185 i::Handle<i::Object> result =
3186 i::Object::GetProperty(receiver, receiver, lookup, name,
3187 &ignored);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003188 has_pending_exception = result.is_null();
3189 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3190
3191 return Utils::ToLocal(result);
3192}
3193
3194
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003195Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003196 Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003197 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3198 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003199 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003200 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003201 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003202 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3203 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003204 i::LookupResult lookup(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003205 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003206 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003207}
3208
3209
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003210Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003211 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3212 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003213 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003214 ENTER_V8(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003215 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3216 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003217 i::LookupResult lookup(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003218 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003219 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003220}
3221
3222
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003223// Turns on access checks by copying the map and setting the check flag.
3224// Because the object gets a new map, existing inline cache caching
3225// the old map of this object will fail.
3226void v8::Object::TurnOnAccessCheck() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003227 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003228 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003229 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003230 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003231 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3232
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003233 // When turning on access checks for a global object deoptimize all functions
3234 // as optimized code does not always handle access checks.
3235 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3236
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003237 i::Handle<i::Map> new_map =
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003238 isolate->factory()->CopyMap(i::Handle<i::Map>(obj->map()));
ager@chromium.org870a0b62008-11-04 11:43:05 +00003239 new_map->set_is_access_check_needed(true);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003240 obj->set_map(*new_map);
3241}
3242
3243
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00003244bool v8::Object::IsDirty() {
3245 return Utils::OpenHandle(this)->IsDirty();
3246}
3247
3248
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003249Local<v8::Object> v8::Object::Clone() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003250 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003251 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003252 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003253 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003254 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003255 i::Handle<i::JSObject> result = i::Copy(self);
3256 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003257 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003258 return Utils::ToLocal(result);
3259}
3260
3261
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003262static i::Context* GetCreationContext(i::JSObject* object) {
3263 i::Object* constructor = object->map()->constructor();
3264 i::JSFunction* function;
3265 if (!constructor->IsJSFunction()) {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003266 // Functions have null as a constructor,
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003267 // but any JSFunction knows its context immediately.
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003268 ASSERT(object->IsJSFunction());
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003269 function = i::JSFunction::cast(object);
3270 } else {
3271 function = i::JSFunction::cast(constructor);
3272 }
3273 return function->context()->global_context();
3274}
3275
3276
3277Local<v8::Context> v8::Object::CreationContext() {
3278 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3279 ON_BAILOUT(isolate,
3280 "v8::Object::CreationContext()", return Local<v8::Context>());
3281 ENTER_V8(isolate);
3282 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3283 i::Context* context = GetCreationContext(*self);
3284 return Utils::ToLocal(i::Handle<i::Context>(context));
3285}
3286
3287
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003288int v8::Object::GetIdentityHash() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003289 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003290 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003291 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003292 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003293 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003294 return i::JSObject::GetIdentityHash(self);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003295}
3296
3297
3298bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3299 v8::Handle<v8::Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003300 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003301 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003302 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003303 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003304 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003305 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003306 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003307 i::Handle<i::Object> result =
3308 i::JSObject::SetHiddenProperty(self, key_obj, value_obj);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003309 return *result == *self;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003310}
3311
3312
3313v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003314 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003315 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3316 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003317 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003318 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003319 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003320 i::Handle<i::Object> result(self->GetHiddenProperty(*key_obj));
3321 if (result->IsUndefined()) return v8::Local<v8::Value>();
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003322 return Utils::ToLocal(result);
3323}
3324
3325
3326bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003327 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003328 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003329 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003330 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003331 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003332 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003333 self->DeleteHiddenProperty(*key_obj);
3334 return true;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003335}
3336
3337
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003338namespace {
3339
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003340static i::ElementsKind GetElementsKindFromExternalArrayType(
3341 ExternalArrayType array_type) {
3342 switch (array_type) {
3343 case kExternalByteArray:
3344 return i::EXTERNAL_BYTE_ELEMENTS;
3345 break;
3346 case kExternalUnsignedByteArray:
3347 return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3348 break;
3349 case kExternalShortArray:
3350 return i::EXTERNAL_SHORT_ELEMENTS;
3351 break;
3352 case kExternalUnsignedShortArray:
3353 return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3354 break;
3355 case kExternalIntArray:
3356 return i::EXTERNAL_INT_ELEMENTS;
3357 break;
3358 case kExternalUnsignedIntArray:
3359 return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
3360 break;
3361 case kExternalFloatArray:
3362 return i::EXTERNAL_FLOAT_ELEMENTS;
3363 break;
3364 case kExternalDoubleArray:
3365 return i::EXTERNAL_DOUBLE_ELEMENTS;
3366 break;
3367 case kExternalPixelArray:
3368 return i::EXTERNAL_PIXEL_ELEMENTS;
3369 break;
3370 }
3371 UNREACHABLE();
3372 return i::DICTIONARY_ELEMENTS;
3373}
3374
3375
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003376void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3377 void* data,
3378 ExternalArrayType array_type,
3379 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003380 i::Isolate* isolate = object->GetIsolate();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003381 i::Handle<i::ExternalArray> array =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003382 isolate->factory()->NewExternalArray(length, array_type, data);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003383
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003384 i::Handle<i::Map> external_array_map =
3385 isolate->factory()->GetElementsTransitionMap(
3386 object,
3387 GetElementsKindFromExternalArrayType(array_type));
3388
3389 object->set_map(*external_array_map);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003390 object->set_elements(*array);
3391}
3392
3393} // namespace
3394
3395
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003396void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003397 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003398 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003399 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003400 i::HandleScope scope(isolate);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003401 if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003402 "v8::Object::SetIndexedPropertiesToPixelData()",
3403 "length exceeds max acceptable value")) {
3404 return;
3405 }
3406 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3407 if (!ApiCheck(!self->IsJSArray(),
3408 "v8::Object::SetIndexedPropertiesToPixelData()",
3409 "JSArray is not supported")) {
3410 return;
3411 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003412 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003413}
3414
3415
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003416bool v8::Object::HasIndexedPropertiesInPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003417 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003418 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3419 return false);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003420 return self->HasExternalPixelElements();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003421}
3422
3423
3424uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003425 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003426 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3427 return NULL);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003428 if (self->HasExternalPixelElements()) {
3429 return i::ExternalPixelArray::cast(self->elements())->
3430 external_pixel_pointer();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003431 } else {
3432 return NULL;
3433 }
3434}
3435
3436
3437int v8::Object::GetIndexedPropertiesPixelDataLength() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003438 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003439 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3440 return -1);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003441 if (self->HasExternalPixelElements()) {
3442 return i::ExternalPixelArray::cast(self->elements())->length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003443 } else {
3444 return -1;
3445 }
3446}
3447
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003448
ager@chromium.org3811b432009-10-28 14:53:37 +00003449void v8::Object::SetIndexedPropertiesToExternalArrayData(
3450 void* data,
3451 ExternalArrayType array_type,
3452 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003453 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003454 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003455 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003456 i::HandleScope scope(isolate);
ager@chromium.org3811b432009-10-28 14:53:37 +00003457 if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
3458 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3459 "length exceeds max acceptable value")) {
3460 return;
3461 }
3462 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3463 if (!ApiCheck(!self->IsJSArray(),
3464 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3465 "JSArray is not supported")) {
3466 return;
3467 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003468 PrepareExternalArrayElements(self, data, array_type, length);
ager@chromium.org3811b432009-10-28 14:53:37 +00003469}
3470
3471
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003472bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003473 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3474 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003475 "v8::HasIndexedPropertiesInExternalArrayData()",
3476 return false);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003477 return self->HasExternalArrayElements();
3478}
3479
3480
3481void* v8::Object::GetIndexedPropertiesExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003482 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3483 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003484 "v8::GetIndexedPropertiesExternalArrayData()",
3485 return NULL);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003486 if (self->HasExternalArrayElements()) {
3487 return i::ExternalArray::cast(self->elements())->external_pointer();
3488 } else {
3489 return NULL;
3490 }
3491}
3492
3493
3494ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003495 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3496 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003497 "v8::GetIndexedPropertiesExternalArrayDataType()",
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003498 return static_cast<ExternalArrayType>(-1));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003499 switch (self->elements()->map()->instance_type()) {
3500 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3501 return kExternalByteArray;
3502 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3503 return kExternalUnsignedByteArray;
3504 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3505 return kExternalShortArray;
3506 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3507 return kExternalUnsignedShortArray;
3508 case i::EXTERNAL_INT_ARRAY_TYPE:
3509 return kExternalIntArray;
3510 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3511 return kExternalUnsignedIntArray;
3512 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3513 return kExternalFloatArray;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003514 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3515 return kExternalDoubleArray;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003516 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3517 return kExternalPixelArray;
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003518 default:
3519 return static_cast<ExternalArrayType>(-1);
3520 }
3521}
3522
3523
3524int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003525 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3526 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003527 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3528 return 0);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003529 if (self->HasExternalArrayElements()) {
3530 return i::ExternalArray::cast(self->elements())->length();
3531 } else {
3532 return -1;
3533 }
3534}
3535
3536
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003537bool v8::Object::IsCallable() {
3538 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3539 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3540 ENTER_V8(isolate);
3541 i::HandleScope scope(isolate);
3542 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3543 if (obj->IsJSFunction()) return true;
3544 return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
3545}
3546
3547
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003548Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv,
3549 int argc,
lrn@chromium.org1c092762011-05-09 09:42:16 +00003550 v8::Handle<v8::Value> argv[]) {
3551 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3552 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3553 return Local<v8::Value>());
3554 LOG_API(isolate, "Object::CallAsFunction");
3555 ENTER_V8(isolate);
3556 i::HandleScope scope(isolate);
3557 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3558 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3559 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003560 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003561 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3562 if (obj->IsJSFunction()) {
3563 fun = i::Handle<i::JSFunction>::cast(obj);
3564 } else {
3565 EXCEPTION_PREAMBLE(isolate);
3566 i::Handle<i::Object> delegate =
3567 i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
3568 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3569 fun = i::Handle<i::JSFunction>::cast(delegate);
3570 recv_obj = obj;
3571 }
3572 EXCEPTION_PREAMBLE(isolate);
3573 i::Handle<i::Object> returned =
3574 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003575 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003576 return Utils::ToLocal(scope.CloseAndEscape(returned));
3577}
3578
3579
3580Local<v8::Value> Object::CallAsConstructor(int argc,
3581 v8::Handle<v8::Value> argv[]) {
3582 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3583 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3584 return Local<v8::Object>());
3585 LOG_API(isolate, "Object::CallAsConstructor");
3586 ENTER_V8(isolate);
3587 i::HandleScope scope(isolate);
3588 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3589 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003590 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003591 if (obj->IsJSFunction()) {
3592 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
3593 EXCEPTION_PREAMBLE(isolate);
3594 i::Handle<i::Object> returned =
3595 i::Execution::New(fun, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003596 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003597 return Utils::ToLocal(scope.CloseAndEscape(
3598 i::Handle<i::JSObject>::cast(returned)));
3599 }
3600 EXCEPTION_PREAMBLE(isolate);
3601 i::Handle<i::Object> delegate =
3602 i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
3603 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3604 if (!delegate->IsUndefined()) {
3605 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
3606 EXCEPTION_PREAMBLE(isolate);
3607 i::Handle<i::Object> returned =
3608 i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003609 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003610 ASSERT(!delegate->IsUndefined());
3611 return Utils::ToLocal(scope.CloseAndEscape(returned));
3612 }
3613 return Local<v8::Object>();
3614}
3615
3616
ager@chromium.org32912102009-01-16 10:38:43 +00003617Local<v8::Object> Function::NewInstance() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003618 return NewInstance(0, NULL);
3619}
3620
3621
3622Local<v8::Object> Function::NewInstance(int argc,
ager@chromium.org32912102009-01-16 10:38:43 +00003623 v8::Handle<v8::Value> argv[]) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003624 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003625 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
3626 return Local<v8::Object>());
3627 LOG_API(isolate, "Function::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003628 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003629 HandleScope scope;
3630 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
3631 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003632 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003633 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003634 i::Handle<i::Object> returned =
3635 i::Execution::New(function, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003636 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003637 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3638}
3639
3640
3641Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3642 v8::Handle<v8::Value> argv[]) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003643 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003644 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
3645 LOG_API(isolate, "Function::Call");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003646 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003647 i::Object* raw_result = NULL;
3648 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003649 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003650 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
3651 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3652 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003653 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003654 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003655 i::Handle<i::Object> returned =
3656 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003657 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003658 raw_result = *returned;
3659 }
3660 i::Handle<i::Object> result(raw_result);
3661 return Utils::ToLocal(result);
3662}
3663
3664
3665void Function::SetName(v8::Handle<v8::String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003666 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3667 ENTER_V8(isolate);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003668 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003669 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3670 func->shared()->set_name(*Utils::OpenHandle(*name));
3671}
3672
3673
ager@chromium.org32912102009-01-16 10:38:43 +00003674Handle<Value> Function::GetName() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003675 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3676 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
3677}
3678
3679
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00003680Handle<Value> Function::GetInferredName() const {
3681 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3682 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name()));
3683}
3684
3685
ager@chromium.org5c838252010-02-19 08:53:10 +00003686ScriptOrigin Function::GetScriptOrigin() const {
3687 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3688 if (func->shared()->script()->IsScript()) {
3689 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3690 v8::ScriptOrigin origin(
3691 Utils::ToLocal(i::Handle<i::Object>(script->name())),
3692 v8::Integer::New(script->line_offset()->value()),
3693 v8::Integer::New(script->column_offset()->value()));
3694 return origin;
3695 }
3696 return v8::ScriptOrigin(Handle<Value>());
3697}
3698
3699
3700const int Function::kLineOffsetNotFound = -1;
3701
3702
3703int Function::GetScriptLineNumber() const {
3704 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3705 if (func->shared()->script()->IsScript()) {
3706 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3707 return i::GetScriptLineNumber(script, func->shared()->start_position());
3708 }
3709 return kLineOffsetNotFound;
3710}
3711
3712
danno@chromium.orgc612e022011-11-10 11:38:15 +00003713int Function::GetScriptColumnNumber() const {
3714 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3715 if (func->shared()->script()->IsScript()) {
3716 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3717 return i::GetScriptColumnNumber(script, func->shared()->start_position());
3718 }
3719 return kLineOffsetNotFound;
3720}
3721
3722Handle<Value> Function::GetScriptId() const {
3723 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
3724 if (!func->shared()->script()->IsScript())
3725 return v8::Undefined();
3726 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
3727 return Utils::ToLocal(i::Handle<i::Object>(script->id()));
3728}
3729
ager@chromium.org32912102009-01-16 10:38:43 +00003730int String::Length() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003731 i::Handle<i::String> str = Utils::OpenHandle(this);
3732 if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
3733 return str->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003734}
3735
3736
ager@chromium.org32912102009-01-16 10:38:43 +00003737int String::Utf8Length() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003738 i::Handle<i::String> str = Utils::OpenHandle(this);
3739 if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003740 return i::Utf8Length(str);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003741}
3742
3743
danno@chromium.org88aa0582012-03-23 15:11:57 +00003744// Will fail with a negative answer if the recursion depth is too high.
3745static int RecursivelySerializeToUtf8(i::String* string,
3746 char* buffer,
3747 int start,
3748 int end,
3749 int recursion_budget,
3750 int32_t previous_character,
3751 int32_t* last_character) {
3752 int utf8_bytes = 0;
3753 while (true) {
3754 if (string->IsAsciiRepresentation()) {
3755 i::String::WriteToFlat(string, buffer, start, end);
3756 *last_character = unibrow::Utf16::kNoPreviousCharacter;
3757 return utf8_bytes + end - start;
3758 }
3759 switch (i::StringShape(string).representation_tag()) {
3760 case i::kExternalStringTag: {
3761 const uint16_t* data = i::ExternalTwoByteString::cast(string)->
3762 ExternalTwoByteStringGetData(0);
3763 char* current = buffer;
3764 for (int i = start; i < end; i++) {
3765 uint16_t character = data[i];
3766 current +=
3767 unibrow::Utf8::Encode(current, character, previous_character);
3768 previous_character = character;
3769 }
3770 *last_character = previous_character;
3771 return static_cast<int>(utf8_bytes + current - buffer);
3772 }
3773 case i::kSeqStringTag: {
3774 const uint16_t* data =
3775 i::SeqTwoByteString::cast(string)->SeqTwoByteStringGetData(0);
3776 char* current = buffer;
3777 for (int i = start; i < end; i++) {
3778 uint16_t character = data[i];
3779 current +=
3780 unibrow::Utf8::Encode(current, character, previous_character);
3781 previous_character = character;
3782 }
3783 *last_character = previous_character;
3784 return static_cast<int>(utf8_bytes + current - buffer);
3785 }
3786 case i::kSlicedStringTag: {
3787 i::SlicedString* slice = i::SlicedString::cast(string);
3788 unsigned offset = slice->offset();
3789 string = slice->parent();
3790 start += offset;
3791 end += offset;
3792 continue;
3793 }
3794 case i::kConsStringTag: {
3795 i::ConsString* cons_string = i::ConsString::cast(string);
3796 i::String* first = cons_string->first();
3797 int boundary = first->length();
3798 if (start >= boundary) {
3799 // Only need RHS.
3800 string = cons_string->second();
3801 start -= boundary;
3802 end -= boundary;
3803 continue;
3804 } else if (end <= boundary) {
3805 // Only need LHS.
3806 string = first;
3807 } else {
3808 if (recursion_budget == 0) return -1;
3809 int extra_utf8_bytes =
3810 RecursivelySerializeToUtf8(first,
3811 buffer,
3812 start,
3813 boundary,
3814 recursion_budget - 1,
3815 previous_character,
3816 &previous_character);
3817 if (extra_utf8_bytes < 0) return extra_utf8_bytes;
3818 buffer += extra_utf8_bytes;
3819 utf8_bytes += extra_utf8_bytes;
3820 string = cons_string->second();
3821 start = 0;
3822 end -= boundary;
3823 }
3824 }
3825 }
3826 }
3827 UNREACHABLE();
3828 return 0;
3829}
3830
3831
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003832bool String::MayContainNonAscii() const {
3833 i::Handle<i::String> str = Utils::OpenHandle(this);
3834 if (IsDeadCheck(str->GetIsolate(), "v8::String::MayContainNonAscii()")) {
3835 return false;
3836 }
3837 return !str->HasOnlyAsciiChars();
3838}
3839
3840
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00003841int String::WriteUtf8(char* buffer,
3842 int capacity,
3843 int* nchars_ref,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003844 int options) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003845 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003846 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3847 LOG_API(isolate, "String::WriteUtf8");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003848 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003849 i::Handle<i::String> str = Utils::OpenHandle(this);
danno@chromium.org88aa0582012-03-23 15:11:57 +00003850 int string_length = str->length();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003851 if (str->IsAsciiRepresentation()) {
3852 int len;
3853 if (capacity == -1) {
3854 capacity = str->length() + 1;
danno@chromium.org88aa0582012-03-23 15:11:57 +00003855 len = string_length;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003856 } else {
3857 len = i::Min(capacity, str->length());
3858 }
3859 i::String::WriteToFlat(*str, buffer, 0, len);
3860 if (nchars_ref != NULL) *nchars_ref = len;
3861 if (!(options & NO_NULL_TERMINATION) && capacity > len) {
3862 buffer[len] = '\0';
3863 return len + 1;
3864 }
3865 return len;
3866 }
3867
danno@chromium.org88aa0582012-03-23 15:11:57 +00003868 if (capacity == -1 || capacity / 3 >= string_length) {
3869 int32_t previous = unibrow::Utf16::kNoPreviousCharacter;
3870 const int kMaxRecursion = 100;
3871 int utf8_bytes =
3872 RecursivelySerializeToUtf8(*str,
3873 buffer,
3874 0,
3875 string_length,
3876 kMaxRecursion,
3877 previous,
3878 &previous);
3879 if (utf8_bytes >= 0) {
3880 // Success serializing with recursion.
3881 if ((options & NO_NULL_TERMINATION) == 0 &&
3882 (capacity > utf8_bytes || capacity == -1)) {
3883 buffer[utf8_bytes++] = '\0';
3884 }
3885 if (nchars_ref != NULL) *nchars_ref = string_length;
3886 return utf8_bytes;
3887 }
3888 FlattenString(str);
3889 // Recurse once. This time around the string is flat and the serializing
3890 // with recursion will certainly succeed.
3891 return WriteUtf8(buffer, capacity, nchars_ref, options);
3892 } else if (capacity >= string_length) {
3893 // First check that the buffer is large enough. If it is, then recurse
3894 // once without a capacity limit, which will get into the other branch of
3895 // this 'if'.
3896 int utf8_bytes = i::Utf8Length(str);
3897 if ((options & NO_NULL_TERMINATION) == 0) utf8_bytes++;
3898 if (utf8_bytes <= capacity) {
3899 return WriteUtf8(buffer, -1, nchars_ref, options);
3900 }
3901 }
3902
3903 // Slow case.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003904 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003905 isolate->string_tracker()->RecordWrite(str);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003906 if (options & HINT_MANY_WRITES_EXPECTED) {
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00003907 // Flatten the string for efficiency. This applies whether we are
3908 // using StringInputBuffer or Get(i) to access the characters.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003909 FlattenString(str);
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00003910 }
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003911 write_input_buffer.Reset(0, *str);
3912 int len = str->length();
3913 // Encode the first K - 3 bytes directly into the buffer since we
3914 // know there's room for them. If no capacity is given we copy all
3915 // of them here.
3916 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3917 int i;
3918 int pos = 0;
ager@chromium.org357bf652010-04-12 11:30:10 +00003919 int nchars = 0;
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003920 int previous = unibrow::Utf16::kNoPreviousCharacter;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003921 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3922 i::uc32 c = write_input_buffer.GetNext();
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003923 int written = unibrow::Utf8::Encode(buffer + pos, c, previous);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003924 pos += written;
ager@chromium.org357bf652010-04-12 11:30:10 +00003925 nchars++;
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003926 previous = c;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003927 }
3928 if (i < len) {
3929 // For the last characters we need to check the length for each one
3930 // because they may be longer than the remaining space in the
3931 // buffer.
3932 char intermediate[unibrow::Utf8::kMaxEncodedSize];
3933 for (; i < len && pos < capacity; i++) {
3934 i::uc32 c = write_input_buffer.GetNext();
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003935 if (unibrow::Utf16::IsTrailSurrogate(c) &&
3936 unibrow::Utf16::IsLeadSurrogate(previous)) {
3937 // We can't use the intermediate buffer here because the encoding
3938 // of surrogate pairs is done under assumption that you can step
3939 // back and fix the UTF8 stream. Luckily we only need space for one
3940 // more byte, so there is always space.
3941 ASSERT(pos < capacity);
3942 int written = unibrow::Utf8::Encode(buffer + pos, c, previous);
3943 ASSERT(written == 1);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003944 pos += written;
ager@chromium.org357bf652010-04-12 11:30:10 +00003945 nchars++;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003946 } else {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003947 int written =
3948 unibrow::Utf8::Encode(intermediate,
3949 c,
3950 unibrow::Utf16::kNoPreviousCharacter);
3951 if (pos + written <= capacity) {
3952 for (int j = 0; j < written; j++)
3953 buffer[pos + j] = intermediate[j];
3954 pos += written;
3955 nchars++;
3956 } else {
3957 // We've reached the end of the buffer
3958 break;
3959 }
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003960 }
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003961 previous = c;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003962 }
3963 }
ager@chromium.org357bf652010-04-12 11:30:10 +00003964 if (nchars_ref != NULL) *nchars_ref = nchars;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003965 if (!(options & NO_NULL_TERMINATION) &&
3966 (i == len && (capacity == -1 || pos < capacity)))
ager@chromium.org9258b6b2008-09-11 09:11:10 +00003967 buffer[pos++] = '\0';
3968 return pos;
3969}
3970
3971
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00003972int String::WriteAscii(char* buffer,
3973 int start,
3974 int length,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003975 int options) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003976 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003977 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3978 LOG_API(isolate, "String::WriteAscii");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003979 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003980 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003981 ASSERT(start >= 0 && length >= -1);
3982 i::Handle<i::String> str = Utils::OpenHandle(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003983 isolate->string_tracker()->RecordWrite(str);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003984 if (options & HINT_MANY_WRITES_EXPECTED) {
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00003985 // Flatten the string for efficiency. This applies whether we are
3986 // using StringInputBuffer or Get(i) to access the characters.
3987 str->TryFlatten();
3988 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003989 int end = length;
3990 if ( (length == -1) || (length > str->length() - start) )
3991 end = str->length() - start;
3992 if (end < 0) return 0;
3993 write_input_buffer.Reset(start, *str);
3994 int i;
3995 for (i = 0; i < end; i++) {
3996 char c = static_cast<char>(write_input_buffer.GetNext());
3997 if (c == '\0') c = ' ';
3998 buffer[i] = c;
3999 }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004000 if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004001 buffer[i] = '\0';
4002 return i;
4003}
4004
4005
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00004006int String::Write(uint16_t* buffer,
4007 int start,
4008 int length,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004009 int options) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004010 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004011 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
4012 LOG_API(isolate, "String::Write");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004013 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004014 ASSERT(start >= 0 && length >= -1);
4015 i::Handle<i::String> str = Utils::OpenHandle(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004016 isolate->string_tracker()->RecordWrite(str);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004017 if (options & HINT_MANY_WRITES_EXPECTED) {
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00004018 // Flatten the string for efficiency. This applies whether we are
4019 // using StringInputBuffer or Get(i) to access the characters.
4020 str->TryFlatten();
4021 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004022 int end = start + length;
4023 if ((length == -1) || (length > str->length() - start) )
4024 end = str->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025 if (end < 0) return 0;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00004026 i::String::WriteToFlat(*str, buffer, start, end);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004027 if (!(options & NO_NULL_TERMINATION) &&
4028 (length == -1 || end - start < length)) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004029 buffer[end - start] = '\0';
4030 }
4031 return end - start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004032}
4033
4034
ager@chromium.org32912102009-01-16 10:38:43 +00004035bool v8::String::IsExternal() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004036 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004037 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
4038 return false;
4039 }
4040 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004041 return i::StringShape(*str).IsExternalTwoByte();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004042}
4043
4044
ager@chromium.org32912102009-01-16 10:38:43 +00004045bool v8::String::IsExternalAscii() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004046 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004047 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
4048 return false;
4049 }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004050 return i::StringShape(*str).IsExternalAscii();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004051}
4052
4053
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004054void v8::String::VerifyExternalStringResource(
4055 v8::String::ExternalStringResource* value) const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004056 i::Handle<i::String> str = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004057 const v8::String::ExternalStringResource* expected;
ager@chromium.org9085a012009-05-11 19:22:57 +00004058 if (i::StringShape(*str).IsExternalTwoByte()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004059 const void* resource =
4060 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4061 expected = reinterpret_cast<const ExternalStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004062 } else {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004063 expected = NULL;
ager@chromium.org9085a012009-05-11 19:22:57 +00004064 }
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004065 CHECK_EQ(expected, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004066}
4067
4068
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004069const v8::String::ExternalAsciiStringResource*
ager@chromium.org32912102009-01-16 10:38:43 +00004070 v8::String::GetExternalAsciiStringResource() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004071 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004072 if (IsDeadCheck(str->GetIsolate(),
4073 "v8::String::GetExternalAsciiStringResource()")) {
4074 return NULL;
4075 }
ager@chromium.org9085a012009-05-11 19:22:57 +00004076 if (i::StringShape(*str).IsExternalAscii()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004077 const void* resource =
4078 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
4079 return reinterpret_cast<const ExternalAsciiStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004080 } else {
4081 return NULL;
4082 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004083}
4084
4085
ager@chromium.org32912102009-01-16 10:38:43 +00004086double Number::Value() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004087 if (IsDeadCheck(i::Isolate::Current(), "v8::Number::Value()")) return 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004088 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4089 return obj->Number();
4090}
4091
4092
ager@chromium.org32912102009-01-16 10:38:43 +00004093bool Boolean::Value() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004094 if (IsDeadCheck(i::Isolate::Current(), "v8::Boolean::Value()")) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004095 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4096 return obj->IsTrue();
4097}
4098
4099
ager@chromium.org32912102009-01-16 10:38:43 +00004100int64_t Integer::Value() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004101 if (IsDeadCheck(i::Isolate::Current(), "v8::Integer::Value()")) return 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004102 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4103 if (obj->IsSmi()) {
4104 return i::Smi::cast(*obj)->value();
4105 } else {
4106 return static_cast<int64_t>(obj->Number());
4107 }
4108}
4109
4110
ager@chromium.org32912102009-01-16 10:38:43 +00004111int32_t Int32::Value() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004112 if (IsDeadCheck(i::Isolate::Current(), "v8::Int32::Value()")) return 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004113 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4114 if (obj->IsSmi()) {
4115 return i::Smi::cast(*obj)->value();
4116 } else {
4117 return static_cast<int32_t>(obj->Number());
4118 }
4119}
4120
4121
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004122uint32_t Uint32::Value() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004123 if (IsDeadCheck(i::Isolate::Current(), "v8::Uint32::Value()")) return 0;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004124 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4125 if (obj->IsSmi()) {
4126 return i::Smi::cast(*obj)->value();
4127 } else {
4128 return static_cast<uint32_t>(obj->Number());
4129 }
4130}
4131
4132
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004133int v8::Object::InternalFieldCount() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004134 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4135 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004136 return 0;
4137 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004138 return obj->GetInternalFieldCount();
4139}
4140
4141
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004142Local<Value> v8::Object::CheckedGetInternalField(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004143 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4144 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004145 return Local<Value>();
4146 }
kasper.lundbd3ec4e2008-07-09 11:06:54 +00004147 if (!ApiCheck(index < obj->GetInternalFieldCount(),
kasper.lund212ac232008-07-16 07:07:30 +00004148 "v8::Object::GetInternalField()",
kasper.lundbd3ec4e2008-07-09 11:06:54 +00004149 "Reading internal field out of bounds")) {
4150 return Local<Value>();
4151 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004152 i::Handle<i::Object> value(obj->GetInternalField(index));
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004153 Local<Value> result = Utils::ToLocal(value);
4154#ifdef DEBUG
4155 Local<Value> unchecked = UncheckedGetInternalField(index);
4156 ASSERT(unchecked.IsEmpty() || (unchecked == result));
4157#endif
4158 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004159}
4160
4161
kasper.lund212ac232008-07-16 07:07:30 +00004162void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004163 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4164 i::Isolate* isolate = obj->GetIsolate();
4165 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004166 return;
4167 }
kasper.lundbd3ec4e2008-07-09 11:06:54 +00004168 if (!ApiCheck(index < obj->GetInternalFieldCount(),
kasper.lund212ac232008-07-16 07:07:30 +00004169 "v8::Object::SetInternalField()",
kasper.lundbd3ec4e2008-07-09 11:06:54 +00004170 "Writing internal field out of bounds")) {
4171 return;
4172 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004173 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004174 i::Handle<i::Object> val = Utils::OpenHandle(*value);
4175 obj->SetInternalField(index, *val);
4176}
4177
4178
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004179static bool CanBeEncodedAsSmi(void* ptr) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004180 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004181 return ((address & i::kEncodablePointerMask) == 0);
4182}
4183
4184
4185static i::Smi* EncodeAsSmi(void* ptr) {
4186 ASSERT(CanBeEncodedAsSmi(ptr));
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004187 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004188 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
4189 ASSERT(i::Internals::HasSmiTag(result));
4190 ASSERT_EQ(result, i::Smi::FromInt(result->value()));
4191 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
4192 return result;
4193}
4194
4195
kasperl@chromium.orge959c182009-07-27 08:59:04 +00004196void v8::Object::SetPointerInInternalField(int index, void* value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004197 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4198 ENTER_V8(isolate);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004199 if (CanBeEncodedAsSmi(value)) {
4200 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
4201 } else {
4202 HandleScope scope;
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004203 i::Handle<i::Foreign> foreign =
4204 isolate->factory()->NewForeign(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004205 reinterpret_cast<i::Address>(value), i::TENURED);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004206 if (!foreign.is_null())
4207 Utils::OpenHandle(this)->SetInternalField(index, *foreign);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004208 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004209 ASSERT_EQ(value, GetPointerFromInternalField(index));
kasperl@chromium.orge959c182009-07-27 08:59:04 +00004210}
4211
4212
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004213// --- E n v i r o n m e n t ---
4214
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004216bool v8::V8::Initialize() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00004217 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004218 if (isolate != NULL && isolate->IsInitialized()) {
4219 return true;
4220 }
4221 return InitializeHelper();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004222}
4223
4224
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00004225void v8::V8::SetEntropySource(EntropySource source) {
4226 i::V8::SetEntropySource(source);
4227}
4228
4229
ulan@chromium.org967e2702012-02-28 09:49:15 +00004230void v8::V8::SetReturnAddressLocationResolver(
4231 ReturnAddressLocationResolver return_address_resolver) {
4232 i::V8::SetReturnAddressLocationResolver(return_address_resolver);
4233}
4234
4235
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004236bool v8::V8::SetFunctionEntryHook(FunctionEntryHook entry_hook) {
4237 return i::ProfileEntryHookStub::SetFunctionEntryHook(entry_hook);
4238}
4239
4240
ager@chromium.org41826e72009-03-30 13:30:57 +00004241bool v8::V8::Dispose() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004242 i::Isolate* isolate = i::Isolate::Current();
4243 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
4244 "v8::V8::Dispose()",
4245 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
4246 return false;
4247 }
ager@chromium.org41826e72009-03-30 13:30:57 +00004248 i::V8::TearDown();
4249 return true;
4250}
4251
4252
ager@chromium.org01fe7df2010-11-10 11:59:11 +00004253HeapStatistics::HeapStatistics(): total_heap_size_(0),
4254 total_heap_size_executable_(0),
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004255 used_heap_size_(0),
4256 heap_size_limit_(0) { }
ager@chromium.org3811b432009-10-28 14:53:37 +00004257
4258
4259void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004260 if (!i::Isolate::Current()->IsInitialized()) {
4261 // Isolate is unitialized thus heap is not configured yet.
4262 heap_statistics->set_total_heap_size(0);
4263 heap_statistics->set_total_heap_size_executable(0);
4264 heap_statistics->set_used_heap_size(0);
4265 heap_statistics->set_heap_size_limit(0);
4266 return;
4267 }
4268
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004269 i::Heap* heap = i::Isolate::Current()->heap();
4270 heap_statistics->set_total_heap_size(heap->CommittedMemory());
ager@chromium.org01fe7df2010-11-10 11:59:11 +00004271 heap_statistics->set_total_heap_size_executable(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004272 heap->CommittedMemoryExecutable());
4273 heap_statistics->set_used_heap_size(heap->SizeOfObjects());
4274 heap_statistics->set_heap_size_limit(heap->MaxReserved());
ager@chromium.org3811b432009-10-28 14:53:37 +00004275}
4276
4277
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004278void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
4279 i::Isolate* isolate = i::Isolate::Current();
4280 IsDeadCheck(isolate, "v8::V8::VisitExternalResources");
4281 isolate->heap()->VisitExternalResources(visitor);
4282}
4283
4284
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00004285bool v8::V8::IdleNotification(int hint) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00004286 // Returning true tells the caller that it need not
4287 // continue to call IdleNotification.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004288 i::Isolate* isolate = i::Isolate::Current();
4289 if (isolate == NULL || !isolate->IsInitialized()) return true;
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00004290 return i::V8::IdleNotification(hint);
ager@chromium.orgadd848f2009-08-13 12:44:13 +00004291}
4292
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00004293
4294void v8::V8::LowMemoryNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004295 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004296 if (isolate == NULL || !isolate->IsInitialized()) return;
rossberg@chromium.org994edf62012-02-06 10:12:55 +00004297 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00004298}
4299
4300
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004301int v8::V8::ContextDisposedNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004302 i::Isolate* isolate = i::Isolate::Current();
4303 if (!isolate->IsInitialized()) return 0;
4304 return isolate->heap()->NotifyContextDisposed();
kasperl@chromium.org8b2bb262010-03-01 09:46:28 +00004305}
4306
4307
kasper.lund7276f142008-07-30 08:49:36 +00004308const char* v8::V8::GetVersion() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004309 return i::Version::GetVersion();
kasper.lund7276f142008-07-30 08:49:36 +00004310}
4311
4312
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004313static i::Handle<i::FunctionTemplateInfo>
4314 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
4315 if (templ->constructor()->IsUndefined()) {
4316 Local<FunctionTemplate> constructor = FunctionTemplate::New();
4317 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
4318 templ->set_constructor(*Utils::OpenHandle(*constructor));
4319 }
4320 return i::Handle<i::FunctionTemplateInfo>(
4321 i::FunctionTemplateInfo::cast(templ->constructor()));
4322}
4323
4324
4325Persistent<Context> v8::Context::New(
4326 v8::ExtensionConfiguration* extensions,
4327 v8::Handle<ObjectTemplate> global_template,
4328 v8::Handle<Value> global_object) {
danno@chromium.org4f821d92012-04-05 11:02:02 +00004329 i::Isolate::EnsureDefaultIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004330 i::Isolate* isolate = i::Isolate::Current();
4331 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
4332 LOG_API(isolate, "Context::New");
4333 ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004334
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004335 // Enter V8 via an ENTER_V8 scope.
4336 i::Handle<i::Context> env;
4337 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004338 ENTER_V8(isolate);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004339 v8::Handle<ObjectTemplate> proxy_template = global_template;
4340 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
4341 i::Handle<i::FunctionTemplateInfo> global_constructor;
ager@chromium.org8bb60582008-12-11 12:02:20 +00004342
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004343 if (!global_template.IsEmpty()) {
4344 // Make sure that the global_template has a constructor.
4345 global_constructor =
4346 EnsureConstructor(Utils::OpenHandle(*global_template));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004347
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004348 // Create a fresh template for the global proxy object.
4349 proxy_template = ObjectTemplate::New();
4350 proxy_constructor =
4351 EnsureConstructor(Utils::OpenHandle(*proxy_template));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004352
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004353 // Set the global template to be the prototype template of
4354 // global proxy template.
4355 proxy_constructor->set_prototype_template(
4356 *Utils::OpenHandle(*global_template));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004357
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004358 // Migrate security handlers from global_template to
4359 // proxy_template. Temporarily removing access check
4360 // information from the global template.
4361 if (!global_constructor->access_check_info()->IsUndefined()) {
4362 proxy_constructor->set_access_check_info(
4363 global_constructor->access_check_info());
4364 proxy_constructor->set_needs_access_check(
4365 global_constructor->needs_access_check());
4366 global_constructor->set_needs_access_check(false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004367 global_constructor->set_access_check_info(
4368 isolate->heap()->undefined_value());
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004369 }
4370 }
4371
4372 // Create the environment.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004373 env = isolate->bootstrapper()->CreateEnvironment(
danno@chromium.org160a7b02011-04-18 15:51:38 +00004374 isolate,
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004375 Utils::OpenHandle(*global_object),
4376 proxy_template,
4377 extensions);
4378
4379 // Restore the access check info on the global template.
4380 if (!global_template.IsEmpty()) {
4381 ASSERT(!global_constructor.is_null());
4382 ASSERT(!proxy_constructor.is_null());
4383 global_constructor->set_access_check_info(
4384 proxy_constructor->access_check_info());
4385 global_constructor->set_needs_access_check(
4386 proxy_constructor->needs_access_check());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004387 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004388 isolate->runtime_profiler()->Reset();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004389 }
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00004390 // Leave V8.
ager@chromium.org8bb60582008-12-11 12:02:20 +00004391
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004392 if (env.is_null()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004393 return Persistent<Context>();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004394 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004395 return Persistent<Context>(Utils::ToLocal(env));
4396}
4397
4398
4399void v8::Context::SetSecurityToken(Handle<Value> token) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004400 i::Isolate* isolate = i::Isolate::Current();
4401 if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004402 return;
4403 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004404 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004405 i::Handle<i::Context> env = Utils::OpenHandle(this);
4406 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004407 env->set_security_token(*token_handle);
4408}
4409
4410
4411void v8::Context::UseDefaultSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004412 i::Isolate* isolate = i::Isolate::Current();
4413 if (IsDeadCheck(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004414 "v8::Context::UseDefaultSecurityToken()")) {
4415 return;
4416 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004417 ENTER_V8(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004418 i::Handle<i::Context> env = Utils::OpenHandle(this);
4419 env->set_security_token(env->global());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004420}
4421
4422
4423Handle<Value> v8::Context::GetSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004424 i::Isolate* isolate = i::Isolate::Current();
4425 if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004426 return Handle<Value>();
4427 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004428 i::Handle<i::Context> env = Utils::OpenHandle(this);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004429 i::Object* security_token = env->security_token();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004430 i::Handle<i::Object> token_handle(security_token);
4431 return Utils::ToLocal(token_handle);
4432}
4433
4434
4435bool Context::HasOutOfMemoryException() {
4436 i::Handle<i::Context> env = Utils::OpenHandle(this);
4437 return env->has_out_of_memory();
4438}
4439
4440
4441bool Context::InContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004442 return i::Isolate::Current()->context() != NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004443}
4444
4445
kasper.lund44510672008-07-25 07:37:58 +00004446v8::Local<v8::Context> Context::GetEntered() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004447 i::Isolate* isolate = i::Isolate::Current();
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004448 if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004449 return Local<Context>();
4450 }
4451 i::Handle<i::Object> last =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004452 isolate->handle_scope_implementer()->LastEnteredContext();
kasper.lund44510672008-07-25 07:37:58 +00004453 if (last.is_null()) return Local<Context>();
4454 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
4455 return Utils::ToLocal(context);
4456}
4457
4458
4459v8::Local<v8::Context> Context::GetCurrent() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004460 i::Isolate* isolate = i::Isolate::Current();
4461 if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004462 return Local<Context>();
4463 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004464 i::Handle<i::Object> current = isolate->global_context();
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004465 if (current.is_null()) return Local<Context>();
4466 i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004467 return Utils::ToLocal(context);
4468}
4469
4470
ager@chromium.org1bf0cd02009-05-20 11:34:19 +00004471v8::Local<v8::Context> Context::GetCalling() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004472 i::Isolate* isolate = i::Isolate::Current();
4473 if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004474 return Local<Context>();
4475 }
4476 i::Handle<i::Object> calling =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004477 isolate->GetCallingGlobalContext();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00004478 if (calling.is_null()) return Local<Context>();
4479 i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
ager@chromium.org1bf0cd02009-05-20 11:34:19 +00004480 return Utils::ToLocal(context);
4481}
4482
4483
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004484v8::Local<v8::Object> Context::Global() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004485 if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
4486 return Local<v8::Object>();
4487 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004488 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4489 i::Handle<i::Context> context =
4490 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004491 i::Handle<i::Object> global(context->global_proxy());
4492 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
4493}
4494
4495
4496void Context::DetachGlobal() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004497 i::Isolate* isolate = i::Isolate::Current();
4498 if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
4499 ENTER_V8(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004500 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4501 i::Handle<i::Context> context =
4502 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004503 isolate->bootstrapper()->DetachGlobal(context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004504}
4505
4506
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00004507void Context::ReattachGlobal(Handle<Object> global_object) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004508 i::Isolate* isolate = i::Isolate::Current();
4509 if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004510 ENTER_V8(isolate);
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00004511 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4512 i::Handle<i::Context> context =
4513 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004514 isolate->bootstrapper()->ReattachGlobal(
4515 context,
4516 Utils::OpenHandle(*global_object));
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00004517}
4518
4519
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00004520void Context::AllowCodeGenerationFromStrings(bool allow) {
4521 i::Isolate* isolate = i::Isolate::Current();
4522 if (IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
4523 return;
4524 }
4525 ENTER_V8(isolate);
4526 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4527 i::Handle<i::Context> context =
4528 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4529 context->set_allow_code_gen_from_strings(
4530 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
4531}
4532
4533
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00004534bool Context::IsCodeGenerationFromStringsAllowed() {
4535 i::Isolate* isolate = i::Isolate::Current();
4536 if (IsDeadCheck(isolate,
4537 "v8::Context::IsCodeGenerationFromStringsAllowed()")) {
4538 return false;
4539 }
4540 ENTER_V8(isolate);
4541 i::Object** ctx = reinterpret_cast<i::Object**>(this);
4542 i::Handle<i::Context> context =
4543 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
4544 return !context->allow_code_gen_from_strings()->IsFalse();
4545}
4546
4547
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004548void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
4549 i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
4550}
4551
4552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004553Local<v8::Object> ObjectTemplate::NewInstance() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004554 i::Isolate* isolate = i::Isolate::Current();
4555 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
4556 return Local<v8::Object>());
4557 LOG_API(isolate, "ObjectTemplate::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004558 ENTER_V8(isolate);
4559 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004560 i::Handle<i::Object> obj =
4561 i::Execution::InstantiateObject(Utils::OpenHandle(this),
4562 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004563 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004564 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
4565}
4566
4567
4568Local<v8::Function> FunctionTemplate::GetFunction() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004569 i::Isolate* isolate = i::Isolate::Current();
4570 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004571 return Local<v8::Function>());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004572 LOG_API(isolate, "FunctionTemplate::GetFunction");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004573 ENTER_V8(isolate);
4574 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004575 i::Handle<i::Object> obj =
4576 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
4577 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004578 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004579 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
4580}
4581
4582
4583bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004584 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
4585 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004586 i::Object* obj = *Utils::OpenHandle(*value);
4587 return obj->IsInstanceOf(*Utils::OpenHandle(this));
4588}
4589
4590
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004591static Local<External> ExternalNewImpl(void* data) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004592 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data)));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004593}
4594
4595static void* ExternalValueImpl(i::Handle<i::Object> obj) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004596 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->foreign_address());
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004597}
4598
4599
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004600Local<Value> v8::External::Wrap(void* data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004601 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004602 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004603 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004604 LOG_API(isolate, "External::Wrap");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004605 ENTER_V8(isolate);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004606
4607 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
4608 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
4609 : v8::Local<v8::Value>(ExternalNewImpl(data));
4610
4611 ASSERT_EQ(data, Unwrap(result));
4612 return result;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004613}
4614
4615
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004616void* v8::Object::SlowGetPointerFromInternalField(int index) {
4617 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4618 i::Object* value = obj->GetInternalField(index);
4619 if (value->IsSmi()) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004620 return i::Internals::GetExternalPointerFromSmi(value);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004621 } else if (value->IsForeign()) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004622 return reinterpret_cast<void*>(i::Foreign::cast(value)->foreign_address());
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004623 } else {
4624 return NULL;
4625 }
4626}
4627
4628
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004629void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004630 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004631 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
4632 void* result;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004633 if (obj->IsSmi()) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004634 result = i::Internals::GetExternalPointerFromSmi(*obj);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004635 } else if (obj->IsForeign()) {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004636 result = ExternalValueImpl(obj);
4637 } else {
4638 result = NULL;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004639 }
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004640 ASSERT_EQ(result, QuickUnwrap(wrapper));
4641 return result;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004642}
4643
4644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004645Local<External> v8::External::New(void* data) {
4646 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004647 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004648 EnsureInitializedForIsolate(isolate, "v8::External::New()");
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004649 LOG_API(isolate, "External::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004650 ENTER_V8(isolate);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004651 return ExternalNewImpl(data);
4652}
4653
4654
4655void* External::Value() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004656 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004657 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4658 return ExternalValueImpl(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004659}
4660
4661
ager@chromium.org563b8dc2009-03-20 14:23:52 +00004662Local<String> v8::String::Empty() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004663 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00004664 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) {
4665 return v8::Local<String>();
4666 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004667 LOG_API(isolate, "String::Empty()");
4668 return Utils::ToLocal(isolate->factory()->empty_symbol());
ager@chromium.org563b8dc2009-03-20 14:23:52 +00004669}
4670
4671
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004672Local<String> v8::String::New(const char* data, int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004673 i::Isolate* isolate = i::Isolate::Current();
4674 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4675 LOG_API(isolate, "String::New(char)");
ager@chromium.org563b8dc2009-03-20 14:23:52 +00004676 if (length == 0) return Empty();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004677 ENTER_V8(isolate);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004678 if (length == -1) length = i::StrLength(data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004679 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004680 isolate->factory()->NewStringFromUtf8(
4681 i::Vector<const char>(data, length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004682 return Utils::ToLocal(result);
4683}
4684
4685
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004686Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004687 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004688 i::Isolate* isolate = left_string->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004689 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4690 LOG_API(isolate, "String::New(char)");
4691 ENTER_V8(isolate);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004692 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004693 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
4694 right_string);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00004695 return Utils::ToLocal(result);
4696}
4697
4698
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004699Local<String> v8::String::NewUndetectable(const char* data, int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004700 i::Isolate* isolate = i::Isolate::Current();
4701 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4702 LOG_API(isolate, "String::NewUndetectable(char)");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004703 ENTER_V8(isolate);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004704 if (length == -1) length = i::StrLength(data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004705 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004706 isolate->factory()->NewStringFromUtf8(
4707 i::Vector<const char>(data, length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004708 result->MarkAsUndetectable();
4709 return Utils::ToLocal(result);
4710}
4711
4712
4713static int TwoByteStringLength(const uint16_t* data) {
4714 int length = 0;
4715 while (data[length] != '\0') length++;
4716 return length;
4717}
4718
4719
4720Local<String> v8::String::New(const uint16_t* data, int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004721 i::Isolate* isolate = i::Isolate::Current();
4722 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4723 LOG_API(isolate, "String::New(uint16_)");
ager@chromium.org563b8dc2009-03-20 14:23:52 +00004724 if (length == 0) return Empty();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004725 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004726 if (length == -1) length = TwoByteStringLength(data);
4727 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004728 isolate->factory()->NewStringFromTwoByte(
4729 i::Vector<const uint16_t>(data, length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004730 return Utils::ToLocal(result);
4731}
4732
4733
4734Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004735 i::Isolate* isolate = i::Isolate::Current();
4736 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4737 LOG_API(isolate, "String::NewUndetectable(uint16_)");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004738 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004739 if (length == -1) length = TwoByteStringLength(data);
4740 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004741 isolate->factory()->NewStringFromTwoByte(
4742 i::Vector<const uint16_t>(data, length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004743 result->MarkAsUndetectable();
4744 return Utils::ToLocal(result);
4745}
4746
4747
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004748i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004749 v8::String::ExternalStringResource* resource) {
4750 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004751 isolate->factory()->NewExternalStringFromTwoByte(resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004752 return result;
4753}
4754
4755
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004756i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004757 v8::String::ExternalAsciiStringResource* resource) {
4758 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004759 isolate->factory()->NewExternalStringFromAscii(resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004760 return result;
4761}
4762
4763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004764Local<String> v8::String::NewExternal(
4765 v8::String::ExternalStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004766 i::Isolate* isolate = i::Isolate::Current();
4767 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4768 LOG_API(isolate, "String::NewExternal");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004769 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004770 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4771 isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004772 return Utils::ToLocal(result);
4773}
4774
4775
ager@chromium.org6f10e412009-02-13 10:11:16 +00004776bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004777 i::Handle<i::String> obj = Utils::OpenHandle(this);
4778 i::Isolate* isolate = obj->GetIsolate();
4779 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004780 if (i::StringShape(*obj).IsExternalTwoByte()) {
4781 return false; // Already an external string.
4782 }
4783 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004784 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4785 return false;
4786 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004787 if (isolate->heap()->IsInGCPostProcessing()) {
4788 return false;
4789 }
ager@chromium.org6f10e412009-02-13 10:11:16 +00004790 bool result = obj->MakeExternal(resource);
4791 if (result && !obj->IsSymbol()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004792 isolate->heap()->external_string_table()->AddString(*obj);
ager@chromium.org6f10e412009-02-13 10:11:16 +00004793 }
4794 return result;
4795}
4796
4797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004798Local<String> v8::String::NewExternal(
4799 v8::String::ExternalAsciiStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004800 i::Isolate* isolate = i::Isolate::Current();
4801 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4802 LOG_API(isolate, "String::NewExternal");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004803 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004804 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4805 isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004806 return Utils::ToLocal(result);
4807}
4808
4809
ager@chromium.org6f10e412009-02-13 10:11:16 +00004810bool v8::String::MakeExternal(
4811 v8::String::ExternalAsciiStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004812 i::Handle<i::String> obj = Utils::OpenHandle(this);
4813 i::Isolate* isolate = obj->GetIsolate();
4814 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004815 if (i::StringShape(*obj).IsExternalTwoByte()) {
4816 return false; // Already an external string.
4817 }
4818 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004819 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4820 return false;
4821 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004822 if (isolate->heap()->IsInGCPostProcessing()) {
4823 return false;
4824 }
ager@chromium.org6f10e412009-02-13 10:11:16 +00004825 bool result = obj->MakeExternal(resource);
4826 if (result && !obj->IsSymbol()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004827 isolate->heap()->external_string_table()->AddString(*obj);
ager@chromium.org6f10e412009-02-13 10:11:16 +00004828 }
4829 return result;
4830}
4831
4832
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00004833bool v8::String::CanMakeExternal() {
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00004834 if (!internal::FLAG_clever_optimizations) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00004835 i::Handle<i::String> obj = Utils::OpenHandle(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004836 i::Isolate* isolate = obj->GetIsolate();
4837 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004838 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00004839 int size = obj->Size(); // Byte size of the original string.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004840 if (size < i::ExternalString::kShortSize) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00004841 i::StringShape shape(*obj);
4842 return !shape.IsExternal();
4843}
4844
4845
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004846Local<v8::Object> v8::Object::New() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004847 i::Isolate* isolate = i::Isolate::Current();
4848 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
4849 LOG_API(isolate, "Object::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004850 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004851 i::Handle<i::JSObject> obj =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004852 isolate->factory()->NewJSObject(isolate->object_function());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004853 return Utils::ToLocal(obj);
4854}
4855
4856
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00004857Local<v8::Value> v8::NumberObject::New(double value) {
4858 i::Isolate* isolate = i::Isolate::Current();
4859 EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
4860 LOG_API(isolate, "NumberObject::New");
4861 ENTER_V8(isolate);
4862 i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
4863 i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
4864 return Utils::ToLocal(obj);
4865}
4866
4867
4868double v8::NumberObject::NumberValue() const {
4869 i::Isolate* isolate = i::Isolate::Current();
4870 if (IsDeadCheck(isolate, "v8::NumberObject::NumberValue()")) return 0;
4871 LOG_API(isolate, "NumberObject::NumberValue");
4872 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4873 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4874 return jsvalue->value()->Number();
4875}
4876
4877
4878Local<v8::Value> v8::BooleanObject::New(bool value) {
4879 i::Isolate* isolate = i::Isolate::Current();
4880 EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
4881 LOG_API(isolate, "BooleanObject::New");
4882 ENTER_V8(isolate);
4883 i::Handle<i::Object> boolean(value ? isolate->heap()->true_value()
4884 : isolate->heap()->false_value());
4885 i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
4886 return Utils::ToLocal(obj);
4887}
4888
4889
4890bool v8::BooleanObject::BooleanValue() const {
4891 i::Isolate* isolate = i::Isolate::Current();
4892 if (IsDeadCheck(isolate, "v8::BooleanObject::BooleanValue()")) return 0;
4893 LOG_API(isolate, "BooleanObject::BooleanValue");
4894 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4895 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4896 return jsvalue->value()->IsTrue();
4897}
4898
4899
4900Local<v8::Value> v8::StringObject::New(Handle<String> value) {
4901 i::Isolate* isolate = i::Isolate::Current();
4902 EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
4903 LOG_API(isolate, "StringObject::New");
4904 ENTER_V8(isolate);
4905 i::Handle<i::Object> obj =
4906 isolate->factory()->ToObject(Utils::OpenHandle(*value));
4907 return Utils::ToLocal(obj);
4908}
4909
4910
4911Local<v8::String> v8::StringObject::StringValue() const {
4912 i::Isolate* isolate = i::Isolate::Current();
4913 if (IsDeadCheck(isolate, "v8::StringObject::StringValue()")) {
4914 return Local<v8::String>();
4915 }
4916 LOG_API(isolate, "StringObject::StringValue");
4917 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4918 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
4919 return Utils::ToLocal(
4920 i::Handle<i::String>(i::String::cast(jsvalue->value())));
4921}
4922
4923
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004924Local<v8::Value> v8::Date::New(double time) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004925 i::Isolate* isolate = i::Isolate::Current();
4926 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
4927 LOG_API(isolate, "Date::New");
ager@chromium.org3811b432009-10-28 14:53:37 +00004928 if (isnan(time)) {
4929 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
4930 time = i::OS::nan_value();
4931 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004932 ENTER_V8(isolate);
4933 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004934 i::Handle<i::Object> obj =
4935 i::Execution::NewDate(time, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004936 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004937 return Utils::ToLocal(obj);
4938}
4939
4940
ager@chromium.org32912102009-01-16 10:38:43 +00004941double v8::Date::NumberValue() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004942 i::Isolate* isolate = i::Isolate::Current();
4943 if (IsDeadCheck(isolate, "v8::Date::NumberValue()")) return 0;
4944 LOG_API(isolate, "Date::NumberValue");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004945 i::Handle<i::Object> obj = Utils::OpenHandle(this);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004946 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
4947 return jsdate->value()->Number();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004948}
4949
4950
whesse@chromium.org023421e2010-12-21 12:19:12 +00004951void v8::Date::DateTimeConfigurationChangeNotification() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004952 i::Isolate* isolate = i::Isolate::Current();
4953 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
4954 return);
4955 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004956 ENTER_V8(isolate);
whesse@chromium.org023421e2010-12-21 12:19:12 +00004957
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004958 isolate->date_cache()->ResetDateCache();
4959
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004960 i::HandleScope scope(isolate);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004961 // Get the function ResetDateCache (defined in date.js).
whesse@chromium.org023421e2010-12-21 12:19:12 +00004962 i::Handle<i::String> func_name_str =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004963 isolate->factory()->LookupAsciiSymbol("ResetDateCache");
4964 i::MaybeObject* result =
4965 isolate->js_builtins_object()->GetProperty(*func_name_str);
whesse@chromium.org023421e2010-12-21 12:19:12 +00004966 i::Object* object_func;
4967 if (!result->ToObject(&object_func)) {
4968 return;
4969 }
4970
4971 if (object_func->IsJSFunction()) {
4972 i::Handle<i::JSFunction> func =
4973 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
4974
4975 // Call ResetDateCache(0 but expect no exceptions:
4976 bool caught_exception = false;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004977 i::Execution::TryCall(func,
4978 isolate->js_builtins_object(),
4979 0,
4980 NULL,
4981 &caught_exception);
whesse@chromium.org023421e2010-12-21 12:19:12 +00004982 }
4983}
4984
4985
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00004986static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
4987 char flags_buf[3];
4988 int num_flags = 0;
4989 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
4990 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
4991 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
4992 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004993 return FACTORY->LookupSymbol(
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00004994 i::Vector<const char>(flags_buf, num_flags));
4995}
4996
4997
4998Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
4999 Flags flags) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005000 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005001 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
5002 LOG_API(isolate, "RegExp::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005003 ENTER_V8(isolate);
5004 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005005 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
5006 Utils::OpenHandle(*pattern),
5007 RegExpFlagsToString(flags),
5008 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005009 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005010 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
5011}
5012
5013
5014Local<v8::String> v8::RegExp::GetSource() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005015 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005016 if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
5017 return Local<v8::String>();
5018 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005019 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5020 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
5021}
5022
5023
5024// Assert that the static flags cast in GetFlags is valid.
5025#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
5026 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
5027 static_cast<int>(i::JSRegExp::internal_flag))
5028REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
5029REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
5030REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
5031REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
5032#undef REGEXP_FLAG_ASSERT_EQ
5033
5034v8::RegExp::Flags v8::RegExp::GetFlags() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005035 if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::GetFlags()")) {
5036 return v8::RegExp::kNone;
5037 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005038 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5039 return static_cast<RegExp::Flags>(obj->GetFlags().value());
5040}
5041
5042
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005043Local<v8::Array> v8::Array::New(int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005044 i::Isolate* isolate = i::Isolate::Current();
5045 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
5046 LOG_API(isolate, "Array::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005047 ENTER_V8(isolate);
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00005048 int real_length = length > 0 ? length : 0;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005049 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005050 i::Handle<i::Object> length_obj =
5051 isolate->factory()->NewNumberFromInt(real_length);
5052 obj->set_length(*length_obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005053 return Utils::ToLocal(obj);
5054}
5055
5056
ager@chromium.org32912102009-01-16 10:38:43 +00005057uint32_t v8::Array::Length() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005058 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005059 if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005060 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
5061 i::Object* length = obj->length();
5062 if (length->IsSmi()) {
5063 return i::Smi::cast(length)->value();
5064 } else {
5065 return static_cast<uint32_t>(length->Number());
5066 }
5067}
5068
5069
ager@chromium.org3e875802009-06-29 08:26:34 +00005070Local<Object> Array::CloneElementAt(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005071 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005072 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005073 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005074 if (!self->HasFastObjectElements()) {
ager@chromium.org3e875802009-06-29 08:26:34 +00005075 return Local<Object>();
5076 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005077 i::FixedArray* elms = i::FixedArray::cast(self->elements());
ager@chromium.org3e875802009-06-29 08:26:34 +00005078 i::Object* paragon = elms->get(index);
5079 if (!paragon->IsJSObject()) {
5080 return Local<Object>();
5081 }
5082 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005083 EXCEPTION_PREAMBLE(isolate);
5084 ENTER_V8(isolate);
ager@chromium.org3e875802009-06-29 08:26:34 +00005085 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
5086 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005087 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005088 return Utils::ToLocal(result);
5089}
5090
5091
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005092Local<String> v8::String::NewSymbol(const char* data, int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005093 i::Isolate* isolate = i::Isolate::Current();
5094 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
5095 LOG_API(isolate, "String::NewSymbol(char)");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005096 ENTER_V8(isolate);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005097 if (length == -1) length = i::StrLength(data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005098 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005099 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005100 return Utils::ToLocal(result);
5101}
5102
5103
5104Local<Number> v8::Number::New(double value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005105 i::Isolate* isolate = i::Isolate::Current();
5106 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
ager@chromium.org3811b432009-10-28 14:53:37 +00005107 if (isnan(value)) {
5108 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5109 value = i::OS::nan_value();
5110 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005111 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005112 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005113 return Utils::NumberToLocal(result);
5114}
5115
5116
5117Local<Integer> v8::Integer::New(int32_t value) {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00005118 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005119 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005120 if (i::Smi::IsValid(value)) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005121 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
5122 isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005123 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005124 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005125 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005126 return Utils::IntegerToLocal(result);
5127}
5128
5129
ager@chromium.org3811b432009-10-28 14:53:37 +00005130Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
5131 bool fits_into_int32_t = (value & (1 << 31)) == 0;
5132 if (fits_into_int32_t) {
5133 return Integer::New(static_cast<int32_t>(value));
5134 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005135 i::Isolate* isolate = i::Isolate::Current();
5136 ENTER_V8(isolate);
5137 i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
ager@chromium.org3811b432009-10-28 14:53:37 +00005138 return Utils::IntegerToLocal(result);
5139}
5140
5141
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005142void V8::IgnoreOutOfMemoryException() {
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005143 EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005144}
5145
5146
5147bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005148 i::Isolate* isolate = i::Isolate::Current();
5149 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
5150 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005151 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005152 i::HandleScope scope(isolate);
5153 NeanderArray listeners(isolate->factory()->message_listeners());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005154 NeanderObject obj(2);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005155 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005156 obj.set(1, data.IsEmpty() ?
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005157 isolate->heap()->undefined_value() :
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005158 *Utils::OpenHandle(*data));
5159 listeners.add(obj.value());
5160 return true;
5161}
5162
5163
5164void V8::RemoveMessageListeners(MessageCallback that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005165 i::Isolate* isolate = i::Isolate::Current();
5166 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
5167 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005168 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005169 i::HandleScope scope(isolate);
5170 NeanderArray listeners(isolate->factory()->message_listeners());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005171 for (int i = 0; i < listeners.length(); i++) {
5172 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
5173
5174 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005175 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005176 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005177 listeners.set(i, isolate->heap()->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005178 }
5179 }
5180}
5181
5182
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00005183void V8::SetCaptureStackTraceForUncaughtExceptions(
5184 bool capture,
5185 int frame_limit,
5186 StackTrace::StackTraceOptions options) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005187 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00005188 capture,
5189 frame_limit,
5190 options);
5191}
5192
5193
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005194void V8::SetCounterFunction(CounterLookupCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00005195 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005196 if (IsDeadCheck(isolate, "v8::V8::SetCounterFunction()")) return;
5197 isolate->stats_table()->SetCounterFunction(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005198}
5199
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005200void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00005201 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005202 if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
5203 isolate->stats_table()->SetCreateHistogramFunction(callback);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005204}
5205
5206void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00005207 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005208 if (IsDeadCheck(isolate, "v8::V8::SetAddHistogramSampleFunction()")) return;
5209 isolate->stats_table()->
5210 SetAddHistogramSampleFunction(callback);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005211}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005212
5213void V8::EnableSlidingStateWindow() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005214 i::Isolate* isolate = i::Isolate::Current();
5215 if (IsDeadCheck(isolate, "v8::V8::EnableSlidingStateWindow()")) return;
5216 isolate->logger()->EnableSlidingStateWindow();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005217}
5218
5219
5220void V8::SetFailedAccessCheckCallbackFunction(
5221 FailedAccessCheckCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005222 i::Isolate* isolate = i::Isolate::Current();
5223 if (IsDeadCheck(isolate, "v8::V8::SetFailedAccessCheckCallbackFunction()")) {
5224 return;
5225 }
5226 isolate->SetFailedAccessCheckCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005227}
5228
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005229void V8::AddObjectGroup(Persistent<Value>* objects,
5230 size_t length,
5231 RetainedObjectInfo* info) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005232 i::Isolate* isolate = i::Isolate::Current();
5233 if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
ager@chromium.org8bb60582008-12-11 12:02:20 +00005234 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005235 isolate->global_handles()->AddObjectGroup(
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005236 reinterpret_cast<i::Object***>(objects), length, info);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005237}
5238
5239
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00005240void V8::AddImplicitReferences(Persistent<Object> parent,
5241 Persistent<Value>* children,
5242 size_t length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005243 i::Isolate* isolate = i::Isolate::Current();
5244 if (IsDeadCheck(isolate, "v8::V8::AddImplicitReferences()")) return;
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00005245 STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005246 isolate->global_handles()->AddImplicitReferences(
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005247 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*parent)).location(),
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00005248 reinterpret_cast<i::Object***>(children), length);
5249}
5250
5251
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005252intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005253 i::Isolate* isolate = i::Isolate::Current();
5254 if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
5255 return 0;
5256 }
5257 return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
5258 change_in_bytes);
kasper.lund7276f142008-07-30 08:49:36 +00005259}
5260
5261
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005262void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005263 i::Isolate* isolate = i::Isolate::Current();
5264 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
5265 isolate->heap()->SetGlobalGCPrologueCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005266}
5267
5268
5269void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005270 i::Isolate* isolate = i::Isolate::Current();
5271 if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
5272 isolate->heap()->SetGlobalGCEpilogueCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005273}
5274
5275
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00005276void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005277 i::Isolate* isolate = i::Isolate::Current();
5278 if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
5279 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00005280}
5281
5282
5283void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005284 i::Isolate* isolate = i::Isolate::Current();
5285 if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
5286 isolate->heap()->RemoveGCPrologueCallback(callback);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00005287}
5288
5289
5290void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005291 i::Isolate* isolate = i::Isolate::Current();
5292 if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
5293 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00005294}
5295
5296
5297void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005298 i::Isolate* isolate = i::Isolate::Current();
5299 if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
5300 isolate->heap()->RemoveGCEpilogueCallback(callback);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00005301}
5302
5303
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00005304void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
5305 ObjectSpace space,
5306 AllocationAction action) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005307 i::Isolate* isolate = i::Isolate::Current();
5308 if (IsDeadCheck(isolate, "v8::V8::AddMemoryAllocationCallback()")) return;
5309 isolate->memory_allocator()->AddMemoryAllocationCallback(
5310 callback, space, action);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00005311}
5312
5313
5314void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005315 i::Isolate* isolate = i::Isolate::Current();
5316 if (IsDeadCheck(isolate, "v8::V8::RemoveMemoryAllocationCallback()")) return;
5317 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
5318 callback);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00005319}
5320
5321
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005322void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
5323 if (callback == NULL) return;
danno@chromium.org74d57b12012-04-04 14:34:26 +00005324 i::Isolate::EnsureDefaultIsolate();
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005325 i::Isolate* isolate = i::Isolate::Current();
5326 if (IsDeadCheck(isolate, "v8::V8::AddLeaveScriptCallback()")) return;
5327 i::V8::AddCallCompletedCallback(callback);
5328}
5329
5330
5331void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
danno@chromium.org74d57b12012-04-04 14:34:26 +00005332 i::Isolate::EnsureDefaultIsolate();
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005333 i::Isolate* isolate = i::Isolate::Current();
5334 if (IsDeadCheck(isolate, "v8::V8::RemoveLeaveScriptCallback()")) return;
5335 i::V8::RemoveCallCompletedCallback(callback);
5336}
5337
5338
iposva@chromium.org245aa852009-02-10 00:49:54 +00005339void V8::PauseProfiler() {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00005340 i::Isolate* isolate = i::Isolate::Current();
5341 isolate->logger()->PauseProfiler();
iposva@chromium.org245aa852009-02-10 00:49:54 +00005342}
5343
kasperl@chromium.org71affb52009-05-26 05:44:31 +00005344
iposva@chromium.org245aa852009-02-10 00:49:54 +00005345void V8::ResumeProfiler() {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00005346 i::Isolate* isolate = i::Isolate::Current();
5347 isolate->logger()->ResumeProfiler();
iposva@chromium.org245aa852009-02-10 00:49:54 +00005348}
5349
kasperl@chromium.org71affb52009-05-26 05:44:31 +00005350
5351bool V8::IsProfilerPaused() {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00005352 i::Isolate* isolate = i::Isolate::Current();
5353 return isolate->logger()->IsProfilerPaused();
ager@chromium.org9085a012009-05-11 19:22:57 +00005354}
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005355
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005356
5357int V8::GetCurrentThreadId() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005358 i::Isolate* isolate = i::Isolate::Current();
5359 EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00005360 return isolate->thread_id().ToInteger();
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005361}
5362
5363
5364void V8::TerminateExecution(int thread_id) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005365 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005366 if (!isolate->IsInitialized()) return;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00005367 API_ENTRY_CHECK(isolate, "V8::TerminateExecution()");
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005368 // If the thread_id identifies the current thread just terminate
5369 // execution right away. Otherwise, ask the thread manager to
5370 // terminate the thread with the given id if any.
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00005371 i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
5372 if (isolate->thread_id().Equals(internal_tid)) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005373 isolate->stack_guard()->TerminateExecution();
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005374 } else {
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00005375 isolate->thread_manager()->TerminateExecution(internal_tid);
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005376 }
5377}
5378
5379
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005380void V8::TerminateExecution(Isolate* isolate) {
5381 // If no isolate is supplied, use the default isolate.
5382 if (isolate != NULL) {
5383 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
5384 } else {
5385 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
5386 }
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005387}
5388
5389
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005390bool V8::IsExecutionTerminating(Isolate* isolate) {
5391 i::Isolate* i_isolate = isolate != NULL ?
5392 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
5393 return IsExecutionTerminatingCheck(i_isolate);
sgjesse@chromium.org2ab99522010-03-10 09:03:43 +00005394}
5395
5396
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005397Isolate* Isolate::GetCurrent() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00005398 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005399 return reinterpret_cast<Isolate*>(isolate);
5400}
5401
5402
5403Isolate* Isolate::New() {
5404 i::Isolate* isolate = new i::Isolate();
5405 return reinterpret_cast<Isolate*>(isolate);
5406}
5407
5408
5409void Isolate::Dispose() {
5410 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5411 if (!ApiCheck(!isolate->IsInUse(),
5412 "v8::Isolate::Dispose()",
5413 "Disposing the isolate that is entered by a thread.")) {
5414 return;
5415 }
5416 isolate->TearDown();
5417}
5418
5419
5420void Isolate::Enter() {
5421 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5422 isolate->Enter();
5423}
5424
5425
5426void Isolate::Exit() {
5427 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5428 isolate->Exit();
5429}
5430
5431
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005432String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
5433 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005434 i::Isolate* isolate = i::Isolate::Current();
5435 if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005436 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005437 ENTER_V8(isolate);
5438 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00005439 TryCatch try_catch;
5440 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005441 if (str.IsEmpty()) return;
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005442 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
5443 length_ = i::Utf8Length(i_str);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005444 str_ = i::NewArray<char>(length_ + 1);
5445 str->WriteUtf8(str_);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00005446}
5447
5448
5449String::Utf8Value::~Utf8Value() {
5450 i::DeleteArray(str_);
5451}
5452
5453
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005454String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
5455 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005456 i::Isolate* isolate = i::Isolate::Current();
5457 if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005458 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005459 ENTER_V8(isolate);
5460 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00005461 TryCatch try_catch;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005462 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005463 if (str.IsEmpty()) return;
5464 length_ = str->Length();
5465 str_ = i::NewArray<char>(length_ + 1);
5466 str->WriteAscii(str_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005467}
5468
5469
5470String::AsciiValue::~AsciiValue() {
5471 i::DeleteArray(str_);
5472}
5473
5474
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005475String::Value::Value(v8::Handle<v8::Value> obj)
5476 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005477 i::Isolate* isolate = i::Isolate::Current();
5478 if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005479 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005480 ENTER_V8(isolate);
5481 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00005482 TryCatch try_catch;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005483 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005484 if (str.IsEmpty()) return;
5485 length_ = str->Length();
5486 str_ = i::NewArray<uint16_t>(length_ + 1);
5487 str->Write(str_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005488}
5489
5490
5491String::Value::~Value() {
5492 i::DeleteArray(str_);
5493}
5494
5495Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005496 i::Isolate* isolate = i::Isolate::Current();
5497 LOG_API(isolate, "RangeError");
5498 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005499 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005500 i::Object* error;
5501 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005502 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005503 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005504 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005505 error = *result;
5506 }
5507 i::Handle<i::Object> result(error);
5508 return Utils::ToLocal(result);
5509}
5510
5511Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005512 i::Isolate* isolate = i::Isolate::Current();
5513 LOG_API(isolate, "ReferenceError");
5514 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005515 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005516 i::Object* error;
5517 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005518 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005519 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005520 i::Handle<i::Object> result =
5521 isolate->factory()->NewReferenceError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005522 error = *result;
5523 }
5524 i::Handle<i::Object> result(error);
5525 return Utils::ToLocal(result);
5526}
5527
5528Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005529 i::Isolate* isolate = i::Isolate::Current();
5530 LOG_API(isolate, "SyntaxError");
5531 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005532 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005533 i::Object* error;
5534 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005535 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005536 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005537 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005538 error = *result;
5539 }
5540 i::Handle<i::Object> result(error);
5541 return Utils::ToLocal(result);
5542}
5543
5544Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005545 i::Isolate* isolate = i::Isolate::Current();
5546 LOG_API(isolate, "TypeError");
5547 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005548 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005549 i::Object* error;
5550 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005551 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005552 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005553 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005554 error = *result;
5555 }
5556 i::Handle<i::Object> result(error);
5557 return Utils::ToLocal(result);
5558}
5559
5560Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005561 i::Isolate* isolate = i::Isolate::Current();
5562 LOG_API(isolate, "Error");
5563 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005564 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005565 i::Object* error;
5566 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005567 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005568 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005569 i::Handle<i::Object> result = isolate->factory()->NewError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005570 error = *result;
5571 }
5572 i::Handle<i::Object> result(error);
5573 return Utils::ToLocal(result);
5574}
5575
5576
5577// --- D e b u g S u p p o r t ---
5578
ager@chromium.org65dad4b2009-04-23 08:48:43 +00005579#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005580
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005581static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005582 i::Isolate* isolate = i::Isolate::Current();
5583 if (isolate->debug_event_callback() != NULL) {
5584 isolate->debug_event_callback()(event_details.GetEvent(),
5585 event_details.GetExecutionState(),
5586 event_details.GetEventData(),
5587 event_details.GetCallbackData());
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005588 }
5589}
5590
5591
ager@chromium.org65dad4b2009-04-23 08:48:43 +00005592bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005593 i::Isolate* isolate = i::Isolate::Current();
5594 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
5595 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005596 ENTER_V8(isolate);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005597
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005598 isolate->set_debug_event_callback(that);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005599
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005600 i::HandleScope scope(isolate);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005601 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005602 if (that != NULL) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005603 foreign =
5604 isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005605 }
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005606 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005607 return true;
5608}
5609
5610
5611bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005612 i::Isolate* isolate = i::Isolate::Current();
5613 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
5614 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005615 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005616 i::HandleScope scope(isolate);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005617 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
ager@chromium.org381abbb2009-02-25 13:23:22 +00005618 if (that != NULL) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005619 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
ager@chromium.org381abbb2009-02-25 13:23:22 +00005620 }
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005621 isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005622 return true;
5623}
5624
5625
iposva@chromium.org245aa852009-02-10 00:49:54 +00005626bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005627 Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005628 i::Isolate* isolate = i::Isolate::Current();
5629 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005630 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005631 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
5632 Utils::OpenHandle(*data));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005633 return true;
5634}
5635
5636
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005637void Debug::DebugBreak(Isolate* isolate) {
5638 // If no isolate is supplied, use the default isolate.
5639 if (isolate != NULL) {
5640 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
5641 } else {
5642 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
5643 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005644}
5645
5646
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005647void Debug::CancelDebugBreak(Isolate* isolate) {
5648 // If no isolate is supplied, use the default isolate.
5649 if (isolate != NULL) {
5650 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5651 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
5652 } else {
5653 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
5654 }
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00005655}
5656
5657
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005658void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
5659 // If no isolate is supplied, use the default isolate.
5660 if (isolate != NULL) {
5661 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5662 internal_isolate->debugger()->EnqueueDebugCommand(data);
5663 } else {
5664 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
5665 }
mikhail.naganov@gmail.com22762872010-07-14 09:29:05 +00005666}
5667
5668
ager@chromium.org5ec48922009-05-05 07:25:34 +00005669static void MessageHandlerWrapper(const v8::Debug::Message& message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005670 i::Isolate* isolate = i::Isolate::Current();
5671 if (isolate->message_handler()) {
ager@chromium.org5ec48922009-05-05 07:25:34 +00005672 v8::String::Value json(message.GetJSON());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005673 (isolate->message_handler())(*json, json.length(), message.GetClientData());
ager@chromium.org5ec48922009-05-05 07:25:34 +00005674 }
5675}
5676
5677
ager@chromium.org65dad4b2009-04-23 08:48:43 +00005678void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
ager@chromium.org41826e72009-03-30 13:30:57 +00005679 bool message_handler_thread) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005680 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005681 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5682 ENTER_V8(isolate);
5683
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00005684 // Message handler thread not supported any more. Parameter temporally left in
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005685 // the API for client compatibility reasons.
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00005686 CHECK(!message_handler_thread);
ager@chromium.org5ec48922009-05-05 07:25:34 +00005687
5688 // TODO(sgjesse) support the old message handler API through a simple wrapper.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005689 isolate->set_message_handler(handler);
5690 if (handler != NULL) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005691 isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
ager@chromium.org5ec48922009-05-05 07:25:34 +00005692 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005693 isolate->debugger()->SetMessageHandler(NULL);
ager@chromium.org5ec48922009-05-05 07:25:34 +00005694 }
5695}
5696
5697
5698void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005699 i::Isolate* isolate = i::Isolate::Current();
5700 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
5701 ENTER_V8(isolate);
5702 isolate->debugger()->SetMessageHandler(handler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005703}
5704
5705
ager@chromium.org65dad4b2009-04-23 08:48:43 +00005706void Debug::SendCommand(const uint16_t* command, int length,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005707 ClientData* client_data,
5708 Isolate* isolate) {
5709 // If no isolate is supplied, use the default isolate.
5710 if (isolate != NULL) {
5711 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
5712 internal_isolate->debugger()->ProcessCommand(
5713 i::Vector<const uint16_t>(command, length), client_data);
5714 } else {
5715 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
5716 i::Vector<const uint16_t>(command, length), client_data);
5717 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005718}
5719
5720
ager@chromium.org65dad4b2009-04-23 08:48:43 +00005721void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
5722 int period) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005723 i::Isolate* isolate = i::Isolate::Current();
5724 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
5725 ENTER_V8(isolate);
5726 isolate->debugger()->SetHostDispatchHandler(handler, period);
ager@chromium.org381abbb2009-02-25 13:23:22 +00005727}
5728
5729
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005730void Debug::SetDebugMessageDispatchHandler(
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005731 DebugMessageDispatchHandler handler, bool provide_locker) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005732 i::Isolate* isolate = i::Isolate::Current();
5733 EnsureInitializedForIsolate(isolate,
5734 "v8::Debug::SetDebugMessageDispatchHandler");
5735 ENTER_V8(isolate);
5736 isolate->debugger()->SetDebugMessageDispatchHandler(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005737 handler, provide_locker);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005738}
5739
5740
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00005741Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
5742 v8::Handle<v8::Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005743 i::Isolate* isolate = i::Isolate::Current();
5744 if (!isolate->IsInitialized()) return Local<Value>();
5745 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005746 ENTER_V8(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005747 i::Handle<i::Object> result;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005748 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005749 if (data.IsEmpty()) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005750 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5751 isolate->factory()->undefined_value(),
5752 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005753 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005754 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
5755 Utils::OpenHandle(*data),
5756 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005757 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005758 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005759 return Utils::ToLocal(result);
5760}
5761
5762
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00005763Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005764 i::Isolate* isolate = i::Isolate::Current();
5765 if (!isolate->IsInitialized()) return Local<Value>();
5766 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005767 ENTER_V8(isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00005768 v8::HandleScope scope;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005769 i::Debug* isolate_debug = isolate->debug();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005770 isolate_debug->Load();
5771 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
5772 i::Handle<i::String> name =
5773 isolate->factory()->LookupAsciiSymbol("MakeMirror");
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00005774 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
5775 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
5776 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
5777 const int kArgc = 1;
5778 v8::Handle<v8::Value> argv[kArgc] = { obj };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005779 EXCEPTION_PREAMBLE(isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00005780 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
5781 kArgc,
5782 argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005783 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00005784 return scope.Close(result);
5785}
5786
5787
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00005788bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005789 return i::Isolate::Current()->debugger()->StartAgent(name, port,
5790 wait_for_connection);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00005791}
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005792
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005793
5794void Debug::DisableAgent() {
5795 return i::Isolate::Current()->debugger()->StopAgent();
5796}
5797
5798
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005799void Debug::ProcessDebugMessages() {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005800 i::Execution::ProcessDebugMessages(true);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005801}
5802
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00005803Local<Context> Debug::GetDebugContext() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005804 i::Isolate* isolate = i::Isolate::Current();
5805 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
5806 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005807 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00005808}
5809
ager@chromium.org65dad4b2009-04-23 08:48:43 +00005810#endif // ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00005811
ager@chromium.org357bf652010-04-12 11:30:10 +00005812
ager@chromium.org357bf652010-04-12 11:30:10 +00005813Handle<String> CpuProfileNode::GetFunctionName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005814 i::Isolate* isolate = i::Isolate::Current();
5815 IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
ager@chromium.org357bf652010-04-12 11:30:10 +00005816 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
5817 const i::CodeEntry* entry = node->entry();
5818 if (!entry->has_name_prefix()) {
5819 return Handle<String>(ToApi<String>(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005820 isolate->factory()->LookupAsciiSymbol(entry->name())));
ager@chromium.org357bf652010-04-12 11:30:10 +00005821 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005822 return Handle<String>(ToApi<String>(isolate->factory()->NewConsString(
5823 isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
5824 isolate->factory()->LookupAsciiSymbol(entry->name()))));
ager@chromium.org357bf652010-04-12 11:30:10 +00005825 }
5826}
5827
5828
5829Handle<String> CpuProfileNode::GetScriptResourceName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005830 i::Isolate* isolate = i::Isolate::Current();
5831 IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
ager@chromium.org357bf652010-04-12 11:30:10 +00005832 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005833 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
ager@chromium.org357bf652010-04-12 11:30:10 +00005834 node->entry()->resource_name())));
5835}
5836
5837
5838int CpuProfileNode::GetLineNumber() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005839 i::Isolate* isolate = i::Isolate::Current();
5840 IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
ager@chromium.org357bf652010-04-12 11:30:10 +00005841 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
5842}
5843
5844
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005845double CpuProfileNode::GetTotalTime() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005846 i::Isolate* isolate = i::Isolate::Current();
5847 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005848 return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
5849}
5850
5851
5852double CpuProfileNode::GetSelfTime() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005853 i::Isolate* isolate = i::Isolate::Current();
5854 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005855 return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
5856}
5857
5858
ager@chromium.org357bf652010-04-12 11:30:10 +00005859double CpuProfileNode::GetTotalSamplesCount() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005860 i::Isolate* isolate = i::Isolate::Current();
5861 IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
ager@chromium.org357bf652010-04-12 11:30:10 +00005862 return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
5863}
5864
5865
5866double CpuProfileNode::GetSelfSamplesCount() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005867 i::Isolate* isolate = i::Isolate::Current();
5868 IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
ager@chromium.org357bf652010-04-12 11:30:10 +00005869 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
5870}
5871
5872
5873unsigned CpuProfileNode::GetCallUid() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005874 i::Isolate* isolate = i::Isolate::Current();
5875 IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00005876 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
ager@chromium.org357bf652010-04-12 11:30:10 +00005877}
5878
5879
5880int CpuProfileNode::GetChildrenCount() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005881 i::Isolate* isolate = i::Isolate::Current();
5882 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
ager@chromium.org357bf652010-04-12 11:30:10 +00005883 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
5884}
5885
5886
5887const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005888 i::Isolate* isolate = i::Isolate::Current();
5889 IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
ager@chromium.org357bf652010-04-12 11:30:10 +00005890 const i::ProfileNode* child =
5891 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
5892 return reinterpret_cast<const CpuProfileNode*>(child);
5893}
5894
5895
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005896void CpuProfile::Delete() {
5897 i::Isolate* isolate = i::Isolate::Current();
5898 IsDeadCheck(isolate, "v8::CpuProfile::Delete");
5899 i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
5900 if (i::CpuProfiler::GetProfilesCount() == 0 &&
5901 !i::CpuProfiler::HasDetachedProfiles()) {
5902 // If this was the last profile, clean up all accessory data as well.
5903 i::CpuProfiler::DeleteAllProfiles();
5904 }
5905}
5906
5907
ager@chromium.org357bf652010-04-12 11:30:10 +00005908unsigned CpuProfile::GetUid() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005909 i::Isolate* isolate = i::Isolate::Current();
5910 IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
ager@chromium.org357bf652010-04-12 11:30:10 +00005911 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
5912}
5913
5914
5915Handle<String> CpuProfile::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005916 i::Isolate* isolate = i::Isolate::Current();
5917 IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
ager@chromium.org357bf652010-04-12 11:30:10 +00005918 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005919 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
ager@chromium.org357bf652010-04-12 11:30:10 +00005920 profile->title())));
5921}
5922
5923
5924const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005925 i::Isolate* isolate = i::Isolate::Current();
5926 IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
ager@chromium.org357bf652010-04-12 11:30:10 +00005927 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5928 return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
5929}
5930
5931
5932const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005933 i::Isolate* isolate = i::Isolate::Current();
5934 IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
ager@chromium.org357bf652010-04-12 11:30:10 +00005935 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
5936 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
5937}
5938
5939
5940int CpuProfiler::GetProfilesCount() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005941 i::Isolate* isolate = i::Isolate::Current();
5942 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
ager@chromium.org357bf652010-04-12 11:30:10 +00005943 return i::CpuProfiler::GetProfilesCount();
5944}
5945
5946
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005947const CpuProfile* CpuProfiler::GetProfile(int index,
5948 Handle<Value> security_token) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005949 i::Isolate* isolate = i::Isolate::Current();
5950 IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005951 return reinterpret_cast<const CpuProfile*>(
5952 i::CpuProfiler::GetProfile(
5953 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5954 index));
ager@chromium.org357bf652010-04-12 11:30:10 +00005955}
5956
5957
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005958const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
5959 Handle<Value> security_token) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005960 i::Isolate* isolate = i::Isolate::Current();
5961 IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005962 return reinterpret_cast<const CpuProfile*>(
5963 i::CpuProfiler::FindProfile(
5964 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5965 uid));
ager@chromium.org357bf652010-04-12 11:30:10 +00005966}
5967
5968
5969void CpuProfiler::StartProfiling(Handle<String> title) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005970 i::Isolate* isolate = i::Isolate::Current();
5971 IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
ager@chromium.org357bf652010-04-12 11:30:10 +00005972 i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
5973}
5974
5975
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005976const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
5977 Handle<Value> security_token) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005978 i::Isolate* isolate = i::Isolate::Current();
5979 IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
ager@chromium.org357bf652010-04-12 11:30:10 +00005980 return reinterpret_cast<const CpuProfile*>(
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00005981 i::CpuProfiler::StopProfiling(
5982 security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
5983 *Utils::OpenHandle(*title)));
ager@chromium.org357bf652010-04-12 11:30:10 +00005984}
5985
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00005986
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005987void CpuProfiler::DeleteAllProfiles() {
5988 i::Isolate* isolate = i::Isolate::Current();
5989 IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
5990 i::CpuProfiler::DeleteAllProfiles();
5991}
5992
5993
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00005994static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
5995 return const_cast<i::HeapGraphEdge*>(
5996 reinterpret_cast<const i::HeapGraphEdge*>(edge));
5997}
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005998
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00005999
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006000HeapGraphEdge::Type HeapGraphEdge::GetType() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006001 i::Isolate* isolate = i::Isolate::Current();
6002 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006003 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006004}
6005
6006
6007Handle<Value> HeapGraphEdge::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006008 i::Isolate* isolate = i::Isolate::Current();
6009 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006010 i::HeapGraphEdge* edge = ToInternal(this);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006011 switch (edge->type()) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006012 case i::HeapGraphEdge::kContextVariable:
6013 case i::HeapGraphEdge::kInternal:
6014 case i::HeapGraphEdge::kProperty:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00006015 case i::HeapGraphEdge::kShortcut:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006016 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006017 edge->name())));
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006018 case i::HeapGraphEdge::kElement:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00006019 case i::HeapGraphEdge::kHidden:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006020 return Handle<Number>(ToApi<Number>(isolate->factory()->NewNumberFromInt(
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006021 edge->index())));
6022 default: UNREACHABLE();
6023 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006024 return v8::Undefined();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006025}
6026
6027
6028const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006029 i::Isolate* isolate = i::Isolate::Current();
6030 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00006031 const i::HeapEntry* from = ToInternal(this)->from();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006032 return reinterpret_cast<const HeapGraphNode*>(from);
6033}
6034
6035
6036const HeapGraphNode* HeapGraphEdge::GetToNode() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006037 i::Isolate* isolate = i::Isolate::Current();
6038 IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006039 const i::HeapEntry* to = ToInternal(this)->to();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006040 return reinterpret_cast<const HeapGraphNode*>(to);
6041}
6042
6043
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006044static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
6045 return const_cast<i::HeapEntry*>(
6046 reinterpret_cast<const i::HeapEntry*>(entry));
6047}
6048
6049
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006050HeapGraphNode::Type HeapGraphNode::GetType() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006051 i::Isolate* isolate = i::Isolate::Current();
6052 IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006053 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006054}
6055
6056
6057Handle<String> HeapGraphNode::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006058 i::Isolate* isolate = i::Isolate::Current();
6059 IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
6060 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006061 ToInternal(this)->name())));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006062}
6063
6064
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00006065SnapshotObjectId HeapGraphNode::GetId() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006066 i::Isolate* isolate = i::Isolate::Current();
6067 IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006068 return ToInternal(this)->id();
ricow@chromium.org4980dff2010-07-19 08:33:45 +00006069}
6070
6071
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006072int HeapGraphNode::GetSelfSize() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006073 i::Isolate* isolate = i::Isolate::Current();
6074 IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006075 return ToInternal(this)->self_size();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006076}
6077
6078
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006079int HeapGraphNode::GetChildrenCount() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006080 i::Isolate* isolate = i::Isolate::Current();
6081 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006082 return ToInternal(this)->children().length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006083}
6084
6085
6086const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006087 i::Isolate* isolate = i::Isolate::Current();
6088 IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006089 return reinterpret_cast<const HeapGraphEdge*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00006090 ToInternal(this)->children()[index]);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006091}
6092
6093
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006094v8::Handle<v8::Value> HeapGraphNode::GetHeapValue() const {
6095 i::Isolate* isolate = i::Isolate::Current();
6096 IsDeadCheck(isolate, "v8::HeapGraphNode::GetHeapValue");
6097 i::Handle<i::HeapObject> object = ToInternal(this)->GetHeapObject();
6098 return v8::Handle<Value>(!object.is_null() ?
6099 ToApi<Value>(object) : ToApi<Value>(
6100 isolate->factory()->undefined_value()));
6101}
6102
6103
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006104static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
6105 return const_cast<i::HeapSnapshot*>(
6106 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
6107}
6108
6109
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006110void HeapSnapshot::Delete() {
6111 i::Isolate* isolate = i::Isolate::Current();
6112 IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
6113 if (i::HeapProfiler::GetSnapshotsCount() > 1) {
6114 ToInternal(this)->Delete();
6115 } else {
6116 // If this is the last snapshot, clean up all accessory data as well.
6117 i::HeapProfiler::DeleteAllSnapshots();
6118 }
6119}
6120
6121
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00006122HeapSnapshot::Type HeapSnapshot::GetType() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006123 i::Isolate* isolate = i::Isolate::Current();
6124 IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00006125 return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
6126}
6127
6128
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006129unsigned HeapSnapshot::GetUid() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006130 i::Isolate* isolate = i::Isolate::Current();
6131 IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006132 return ToInternal(this)->uid();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006133}
6134
6135
6136Handle<String> HeapSnapshot::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006137 i::Isolate* isolate = i::Isolate::Current();
6138 IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
6139 return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006140 ToInternal(this)->title())));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006141}
6142
6143
ricow@chromium.org4980dff2010-07-19 08:33:45 +00006144const HeapGraphNode* HeapSnapshot::GetRoot() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006145 i::Isolate* isolate = i::Isolate::Current();
6146 IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00006147 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006148}
6149
6150
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00006151const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006152 i::Isolate* isolate = i::Isolate::Current();
6153 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006154 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00006155 ToInternal(this)->GetEntryById(id));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006156}
6157
6158
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00006159int HeapSnapshot::GetNodesCount() const {
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00006160 i::Isolate* isolate = i::Isolate::Current();
6161 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00006162 return ToInternal(this)->entries().length();
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00006163}
6164
6165
6166const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00006167 i::Isolate* isolate = i::Isolate::Current();
6168 IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
6169 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00006170 &ToInternal(this)->entries().at(index));
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00006171}
6172
6173
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00006174SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
6175 i::Isolate* isolate = i::Isolate::Current();
6176 IsDeadCheck(isolate, "v8::HeapSnapshot::GetMaxSnapshotJSObjectId");
6177 return ToInternal(this)->max_snapshot_js_object_id();
6178}
6179
6180
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00006181void HeapSnapshot::Serialize(OutputStream* stream,
6182 HeapSnapshot::SerializationFormat format) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006183 i::Isolate* isolate = i::Isolate::Current();
6184 IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00006185 ApiCheck(format == kJSON,
6186 "v8::HeapSnapshot::Serialize",
6187 "Unknown serialization format");
6188 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
6189 "v8::HeapSnapshot::Serialize",
6190 "Unsupported output encoding");
6191 ApiCheck(stream->GetChunkSize() > 0,
6192 "v8::HeapSnapshot::Serialize",
6193 "Invalid stream chunk size");
6194 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
6195 serializer.Serialize(stream);
6196}
6197
6198
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006199int HeapProfiler::GetSnapshotsCount() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006200 i::Isolate* isolate = i::Isolate::Current();
6201 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006202 return i::HeapProfiler::GetSnapshotsCount();
6203}
6204
6205
6206const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006207 i::Isolate* isolate = i::Isolate::Current();
6208 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006209 return reinterpret_cast<const HeapSnapshot*>(
6210 i::HeapProfiler::GetSnapshot(index));
6211}
6212
6213
6214const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006215 i::Isolate* isolate = i::Isolate::Current();
6216 IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006217 return reinterpret_cast<const HeapSnapshot*>(
6218 i::HeapProfiler::FindSnapshot(uid));
6219}
6220
6221
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00006222SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Value> value) {
6223 i::Isolate* isolate = i::Isolate::Current();
6224 IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotObjectId");
6225 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
6226 return i::HeapProfiler::GetSnapshotObjectId(obj);
6227}
6228
6229
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00006230const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00006231 HeapSnapshot::Type type,
6232 ActivityControl* control) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006233 i::Isolate* isolate = i::Isolate::Current();
6234 IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00006235 i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
6236 switch (type) {
6237 case HeapSnapshot::kFull:
6238 internal_type = i::HeapSnapshot::kFull;
6239 break;
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00006240 default:
6241 UNREACHABLE();
6242 }
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006243 return reinterpret_cast<const HeapSnapshot*>(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00006244 i::HeapProfiler::TakeSnapshot(
6245 *Utils::OpenHandle(*title), internal_type, control));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00006246}
6247
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00006248
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00006249void HeapProfiler::StartHeapObjectsTracking() {
6250 i::Isolate* isolate = i::Isolate::Current();
6251 IsDeadCheck(isolate, "v8::HeapProfiler::StartHeapObjectsTracking");
6252 i::HeapProfiler::StartHeapObjectsTracking();
6253}
6254
6255
6256void HeapProfiler::StopHeapObjectsTracking() {
6257 i::Isolate* isolate = i::Isolate::Current();
6258 IsDeadCheck(isolate, "v8::HeapProfiler::StopHeapObjectsTracking");
6259 i::HeapProfiler::StopHeapObjectsTracking();
6260}
6261
6262
rossberg@chromium.org400388e2012-06-06 09:29:22 +00006263SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream) {
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00006264 i::Isolate* isolate = i::Isolate::Current();
6265 IsDeadCheck(isolate, "v8::HeapProfiler::PushHeapObjectsStats");
6266 return i::HeapProfiler::PushHeapObjectsStats(stream);
6267}
6268
6269
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006270void HeapProfiler::DeleteAllSnapshots() {
6271 i::Isolate* isolate = i::Isolate::Current();
6272 IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
6273 i::HeapProfiler::DeleteAllSnapshots();
6274}
6275
6276
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00006277void HeapProfiler::DefineWrapperClass(uint16_t class_id,
6278 WrapperInfoCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006279 i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
6280 callback);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00006281}
6282
ager@chromium.org357bf652010-04-12 11:30:10 +00006283
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00006284int HeapProfiler::GetPersistentHandleCount() {
6285 i::Isolate* isolate = i::Isolate::Current();
6286 return isolate->global_handles()->NumberOfGlobalHandles();
6287}
6288
ager@chromium.org357bf652010-04-12 11:30:10 +00006289
mmassi@chromium.org7028c052012-06-13 11:51:58 +00006290size_t HeapProfiler::GetMemorySizeUsedByProfiler() {
6291 return i::HeapProfiler::GetMemorySizeUsedByProfiler();
6292}
6293
6294
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006295v8::Testing::StressType internal::Testing::stress_type_ =
6296 v8::Testing::kStressTypeOpt;
6297
6298
6299void Testing::SetStressRunType(Testing::StressType type) {
6300 internal::Testing::set_stress_type(type);
6301}
6302
6303int Testing::GetStressRuns() {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00006304 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006305#ifdef DEBUG
6306 // In debug mode the code runs much slower so stressing will only make two
6307 // runs.
6308 return 2;
6309#else
6310 return 5;
6311#endif
6312}
6313
6314
6315static void SetFlagsFromString(const char* flags) {
6316 V8::SetFlagsFromString(flags, i::StrLength(flags));
6317}
6318
6319
6320void Testing::PrepareStressRun(int run) {
6321 static const char* kLazyOptimizations =
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00006322 "--prepare-always-opt "
6323 "--max-inlined-source-size=999999 "
6324 "--max-inlined-nodes=999999 "
6325 "--max-inlined-nodes-cumulative=999999 "
6326 "--noalways-opt";
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006327 static const char* kForcedOptimizations = "--always-opt";
6328
6329 // If deoptimization stressed turn on frequent deoptimization. If no value
6330 // is spefified through --deopt-every-n-times use a default default value.
6331 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
6332 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
6333 internal::FLAG_deopt_every_n_times == 0) {
6334 SetFlagsFromString(kDeoptEvery13Times);
6335 }
6336
6337#ifdef DEBUG
6338 // As stressing in debug mode only make two runs skip the deopt stressing
6339 // here.
6340 if (run == GetStressRuns() - 1) {
6341 SetFlagsFromString(kForcedOptimizations);
6342 } else {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006343 SetFlagsFromString(kLazyOptimizations);
6344 }
6345#else
6346 if (run == GetStressRuns() - 1) {
6347 SetFlagsFromString(kForcedOptimizations);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00006348 } else if (run != GetStressRuns() - 2) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006349 SetFlagsFromString(kLazyOptimizations);
6350 }
6351#endif
6352}
6353
6354
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00006355void Testing::DeoptimizeAll() {
6356 internal::Deoptimizer::DeoptimizeAll();
6357}
6358
6359
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006360namespace internal {
6361
6362
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00006363void HandleScopeImplementer::FreeThreadResources() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006364 Free();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00006365}
6366
6367
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006368char* HandleScopeImplementer::ArchiveThread(char* storage) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00006369 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00006370 isolate_->handle_scope_data();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006371 handle_scope_data_ = *current;
6372 memcpy(storage, this, sizeof(*this));
6373
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00006374 ResetAfterArchive();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006375 current->Initialize();
6376
6377 return storage + ArchiveSpacePerThread();
6378}
6379
6380
6381int HandleScopeImplementer::ArchiveSpacePerThread() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006382 return sizeof(HandleScopeImplementer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006383}
6384
6385
6386char* HandleScopeImplementer::RestoreThread(char* storage) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006387 memcpy(this, storage, sizeof(*this));
lrn@chromium.org1c092762011-05-09 09:42:16 +00006388 *isolate_->handle_scope_data() = handle_scope_data_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006389 return storage + ArchiveSpacePerThread();
6390}
6391
6392
ager@chromium.orga1645e22009-09-09 19:27:10 +00006393void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00006394#ifdef DEBUG
6395 bool found_block_before_deferred = false;
6396#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006397 // Iterate over all handles in the blocks except for the last.
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00006398 for (int i = blocks()->length() - 2; i >= 0; --i) {
6399 Object** block = blocks()->at(i);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00006400 if (last_handle_before_deferred_block_ != NULL &&
6401 (last_handle_before_deferred_block_ < &block[kHandleBlockSize]) &&
6402 (last_handle_before_deferred_block_ >= block)) {
6403 v->VisitPointers(block, last_handle_before_deferred_block_);
6404 ASSERT(!found_block_before_deferred);
6405#ifdef DEBUG
6406 found_block_before_deferred = true;
6407#endif
6408 } else {
6409 v->VisitPointers(block, &block[kHandleBlockSize]);
6410 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006411 }
6412
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00006413 ASSERT(last_handle_before_deferred_block_ == NULL ||
6414 found_block_before_deferred);
6415
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006416 // Iterate over live handles in the last block (if any).
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00006417 if (!blocks()->is_empty()) {
6418 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
ager@chromium.orga1645e22009-09-09 19:27:10 +00006419 }
6420
6421 if (!saved_contexts_.is_empty()) {
6422 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
6423 v->VisitPointers(start, start + saved_contexts_.length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006424 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00006425
6426 for (DeferredHandles* deferred = deferred_handles_head_;
6427 deferred != NULL;
6428 deferred = deferred->next_) {
6429 deferred->Iterate(v);
6430 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006431}
6432
6433
6434void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00006435 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00006436 isolate_->handle_scope_data();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006437 handle_scope_data_ = *current;
6438 IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006439}
6440
6441
6442char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
lrn@chromium.org7516f052011-03-30 08:52:27 +00006443 HandleScopeImplementer* scope_implementer =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006444 reinterpret_cast<HandleScopeImplementer*>(storage);
lrn@chromium.org7516f052011-03-30 08:52:27 +00006445 scope_implementer->IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006446 return storage + ArchiveSpacePerThread();
6447}
6448
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00006449
6450DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
6451 DeferredHandles* deferred = new DeferredHandles(
6452 deferred_handles_head_, isolate()->handle_scope_data()->next, this);
6453
6454 while (!blocks_.is_empty()) {
6455 Object** block_start = blocks_.last();
6456 Object** block_limit = &block_start[kHandleBlockSize];
6457 // We should not need to check for NoHandleAllocation here. Assert
6458 // this.
6459 ASSERT(prev_limit == block_limit ||
6460 !(block_start <= prev_limit && prev_limit <= block_limit));
6461 if (prev_limit == block_limit) break;
6462 deferred->blocks_.Add(blocks_.last());
6463 blocks_.RemoveLast();
6464 }
6465
6466 // deferred->blocks_ now contains the blocks installed on the
6467 // HandleScope stack since BeginDeferredScope was called, but in
6468 // reverse order.
6469
6470 ASSERT(prev_limit == NULL || !blocks_.is_empty());
6471
6472 ASSERT(!blocks_.is_empty() && prev_limit != NULL);
6473 deferred_handles_head_ = deferred;
6474 ASSERT(last_handle_before_deferred_block_ != NULL);
6475 last_handle_before_deferred_block_ = NULL;
6476 return deferred;
6477}
6478
6479
6480void HandleScopeImplementer::DestroyDeferredHandles(DeferredHandles* deferred) {
6481#ifdef DEBUG
6482 DeferredHandles* deferred_iterator = deferred;
6483 while (deferred_iterator->previous_ != NULL) {
6484 deferred_iterator = deferred_iterator->previous_;
6485 }
6486 ASSERT(deferred_handles_head_ == deferred_iterator);
6487#endif
6488 if (deferred_handles_head_ == deferred) {
6489 deferred_handles_head_ = deferred_handles_head_->next_;
6490 }
6491 if (deferred->next_ != NULL) {
6492 deferred->next_->previous_ = deferred->previous_;
6493 }
6494 if (deferred->previous_ != NULL) {
6495 deferred->previous_->next_ = deferred->next_;
6496 }
6497 for (int i = 0; i < deferred->blocks_.length(); i++) {
6498#ifdef DEBUG
6499 HandleScope::ZapRange(deferred->blocks_[i],
6500 &deferred->blocks_[i][kHandleBlockSize]);
6501#endif
6502 if (spare_ != NULL) DeleteArray(spare_);
6503 spare_ = deferred->blocks_[i];
6504 }
6505}
6506
6507
6508void HandleScopeImplementer::BeginDeferredScope() {
6509 ASSERT(last_handle_before_deferred_block_ == NULL);
6510 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
6511}
6512
6513
6514DeferredHandles::~DeferredHandles() {
6515 impl_->DestroyDeferredHandles(this);
6516}
6517
6518
6519void DeferredHandles::Iterate(ObjectVisitor* v) {
6520 ASSERT(!blocks_.is_empty());
6521
6522 ASSERT((first_block_limit_ >= blocks_.first()) &&
verwaest@chromium.org753aee42012-07-17 16:15:42 +00006523 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00006524
6525 v->VisitPointers(blocks_.first(), first_block_limit_);
6526
6527 for (int i = 1; i < blocks_.length(); i++) {
6528 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
6529 }
6530}
6531
6532
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006533} } // namespace v8::internal