blob: f5daba45d4f8c59dcfdd90f22aabc41a72a00e03 [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 <string.h> // For memcpy, strlen.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000031#include <cmath> // For isnan.
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000032#include "../include/v8-debug.h"
33#include "../include/v8-profiler.h"
34#include "../include/v8-testing.h"
rossberg@chromium.org79e79022013-06-03 15:43:46 +000035#include "assert-scope.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036#include "bootstrapper.h"
verwaest@chromium.org753aee42012-07-17 16:15:42 +000037#include "code-stubs.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038#include "compiler.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000039#include "conversions-inl.h"
40#include "counters.h"
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000041#include "cpu-profiler.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042#include "debug.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000043#include "deoptimizer.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "execution.h"
45#include "global-handles.h"
whesse@chromium.org2c186ca2010-06-16 11:32:39 +000046#include "heap-profiler.h"
ulan@chromium.org2e04b582013-02-21 14:06:02 +000047#include "heap-snapshot-generator-inl.h"
danno@chromium.org169691d2013-07-15 08:01:13 +000048#include "icu_util.h"
danno@chromium.org59400602013-08-13 17:09:37 +000049#include "json-parser.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000050#include "messages.h"
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +000051#ifdef COMPRESS_STARTUP_DATA_BZ2
52#include "natives.h"
53#endif
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000054#include "parser.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000055#include "platform.h"
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000056#include "platform/time.h"
ager@chromium.org357bf652010-04-12 11:30:10 +000057#include "profile-generator-inl.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000058#include "property-details.h"
59#include "property.h"
danno@chromium.orgca29dd82013-04-26 11:59:48 +000060#include "runtime.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000061#include "runtime-profiler.h"
ricow@chromium.org55ee8072011-09-08 16:33:10 +000062#include "scanner-character-streams.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063#include "snapshot.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000064#include "unicode-inl.h"
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +000065#include "utils/random-number-generator.h"
ager@chromium.orgddb913d2009-01-27 10:01:48 +000066#include "v8threads.h"
ager@chromium.org5ec48922009-05-05 07:25:34 +000067#include "version.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000068#include "vm-state-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000069
70
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000071#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072
danno@chromium.orgca29dd82013-04-26 11:59:48 +000073#define ENTER_V8(isolate) \
74 ASSERT((isolate)->IsInitialized()); \
75 i::VMState<i::OTHER> __state__((isolate))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000076
77namespace v8 {
78
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000079#define ON_BAILOUT(isolate, location, code) \
machenbach@chromium.orgae161032013-09-24 09:12:30 +000080 if (IsExecutionTerminatingCheck(isolate)) { \
kmillikin@chromium.org9155e252010-05-26 13:27:57 +000081 code; \
82 UNREACHABLE(); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000083 }
84
85
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000086#define EXCEPTION_PREAMBLE(isolate) \
87 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
88 ASSERT(!(isolate)->external_caught_exception()); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000089 bool has_pending_exception = false
90
91
rossberg@chromium.orgfab14982012-01-05 15:02:15 +000092#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093 do { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000094 i::HandleScopeImplementer* handle_scope_implementer = \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000095 (isolate)->handle_scope_implementer(); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000096 handle_scope_implementer->DecrementCallDepth(); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000097 if (has_pending_exception) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000098 if (handle_scope_implementer->CallDepthIsZero() && \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000099 (isolate)->is_out_of_memory()) { \
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000100 if (!(isolate)->ignore_out_of_memory()) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 i::V8::FatalProcessOutOfMemory(NULL); \
102 } \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000103 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000104 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000105 do_callback \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106 return value; \
107 } \
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000108 do_callback \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000109 } while (false)
110
111
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000112#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
113 EXCEPTION_BAILOUT_CHECK_GENERIC( \
114 isolate, value, i::V8::FireCallCompletedCallback(isolate);)
115
116
117#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
118 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
119
120
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000121#define API_ENTRY_CHECK(isolate, msg) \
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000122 do { \
123 if (v8::Locker::IsActive()) { \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000124 ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(), \
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000125 msg, \
126 "Entering the V8 API without proper locking in place"); \
127 } \
128 } while (false)
129
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000131// --- E x c e p t i o n B e h a v i o r ---
132
133
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000134static void DefaultFatalErrorHandler(const char* location,
135 const char* message) {
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000136 i::Isolate* isolate = i::Isolate::Current();
137 if (isolate->IsInitialized()) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000138 i::VMState<i::OTHER> state(isolate);
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000139 API_Fatal(location, message);
140 } else {
141 API_Fatal(location, message);
142 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000143}
144
145
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000146static FatalErrorCallback GetFatalErrorHandler() {
147 i::Isolate* isolate = i::Isolate::Current();
148 if (isolate->exception_behavior() == NULL) {
149 isolate->set_exception_behavior(DefaultFatalErrorHandler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000151 return isolate->exception_behavior();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000152}
153
154
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000155void i::FatalProcessOutOfMemory(const char* location) {
156 i::V8::FatalProcessOutOfMemory(location, false);
157}
158
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159
160// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
161// The default fatal error handler is called and execution is stopped.
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000162void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000163 i::HeapStats heap_stats;
164 int start_marker;
165 heap_stats.start_marker = &start_marker;
166 int new_space_size;
167 heap_stats.new_space_size = &new_space_size;
168 int new_space_capacity;
169 heap_stats.new_space_capacity = &new_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000170 intptr_t old_pointer_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000171 heap_stats.old_pointer_space_size = &old_pointer_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000172 intptr_t old_pointer_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000173 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000174 intptr_t old_data_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000175 heap_stats.old_data_space_size = &old_data_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000176 intptr_t old_data_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000177 heap_stats.old_data_space_capacity = &old_data_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000178 intptr_t code_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000179 heap_stats.code_space_size = &code_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000180 intptr_t code_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000181 heap_stats.code_space_capacity = &code_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000182 intptr_t map_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000183 heap_stats.map_space_size = &map_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000184 intptr_t map_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000185 heap_stats.map_space_capacity = &map_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000186 intptr_t cell_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000187 heap_stats.cell_space_size = &cell_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000188 intptr_t cell_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000189 heap_stats.cell_space_capacity = &cell_space_capacity;
danno@chromium.org41728482013-06-12 22:31:22 +0000190 intptr_t property_cell_space_size;
191 heap_stats.property_cell_space_size = &property_cell_space_size;
192 intptr_t property_cell_space_capacity;
193 heap_stats.property_cell_space_capacity = &property_cell_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000194 intptr_t lo_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000195 heap_stats.lo_space_size = &lo_space_size;
196 int global_handle_count;
197 heap_stats.global_handle_count = &global_handle_count;
198 int weak_global_handle_count;
199 heap_stats.weak_global_handle_count = &weak_global_handle_count;
200 int pending_global_handle_count;
201 heap_stats.pending_global_handle_count = &pending_global_handle_count;
202 int near_death_global_handle_count;
203 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000204 int free_global_handle_count;
205 heap_stats.free_global_handle_count = &free_global_handle_count;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000206 intptr_t memory_allocator_size;
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000207 heap_stats.memory_allocator_size = &memory_allocator_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000208 intptr_t memory_allocator_capacity;
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000209 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
210 int objects_per_type[LAST_TYPE + 1] = {0};
211 heap_stats.objects_per_type = objects_per_type;
212 int size_per_type[LAST_TYPE + 1] = {0};
213 heap_stats.size_per_type = size_per_type;
ager@chromium.orgea4f62e2010-08-16 16:28:43 +0000214 int os_error;
215 heap_stats.os_error = &os_error;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000216 int end_marker;
217 heap_stats.end_marker = &end_marker;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000218 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000219 if (isolate->heap()->HasBeenSetUp()) {
220 // BUG(1718): Don't use the take_snapshot since we don't support
221 // HeapIterator here without doing a special GC.
222 isolate->heap()->RecordStats(&heap_stats, false);
223 }
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000224 isolate->SignalFatalError();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225 FatalErrorCallback callback = GetFatalErrorHandler();
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000226 const char* message = "Allocation failed - process out of memory";
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000227 callback(location, message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000228 // If the callback returns, we stop execution.
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000229 FATAL("API fatal error handler returned after process out of memory");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230}
231
232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000233bool Utils::ReportApiFailure(const char* location, const char* message) {
234 FatalErrorCallback callback = GetFatalErrorHandler();
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000235 callback(location, message);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000236 i::Isolate* isolate = i::Isolate::Current();
237 isolate->SignalFatalError();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000238 return false;
239}
240
241
242bool V8::IsDead() {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000243 i::Isolate* isolate = i::Isolate::Current();
244 return isolate->IsDead();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000245}
246
247
248static inline bool ApiCheck(bool condition,
249 const char* location,
250 const char* message) {
251 return condition ? true : Utils::ReportApiFailure(location, message);
252}
253
254
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000255static bool ReportEmptyHandle(const char* location) {
256 FatalErrorCallback callback = GetFatalErrorHandler();
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000257 callback(location, "Reading from empty handle");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000258 return true;
259}
260
261
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000262static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
263 if (!isolate->IsInitialized()) return false;
264 if (isolate->has_scheduled_exception()) {
265 return isolate->scheduled_exception() ==
266 isolate->heap()->termination_exception();
267 }
268 return false;
269}
270
271
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
273 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
274}
275
276
ager@chromium.org32912102009-01-16 10:38:43 +0000277static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000278 return (obj == 0) ? ReportEmptyHandle(location) : false;
279}
280
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000281
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000282// --- S t a t i c s ---
283
284
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000285static bool InitializeHelper(i::Isolate* isolate) {
286 // If the isolate has a function entry hook, it needs to re-build all its
287 // code stubs with entry hooks embedded, so let's deserialize a snapshot.
288 if (isolate == NULL || isolate->function_entry_hook() == NULL) {
289 if (i::Snapshot::Initialize())
290 return true;
291 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000292 return i::V8::Initialize(NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000293}
294
295
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000296static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
297 const char* location) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000298 if (isolate != NULL) {
299 if (isolate->IsInitialized()) return true;
300 }
lrn@chromium.org1c092762011-05-09 09:42:16 +0000301 ASSERT(isolate == i::Isolate::Current());
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000302 return ApiCheck(InitializeHelper(isolate), location, "Error initializing V8");
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000303}
304
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000305
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000306// Some initializing API functions are called early and may be
307// called on a thread different from static initializer thread.
308// If Isolate API is used, Isolate::Enter() will initialize TLS so
309// Isolate::Current() works. If it's a legacy case, then the thread
310// may not have TLS initialized yet. However, in initializing APIs it
311// may be too early to call EnsureInitialized() - some pre-init
312// parameters still have to be configured.
313static inline i::Isolate* EnterIsolateIfNeeded() {
314 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
315 if (isolate != NULL)
316 return isolate;
317
318 i::Isolate::EnterDefaultIsolate();
319 isolate = i::Isolate::Current();
320 return isolate;
321}
322
323
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000324StartupDataDecompressor::StartupDataDecompressor()
325 : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
326 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
327 raw_data[i] = NULL;
328 }
329}
330
331
332StartupDataDecompressor::~StartupDataDecompressor() {
333 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
334 i::DeleteArray(raw_data[i]);
335 }
336 i::DeleteArray(raw_data);
337}
338
339
340int StartupDataDecompressor::Decompress() {
341 int compressed_data_count = V8::GetCompressedStartupDataCount();
342 StartupData* compressed_data =
343 i::NewArray<StartupData>(compressed_data_count);
344 V8::GetCompressedStartupData(compressed_data);
345 for (int i = 0; i < compressed_data_count; ++i) {
346 char* decompressed = raw_data[i] =
347 i::NewArray<char>(compressed_data[i].raw_size);
348 if (compressed_data[i].compressed_size != 0) {
349 int result = DecompressData(decompressed,
350 &compressed_data[i].raw_size,
351 compressed_data[i].data,
352 compressed_data[i].compressed_size);
353 if (result != 0) return result;
354 } else {
355 ASSERT_EQ(0, compressed_data[i].raw_size);
356 }
357 compressed_data[i].data = decompressed;
358 }
359 V8::SetDecompressedStartupData(compressed_data);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000360 i::DeleteArray(compressed_data);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000361 return 0;
362}
363
364
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000365StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
366#ifdef COMPRESS_STARTUP_DATA_BZ2
367 return StartupData::kBZip2;
368#else
369 return StartupData::kUncompressed;
370#endif
371}
372
373
374enum CompressedStartupDataItems {
375 kSnapshot = 0,
376 kSnapshotContext,
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000377 kLibraries,
378 kExperimentalLibraries,
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000379 kCompressedStartupDataCount
380};
381
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000382
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000383int V8::GetCompressedStartupDataCount() {
384#ifdef COMPRESS_STARTUP_DATA_BZ2
385 return kCompressedStartupDataCount;
386#else
387 return 0;
388#endif
389}
390
391
392void V8::GetCompressedStartupData(StartupData* compressed_data) {
393#ifdef COMPRESS_STARTUP_DATA_BZ2
394 compressed_data[kSnapshot].data =
395 reinterpret_cast<const char*>(i::Snapshot::data());
396 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
397 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
398
399 compressed_data[kSnapshotContext].data =
400 reinterpret_cast<const char*>(i::Snapshot::context_data());
401 compressed_data[kSnapshotContext].compressed_size =
402 i::Snapshot::context_size();
403 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000404
405 i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
406 compressed_data[kLibraries].data =
407 reinterpret_cast<const char*>(libraries_source.start());
408 compressed_data[kLibraries].compressed_size = libraries_source.length();
409 compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
410
411 i::Vector<const i::byte> exp_libraries_source =
412 i::ExperimentalNatives::GetScriptsSource();
413 compressed_data[kExperimentalLibraries].data =
414 reinterpret_cast<const char*>(exp_libraries_source.start());
415 compressed_data[kExperimentalLibraries].compressed_size =
416 exp_libraries_source.length();
417 compressed_data[kExperimentalLibraries].raw_size =
418 i::ExperimentalNatives::GetRawScriptsSize();
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000419#endif
420}
421
422
423void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
424#ifdef COMPRESS_STARTUP_DATA_BZ2
425 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
426 i::Snapshot::set_raw_data(
427 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
428
429 ASSERT_EQ(i::Snapshot::context_raw_size(),
430 decompressed_data[kSnapshotContext].raw_size);
431 i::Snapshot::set_context_raw_data(
432 reinterpret_cast<const i::byte*>(
433 decompressed_data[kSnapshotContext].data));
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000434
435 ASSERT_EQ(i::Natives::GetRawScriptsSize(),
436 decompressed_data[kLibraries].raw_size);
437 i::Vector<const char> libraries_source(
438 decompressed_data[kLibraries].data,
439 decompressed_data[kLibraries].raw_size);
440 i::Natives::SetRawScriptsSource(libraries_source);
441
442 ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
443 decompressed_data[kExperimentalLibraries].raw_size);
444 i::Vector<const char> exp_libraries_source(
445 decompressed_data[kExperimentalLibraries].data,
446 decompressed_data[kExperimentalLibraries].raw_size);
447 i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000448#endif
449}
450
451
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000452void V8::SetFatalErrorHandler(FatalErrorCallback that) {
453 i::Isolate* isolate = EnterIsolateIfNeeded();
454 isolate->set_exception_behavior(that);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000455}
456
457
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000458void V8::SetAllowCodeGenerationFromStringsCallback(
459 AllowCodeGenerationFromStringsCallback callback) {
460 i::Isolate* isolate = EnterIsolateIfNeeded();
461 isolate->set_allow_code_gen_callback(callback);
462}
463
464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465void V8::SetFlagsFromString(const char* str, int length) {
466 i::FlagList::SetFlagsFromString(str, length);
467}
468
469
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000470void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
471 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
472}
473
474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000475v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000476 return v8::Isolate::GetCurrent()->ThrowException(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477}
478
479
480RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
481
482
483RegisteredExtension::RegisteredExtension(Extension* extension)
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000484 : extension_(extension) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000485
486
487void RegisteredExtension::Register(RegisteredExtension* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000488 that->next_ = first_extension_;
489 first_extension_ = that;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000490}
491
492
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000493void RegisteredExtension::UnregisterAll() {
494 RegisteredExtension* re = first_extension_;
495 while (re != NULL) {
496 RegisteredExtension* next = re->next();
497 delete re;
498 re = next;
499 }
500}
501
502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503void RegisterExtension(Extension* that) {
504 RegisteredExtension* extension = new RegisteredExtension(that);
505 RegisteredExtension::Register(extension);
506}
507
508
509Extension::Extension(const char* name,
510 const char* source,
511 int dep_count,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000512 const char** deps,
513 int source_length)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514 : name_(name),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000515 source_length_(source_length >= 0 ?
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000516 source_length :
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000517 (source ? static_cast<int>(strlen(source)) : 0)),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000518 source_(source, source_length_),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000519 dep_count_(dep_count),
520 deps_(deps),
danno@chromium.org412fa512012-09-14 13:28:26 +0000521 auto_enable_(false) {
522 CHECK(source != NULL || source_length_ == 0);
523}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524
525
526v8::Handle<Primitive> Undefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000527 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000528 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
529 return v8::Handle<v8::Primitive>();
530 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000531 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000532}
533
534
535v8::Handle<Primitive> Null() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000536 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000537 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
538 return v8::Handle<v8::Primitive>();
539 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000540 return ToApiHandle<Primitive>(isolate->factory()->null_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000541}
542
543
544v8::Handle<Boolean> True() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000545 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000546 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
547 return v8::Handle<Boolean>();
548 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000549 return ToApiHandle<Boolean>(isolate->factory()->true_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550}
551
552
553v8::Handle<Boolean> False() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000554 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000555 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
556 return v8::Handle<Boolean>();
557 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000558 return ToApiHandle<Boolean>(isolate->factory()->false_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000559}
560
561
562ResourceConstraints::ResourceConstraints()
563 : max_young_space_size_(0),
564 max_old_space_size_(0),
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000565 max_executable_size_(0),
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000566 stack_limit_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567
568
569bool SetResourceConstraints(ResourceConstraints* constraints) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000570 i::Isolate* isolate = EnterIsolateIfNeeded();
571
ager@chromium.org3811b432009-10-28 14:53:37 +0000572 int young_space_size = constraints->max_young_space_size();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000573 int old_gen_size = constraints->max_old_space_size();
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000574 int max_executable_size = constraints->max_executable_size();
575 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000576 // After initialization it's too late to change Heap constraints.
577 ASSERT(!isolate->IsInitialized());
578 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
579 old_gen_size,
580 max_executable_size);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000581 if (!result) return false;
582 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000583 if (constraints->stack_limit() != NULL) {
584 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000585 isolate->stack_guard()->SetStackLimit(limit);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586 }
587 return true;
588}
589
590
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000591i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000592 LOG_API(isolate, "Persistent::New");
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000593 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000594#ifdef DEBUG
595 (*obj)->Verify();
596#endif // DEBUG
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000597 return result.location();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000598}
599
600
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000601i::Object** V8::CopyPersistent(i::Object** obj) {
602 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
603#ifdef DEBUG
604 (*obj)->Verify();
605#endif // DEBUG
606 return result.location();
607}
608
609
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000610void V8::MakeWeak(i::Object** object,
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000611 void* parameters,
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000612 WeakCallback weak_callback,
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000613 RevivableCallback weak_reference_callback) {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000614 i::GlobalHandles::MakeWeak(object,
615 parameters,
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000616 weak_callback,
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000617 weak_reference_callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618}
619
620
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000621void V8::ClearWeak(i::Object** obj) {
622 i::GlobalHandles::ClearWeakness(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000626void V8::DisposeGlobal(i::Object** obj) {
627 i::GlobalHandles::Destroy(obj);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000628}
629
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000630
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000631void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
632 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
633 i::Object* object = *Utils::OpenHandle(value);
634 isolate->eternal_handles()->Create(isolate, object, index);
danno@chromium.org59400602013-08-13 17:09:37 +0000635}
636
637
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000638Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
639 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
640 return Utils::ToLocal(isolate->eternal_handles()->Get(index));
danno@chromium.org59400602013-08-13 17:09:37 +0000641}
642
643
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644// --- H a n d l e s ---
645
646
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000647HandleScope::HandleScope(Isolate* isolate) {
648 Initialize(isolate);
649}
650
651
652void HandleScope::Initialize(Isolate* isolate) {
653 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
654 API_ENTRY_CHECK(internal_isolate, "HandleScope::HandleScope");
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000655 v8::ImplementationUtilities::HandleScopeData* current =
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000656 internal_isolate->handle_scope_data();
657 isolate_ = internal_isolate;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000658 prev_next_ = current->next;
659 prev_limit_ = current->limit;
660 is_closed_ = false;
661 current->level++;
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000662}
663
664
665HandleScope::~HandleScope() {
666 if (!is_closed_) {
lrn@chromium.org303ada72010-10-27 09:33:13 +0000667 Leave();
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000668 }
669}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670
671
lrn@chromium.org303ada72010-10-27 09:33:13 +0000672void HandleScope::Leave() {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000673 return i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000674}
675
676
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000677int HandleScope::NumberOfHandles() {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000678 i::Isolate* isolate = i::Isolate::Current();
679 if (!EnsureInitializedForIsolate(isolate, "HandleScope::NumberOfHandles")) {
680 return 0;
681 }
682 return i::HandleScope::NumberOfHandles(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000683}
684
685
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000686i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000687 return i::HandleScope::CreateHandle(isolate, value);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000688}
689
690
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000691i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
692 i::Object* value) {
693 ASSERT(heap_object->IsHeapObject());
694 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
695}
696
697
698EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
699 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
700 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
701 Initialize(v8_isolate);
702}
703
704
705i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
706 ApiCheck(*escape_slot_ == isolate_->heap()->the_hole_value(),
707 "EscapeableHandleScope::Escape",
708 "Escape value set twice");
709 if (escape_value == NULL) {
710 *escape_slot_ = isolate_->heap()->undefined_value();
711 return NULL;
712 }
713 *escape_slot_ = *escape_value;
714 return escape_slot_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000715}
716
717
718void Context::Enter() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000719 i::Handle<i::Context> env = Utils::OpenHandle(this);
720 i::Isolate* isolate = env->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000721 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000722 isolate->handle_scope_implementer()->EnterContext(env);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000723 isolate->handle_scope_implementer()->SaveContext(isolate->context());
724 isolate->set_context(*env);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000725}
726
727
728void Context::Exit() {
machenbach@chromium.orgae161032013-09-24 09:12:30 +0000729 // TODO(dcarney): fix this once chrome is fixed.
730 i::Isolate* isolate = i::Isolate::Current();
731 i::Handle<i::Context> context = i::Handle<i::Context>::null();
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000732 ENTER_V8(isolate);
733 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveContext(context),
kasper.lund44510672008-07-25 07:37:58 +0000734 "v8::Context::Exit()",
735 "Cannot exit non-entered context")) {
736 return;
737 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000738 // Content of 'last_context' could be NULL.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000739 i::Context* last_context =
740 isolate->handle_scope_implementer()->RestoreContext();
741 isolate->set_context(last_context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742}
743
744
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000745static void* DecodeSmiToAligned(i::Object* value, const char* location) {
746 ApiCheck(value->IsSmi(), location, "Not a Smi");
747 return reinterpret_cast<void*>(value);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000748}
749
750
mstarzinger@chromium.org0c977e02013-07-26 10:45:47 +0000751static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
752 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000753 ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
754 return smi;
755}
756
757
758static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
759 int index,
760 bool can_grow,
761 const char* location) {
762 i::Handle<i::Context> env = Utils::OpenHandle(context);
machenbach@chromium.orgae161032013-09-24 09:12:30 +0000763 bool ok =
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000764 ApiCheck(env->IsNativeContext(), location, "Not a native context") &&
765 ApiCheck(index >= 0, location, "Negative index");
766 if (!ok) return i::Handle<i::FixedArray>();
767 i::Handle<i::FixedArray> data(env->embedder_data());
768 if (index < data->length()) return data;
769 if (!can_grow) {
770 Utils::ReportApiFailure(location, "Index too large");
771 return i::Handle<i::FixedArray>();
svenpanne@chromium.orgfc2a4f42012-11-07 09:25:55 +0000772 }
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000773 int new_size = i::Max(index, data->length() << 1) + 1;
774 data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size);
775 env->set_embedder_data(*data);
776 return data;
777}
778
779
780v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
781 const char* location = "v8::Context::GetEmbedderData()";
782 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
783 if (data.is_null()) return Local<Value>();
784 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
ager@chromium.org9085a012009-05-11 19:22:57 +0000785 return Utils::ToLocal(result);
786}
787
788
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000789void Context::SetEmbedderData(int index, v8::Handle<Value> value) {
790 const char* location = "v8::Context::SetEmbedderData()";
791 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
792 if (data.is_null()) return;
793 i::Handle<i::Object> val = Utils::OpenHandle(*value);
794 data->set(index, *val);
795 ASSERT_EQ(*Utils::OpenHandle(*value),
796 *Utils::OpenHandle(*GetEmbedderData(index)));
797}
798
799
800void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
801 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
802 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
803 if (data.is_null()) return NULL;
804 return DecodeSmiToAligned(data->get(index), location);
805}
806
807
808void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
809 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
810 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
811 data->set(index, EncodeAlignedAsSmi(value, location));
812 ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index));
813}
814
815
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000816i::Object** v8::HandleScope::RawClose(i::Object** value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000817 if (!ApiCheck(!is_closed_,
818 "v8::HandleScope::Close()",
819 "Local scope has already been closed")) {
820 return 0;
821 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000822 LOG_API(isolate_, "CloseHandleScope");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000823
824 // Read the result before popping the handle block.
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000825 i::Object* result = NULL;
826 if (value != NULL) {
827 result = *value;
828 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000829 is_closed_ = true;
lrn@chromium.org303ada72010-10-27 09:33:13 +0000830 Leave();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000831
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000832 if (value == NULL) {
833 return NULL;
834 }
835
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 // Allocate a new handle on the previous handle block.
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000837 i::Handle<i::Object> handle(result, isolate_);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000838 return handle.location();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000839}
840
841
842// --- N e a n d e r ---
843
844
845// A constructor cannot easily return an error value, therefore it is necessary
846// to check for a dead VM with ON_BAILOUT before constructing any Neander
847// objects. To remind you about this there is no HandleScope in the
848// NeanderObject constructor. When you add one to the site calling the
849// constructor you should check that you ensured the VM was not dead first.
850NeanderObject::NeanderObject(int size) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000851 i::Isolate* isolate = i::Isolate::Current();
852 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
853 ENTER_V8(isolate);
854 value_ = isolate->factory()->NewNeanderObject();
855 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000856 value_->set_elements(*elements);
857}
858
859
860int NeanderObject::size() {
861 return i::FixedArray::cast(value_->elements())->length();
862}
863
864
865NeanderArray::NeanderArray() : obj_(2) {
866 obj_.set(0, i::Smi::FromInt(0));
867}
868
869
870int NeanderArray::length() {
871 return i::Smi::cast(obj_.get(0))->value();
872}
873
874
875i::Object* NeanderArray::get(int offset) {
876 ASSERT(0 <= offset);
877 ASSERT(offset < length());
878 return obj_.get(offset + 1);
879}
880
881
882// This method cannot easily return an error value, therefore it is necessary
883// to check for a dead VM with ON_BAILOUT before calling it. To remind you
884// about this there is no HandleScope in this method. When you add one to the
885// site calling this method you should check that you ensured the VM was not
886// dead first.
887void NeanderArray::add(i::Handle<i::Object> value) {
888 int length = this->length();
889 int size = obj_.size();
890 if (length == size - 1) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000891 i::Factory* factory = i::Isolate::Current()->factory();
892 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000893 for (int i = 0; i < length; i++)
894 new_elms->set(i + 1, get(i));
895 obj_.value()->set_elements(*new_elms);
896 }
897 obj_.set(length + 1, *value);
898 obj_.set(0, i::Smi::FromInt(length + 1));
899}
900
901
902void NeanderArray::set(int index, i::Object* value) {
903 if (index < 0 || index >= this->length()) return;
904 obj_.set(index + 1, value);
905}
906
907
908// --- T e m p l a t e ---
909
910
911static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
912 that->set_tag(i::Smi::FromInt(type));
913}
914
915
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000916static void TemplateSet(i::Isolate* isolate,
917 v8::Template* templ,
918 int length,
919 v8::Handle<v8::Data>* data) {
920 i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
921 if (list->IsUndefined()) {
922 list = NeanderArray().value();
923 Utils::OpenHandle(templ)->set_property_list(*list);
924 }
925 NeanderArray array(list);
926 array.add(Utils::OpenHandle(*v8::Integer::New(length)));
927 for (int i = 0; i < length; i++) {
928 i::Handle<i::Object> value = data[i].IsEmpty() ?
929 i::Handle<i::Object>(isolate->factory()->undefined_value()) :
930 Utils::OpenHandle(*data[i]);
931 array.add(value);
932 }
933}
934
935
936void Template::Set(v8::Handle<String> name,
937 v8::Handle<Data> value,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000938 v8::PropertyAttribute attribute) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000939 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000940 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000941 i::HandleScope scope(isolate);
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000942 const int kSize = 3;
943 v8::Handle<v8::Data> data[kSize] = {
944 name,
945 value,
946 v8::Integer::New(attribute)};
947 TemplateSet(isolate, this, kSize, data);
948}
949
950
951void Template::SetAccessorProperty(
952 v8::Local<v8::String> name,
953 v8::Local<FunctionTemplate> getter,
954 v8::Local<FunctionTemplate> setter,
955 v8::PropertyAttribute attribute,
956 v8::AccessControl access_control) {
957 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000958 ENTER_V8(isolate);
959 ASSERT(!name.IsEmpty());
960 ASSERT(!getter.IsEmpty() || !setter.IsEmpty());
961 i::HandleScope scope(isolate);
962 const int kSize = 5;
963 v8::Handle<v8::Data> data[kSize] = {
964 name,
965 getter,
966 setter,
967 v8::Integer::New(attribute),
968 v8::Integer::New(access_control)};
969 TemplateSet(isolate, this, kSize, data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970}
971
972
973// --- F u n c t i o n T e m p l a t e ---
974static void InitializeFunctionTemplate(
975 i::Handle<i::FunctionTemplateInfo> info) {
976 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
977 info->set_flag(0);
978}
979
980
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000981Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000982 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000983 ENTER_V8(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000984 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
985 isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986 if (result->IsUndefined()) {
987 result = Utils::OpenHandle(*ObjectTemplate::New());
988 Utils::OpenHandle(this)->set_prototype_template(*result);
989 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000990 return ToApiHandle<ObjectTemplate>(result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000991}
992
993
994void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000995 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000996 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000997 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
998}
999
1000
dslomov@chromium.org639bac02013-09-09 11:58:54 +00001001static Local<FunctionTemplate> FunctionTemplateNew(
1002 i::Isolate* isolate,
1003 FunctionCallback callback,
1004 v8::Handle<Value> data,
1005 v8::Handle<Signature> signature,
1006 int length,
1007 bool do_not_cache) {
1008 i::Handle<i::Struct> struct_obj =
1009 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
1010 i::Handle<i::FunctionTemplateInfo> obj =
1011 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1012 InitializeFunctionTemplate(obj);
1013 obj->set_do_not_cache(do_not_cache);
1014 int next_serial_number = 0;
1015 if (!do_not_cache) {
1016 next_serial_number = isolate->next_serial_number() + 1;
1017 isolate->set_next_serial_number(next_serial_number);
1018 }
1019 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
1020 if (callback != 0) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001021 if (data.IsEmpty()) {
1022 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1023 }
dslomov@chromium.org639bac02013-09-09 11:58:54 +00001024 Utils::ToLocal(obj)->SetCallHandler(callback, data);
1025 }
1026 obj->set_length(length);
1027 obj->set_undetectable(false);
1028 obj->set_needs_access_check(false);
1029 if (!signature.IsEmpty())
1030 obj->set_signature(*Utils::OpenHandle(*signature));
1031 return Utils::ToLocal(obj);
1032}
1033
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001034Local<FunctionTemplate> FunctionTemplate::New(
1035 FunctionCallback callback,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001036 v8::Handle<Value> data,
1037 v8::Handle<Signature> signature,
1038 int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001039 i::Isolate* isolate = i::Isolate::Current();
1040 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
1041 LOG_API(isolate, "FunctionTemplate::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001042 ENTER_V8(isolate);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00001043 return FunctionTemplateNew(
1044 isolate, callback, data, signature, length, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045}
1046
1047
1048Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
1049 int argc, Handle<FunctionTemplate> argv[]) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001050 i::Isolate* isolate = i::Isolate::Current();
1051 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
1052 LOG_API(isolate, "Signature::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001053 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001054 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001055 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056 i::Handle<i::SignatureInfo> obj =
1057 i::Handle<i::SignatureInfo>::cast(struct_obj);
1058 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
1059 if (argc > 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001060 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061 for (int i = 0; i < argc; i++) {
1062 if (!argv[i].IsEmpty())
1063 args->set(i, *Utils::OpenHandle(*argv[i]));
1064 }
1065 obj->set_args(*args);
1066 }
1067 return Utils::ToLocal(obj);
1068}
1069
1070
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001071Local<AccessorSignature> AccessorSignature::New(
1072 Handle<FunctionTemplate> receiver) {
1073 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1074}
1075
1076
ulan@chromium.org750145a2013-03-07 15:14:13 +00001077template<typename Operation>
1078static Local<Operation> NewDescriptor(
1079 Isolate* isolate,
1080 const i::DeclaredAccessorDescriptorData& data,
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001081 Data* previous_descriptor) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001082 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
1083 i::Handle<i::DeclaredAccessorDescriptor> previous =
1084 i::Handle<i::DeclaredAccessorDescriptor>();
1085 if (previous_descriptor != NULL) {
1086 previous = Utils::OpenHandle(
1087 static_cast<DeclaredAccessorDescriptor*>(previous_descriptor));
1088 }
1089 i::Handle<i::DeclaredAccessorDescriptor> descriptor =
1090 i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001091 return Utils::Convert<i::DeclaredAccessorDescriptor, Operation>(descriptor);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001092}
1093
1094
1095Local<RawOperationDescriptor>
1096 ObjectOperationDescriptor::NewInternalFieldDereference(
1097 Isolate* isolate,
1098 int internal_field) {
1099 i::DeclaredAccessorDescriptorData data;
1100 data.type = i::kDescriptorObjectDereference;
1101 data.object_dereference_descriptor.internal_field = internal_field;
1102 return NewDescriptor<RawOperationDescriptor>(isolate, data, NULL);
1103}
1104
1105
1106Local<RawOperationDescriptor> RawOperationDescriptor::NewRawShift(
1107 Isolate* isolate,
1108 int16_t byte_offset) {
1109 i::DeclaredAccessorDescriptorData data;
1110 data.type = i::kDescriptorPointerShift;
1111 data.pointer_shift_descriptor.byte_offset = byte_offset;
1112 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1113}
1114
1115
1116Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewHandleDereference(
1117 Isolate* isolate) {
1118 i::DeclaredAccessorDescriptorData data;
1119 data.type = i::kDescriptorReturnObject;
1120 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1121}
1122
1123
1124Local<RawOperationDescriptor> RawOperationDescriptor::NewRawDereference(
1125 Isolate* isolate) {
1126 i::DeclaredAccessorDescriptorData data;
1127 data.type = i::kDescriptorPointerDereference;
1128 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1129}
1130
1131
1132Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPointerCompare(
1133 Isolate* isolate,
1134 void* compare_value) {
1135 i::DeclaredAccessorDescriptorData data;
1136 data.type = i::kDescriptorPointerCompare;
1137 data.pointer_compare_descriptor.compare_value = compare_value;
1138 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1139}
1140
1141
1142Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPrimitiveValue(
1143 Isolate* isolate,
1144 DeclaredAccessorDescriptorDataType data_type,
1145 uint8_t bool_offset) {
1146 i::DeclaredAccessorDescriptorData data;
1147 data.type = i::kDescriptorPrimitiveValue;
1148 data.primitive_value_descriptor.data_type = data_type;
1149 data.primitive_value_descriptor.bool_offset = bool_offset;
1150 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1151}
1152
1153
1154template<typename T>
1155static Local<DeclaredAccessorDescriptor> NewBitmaskCompare(
1156 Isolate* isolate,
1157 T bitmask,
1158 T compare_value,
1159 RawOperationDescriptor* operation) {
1160 i::DeclaredAccessorDescriptorData data;
1161 data.type = i::kDescriptorBitmaskCompare;
1162 data.bitmask_compare_descriptor.bitmask = bitmask;
1163 data.bitmask_compare_descriptor.compare_value = compare_value;
1164 data.bitmask_compare_descriptor.size = sizeof(T);
1165 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, operation);
1166}
1167
1168
1169Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare8(
1170 Isolate* isolate,
1171 uint8_t bitmask,
1172 uint8_t compare_value) {
1173 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1174}
1175
1176
1177Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare16(
1178 Isolate* isolate,
1179 uint16_t bitmask,
1180 uint16_t compare_value) {
1181 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1182}
1183
1184
1185Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare32(
1186 Isolate* isolate,
1187 uint32_t bitmask,
1188 uint32_t compare_value) {
1189 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1190}
1191
1192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
1194 Handle<FunctionTemplate> types[1] = { type };
1195 return TypeSwitch::New(1, types);
1196}
1197
1198
1199Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001200 i::Isolate* isolate = i::Isolate::Current();
1201 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
1202 LOG_API(isolate, "TypeSwitch::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001203 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001204 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001205 for (int i = 0; i < argc; i++)
1206 vector->set(i, *Utils::OpenHandle(*types[i]));
1207 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001208 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001209 i::Handle<i::TypeSwitchInfo> obj =
1210 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
1211 obj->set_types(*vector);
1212 return Utils::ToLocal(obj);
1213}
1214
1215
1216int TypeSwitch::match(v8::Handle<Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001217 i::Isolate* isolate = i::Isolate::Current();
1218 LOG_API(isolate, "TypeSwitch::match");
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001219 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001220 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
1221 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
1222 i::FixedArray* types = i::FixedArray::cast(info->types());
1223 for (int i = 0; i < types->length(); i++) {
1224 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
1225 return i + 1;
1226 }
1227 return 0;
1228}
1229
1230
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001231#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00001232 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001233 (obj)->setter(*foreign); \
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001234 } while (false)
1235
1236
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001237void FunctionTemplate::SetCallHandler(FunctionCallback callback,
1238 v8::Handle<Value> data) {
1239 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001240 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001241 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001242 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001243 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244 i::Handle<i::CallHandlerInfo> obj =
1245 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001246 SET_FIELD_WRAPPED(obj, set_callback, callback);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001247 if (data.IsEmpty()) {
1248 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1249 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001250 obj->set_data(*Utils::OpenHandle(*data));
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001251 Utils::OpenHandle(this)->set_call_code(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001252}
1253
1254
ulan@chromium.org750145a2013-03-07 15:14:13 +00001255static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1256 i::Handle<i::AccessorInfo> obj,
1257 v8::Handle<String> name,
1258 v8::AccessControl settings,
1259 v8::PropertyAttribute attributes,
1260 v8::Handle<AccessorSignature> signature) {
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001261 obj->set_name(*Utils::OpenHandle(*name));
1262 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1263 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1264 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
1265 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001266 if (!signature.IsEmpty()) {
1267 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1268 }
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001269 return obj;
1270}
1271
1272
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001273template<typename Getter, typename Setter>
ulan@chromium.org750145a2013-03-07 15:14:13 +00001274static i::Handle<i::AccessorInfo> MakeAccessorInfo(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275 v8::Handle<String> name,
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001276 Getter getter,
1277 Setter setter,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001278 v8::Handle<Value> data,
1279 v8::AccessControl settings,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001280 v8::PropertyAttribute attributes,
1281 v8::Handle<AccessorSignature> signature) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001282 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1283 i::Handle<i::ExecutableAccessorInfo> obj =
1284 isolate->factory()->NewExecutableAccessorInfo();
1285 SET_FIELD_WRAPPED(obj, set_getter, getter);
1286 SET_FIELD_WRAPPED(obj, set_setter, setter);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001287 if (data.IsEmpty()) {
1288 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1289 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00001290 obj->set_data(*Utils::OpenHandle(*data));
1291 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1292}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001293
ulan@chromium.org750145a2013-03-07 15:14:13 +00001294
1295static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1296 v8::Handle<String> name,
1297 v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001298 void* setter_ignored,
1299 void* data_ignored,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001300 v8::AccessControl settings,
1301 v8::PropertyAttribute attributes,
1302 v8::Handle<AccessorSignature> signature) {
1303 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1304 if (descriptor.IsEmpty()) return i::Handle<i::DeclaredAccessorInfo>();
1305 i::Handle<i::DeclaredAccessorInfo> obj =
1306 isolate->factory()->NewDeclaredAccessorInfo();
1307 obj->set_descriptor(*Utils::OpenHandle(*descriptor));
1308 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001309}
1310
1311
1312Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001313 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00001314 if (EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001315 return Local<ObjectTemplate>();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001316 ENTER_V8(isolate);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001317 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this);
1318 if (handle->instance_template()->IsUndefined()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319 Local<ObjectTemplate> templ =
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001320 ObjectTemplate::New(ToApiHandle<FunctionTemplate>(handle));
1321 handle->set_instance_template(*Utils::OpenHandle(*templ));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001322 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001323 i::Handle<i::ObjectTemplateInfo> result(
1324 i::ObjectTemplateInfo::cast(handle->instance_template()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001325 return Utils::ToLocal(result);
1326}
1327
1328
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001329void FunctionTemplate::SetLength(int length) {
1330 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001331 ENTER_V8(isolate);
1332 Utils::OpenHandle(this)->set_length(length);
1333}
1334
1335
kasper.lund212ac232008-07-16 07:07:30 +00001336void FunctionTemplate::SetClassName(Handle<String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001337 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001338 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001339 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1340}
1341
1342
1343void FunctionTemplate::SetHiddenPrototype(bool value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001344 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001345 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001346 Utils::OpenHandle(this)->set_hidden_prototype(value);
1347}
1348
1349
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001350void FunctionTemplate::ReadOnlyPrototype() {
ager@chromium.org04921a82011-06-27 13:21:41 +00001351 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ager@chromium.org04921a82011-06-27 13:21:41 +00001352 ENTER_V8(isolate);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001353 Utils::OpenHandle(this)->set_read_only_prototype(true);
ager@chromium.org04921a82011-06-27 13:21:41 +00001354}
1355
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001356
1357void FunctionTemplate::RemovePrototype() {
1358 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001359 ENTER_V8(isolate);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001360 Utils::OpenHandle(this)->set_remove_prototype(true);
kasper.lund212ac232008-07-16 07:07:30 +00001361}
1362
1363
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001364// --- O b j e c t T e m p l a t e ---
1365
1366
1367Local<ObjectTemplate> ObjectTemplate::New() {
1368 return New(Local<FunctionTemplate>());
1369}
1370
1371
1372Local<ObjectTemplate> ObjectTemplate::New(
1373 v8::Handle<FunctionTemplate> constructor) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001374 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001375 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1376 LOG_API(isolate, "ObjectTemplate::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001377 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001378 i::Handle<i::Struct> struct_obj =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001379 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 i::Handle<i::ObjectTemplateInfo> obj =
1381 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1382 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1383 if (!constructor.IsEmpty())
1384 obj->set_constructor(*Utils::OpenHandle(*constructor));
kasper.lund212ac232008-07-16 07:07:30 +00001385 obj->set_internal_field_count(i::Smi::FromInt(0));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001386 return Utils::ToLocal(obj);
1387}
1388
1389
1390// Ensure that the object template has a constructor. If no
1391// constructor is available we create one.
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001392static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1393 ObjectTemplate* object_template) {
1394 i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1395 if (!obj ->IsUndefined()) {
1396 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1397 return i::Handle<i::FunctionTemplateInfo>(info, info->GetIsolate());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398 }
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001399 Local<FunctionTemplate> templ = FunctionTemplate::New();
1400 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1401 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1402 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1403 return constructor;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001404}
1405
1406
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001407static inline void AddPropertyToTemplate(
1408 i::Handle<i::TemplateInfo> info,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001409 i::Handle<i::AccessorInfo> obj) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001410 i::Handle<i::Object> list(info->property_accessors(), info->GetIsolate());
ulan@chromium.org750145a2013-03-07 15:14:13 +00001411 if (list->IsUndefined()) {
1412 list = NeanderArray().value();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001413 info->set_property_accessors(*list);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001414 }
1415 NeanderArray array(list);
1416 array.add(obj);
1417}
1418
1419
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001420static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1421 Template* template_obj) {
1422 return Utils::OpenHandle(template_obj);
1423}
1424
1425
1426// TODO(dcarney): remove this with ObjectTemplate::SetAccessor
1427static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1428 ObjectTemplate* object_template) {
1429 EnsureConstructor(object_template);
1430 return Utils::OpenHandle(object_template);
1431}
1432
1433
1434template<typename Setter, typename Getter, typename Data, typename Template>
1435static bool TemplateSetAccessor(
1436 Template* template_obj,
1437 v8::Local<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001438 Getter getter,
1439 Setter setter,
1440 Data data,
1441 AccessControl settings,
1442 PropertyAttribute attribute,
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001443 v8::Local<AccessorSignature> signature) {
1444 i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001445 ENTER_V8(isolate);
1446 i::HandleScope scope(isolate);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001447 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
1448 name, getter, setter, data, settings, attribute, signature);
1449 if (obj.is_null()) return false;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001450 i::Handle<i::TemplateInfo> info = GetTemplateInfo(template_obj);
1451 AddPropertyToTemplate(info, obj);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001452 return true;
1453}
1454
1455
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001456bool Template::SetDeclaredAccessor(
1457 Local<String> name,
1458 Local<DeclaredAccessorDescriptor> descriptor,
1459 PropertyAttribute attribute,
1460 Local<AccessorSignature> signature,
1461 AccessControl settings) {
1462 void* null = NULL;
1463 return TemplateSetAccessor(
1464 this, name, descriptor, null, null, settings, attribute, signature);
1465}
1466
1467
1468void Template::SetNativeDataProperty(v8::Local<String> name,
1469 AccessorGetterCallback getter,
1470 AccessorSetterCallback setter,
1471 v8::Handle<Value> data,
1472 PropertyAttribute attribute,
1473 v8::Local<AccessorSignature> signature,
1474 AccessControl settings) {
1475 TemplateSetAccessor(
1476 this, name, getter, setter, data, settings, attribute, signature);
1477}
1478
1479
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001480void ObjectTemplate::SetAccessor(v8::Handle<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001481 AccessorGetterCallback getter,
1482 AccessorSetterCallback setter,
1483 v8::Handle<Value> data,
1484 AccessControl settings,
1485 PropertyAttribute attribute,
1486 v8::Handle<AccessorSignature> signature) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001487 TemplateSetAccessor(
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001488 this, name, getter, setter, data, settings, attribute, signature);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001489}
1490
1491
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001492void ObjectTemplate::SetNamedPropertyHandler(
1493 NamedPropertyGetterCallback getter,
1494 NamedPropertySetterCallback setter,
1495 NamedPropertyQueryCallback query,
1496 NamedPropertyDeleterCallback remover,
1497 NamedPropertyEnumeratorCallback enumerator,
1498 Handle<Value> data) {
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001499 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001500 ENTER_V8(isolate);
1501 i::HandleScope scope(isolate);
1502 EnsureConstructor(this);
1503 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1504 Utils::OpenHandle(this)->constructor());
1505 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1506 i::Handle<i::Struct> struct_obj =
1507 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1508 i::Handle<i::InterceptorInfo> obj =
1509 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1510
1511 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1512 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1513 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1514 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1515 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1516
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001517 if (data.IsEmpty()) {
1518 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1519 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001520 obj->set_data(*Utils::OpenHandle(*data));
1521 cons->set_named_property_handler(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001522}
1523
1524
1525void ObjectTemplate::MarkAsUndetectable() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001526 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001527 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001528 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001529 EnsureConstructor(this);
1530 i::FunctionTemplateInfo* constructor =
1531 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1532 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1533 cons->set_undetectable(true);
1534}
1535
1536
1537void ObjectTemplate::SetAccessCheckCallbacks(
1538 NamedSecurityCallback named_callback,
1539 IndexedSecurityCallback indexed_callback,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001540 Handle<Value> data,
1541 bool turned_on_by_default) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001542 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001543 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001544 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001545 EnsureConstructor(this);
1546
1547 i::Handle<i::Struct> struct_info =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001548 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001549 i::Handle<i::AccessCheckInfo> info =
1550 i::Handle<i::AccessCheckInfo>::cast(struct_info);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001551
1552 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1553 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1554
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001555 if (data.IsEmpty()) {
1556 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1557 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001558 info->set_data(*Utils::OpenHandle(*data));
1559
1560 i::FunctionTemplateInfo* constructor =
1561 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1562 i::Handle<i::FunctionTemplateInfo> cons(constructor);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001563 cons->set_access_check_info(*info);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001564 cons->set_needs_access_check(turned_on_by_default);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001565}
1566
1567
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001568void ObjectTemplate::SetIndexedPropertyHandler(
1569 IndexedPropertyGetterCallback getter,
1570 IndexedPropertySetterCallback setter,
1571 IndexedPropertyQueryCallback query,
1572 IndexedPropertyDeleterCallback remover,
1573 IndexedPropertyEnumeratorCallback enumerator,
1574 Handle<Value> data) {
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001575 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001576 ENTER_V8(isolate);
1577 i::HandleScope scope(isolate);
1578 EnsureConstructor(this);
1579 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1580 Utils::OpenHandle(this)->constructor());
1581 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1582 i::Handle<i::Struct> struct_obj =
1583 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1584 i::Handle<i::InterceptorInfo> obj =
1585 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1586
1587 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1588 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1589 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1590 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1591 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1592
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001593 if (data.IsEmpty()) {
1594 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1595 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001596 obj->set_data(*Utils::OpenHandle(*data));
1597 cons->set_indexed_property_handler(*obj);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001598}
1599
1600
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001601void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1602 Handle<Value> data) {
1603 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001604 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001605 i::HandleScope scope(isolate);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001606 EnsureConstructor(this);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001607 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001608 Utils::OpenHandle(this)->constructor());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609 i::Handle<i::FunctionTemplateInfo> cons(constructor);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001610 i::Handle<i::Struct> struct_obj =
1611 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1612 i::Handle<i::CallHandlerInfo> obj =
1613 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1614 SET_FIELD_WRAPPED(obj, set_callback, callback);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001615 if (data.IsEmpty()) {
1616 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1617 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001618 obj->set_data(*Utils::OpenHandle(*data));
1619 cons->set_instance_call_handler(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620}
1621
1622
kasper.lund212ac232008-07-16 07:07:30 +00001623int ObjectTemplate::InternalFieldCount() {
kasper.lund212ac232008-07-16 07:07:30 +00001624 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625}
1626
1627
kasper.lund212ac232008-07-16 07:07:30 +00001628void ObjectTemplate::SetInternalFieldCount(int value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001629 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
kasper.lund212ac232008-07-16 07:07:30 +00001630 if (!ApiCheck(i::Smi::IsValid(value),
1631 "v8::ObjectTemplate::SetInternalFieldCount()",
1632 "Invalid internal field count")) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001633 return;
1634 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001635 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001636 if (value > 0) {
1637 // The internal field count is set by the constructor function's
1638 // construct code, so we ensure that there is a constructor
1639 // function to do the setting.
1640 EnsureConstructor(this);
1641 }
kasper.lund212ac232008-07-16 07:07:30 +00001642 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001643}
1644
1645
kasper.lund212ac232008-07-16 07:07:30 +00001646// --- S c r i p t D a t a ---
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001647
1648
1649ScriptData* ScriptData::PreCompile(const char* input, int length) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001650 i::Utf8ToUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001651 reinterpret_cast<const unsigned char*>(input), length);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001652 return i::PreParserApi::PreParse(i::Isolate::Current(), &stream);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001653}
1654
1655
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001656ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1657 i::Handle<i::String> str = Utils::OpenHandle(*source);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001658 i::Isolate* isolate = str->GetIsolate();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001659 if (str->IsExternalTwoByteString()) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001660 i::ExternalTwoByteStringUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001661 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001662 return i::PreParserApi::PreParse(isolate, &stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001663 } else {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001664 i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001665 return i::PreParserApi::PreParse(isolate, &stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001666 }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001667}
1668
1669
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001670ScriptData* ScriptData::New(const char* data, int length) {
1671 // Return an empty ScriptData if the length is obviously invalid.
1672 if (length % sizeof(unsigned) != 0) {
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001673 return new i::ScriptDataImpl();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001674 }
1675
1676 // Copy the data to ensure it is properly aligned.
1677 int deserialized_data_length = length / sizeof(unsigned);
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001678 // If aligned, don't create a copy of the data.
1679 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1680 return new i::ScriptDataImpl(data, length);
1681 }
1682 // Copy the data to align it.
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001683 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001684 i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
1685 data, static_cast<size_t>(length));
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001686
1687 return new i::ScriptDataImpl(
1688 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001689}
1690
1691
1692// --- S c r i p t ---
1693
1694
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001695Local<Script> Script::New(v8::Handle<String> source,
1696 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001697 v8::ScriptData* pre_data,
1698 v8::Handle<String> script_data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001699 i::Isolate* isolate = i::Isolate::Current();
1700 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1701 LOG_API(isolate, "Script::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001702 ENTER_V8(isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001703 i::SharedFunctionInfo* raw_result = NULL;
1704 { i::HandleScope scope(isolate);
1705 i::Handle<i::String> str = Utils::OpenHandle(*source);
1706 i::Handle<i::Object> name_obj;
1707 int line_offset = 0;
1708 int column_offset = 0;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001709 bool is_shared_cross_origin = false;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001710 if (origin != NULL) {
1711 if (!origin->ResourceName().IsEmpty()) {
1712 name_obj = Utils::OpenHandle(*origin->ResourceName());
1713 }
1714 if (!origin->ResourceLineOffset().IsEmpty()) {
1715 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1716 }
1717 if (!origin->ResourceColumnOffset().IsEmpty()) {
1718 column_offset =
1719 static_cast<int>(origin->ResourceColumnOffset()->Value());
1720 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001721 if (!origin->ResourceIsSharedCrossOrigin().IsEmpty()) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001722 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001723 is_shared_cross_origin =
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001724 origin->ResourceIsSharedCrossOrigin() == v8::True(v8_isolate);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001725 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001726 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001727 EXCEPTION_PREAMBLE(isolate);
1728 i::ScriptDataImpl* pre_data_impl =
1729 static_cast<i::ScriptDataImpl*>(pre_data);
1730 // We assert that the pre-data is sane, even though we can actually
1731 // handle it if it turns out not to be in release mode.
1732 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
1733 // If the pre-data isn't sane we simply ignore it
1734 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1735 pre_data_impl = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001737 i::Handle<i::SharedFunctionInfo> result =
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001738 i::Compiler::Compile(str,
1739 name_obj,
1740 line_offset,
1741 column_offset,
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001742 is_shared_cross_origin,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001743 isolate->global_context(),
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001744 NULL,
1745 pre_data_impl,
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00001746 Utils::OpenHandle(*script_data, true),
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001747 i::NOT_NATIVES_CODE);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001748 has_pending_exception = result.is_null();
1749 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
1750 raw_result = *result;
1751 }
1752 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001753 return ToApiHandle<Script>(result);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001754}
1755
1756
1757Local<Script> Script::New(v8::Handle<String> source,
1758 v8::Handle<Value> file_name) {
1759 ScriptOrigin origin(file_name);
1760 return New(source, &origin);
1761}
1762
1763
1764Local<Script> Script::Compile(v8::Handle<String> source,
1765 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001766 v8::ScriptData* pre_data,
1767 v8::Handle<String> script_data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001768 i::Isolate* isolate = i::Isolate::Current();
1769 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1770 LOG_API(isolate, "Script::Compile");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001771 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00001772 Local<Script> generic = New(source, origin, pre_data, script_data);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001773 if (generic.IsEmpty())
1774 return generic;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001775 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1776 i::Handle<i::SharedFunctionInfo> function =
1777 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778 i::Handle<i::JSFunction> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001779 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1780 function,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001781 isolate->global_context());
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001782 return ToApiHandle<Script>(result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783}
1784
1785
mads.s.agercbaa0602008-08-14 13:41:48 +00001786Local<Script> Script::Compile(v8::Handle<String> source,
ager@chromium.org5c838252010-02-19 08:53:10 +00001787 v8::Handle<Value> file_name,
1788 v8::Handle<String> script_data) {
mads.s.agercbaa0602008-08-14 13:41:48 +00001789 ScriptOrigin origin(file_name);
ager@chromium.org5c838252010-02-19 08:53:10 +00001790 return Compile(source, &origin, 0, script_data);
mads.s.agercbaa0602008-08-14 13:41:48 +00001791}
1792
1793
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794Local<Value> Script::Run() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001795 i::Isolate* isolate = i::Isolate::Current();
1796 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1797 LOG_API(isolate, "Script::Run");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001798 ENTER_V8(isolate);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001799 i::Logger::TimerEventScope timer_scope(
danno@chromium.org1f34ad32012-11-26 14:53:56 +00001800 isolate, i::Logger::TimerEventScope::v8_execute);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801 i::Object* raw_result = NULL;
1802 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001803 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001804 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1805 i::Handle<i::JSFunction> fun;
1806 if (obj->IsSharedFunctionInfo()) {
1807 i::Handle<i::SharedFunctionInfo>
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001808 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001809 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001810 function_info, isolate->global_context());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001811 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001812 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001813 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001814 EXCEPTION_PREAMBLE(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815 i::Handle<i::Object> receiver(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001816 isolate->context()->global_proxy(), isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00001817 i::Handle<i::Object> result = i::Execution::Call(
1818 isolate, fun, receiver, 0, NULL, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00001819 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820 raw_result = *result;
1821 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001822 i::Handle<i::Object> result(raw_result, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001823 return Utils::ToLocal(result);
1824}
1825
1826
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001827static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1828 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1829 i::Handle<i::SharedFunctionInfo> result;
1830 if (obj->IsSharedFunctionInfo()) {
1831 result =
1832 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1833 } else {
1834 result =
1835 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1836 }
1837 return result;
1838}
1839
1840
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001841Local<Value> Script::Id() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 i::Isolate* isolate = i::Isolate::Current();
1843 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1844 LOG_API(isolate, "Script::Id");
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001845 i::Object* raw_id = NULL;
1846 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001847 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001848 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1849 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00001850 i::Handle<i::Object> id(script->id(), isolate);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001851 raw_id = *id;
1852 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00001853 i::Handle<i::Object> id(raw_id, isolate);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001854 return Utils::ToLocal(id);
1855}
1856
1857
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001858int Script::GetId() {
1859 i::Isolate* isolate = i::Isolate::Current();
1860 ON_BAILOUT(isolate, "v8::Script::Id()", return -1);
1861 LOG_API(isolate, "Script::Id");
1862 {
1863 i::HandleScope scope(isolate);
1864 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1865 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1866 return script->id()->value();
1867 }
1868}
1869
1870
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001871int Script::GetLineNumber(int code_pos) {
1872 i::Isolate* isolate = i::Isolate::Current();
1873 ON_BAILOUT(isolate, "v8::Script::GetLineNumber()", return -1);
1874 LOG_API(isolate, "Script::GetLineNumber");
1875 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1876 if (obj->IsScript()) {
1877 i::Handle<i::Script> script = i::Handle<i::Script>(i::Script::cast(*obj));
1878 return i::GetScriptLineNumber(script, code_pos);
1879 } else {
1880 return -1;
1881 }
1882}
1883
1884
1885Handle<Value> Script::GetScriptName() {
1886 i::Isolate* isolate = i::Isolate::Current();
1887 ON_BAILOUT(isolate, "v8::Script::GetName()", return Handle<String>());
1888 LOG_API(isolate, "Script::GetName");
1889 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1890 if (obj->IsScript()) {
1891 i::Object* name = i::Script::cast(*obj)->name();
1892 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1893 } else {
1894 return Handle<String>();
1895 }
1896}
1897
1898
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00001899void Script::SetData(v8::Handle<String> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001900 i::Isolate* isolate = i::Isolate::Current();
1901 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1902 LOG_API(isolate, "Script::SetData");
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001903 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001904 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001905 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001906 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001907 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001908 script->set_data(*raw_data);
1909 }
1910}
1911
1912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913// --- E x c e p t i o n s ---
1914
1915
1916v8::TryCatch::TryCatch()
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001917 : isolate_(i::Isolate::Current()),
1918 next_(isolate_->try_catch_handler_address()),
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001919 is_verbose_(false),
ager@chromium.org68e7ab72009-09-23 09:40:39 +00001920 can_continue_(true),
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001921 capture_message_(true),
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001922 rethrow_(false),
1923 has_terminated_(false) {
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001924 Reset();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001925 isolate_->RegisterTryCatchHandler(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001926}
1927
1928
1929v8::TryCatch::~TryCatch() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001930 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001931 if (rethrow_) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001932 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
1933 v8::HandleScope scope(isolate);
1934 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001935 if (HasCaught() && capture_message_) {
1936 // If an exception was caught and rethrow_ is indicated, the saved
1937 // message, script, and location need to be restored to Isolate TLS
1938 // for reuse. capture_message_ needs to be disabled so that DoThrow()
1939 // does not create a new message.
1940 isolate_->thread_local_top()->rethrowing_message_ = true;
1941 isolate_->RestorePendingMessageFromTryCatch(this);
1942 }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001943 isolate_->UnregisterTryCatchHandler(this);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001944 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001945 ASSERT(!isolate_->thread_local_top()->rethrowing_message_);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001946 } else {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001947 isolate_->UnregisterTryCatchHandler(this);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001948 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001949}
1950
1951
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001952bool v8::TryCatch::HasCaught() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001953 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1954}
1955
1956
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001957bool v8::TryCatch::CanContinue() const {
1958 return can_continue_;
1959}
1960
1961
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001962bool v8::TryCatch::HasTerminated() const {
1963 return has_terminated_;
1964}
1965
1966
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001967v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1968 if (!HasCaught()) return v8::Local<v8::Value>();
1969 rethrow_ = true;
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001970 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001971}
1972
1973
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001974v8::Local<Value> v8::TryCatch::Exception() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001975 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001976 if (HasCaught()) {
1977 // Check for out of memory exception.
1978 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001979 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001980 } else {
1981 return v8::Local<Value>();
1982 }
1983}
1984
1985
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001986v8::Local<Value> v8::TryCatch::StackTrace() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001987 ASSERT(isolate_ == i::Isolate::Current());
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001988 if (HasCaught()) {
1989 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1990 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001991 i::HandleScope scope(isolate_);
1992 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001993 i::Handle<i::String> name = isolate_->factory()->stack_string();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00001994 if (!i::JSReceiver::HasProperty(obj, name)) return v8::Local<Value>();
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00001995 i::Handle<i::Object> value = i::GetProperty(isolate_, obj, name);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001996 if (value.is_null()) return v8::Local<Value>();
1997 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001998 } else {
1999 return v8::Local<Value>();
2000 }
2001}
2002
2003
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002004v8::Local<v8::Message> v8::TryCatch::Message() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002005 ASSERT(isolate_ == i::Isolate::Current());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00002006 i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2007 ASSERT(message->IsJSMessageObject() || message->IsTheHole());
2008 if (HasCaught() && !message->IsTheHole()) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002009 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002010 } else {
2011 return v8::Local<v8::Message>();
2012 }
2013}
2014
2015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016void v8::TryCatch::Reset() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002017 ASSERT(isolate_ == i::Isolate::Current());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00002018 i::Object* the_hole = isolate_->heap()->the_hole_value();
2019 exception_ = the_hole;
2020 message_obj_ = the_hole;
2021 message_script_ = the_hole;
2022 message_start_pos_ = 0;
2023 message_end_pos_ = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002024}
2025
2026
2027void v8::TryCatch::SetVerbose(bool value) {
2028 is_verbose_ = value;
2029}
2030
2031
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002032void v8::TryCatch::SetCaptureMessage(bool value) {
2033 capture_message_ = value;
2034}
2035
2036
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002037// --- M e s s a g e ---
2038
2039
ager@chromium.org32912102009-01-16 10:38:43 +00002040Local<String> Message::Get() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002041 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002042 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002043 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002044 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045 i::Handle<i::Object> obj = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002046 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002047 Local<String> result = Utils::ToLocal(raw_result);
2048 return scope.Close(result);
2049}
2050
2051
ager@chromium.org32912102009-01-16 10:38:43 +00002052v8::Handle<Value> Message::GetScriptResourceName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002053 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002054 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002055 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002056 i::Handle<i::JSMessageObject> message =
2057 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002058 // Return this.script.name.
2059 i::Handle<i::JSValue> script =
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002060 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2061 isolate));
2062 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name(),
2063 isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002064 return scope.Close(Utils::ToLocal(resource_name));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002065}
2066
2067
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002068v8::Handle<Value> Message::GetScriptData() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002069 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002070 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002071 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002072 i::Handle<i::JSMessageObject> message =
2073 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002074 // Return this.script.data.
2075 i::Handle<i::JSValue> script =
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002076 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2077 isolate));
2078 i::Handle<i::Object> data(i::Script::cast(script->value())->data(), isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002079 return scope.Close(Utils::ToLocal(data));
2080}
2081
2082
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002083v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002084 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002085 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002086 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002087 i::Handle<i::JSMessageObject> message =
2088 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002089 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002090 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
2091 i::Handle<i::JSArray> stackTrace =
2092 i::Handle<i::JSArray>::cast(stackFramesObj);
2093 return scope.Close(Utils::StackTraceToLocal(stackTrace));
2094}
2095
2096
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002097static i::Handle<i::Object> CallV8HeapFunction(const char* name,
2098 i::Handle<i::Object> recv,
2099 int argc,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002100 i::Handle<i::Object> argv[],
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101 bool* has_pending_exception) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002102 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002103 i::Handle<i::String> fmt_str =
2104 isolate->factory()->InternalizeUtf8String(name);
lrn@chromium.org303ada72010-10-27 09:33:13 +00002105 i::Object* object_fun =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002106 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107 i::Handle<i::JSFunction> fun =
2108 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00002109 i::Handle<i::Object> value = i::Execution::Call(
2110 isolate, fun, recv, argc, argv, has_pending_exception);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002111 return value;
2112}
2113
2114
2115static i::Handle<i::Object> CallV8HeapFunction(const char* name,
2116 i::Handle<i::Object> data,
2117 bool* has_pending_exception) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002118 i::Handle<i::Object> argv[] = { data };
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119 return CallV8HeapFunction(name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002120 i::Isolate::Current()->js_builtins_object(),
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002121 ARRAY_SIZE(argv),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122 argv,
2123 has_pending_exception);
2124}
2125
2126
ager@chromium.org32912102009-01-16 10:38:43 +00002127int Message::GetLineNumber() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002128 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002129 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002130 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002131 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002132
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002133 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
2135 Utils::OpenHandle(this),
2136 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002137 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138 return static_cast<int>(result->Number());
2139}
2140
2141
ager@chromium.org32912102009-01-16 10:38:43 +00002142int Message::GetStartPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002143 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002144 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002145 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002146 i::Handle<i::JSMessageObject> message =
2147 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2148 return message->start_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002149}
2150
2151
ager@chromium.org32912102009-01-16 10:38:43 +00002152int Message::GetEndPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002153 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002154 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002155 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002156 i::Handle<i::JSMessageObject> message =
2157 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2158 return message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002159}
2160
2161
ager@chromium.org32912102009-01-16 10:38:43 +00002162int Message::GetStartColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002163 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002164 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002165 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002166 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002167 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002168 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
2169 "GetPositionInLine",
2170 data_obj,
2171 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002172 EXCEPTION_BAILOUT_CHECK(isolate, 0);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002173 return static_cast<int>(start_col_obj->Number());
2174}
2175
2176
ager@chromium.org32912102009-01-16 10:38:43 +00002177int Message::GetEndColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002178 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002179 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002180 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002181 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002182 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002183 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
2184 "GetPositionInLine",
2185 data_obj,
2186 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002187 EXCEPTION_BAILOUT_CHECK(isolate, 0);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002188 i::Handle<i::JSMessageObject> message =
2189 i::Handle<i::JSMessageObject>::cast(data_obj);
2190 int start = message->start_position();
2191 int end = message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002192 return static_cast<int>(start_col_obj->Number()) + (end - start);
2193}
2194
2195
danno@chromium.orgd3c42102013-08-01 16:58:23 +00002196bool Message::IsSharedCrossOrigin() const {
2197 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
danno@chromium.orgd3c42102013-08-01 16:58:23 +00002198 ENTER_V8(isolate);
2199 i::HandleScope scope(isolate);
2200 i::Handle<i::JSMessageObject> message =
2201 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2202 i::Handle<i::JSValue> script =
2203 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2204 isolate));
2205 return i::Script::cast(script->value())->is_shared_cross_origin();
2206}
2207
2208
ager@chromium.org32912102009-01-16 10:38:43 +00002209Local<String> Message::GetSourceLine() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002210 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002211 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002212 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002213 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002214 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002215 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
2216 Utils::OpenHandle(this),
2217 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002218 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002219 if (result->IsString()) {
2220 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
2221 } else {
2222 return Local<String>();
2223 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002224}
2225
2226
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227void Message::PrintCurrentStackTrace(FILE* out) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002228 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002229 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002230 isolate->PrintCurrentStackTrace(out);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231}
2232
2233
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002234// --- S t a c k T r a c e ---
2235
2236Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002237 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002238 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002239 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002240 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00002241 i::Object* raw_object = self->GetElementNoExceptionThrown(isolate, index);
lrn@chromium.org303ada72010-10-27 09:33:13 +00002242 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002243 return scope.Close(Utils::StackFrameToLocal(obj));
2244}
2245
2246
2247int StackTrace::GetFrameCount() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002248 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002249 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002250 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2251}
2252
2253
2254Local<Array> StackTrace::AsArray() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002255 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002256 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002257 return Utils::ToLocal(Utils::OpenHandle(this));
2258}
2259
2260
2261Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
2262 StackTraceOptions options) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002263 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002264 ENTER_V8(isolate);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002265 i::Handle<i::JSArray> stackTrace =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002266 isolate->CaptureCurrentStackTrace(frame_limit, options);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002267 return Utils::StackTraceToLocal(stackTrace);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002268}
2269
2270
2271// --- S t a c k F r a m e ---
2272
2273int StackFrame::GetLineNumber() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002274 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002275 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002276 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002277 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2278 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
2279 if (!line->IsSmi()) {
2280 return Message::kNoLineNumberInfo;
2281 }
2282 return i::Smi::cast(*line)->value();
2283}
2284
2285
2286int StackFrame::GetColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002287 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002288 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002289 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002290 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2291 i::Handle<i::Object> column = GetProperty(self, "column");
2292 if (!column->IsSmi()) {
2293 return Message::kNoColumnInfo;
2294 }
2295 return i::Smi::cast(*column)->value();
2296}
2297
2298
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00002299int StackFrame::GetScriptId() const {
2300 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00002301 ENTER_V8(isolate);
2302 i::HandleScope scope(isolate);
2303 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2304 i::Handle<i::Object> scriptId = GetProperty(self, "scriptId");
2305 if (!scriptId->IsSmi()) {
2306 return Message::kNoScriptIdInfo;
2307 }
2308 return i::Smi::cast(*scriptId)->value();
2309}
2310
2311
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002312Local<String> StackFrame::GetScriptName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002313 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002314 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002315 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002316 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2317 i::Handle<i::Object> name = GetProperty(self, "scriptName");
2318 if (!name->IsString()) {
2319 return Local<String>();
2320 }
2321 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2322}
2323
2324
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002325Local<String> StackFrame::GetScriptNameOrSourceURL() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002326 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002327 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002328 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002329 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2330 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
2331 if (!name->IsString()) {
2332 return Local<String>();
2333 }
2334 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2335}
2336
2337
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002338Local<String> StackFrame::GetFunctionName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002339 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002340 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002341 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002342 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2343 i::Handle<i::Object> name = GetProperty(self, "functionName");
2344 if (!name->IsString()) {
2345 return Local<String>();
2346 }
2347 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2348}
2349
2350
2351bool StackFrame::IsEval() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002352 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002353 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002354 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002355 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2356 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
2357 return is_eval->IsTrue();
2358}
2359
2360
2361bool StackFrame::IsConstructor() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002362 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002363 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002364 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002365 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2366 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
2367 return is_constructor->IsTrue();
2368}
2369
2370
danno@chromium.org59400602013-08-13 17:09:37 +00002371// --- J S O N ---
2372
2373Local<Value> JSON::Parse(Local<String> json_string) {
2374 i::Isolate* isolate = i::Isolate::Current();
2375 EnsureInitializedForIsolate(isolate, "v8::JSON::Parse");
2376 ENTER_V8(isolate);
2377 i::HandleScope scope(isolate);
2378 i::Handle<i::String> source = i::Handle<i::String>(
2379 FlattenGetString(Utils::OpenHandle(*json_string)));
2380 EXCEPTION_PREAMBLE(isolate);
2381 i::Handle<i::Object> result;
2382 if (source->IsSeqOneByteString()) {
2383 result = i::JsonParser<true>::Parse(source);
2384 } else {
2385 result = i::JsonParser<false>::Parse(source);
2386 }
2387 has_pending_exception = result.is_null();
2388 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
2389 return Utils::ToLocal(
2390 i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
2391}
2392
2393
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002394// --- D a t a ---
2395
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002396bool Value::FullIsUndefined() const {
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002397 bool result = Utils::OpenHandle(this)->IsUndefined();
2398 ASSERT_EQ(result, QuickIsUndefined());
2399 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002400}
2401
2402
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002403bool Value::FullIsNull() const {
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002404 bool result = Utils::OpenHandle(this)->IsNull();
2405 ASSERT_EQ(result, QuickIsNull());
2406 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002407}
2408
2409
ager@chromium.org32912102009-01-16 10:38:43 +00002410bool Value::IsTrue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411 return Utils::OpenHandle(this)->IsTrue();
2412}
2413
2414
ager@chromium.org32912102009-01-16 10:38:43 +00002415bool Value::IsFalse() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002416 return Utils::OpenHandle(this)->IsFalse();
2417}
2418
2419
ager@chromium.org32912102009-01-16 10:38:43 +00002420bool Value::IsFunction() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421 return Utils::OpenHandle(this)->IsJSFunction();
2422}
2423
2424
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002425bool Value::FullIsString() const {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002426 bool result = Utils::OpenHandle(this)->IsString();
2427 ASSERT_EQ(result, QuickIsString());
2428 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002429}
2430
2431
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002432bool Value::IsSymbol() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002433 return Utils::OpenHandle(this)->IsSymbol();
2434}
2435
2436
ager@chromium.org32912102009-01-16 10:38:43 +00002437bool Value::IsArray() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002438 return Utils::OpenHandle(this)->IsJSArray();
2439}
2440
2441
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002442bool Value::IsArrayBuffer() const {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002443 return Utils::OpenHandle(this)->IsJSArrayBuffer();
2444}
2445
2446
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002447bool Value::IsArrayBufferView() const {
2448 return Utils::OpenHandle(this)->IsJSArrayBufferView();
2449}
2450
2451
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002452bool Value::IsTypedArray() const {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002453 return Utils::OpenHandle(this)->IsJSTypedArray();
2454}
2455
2456
2457#define TYPED_ARRAY_LIST(F) \
2458F(Uint8Array, kExternalUnsignedByteArray) \
2459F(Int8Array, kExternalByteArray) \
2460F(Uint16Array, kExternalUnsignedShortArray) \
2461F(Int16Array, kExternalShortArray) \
2462F(Uint32Array, kExternalUnsignedIntArray) \
2463F(Int32Array, kExternalIntArray) \
2464F(Float32Array, kExternalFloatArray) \
2465F(Float64Array, kExternalDoubleArray) \
2466F(Uint8ClampedArray, kExternalPixelArray)
2467
2468
2469#define VALUE_IS_TYPED_ARRAY(TypedArray, type_const) \
2470 bool Value::Is##TypedArray() const { \
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002471 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2472 if (!obj->IsJSTypedArray()) return false; \
2473 return i::JSTypedArray::cast(*obj)->type() == type_const; \
2474 }
2475
2476TYPED_ARRAY_LIST(VALUE_IS_TYPED_ARRAY)
2477
2478#undef VALUE_IS_TYPED_ARRAY
2479
2480
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002481bool Value::IsDataView() const {
2482 return Utils::OpenHandle(this)->IsJSDataView();
2483}
2484
2485
ager@chromium.org32912102009-01-16 10:38:43 +00002486bool Value::IsObject() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002487 return Utils::OpenHandle(this)->IsJSObject();
2488}
2489
2490
ager@chromium.org32912102009-01-16 10:38:43 +00002491bool Value::IsNumber() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002492 return Utils::OpenHandle(this)->IsNumber();
2493}
2494
2495
ager@chromium.org32912102009-01-16 10:38:43 +00002496bool Value::IsBoolean() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497 return Utils::OpenHandle(this)->IsBoolean();
2498}
2499
2500
ager@chromium.org32912102009-01-16 10:38:43 +00002501bool Value::IsExternal() const {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002502 return Utils::OpenHandle(this)->IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002503}
2504
2505
ager@chromium.org32912102009-01-16 10:38:43 +00002506bool Value::IsInt32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002507 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2508 if (obj->IsSmi()) return true;
2509 if (obj->IsNumber()) {
2510 double value = obj->Number();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002511 static const i::DoubleRepresentation minus_zero(-0.0);
2512 i::DoubleRepresentation rep(value);
2513 if (rep.bits == minus_zero.bits) {
2514 return false;
2515 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002516 return i::FastI2D(i::FastD2I(value)) == value;
2517 }
2518 return false;
2519}
2520
2521
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002522bool Value::IsUint32() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002523 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2524 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2525 if (obj->IsNumber()) {
2526 double value = obj->Number();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002527 static const i::DoubleRepresentation minus_zero(-0.0);
2528 i::DoubleRepresentation rep(value);
2529 if (rep.bits == minus_zero.bits) {
2530 return false;
2531 }
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002532 return i::FastUI2D(i::FastD2UI(value)) == value;
2533 }
2534 return false;
2535}
2536
2537
ager@chromium.org32912102009-01-16 10:38:43 +00002538bool Value::IsDate() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002539 i::Isolate* isolate = i::Isolate::Current();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002540 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002541 return obj->HasSpecificClassOf(isolate->heap()->Date_string());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002542}
2543
2544
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002545bool Value::IsStringObject() const {
2546 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002547 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002548 return obj->HasSpecificClassOf(isolate->heap()->String_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002549}
2550
2551
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002552bool Value::IsSymbolObject() const {
2553 // TODO(svenpanne): these and other test functions should be written such
2554 // that they do not use Isolate::Current().
2555 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002556 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2557 return obj->HasSpecificClassOf(isolate->heap()->Symbol_string());
2558}
2559
2560
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002561bool Value::IsNumberObject() const {
2562 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002563 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002564 return obj->HasSpecificClassOf(isolate->heap()->Number_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002565}
2566
2567
2568static i::Object* LookupBuiltin(i::Isolate* isolate,
2569 const char* builtin_name) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002570 i::Handle<i::String> string =
2571 isolate->factory()->InternalizeUtf8String(builtin_name);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002572 i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002573 return builtins->GetPropertyNoExceptionThrown(*string);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002574}
2575
2576
2577static bool CheckConstructor(i::Isolate* isolate,
2578 i::Handle<i::JSObject> obj,
2579 const char* class_name) {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002580 i::Object* constr = obj->map()->constructor();
2581 if (!constr->IsJSFunction()) return false;
2582 i::JSFunction* func = i::JSFunction::cast(constr);
2583 return func->shared()->native() &&
2584 constr == LookupBuiltin(isolate, class_name);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002585}
2586
2587
2588bool Value::IsNativeError() const {
2589 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002590 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2591 if (obj->IsJSObject()) {
2592 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
2593 return CheckConstructor(isolate, js_obj, "$Error") ||
2594 CheckConstructor(isolate, js_obj, "$EvalError") ||
2595 CheckConstructor(isolate, js_obj, "$RangeError") ||
2596 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2597 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2598 CheckConstructor(isolate, js_obj, "$TypeError") ||
2599 CheckConstructor(isolate, js_obj, "$URIError");
2600 } else {
2601 return false;
2602 }
2603}
2604
2605
2606bool Value::IsBooleanObject() const {
2607 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002608 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002609 return obj->HasSpecificClassOf(isolate->heap()->Boolean_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002610}
2611
2612
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002613bool Value::IsRegExp() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002614 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2615 return obj->IsJSRegExp();
2616}
2617
2618
ager@chromium.org32912102009-01-16 10:38:43 +00002619Local<String> Value::ToString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002620 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2621 i::Handle<i::Object> str;
2622 if (obj->IsString()) {
2623 str = obj;
2624 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002625 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002626 LOG_API(isolate, "ToString");
2627 ENTER_V8(isolate);
2628 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002629 str = i::Execution::ToString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002630 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002631 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002632 return ToApiHandle<String>(str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002633}
2634
2635
ager@chromium.org32912102009-01-16 10:38:43 +00002636Local<String> Value::ToDetailString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002637 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2638 i::Handle<i::Object> str;
2639 if (obj->IsString()) {
2640 str = obj;
2641 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002642 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002643 LOG_API(isolate, "ToDetailString");
2644 ENTER_V8(isolate);
2645 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002646 str = i::Execution::ToDetailString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002647 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002648 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002649 return ToApiHandle<String>(str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002650}
2651
2652
ager@chromium.org32912102009-01-16 10:38:43 +00002653Local<v8::Object> Value::ToObject() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002654 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2655 i::Handle<i::Object> val;
2656 if (obj->IsJSObject()) {
2657 val = obj;
2658 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002659 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002660 LOG_API(isolate, "ToObject");
2661 ENTER_V8(isolate);
2662 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002663 val = i::Execution::ToObject(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002664 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002666 return ToApiHandle<Object>(val);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002667}
2668
2669
ager@chromium.org32912102009-01-16 10:38:43 +00002670Local<Boolean> Value::ToBoolean() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002671 i::Handle<i::Object> obj = Utils::OpenHandle(this);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002672 if (obj->IsBoolean()) {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002673 return ToApiHandle<Boolean>(obj);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002674 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002675 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002676 LOG_API(isolate, "ToBoolean");
2677 ENTER_V8(isolate);
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +00002678 i::Handle<i::Object> val =
2679 isolate->factory()->ToBoolean(obj->BooleanValue());
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002680 return ToApiHandle<Boolean>(val);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002681 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002682}
2683
2684
ager@chromium.org32912102009-01-16 10:38:43 +00002685Local<Number> Value::ToNumber() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002686 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2687 i::Handle<i::Object> num;
2688 if (obj->IsNumber()) {
2689 num = obj;
2690 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002691 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002692 LOG_API(isolate, "ToNumber");
2693 ENTER_V8(isolate);
2694 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002695 num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002696 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002697 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002698 return ToApiHandle<Number>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002699}
2700
2701
ager@chromium.org32912102009-01-16 10:38:43 +00002702Local<Integer> Value::ToInteger() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002703 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2704 i::Handle<i::Object> num;
2705 if (obj->IsSmi()) {
2706 num = obj;
2707 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002708 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002709 LOG_API(isolate, "ToInteger");
2710 ENTER_V8(isolate);
2711 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002712 num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002713 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002714 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002715 return ToApiHandle<Integer>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002716}
2717
2718
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00002719void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002720 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002721 ApiCheck(isolate != NULL && isolate->IsInitialized() && !isolate->IsDead(),
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002722 "v8::internal::Internals::CheckInitialized()",
2723 "Isolate is not initialized or V8 has died");
2724}
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002725
2726
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002727void External::CheckCast(v8::Value* that) {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002728 ApiCheck(Utils::OpenHandle(that)->IsExternal(),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002729 "v8::External::Cast()",
2730 "Could not convert to external");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002731}
2732
2733
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002734void v8::Object::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002735 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2736 ApiCheck(obj->IsJSObject(),
2737 "v8::Object::Cast()",
2738 "Could not convert to object");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002739}
2740
2741
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002742void v8::Function::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002743 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2744 ApiCheck(obj->IsJSFunction(),
2745 "v8::Function::Cast()",
2746 "Could not convert to function");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002747}
2748
2749
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002750void v8::String::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002751 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2752 ApiCheck(obj->IsString(),
2753 "v8::String::Cast()",
2754 "Could not convert to string");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002755}
2756
2757
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002758void v8::Symbol::CheckCast(v8::Value* that) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002759 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2760 ApiCheck(obj->IsSymbol(),
2761 "v8::Symbol::Cast()",
2762 "Could not convert to symbol");
2763}
2764
2765
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002766void v8::Number::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002767 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2768 ApiCheck(obj->IsNumber(),
2769 "v8::Number::Cast()",
2770 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771}
2772
2773
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002774void v8::Integer::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002775 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2776 ApiCheck(obj->IsNumber(),
2777 "v8::Integer::Cast()",
2778 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779}
2780
2781
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002782void v8::Array::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002783 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2784 ApiCheck(obj->IsJSArray(),
2785 "v8::Array::Cast()",
2786 "Could not convert to array");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002787}
2788
2789
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002790void v8::ArrayBuffer::CheckCast(Value* that) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002791 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2792 ApiCheck(obj->IsJSArrayBuffer(),
2793 "v8::ArrayBuffer::Cast()",
2794 "Could not convert to ArrayBuffer");
2795}
2796
2797
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002798void v8::ArrayBufferView::CheckCast(Value* that) {
2799 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2800 ApiCheck(obj->IsJSArrayBufferView(),
2801 "v8::ArrayBufferView::Cast()",
2802 "Could not convert to ArrayBufferView");
2803}
2804
2805
danno@chromium.orgf005df62013-04-30 16:36:45 +00002806void v8::TypedArray::CheckCast(Value* that) {
danno@chromium.orgf005df62013-04-30 16:36:45 +00002807 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2808 ApiCheck(obj->IsJSTypedArray(),
2809 "v8::TypedArray::Cast()",
2810 "Could not convert to TypedArray");
2811}
2812
2813
2814#define CHECK_TYPED_ARRAY_CAST(ApiClass, typeConst) \
2815 void v8::ApiClass::CheckCast(Value* that) { \
danno@chromium.orgf005df62013-04-30 16:36:45 +00002816 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
2817 ApiCheck(obj->IsJSTypedArray() && \
2818 i::JSTypedArray::cast(*obj)->type() == typeConst, \
2819 "v8::" #ApiClass "::Cast()", \
2820 "Could not convert to " #ApiClass); \
2821 }
2822
2823
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002824TYPED_ARRAY_LIST(CHECK_TYPED_ARRAY_CAST)
danno@chromium.orgf005df62013-04-30 16:36:45 +00002825
2826#undef CHECK_TYPED_ARRAY_CAST
2827
2828
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002829void v8::DataView::CheckCast(Value* that) {
2830 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2831 ApiCheck(obj->IsJSDataView(),
2832 "v8::DataView::Cast()",
2833 "Could not convert to DataView");
2834}
2835
2836
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002837void v8::Date::CheckCast(v8::Value* that) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002838 i::Isolate* isolate = i::Isolate::Current();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002839 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002840 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_string()),
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002841 "v8::Date::Cast()",
2842 "Could not convert to date");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002843}
2844
2845
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002846void v8::StringObject::CheckCast(v8::Value* that) {
2847 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002848 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002849 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002850 "v8::StringObject::Cast()",
2851 "Could not convert to StringObject");
2852}
2853
2854
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002855void v8::SymbolObject::CheckCast(v8::Value* that) {
2856 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002857 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2858 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
2859 "v8::SymbolObject::Cast()",
2860 "Could not convert to SymbolObject");
2861}
2862
2863
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002864void v8::NumberObject::CheckCast(v8::Value* that) {
2865 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002866 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002867 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002868 "v8::NumberObject::Cast()",
2869 "Could not convert to NumberObject");
2870}
2871
2872
2873void v8::BooleanObject::CheckCast(v8::Value* that) {
2874 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002875 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002876 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002877 "v8::BooleanObject::Cast()",
2878 "Could not convert to BooleanObject");
2879}
2880
2881
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002882void v8::RegExp::CheckCast(v8::Value* that) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002883 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2884 ApiCheck(obj->IsJSRegExp(),
2885 "v8::RegExp::Cast()",
2886 "Could not convert to regular expression");
2887}
2888
2889
ager@chromium.org32912102009-01-16 10:38:43 +00002890bool Value::BooleanValue() const {
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +00002891 return Utils::OpenHandle(this)->BooleanValue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002892}
2893
2894
ager@chromium.org32912102009-01-16 10:38:43 +00002895double Value::NumberValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002896 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2897 i::Handle<i::Object> num;
2898 if (obj->IsNumber()) {
2899 num = obj;
2900 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002901 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002902 LOG_API(isolate, "NumberValue");
2903 ENTER_V8(isolate);
2904 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002905 num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002906 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002907 }
2908 return num->Number();
2909}
2910
2911
ager@chromium.org32912102009-01-16 10:38:43 +00002912int64_t Value::IntegerValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2914 i::Handle<i::Object> num;
2915 if (obj->IsNumber()) {
2916 num = obj;
2917 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002918 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002919 LOG_API(isolate, "IntegerValue");
2920 ENTER_V8(isolate);
2921 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002922 num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002923 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002924 }
2925 if (num->IsSmi()) {
2926 return i::Smi::cast(*num)->value();
2927 } else {
2928 return static_cast<int64_t>(num->Number());
2929 }
2930}
2931
2932
ager@chromium.org32912102009-01-16 10:38:43 +00002933Local<Int32> Value::ToInt32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002934 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2935 i::Handle<i::Object> num;
2936 if (obj->IsSmi()) {
2937 num = obj;
2938 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002939 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002940 LOG_API(isolate, "ToInt32");
2941 ENTER_V8(isolate);
2942 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002943 num = i::Execution::ToInt32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002944 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002945 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002946 return ToApiHandle<Int32>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002947}
2948
2949
ager@chromium.org32912102009-01-16 10:38:43 +00002950Local<Uint32> Value::ToUint32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002951 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2952 i::Handle<i::Object> num;
2953 if (obj->IsSmi()) {
2954 num = obj;
2955 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002956 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002957 LOG_API(isolate, "ToUInt32");
2958 ENTER_V8(isolate);
2959 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002960 num = i::Execution::ToUint32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002961 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002962 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002963 return ToApiHandle<Uint32>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964}
2965
2966
ager@chromium.org32912102009-01-16 10:38:43 +00002967Local<Uint32> Value::ToArrayIndex() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2969 if (obj->IsSmi()) {
2970 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2971 return Local<Uint32>();
2972 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002973 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002974 LOG_API(isolate, "ToArrayIndex");
2975 ENTER_V8(isolate);
2976 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002977 i::Handle<i::Object> string_obj =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002978 i::Execution::ToString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002979 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002980 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2981 uint32_t index;
2982 if (str->AsArrayIndex(&index)) {
2983 i::Handle<i::Object> value;
2984 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002985 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002987 value = isolate->factory()->NewNumber(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002988 }
2989 return Utils::Uint32ToLocal(value);
2990 }
2991 return Local<Uint32>();
2992}
2993
2994
ager@chromium.org32912102009-01-16 10:38:43 +00002995int32_t Value::Int32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002996 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2997 if (obj->IsSmi()) {
2998 return i::Smi::cast(*obj)->value();
2999 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003000 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003001 LOG_API(isolate, "Int32Value (slow)");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003002 ENTER_V8(isolate);
3003 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003004 i::Handle<i::Object> num =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003005 i::Execution::ToInt32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003006 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003007 if (num->IsSmi()) {
3008 return i::Smi::cast(*num)->value();
3009 } else {
3010 return static_cast<int32_t>(num->Number());
3011 }
3012 }
3013}
3014
3015
ager@chromium.org32912102009-01-16 10:38:43 +00003016bool Value::Equals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003017 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00003018 if (EmptyCheck("v8::Value::Equals()", this) ||
3019 EmptyCheck("v8::Value::Equals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003020 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00003021 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003022 LOG_API(isolate, "Equals");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003023 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003024 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3025 i::Handle<i::Object> other = Utils::OpenHandle(*that);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003026 // If both obj and other are JSObjects, we'd better compare by identity
3027 // immediately when going into JS builtin. The reason is Invoke
3028 // would overwrite global object receiver with global proxy.
3029 if (obj->IsJSObject() && other->IsJSObject()) {
3030 return *obj == *other;
3031 }
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003032 i::Handle<i::Object> args[] = { other };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003033 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003034 i::Handle<i::Object> result =
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003035 CallV8HeapFunction("EQUALS", obj, ARRAY_SIZE(args), args,
3036 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003037 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003038 return *result == i::Smi::FromInt(i::EQUAL);
3039}
3040
3041
ager@chromium.org32912102009-01-16 10:38:43 +00003042bool Value::StrictEquals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003043 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00003044 if (EmptyCheck("v8::Value::StrictEquals()", this) ||
3045 EmptyCheck("v8::Value::StrictEquals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003046 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00003047 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003048 LOG_API(isolate, "StrictEquals");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003049 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3050 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3051 // Must check HeapNumber first, since NaN !== NaN.
3052 if (obj->IsHeapNumber()) {
3053 if (!other->IsNumber()) return false;
3054 double x = obj->Number();
3055 double y = other->Number();
3056 // Must check explicitly for NaN:s on Windows, but -0 works fine.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00003057 return x == y && !std::isnan(x) && !std::isnan(y);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003058 } else if (*obj == *other) { // Also covers Booleans.
3059 return true;
3060 } else if (obj->IsSmi()) {
3061 return other->IsNumber() && obj->Number() == other->Number();
3062 } else if (obj->IsString()) {
3063 return other->IsString() &&
3064 i::String::cast(*obj)->Equals(i::String::cast(*other));
3065 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
3066 return other->IsUndefined() || other->IsUndetectableObject();
3067 } else {
3068 return false;
3069 }
3070}
3071
3072
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00003073bool Value::SameValue(Handle<Value> that) const {
3074 i::Isolate* isolate = i::Isolate::Current();
3075 if (EmptyCheck("v8::Value::SameValue()", this) ||
3076 EmptyCheck("v8::Value::SameValue()", that)) {
3077 return false;
3078 }
3079 LOG_API(isolate, "SameValue");
3080 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3081 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3082 return obj->SameValue(*other);
3083}
3084
3085
ager@chromium.org32912102009-01-16 10:38:43 +00003086uint32_t Value::Uint32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003087 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3088 if (obj->IsSmi()) {
3089 return i::Smi::cast(*obj)->value();
3090 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003091 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003092 LOG_API(isolate, "Uint32Value");
3093 ENTER_V8(isolate);
3094 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003095 i::Handle<i::Object> num =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003096 i::Execution::ToUint32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003097 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003098 if (num->IsSmi()) {
3099 return i::Smi::cast(*num)->value();
3100 } else {
3101 return static_cast<uint32_t>(num->Number());
3102 }
3103 }
3104}
3105
3106
3107bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003108 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003109 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003110 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003111 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003112 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003113 i::Handle<i::Object> self = Utils::OpenHandle(this);
3114 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3115 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003116 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003117 i::Handle<i::Object> obj = i::SetProperty(
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00003118 isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003119 self,
3120 key_obj,
3121 value_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003122 static_cast<PropertyAttributes>(attribs),
3123 i::kNonStrictMode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003124 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003125 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003126 return true;
3127}
3128
3129
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003130bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003131 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003132 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003133 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003134 i::HandleScope scope(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003135 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3136 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003137 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003138 i::Handle<i::Object> obj = i::JSObject::SetElement(
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003139 self,
3140 index,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00003141 value_obj,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003142 NONE,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00003143 i::kNonStrictMode);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003144 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003145 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003146 return true;
3147}
3148
3149
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003150bool v8::Object::ForceSet(v8::Handle<Value> key,
3151 v8::Handle<Value> value,
3152 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003153 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003154 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003155 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003156 i::HandleScope scope(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003157 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3158 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3159 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003160 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003161 i::Handle<i::Object> obj = i::ForceSetProperty(
3162 self,
3163 key_obj,
3164 value_obj,
3165 static_cast<PropertyAttributes>(attribs));
3166 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003167 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003168 return true;
3169}
3170
3171
ager@chromium.orge2902be2009-06-08 12:21:35 +00003172bool v8::Object::ForceDelete(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003173 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003174 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003175 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003176 i::HandleScope scope(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003177 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3178 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003179
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00003180 // When deleting a property on the global object using ForceDelete
3181 // deoptimize all functions as optimized code does not check for the hole
3182 // value with DontDelete properties. We have to deoptimize all contexts
3183 // because of possible cross-context inlined functions.
3184 if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003185 i::Deoptimizer::DeoptimizeAll(isolate);
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00003186 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003187
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003188 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003189 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
3190 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003191 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003192 return obj->IsTrue();
3193}
3194
3195
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003196Local<Value> v8::Object::Get(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003197 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003198 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003199 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003200 i::Handle<i::Object> self = Utils::OpenHandle(this);
3201 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003202 EXCEPTION_PREAMBLE(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003203 i::Handle<i::Object> result = i::GetProperty(isolate, self, key_obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003204 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003205 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003206 return Utils::ToLocal(result);
3207}
3208
3209
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003210Local<Value> v8::Object::Get(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003211 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003212 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003213 ENTER_V8(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003214 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003215 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00003216 i::Handle<i::Object> result = i::Object::GetElement(isolate, self, index);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003217 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003218 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003219 return Utils::ToLocal(result);
3220}
3221
3222
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003223PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
3224 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3225 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
3226 return static_cast<PropertyAttribute>(NONE));
3227 ENTER_V8(isolate);
3228 i::HandleScope scope(isolate);
3229 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3230 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003231 if (!key_obj->IsName()) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003232 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003233 key_obj = i::Execution::ToString(isolate, key_obj, &has_pending_exception);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003234 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3235 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003236 i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
3237 PropertyAttributes result = self->GetPropertyAttribute(*key_name);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003238 if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
3239 return static_cast<PropertyAttribute>(result);
3240}
3241
3242
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003243Local<Value> v8::Object::GetPrototype() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003244 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3245 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003246 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003247 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003248 i::Handle<i::Object> self = Utils::OpenHandle(this);
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003249 i::Handle<i::Object> result(self->GetPrototype(isolate), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003250 return Utils::ToLocal(result);
3251}
3252
3253
ager@chromium.org5c838252010-02-19 08:53:10 +00003254bool v8::Object::SetPrototype(Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003255 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003256 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003257 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00003258 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3259 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003260 // We do not allow exceptions thrown while setting the prototype
3261 // to propagate outside.
3262 TryCatch try_catch;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003263 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +00003264 i::Handle<i::Object> result = i::JSObject::SetPrototype(self, value_obj);
ager@chromium.org5c838252010-02-19 08:53:10 +00003265 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003266 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org5c838252010-02-19 08:53:10 +00003267 return true;
3268}
3269
3270
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003271Local<Object> v8::Object::FindInstanceInPrototypeChain(
3272 v8::Handle<FunctionTemplate> tmpl) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003273 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3274 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003275 "v8::Object::FindInstanceInPrototypeChain()",
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003276 return Local<v8::Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003277 ENTER_V8(isolate);
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003278 i::JSObject* object = *Utils::OpenHandle(this);
3279 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
3280 while (!object->IsInstanceOf(tmpl_info)) {
3281 i::Object* prototype = object->GetPrototype();
3282 if (!prototype->IsJSObject()) return Local<Object>();
3283 object = i::JSObject::cast(prototype);
3284 }
3285 return Utils::ToLocal(i::Handle<i::JSObject>(object));
3286}
3287
3288
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003289Local<Array> v8::Object::GetPropertyNames() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003290 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003291 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
3292 return Local<v8::Array>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003293 ENTER_V8(isolate);
3294 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003295 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003296 bool threw = false;
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00003297 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003298 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS, &threw);
3299 if (threw) return Local<v8::Array>();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003300 // Because we use caching to speed up enumeration it is important
3301 // to never change the result of the basic enumeration function so
3302 // we clone the result.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003303 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3304 i::Handle<i::JSArray> result =
3305 isolate->factory()->NewJSArrayWithElements(elms);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003306 return Utils::ToLocal(scope.CloseAndEscape(result));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003307}
3308
3309
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003310Local<Array> v8::Object::GetOwnPropertyNames() {
3311 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3312 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
3313 return Local<v8::Array>());
3314 ENTER_V8(isolate);
3315 i::HandleScope scope(isolate);
3316 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003317 bool threw = false;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003318 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003319 i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY, &threw);
3320 if (threw) return Local<v8::Array>();
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003321 // Because we use caching to speed up enumeration it is important
3322 // to never change the result of the basic enumeration function so
3323 // we clone the result.
3324 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3325 i::Handle<i::JSArray> result =
3326 isolate->factory()->NewJSArrayWithElements(elms);
3327 return Utils::ToLocal(scope.CloseAndEscape(result));
3328}
3329
3330
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003331Local<String> v8::Object::ObjectProtoToString() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003332 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3333 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003334 return Local<v8::String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003335 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003336 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3337
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003338 i::Handle<i::Object> name(self->class_name(), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003339
3340 // Native implementation of Object.prototype.toString (v8natives.js):
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00003341 // var c = %_ClassOf(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003342 // if (c === 'Arguments') c = 'Object';
3343 // return "[object " + c + "]";
3344
3345 if (!name->IsString()) {
3346 return v8::String::New("[object ]");
3347
3348 } else {
3349 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00003350 if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Arguments"))) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351 return v8::String::New("[object Object]");
3352
3353 } else {
3354 const char* prefix = "[object ";
3355 Local<String> str = Utils::ToLocal(class_name);
3356 const char* postfix = "]";
3357
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003358 int prefix_len = i::StrLength(prefix);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003359 int str_len = str->Utf8Length();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003360 int postfix_len = i::StrLength(postfix);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003361
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003362 int buf_len = prefix_len + str_len + postfix_len;
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003363 i::ScopedVector<char> buf(buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003364
3365 // Write prefix.
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003366 char* ptr = buf.start();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003367 i::OS::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368 ptr += prefix_len;
3369
3370 // Write real content.
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003371 str->WriteUtf8(ptr, str_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003372 ptr += str_len;
3373
3374 // Write postfix.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003375 i::OS::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376
3377 // Copy the buffer into a heap-allocated string and return it.
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003378 Local<String> result = v8::String::New(buf.start(), buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003379 return result;
3380 }
3381 }
3382}
3383
3384
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00003385Local<Value> v8::Object::GetConstructor() {
3386 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3387 ON_BAILOUT(isolate, "v8::Object::GetConstructor()",
3388 return Local<v8::Function>());
3389 ENTER_V8(isolate);
3390 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003391 i::Handle<i::Object> constructor(self->GetConstructor(), isolate);
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00003392 return Utils::ToLocal(constructor);
3393}
3394
3395
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003396Local<String> v8::Object::GetConstructorName() {
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::Object::GetConstructorName()",
3399 return Local<v8::String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003400 ENTER_V8(isolate);
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003401 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3402 i::Handle<i::String> name(self->constructor_name());
3403 return Utils::ToLocal(name);
3404}
3405
3406
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003407bool v8::Object::Delete(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003408 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003409 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003410 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003411 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003413 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3414 EXCEPTION_PREAMBLE(isolate);
3415 i::Handle<i::Object> obj = i::DeleteProperty(self, key_obj);
3416 has_pending_exception = obj.is_null();
3417 EXCEPTION_BAILOUT_CHECK(isolate, false);
3418 return obj->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003419}
3420
3421
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003422bool v8::Object::Has(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003423 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3424 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
3425 ENTER_V8(isolate);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003426 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3427 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3428 EXCEPTION_PREAMBLE(isolate);
3429 i::Handle<i::Object> obj = i::HasProperty(self, key_obj);
3430 has_pending_exception = obj.is_null();
3431 EXCEPTION_BAILOUT_CHECK(isolate, false);
3432 return obj->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003433}
3434
3435
3436bool v8::Object::Delete(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003437 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3438 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003439 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003440 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003441 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003442 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00003443 return i::JSReceiver::DeleteElement(self, index)->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003444}
3445
3446
3447bool v8::Object::Has(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003448 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3449 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003450 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003451 return i::JSReceiver::HasElement(self, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003452}
3453
3454
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003455template<typename Setter, typename Getter, typename Data>
3456static inline bool ObjectSetAccessor(Object* obj,
3457 Handle<String> name,
3458 Setter getter,
3459 Getter setter,
3460 Data data,
3461 AccessControl settings,
3462 PropertyAttribute attributes) {
3463 i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate();
3464 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3465 ENTER_V8(isolate);
3466 i::HandleScope scope(isolate);
3467 v8::Handle<AccessorSignature> signature;
3468 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(
3469 name, getter, setter, data, settings, attributes, signature);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003470 if (info.is_null()) return false;
3471 bool fast = Utils::OpenHandle(obj)->HasFastProperties();
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00003472 i::Handle<i::Object> result =
3473 i::JSObject::SetAccessor(Utils::OpenHandle(obj), info);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003474 if (result.is_null() || result->IsUndefined()) return false;
3475 if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(obj), 0);
3476 return true;
3477}
3478
3479
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003480bool Object::SetAccessor(Handle<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003481 AccessorGetterCallback getter,
3482 AccessorSetterCallback setter,
3483 v8::Handle<Value> data,
3484 AccessControl settings,
3485 PropertyAttribute attributes) {
3486 return ObjectSetAccessor(
3487 this, name, getter, setter, data, settings, attributes);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003488}
3489
3490
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00003491bool Object::SetDeclaredAccessor(Local<String> name,
3492 Local<DeclaredAccessorDescriptor> descriptor,
3493 PropertyAttribute attributes,
3494 AccessControl settings) {
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003495 void* null = NULL;
3496 return ObjectSetAccessor(
3497 this, name, descriptor, null, null, settings, attributes);
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003498}
3499
3500
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003501bool v8::Object::HasOwnProperty(Handle<String> key) {
3502 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3503 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3504 return false);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003505 return i::JSReceiver::HasLocalProperty(
3506 Utils::OpenHandle(this), Utils::OpenHandle(*key));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003507}
3508
3509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003510bool v8::Object::HasRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003511 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3512 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003513 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003514 return Utils::OpenHandle(this)->HasRealNamedProperty(
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003515 isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003516 *Utils::OpenHandle(*key));
3517}
3518
3519
3520bool v8::Object::HasRealIndexedProperty(uint32_t index) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003521 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3522 ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003523 return false);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003524 return Utils::OpenHandle(this)->HasRealElementProperty(isolate, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003525}
3526
3527
3528bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003529 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3530 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003531 "v8::Object::HasRealNamedCallbackProperty()",
3532 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003533 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003534 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003535 isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003536 *Utils::OpenHandle(*key));
3537}
3538
3539
3540bool v8::Object::HasNamedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003541 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3542 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003543 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003544 return Utils::OpenHandle(this)->HasNamedInterceptor();
3545}
3546
3547
3548bool v8::Object::HasIndexedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003549 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3550 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003551 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003552 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3553}
3554
3555
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003556static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
3557 i::Handle<i::JSObject> receiver,
3558 i::Handle<i::String> name,
3559 i::LookupResult* lookup) {
3560 if (!lookup->IsProperty()) {
3561 // No real property was found.
3562 return Local<Value>();
3563 }
3564
3565 // If the property being looked up is a callback, it can throw
3566 // an exception.
3567 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003568 PropertyAttributes ignored;
3569 i::Handle<i::Object> result =
3570 i::Object::GetProperty(receiver, receiver, lookup, name,
3571 &ignored);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003572 has_pending_exception = result.is_null();
3573 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3574
3575 return Utils::ToLocal(result);
3576}
3577
3578
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003579Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003580 Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003581 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3582 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003583 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003584 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003585 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003586 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3587 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003588 i::LookupResult lookup(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003589 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003590 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003591}
3592
3593
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003594Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003595 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3596 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003597 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003598 ENTER_V8(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003599 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3600 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003601 i::LookupResult lookup(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003602 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003603 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003604}
3605
3606
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003607// Turns on access checks by copying the map and setting the check flag.
3608// Because the object gets a new map, existing inline cache caching
3609// the old map of this object will fail.
3610void v8::Object::TurnOnAccessCheck() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003611 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003612 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003613 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003614 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003615 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3616
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003617 // When turning on access checks for a global object deoptimize all functions
3618 // as optimized code does not always handle access checks.
3619 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3620
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003621 i::Handle<i::Map> new_map =
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003622 isolate->factory()->CopyMap(i::Handle<i::Map>(obj->map()));
ager@chromium.org870a0b62008-11-04 11:43:05 +00003623 new_map->set_is_access_check_needed(true);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003624 obj->set_map(*new_map);
3625}
3626
3627
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00003628bool v8::Object::IsDirty() {
3629 return Utils::OpenHandle(this)->IsDirty();
3630}
3631
3632
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003633Local<v8::Object> v8::Object::Clone() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003634 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003635 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003636 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003637 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003638 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003639 i::Handle<i::JSObject> result = i::JSObject::Copy(self);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003640 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003641 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003642 return Utils::ToLocal(result);
3643}
3644
3645
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003646static i::Context* GetCreationContext(i::JSObject* object) {
3647 i::Object* constructor = object->map()->constructor();
3648 i::JSFunction* function;
3649 if (!constructor->IsJSFunction()) {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003650 // Functions have null as a constructor,
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003651 // but any JSFunction knows its context immediately.
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003652 ASSERT(object->IsJSFunction());
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003653 function = i::JSFunction::cast(object);
3654 } else {
3655 function = i::JSFunction::cast(constructor);
3656 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003657 return function->context()->native_context();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003658}
3659
3660
3661Local<v8::Context> v8::Object::CreationContext() {
3662 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3663 ON_BAILOUT(isolate,
3664 "v8::Object::CreationContext()", return Local<v8::Context>());
3665 ENTER_V8(isolate);
3666 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3667 i::Context* context = GetCreationContext(*self);
3668 return Utils::ToLocal(i::Handle<i::Context>(context));
3669}
3670
3671
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003672int v8::Object::GetIdentityHash() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003673 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003674 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003675 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003676 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003677 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003678 return i::JSObject::GetIdentityHash(self);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003679}
3680
3681
3682bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3683 v8::Handle<v8::Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003684 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003685 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00003686 if (value.IsEmpty()) return DeleteHiddenValue(key);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003687 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003688 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003689 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003690 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003691 i::Handle<i::String> key_string =
3692 isolate->factory()->InternalizeString(key_obj);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003693 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003694 i::Handle<i::Object> result =
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003695 i::JSObject::SetHiddenProperty(self, key_string, value_obj);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003696 return *result == *self;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003697}
3698
3699
3700v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003701 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003702 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3703 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003704 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003705 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003706 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00003707 i::Handle<i::String> key_string =
3708 isolate->factory()->InternalizeString(key_obj);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003709 i::Handle<i::Object> result(self->GetHiddenProperty(*key_string), isolate);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00003710 if (result->IsTheHole()) return v8::Local<v8::Value>();
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003711 return Utils::ToLocal(result);
3712}
3713
3714
3715bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003716 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003717 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003718 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003719 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003720 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003721 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00003722 i::Handle<i::String> key_string =
3723 isolate->factory()->InternalizeString(key_obj);
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00003724 i::JSObject::DeleteHiddenProperty(self, key_string);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003725 return true;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003726}
3727
3728
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003729namespace {
3730
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003731static i::ElementsKind GetElementsKindFromExternalArrayType(
3732 ExternalArrayType array_type) {
3733 switch (array_type) {
3734 case kExternalByteArray:
3735 return i::EXTERNAL_BYTE_ELEMENTS;
3736 break;
3737 case kExternalUnsignedByteArray:
3738 return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3739 break;
3740 case kExternalShortArray:
3741 return i::EXTERNAL_SHORT_ELEMENTS;
3742 break;
3743 case kExternalUnsignedShortArray:
3744 return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3745 break;
3746 case kExternalIntArray:
3747 return i::EXTERNAL_INT_ELEMENTS;
3748 break;
3749 case kExternalUnsignedIntArray:
3750 return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
3751 break;
3752 case kExternalFloatArray:
3753 return i::EXTERNAL_FLOAT_ELEMENTS;
3754 break;
3755 case kExternalDoubleArray:
3756 return i::EXTERNAL_DOUBLE_ELEMENTS;
3757 break;
3758 case kExternalPixelArray:
3759 return i::EXTERNAL_PIXEL_ELEMENTS;
3760 break;
3761 }
3762 UNREACHABLE();
3763 return i::DICTIONARY_ELEMENTS;
3764}
3765
3766
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003767void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3768 void* data,
3769 ExternalArrayType array_type,
3770 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003771 i::Isolate* isolate = object->GetIsolate();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003772 i::Handle<i::ExternalArray> array =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003773 isolate->factory()->NewExternalArray(length, array_type, data);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003774
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003775 i::Handle<i::Map> external_array_map =
3776 isolate->factory()->GetElementsTransitionMap(
3777 object,
3778 GetElementsKindFromExternalArrayType(array_type));
3779
3780 object->set_map(*external_array_map);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003781 object->set_elements(*array);
3782}
3783
3784} // namespace
3785
3786
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003787void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003788 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003789 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003790 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003791 i::HandleScope scope(isolate);
danno@chromium.org412fa512012-09-14 13:28:26 +00003792 if (!ApiCheck(length >= 0 && length <= i::ExternalPixelArray::kMaxLength,
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003793 "v8::Object::SetIndexedPropertiesToPixelData()",
3794 "length exceeds max acceptable value")) {
3795 return;
3796 }
3797 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3798 if (!ApiCheck(!self->IsJSArray(),
3799 "v8::Object::SetIndexedPropertiesToPixelData()",
3800 "JSArray is not supported")) {
3801 return;
3802 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003803 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003804}
3805
3806
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003807bool v8::Object::HasIndexedPropertiesInPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003808 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003809 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3810 return false);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003811 return self->HasExternalPixelElements();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003812}
3813
3814
3815uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003816 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003817 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3818 return NULL);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003819 if (self->HasExternalPixelElements()) {
3820 return i::ExternalPixelArray::cast(self->elements())->
3821 external_pixel_pointer();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003822 } else {
3823 return NULL;
3824 }
3825}
3826
3827
3828int v8::Object::GetIndexedPropertiesPixelDataLength() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003829 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003830 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3831 return -1);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003832 if (self->HasExternalPixelElements()) {
3833 return i::ExternalPixelArray::cast(self->elements())->length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003834 } else {
3835 return -1;
3836 }
3837}
3838
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003839
ager@chromium.org3811b432009-10-28 14:53:37 +00003840void v8::Object::SetIndexedPropertiesToExternalArrayData(
3841 void* data,
3842 ExternalArrayType array_type,
3843 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003844 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003845 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003846 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003847 i::HandleScope scope(isolate);
danno@chromium.org412fa512012-09-14 13:28:26 +00003848 if (!ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
ager@chromium.org3811b432009-10-28 14:53:37 +00003849 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3850 "length exceeds max acceptable value")) {
3851 return;
3852 }
3853 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3854 if (!ApiCheck(!self->IsJSArray(),
3855 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3856 "JSArray is not supported")) {
3857 return;
3858 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003859 PrepareExternalArrayElements(self, data, array_type, length);
ager@chromium.org3811b432009-10-28 14:53:37 +00003860}
3861
3862
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003863bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003864 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3865 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003866 "v8::HasIndexedPropertiesInExternalArrayData()",
3867 return false);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003868 return self->HasExternalArrayElements();
3869}
3870
3871
3872void* v8::Object::GetIndexedPropertiesExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003873 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3874 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003875 "v8::GetIndexedPropertiesExternalArrayData()",
3876 return NULL);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003877 if (self->HasExternalArrayElements()) {
3878 return i::ExternalArray::cast(self->elements())->external_pointer();
3879 } else {
3880 return NULL;
3881 }
3882}
3883
3884
3885ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003886 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3887 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003888 "v8::GetIndexedPropertiesExternalArrayDataType()",
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003889 return static_cast<ExternalArrayType>(-1));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003890 switch (self->elements()->map()->instance_type()) {
3891 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3892 return kExternalByteArray;
3893 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3894 return kExternalUnsignedByteArray;
3895 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3896 return kExternalShortArray;
3897 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3898 return kExternalUnsignedShortArray;
3899 case i::EXTERNAL_INT_ARRAY_TYPE:
3900 return kExternalIntArray;
3901 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3902 return kExternalUnsignedIntArray;
3903 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3904 return kExternalFloatArray;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003905 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3906 return kExternalDoubleArray;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003907 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3908 return kExternalPixelArray;
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003909 default:
3910 return static_cast<ExternalArrayType>(-1);
3911 }
3912}
3913
3914
3915int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003916 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3917 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003918 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3919 return 0);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003920 if (self->HasExternalArrayElements()) {
3921 return i::ExternalArray::cast(self->elements())->length();
3922 } else {
3923 return -1;
3924 }
3925}
3926
3927
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003928bool v8::Object::IsCallable() {
3929 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3930 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3931 ENTER_V8(isolate);
3932 i::HandleScope scope(isolate);
3933 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3934 if (obj->IsJSFunction()) return true;
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003935 return i::Execution::GetFunctionDelegate(isolate, obj)->IsJSFunction();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003936}
3937
3938
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00003939Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003940 int argc,
lrn@chromium.org1c092762011-05-09 09:42:16 +00003941 v8::Handle<v8::Value> argv[]) {
3942 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3943 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3944 return Local<v8::Value>());
3945 LOG_API(isolate, "Object::CallAsFunction");
3946 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00003947 i::Logger::TimerEventScope timer_scope(
3948 isolate, i::Logger::TimerEventScope::v8_execute);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003949 i::HandleScope scope(isolate);
3950 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3951 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3952 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003953 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003954 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3955 if (obj->IsJSFunction()) {
3956 fun = i::Handle<i::JSFunction>::cast(obj);
3957 } else {
3958 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003959 i::Handle<i::Object> delegate = i::Execution::TryGetFunctionDelegate(
3960 isolate, obj, &has_pending_exception);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003961 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3962 fun = i::Handle<i::JSFunction>::cast(delegate);
3963 recv_obj = obj;
3964 }
3965 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00003966 i::Handle<i::Object> returned = i::Execution::Call(
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00003967 isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003968 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003969 return Utils::ToLocal(scope.CloseAndEscape(returned));
3970}
3971
3972
3973Local<v8::Value> Object::CallAsConstructor(int argc,
3974 v8::Handle<v8::Value> argv[]) {
3975 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3976 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3977 return Local<v8::Object>());
3978 LOG_API(isolate, "Object::CallAsConstructor");
3979 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00003980 i::Logger::TimerEventScope timer_scope(
3981 isolate, i::Logger::TimerEventScope::v8_execute);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003982 i::HandleScope scope(isolate);
3983 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3984 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003985 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003986 if (obj->IsJSFunction()) {
3987 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
3988 EXCEPTION_PREAMBLE(isolate);
3989 i::Handle<i::Object> returned =
3990 i::Execution::New(fun, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003991 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003992 return Utils::ToLocal(scope.CloseAndEscape(
3993 i::Handle<i::JSObject>::cast(returned)));
3994 }
3995 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003996 i::Handle<i::Object> delegate = i::Execution::TryGetConstructorDelegate(
3997 isolate, obj, &has_pending_exception);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003998 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3999 if (!delegate->IsUndefined()) {
4000 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
4001 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00004002 i::Handle<i::Object> returned = i::Execution::Call(
4003 isolate, fun, obj, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004004 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00004005 ASSERT(!delegate->IsUndefined());
4006 return Utils::ToLocal(scope.CloseAndEscape(returned));
4007 }
4008 return Local<v8::Object>();
4009}
4010
4011
dslomov@chromium.org639bac02013-09-09 11:58:54 +00004012Local<Function> Function::New(Isolate* v8_isolate,
4013 FunctionCallback callback,
4014 Local<Value> data,
4015 int length) {
4016 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
4017 LOG_API(isolate, "Function::New");
4018 ENTER_V8(isolate);
4019 return FunctionTemplateNew(
4020 isolate, callback, data, Local<Signature>(), length, true)->
4021 GetFunction();
4022}
4023
4024
ager@chromium.org32912102009-01-16 10:38:43 +00004025Local<v8::Object> Function::NewInstance() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004026 return NewInstance(0, NULL);
4027}
4028
4029
4030Local<v8::Object> Function::NewInstance(int argc,
ager@chromium.org32912102009-01-16 10:38:43 +00004031 v8::Handle<v8::Value> argv[]) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004032 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004033 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
4034 return Local<v8::Object>());
4035 LOG_API(isolate, "Function::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004036 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00004037 i::Logger::TimerEventScope timer_scope(
4038 isolate, i::Logger::TimerEventScope::v8_execute);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004039 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004040 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
4041 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00004042 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004043 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004044 i::Handle<i::Object> returned =
4045 i::Execution::New(function, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004046 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004047 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
4048}
4049
4050
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00004051Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004052 v8::Handle<v8::Value> argv[]) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004053 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004054 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
4055 LOG_API(isolate, "Function::Call");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004056 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00004057 i::Logger::TimerEventScope timer_scope(
4058 isolate, i::Logger::TimerEventScope::v8_execute);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004059 i::Object* raw_result = NULL;
4060 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004061 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004062 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
4063 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4064 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00004065 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004066 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00004067 i::Handle<i::Object> returned = i::Execution::Call(
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00004068 isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004069 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004070 raw_result = *returned;
4071 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004072 i::Handle<i::Object> result(raw_result, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004073 return Utils::ToLocal(result);
4074}
4075
4076
4077void Function::SetName(v8::Handle<v8::String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004078 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4079 ENTER_V8(isolate);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004080 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004081 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4082 func->shared()->set_name(*Utils::OpenHandle(*name));
4083}
4084
4085
ager@chromium.org32912102009-01-16 10:38:43 +00004086Handle<Value> Function::GetName() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004087 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004088 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name(),
4089 func->GetIsolate()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004090}
4091
4092
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004093Handle<Value> Function::GetInferredName() const {
4094 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004095 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4096 func->GetIsolate()));
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004097}
4098
4099
ager@chromium.org5c838252010-02-19 08:53:10 +00004100ScriptOrigin Function::GetScriptOrigin() const {
4101 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4102 if (func->shared()->script()->IsScript()) {
4103 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00004104 i::Handle<i::Object> scriptName = GetScriptNameOrSourceURL(script);
ager@chromium.org5c838252010-02-19 08:53:10 +00004105 v8::ScriptOrigin origin(
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00004106 Utils::ToLocal(scriptName),
ager@chromium.org5c838252010-02-19 08:53:10 +00004107 v8::Integer::New(script->line_offset()->value()),
4108 v8::Integer::New(script->column_offset()->value()));
4109 return origin;
4110 }
4111 return v8::ScriptOrigin(Handle<Value>());
4112}
4113
4114
4115const int Function::kLineOffsetNotFound = -1;
4116
4117
4118int Function::GetScriptLineNumber() const {
4119 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4120 if (func->shared()->script()->IsScript()) {
4121 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4122 return i::GetScriptLineNumber(script, func->shared()->start_position());
4123 }
4124 return kLineOffsetNotFound;
4125}
4126
4127
danno@chromium.orgc612e022011-11-10 11:38:15 +00004128int Function::GetScriptColumnNumber() const {
4129 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4130 if (func->shared()->script()->IsScript()) {
4131 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4132 return i::GetScriptColumnNumber(script, func->shared()->start_position());
4133 }
4134 return kLineOffsetNotFound;
4135}
4136
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004137
danno@chromium.orgc612e022011-11-10 11:38:15 +00004138Handle<Value> Function::GetScriptId() const {
4139 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00004140 i::Isolate* isolate = func->GetIsolate();
4141 if (!func->shared()->script()->IsScript()) {
4142 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4143 }
danno@chromium.orgc612e022011-11-10 11:38:15 +00004144 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00004145 return Utils::ToLocal(i::Handle<i::Object>(script->id(), isolate));
danno@chromium.orgc612e022011-11-10 11:38:15 +00004146}
4147
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004148
4149int Function::ScriptId() const {
4150 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4151 if (!func->shared()->script()->IsScript()) return v8::Script::kNoScriptId;
4152 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4153 return script->id()->value();
4154}
4155
4156
ager@chromium.org32912102009-01-16 10:38:43 +00004157int String::Length() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004158 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004159 return str->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004160}
4161
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004162
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004163bool String::IsOneByte() const {
4164 i::Handle<i::String> str = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00004165 return str->HasOnlyOneByteChars();
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004166}
4167
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00004168
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004169// Helpers for ContainsOnlyOneByteHelper
4170template<size_t size> struct OneByteMask;
4171template<> struct OneByteMask<4> {
4172 static const uint32_t value = 0xFF00FF00;
4173};
4174template<> struct OneByteMask<8> {
4175 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4176};
4177static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4178static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4179static inline bool Unaligned(const uint16_t* chars) {
4180 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4181}
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00004182
4183
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004184static inline const uint16_t* Align(const uint16_t* chars) {
4185 return reinterpret_cast<uint16_t*>(
4186 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4187}
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004188
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004189class ContainsOnlyOneByteHelper {
4190 public:
4191 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4192 bool Check(i::String* string) {
4193 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4194 if (cons_string == NULL) return is_one_byte_;
4195 return CheckCons(cons_string);
4196 }
4197 void VisitOneByteString(const uint8_t* chars, int length) {
4198 // Nothing to do.
4199 }
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004200 void VisitTwoByteString(const uint16_t* chars, int length) {
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004201 // Accumulated bits.
4202 uintptr_t acc = 0;
4203 // Align to uintptr_t.
4204 const uint16_t* end = chars + length;
4205 while (Unaligned(chars) && chars != end) {
4206 acc |= *chars++;
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004207 }
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004208 // Read word aligned in blocks,
4209 // checking the return value at the end of each block.
4210 const uint16_t* aligned_end = Align(end);
4211 const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4212 const int inner_loops = 16;
4213 while (chars + inner_loops*increment < aligned_end) {
4214 for (int i = 0; i < inner_loops; i++) {
4215 acc |= *reinterpret_cast<const uintptr_t*>(chars);
4216 chars += increment;
4217 }
4218 // Check for early return.
4219 if ((acc & kOneByteMask) != 0) {
4220 is_one_byte_ = false;
4221 return;
4222 }
4223 }
4224 // Read the rest.
4225 while (chars != end) {
4226 acc |= *chars++;
4227 }
4228 // Check result.
4229 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004230 }
4231
4232 private:
4233 bool CheckCons(i::ConsString* cons_string) {
4234 while (true) {
4235 // Check left side if flat.
4236 i::String* left = cons_string->first();
4237 i::ConsString* left_as_cons =
4238 i::String::VisitFlat(this, left, 0);
4239 if (!is_one_byte_) return false;
4240 // Check right side if flat.
4241 i::String* right = cons_string->second();
4242 i::ConsString* right_as_cons =
4243 i::String::VisitFlat(this, right, 0);
4244 if (!is_one_byte_) return false;
4245 // Standard recurse/iterate trick.
4246 if (left_as_cons != NULL && right_as_cons != NULL) {
4247 if (left->length() < right->length()) {
4248 CheckCons(left_as_cons);
4249 cons_string = right_as_cons;
4250 } else {
4251 CheckCons(right_as_cons);
4252 cons_string = left_as_cons;
4253 }
4254 // Check fast return.
4255 if (!is_one_byte_) return false;
4256 continue;
4257 }
4258 // Descend left in place.
4259 if (left_as_cons != NULL) {
4260 cons_string = left_as_cons;
4261 continue;
4262 }
4263 // Descend right in place.
4264 if (right_as_cons != NULL) {
4265 cons_string = right_as_cons;
4266 continue;
4267 }
4268 // Terminate.
4269 break;
4270 }
4271 return is_one_byte_;
4272 }
4273 bool is_one_byte_;
4274 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4275};
4276
4277
4278bool String::ContainsOnlyOneByte() const {
4279 i::Handle<i::String> str = Utils::OpenHandle(this);
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004280 if (str->HasOnlyOneByteChars()) return true;
4281 ContainsOnlyOneByteHelper helper;
4282 return helper.Check(*str);
4283}
4284
4285
ulan@chromium.org750145a2013-03-07 15:14:13 +00004286class Utf8LengthHelper : public i::AllStatic {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004287 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004288 enum State {
4289 kEndsWithLeadingSurrogate = 1 << 0,
4290 kStartsWithTrailingSurrogate = 1 << 1,
4291 kLeftmostEdgeIsCalculated = 1 << 2,
4292 kRightmostEdgeIsCalculated = 1 << 3,
4293 kLeftmostEdgeIsSurrogate = 1 << 4,
4294 kRightmostEdgeIsSurrogate = 1 << 5
4295 };
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004296
ulan@chromium.org750145a2013-03-07 15:14:13 +00004297 static const uint8_t kInitialState = 0;
4298
4299 static inline bool EndsWithSurrogate(uint8_t state) {
4300 return state & kEndsWithLeadingSurrogate;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004301 }
4302
ulan@chromium.org750145a2013-03-07 15:14:13 +00004303 static inline bool StartsWithSurrogate(uint8_t state) {
4304 return state & kStartsWithTrailingSurrogate;
4305 }
4306
4307 class Visitor {
4308 public:
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004309 inline explicit Visitor()
ulan@chromium.org750145a2013-03-07 15:14:13 +00004310 : utf8_length_(0),
4311 state_(kInitialState) {}
4312
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004313 void VisitOneByteString(const uint8_t* chars, int length) {
4314 int utf8_length = 0;
4315 // Add in length 1 for each non-ASCII character.
4316 for (int i = 0; i < length; i++) {
4317 utf8_length += *chars++ >> 7;
4318 }
4319 // Add in length 1 for each character.
4320 utf8_length_ = utf8_length + length;
4321 state_ = kInitialState;
4322 }
4323
4324 void VisitTwoByteString(const uint16_t* chars, int length) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00004325 int utf8_length = 0;
4326 int last_character = unibrow::Utf16::kNoPreviousCharacter;
4327 for (int i = 0; i < length; i++) {
4328 uint16_t c = chars[i];
4329 utf8_length += unibrow::Utf8::Length(c, last_character);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004330 last_character = c;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004331 }
4332 utf8_length_ = utf8_length;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004333 uint8_t state = 0;
4334 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4335 state |= kStartsWithTrailingSurrogate;
4336 }
4337 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4338 state |= kEndsWithLeadingSurrogate;
4339 }
4340 state_ = state;
4341 }
4342
4343 static i::ConsString* VisitFlat(i::String* string,
4344 int* length,
4345 uint8_t* state) {
4346 Visitor visitor;
4347 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4348 *length = visitor.utf8_length_;
4349 *state = visitor.state_;
4350 return cons_string;
4351 }
4352
4353 private:
4354 int utf8_length_;
4355 uint8_t state_;
4356 DISALLOW_COPY_AND_ASSIGN(Visitor);
4357 };
4358
4359 static inline void MergeLeafLeft(int* length,
4360 uint8_t* state,
4361 uint8_t leaf_state) {
4362 bool edge_surrogate = StartsWithSurrogate(leaf_state);
4363 if (!(*state & kLeftmostEdgeIsCalculated)) {
4364 ASSERT(!(*state & kLeftmostEdgeIsSurrogate));
4365 *state |= kLeftmostEdgeIsCalculated
4366 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4367 } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4368 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4369 }
4370 if (EndsWithSurrogate(leaf_state)) {
4371 *state |= kEndsWithLeadingSurrogate;
4372 } else {
4373 *state &= ~kEndsWithLeadingSurrogate;
4374 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004375 }
4376
ulan@chromium.org750145a2013-03-07 15:14:13 +00004377 static inline void MergeLeafRight(int* length,
4378 uint8_t* state,
4379 uint8_t leaf_state) {
4380 bool edge_surrogate = EndsWithSurrogate(leaf_state);
4381 if (!(*state & kRightmostEdgeIsCalculated)) {
4382 ASSERT(!(*state & kRightmostEdgeIsSurrogate));
4383 *state |= (kRightmostEdgeIsCalculated
4384 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4385 } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4386 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4387 }
4388 if (StartsWithSurrogate(leaf_state)) {
4389 *state |= kStartsWithTrailingSurrogate;
4390 } else {
4391 *state &= ~kStartsWithTrailingSurrogate;
4392 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004393 }
4394
ulan@chromium.org750145a2013-03-07 15:14:13 +00004395 static inline void MergeTerminal(int* length,
4396 uint8_t state,
4397 uint8_t* state_out) {
4398 ASSERT((state & kLeftmostEdgeIsCalculated) &&
4399 (state & kRightmostEdgeIsCalculated));
4400 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4401 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4402 }
4403 *state_out = kInitialState |
4404 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4405 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4406 }
4407
4408 static int Calculate(i::ConsString* current, uint8_t* state_out) {
4409 using namespace internal;
4410 int total_length = 0;
4411 uint8_t state = kInitialState;
4412 while (true) {
4413 i::String* left = current->first();
4414 i::String* right = current->second();
4415 uint8_t right_leaf_state;
4416 uint8_t left_leaf_state;
4417 int leaf_length;
4418 ConsString* left_as_cons =
4419 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4420 if (left_as_cons == NULL) {
4421 total_length += leaf_length;
4422 MergeLeafLeft(&total_length, &state, left_leaf_state);
4423 }
4424 ConsString* right_as_cons =
4425 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4426 if (right_as_cons == NULL) {
4427 total_length += leaf_length;
4428 MergeLeafRight(&total_length, &state, right_leaf_state);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004429 if (left_as_cons != NULL) {
4430 // 1 Leaf node. Descend in place.
4431 current = left_as_cons;
4432 continue;
4433 } else {
4434 // Terminal node.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004435 MergeTerminal(&total_length, state, state_out);
4436 return total_length;
4437 }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004438 } else if (left_as_cons == NULL) {
4439 // 1 Leaf node. Descend in place.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004440 current = right_as_cons;
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004441 continue;
4442 }
4443 // Both strings are ConsStrings.
4444 // Recurse on smallest.
4445 if (left->length() < right->length()) {
4446 total_length += Calculate(left_as_cons, &left_leaf_state);
4447 MergeLeafLeft(&total_length, &state, left_leaf_state);
4448 current = right_as_cons;
4449 } else {
4450 total_length += Calculate(right_as_cons, &right_leaf_state);
4451 MergeLeafRight(&total_length, &state, right_leaf_state);
4452 current = left_as_cons;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004453 }
4454 }
4455 UNREACHABLE();
4456 return 0;
4457 }
4458
4459 static inline int Calculate(i::ConsString* current) {
4460 uint8_t state = kInitialState;
4461 return Calculate(current, &state);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004462 }
4463
4464 private:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004465 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004466};
4467
4468
4469static int Utf8Length(i::String* str, i::Isolate* isolate) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00004470 int length = str->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004471 if (length == 0) return 0;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004472 uint8_t state;
4473 i::ConsString* cons_string =
4474 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4475 if (cons_string == NULL) return length;
4476 return Utf8LengthHelper::Calculate(cons_string);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004477}
4478
4479
4480int String::Utf8Length() const {
4481 i::Handle<i::String> str = Utils::OpenHandle(this);
4482 i::Isolate* isolate = str->GetIsolate();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004483 return v8::Utf8Length(*str, isolate);
4484}
4485
4486
4487class Utf8WriterVisitor {
4488 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004489 Utf8WriterVisitor(
4490 char* buffer, int capacity, bool skip_capacity_check)
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004491 : early_termination_(false),
4492 last_character_(unibrow::Utf16::kNoPreviousCharacter),
4493 buffer_(buffer),
4494 start_(buffer),
4495 capacity_(capacity),
ulan@chromium.org750145a2013-03-07 15:14:13 +00004496 skip_capacity_check_(capacity == -1 || skip_capacity_check),
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004497 utf16_chars_read_(0) {
4498 }
4499
4500 static int WriteEndCharacter(uint16_t character,
4501 int last_character,
4502 int remaining,
4503 char* const buffer) {
4504 using namespace unibrow;
4505 ASSERT(remaining > 0);
4506 // We can't use a local buffer here because Encode needs to modify
4507 // previous characters in the stream. We know, however, that
4508 // exactly one character will be advanced.
4509 if (Utf16::IsTrailSurrogate(character) &&
4510 Utf16::IsLeadSurrogate(last_character)) {
4511 int written = Utf8::Encode(buffer, character, last_character);
4512 ASSERT(written == 1);
4513 return written;
4514 }
4515 // Use a scratch buffer to check the required characters.
4516 char temp_buffer[Utf8::kMaxEncodedSize];
4517 // Can't encode using last_character as gcc has array bounds issues.
4518 int written = Utf8::Encode(temp_buffer,
4519 character,
ulan@chromium.org750145a2013-03-07 15:14:13 +00004520 Utf16::kNoPreviousCharacter);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004521 // Won't fit.
4522 if (written > remaining) return 0;
4523 // Copy over the character from temp_buffer.
4524 for (int j = 0; j < written; j++) {
4525 buffer[j] = temp_buffer[j];
4526 }
4527 return written;
4528 }
4529
4530 template<typename Char>
4531 void Visit(const Char* chars, const int length) {
4532 using namespace unibrow;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004533 ASSERT(!early_termination_);
ulan@chromium.org750145a2013-03-07 15:14:13 +00004534 if (length == 0) return;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004535 // Copy state to stack.
4536 char* buffer = buffer_;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004537 int last_character =
4538 sizeof(Char) == 1 ? Utf16::kNoPreviousCharacter : last_character_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004539 int i = 0;
4540 // Do a fast loop where there is no exit capacity check.
4541 while (true) {
4542 int fast_length;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004543 if (skip_capacity_check_) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004544 fast_length = length;
4545 } else {
4546 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4547 // Need enough space to write everything but one character.
4548 STATIC_ASSERT(Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
ulan@chromium.org750145a2013-03-07 15:14:13 +00004549 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
4550 int writable_length =
4551 (remaining_capacity - max_size_per_char)/max_size_per_char;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004552 // Need to drop into slow loop.
4553 if (writable_length <= 0) break;
4554 fast_length = i + writable_length;
4555 if (fast_length > length) fast_length = length;
4556 }
4557 // Write the characters to the stream.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004558 if (sizeof(Char) == 1) {
4559 for (; i < fast_length; i++) {
4560 buffer +=
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004561 Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
ulan@chromium.org750145a2013-03-07 15:14:13 +00004562 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
4563 }
4564 } else {
4565 for (; i < fast_length; i++) {
4566 uint16_t character = *chars++;
4567 buffer += Utf8::Encode(buffer, character, last_character);
4568 last_character = character;
4569 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
4570 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004571 }
4572 // Array is fully written. Exit.
4573 if (fast_length == length) {
4574 // Write state back out to object.
4575 last_character_ = last_character;
4576 buffer_ = buffer;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004577 utf16_chars_read_ += length;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004578 return;
4579 }
4580 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004581 ASSERT(!skip_capacity_check_);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004582 // Slow loop. Must check capacity on each iteration.
4583 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4584 ASSERT(remaining_capacity >= 0);
4585 for (; i < length && remaining_capacity > 0; i++) {
4586 uint16_t character = *chars++;
4587 int written = WriteEndCharacter(character,
4588 last_character,
4589 remaining_capacity,
4590 buffer);
4591 if (written == 0) {
4592 early_termination_ = true;
4593 break;
4594 }
4595 buffer += written;
4596 remaining_capacity -= written;
4597 last_character = character;
4598 }
4599 // Write state back out to object.
4600 last_character_ = last_character;
4601 buffer_ = buffer;
4602 utf16_chars_read_ += i;
4603 }
4604
4605 inline bool IsDone() {
4606 return early_termination_;
4607 }
4608
ulan@chromium.org750145a2013-03-07 15:14:13 +00004609 inline void VisitOneByteString(const uint8_t* chars, int length) {
4610 Visit(chars, length);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004611 }
4612
ulan@chromium.org750145a2013-03-07 15:14:13 +00004613 inline void VisitTwoByteString(const uint16_t* chars, int length) {
4614 Visit(chars, length);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004615 }
4616
ulan@chromium.org750145a2013-03-07 15:14:13 +00004617 int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004618 // Write out number of utf16 characters written to the stream.
4619 if (utf16_chars_read_out != NULL) {
4620 *utf16_chars_read_out = utf16_chars_read_;
4621 }
4622 // Only null terminate if all of the string was written and there's space.
4623 if (write_null &&
4624 !early_termination_ &&
4625 (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
4626 *buffer_++ = '\0';
4627 }
4628 return static_cast<int>(buffer_ - start_);
4629 }
4630
4631 private:
4632 bool early_termination_;
4633 int last_character_;
4634 char* buffer_;
4635 char* const start_;
4636 int capacity_;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004637 bool const skip_capacity_check_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004638 int utf16_chars_read_;
4639 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
4640};
4641
4642
ulan@chromium.org750145a2013-03-07 15:14:13 +00004643static bool RecursivelySerializeToUtf8(i::String* current,
4644 Utf8WriterVisitor* writer,
4645 int recursion_budget) {
4646 while (!writer->IsDone()) {
4647 i::ConsString* cons_string = i::String::VisitFlat(writer, current);
4648 if (cons_string == NULL) return true; // Leaf node.
4649 if (recursion_budget <= 0) return false;
4650 // Must write the left branch first.
4651 i::String* first = cons_string->first();
4652 bool success = RecursivelySerializeToUtf8(first,
4653 writer,
4654 recursion_budget - 1);
4655 if (!success) return false;
4656 // Inline tail recurse for right branch.
4657 current = cons_string->second();
4658 }
4659 return true;
4660}
4661
4662
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00004663int String::WriteUtf8(char* buffer,
4664 int capacity,
4665 int* nchars_ref,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004666 int options) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004667 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004668 LOG_API(isolate, "String::WriteUtf8");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004669 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00004670 i::Handle<i::String> str = Utils::OpenHandle(this);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004671 if (options & HINT_MANY_WRITES_EXPECTED) {
4672 FlattenString(str); // Flatten the string for efficiency.
4673 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004674 const int string_length = str->length();
4675 bool write_null = !(options & NO_NULL_TERMINATION);
4676 // First check if we can just write the string without checking capacity.
4677 if (capacity == -1 || capacity / 3 >= string_length) {
4678 Utf8WriterVisitor writer(buffer, capacity, true);
4679 const int kMaxRecursion = 100;
4680 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
4681 if (success) return writer.CompleteWrite(write_null, nchars_ref);
4682 } else if (capacity >= string_length) {
4683 // First check that the buffer is large enough.
4684 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
4685 if (utf8_bytes <= capacity) {
4686 // ASCII fast path.
4687 if (utf8_bytes == string_length) {
4688 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
4689 if (nchars_ref != NULL) *nchars_ref = string_length;
4690 if (write_null && (utf8_bytes+1 <= capacity)) {
4691 return string_length + 1;
4692 }
4693 return string_length;
4694 }
4695 if (write_null && (utf8_bytes+1 > capacity)) {
4696 options |= NO_NULL_TERMINATION;
4697 }
4698 // Recurse once without a capacity limit.
4699 // This will get into the first branch above.
4700 // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
4701 return WriteUtf8(buffer, -1, nchars_ref, options);
danno@chromium.org88aa0582012-03-23 15:11:57 +00004702 }
4703 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004704 // Recursive slow path can potentially be unreasonable slow. Flatten.
4705 str = FlattenGetString(str);
4706 Utf8WriterVisitor writer(buffer, capacity, false);
4707 i::String::VisitFlat(&writer, *str);
4708 return writer.CompleteWrite(write_null, nchars_ref);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00004709}
4710
4711
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004712template<typename CharType>
4713static inline int WriteHelper(const String* string,
4714 CharType* buffer,
4715 int start,
4716 int length,
4717 int options) {
4718 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004719 LOG_API(isolate, "String::Write");
4720 ENTER_V8(isolate);
4721 ASSERT(start >= 0 && length >= -1);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004722 i::Handle<i::String> str = Utils::OpenHandle(string);
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004723 isolate->string_tracker()->RecordWrite(str);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004724 if (options & String::HINT_MANY_WRITES_EXPECTED) {
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004725 // Flatten the string for efficiency. This applies whether we are
4726 // using StringCharacterStream or Get(i) to access the characters.
4727 FlattenString(str);
4728 }
4729 int end = start + length;
4730 if ((length == -1) || (length > str->length() - start) )
4731 end = str->length();
4732 if (end < 0) return 0;
4733 i::String::WriteToFlat(*str, buffer, start, end);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004734 if (!(options & String::NO_NULL_TERMINATION) &&
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004735 (length == -1 || end - start < length)) {
4736 buffer[end - start] = '\0';
4737 }
4738 return end - start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004739}
4740
4741
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004742int String::WriteOneByte(uint8_t* buffer,
4743 int start,
4744 int length,
4745 int options) const {
4746 return WriteHelper(this, buffer, start, length, options);
4747}
4748
4749
4750int String::Write(uint16_t* buffer,
4751 int start,
4752 int length,
4753 int options) const {
4754 return WriteHelper(this, buffer, start, length, options);
4755}
4756
4757
ager@chromium.org32912102009-01-16 10:38:43 +00004758bool v8::String::IsExternal() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004759 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004760 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004761 return i::StringShape(*str).IsExternalTwoByte();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004762}
4763
4764
ager@chromium.org32912102009-01-16 10:38:43 +00004765bool v8::String::IsExternalAscii() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004766 i::Handle<i::String> str = Utils::OpenHandle(this);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004767 return i::StringShape(*str).IsExternalAscii();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004768}
4769
4770
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004771void v8::String::VerifyExternalStringResource(
4772 v8::String::ExternalStringResource* value) const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004773 i::Handle<i::String> str = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004774 const v8::String::ExternalStringResource* expected;
ager@chromium.org9085a012009-05-11 19:22:57 +00004775 if (i::StringShape(*str).IsExternalTwoByte()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004776 const void* resource =
4777 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4778 expected = reinterpret_cast<const ExternalStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004779 } else {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004780 expected = NULL;
ager@chromium.org9085a012009-05-11 19:22:57 +00004781 }
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004782 CHECK_EQ(expected, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004783}
4784
ulan@chromium.org56c14af2012-09-20 12:51:09 +00004785void v8::String::VerifyExternalStringResourceBase(
4786 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
4787 i::Handle<i::String> str = Utils::OpenHandle(this);
4788 const v8::String::ExternalStringResourceBase* expected;
4789 Encoding expectedEncoding;
4790 if (i::StringShape(*str).IsExternalAscii()) {
4791 const void* resource =
4792 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
4793 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4794 expectedEncoding = ASCII_ENCODING;
4795 } else if (i::StringShape(*str).IsExternalTwoByte()) {
4796 const void* resource =
4797 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4798 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4799 expectedEncoding = TWO_BYTE_ENCODING;
4800 } else {
4801 expected = NULL;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004802 expectedEncoding = str->IsOneByteRepresentation() ? ASCII_ENCODING
ulan@chromium.org56c14af2012-09-20 12:51:09 +00004803 : TWO_BYTE_ENCODING;
4804 }
4805 CHECK_EQ(expected, value);
4806 CHECK_EQ(expectedEncoding, encoding);
4807}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004808
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004809const v8::String::ExternalAsciiStringResource*
ager@chromium.org32912102009-01-16 10:38:43 +00004810 v8::String::GetExternalAsciiStringResource() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004811 i::Handle<i::String> str = Utils::OpenHandle(this);
ager@chromium.org9085a012009-05-11 19:22:57 +00004812 if (i::StringShape(*str).IsExternalAscii()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004813 const void* resource =
4814 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
4815 return reinterpret_cast<const ExternalAsciiStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004816 } else {
4817 return NULL;
4818 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004819}
4820
4821
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004822Local<Value> Symbol::Name() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004823 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
4824 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
4825 return Utils::ToLocal(name);
4826}
4827
4828
ager@chromium.org32912102009-01-16 10:38:43 +00004829double Number::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004830 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4831 return obj->Number();
4832}
4833
4834
ager@chromium.org32912102009-01-16 10:38:43 +00004835bool Boolean::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004836 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4837 return obj->IsTrue();
4838}
4839
4840
ager@chromium.org32912102009-01-16 10:38:43 +00004841int64_t Integer::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004842 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4843 if (obj->IsSmi()) {
4844 return i::Smi::cast(*obj)->value();
4845 } else {
4846 return static_cast<int64_t>(obj->Number());
4847 }
4848}
4849
4850
ager@chromium.org32912102009-01-16 10:38:43 +00004851int32_t Int32::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004852 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4853 if (obj->IsSmi()) {
4854 return i::Smi::cast(*obj)->value();
4855 } else {
4856 return static_cast<int32_t>(obj->Number());
4857 }
4858}
4859
4860
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004861uint32_t Uint32::Value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004862 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4863 if (obj->IsSmi()) {
4864 return i::Smi::cast(*obj)->value();
4865 } else {
4866 return static_cast<uint32_t>(obj->Number());
4867 }
4868}
4869
4870
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004871int v8::Object::InternalFieldCount() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004872 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004873 return obj->GetInternalFieldCount();
4874}
4875
4876
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004877static bool InternalFieldOK(i::Handle<i::JSObject> obj,
4878 int index,
4879 const char* location) {
machenbach@chromium.orgae161032013-09-24 09:12:30 +00004880 return ApiCheck(index < obj->GetInternalFieldCount(),
4881 location,
4882 "Internal field out of bounds");
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004883}
4884
4885
4886Local<Value> v8::Object::SlowGetInternalField(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004887 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004888 const char* location = "v8::Object::GetInternalField()";
4889 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
4890 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
4891 return Utils::ToLocal(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004892}
4893
4894
kasper.lund212ac232008-07-16 07:07:30 +00004895void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004896 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004897 const char* location = "v8::Object::SetInternalField()";
4898 if (!InternalFieldOK(obj, index, location)) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004899 i::Handle<i::Object> val = Utils::OpenHandle(*value);
4900 obj->SetInternalField(index, *val);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004901 ASSERT_EQ(value, GetInternalField(index));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004902}
4903
4904
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004905void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
4906 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4907 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
4908 if (!InternalFieldOK(obj, index, location)) return NULL;
4909 return DecodeSmiToAligned(obj->GetInternalField(index), location);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004910}
4911
4912
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004913void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
4914 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4915 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
4916 if (!InternalFieldOK(obj, index, location)) return;
4917 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
4918 ASSERT_EQ(value, GetAlignedPointerFromInternalField(index));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004919}
4920
4921
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004922static void* ExternalValue(i::Object* obj) {
4923 // Obscure semantics for undefined, but somehow checked in our unit tests...
4924 if (obj->IsUndefined()) return NULL;
4925 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
4926 return i::Foreign::cast(foreign)->foreign_address();
4927}
4928
4929
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004930// --- E n v i r o n m e n t ---
4931
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004932
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004933bool v8::V8::Initialize() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00004934 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004935 if (isolate != NULL && isolate->IsInitialized()) {
4936 return true;
4937 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004938 return InitializeHelper(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004939}
4940
4941
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00004942void v8::V8::SetEntropySource(EntropySource entropy_source) {
4943 i::RandomNumberGenerator::SetEntropySource(entropy_source);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00004944}
4945
4946
ulan@chromium.org967e2702012-02-28 09:49:15 +00004947void v8::V8::SetReturnAddressLocationResolver(
4948 ReturnAddressLocationResolver return_address_resolver) {
4949 i::V8::SetReturnAddressLocationResolver(return_address_resolver);
4950}
4951
4952
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004953bool v8::V8::SetFunctionEntryHook(Isolate* ext_isolate,
4954 FunctionEntryHook entry_hook) {
4955 ASSERT(ext_isolate != NULL);
4956 ASSERT(entry_hook != NULL);
4957
4958 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(ext_isolate);
4959
4960 // The entry hook can only be set before the Isolate is initialized, as
4961 // otherwise the Isolate's code stubs generated at initialization won't
4962 // contain entry hooks.
4963 if (isolate->IsInitialized())
4964 return false;
4965
4966 // Setting an entry hook is a one-way operation, once set, it cannot be
4967 // changed or unset.
4968 if (isolate->function_entry_hook() != NULL)
4969 return false;
4970
4971 isolate->set_function_entry_hook(entry_hook);
4972 return true;
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004973}
4974
4975
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004976void v8::V8::SetJitCodeEventHandler(
4977 JitCodeEventOptions options, JitCodeEventHandler event_handler) {
4978 i::Isolate* isolate = i::Isolate::Current();
4979 // Ensure that logging is initialized for our isolate.
4980 isolate->InitializeLoggingAndCounters();
4981 isolate->logger()->SetCodeEventHandler(options, event_handler);
4982}
4983
ulan@chromium.org837a67e2013-06-11 15:39:48 +00004984void v8::V8::SetArrayBufferAllocator(
4985 ArrayBuffer::Allocator* allocator) {
4986 if (!ApiCheck(i::V8::ArrayBufferAllocator() == NULL,
4987 "v8::V8::SetArrayBufferAllocator",
4988 "ArrayBufferAllocator might only be set once"))
4989 return;
4990 i::V8::SetArrayBufferAllocator(allocator);
4991}
4992
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004993
ager@chromium.org41826e72009-03-30 13:30:57 +00004994bool v8::V8::Dispose() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004995 i::Isolate* isolate = i::Isolate::Current();
4996 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
4997 "v8::V8::Dispose()",
4998 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
4999 return false;
5000 }
ager@chromium.org41826e72009-03-30 13:30:57 +00005001 i::V8::TearDown();
5002 return true;
5003}
5004
5005
ager@chromium.org01fe7df2010-11-10 11:59:11 +00005006HeapStatistics::HeapStatistics(): total_heap_size_(0),
5007 total_heap_size_executable_(0),
danno@chromium.org72204d52012-10-31 10:02:10 +00005008 total_physical_size_(0),
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005009 used_heap_size_(0),
5010 heap_size_limit_(0) { }
ager@chromium.org3811b432009-10-28 14:53:37 +00005011
5012
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005013void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
5014 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005015 isolate->heap()->VisitExternalResources(visitor);
5016}
5017
5018
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005019class VisitorAdapter : public i::ObjectVisitor {
5020 public:
5021 explicit VisitorAdapter(PersistentHandleVisitor* visitor)
5022 : visitor_(visitor) {}
5023 virtual void VisitPointers(i::Object** start, i::Object** end) {
5024 UNREACHABLE();
5025 }
5026 virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00005027 Value* value = ToApi<Value>(i::Handle<i::Object>(p));
5028 visitor_->VisitPersistentHandle(
5029 reinterpret_cast<Persistent<Value>*>(&value), class_id);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005030 }
5031 private:
5032 PersistentHandleVisitor* visitor_;
5033};
5034
5035
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005036void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
5037 i::Isolate* isolate = i::Isolate::Current();
rossberg@chromium.org79e79022013-06-03 15:43:46 +00005038 i::DisallowHeapAllocation no_allocation;
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005039
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005040 VisitorAdapter visitor_adapter(visitor);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005041 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
5042}
5043
5044
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005045void v8::V8::VisitHandlesForPartialDependence(
5046 Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
5047 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
5048 ASSERT(isolate == i::Isolate::Current());
rossberg@chromium.org79e79022013-06-03 15:43:46 +00005049 i::DisallowHeapAllocation no_allocation;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005050
5051 VisitorAdapter visitor_adapter(visitor);
5052 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
5053 &visitor_adapter);
5054}
5055
5056
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00005057bool v8::V8::IdleNotification(int hint) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00005058 // Returning true tells the caller that it need not
5059 // continue to call IdleNotification.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005060 i::Isolate* isolate = i::Isolate::Current();
5061 if (isolate == NULL || !isolate->IsInitialized()) return true;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00005062 if (!i::FLAG_use_idle_notification) return true;
5063 return isolate->heap()->IdleNotification(hint);
ager@chromium.orgadd848f2009-08-13 12:44:13 +00005064}
5065
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005066
5067void v8::V8::LowMemoryNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005068 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005069 if (isolate == NULL || !isolate->IsInitialized()) return;
rossberg@chromium.org994edf62012-02-06 10:12:55 +00005070 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005071}
5072
5073
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00005074int v8::V8::ContextDisposedNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005075 i::Isolate* isolate = i::Isolate::Current();
5076 if (!isolate->IsInitialized()) return 0;
5077 return isolate->heap()->NotifyContextDisposed();
kasperl@chromium.org8b2bb262010-03-01 09:46:28 +00005078}
5079
5080
danno@chromium.org169691d2013-07-15 08:01:13 +00005081bool v8::V8::InitializeICU() {
5082 return i::InitializeICU();
5083}
5084
5085
kasper.lund7276f142008-07-30 08:49:36 +00005086const char* v8::V8::GetVersion() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005087 return i::Version::GetVersion();
kasper.lund7276f142008-07-30 08:49:36 +00005088}
5089
5090
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005091static i::Handle<i::Context> CreateEnvironment(
5092 i::Isolate* isolate,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005093 v8::ExtensionConfiguration* extensions,
5094 v8::Handle<ObjectTemplate> global_template,
5095 v8::Handle<Value> global_object) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005096 i::Handle<i::Context> env;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005097
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005098 // Enter V8 via an ENTER_V8 scope.
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005099 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005100 ENTER_V8(isolate);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005101 v8::Handle<ObjectTemplate> proxy_template = global_template;
5102 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5103 i::Handle<i::FunctionTemplateInfo> global_constructor;
ager@chromium.org8bb60582008-12-11 12:02:20 +00005104
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005105 if (!global_template.IsEmpty()) {
5106 // Make sure that the global_template has a constructor.
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00005107 global_constructor = EnsureConstructor(*global_template);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005108
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005109 // Create a fresh template for the global proxy object.
5110 proxy_template = ObjectTemplate::New();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00005111 proxy_constructor = EnsureConstructor(*proxy_template);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005112
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005113 // Set the global template to be the prototype template of
5114 // global proxy template.
5115 proxy_constructor->set_prototype_template(
5116 *Utils::OpenHandle(*global_template));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005117
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005118 // Migrate security handlers from global_template to
5119 // proxy_template. Temporarily removing access check
5120 // information from the global template.
5121 if (!global_constructor->access_check_info()->IsUndefined()) {
5122 proxy_constructor->set_access_check_info(
5123 global_constructor->access_check_info());
5124 proxy_constructor->set_needs_access_check(
5125 global_constructor->needs_access_check());
5126 global_constructor->set_needs_access_check(false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005127 global_constructor->set_access_check_info(
5128 isolate->heap()->undefined_value());
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005129 }
5130 }
5131
5132 // Create the environment.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005133 env = isolate->bootstrapper()->CreateEnvironment(
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00005134 Utils::OpenHandle(*global_object, true),
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005135 proxy_template,
5136 extensions);
5137
5138 // Restore the access check info on the global template.
5139 if (!global_template.IsEmpty()) {
5140 ASSERT(!global_constructor.is_null());
5141 ASSERT(!proxy_constructor.is_null());
5142 global_constructor->set_access_check_info(
5143 proxy_constructor->access_check_info());
5144 global_constructor->set_needs_access_check(
5145 proxy_constructor->needs_access_check());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005146 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005147 isolate->runtime_profiler()->Reset();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005148 }
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005149 // Leave V8.
ager@chromium.org8bb60582008-12-11 12:02:20 +00005150
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005151 return env;
5152}
5153
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005154Local<Context> v8::Context::New(
5155 v8::Isolate* external_isolate,
5156 v8::ExtensionConfiguration* extensions,
5157 v8::Handle<ObjectTemplate> global_template,
5158 v8::Handle<Value> global_object) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005159 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5160 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
5161 LOG_API(isolate, "Context::New");
5162 ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
5163 i::HandleScope scope(isolate);
5164 i::Handle<i::Context> env =
5165 CreateEnvironment(isolate, extensions, global_template, global_object);
5166 if (env.is_null()) return Local<Context>();
5167 return Utils::ToLocal(scope.CloseAndEscape(env));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005168}
5169
5170
5171void v8::Context::SetSecurityToken(Handle<Value> token) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005172 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005173 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005174 i::Handle<i::Context> env = Utils::OpenHandle(this);
5175 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005176 env->set_security_token(*token_handle);
5177}
5178
5179
5180void v8::Context::UseDefaultSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005181 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005182 ENTER_V8(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005183 i::Handle<i::Context> env = Utils::OpenHandle(this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005184 env->set_security_token(env->global_object());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005185}
5186
5187
5188Handle<Value> v8::Context::GetSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005189 i::Isolate* isolate = i::Isolate::Current();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005190 i::Handle<i::Context> env = Utils::OpenHandle(this);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005191 i::Object* security_token = env->security_token();
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005192 i::Handle<i::Object> token_handle(security_token, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005193 return Utils::ToLocal(token_handle);
5194}
5195
5196
5197bool Context::HasOutOfMemoryException() {
5198 i::Handle<i::Context> env = Utils::OpenHandle(this);
5199 return env->has_out_of_memory();
5200}
5201
5202
5203bool Context::InContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005204 return i::Isolate::Current()->context() != NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005205}
5206
5207
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005208v8::Isolate* Context::GetIsolate() {
5209 i::Handle<i::Context> env = Utils::OpenHandle(this);
5210 return reinterpret_cast<Isolate*>(env->GetIsolate());
5211}
5212
5213
kasper.lund44510672008-07-25 07:37:58 +00005214v8::Local<v8::Context> Context::GetEntered() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005215 i::Isolate* isolate = i::Isolate::Current();
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00005216 if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005217 return Local<Context>();
5218 }
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005219 return reinterpret_cast<Isolate*>(isolate)->GetEnteredContext();
kasper.lund44510672008-07-25 07:37:58 +00005220}
5221
5222
5223v8::Local<v8::Context> Context::GetCurrent() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005224 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005225 return reinterpret_cast<Isolate*>(isolate)->GetCurrentContext();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005226}
5227
5228
ager@chromium.org1bf0cd02009-05-20 11:34:19 +00005229v8::Local<v8::Context> Context::GetCalling() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005230 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005231 return reinterpret_cast<Isolate*>(isolate)->GetCallingContext();
ager@chromium.org1bf0cd02009-05-20 11:34:19 +00005232}
5233
5234
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005235v8::Local<v8::Object> Context::Global() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005236 i::Handle<i::Context> context = Utils::OpenHandle(this);
5237 i::Isolate* isolate = context->GetIsolate();
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005238 i::Handle<i::Object> global(context->global_proxy(), isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005239 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5240}
5241
5242
5243void Context::DetachGlobal() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005244 i::Handle<i::Context> context = Utils::OpenHandle(this);
5245 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005246 ENTER_V8(isolate);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005247 isolate->bootstrapper()->DetachGlobal(context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005248}
5249
5250
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00005251void Context::ReattachGlobal(Handle<Object> global_object) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005252 i::Handle<i::Context> context = Utils::OpenHandle(this);
5253 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005254 ENTER_V8(isolate);
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00005255 i::Handle<i::JSGlobalProxy> global_proxy =
5256 i::Handle<i::JSGlobalProxy>::cast(Utils::OpenHandle(*global_object));
5257 isolate->bootstrapper()->ReattachGlobal(context, global_proxy);
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00005258}
5259
5260
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005261void Context::AllowCodeGenerationFromStrings(bool allow) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005262 i::Handle<i::Context> context = Utils::OpenHandle(this);
5263 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005264 ENTER_V8(isolate);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005265 context->set_allow_code_gen_from_strings(
5266 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5267}
5268
5269
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00005270bool Context::IsCodeGenerationFromStringsAllowed() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005271 i::Handle<i::Context> context = Utils::OpenHandle(this);
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00005272 return !context->allow_code_gen_from_strings()->IsFalse();
5273}
5274
5275
ulan@chromium.org56c14af2012-09-20 12:51:09 +00005276void Context::SetErrorMessageForCodeGenerationFromStrings(
5277 Handle<String> error) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005278 i::Handle<i::Context> context = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005279 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00005280 context->set_error_message_for_code_gen_from_strings(*error_handle);
5281}
5282
5283
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005284Local<v8::Object> ObjectTemplate::NewInstance() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005285 i::Isolate* isolate = i::Isolate::Current();
5286 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
5287 return Local<v8::Object>());
5288 LOG_API(isolate, "ObjectTemplate::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005289 ENTER_V8(isolate);
5290 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005291 i::Handle<i::Object> obj =
5292 i::Execution::InstantiateObject(Utils::OpenHandle(this),
5293 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005294 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005295 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
5296}
5297
5298
5299Local<v8::Function> FunctionTemplate::GetFunction() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005300 i::Isolate* isolate = i::Isolate::Current();
5301 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005302 return Local<v8::Function>());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005303 LOG_API(isolate, "FunctionTemplate::GetFunction");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005304 ENTER_V8(isolate);
5305 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005306 i::Handle<i::Object> obj =
5307 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
5308 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005309 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005310 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
5311}
5312
5313
5314bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005315 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
5316 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005317 i::Object* obj = *Utils::OpenHandle(*value);
5318 return obj->IsInstanceOf(*Utils::OpenHandle(this));
5319}
5320
5321
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005322Local<External> v8::External::New(void* value) {
5323 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005324 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005325 EnsureInitializedForIsolate(isolate, "v8::External::New()");
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005326 LOG_API(isolate, "External::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005327 ENTER_V8(isolate);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005328 i::Handle<i::JSObject> external = isolate->factory()->NewExternal(value);
5329 return Utils::ExternalToLocal(external);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005330}
5331
5332
5333void* External::Value() const {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005334 return ExternalValue(*Utils::OpenHandle(this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005335}
5336
5337
ager@chromium.org563b8dc2009-03-20 14:23:52 +00005338Local<String> v8::String::Empty() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005339 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00005340 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) {
5341 return v8::Local<String>();
5342 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005343 LOG_API(isolate, "String::Empty()");
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005344 return Utils::ToLocal(isolate->factory()->empty_string());
ager@chromium.org563b8dc2009-03-20 14:23:52 +00005345}
5346
5347
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00005348// anonymous namespace for string creation helper functions
5349namespace {
5350
5351inline int StringLength(const char* string) {
5352 return i::StrLength(string);
5353}
5354
5355
5356inline int StringLength(const uint8_t* string) {
5357 return i::StrLength(reinterpret_cast<const char*>(string));
5358}
5359
5360
5361inline int StringLength(const uint16_t* string) {
5362 int length = 0;
5363 while (string[length] != '\0')
5364 length++;
5365 return length;
5366}
5367
5368
5369inline i::Handle<i::String> NewString(i::Factory* factory,
5370 String::NewStringType type,
5371 i::Vector<const char> string) {
5372 if (type ==String::kInternalizedString) {
5373 return factory->InternalizeUtf8String(string);
5374 }
5375 return factory->NewStringFromUtf8(string);
5376}
5377
5378
5379inline i::Handle<i::String> NewString(i::Factory* factory,
5380 String::NewStringType type,
5381 i::Vector<const uint8_t> string) {
5382 if (type == String::kInternalizedString) {
5383 return factory->InternalizeOneByteString(string);
5384 }
5385 return factory->NewStringFromOneByte(string);
5386}
5387
5388
5389inline i::Handle<i::String> NewString(i::Factory* factory,
5390 String::NewStringType type,
5391 i::Vector<const uint16_t> string) {
5392 if (type == String::kInternalizedString) {
5393 return factory->InternalizeTwoByteString(string);
5394 }
5395 return factory->NewStringFromTwoByte(string);
5396}
5397
5398
5399template<typename Char>
5400inline Local<String> NewString(Isolate* v8_isolate,
5401 const char* location,
5402 const char* env,
5403 const Char* data,
5404 String::NewStringType type,
5405 int length) {
5406 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
5407 EnsureInitializedForIsolate(isolate, location);
5408 LOG_API(isolate, env);
5409 if (length == 0 && type != String::kUndetectableString) {
5410 return String::Empty();
5411 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005412 ENTER_V8(isolate);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00005413 if (length == -1) length = StringLength(data);
5414 i::Handle<i::String> result = NewString(
5415 isolate->factory(), type, i::Vector<const Char>(data, length));
5416 if (type == String::kUndetectableString) {
5417 result->MarkAsUndetectable();
5418 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005419 return Utils::ToLocal(result);
5420}
5421
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00005422} // anonymous namespace
5423
5424
5425Local<String> String::NewFromUtf8(Isolate* isolate,
5426 const char* data,
5427 NewStringType type,
5428 int length) {
5429 return NewString(isolate,
5430 "v8::String::NewFromUtf8()",
5431 "String::NewFromUtf8",
5432 data,
5433 type,
5434 length);
5435}
5436
5437
5438Local<String> String::NewFromOneByte(Isolate* isolate,
5439 const uint8_t* data,
5440 NewStringType type,
5441 int length) {
5442 return NewString(isolate,
5443 "v8::String::NewFromOneByte()",
5444 "String::NewFromOneByte",
5445 data,
5446 type,
5447 length);
5448}
5449
5450
5451Local<String> String::NewFromTwoByte(Isolate* isolate,
5452 const uint16_t* data,
5453 NewStringType type,
5454 int length) {
5455 return NewString(isolate,
5456 "v8::String::NewFromTwoByte()",
5457 "String::NewFromTwoByte",
5458 data,
5459 type,
5460 length);
5461}
5462
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005463
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005464Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005465 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005466 i::Isolate* isolate = left_string->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005467 EnsureInitializedForIsolate(isolate, "v8::String::New()");
5468 LOG_API(isolate, "String::New(char)");
5469 ENTER_V8(isolate);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005470 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005471 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
5472 right_string);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005473 return Utils::ToLocal(result);
5474}
5475
5476
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005477i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005478 v8::String::ExternalStringResource* resource) {
5479 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005480 isolate->factory()->NewExternalStringFromTwoByte(resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005481 return result;
5482}
5483
5484
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005485i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005486 v8::String::ExternalAsciiStringResource* resource) {
5487 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005488 isolate->factory()->NewExternalStringFromAscii(resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005489 return result;
5490}
5491
5492
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005493bool RedirectToExternalString(i::Isolate* isolate,
5494 i::Handle<i::String> parent,
5495 i::Handle<i::String> external) {
5496 if (parent->IsConsString()) {
5497 i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent);
5498 cons->set_first(*external);
5499 cons->set_second(isolate->heap()->empty_string());
5500 } else {
5501 ASSERT(parent->IsSlicedString());
5502 i::Handle<i::SlicedString> slice = i::Handle<i::SlicedString>::cast(parent);
5503 slice->set_parent(*external);
5504 slice->set_offset(0);
5505 }
5506 return true;
5507}
5508
5509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005510Local<String> v8::String::NewExternal(
5511 v8::String::ExternalStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005512 i::Isolate* isolate = i::Isolate::Current();
5513 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
5514 LOG_API(isolate, "String::NewExternal");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005515 ENTER_V8(isolate);
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005516 CHECK(resource && resource->data());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005517 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
5518 isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005519 return Utils::ToLocal(result);
5520}
5521
5522
ager@chromium.org6f10e412009-02-13 10:11:16 +00005523bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005524 i::Handle<i::String> obj = Utils::OpenHandle(this);
5525 i::Isolate* isolate = obj->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005526 if (i::StringShape(*obj).IsExternalTwoByte()) {
5527 return false; // Already an external string.
5528 }
5529 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005530 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5531 return false;
5532 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005533 if (isolate->heap()->IsInGCPostProcessing()) {
5534 return false;
5535 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005536 CHECK(resource && resource->data());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005537
5538 bool result;
5539 i::Handle<i::String> external;
5540 if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
5541 // We do not allow external strings in the old pointer space. Instead of
5542 // converting the string in-place, we keep the cons/sliced string and
5543 // point it to a newly-allocated external string.
5544 external = NewExternalStringHandle(isolate, resource);
5545 result = RedirectToExternalString(isolate, obj, external);
5546 } else {
5547 result = obj->MakeExternal(resource);
5548 external = obj;
5549 }
5550
5551 ASSERT(external->IsExternalString());
5552 if (result && !external->IsInternalizedString()) {
5553 isolate->heap()->external_string_table()->AddString(*external);
ager@chromium.org6f10e412009-02-13 10:11:16 +00005554 }
5555 return result;
5556}
5557
5558
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005559Local<String> v8::String::NewExternal(
5560 v8::String::ExternalAsciiStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005561 i::Isolate* isolate = i::Isolate::Current();
5562 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
5563 LOG_API(isolate, "String::NewExternal");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005564 ENTER_V8(isolate);
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005565 CHECK(resource && resource->data());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005566 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
5567 isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005568 return Utils::ToLocal(result);
5569}
5570
5571
ager@chromium.org6f10e412009-02-13 10:11:16 +00005572bool v8::String::MakeExternal(
5573 v8::String::ExternalAsciiStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005574 i::Handle<i::String> obj = Utils::OpenHandle(this);
5575 i::Isolate* isolate = obj->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005576 if (i::StringShape(*obj).IsExternalTwoByte()) {
5577 return false; // Already an external string.
5578 }
5579 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005580 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5581 return false;
5582 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005583 if (isolate->heap()->IsInGCPostProcessing()) {
5584 return false;
5585 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005586 CHECK(resource && resource->data());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005587
5588 bool result;
5589 i::Handle<i::String> external;
5590 if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
5591 // We do not allow external strings in the old pointer space. Instead of
5592 // converting the string in-place, we keep the cons/sliced string and
5593 // point it to a newly-allocated external string.
5594 external = NewExternalAsciiStringHandle(isolate, resource);
5595 result = RedirectToExternalString(isolate, obj, external);
5596 } else {
5597 result = obj->MakeExternal(resource);
5598 external = obj;
5599 }
5600
5601 ASSERT(external->IsExternalString());
5602 if (result && !external->IsInternalizedString()) {
5603 isolate->heap()->external_string_table()->AddString(*external);
ager@chromium.org6f10e412009-02-13 10:11:16 +00005604 }
5605 return result;
5606}
5607
5608
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005609bool v8::String::CanMakeExternal() {
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00005610 if (!internal::FLAG_clever_optimizations) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005611 i::Handle<i::String> obj = Utils::OpenHandle(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005612 i::Isolate* isolate = obj->GetIsolate();
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005613 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005614 int size = obj->Size(); // Byte size of the original string.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005615 if (size < i::ExternalString::kShortSize) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005616 i::StringShape shape(*obj);
5617 return !shape.IsExternal();
5618}
5619
5620
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005621Local<v8::Object> v8::Object::New() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005622 i::Isolate* isolate = i::Isolate::Current();
5623 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
5624 LOG_API(isolate, "Object::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005625 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005626 i::Handle<i::JSObject> obj =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005627 isolate->factory()->NewJSObject(isolate->object_function());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005628 return Utils::ToLocal(obj);
5629}
5630
5631
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005632Local<v8::Value> v8::NumberObject::New(double value) {
5633 i::Isolate* isolate = i::Isolate::Current();
5634 EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
5635 LOG_API(isolate, "NumberObject::New");
5636 ENTER_V8(isolate);
5637 i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
5638 i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
5639 return Utils::ToLocal(obj);
5640}
5641
5642
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005643double v8::NumberObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005644 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005645 LOG_API(isolate, "NumberObject::NumberValue");
5646 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5647 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5648 return jsvalue->value()->Number();
5649}
5650
5651
5652Local<v8::Value> v8::BooleanObject::New(bool value) {
5653 i::Isolate* isolate = i::Isolate::Current();
5654 EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
5655 LOG_API(isolate, "BooleanObject::New");
5656 ENTER_V8(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005657 i::Handle<i::Object> boolean(value
5658 ? isolate->heap()->true_value()
5659 : isolate->heap()->false_value(),
5660 isolate);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005661 i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
5662 return Utils::ToLocal(obj);
5663}
5664
5665
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005666bool v8::BooleanObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005667 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005668 LOG_API(isolate, "BooleanObject::BooleanValue");
5669 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5670 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5671 return jsvalue->value()->IsTrue();
5672}
5673
5674
5675Local<v8::Value> v8::StringObject::New(Handle<String> value) {
5676 i::Isolate* isolate = i::Isolate::Current();
5677 EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
5678 LOG_API(isolate, "StringObject::New");
5679 ENTER_V8(isolate);
5680 i::Handle<i::Object> obj =
5681 isolate->factory()->ToObject(Utils::OpenHandle(*value));
5682 return Utils::ToLocal(obj);
5683}
5684
5685
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005686Local<v8::String> v8::StringObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005687 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005688 LOG_API(isolate, "StringObject::StringValue");
5689 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5690 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5691 return Utils::ToLocal(
5692 i::Handle<i::String>(i::String::cast(jsvalue->value())));
5693}
5694
5695
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005696Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
5697 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5698 EnsureInitializedForIsolate(i_isolate, "v8::SymbolObject::New()");
5699 LOG_API(i_isolate, "SymbolObject::New");
5700 ENTER_V8(i_isolate);
5701 i::Handle<i::Object> obj =
5702 i_isolate->factory()->ToObject(Utils::OpenHandle(*value));
5703 return Utils::ToLocal(obj);
5704}
5705
5706
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005707Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005708 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005709 LOG_API(isolate, "SymbolObject::SymbolValue");
5710 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5711 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5712 return Utils::ToLocal(
5713 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
5714}
5715
5716
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005717Local<v8::Value> v8::Date::New(double time) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005718 i::Isolate* isolate = i::Isolate::Current();
5719 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
5720 LOG_API(isolate, "Date::New");
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00005721 if (std::isnan(time)) {
ager@chromium.org3811b432009-10-28 14:53:37 +00005722 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5723 time = i::OS::nan_value();
5724 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005725 ENTER_V8(isolate);
5726 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005727 i::Handle<i::Object> obj =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00005728 i::Execution::NewDate(isolate, time, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005729 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005730 return Utils::ToLocal(obj);
5731}
5732
5733
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005734double v8::Date::ValueOf() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005735 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005736 LOG_API(isolate, "Date::NumberValue");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005737 i::Handle<i::Object> obj = Utils::OpenHandle(this);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005738 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
5739 return jsdate->value()->Number();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005740}
5741
5742
whesse@chromium.org023421e2010-12-21 12:19:12 +00005743void v8::Date::DateTimeConfigurationChangeNotification() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005744 i::Isolate* isolate = i::Isolate::Current();
5745 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
5746 return);
5747 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005748 ENTER_V8(isolate);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005749
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005750 isolate->date_cache()->ResetDateCache();
5751
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005752 i::HandleScope scope(isolate);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005753 // Get the function ResetDateCache (defined in date.js).
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005754 i::Handle<i::String> func_name_str =
5755 isolate->factory()->InternalizeOneByteString(
5756 STATIC_ASCII_VECTOR("ResetDateCache"));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005757 i::MaybeObject* result =
5758 isolate->js_builtins_object()->GetProperty(*func_name_str);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005759 i::Object* object_func;
5760 if (!result->ToObject(&object_func)) {
5761 return;
5762 }
5763
5764 if (object_func->IsJSFunction()) {
5765 i::Handle<i::JSFunction> func =
5766 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
5767
5768 // Call ResetDateCache(0 but expect no exceptions:
5769 bool caught_exception = false;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005770 i::Execution::TryCall(func,
5771 isolate->js_builtins_object(),
5772 0,
5773 NULL,
5774 &caught_exception);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005775 }
5776}
5777
5778
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005779static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00005780 i::Isolate* isolate = i::Isolate::Current();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00005781 uint8_t flags_buf[3];
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005782 int num_flags = 0;
5783 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
5784 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
5785 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
5786 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00005787 return isolate->factory()->InternalizeOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00005788 i::Vector<const uint8_t>(flags_buf, num_flags));
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005789}
5790
5791
5792Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
5793 Flags flags) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005794 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005795 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
5796 LOG_API(isolate, "RegExp::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005797 ENTER_V8(isolate);
5798 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005799 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
5800 Utils::OpenHandle(*pattern),
5801 RegExpFlagsToString(flags),
5802 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005803 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005804 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
5805}
5806
5807
5808Local<v8::String> v8::RegExp::GetSource() const {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005809 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5810 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
5811}
5812
5813
5814// Assert that the static flags cast in GetFlags is valid.
5815#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
5816 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
5817 static_cast<int>(i::JSRegExp::internal_flag))
5818REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
5819REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
5820REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
5821REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
5822#undef REGEXP_FLAG_ASSERT_EQ
5823
5824v8::RegExp::Flags v8::RegExp::GetFlags() const {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005825 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5826 return static_cast<RegExp::Flags>(obj->GetFlags().value());
5827}
5828
5829
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005830Local<v8::Array> v8::Array::New(int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005831 i::Isolate* isolate = i::Isolate::Current();
5832 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
5833 LOG_API(isolate, "Array::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005834 ENTER_V8(isolate);
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00005835 int real_length = length > 0 ? length : 0;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005836 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005837 i::Handle<i::Object> length_obj =
5838 isolate->factory()->NewNumberFromInt(real_length);
5839 obj->set_length(*length_obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005840 return Utils::ToLocal(obj);
5841}
5842
5843
ager@chromium.org32912102009-01-16 10:38:43 +00005844uint32_t v8::Array::Length() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005845 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
5846 i::Object* length = obj->length();
5847 if (length->IsSmi()) {
5848 return i::Smi::cast(length)->value();
5849 } else {
5850 return static_cast<uint32_t>(length->Number());
5851 }
5852}
5853
5854
ager@chromium.org3e875802009-06-29 08:26:34 +00005855Local<Object> Array::CloneElementAt(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005856 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005857 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005858 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005859 if (!self->HasFastObjectElements()) {
ager@chromium.org3e875802009-06-29 08:26:34 +00005860 return Local<Object>();
5861 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005862 i::FixedArray* elms = i::FixedArray::cast(self->elements());
ager@chromium.org3e875802009-06-29 08:26:34 +00005863 i::Object* paragon = elms->get(index);
5864 if (!paragon->IsJSObject()) {
5865 return Local<Object>();
5866 }
5867 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005868 EXCEPTION_PREAMBLE(isolate);
5869 ENTER_V8(isolate);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005870 i::Handle<i::JSObject> result = i::JSObject::Copy(paragon_handle);
ager@chromium.org3e875802009-06-29 08:26:34 +00005871 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005872 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005873 return Utils::ToLocal(result);
5874}
5875
5876
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005877bool v8::ArrayBuffer::IsExternal() const {
5878 return Utils::OpenHandle(this)->is_external();
5879}
5880
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00005881
ulan@chromium.org837a67e2013-06-11 15:39:48 +00005882v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005883 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5884 ApiCheck(!obj->is_external(),
5885 "v8::ArrayBuffer::Externalize",
5886 "ArrayBuffer already externalized");
5887 obj->set_is_external(true);
5888 size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
ulan@chromium.org837a67e2013-06-11 15:39:48 +00005889 Contents contents;
5890 contents.data_ = obj->backing_store();
5891 contents.byte_length_ = byte_length;
5892 return contents;
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005893}
5894
5895
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005896void v8::ArrayBuffer::Neuter() {
5897 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5898 i::Isolate* isolate = obj->GetIsolate();
5899 ApiCheck(obj->is_external(),
5900 "v8::ArrayBuffer::Neuter",
5901 "Only externalized ArrayBuffers can be neutered");
5902 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
5903 ENTER_V8(isolate);
5904
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005905 for (i::Handle<i::Object> view_obj(obj->weak_first_view(), isolate);
5906 !view_obj->IsUndefined();) {
5907 i::Handle<i::JSArrayBufferView> view(i::JSArrayBufferView::cast(*view_obj));
5908 if (view->IsJSTypedArray()) {
5909 i::JSTypedArray::cast(*view)->Neuter();
5910 } else if (view->IsJSDataView()) {
5911 i::JSDataView::cast(*view)->Neuter();
5912 } else {
5913 UNREACHABLE();
5914 }
5915 view_obj = i::handle(view->weak_next(), isolate);
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005916 }
5917 obj->Neuter();
5918}
5919
5920
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005921size_t v8::ArrayBuffer::ByteLength() const {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005922 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5923 return static_cast<size_t>(obj->byte_length()->Number());
5924}
5925
5926
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005927Local<ArrayBuffer> v8::ArrayBuffer::New(size_t byte_length) {
5928 i::Isolate* isolate = i::Isolate::Current();
5929 EnsureInitializedForIsolate(isolate, "v8::ArrayBuffer::New(size_t)");
5930 LOG_API(isolate, "v8::ArrayBuffer::New(size_t)");
5931 ENTER_V8(isolate);
5932 i::Handle<i::JSArrayBuffer> obj =
5933 isolate->factory()->NewJSArrayBuffer();
5934 i::Runtime::SetupArrayBufferAllocatingData(isolate, obj, byte_length);
5935 return Utils::ToLocal(obj);
5936}
5937
5938
5939Local<ArrayBuffer> v8::ArrayBuffer::New(void* data, size_t byte_length) {
5940 i::Isolate* isolate = i::Isolate::Current();
5941 EnsureInitializedForIsolate(isolate, "v8::ArrayBuffer::New(void*, size_t)");
5942 LOG_API(isolate, "v8::ArrayBuffer::New(void*, size_t)");
5943 ENTER_V8(isolate);
5944 i::Handle<i::JSArrayBuffer> obj =
5945 isolate->factory()->NewJSArrayBuffer();
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005946 i::Runtime::SetupArrayBuffer(isolate, obj, true, data, byte_length);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005947 return Utils::ToLocal(obj);
5948}
5949
5950
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005951Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
5952 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005953 ASSERT(obj->buffer()->IsJSArrayBuffer());
5954 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(obj->buffer()));
5955 return Utils::ToLocal(buffer);
5956}
5957
5958
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005959size_t v8::ArrayBufferView::ByteOffset() {
5960 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005961 return static_cast<size_t>(obj->byte_offset()->Number());
5962}
5963
5964
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005965size_t v8::ArrayBufferView::ByteLength() {
5966 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005967 return static_cast<size_t>(obj->byte_length()->Number());
5968}
5969
5970
5971size_t v8::TypedArray::Length() {
danno@chromium.orgf005df62013-04-30 16:36:45 +00005972 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
5973 return static_cast<size_t>(obj->length()->Number());
5974}
5975
5976
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005977static inline void SetupArrayBufferView(
5978 i::Isolate* isolate,
5979 i::Handle<i::JSArrayBufferView> obj,
5980 i::Handle<i::JSArrayBuffer> buffer,
5981 size_t byte_offset,
5982 size_t byte_length) {
5983 ASSERT(byte_offset + byte_length <=
5984 static_cast<size_t>(buffer->byte_length()->Number()));
danno@chromium.orgf005df62013-04-30 16:36:45 +00005985
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005986 obj->set_buffer(*buffer);
5987
5988 obj->set_weak_next(buffer->weak_first_view());
5989 buffer->set_weak_first_view(*obj);
5990
5991 i::Handle<i::Object> byte_offset_object =
5992 isolate->factory()->NewNumberFromSize(byte_offset);
5993 obj->set_byte_offset(*byte_offset_object);
5994
5995 i::Handle<i::Object> byte_length_object =
5996 isolate->factory()->NewNumberFromSize(byte_length);
5997 obj->set_byte_length(*byte_length_object);
5998}
danno@chromium.orgf005df62013-04-30 16:36:45 +00005999
6000template<typename ElementType,
6001 ExternalArrayType array_type,
6002 i::ElementsKind elements_kind>
6003i::Handle<i::JSTypedArray> NewTypedArray(
6004 i::Isolate* isolate,
6005 Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
6006 i::Handle<i::JSTypedArray> obj =
6007 isolate->factory()->NewJSTypedArray(array_type);
6008 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6009
6010 ASSERT(byte_offset % sizeof(ElementType) == 0);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006011
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006012 SetupArrayBufferView(
6013 isolate, obj, buffer, byte_offset, length * sizeof(ElementType));
danno@chromium.orgf005df62013-04-30 16:36:45 +00006014
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006015 i::Handle<i::Object> length_object =
6016 isolate->factory()->NewNumberFromSize(length);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006017 obj->set_length(*length_object);
6018
6019 i::Handle<i::ExternalArray> elements =
6020 isolate->factory()->NewExternalArray(
6021 static_cast<int>(length), array_type,
6022 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006023 obj->set_elements(*elements);
6024 return obj;
6025}
6026
6027
6028#define TYPED_ARRAY_NEW(TypedArray, element_type, array_type, elements_kind) \
6029 Local<TypedArray> TypedArray::New(Handle<ArrayBuffer> array_buffer, \
6030 size_t byte_offset, size_t length) { \
6031 i::Isolate* isolate = i::Isolate::Current(); \
6032 EnsureInitializedForIsolate(isolate, \
6033 "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
6034 LOG_API(isolate, \
6035 "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
6036 ENTER_V8(isolate); \
6037 i::Handle<i::JSTypedArray> obj = \
6038 NewTypedArray<element_type, array_type, elements_kind>( \
6039 isolate, array_buffer, byte_offset, length); \
6040 return Utils::ToLocal##TypedArray(obj); \
6041 }
6042
6043
6044TYPED_ARRAY_NEW(Uint8Array, uint8_t, kExternalUnsignedByteArray,
6045 i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS)
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006046TYPED_ARRAY_NEW(Uint8ClampedArray, uint8_t, kExternalPixelArray,
6047 i::EXTERNAL_PIXEL_ELEMENTS)
danno@chromium.orgf005df62013-04-30 16:36:45 +00006048TYPED_ARRAY_NEW(Int8Array, int8_t, kExternalByteArray,
6049 i::EXTERNAL_BYTE_ELEMENTS)
6050TYPED_ARRAY_NEW(Uint16Array, uint16_t, kExternalUnsignedShortArray,
6051 i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS)
6052TYPED_ARRAY_NEW(Int16Array, int16_t, kExternalShortArray,
6053 i::EXTERNAL_SHORT_ELEMENTS)
6054TYPED_ARRAY_NEW(Uint32Array, uint32_t, kExternalUnsignedIntArray,
6055 i::EXTERNAL_UNSIGNED_INT_ELEMENTS)
6056TYPED_ARRAY_NEW(Int32Array, int32_t, kExternalIntArray,
6057 i::EXTERNAL_INT_ELEMENTS)
6058TYPED_ARRAY_NEW(Float32Array, float, kExternalFloatArray,
6059 i::EXTERNAL_FLOAT_ELEMENTS)
6060TYPED_ARRAY_NEW(Float64Array, double, kExternalDoubleArray,
6061 i::EXTERNAL_DOUBLE_ELEMENTS)
6062
6063#undef TYPED_ARRAY_NEW
6064
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006065Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
6066 size_t byte_offset, size_t byte_length) {
6067 i::Isolate* isolate = i::Isolate::Current();
6068 EnsureInitializedForIsolate(
6069 isolate, "v8::DataView::New(void*, size_t, size_t)");
6070 LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
6071 ENTER_V8(isolate);
6072 i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
6073 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6074 SetupArrayBufferView(
6075 isolate, obj, buffer, byte_offset, byte_length);
6076 return Utils::ToLocal(obj);
6077}
6078
danno@chromium.orgf005df62013-04-30 16:36:45 +00006079
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006080Local<Symbol> v8::Symbol::New(Isolate* isolate) {
6081 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6082 EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()");
6083 LOG_API(i_isolate, "Symbol::New()");
6084 ENTER_V8(i_isolate);
6085 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6086 return Utils::ToLocal(result);
6087}
6088
6089
6090Local<Symbol> v8::Symbol::New(Isolate* isolate, const char* data, int length) {
6091 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6092 EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()");
6093 LOG_API(i_isolate, "Symbol::New(char)");
6094 ENTER_V8(i_isolate);
6095 if (length == -1) length = i::StrLength(data);
6096 i::Handle<i::String> name = i_isolate->factory()->NewStringFromUtf8(
6097 i::Vector<const char>(data, length));
6098 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6099 result->set_name(*name);
6100 return Utils::ToLocal(result);
6101}
6102
6103
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006104Local<Number> v8::Number::New(double value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006105 i::Isolate* isolate = i::Isolate::Current();
6106 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00006107 return Number::New(reinterpret_cast<Isolate*>(isolate), value);
6108}
6109
6110
6111Local<Number> v8::Number::New(Isolate* isolate, double value) {
6112 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6113 ASSERT(internal_isolate->IsInitialized());
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00006114 if (std::isnan(value)) {
ager@chromium.org3811b432009-10-28 14:53:37 +00006115 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6116 value = i::OS::nan_value();
6117 }
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00006118 ENTER_V8(internal_isolate);
6119 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006120 return Utils::NumberToLocal(result);
6121}
6122
6123
6124Local<Integer> v8::Integer::New(int32_t value) {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00006125 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006126 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006127 return v8::Integer::New(value, reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006128}
6129
6130
ager@chromium.org3811b432009-10-28 14:53:37 +00006131Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006132 i::Isolate* isolate = i::Isolate::Current();
6133 EnsureInitializedForIsolate(isolate, "v8::Integer::NewFromUnsigned()");
6134 return Integer::NewFromUnsigned(value, reinterpret_cast<Isolate*>(isolate));
6135}
6136
6137
6138Local<Integer> v8::Integer::New(int32_t value, Isolate* isolate) {
6139 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6140 ASSERT(internal_isolate->IsInitialized());
6141 if (i::Smi::IsValid(value)) {
6142 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
6143 internal_isolate));
6144 }
6145 ENTER_V8(internal_isolate);
6146 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
6147 return Utils::IntegerToLocal(result);
6148}
6149
6150
6151Local<Integer> v8::Integer::NewFromUnsigned(uint32_t value, Isolate* isolate) {
6152 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6153 ASSERT(internal_isolate->IsInitialized());
ager@chromium.org3811b432009-10-28 14:53:37 +00006154 bool fits_into_int32_t = (value & (1 << 31)) == 0;
6155 if (fits_into_int32_t) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006156 return Integer::New(static_cast<int32_t>(value), isolate);
ager@chromium.org3811b432009-10-28 14:53:37 +00006157 }
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006158 ENTER_V8(internal_isolate);
6159 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
ager@chromium.org3811b432009-10-28 14:53:37 +00006160 return Utils::IntegerToLocal(result);
6161}
6162
6163
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006164#ifdef DEBUG
rossberg@chromium.org79e79022013-06-03 15:43:46 +00006165v8::AssertNoGCScope::AssertNoGCScope(v8::Isolate* isolate) {
6166 disallow_heap_allocation_ = new i::DisallowHeapAllocation();
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006167}
6168
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006169
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006170v8::AssertNoGCScope::~AssertNoGCScope() {
rossberg@chromium.org79e79022013-06-03 15:43:46 +00006171 delete static_cast<i::DisallowHeapAllocation*>(disallow_heap_allocation_);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006172}
6173#endif
6174
6175
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006176void V8::IgnoreOutOfMemoryException() {
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00006177 EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006178}
6179
6180
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006181bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006182 i::Isolate* isolate = i::Isolate::Current();
6183 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
6184 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006185 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006186 i::HandleScope scope(isolate);
6187 NeanderArray listeners(isolate->factory()->message_listeners());
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006188 NeanderObject obj(2);
6189 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
6190 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
6191 : *Utils::OpenHandle(*data));
6192 listeners.add(obj.value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006193 return true;
6194}
6195
6196
6197void V8::RemoveMessageListeners(MessageCallback that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006198 i::Isolate* isolate = i::Isolate::Current();
6199 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
6200 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006201 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006202 i::HandleScope scope(isolate);
6203 NeanderArray listeners(isolate->factory()->message_listeners());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006204 for (int i = 0; i < listeners.length(); i++) {
6205 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
6206
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006207 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
6208 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00006209 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006210 listeners.set(i, isolate->heap()->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006211 }
6212 }
6213}
6214
6215
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00006216void V8::SetCaptureStackTraceForUncaughtExceptions(
6217 bool capture,
6218 int frame_limit,
6219 StackTrace::StackTraceOptions options) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006220 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00006221 capture,
6222 frame_limit,
6223 options);
6224}
6225
6226
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006227void V8::SetCounterFunction(CounterLookupCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006228 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006229 isolate->stats_table()->SetCounterFunction(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006230}
6231
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006232
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006233void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006234 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006235 isolate->stats_table()->SetCreateHistogramFunction(callback);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006236 isolate->InitializeLoggingAndCounters();
6237 isolate->counters()->ResetHistograms();
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006238}
6239
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006240
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006241void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006242 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006243 isolate->stats_table()->
6244 SetAddHistogramSampleFunction(callback);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006245}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006246
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006247void V8::SetFailedAccessCheckCallbackFunction(
6248 FailedAccessCheckCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006249 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006250 isolate->SetFailedAccessCheckCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006251}
6252
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00006253
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00006254intptr_t Isolate::AdjustAmountOfExternalAllocatedMemory(
6255 intptr_t change_in_bytes) {
6256 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
6257 return heap->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
6258}
6259
6260
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00006261intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006262 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00006263 if (isolate == NULL || !isolate->IsInitialized()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006264 return 0;
6265 }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00006266 Isolate* isolate_ext = reinterpret_cast<Isolate*>(isolate);
6267 return isolate_ext->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
kasper.lund7276f142008-07-30 08:49:36 +00006268}
6269
6270
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006271HeapProfiler* Isolate::GetHeapProfiler() {
6272 i::HeapProfiler* heap_profiler =
6273 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
6274 return reinterpret_cast<HeapProfiler*>(heap_profiler);
6275}
6276
6277
6278CpuProfiler* Isolate::GetCpuProfiler() {
6279 i::CpuProfiler* cpu_profiler =
6280 reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
6281 return reinterpret_cast<CpuProfiler*>(cpu_profiler);
6282}
6283
6284
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006285bool Isolate::InContext() {
6286 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6287 return isolate->context() != NULL;
6288}
6289
6290
mvstanton@chromium.org40ce96b2013-04-09 09:52:22 +00006291v8::Local<v8::Context> Isolate::GetCurrentContext() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006292 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6293 i::Context* context = isolate->context();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006294 if (context == NULL) return Local<Context>();
6295 i::Context* native_context = context->global_object()->native_context();
6296 if (native_context == NULL) return Local<Context>();
6297 return Utils::ToLocal(i::Handle<i::Context>(native_context));
mvstanton@chromium.org40ce96b2013-04-09 09:52:22 +00006298}
6299
6300
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006301v8::Local<v8::Context> Isolate::GetCallingContext() {
6302 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6303 i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
6304 if (calling.is_null()) return Local<Context>();
6305 return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
6306}
6307
6308
6309v8::Local<v8::Context> Isolate::GetEnteredContext() {
6310 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6311 i::Handle<i::Object> last =
6312 isolate->handle_scope_implementer()->LastEnteredContext();
6313 if (last.is_null()) return Local<Context>();
6314 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
6315}
6316
6317
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00006318v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
6319 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6320 ENTER_V8(isolate);
6321 // If we're passed an empty handle, we throw an undefined exception
6322 // to deal more gracefully with out of memory situations.
6323 if (value.IsEmpty()) {
6324 isolate->ScheduleThrow(isolate->heap()->undefined_value());
6325 } else {
6326 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
6327 }
6328 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6329}
6330
6331
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006332void Isolate::SetObjectGroupId(const Persistent<Value>& object,
6333 UniqueId id) {
6334 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6335 internal_isolate->global_handles()->SetObjectGroupId(
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006336 Utils::OpenPersistent(object).location(),
6337 id);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006338}
6339
6340
6341void Isolate::SetReferenceFromGroup(UniqueId id,
6342 const Persistent<Value>& object) {
6343 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006344 internal_isolate->global_handles()->SetReferenceFromGroup(
6345 id,
6346 Utils::OpenPersistent(object).location());
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006347}
6348
6349
6350void Isolate::SetReference(const Persistent<Object>& parent,
6351 const Persistent<Value>& child) {
6352 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006353 i::Object** parent_location = Utils::OpenPersistent(parent).location();
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006354 internal_isolate->global_handles()->SetReference(
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006355 reinterpret_cast<i::HeapObject**>(parent_location),
6356 Utils::OpenPersistent(child).location());
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006357}
6358
6359
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006360void Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
6361 GCType gc_type) {
6362 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6363 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006364}
6365
6366
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006367void Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
6368 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6369 isolate->heap()->RemoveGCPrologueCallback(callback);
6370}
6371
6372
6373void Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
6374 GCType gc_type) {
6375 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6376 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
6377}
6378
6379
6380void Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
6381 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6382 isolate->heap()->RemoveGCEpilogueCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006383}
6384
6385
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006386void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006387 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006388 isolate->heap()->AddGCPrologueCallback(
6389 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
6390 gc_type,
6391 false);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006392}
6393
6394
6395void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006396 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006397 isolate->heap()->RemoveGCPrologueCallback(
6398 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006399}
6400
6401
6402void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006403 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006404 isolate->heap()->AddGCEpilogueCallback(
6405 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
6406 gc_type,
6407 false);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006408}
6409
6410
6411void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006412 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006413 isolate->heap()->RemoveGCEpilogueCallback(
6414 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006415}
6416
6417
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006418void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
6419 ObjectSpace space,
6420 AllocationAction action) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006421 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006422 isolate->memory_allocator()->AddMemoryAllocationCallback(
6423 callback, space, action);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006424}
6425
6426
6427void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006428 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006429 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
6430 callback);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006431}
6432
6433
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006434void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
6435 if (callback == NULL) return;
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006436 i::V8::AddCallCompletedCallback(callback);
6437}
6438
6439
6440void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006441 i::V8::RemoveCallCompletedCallback(callback);
6442}
6443
6444
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006445void V8::TerminateExecution(Isolate* isolate) {
6446 // If no isolate is supplied, use the default isolate.
6447 if (isolate != NULL) {
6448 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
6449 } else {
6450 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
6451 }
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00006452}
6453
6454
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00006455bool V8::IsExecutionTerminating(Isolate* isolate) {
6456 i::Isolate* i_isolate = isolate != NULL ?
6457 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
6458 return IsExecutionTerminatingCheck(i_isolate);
sgjesse@chromium.org2ab99522010-03-10 09:03:43 +00006459}
6460
6461
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006462void V8::CancelTerminateExecution(Isolate* isolate) {
6463 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6464 i_isolate->stack_guard()->CancelTerminateExecution();
6465}
6466
6467
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006468Isolate* Isolate::GetCurrent() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00006469 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006470 return reinterpret_cast<Isolate*>(isolate);
6471}
6472
6473
6474Isolate* Isolate::New() {
6475 i::Isolate* isolate = new i::Isolate();
6476 return reinterpret_cast<Isolate*>(isolate);
6477}
6478
6479
6480void Isolate::Dispose() {
6481 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6482 if (!ApiCheck(!isolate->IsInUse(),
6483 "v8::Isolate::Dispose()",
6484 "Disposing the isolate that is entered by a thread.")) {
6485 return;
6486 }
6487 isolate->TearDown();
6488}
6489
6490
6491void Isolate::Enter() {
6492 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6493 isolate->Enter();
6494}
6495
6496
6497void Isolate::Exit() {
6498 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6499 isolate->Exit();
6500}
6501
6502
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00006503void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
6504 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006505 if (!isolate->IsInitialized()) {
6506 heap_statistics->total_heap_size_ = 0;
6507 heap_statistics->total_heap_size_executable_ = 0;
6508 heap_statistics->total_physical_size_ = 0;
6509 heap_statistics->used_heap_size_ = 0;
6510 heap_statistics->heap_size_limit_ = 0;
6511 return;
6512 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00006513 i::Heap* heap = isolate->heap();
6514 heap_statistics->total_heap_size_ = heap->CommittedMemory();
6515 heap_statistics->total_heap_size_executable_ =
6516 heap->CommittedMemoryExecutable();
6517 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
6518 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
6519 heap_statistics->heap_size_limit_ = heap->MaxReserved();
6520}
6521
6522
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006523String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
6524 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006525 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006526 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006527 ENTER_V8(isolate);
6528 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006529 TryCatch try_catch;
6530 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006531 if (str.IsEmpty()) return;
yangguo@chromium.org154ff992012-03-13 08:09:54 +00006532 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00006533 length_ = v8::Utf8Length(*i_str, isolate);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006534 str_ = i::NewArray<char>(length_ + 1);
6535 str->WriteUtf8(str_);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006536}
6537
6538
6539String::Utf8Value::~Utf8Value() {
6540 i::DeleteArray(str_);
6541}
6542
6543
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006544String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
6545 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006546 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006547 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006548 ENTER_V8(isolate);
6549 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006550 TryCatch try_catch;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006551 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006552 if (str.IsEmpty()) return;
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006553 length_ = str->Utf8Length();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006554 str_ = i::NewArray<char>(length_ + 1);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006555 str->WriteUtf8(str_);
6556 ASSERT(i::String::NonAsciiStart(str_, length_) >= length_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006557}
6558
6559
6560String::AsciiValue::~AsciiValue() {
6561 i::DeleteArray(str_);
6562}
6563
6564
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006565String::Value::Value(v8::Handle<v8::Value> obj)
6566 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006567 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006568 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006569 ENTER_V8(isolate);
6570 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006571 TryCatch try_catch;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006572 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006573 if (str.IsEmpty()) return;
6574 length_ = str->Length();
6575 str_ = i::NewArray<uint16_t>(length_ + 1);
6576 str->Write(str_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006577}
6578
6579
6580String::Value::~Value() {
6581 i::DeleteArray(str_);
6582}
6583
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006585Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006586 i::Isolate* isolate = i::Isolate::Current();
6587 LOG_API(isolate, "RangeError");
6588 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006589 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006590 i::Object* error;
6591 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006592 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006593 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006594 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006595 error = *result;
6596 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006597 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006598 return Utils::ToLocal(result);
6599}
6600
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006602Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006603 i::Isolate* isolate = i::Isolate::Current();
6604 LOG_API(isolate, "ReferenceError");
6605 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006606 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006607 i::Object* error;
6608 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006609 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006610 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006611 i::Handle<i::Object> result =
6612 isolate->factory()->NewReferenceError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006613 error = *result;
6614 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006615 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006616 return Utils::ToLocal(result);
6617}
6618
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006619
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006620Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006621 i::Isolate* isolate = i::Isolate::Current();
6622 LOG_API(isolate, "SyntaxError");
6623 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006624 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006625 i::Object* error;
6626 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006627 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006628 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006629 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006630 error = *result;
6631 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006632 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006633 return Utils::ToLocal(result);
6634}
6635
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006636
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006637Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006638 i::Isolate* isolate = i::Isolate::Current();
6639 LOG_API(isolate, "TypeError");
6640 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006641 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006642 i::Object* error;
6643 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006644 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006645 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006646 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006647 error = *result;
6648 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006649 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006650 return Utils::ToLocal(result);
6651}
6652
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006654Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006655 i::Isolate* isolate = i::Isolate::Current();
6656 LOG_API(isolate, "Error");
6657 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006658 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006659 i::Object* error;
6660 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006661 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006662 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006663 i::Handle<i::Object> result = isolate->factory()->NewError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006664 error = *result;
6665 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006666 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006667 return Utils::ToLocal(result);
6668}
6669
6670
6671// --- D e b u g S u p p o r t ---
6672
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006673#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00006674
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00006675bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006676 i::Isolate* isolate = i::Isolate::Current();
6677 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
6678 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006679 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006680 i::HandleScope scope(isolate);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006681 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
ager@chromium.org381abbb2009-02-25 13:23:22 +00006682 if (that != NULL) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006683 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
ager@chromium.org381abbb2009-02-25 13:23:22 +00006684 }
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00006685 isolate->debugger()->SetEventListener(foreign,
6686 Utils::OpenHandle(*data, true));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006687 return true;
6688}
6689
6690
iposva@chromium.org245aa852009-02-10 00:49:54 +00006691bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006692 Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006693 i::Isolate* isolate = i::Isolate::Current();
6694 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006695 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006696 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00006697 Utils::OpenHandle(*data, true));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006698 return true;
6699}
6700
6701
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006702void Debug::DebugBreak(Isolate* isolate) {
6703 // If no isolate is supplied, use the default isolate.
6704 if (isolate != NULL) {
6705 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
6706 } else {
6707 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
6708 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006709}
6710
6711
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006712void Debug::CancelDebugBreak(Isolate* isolate) {
6713 // If no isolate is supplied, use the default isolate.
6714 if (isolate != NULL) {
6715 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6716 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
6717 } else {
6718 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
6719 }
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00006720}
6721
6722
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006723void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
6724 // If no isolate is supplied, use the default isolate.
6725 if (isolate != NULL) {
6726 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6727 internal_isolate->debugger()->EnqueueDebugCommand(data);
6728 } else {
6729 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
6730 }
mikhail.naganov@gmail.com22762872010-07-14 09:29:05 +00006731}
6732
6733
ager@chromium.org5ec48922009-05-05 07:25:34 +00006734void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006735 i::Isolate* isolate = i::Isolate::Current();
6736 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
6737 ENTER_V8(isolate);
6738 isolate->debugger()->SetMessageHandler(handler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006739}
6740
6741
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006742void Debug::SendCommand(Isolate* isolate,
6743 const uint16_t* command,
6744 int length,
6745 ClientData* client_data) {
6746 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6747 internal_isolate->debugger()->ProcessCommand(
6748 i::Vector<const uint16_t>(command, length), client_data);
6749}
6750
6751
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006752void Debug::SendCommand(const uint16_t* command, int length,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006753 ClientData* client_data,
6754 Isolate* isolate) {
6755 // If no isolate is supplied, use the default isolate.
6756 if (isolate != NULL) {
6757 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6758 internal_isolate->debugger()->ProcessCommand(
6759 i::Vector<const uint16_t>(command, length), client_data);
6760 } else {
6761 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
6762 i::Vector<const uint16_t>(command, length), client_data);
6763 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006764}
6765
6766
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006767void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
6768 int period) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006769 i::Isolate* isolate = i::Isolate::Current();
6770 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
6771 ENTER_V8(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00006772 isolate->debugger()->SetHostDispatchHandler(
6773 handler, i::TimeDelta::FromMilliseconds(period));
ager@chromium.org381abbb2009-02-25 13:23:22 +00006774}
6775
6776
ager@chromium.orgc4c92722009-11-18 14:12:51 +00006777void Debug::SetDebugMessageDispatchHandler(
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006778 DebugMessageDispatchHandler handler, bool provide_locker) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006779 i::Isolate* isolate = i::Isolate::Current();
6780 EnsureInitializedForIsolate(isolate,
6781 "v8::Debug::SetDebugMessageDispatchHandler");
6782 ENTER_V8(isolate);
6783 isolate->debugger()->SetDebugMessageDispatchHandler(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006784 handler, provide_locker);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00006785}
6786
6787
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006788Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
6789 v8::Handle<v8::Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006790 i::Isolate* isolate = i::Isolate::Current();
6791 if (!isolate->IsInitialized()) return Local<Value>();
6792 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006793 ENTER_V8(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006794 i::Handle<i::Object> result;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006795 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006796 if (data.IsEmpty()) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006797 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
6798 isolate->factory()->undefined_value(),
6799 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006800 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006801 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
6802 Utils::OpenHandle(*data),
6803 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006804 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006805 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006806 return Utils::ToLocal(result);
6807}
6808
6809
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006810Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006811 i::Isolate* isolate = i::Isolate::Current();
6812 if (!isolate->IsInitialized()) return Local<Value>();
6813 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006814 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00006815 v8::HandleScope scope(reinterpret_cast<Isolate*>(isolate));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006816 i::Debug* isolate_debug = isolate->debug();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006817 isolate_debug->Load();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00006818 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00006819 i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00006820 STATIC_ASCII_VECTOR("MakeMirror"));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006821 i::Handle<i::Object> fun_obj = i::GetProperty(isolate, debug, name);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006822 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
6823 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
6824 const int kArgc = 1;
6825 v8::Handle<v8::Value> argv[kArgc] = { obj };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006826 EXCEPTION_PREAMBLE(isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006827 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
6828 kArgc,
6829 argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006830 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006831 return scope.Close(result);
6832}
6833
6834
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00006835bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006836 return i::Isolate::Current()->debugger()->StartAgent(name, port,
6837 wait_for_connection);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00006838}
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006839
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006840
6841void Debug::DisableAgent() {
6842 return i::Isolate::Current()->debugger()->StopAgent();
6843}
6844
6845
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006846void Debug::ProcessDebugMessages() {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00006847 i::Execution::ProcessDebugMessages(i::Isolate::Current(), true);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006848}
6849
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00006850
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00006851Local<Context> Debug::GetDebugContext() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006852 i::Isolate* isolate = i::Isolate::Current();
6853 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
6854 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006855 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00006856}
6857
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00006858
6859void Debug::SetLiveEditEnabled(bool enable, Isolate* isolate) {
6860 // If no isolate is supplied, use the default isolate.
6861 i::Debugger* debugger;
6862 if (isolate != NULL) {
6863 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6864 debugger = internal_isolate->debugger();
6865 } else {
6866 debugger = i::Isolate::GetDefaultIsolateDebugger();
6867 }
6868 debugger->set_live_edit_enabled(enable);
6869}
6870
6871
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006872#endif // ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00006873
ager@chromium.org357bf652010-04-12 11:30:10 +00006874
ager@chromium.org357bf652010-04-12 11:30:10 +00006875Handle<String> CpuProfileNode::GetFunctionName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006876 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006877 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6878 const i::CodeEntry* entry = node->entry();
6879 if (!entry->has_name_prefix()) {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006880 return ToApiHandle<String>(
6881 isolate->factory()->InternalizeUtf8String(entry->name()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006882 } else {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006883 return ToApiHandle<String>(isolate->factory()->NewConsString(
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00006884 isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006885 isolate->factory()->InternalizeUtf8String(entry->name())));
ager@chromium.org357bf652010-04-12 11:30:10 +00006886 }
6887}
6888
6889
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00006890int CpuProfileNode::GetScriptId() const {
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00006891 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6892 const i::CodeEntry* entry = node->entry();
6893 return entry->script_id();
6894}
6895
6896
ager@chromium.org357bf652010-04-12 11:30:10 +00006897Handle<String> CpuProfileNode::GetScriptResourceName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006898 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006899 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006900 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
6901 node->entry()->resource_name()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006902}
6903
6904
6905int CpuProfileNode::GetLineNumber() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006906 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
6907}
6908
6909
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00006910const char* CpuProfileNode::GetBailoutReason() const {
6911 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6912 return node->entry()->bailout_reason();
6913}
6914
6915
danno@chromium.org59400602013-08-13 17:09:37 +00006916unsigned CpuProfileNode::GetHitCount() const {
6917 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
6918}
6919
6920
ager@chromium.org357bf652010-04-12 11:30:10 +00006921unsigned CpuProfileNode::GetCallUid() const {
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00006922 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
ager@chromium.org357bf652010-04-12 11:30:10 +00006923}
6924
6925
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006926unsigned CpuProfileNode::GetNodeId() const {
6927 return reinterpret_cast<const i::ProfileNode*>(this)->id();
6928}
6929
6930
ager@chromium.org357bf652010-04-12 11:30:10 +00006931int CpuProfileNode::GetChildrenCount() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006932 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
6933}
6934
6935
6936const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006937 const i::ProfileNode* child =
6938 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
6939 return reinterpret_cast<const CpuProfileNode*>(child);
6940}
6941
6942
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006943void CpuProfile::Delete() {
6944 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006945 i::CpuProfiler* profiler = isolate->cpu_profiler();
6946 ASSERT(profiler != NULL);
6947 profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006948 if (profiler->GetProfilesCount() == 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006949 // If this was the last profile, clean up all accessory data as well.
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006950 profiler->DeleteAllProfiles();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006951 }
6952}
6953
6954
ager@chromium.org357bf652010-04-12 11:30:10 +00006955unsigned CpuProfile::GetUid() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006956 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
6957}
6958
6959
6960Handle<String> CpuProfile::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006961 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006962 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006963 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
6964 profile->title()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006965}
6966
6967
ager@chromium.org357bf652010-04-12 11:30:10 +00006968const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006969 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
6970 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
6971}
6972
6973
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006974const CpuProfileNode* CpuProfile::GetSample(int index) const {
6975 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
6976 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
6977}
6978
6979
danno@chromium.org89acc0b2013-08-09 20:55:58 +00006980int64_t CpuProfile::GetStartTime() const {
6981 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00006982 return (profile->start_time() - i::Time::UnixEpoch()).InMicroseconds();
danno@chromium.org89acc0b2013-08-09 20:55:58 +00006983}
6984
6985
6986int64_t CpuProfile::GetEndTime() const {
6987 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00006988 return (profile->end_time() - i::Time::UnixEpoch()).InMicroseconds();
danno@chromium.org89acc0b2013-08-09 20:55:58 +00006989}
6990
6991
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006992int CpuProfile::GetSamplesCount() const {
6993 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
6994}
6995
6996
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006997int CpuProfiler::GetProfileCount() {
6998 return reinterpret_cast<i::CpuProfiler*>(this)->GetProfilesCount();
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +00006999}
7000
7001
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00007002void CpuProfiler::SetSamplingInterval(int us) {
7003 ASSERT(us >= 0);
7004 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
7005 i::TimeDelta::FromMicroseconds(us));
7006}
7007
7008
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00007009const CpuProfile* CpuProfiler::GetCpuProfile(int index) {
7010 return reinterpret_cast<const CpuProfile*>(
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00007011 reinterpret_cast<i::CpuProfiler*>(this)->GetProfile(index));
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007012}
7013
7014
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007015void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
7016 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
7017 *Utils::OpenHandle(*title), record_samples);
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +00007018}
7019
7020
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00007021const CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title) {
7022 return reinterpret_cast<const CpuProfile*>(
7023 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00007024 *Utils::OpenHandle(*title)));
7025}
7026
7027
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007028void CpuProfiler::DeleteAllCpuProfiles() {
7029 reinterpret_cast<i::CpuProfiler*>(this)->DeleteAllProfiles();
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +00007030}
7031
7032
danno@chromium.org59400602013-08-13 17:09:37 +00007033void CpuProfiler::SetIdle(bool is_idle) {
7034 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
7035 i::StateTag state = isolate->current_vm_state();
7036 ASSERT(state == i::EXTERNAL || state == i::IDLE);
7037 if (isolate->js_entry_sp() != NULL) return;
7038 if (is_idle) {
7039 isolate->set_current_vm_state(i::IDLE);
7040 } else if (state == i::IDLE) {
7041 isolate->set_current_vm_state(i::EXTERNAL);
7042 }
7043}
7044
7045
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007046static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
7047 return const_cast<i::HeapGraphEdge*>(
7048 reinterpret_cast<const i::HeapGraphEdge*>(edge));
7049}
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00007050
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007051
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007052HeapGraphEdge::Type HeapGraphEdge::GetType() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007053 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007054}
7055
7056
7057Handle<Value> HeapGraphEdge::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007058 i::Isolate* isolate = i::Isolate::Current();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007059 i::HeapGraphEdge* edge = ToInternal(this);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007060 switch (edge->type()) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007061 case i::HeapGraphEdge::kContextVariable:
7062 case i::HeapGraphEdge::kInternal:
7063 case i::HeapGraphEdge::kProperty:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00007064 case i::HeapGraphEdge::kShortcut:
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007065 return ToApiHandle<String>(
7066 isolate->factory()->InternalizeUtf8String(edge->name()));
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007067 case i::HeapGraphEdge::kElement:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00007068 case i::HeapGraphEdge::kHidden:
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00007069 case i::HeapGraphEdge::kWeak:
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007070 return ToApiHandle<Number>(
7071 isolate->factory()->NewNumberFromInt(edge->index()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007072 default: UNREACHABLE();
7073 }
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00007074 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007075}
7076
7077
7078const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00007079 const i::HeapEntry* from = ToInternal(this)->from();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007080 return reinterpret_cast<const HeapGraphNode*>(from);
7081}
7082
7083
7084const HeapGraphNode* HeapGraphEdge::GetToNode() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007085 const i::HeapEntry* to = ToInternal(this)->to();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007086 return reinterpret_cast<const HeapGraphNode*>(to);
7087}
7088
7089
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007090static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
7091 return const_cast<i::HeapEntry*>(
7092 reinterpret_cast<const i::HeapEntry*>(entry));
7093}
7094
7095
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007096HeapGraphNode::Type HeapGraphNode::GetType() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007097 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007098}
7099
7100
7101Handle<String> HeapGraphNode::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007102 i::Isolate* isolate = i::Isolate::Current();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007103 return ToApiHandle<String>(
7104 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007105}
7106
7107
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007108SnapshotObjectId HeapGraphNode::GetId() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007109 return ToInternal(this)->id();
ricow@chromium.org4980dff2010-07-19 08:33:45 +00007110}
7111
7112
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007113int HeapGraphNode::GetSelfSize() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007114 return ToInternal(this)->self_size();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007115}
7116
7117
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007118int HeapGraphNode::GetChildrenCount() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007119 return ToInternal(this)->children().length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007120}
7121
7122
7123const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007124 return reinterpret_cast<const HeapGraphEdge*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007125 ToInternal(this)->children()[index]);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007126}
7127
7128
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00007129v8::Handle<v8::Value> HeapGraphNode::GetHeapValue() const {
7130 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00007131 i::Handle<i::HeapObject> object = ToInternal(this)->GetHeapObject();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007132 return !object.is_null() ?
7133 ToApiHandle<Value>(object) :
7134 ToApiHandle<Value>(isolate->factory()->undefined_value());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00007135}
7136
7137
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007138static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
7139 return const_cast<i::HeapSnapshot*>(
7140 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
7141}
7142
7143
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007144void HeapSnapshot::Delete() {
7145 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007146 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007147 ToInternal(this)->Delete();
7148 } else {
7149 // If this is the last snapshot, clean up all accessory data as well.
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007150 isolate->heap_profiler()->DeleteAllSnapshots();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007151 }
7152}
7153
7154
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007155unsigned HeapSnapshot::GetUid() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007156 return ToInternal(this)->uid();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007157}
7158
7159
7160Handle<String> HeapSnapshot::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007161 i::Isolate* isolate = i::Isolate::Current();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007162 return ToApiHandle<String>(
7163 isolate->factory()->InternalizeUtf8String(ToInternal(this)->title()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007164}
7165
7166
ricow@chromium.org4980dff2010-07-19 08:33:45 +00007167const HeapGraphNode* HeapSnapshot::GetRoot() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007168 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007169}
7170
7171
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007172const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007173 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007174 ToInternal(this)->GetEntryById(id));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007175}
7176
7177
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007178int HeapSnapshot::GetNodesCount() const {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007179 return ToInternal(this)->entries().length();
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007180}
7181
7182
7183const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007184 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007185 &ToInternal(this)->entries().at(index));
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007186}
7187
7188
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007189SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007190 return ToInternal(this)->max_snapshot_js_object_id();
7191}
7192
7193
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00007194void HeapSnapshot::Serialize(OutputStream* stream,
7195 HeapSnapshot::SerializationFormat format) const {
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00007196 ApiCheck(format == kJSON,
7197 "v8::HeapSnapshot::Serialize",
7198 "Unknown serialization format");
7199 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
7200 "v8::HeapSnapshot::Serialize",
7201 "Unsupported output encoding");
7202 ApiCheck(stream->GetChunkSize() > 0,
7203 "v8::HeapSnapshot::Serialize",
7204 "Invalid stream chunk size");
7205 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
7206 serializer.Serialize(stream);
7207}
7208
7209
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007210int HeapProfiler::GetSnapshotCount() {
7211 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007212}
7213
7214
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007215const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
7216 return reinterpret_cast<const HeapSnapshot*>(
7217 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007218}
7219
7220
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007221SnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
7222 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
7223 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00007224}
7225
7226
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007227const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
7228 Handle<String> title,
7229 ActivityControl* control,
7230 ObjectNameResolver* resolver) {
7231 return reinterpret_cast<const HeapSnapshot*>(
7232 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
7233 *Utils::OpenHandle(*title), control, resolver));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007234}
7235
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007236
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007237void HeapProfiler::StartTrackingHeapObjects() {
7238 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007239}
7240
7241
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007242void HeapProfiler::StopTrackingHeapObjects() {
7243 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007244}
7245
7246
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007247SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
7248 return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007249}
7250
7251
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007252void HeapProfiler::DeleteAllHeapSnapshots() {
7253 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007254}
7255
7256
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007257void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
7258 WrapperInfoCallback callback) {
7259 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
7260 callback);
7261}
7262
7263
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007264size_t HeapProfiler::GetProfilerMemorySize() {
7265 return reinterpret_cast<i::HeapProfiler*>(this)->
7266 GetMemorySizeUsedByProfiler();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00007267}
7268
7269
danno@chromium.orgca29dd82013-04-26 11:59:48 +00007270void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
7271 RetainedObjectInfo* info) {
7272 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
7273}
7274
7275
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007276v8::Testing::StressType internal::Testing::stress_type_ =
7277 v8::Testing::kStressTypeOpt;
7278
7279
7280void Testing::SetStressRunType(Testing::StressType type) {
7281 internal::Testing::set_stress_type(type);
7282}
7283
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00007284
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007285int Testing::GetStressRuns() {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00007286 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007287#ifdef DEBUG
7288 // In debug mode the code runs much slower so stressing will only make two
7289 // runs.
7290 return 2;
7291#else
7292 return 5;
7293#endif
7294}
7295
7296
7297static void SetFlagsFromString(const char* flags) {
7298 V8::SetFlagsFromString(flags, i::StrLength(flags));
7299}
7300
7301
7302void Testing::PrepareStressRun(int run) {
7303 static const char* kLazyOptimizations =
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00007304 "--prepare-always-opt "
7305 "--max-inlined-source-size=999999 "
7306 "--max-inlined-nodes=999999 "
7307 "--max-inlined-nodes-cumulative=999999 "
7308 "--noalways-opt";
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007309 static const char* kForcedOptimizations = "--always-opt";
7310
7311 // If deoptimization stressed turn on frequent deoptimization. If no value
7312 // is spefified through --deopt-every-n-times use a default default value.
7313 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
7314 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
7315 internal::FLAG_deopt_every_n_times == 0) {
7316 SetFlagsFromString(kDeoptEvery13Times);
7317 }
7318
7319#ifdef DEBUG
7320 // As stressing in debug mode only make two runs skip the deopt stressing
7321 // here.
7322 if (run == GetStressRuns() - 1) {
7323 SetFlagsFromString(kForcedOptimizations);
7324 } else {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007325 SetFlagsFromString(kLazyOptimizations);
7326 }
7327#else
7328 if (run == GetStressRuns() - 1) {
7329 SetFlagsFromString(kForcedOptimizations);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00007330 } else if (run != GetStressRuns() - 2) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007331 SetFlagsFromString(kLazyOptimizations);
7332 }
7333#endif
7334}
7335
7336
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00007337// TODO(svenpanne) Deprecate this.
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007338void Testing::DeoptimizeAll() {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00007339 i::Isolate* isolate = i::Isolate::Current();
7340 i::HandleScope scope(isolate);
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00007341 internal::Deoptimizer::DeoptimizeAll(isolate);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007342}
7343
7344
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007345namespace internal {
7346
7347
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007348void HandleScopeImplementer::FreeThreadResources() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007349 Free();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007350}
7351
7352
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007353char* HandleScopeImplementer::ArchiveThread(char* storage) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00007354 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00007355 isolate_->handle_scope_data();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007356 handle_scope_data_ = *current;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00007357 OS::MemCopy(storage, this, sizeof(*this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007358
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007359 ResetAfterArchive();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007360 current->Initialize();
7361
7362 return storage + ArchiveSpacePerThread();
7363}
7364
7365
7366int HandleScopeImplementer::ArchiveSpacePerThread() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007367 return sizeof(HandleScopeImplementer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007368}
7369
7370
7371char* HandleScopeImplementer::RestoreThread(char* storage) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00007372 OS::MemCopy(this, storage, sizeof(*this));
lrn@chromium.org1c092762011-05-09 09:42:16 +00007373 *isolate_->handle_scope_data() = handle_scope_data_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007374 return storage + ArchiveSpacePerThread();
7375}
7376
7377
ager@chromium.orga1645e22009-09-09 19:27:10 +00007378void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007379#ifdef DEBUG
7380 bool found_block_before_deferred = false;
7381#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007382 // Iterate over all handles in the blocks except for the last.
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007383 for (int i = blocks()->length() - 2; i >= 0; --i) {
7384 Object** block = blocks()->at(i);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007385 if (last_handle_before_deferred_block_ != NULL &&
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00007386 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007387 (last_handle_before_deferred_block_ >= block)) {
7388 v->VisitPointers(block, last_handle_before_deferred_block_);
7389 ASSERT(!found_block_before_deferred);
7390#ifdef DEBUG
7391 found_block_before_deferred = true;
7392#endif
7393 } else {
7394 v->VisitPointers(block, &block[kHandleBlockSize]);
7395 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007396 }
7397
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007398 ASSERT(last_handle_before_deferred_block_ == NULL ||
7399 found_block_before_deferred);
7400
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007401 // Iterate over live handles in the last block (if any).
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007402 if (!blocks()->is_empty()) {
7403 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
ager@chromium.orga1645e22009-09-09 19:27:10 +00007404 }
7405
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00007406 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
7407 for (unsigned i = 0; i < ARRAY_SIZE(context_lists); i++) {
7408 if (context_lists[i]->is_empty()) continue;
7409 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
7410 v->VisitPointers(start, start + context_lists[i]->length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007411 }
7412}
7413
7414
7415void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00007416 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00007417 isolate_->handle_scope_data();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007418 handle_scope_data_ = *current;
7419 IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007420}
7421
7422
7423char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
lrn@chromium.org7516f052011-03-30 08:52:27 +00007424 HandleScopeImplementer* scope_implementer =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007425 reinterpret_cast<HandleScopeImplementer*>(storage);
lrn@chromium.org7516f052011-03-30 08:52:27 +00007426 scope_implementer->IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007427 return storage + ArchiveSpacePerThread();
7428}
7429
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007430
7431DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007432 DeferredHandles* deferred =
7433 new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007434
7435 while (!blocks_.is_empty()) {
7436 Object** block_start = blocks_.last();
7437 Object** block_limit = &block_start[kHandleBlockSize];
rossberg@chromium.org79e79022013-06-03 15:43:46 +00007438 // We should not need to check for SealHandleScope here. Assert this.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007439 ASSERT(prev_limit == block_limit ||
7440 !(block_start <= prev_limit && prev_limit <= block_limit));
7441 if (prev_limit == block_limit) break;
7442 deferred->blocks_.Add(blocks_.last());
7443 blocks_.RemoveLast();
7444 }
7445
7446 // deferred->blocks_ now contains the blocks installed on the
7447 // HandleScope stack since BeginDeferredScope was called, but in
7448 // reverse order.
7449
7450 ASSERT(prev_limit == NULL || !blocks_.is_empty());
7451
7452 ASSERT(!blocks_.is_empty() && prev_limit != NULL);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007453 ASSERT(last_handle_before_deferred_block_ != NULL);
7454 last_handle_before_deferred_block_ = NULL;
7455 return deferred;
7456}
7457
7458
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007459void HandleScopeImplementer::BeginDeferredScope() {
7460 ASSERT(last_handle_before_deferred_block_ == NULL);
7461 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
7462}
7463
7464
7465DeferredHandles::~DeferredHandles() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007466 isolate_->UnlinkDeferredHandles(this);
7467
7468 for (int i = 0; i < blocks_.length(); i++) {
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00007469#ifdef ENABLE_HANDLE_ZAPPING
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007470 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
7471#endif
7472 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
7473 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007474}
7475
7476
7477void DeferredHandles::Iterate(ObjectVisitor* v) {
7478 ASSERT(!blocks_.is_empty());
7479
7480 ASSERT((first_block_limit_ >= blocks_.first()) &&
verwaest@chromium.org753aee42012-07-17 16:15:42 +00007481 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007482
7483 v->VisitPointers(blocks_.first(), first_block_limit_);
7484
7485 for (int i = 1; i < blocks_.length(); i++) {
7486 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
7487 }
7488}
7489
7490
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007491void InvokeAccessorGetterCallback(
7492 v8::Local<v8::String> property,
7493 const v8::PropertyCallbackInfo<v8::Value>& info,
7494 v8::AccessorGetterCallback getter) {
7495 // Leaving JavaScript.
7496 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7497 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
7498 getter));
7499 VMState<EXTERNAL> state(isolate);
7500 ExternalCallbackScope call_scope(isolate, getter_address);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00007501 getter(property, info);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007502}
7503
7504
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007505void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
7506 v8::FunctionCallback callback) {
7507 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7508 Address callback_address =
7509 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
7510 VMState<EXTERNAL> state(isolate);
7511 ExternalCallbackScope call_scope(isolate, callback_address);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00007512 callback(info);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007513}
7514
7515
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007516} } // namespace v8::internal