blob: 5a35cb682c05b4c7aa1c19513ea668d2018f9816 [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 +0000475RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
476
477
478RegisteredExtension::RegisteredExtension(Extension* extension)
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000479 : extension_(extension) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000480
481
482void RegisteredExtension::Register(RegisteredExtension* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000483 that->next_ = first_extension_;
484 first_extension_ = that;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000485}
486
487
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000488void RegisteredExtension::UnregisterAll() {
489 RegisteredExtension* re = first_extension_;
490 while (re != NULL) {
491 RegisteredExtension* next = re->next();
492 delete re;
493 re = next;
494 }
495}
496
497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498void RegisterExtension(Extension* that) {
499 RegisteredExtension* extension = new RegisteredExtension(that);
500 RegisteredExtension::Register(extension);
501}
502
503
504Extension::Extension(const char* name,
505 const char* source,
506 int dep_count,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000507 const char** deps,
508 int source_length)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000509 : name_(name),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000510 source_length_(source_length >= 0 ?
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000511 source_length :
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000512 (source ? static_cast<int>(strlen(source)) : 0)),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000513 source_(source, source_length_),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514 dep_count_(dep_count),
515 deps_(deps),
danno@chromium.org412fa512012-09-14 13:28:26 +0000516 auto_enable_(false) {
517 CHECK(source != NULL || source_length_ == 0);
518}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000519
520
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000521ResourceConstraints::ResourceConstraints()
522 : max_young_space_size_(0),
523 max_old_space_size_(0),
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000524 max_executable_size_(0),
machenbach@chromium.org9af454f2013-11-20 09:25:57 +0000525 stack_limit_(NULL),
526 max_available_threads_(0) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000527
machenbach@chromium.org9af454f2013-11-20 09:25:57 +0000528void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
529 uint32_t number_of_processors) {
machenbach@chromium.orgfeecfde2013-11-14 10:55:00 +0000530 const int lump_of_memory = (i::kPointerSize / 4) * i::MB;
531#if V8_OS_ANDROID
532 // Android has higher physical memory requirements before raising the maximum
533 // heap size limits since it has no swap space.
534 const uint64_t low_limit = 512ul * i::MB;
535 const uint64_t medium_limit = 1ul * i::GB;
536 const uint64_t high_limit = 2ul * i::GB;
537#else
538 const uint64_t low_limit = 512ul * i::MB;
539 const uint64_t medium_limit = 768ul * i::MB;
540 const uint64_t high_limit = 1ul * i::GB;
541#endif
542
543 // The young_space_size should be a power of 2 and old_generation_size should
544 // be a multiple of Page::kPageSize.
545 if (physical_memory <= low_limit) {
546 set_max_young_space_size(2 * lump_of_memory);
547 set_max_old_space_size(128 * lump_of_memory);
548 set_max_executable_size(96 * lump_of_memory);
549 } else if (physical_memory <= medium_limit) {
550 set_max_young_space_size(8 * lump_of_memory);
551 set_max_old_space_size(256 * lump_of_memory);
552 set_max_executable_size(192 * lump_of_memory);
553 } else if (physical_memory <= high_limit) {
554 set_max_young_space_size(16 * lump_of_memory);
555 set_max_old_space_size(512 * lump_of_memory);
556 set_max_executable_size(256 * lump_of_memory);
557 } else {
558 set_max_young_space_size(16 * lump_of_memory);
559 set_max_old_space_size(700 * lump_of_memory);
560 set_max_executable_size(256 * lump_of_memory);
561 }
machenbach@chromium.org9af454f2013-11-20 09:25:57 +0000562
563 set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u));
564}
565
566
verwaest@chromium.org057bd502013-11-06 12:03:29 +0000567bool SetResourceConstraints(Isolate* v8_isolate,
568 ResourceConstraints* constraints) {
569 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ager@chromium.org3811b432009-10-28 14:53:37 +0000570 int young_space_size = constraints->max_young_space_size();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000571 int old_gen_size = constraints->max_old_space_size();
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000572 int max_executable_size = constraints->max_executable_size();
573 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000574 // After initialization it's too late to change Heap constraints.
verwaest@chromium.org057bd502013-11-06 12:03:29 +0000575 ASSERT(!isolate->IsInitialized());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000576 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
577 old_gen_size,
578 max_executable_size);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000579 if (!result) return false;
580 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000581 if (constraints->stack_limit() != NULL) {
582 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000583 isolate->stack_guard()->SetStackLimit(limit);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000584 }
machenbach@chromium.org9af454f2013-11-20 09:25:57 +0000585
586 isolate->set_max_available_threads(constraints->max_available_threads());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587 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,
hpayer@chromium.org4f99be92013-12-18 16:23:55 +0000612 WeakCallback weak_callback) {
613 i::GlobalHandles::MakeWeak(object, parameters, weak_callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000614}
615
616
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000617void V8::ClearWeak(i::Object** obj) {
618 i::GlobalHandles::ClearWeakness(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000619}
620
621
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000622void V8::DisposeGlobal(i::Object** obj) {
623 i::GlobalHandles::Destroy(obj);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000624}
625
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000626
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000627void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
628 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
629 i::Object* object = *Utils::OpenHandle(value);
630 isolate->eternal_handles()->Create(isolate, object, index);
danno@chromium.org59400602013-08-13 17:09:37 +0000631}
632
633
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000634Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
635 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
636 return Utils::ToLocal(isolate->eternal_handles()->Get(index));
danno@chromium.org59400602013-08-13 17:09:37 +0000637}
638
639
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640// --- H a n d l e s ---
641
642
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000643HandleScope::HandleScope(Isolate* isolate) {
644 Initialize(isolate);
645}
646
647
648void HandleScope::Initialize(Isolate* isolate) {
649 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
650 API_ENTRY_CHECK(internal_isolate, "HandleScope::HandleScope");
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000651 v8::ImplementationUtilities::HandleScopeData* current =
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000652 internal_isolate->handle_scope_data();
653 isolate_ = internal_isolate;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000654 prev_next_ = current->next;
655 prev_limit_ = current->limit;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000656 current->level++;
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000657}
658
659
660HandleScope::~HandleScope() {
hpayer@chromium.org4f99be92013-12-18 16:23:55 +0000661 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000662}
663
664
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000665int HandleScope::NumberOfHandles() {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000666 i::Isolate* isolate = i::Isolate::Current();
667 if (!EnsureInitializedForIsolate(isolate, "HandleScope::NumberOfHandles")) {
668 return 0;
669 }
670 return i::HandleScope::NumberOfHandles(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000671}
672
673
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000674i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000675 return i::HandleScope::CreateHandle(isolate, value);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000676}
677
678
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000679i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
680 i::Object* value) {
681 ASSERT(heap_object->IsHeapObject());
682 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
683}
684
685
686EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
687 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
688 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
689 Initialize(v8_isolate);
690}
691
692
693i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
694 ApiCheck(*escape_slot_ == isolate_->heap()->the_hole_value(),
695 "EscapeableHandleScope::Escape",
696 "Escape value set twice");
697 if (escape_value == NULL) {
698 *escape_slot_ = isolate_->heap()->undefined_value();
699 return NULL;
700 }
701 *escape_slot_ = *escape_value;
702 return escape_slot_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000703}
704
705
706void Context::Enter() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000707 i::Handle<i::Context> env = Utils::OpenHandle(this);
708 i::Isolate* isolate = env->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000709 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000710 isolate->handle_scope_implementer()->EnterContext(env);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000711 isolate->handle_scope_implementer()->SaveContext(isolate->context());
712 isolate->set_context(*env);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713}
714
715
716void Context::Exit() {
machenbach@chromium.orgae161032013-09-24 09:12:30 +0000717 // TODO(dcarney): fix this once chrome is fixed.
718 i::Isolate* isolate = i::Isolate::Current();
719 i::Handle<i::Context> context = i::Handle<i::Context>::null();
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000720 ENTER_V8(isolate);
721 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveContext(context),
kasper.lund44510672008-07-25 07:37:58 +0000722 "v8::Context::Exit()",
723 "Cannot exit non-entered context")) {
724 return;
725 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000726 // Content of 'last_context' could be NULL.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000727 i::Context* last_context =
728 isolate->handle_scope_implementer()->RestoreContext();
729 isolate->set_context(last_context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000730}
731
732
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000733static void* DecodeSmiToAligned(i::Object* value, const char* location) {
734 ApiCheck(value->IsSmi(), location, "Not a Smi");
735 return reinterpret_cast<void*>(value);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000736}
737
738
mstarzinger@chromium.org0c977e02013-07-26 10:45:47 +0000739static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
740 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000741 ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
742 return smi;
743}
744
745
746static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
747 int index,
748 bool can_grow,
749 const char* location) {
750 i::Handle<i::Context> env = Utils::OpenHandle(context);
machenbach@chromium.orgae161032013-09-24 09:12:30 +0000751 bool ok =
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000752 ApiCheck(env->IsNativeContext(), location, "Not a native context") &&
753 ApiCheck(index >= 0, location, "Negative index");
754 if (!ok) return i::Handle<i::FixedArray>();
755 i::Handle<i::FixedArray> data(env->embedder_data());
756 if (index < data->length()) return data;
757 if (!can_grow) {
758 Utils::ReportApiFailure(location, "Index too large");
759 return i::Handle<i::FixedArray>();
svenpanne@chromium.orgfc2a4f42012-11-07 09:25:55 +0000760 }
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000761 int new_size = i::Max(index, data->length() << 1) + 1;
762 data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size);
763 env->set_embedder_data(*data);
764 return data;
765}
766
767
768v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
769 const char* location = "v8::Context::GetEmbedderData()";
770 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
771 if (data.is_null()) return Local<Value>();
772 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
ager@chromium.org9085a012009-05-11 19:22:57 +0000773 return Utils::ToLocal(result);
774}
775
776
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000777void Context::SetEmbedderData(int index, v8::Handle<Value> value) {
778 const char* location = "v8::Context::SetEmbedderData()";
779 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
780 if (data.is_null()) return;
781 i::Handle<i::Object> val = Utils::OpenHandle(*value);
782 data->set(index, *val);
783 ASSERT_EQ(*Utils::OpenHandle(*value),
784 *Utils::OpenHandle(*GetEmbedderData(index)));
785}
786
787
788void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
789 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
790 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
791 if (data.is_null()) return NULL;
792 return DecodeSmiToAligned(data->get(index), location);
793}
794
795
796void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
797 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
798 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
799 data->set(index, EncodeAlignedAsSmi(value, location));
800 ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index));
801}
802
803
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804// --- N e a n d e r ---
805
806
807// A constructor cannot easily return an error value, therefore it is necessary
808// to check for a dead VM with ON_BAILOUT before constructing any Neander
809// objects. To remind you about this there is no HandleScope in the
810// NeanderObject constructor. When you add one to the site calling the
811// constructor you should check that you ensured the VM was not dead first.
812NeanderObject::NeanderObject(int size) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000813 i::Isolate* isolate = i::Isolate::Current();
814 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
815 ENTER_V8(isolate);
816 value_ = isolate->factory()->NewNeanderObject();
817 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000818 value_->set_elements(*elements);
819}
820
821
822int NeanderObject::size() {
823 return i::FixedArray::cast(value_->elements())->length();
824}
825
826
827NeanderArray::NeanderArray() : obj_(2) {
828 obj_.set(0, i::Smi::FromInt(0));
829}
830
831
832int NeanderArray::length() {
833 return i::Smi::cast(obj_.get(0))->value();
834}
835
836
837i::Object* NeanderArray::get(int offset) {
838 ASSERT(0 <= offset);
839 ASSERT(offset < length());
840 return obj_.get(offset + 1);
841}
842
843
844// This method cannot easily return an error value, therefore it is necessary
845// to check for a dead VM with ON_BAILOUT before calling it. To remind you
846// about this there is no HandleScope in this method. When you add one to the
847// site calling this method you should check that you ensured the VM was not
848// dead first.
849void NeanderArray::add(i::Handle<i::Object> value) {
850 int length = this->length();
851 int size = obj_.size();
852 if (length == size - 1) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000853 i::Factory* factory = i::Isolate::Current()->factory();
854 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855 for (int i = 0; i < length; i++)
856 new_elms->set(i + 1, get(i));
857 obj_.value()->set_elements(*new_elms);
858 }
859 obj_.set(length + 1, *value);
860 obj_.set(0, i::Smi::FromInt(length + 1));
861}
862
863
864void NeanderArray::set(int index, i::Object* value) {
865 if (index < 0 || index >= this->length()) return;
866 obj_.set(index + 1, value);
867}
868
869
870// --- T e m p l a t e ---
871
872
873static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
874 that->set_tag(i::Smi::FromInt(type));
875}
876
877
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000878static void TemplateSet(i::Isolate* isolate,
879 v8::Template* templ,
880 int length,
881 v8::Handle<v8::Data>* data) {
882 i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
883 if (list->IsUndefined()) {
884 list = NeanderArray().value();
885 Utils::OpenHandle(templ)->set_property_list(*list);
886 }
887 NeanderArray array(list);
ulan@chromium.org0f13e742014-01-03 15:51:11 +0000888 array.add(isolate->factory()->NewNumberFromInt(length));
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000889 for (int i = 0; i < length; i++) {
890 i::Handle<i::Object> value = data[i].IsEmpty() ?
891 i::Handle<i::Object>(isolate->factory()->undefined_value()) :
892 Utils::OpenHandle(*data[i]);
893 array.add(value);
894 }
895}
896
897
898void Template::Set(v8::Handle<String> name,
899 v8::Handle<Data> value,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000900 v8::PropertyAttribute attribute) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000901 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000902 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000903 i::HandleScope scope(isolate);
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000904 const int kSize = 3;
ulan@chromium.org0f13e742014-01-03 15:51:11 +0000905 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000906 v8::Handle<v8::Data> data[kSize] = {
907 name,
908 value,
ulan@chromium.org0f13e742014-01-03 15:51:11 +0000909 v8::Integer::New(v8_isolate, attribute)};
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000910 TemplateSet(isolate, this, kSize, data);
911}
912
913
914void Template::SetAccessorProperty(
915 v8::Local<v8::String> name,
916 v8::Local<FunctionTemplate> getter,
917 v8::Local<FunctionTemplate> setter,
918 v8::PropertyAttribute attribute,
919 v8::AccessControl access_control) {
920 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000921 ENTER_V8(isolate);
922 ASSERT(!name.IsEmpty());
923 ASSERT(!getter.IsEmpty() || !setter.IsEmpty());
924 i::HandleScope scope(isolate);
925 const int kSize = 5;
ulan@chromium.org0f13e742014-01-03 15:51:11 +0000926 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000927 v8::Handle<v8::Data> data[kSize] = {
928 name,
929 getter,
930 setter,
ulan@chromium.org0f13e742014-01-03 15:51:11 +0000931 v8::Integer::New(v8_isolate, attribute),
932 v8::Integer::New(v8_isolate, access_control)};
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000933 TemplateSet(isolate, this, kSize, data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000934}
935
936
937// --- F u n c t i o n T e m p l a t e ---
938static void InitializeFunctionTemplate(
939 i::Handle<i::FunctionTemplateInfo> info) {
940 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
941 info->set_flag(0);
942}
943
944
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000945Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000946 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000947 ENTER_V8(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000948 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
949 isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000950 if (result->IsUndefined()) {
951 result = Utils::OpenHandle(*ObjectTemplate::New());
952 Utils::OpenHandle(this)->set_prototype_template(*result);
953 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000954 return ToApiHandle<ObjectTemplate>(result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000955}
956
957
958void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000959 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000960 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000961 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
962}
963
964
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000965static Local<FunctionTemplate> FunctionTemplateNew(
966 i::Isolate* isolate,
967 FunctionCallback callback,
968 v8::Handle<Value> data,
969 v8::Handle<Signature> signature,
970 int length,
971 bool do_not_cache) {
972 i::Handle<i::Struct> struct_obj =
973 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
974 i::Handle<i::FunctionTemplateInfo> obj =
975 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
976 InitializeFunctionTemplate(obj);
977 obj->set_do_not_cache(do_not_cache);
978 int next_serial_number = 0;
979 if (!do_not_cache) {
980 next_serial_number = isolate->next_serial_number() + 1;
981 isolate->set_next_serial_number(next_serial_number);
982 }
983 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
984 if (callback != 0) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000985 if (data.IsEmpty()) {
986 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
987 }
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000988 Utils::ToLocal(obj)->SetCallHandler(callback, data);
989 }
990 obj->set_length(length);
991 obj->set_undetectable(false);
992 obj->set_needs_access_check(false);
993 if (!signature.IsEmpty())
994 obj->set_signature(*Utils::OpenHandle(*signature));
995 return Utils::ToLocal(obj);
996}
997
verwaest@chromium.org662436e2013-08-28 08:41:27 +0000998Local<FunctionTemplate> FunctionTemplate::New(
machenbach@chromium.org37be4082013-11-26 13:50:38 +0000999 Isolate* isolate,
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001000 FunctionCallback callback,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001001 v8::Handle<Value> data,
1002 v8::Handle<Signature> signature,
1003 int length) {
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001004 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1005 EnsureInitializedForIsolate(i_isolate, "v8::FunctionTemplate::New()");
1006 LOG_API(i_isolate, "FunctionTemplate::New");
1007 ENTER_V8(i_isolate);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00001008 return FunctionTemplateNew(
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001009 i_isolate, callback, data, signature, length, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001010}
1011
1012
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001013Local<Signature> Signature::New(Isolate* isolate,
1014 Handle<FunctionTemplate> receiver, int argc,
1015 Handle<FunctionTemplate> argv[]) {
1016 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1017 EnsureInitializedForIsolate(i_isolate, "v8::Signature::New()");
1018 LOG_API(i_isolate, "Signature::New");
1019 ENTER_V8(i_isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020 i::Handle<i::Struct> struct_obj =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001021 i_isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001022 i::Handle<i::SignatureInfo> obj =
1023 i::Handle<i::SignatureInfo>::cast(struct_obj);
1024 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
1025 if (argc > 0) {
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001026 i::Handle<i::FixedArray> args = i_isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001027 for (int i = 0; i < argc; i++) {
1028 if (!argv[i].IsEmpty())
1029 args->set(i, *Utils::OpenHandle(*argv[i]));
1030 }
1031 obj->set_args(*args);
1032 }
1033 return Utils::ToLocal(obj);
1034}
1035
1036
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001037Local<AccessorSignature> AccessorSignature::New(
1038 Isolate* isolate,
1039 Handle<FunctionTemplate> receiver) {
1040 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1041}
1042
1043
ulan@chromium.org750145a2013-03-07 15:14:13 +00001044template<typename Operation>
1045static Local<Operation> NewDescriptor(
1046 Isolate* isolate,
1047 const i::DeclaredAccessorDescriptorData& data,
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001048 Data* previous_descriptor) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001049 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
1050 i::Handle<i::DeclaredAccessorDescriptor> previous =
1051 i::Handle<i::DeclaredAccessorDescriptor>();
1052 if (previous_descriptor != NULL) {
1053 previous = Utils::OpenHandle(
1054 static_cast<DeclaredAccessorDescriptor*>(previous_descriptor));
1055 }
1056 i::Handle<i::DeclaredAccessorDescriptor> descriptor =
1057 i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001058 return Utils::Convert<i::DeclaredAccessorDescriptor, Operation>(descriptor);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001059}
1060
1061
1062Local<RawOperationDescriptor>
1063 ObjectOperationDescriptor::NewInternalFieldDereference(
1064 Isolate* isolate,
1065 int internal_field) {
1066 i::DeclaredAccessorDescriptorData data;
1067 data.type = i::kDescriptorObjectDereference;
1068 data.object_dereference_descriptor.internal_field = internal_field;
1069 return NewDescriptor<RawOperationDescriptor>(isolate, data, NULL);
1070}
1071
1072
1073Local<RawOperationDescriptor> RawOperationDescriptor::NewRawShift(
1074 Isolate* isolate,
1075 int16_t byte_offset) {
1076 i::DeclaredAccessorDescriptorData data;
1077 data.type = i::kDescriptorPointerShift;
1078 data.pointer_shift_descriptor.byte_offset = byte_offset;
1079 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1080}
1081
1082
1083Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewHandleDereference(
1084 Isolate* isolate) {
1085 i::DeclaredAccessorDescriptorData data;
1086 data.type = i::kDescriptorReturnObject;
1087 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1088}
1089
1090
1091Local<RawOperationDescriptor> RawOperationDescriptor::NewRawDereference(
1092 Isolate* isolate) {
1093 i::DeclaredAccessorDescriptorData data;
1094 data.type = i::kDescriptorPointerDereference;
1095 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1096}
1097
1098
1099Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPointerCompare(
1100 Isolate* isolate,
1101 void* compare_value) {
1102 i::DeclaredAccessorDescriptorData data;
1103 data.type = i::kDescriptorPointerCompare;
1104 data.pointer_compare_descriptor.compare_value = compare_value;
1105 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1106}
1107
1108
1109Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPrimitiveValue(
1110 Isolate* isolate,
1111 DeclaredAccessorDescriptorDataType data_type,
1112 uint8_t bool_offset) {
1113 i::DeclaredAccessorDescriptorData data;
1114 data.type = i::kDescriptorPrimitiveValue;
1115 data.primitive_value_descriptor.data_type = data_type;
1116 data.primitive_value_descriptor.bool_offset = bool_offset;
1117 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1118}
1119
1120
1121template<typename T>
1122static Local<DeclaredAccessorDescriptor> NewBitmaskCompare(
1123 Isolate* isolate,
1124 T bitmask,
1125 T compare_value,
1126 RawOperationDescriptor* operation) {
1127 i::DeclaredAccessorDescriptorData data;
1128 data.type = i::kDescriptorBitmaskCompare;
1129 data.bitmask_compare_descriptor.bitmask = bitmask;
1130 data.bitmask_compare_descriptor.compare_value = compare_value;
1131 data.bitmask_compare_descriptor.size = sizeof(T);
1132 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, operation);
1133}
1134
1135
1136Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare8(
1137 Isolate* isolate,
1138 uint8_t bitmask,
1139 uint8_t compare_value) {
1140 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1141}
1142
1143
1144Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare16(
1145 Isolate* isolate,
1146 uint16_t bitmask,
1147 uint16_t compare_value) {
1148 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1149}
1150
1151
1152Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare32(
1153 Isolate* isolate,
1154 uint32_t bitmask,
1155 uint32_t compare_value) {
1156 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1157}
1158
1159
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001160Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
1161 Handle<FunctionTemplate> types[1] = { type };
1162 return TypeSwitch::New(1, types);
1163}
1164
1165
1166Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001167 i::Isolate* isolate = i::Isolate::Current();
1168 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
1169 LOG_API(isolate, "TypeSwitch::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001170 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001171 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001172 for (int i = 0; i < argc; i++)
1173 vector->set(i, *Utils::OpenHandle(*types[i]));
1174 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001175 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001176 i::Handle<i::TypeSwitchInfo> obj =
1177 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
1178 obj->set_types(*vector);
1179 return Utils::ToLocal(obj);
1180}
1181
1182
1183int TypeSwitch::match(v8::Handle<Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001184 i::Isolate* isolate = i::Isolate::Current();
1185 LOG_API(isolate, "TypeSwitch::match");
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001186 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001187 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
1188 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
1189 i::FixedArray* types = i::FixedArray::cast(info->types());
1190 for (int i = 0; i < types->length(); i++) {
machenbach@chromium.org9af454f2013-11-20 09:25:57 +00001191 if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001192 return i + 1;
1193 }
1194 return 0;
1195}
1196
1197
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001198#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00001199 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001200 (obj)->setter(*foreign); \
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001201 } while (false)
1202
1203
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001204void FunctionTemplate::SetCallHandler(FunctionCallback callback,
1205 v8::Handle<Value> data) {
1206 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001207 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001208 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001209 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001210 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211 i::Handle<i::CallHandlerInfo> obj =
1212 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001213 SET_FIELD_WRAPPED(obj, set_callback, callback);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001214 if (data.IsEmpty()) {
1215 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1216 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217 obj->set_data(*Utils::OpenHandle(*data));
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001218 Utils::OpenHandle(this)->set_call_code(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219}
1220
1221
ulan@chromium.org750145a2013-03-07 15:14:13 +00001222static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1223 i::Handle<i::AccessorInfo> obj,
1224 v8::Handle<String> name,
1225 v8::AccessControl settings,
1226 v8::PropertyAttribute attributes,
1227 v8::Handle<AccessorSignature> signature) {
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001228 obj->set_name(*Utils::OpenHandle(*name));
1229 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1230 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1231 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
1232 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001233 if (!signature.IsEmpty()) {
1234 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1235 }
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001236 return obj;
1237}
1238
1239
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001240template<typename Getter, typename Setter>
ulan@chromium.org750145a2013-03-07 15:14:13 +00001241static i::Handle<i::AccessorInfo> MakeAccessorInfo(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001242 v8::Handle<String> name,
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001243 Getter getter,
1244 Setter setter,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001245 v8::Handle<Value> data,
1246 v8::AccessControl settings,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001247 v8::PropertyAttribute attributes,
1248 v8::Handle<AccessorSignature> signature) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001249 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1250 i::Handle<i::ExecutableAccessorInfo> obj =
1251 isolate->factory()->NewExecutableAccessorInfo();
1252 SET_FIELD_WRAPPED(obj, set_getter, getter);
1253 SET_FIELD_WRAPPED(obj, set_setter, setter);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001254 if (data.IsEmpty()) {
1255 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1256 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00001257 obj->set_data(*Utils::OpenHandle(*data));
1258 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1259}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001260
ulan@chromium.org750145a2013-03-07 15:14:13 +00001261
1262static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1263 v8::Handle<String> name,
1264 v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001265 void* setter_ignored,
1266 void* data_ignored,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001267 v8::AccessControl settings,
1268 v8::PropertyAttribute attributes,
1269 v8::Handle<AccessorSignature> signature) {
1270 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1271 if (descriptor.IsEmpty()) return i::Handle<i::DeclaredAccessorInfo>();
1272 i::Handle<i::DeclaredAccessorInfo> obj =
1273 isolate->factory()->NewDeclaredAccessorInfo();
1274 obj->set_descriptor(*Utils::OpenHandle(*descriptor));
1275 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001276}
1277
1278
1279Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001280 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00001281 if (EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001282 return Local<ObjectTemplate>();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001283 ENTER_V8(isolate);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001284 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this);
1285 if (handle->instance_template()->IsUndefined()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001286 Local<ObjectTemplate> templ =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001287 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001288 handle->set_instance_template(*Utils::OpenHandle(*templ));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001289 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001290 i::Handle<i::ObjectTemplateInfo> result(
1291 i::ObjectTemplateInfo::cast(handle->instance_template()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001292 return Utils::ToLocal(result);
1293}
1294
1295
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001296void FunctionTemplate::SetLength(int length) {
1297 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001298 ENTER_V8(isolate);
1299 Utils::OpenHandle(this)->set_length(length);
1300}
1301
1302
kasper.lund212ac232008-07-16 07:07:30 +00001303void FunctionTemplate::SetClassName(Handle<String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001304 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001305 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001306 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1307}
1308
1309
1310void FunctionTemplate::SetHiddenPrototype(bool value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001311 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001312 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001313 Utils::OpenHandle(this)->set_hidden_prototype(value);
1314}
1315
1316
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001317void FunctionTemplate::ReadOnlyPrototype() {
ager@chromium.org04921a82011-06-27 13:21:41 +00001318 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ager@chromium.org04921a82011-06-27 13:21:41 +00001319 ENTER_V8(isolate);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001320 Utils::OpenHandle(this)->set_read_only_prototype(true);
ager@chromium.org04921a82011-06-27 13:21:41 +00001321}
1322
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001323
1324void FunctionTemplate::RemovePrototype() {
1325 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001326 ENTER_V8(isolate);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001327 Utils::OpenHandle(this)->set_remove_prototype(true);
kasper.lund212ac232008-07-16 07:07:30 +00001328}
1329
1330
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331// --- O b j e c t T e m p l a t e ---
1332
1333
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001334Local<ObjectTemplate> ObjectTemplate::New(Isolate* isolate) {
1335 return New(reinterpret_cast<i::Isolate*>(isolate), Local<FunctionTemplate>());
1336}
1337
1338
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001339Local<ObjectTemplate> ObjectTemplate::New() {
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001340 return New(i::Isolate::Current(), Local<FunctionTemplate>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001341}
1342
1343
1344Local<ObjectTemplate> ObjectTemplate::New(
machenbach@chromium.org37be4082013-11-26 13:50:38 +00001345 i::Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346 v8::Handle<FunctionTemplate> constructor) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001347 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1348 LOG_API(isolate, "ObjectTemplate::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001349 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001350 i::Handle<i::Struct> struct_obj =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001351 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001352 i::Handle<i::ObjectTemplateInfo> obj =
1353 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1354 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1355 if (!constructor.IsEmpty())
1356 obj->set_constructor(*Utils::OpenHandle(*constructor));
kasper.lund212ac232008-07-16 07:07:30 +00001357 obj->set_internal_field_count(i::Smi::FromInt(0));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001358 return Utils::ToLocal(obj);
1359}
1360
1361
1362// Ensure that the object template has a constructor. If no
1363// constructor is available we create one.
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001364static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001365 i::Isolate* isolate,
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001366 ObjectTemplate* object_template) {
1367 i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1368 if (!obj ->IsUndefined()) {
1369 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001370 return i::Handle<i::FunctionTemplateInfo>(info, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001371 }
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001372 Local<FunctionTemplate> templ =
1373 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001374 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1375 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1376 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1377 return constructor;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001378}
1379
1380
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001381static inline void AddPropertyToTemplate(
1382 i::Handle<i::TemplateInfo> info,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001383 i::Handle<i::AccessorInfo> obj) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001384 i::Handle<i::Object> list(info->property_accessors(), info->GetIsolate());
ulan@chromium.org750145a2013-03-07 15:14:13 +00001385 if (list->IsUndefined()) {
1386 list = NeanderArray().value();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001387 info->set_property_accessors(*list);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001388 }
1389 NeanderArray array(list);
1390 array.add(obj);
1391}
1392
1393
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001394static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001395 i::Isolate* isolate,
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001396 Template* template_obj) {
1397 return Utils::OpenHandle(template_obj);
1398}
1399
1400
1401// TODO(dcarney): remove this with ObjectTemplate::SetAccessor
1402static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001403 i::Isolate* isolate,
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001404 ObjectTemplate* object_template) {
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001405 EnsureConstructor(isolate, object_template);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001406 return Utils::OpenHandle(object_template);
1407}
1408
1409
1410template<typename Setter, typename Getter, typename Data, typename Template>
1411static bool TemplateSetAccessor(
1412 Template* template_obj,
1413 v8::Local<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001414 Getter getter,
1415 Setter setter,
1416 Data data,
1417 AccessControl settings,
1418 PropertyAttribute attribute,
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001419 v8::Local<AccessorSignature> signature) {
1420 i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001421 ENTER_V8(isolate);
1422 i::HandleScope scope(isolate);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001423 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
1424 name, getter, setter, data, settings, attribute, signature);
1425 if (obj.is_null()) return false;
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001426 i::Handle<i::TemplateInfo> info = GetTemplateInfo(isolate, template_obj);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001427 AddPropertyToTemplate(info, obj);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001428 return true;
1429}
1430
1431
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001432bool Template::SetDeclaredAccessor(
1433 Local<String> name,
1434 Local<DeclaredAccessorDescriptor> descriptor,
1435 PropertyAttribute attribute,
1436 Local<AccessorSignature> signature,
1437 AccessControl settings) {
1438 void* null = NULL;
1439 return TemplateSetAccessor(
1440 this, name, descriptor, null, null, settings, attribute, signature);
1441}
1442
1443
1444void Template::SetNativeDataProperty(v8::Local<String> name,
1445 AccessorGetterCallback getter,
1446 AccessorSetterCallback setter,
1447 v8::Handle<Value> data,
1448 PropertyAttribute attribute,
1449 v8::Local<AccessorSignature> signature,
1450 AccessControl settings) {
1451 TemplateSetAccessor(
1452 this, name, getter, setter, data, settings, attribute, signature);
1453}
1454
1455
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001456void ObjectTemplate::SetAccessor(v8::Handle<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001457 AccessorGetterCallback getter,
1458 AccessorSetterCallback setter,
1459 v8::Handle<Value> data,
1460 AccessControl settings,
1461 PropertyAttribute attribute,
1462 v8::Handle<AccessorSignature> signature) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001463 TemplateSetAccessor(
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001464 this, name, getter, setter, data, settings, attribute, signature);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001465}
1466
1467
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001468void ObjectTemplate::SetNamedPropertyHandler(
1469 NamedPropertyGetterCallback getter,
1470 NamedPropertySetterCallback setter,
1471 NamedPropertyQueryCallback query,
1472 NamedPropertyDeleterCallback remover,
1473 NamedPropertyEnumeratorCallback enumerator,
1474 Handle<Value> data) {
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001475 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001476 ENTER_V8(isolate);
1477 i::HandleScope scope(isolate);
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001478 EnsureConstructor(isolate, this);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001479 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1480 Utils::OpenHandle(this)->constructor());
1481 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1482 i::Handle<i::Struct> struct_obj =
1483 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1484 i::Handle<i::InterceptorInfo> obj =
1485 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1486
1487 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1488 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1489 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1490 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1491 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1492
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001493 if (data.IsEmpty()) {
1494 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1495 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001496 obj->set_data(*Utils::OpenHandle(*data));
1497 cons->set_named_property_handler(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498}
1499
1500
1501void ObjectTemplate::MarkAsUndetectable() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001502 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001503 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001504 i::HandleScope scope(isolate);
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001505 EnsureConstructor(isolate, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001506 i::FunctionTemplateInfo* constructor =
1507 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1508 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1509 cons->set_undetectable(true);
1510}
1511
1512
1513void ObjectTemplate::SetAccessCheckCallbacks(
1514 NamedSecurityCallback named_callback,
1515 IndexedSecurityCallback indexed_callback,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001516 Handle<Value> data,
1517 bool turned_on_by_default) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001518 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001519 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520 i::HandleScope scope(isolate);
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001521 EnsureConstructor(isolate, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001522
1523 i::Handle<i::Struct> struct_info =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001524 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001525 i::Handle<i::AccessCheckInfo> info =
1526 i::Handle<i::AccessCheckInfo>::cast(struct_info);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001527
1528 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1529 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1530
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001531 if (data.IsEmpty()) {
1532 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1533 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001534 info->set_data(*Utils::OpenHandle(*data));
1535
1536 i::FunctionTemplateInfo* constructor =
1537 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1538 i::Handle<i::FunctionTemplateInfo> cons(constructor);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001539 cons->set_access_check_info(*info);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001540 cons->set_needs_access_check(turned_on_by_default);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001541}
1542
1543
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001544void ObjectTemplate::SetIndexedPropertyHandler(
1545 IndexedPropertyGetterCallback getter,
1546 IndexedPropertySetterCallback setter,
1547 IndexedPropertyQueryCallback query,
1548 IndexedPropertyDeleterCallback remover,
1549 IndexedPropertyEnumeratorCallback enumerator,
1550 Handle<Value> data) {
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001551 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001552 ENTER_V8(isolate);
1553 i::HandleScope scope(isolate);
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001554 EnsureConstructor(isolate, this);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001555 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1556 Utils::OpenHandle(this)->constructor());
1557 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1558 i::Handle<i::Struct> struct_obj =
1559 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1560 i::Handle<i::InterceptorInfo> obj =
1561 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1562
1563 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1564 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1565 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1566 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1567 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1568
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001569 if (data.IsEmpty()) {
1570 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1571 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001572 obj->set_data(*Utils::OpenHandle(*data));
1573 cons->set_indexed_property_handler(*obj);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001574}
1575
1576
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001577void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1578 Handle<Value> data) {
1579 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001580 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001581 i::HandleScope scope(isolate);
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001582 EnsureConstructor(isolate, this);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001583 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001584 Utils::OpenHandle(this)->constructor());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585 i::Handle<i::FunctionTemplateInfo> cons(constructor);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001586 i::Handle<i::Struct> struct_obj =
1587 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1588 i::Handle<i::CallHandlerInfo> obj =
1589 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1590 SET_FIELD_WRAPPED(obj, set_callback, callback);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001591 if (data.IsEmpty()) {
1592 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1593 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001594 obj->set_data(*Utils::OpenHandle(*data));
1595 cons->set_instance_call_handler(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596}
1597
1598
kasper.lund212ac232008-07-16 07:07:30 +00001599int ObjectTemplate::InternalFieldCount() {
kasper.lund212ac232008-07-16 07:07:30 +00001600 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601}
1602
1603
kasper.lund212ac232008-07-16 07:07:30 +00001604void ObjectTemplate::SetInternalFieldCount(int value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001605 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
kasper.lund212ac232008-07-16 07:07:30 +00001606 if (!ApiCheck(i::Smi::IsValid(value),
1607 "v8::ObjectTemplate::SetInternalFieldCount()",
1608 "Invalid internal field count")) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609 return;
1610 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001611 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001612 if (value > 0) {
1613 // The internal field count is set by the constructor function's
1614 // construct code, so we ensure that there is a constructor
1615 // function to do the setting.
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00001616 EnsureConstructor(isolate, this);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001617 }
kasper.lund212ac232008-07-16 07:07:30 +00001618 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619}
1620
1621
kasper.lund212ac232008-07-16 07:07:30 +00001622// --- S c r i p t D a t a ---
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623
1624
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001625ScriptData* ScriptData::PreCompile(v8::Isolate* isolate,
1626 const char* input,
1627 int length) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001628 i::Utf8ToUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001629 reinterpret_cast<const unsigned char*>(input), length);
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001630 return i::PreParserApi::PreParse(
1631 reinterpret_cast<i::Isolate*>(isolate), &stream);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632}
1633
1634
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001635ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1636 i::Handle<i::String> str = Utils::OpenHandle(*source);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001637 i::Isolate* isolate = str->GetIsolate();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001638 if (str->IsExternalTwoByteString()) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001639 i::ExternalTwoByteStringUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001640 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001641 return i::PreParserApi::PreParse(isolate, &stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001642 } else {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001643 i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001644 return i::PreParserApi::PreParse(isolate, &stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001645 }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001646}
1647
1648
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001649ScriptData* ScriptData::New(const char* data, int length) {
1650 // Return an empty ScriptData if the length is obviously invalid.
1651 if (length % sizeof(unsigned) != 0) {
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001652 return new i::ScriptDataImpl();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001653 }
1654
1655 // Copy the data to ensure it is properly aligned.
1656 int deserialized_data_length = length / sizeof(unsigned);
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001657 // If aligned, don't create a copy of the data.
1658 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1659 return new i::ScriptDataImpl(data, length);
1660 }
1661 // Copy the data to align it.
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001662 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001663 i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
1664 data, static_cast<size_t>(length));
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001665
1666 return new i::ScriptDataImpl(
1667 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001668}
1669
1670
1671// --- S c r i p t ---
1672
1673
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001674Local<Script> Script::New(v8::Handle<String> source,
1675 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001676 v8::ScriptData* pre_data,
1677 v8::Handle<String> script_data) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001678 i::Handle<i::String> str = Utils::OpenHandle(*source);
1679 i::Isolate* isolate = str->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001680 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1681 LOG_API(isolate, "Script::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001682 ENTER_V8(isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001683 i::SharedFunctionInfo* raw_result = NULL;
1684 { i::HandleScope scope(isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001685 i::Handle<i::Object> name_obj;
1686 int line_offset = 0;
1687 int column_offset = 0;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001688 bool is_shared_cross_origin = false;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001689 if (origin != NULL) {
1690 if (!origin->ResourceName().IsEmpty()) {
1691 name_obj = Utils::OpenHandle(*origin->ResourceName());
1692 }
1693 if (!origin->ResourceLineOffset().IsEmpty()) {
1694 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1695 }
1696 if (!origin->ResourceColumnOffset().IsEmpty()) {
1697 column_offset =
1698 static_cast<int>(origin->ResourceColumnOffset()->Value());
1699 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001700 if (!origin->ResourceIsSharedCrossOrigin().IsEmpty()) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001701 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001702 is_shared_cross_origin =
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001703 origin->ResourceIsSharedCrossOrigin() == v8::True(v8_isolate);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001704 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001706 EXCEPTION_PREAMBLE(isolate);
1707 i::ScriptDataImpl* pre_data_impl =
1708 static_cast<i::ScriptDataImpl*>(pre_data);
1709 // We assert that the pre-data is sane, even though we can actually
1710 // handle it if it turns out not to be in release mode.
1711 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
1712 // If the pre-data isn't sane we simply ignore it
1713 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1714 pre_data_impl = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001716 i::Handle<i::SharedFunctionInfo> result =
yangguo@chromium.org49546742013-12-23 16:17:49 +00001717 i::Compiler::CompileScript(str,
1718 name_obj,
1719 line_offset,
1720 column_offset,
1721 is_shared_cross_origin,
1722 isolate->global_context(),
1723 NULL,
1724 pre_data_impl,
1725 Utils::OpenHandle(*script_data, true),
1726 i::NOT_NATIVES_CODE);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001727 has_pending_exception = result.is_null();
1728 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
1729 raw_result = *result;
1730 }
1731 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001732 return ToApiHandle<Script>(result);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001733}
1734
1735
1736Local<Script> Script::New(v8::Handle<String> source,
1737 v8::Handle<Value> file_name) {
1738 ScriptOrigin origin(file_name);
1739 return New(source, &origin);
1740}
1741
1742
1743Local<Script> Script::Compile(v8::Handle<String> source,
1744 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001745 v8::ScriptData* pre_data,
1746 v8::Handle<String> script_data) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001747 i::Handle<i::String> str = Utils::OpenHandle(*source);
1748 i::Isolate* isolate = str->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001749 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1750 LOG_API(isolate, "Script::Compile");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001751 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00001752 Local<Script> generic = New(source, origin, pre_data, script_data);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001753 if (generic.IsEmpty())
1754 return generic;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001755 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1756 i::Handle<i::SharedFunctionInfo> function =
1757 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001758 i::Handle<i::JSFunction> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001759 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1760 function,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001761 isolate->global_context());
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001762 return ToApiHandle<Script>(result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001763}
1764
1765
mads.s.agercbaa0602008-08-14 13:41:48 +00001766Local<Script> Script::Compile(v8::Handle<String> source,
ager@chromium.org5c838252010-02-19 08:53:10 +00001767 v8::Handle<Value> file_name,
1768 v8::Handle<String> script_data) {
mads.s.agercbaa0602008-08-14 13:41:48 +00001769 ScriptOrigin origin(file_name);
ager@chromium.org5c838252010-02-19 08:53:10 +00001770 return Compile(source, &origin, 0, script_data);
mads.s.agercbaa0602008-08-14 13:41:48 +00001771}
1772
1773
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001774Local<Value> Script::Run() {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001775 // If execution is terminating, Compile(script)->Run() requires this check.
1776 if (this == NULL) return Local<Value>();
1777 i::Handle<i::HeapObject> obj =
1778 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1779 i::Isolate* isolate = obj->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001780 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1781 LOG_API(isolate, "Script::Run");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001782 ENTER_V8(isolate);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001783 i::Logger::TimerEventScope timer_scope(
danno@chromium.org1f34ad32012-11-26 14:53:56 +00001784 isolate, i::Logger::TimerEventScope::v8_execute);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001785 i::Object* raw_result = NULL;
1786 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001787 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001788 i::Handle<i::JSFunction> fun;
1789 if (obj->IsSharedFunctionInfo()) {
1790 i::Handle<i::SharedFunctionInfo>
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001791 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001792 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001793 function_info, isolate->global_context());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001794 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001795 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001796 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001797 EXCEPTION_PREAMBLE(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001798 i::Handle<i::Object> receiver(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001799 isolate->context()->global_proxy(), isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00001800 i::Handle<i::Object> result = i::Execution::Call(
1801 isolate, fun, receiver, 0, NULL, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00001802 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803 raw_result = *result;
1804 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001805 i::Handle<i::Object> result(raw_result, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806 return Utils::ToLocal(result);
1807}
1808
1809
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001810static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1811 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1812 i::Handle<i::SharedFunctionInfo> result;
1813 if (obj->IsSharedFunctionInfo()) {
1814 result =
1815 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1816 } else {
1817 result =
1818 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1819 }
1820 return result;
1821}
1822
1823
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001824int Script::GetId() {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001825 i::Handle<i::HeapObject> obj =
1826 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1827 i::Isolate* isolate = obj->GetIsolate();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001828 ON_BAILOUT(isolate, "v8::Script::Id()", return -1);
1829 LOG_API(isolate, "Script::Id");
1830 {
1831 i::HandleScope scope(isolate);
1832 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1833 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1834 return script->id()->value();
1835 }
1836}
1837
1838
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001839int Script::GetLineNumber(int code_pos) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001840 i::Handle<i::HeapObject> obj =
1841 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1842 i::Isolate* isolate = obj->GetIsolate();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001843 ON_BAILOUT(isolate, "v8::Script::GetLineNumber()", return -1);
1844 LOG_API(isolate, "Script::GetLineNumber");
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001845 if (obj->IsScript()) {
1846 i::Handle<i::Script> script = i::Handle<i::Script>(i::Script::cast(*obj));
1847 return i::GetScriptLineNumber(script, code_pos);
1848 } else {
1849 return -1;
1850 }
1851}
1852
1853
1854Handle<Value> Script::GetScriptName() {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001855 i::Handle<i::HeapObject> obj =
1856 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1857 i::Isolate* isolate = obj->GetIsolate();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001858 ON_BAILOUT(isolate, "v8::Script::GetName()", return Handle<String>());
1859 LOG_API(isolate, "Script::GetName");
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001860 if (obj->IsScript()) {
1861 i::Object* name = i::Script::cast(*obj)->name();
1862 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1863 } else {
1864 return Handle<String>();
1865 }
1866}
1867
1868
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00001869void Script::SetData(v8::Handle<String> data) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001870 i::Handle<i::HeapObject> obj =
1871 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1872 i::Isolate* isolate = obj->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001873 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1874 LOG_API(isolate, "Script::SetData");
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001875 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001876 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001877 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001878 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001879 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001880 script->set_data(*raw_data);
1881 }
1882}
1883
1884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001885// --- E x c e p t i o n s ---
1886
1887
1888v8::TryCatch::TryCatch()
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001889 : isolate_(i::Isolate::Current()),
1890 next_(isolate_->try_catch_handler_address()),
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001891 is_verbose_(false),
ager@chromium.org68e7ab72009-09-23 09:40:39 +00001892 can_continue_(true),
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001893 capture_message_(true),
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001894 rethrow_(false),
1895 has_terminated_(false) {
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001896 Reset();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001897 isolate_->RegisterTryCatchHandler(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001898}
1899
1900
1901v8::TryCatch::~TryCatch() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001902 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001903 if (rethrow_) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001904 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
1905 v8::HandleScope scope(isolate);
1906 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001907 if (HasCaught() && capture_message_) {
1908 // If an exception was caught and rethrow_ is indicated, the saved
1909 // message, script, and location need to be restored to Isolate TLS
1910 // for reuse. capture_message_ needs to be disabled so that DoThrow()
1911 // does not create a new message.
1912 isolate_->thread_local_top()->rethrowing_message_ = true;
1913 isolate_->RestorePendingMessageFromTryCatch(this);
1914 }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001915 isolate_->UnregisterTryCatchHandler(this);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001916 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001917 ASSERT(!isolate_->thread_local_top()->rethrowing_message_);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001918 } else {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001919 isolate_->UnregisterTryCatchHandler(this);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001920 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001921}
1922
1923
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001924bool v8::TryCatch::HasCaught() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001925 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1926}
1927
1928
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001929bool v8::TryCatch::CanContinue() const {
1930 return can_continue_;
1931}
1932
1933
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001934bool v8::TryCatch::HasTerminated() const {
1935 return has_terminated_;
1936}
1937
1938
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001939v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1940 if (!HasCaught()) return v8::Local<v8::Value>();
1941 rethrow_ = true;
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001942 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001943}
1944
1945
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001946v8::Local<Value> v8::TryCatch::Exception() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001947 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001948 if (HasCaught()) {
1949 // Check for out of memory exception.
1950 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001951 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001952 } else {
1953 return v8::Local<Value>();
1954 }
1955}
1956
1957
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001958v8::Local<Value> v8::TryCatch::StackTrace() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001959 ASSERT(isolate_ == i::Isolate::Current());
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001960 if (HasCaught()) {
1961 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1962 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001963 i::HandleScope scope(isolate_);
1964 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001965 i::Handle<i::String> name = isolate_->factory()->stack_string();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00001966 if (!i::JSReceiver::HasProperty(obj, name)) return v8::Local<Value>();
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00001967 i::Handle<i::Object> value = i::GetProperty(isolate_, obj, name);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001968 if (value.is_null()) return v8::Local<Value>();
1969 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001970 } else {
1971 return v8::Local<Value>();
1972 }
1973}
1974
1975
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001976v8::Local<v8::Message> v8::TryCatch::Message() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001977 ASSERT(isolate_ == i::Isolate::Current());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001978 i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
1979 ASSERT(message->IsJSMessageObject() || message->IsTheHole());
1980 if (HasCaught() && !message->IsTheHole()) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001981 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001982 } else {
1983 return v8::Local<v8::Message>();
1984 }
1985}
1986
1987
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001988void v8::TryCatch::Reset() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001989 ASSERT(isolate_ == i::Isolate::Current());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001990 i::Object* the_hole = isolate_->heap()->the_hole_value();
1991 exception_ = the_hole;
1992 message_obj_ = the_hole;
1993 message_script_ = the_hole;
1994 message_start_pos_ = 0;
1995 message_end_pos_ = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001996}
1997
1998
1999void v8::TryCatch::SetVerbose(bool value) {
2000 is_verbose_ = value;
2001}
2002
2003
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002004void v8::TryCatch::SetCaptureMessage(bool value) {
2005 capture_message_ = value;
2006}
2007
2008
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002009// --- M e s s a g e ---
2010
2011
ager@chromium.org32912102009-01-16 10:38:43 +00002012Local<String> Message::Get() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002013 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002014 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002015 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002016 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017 i::Handle<i::Object> obj = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002018 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019 Local<String> result = Utils::ToLocal(raw_result);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002020 return scope.Escape(result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021}
2022
2023
ager@chromium.org32912102009-01-16 10:38:43 +00002024v8::Handle<Value> Message::GetScriptResourceName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002025 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002026 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002027 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002028 i::Handle<i::JSMessageObject> message =
2029 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002030 // Return this.script.name.
2031 i::Handle<i::JSValue> script =
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002032 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2033 isolate));
2034 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name(),
2035 isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002036 return scope.Escape(Utils::ToLocal(resource_name));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002037}
2038
2039
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002040v8::Handle<Value> Message::GetScriptData() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002041 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002042 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002043 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002044 i::Handle<i::JSMessageObject> message =
2045 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002046 // Return this.script.data.
2047 i::Handle<i::JSValue> script =
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002048 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2049 isolate));
2050 i::Handle<i::Object> data(i::Script::cast(script->value())->data(), isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002051 return scope.Escape(Utils::ToLocal(data));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002052}
2053
2054
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002055v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002056 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002057 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002058 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002059 i::Handle<i::JSMessageObject> message =
2060 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002061 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002062 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
2063 i::Handle<i::JSArray> stackTrace =
2064 i::Handle<i::JSArray>::cast(stackFramesObj);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002065 return scope.Escape(Utils::StackTraceToLocal(stackTrace));
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002066}
2067
2068
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002069static i::Handle<i::Object> CallV8HeapFunction(const char* name,
2070 i::Handle<i::Object> recv,
2071 int argc,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002072 i::Handle<i::Object> argv[],
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002073 bool* has_pending_exception) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002074 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002075 i::Handle<i::String> fmt_str =
2076 isolate->factory()->InternalizeUtf8String(name);
lrn@chromium.org303ada72010-10-27 09:33:13 +00002077 i::Object* object_fun =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002078 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002079 i::Handle<i::JSFunction> fun =
2080 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00002081 i::Handle<i::Object> value = i::Execution::Call(
2082 isolate, fun, recv, argc, argv, has_pending_exception);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083 return value;
2084}
2085
2086
2087static i::Handle<i::Object> CallV8HeapFunction(const char* name,
2088 i::Handle<i::Object> data,
2089 bool* has_pending_exception) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002090 i::Handle<i::Object> argv[] = { data };
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002091 return CallV8HeapFunction(name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002092 i::Isolate::Current()->js_builtins_object(),
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002093 ARRAY_SIZE(argv),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002094 argv,
2095 has_pending_exception);
2096}
2097
2098
ager@chromium.org32912102009-01-16 10:38:43 +00002099int Message::GetLineNumber() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002100 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002101 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002102 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002103 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002104
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002105 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002106 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
2107 Utils::OpenHandle(this),
2108 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002109 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110 return static_cast<int>(result->Number());
2111}
2112
2113
ager@chromium.org32912102009-01-16 10:38:43 +00002114int Message::GetStartPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002115 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002116 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002117 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002118 i::Handle<i::JSMessageObject> message =
2119 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2120 return message->start_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002121}
2122
2123
ager@chromium.org32912102009-01-16 10:38:43 +00002124int Message::GetEndPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002125 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002126 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002127 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002128 i::Handle<i::JSMessageObject> message =
2129 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2130 return message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002131}
2132
2133
ager@chromium.org32912102009-01-16 10:38:43 +00002134int Message::GetStartColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002135 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002136 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002137 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002138 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002139 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002140 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
2141 "GetPositionInLine",
2142 data_obj,
2143 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002144 EXCEPTION_BAILOUT_CHECK(isolate, 0);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002145 return static_cast<int>(start_col_obj->Number());
2146}
2147
2148
ager@chromium.org32912102009-01-16 10:38:43 +00002149int Message::GetEndColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002150 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002151 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002152 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002153 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002154 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002155 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
2156 "GetPositionInLine",
2157 data_obj,
2158 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002159 EXCEPTION_BAILOUT_CHECK(isolate, 0);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002160 i::Handle<i::JSMessageObject> message =
2161 i::Handle<i::JSMessageObject>::cast(data_obj);
2162 int start = message->start_position();
2163 int end = message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002164 return static_cast<int>(start_col_obj->Number()) + (end - start);
2165}
2166
2167
danno@chromium.orgd3c42102013-08-01 16:58:23 +00002168bool Message::IsSharedCrossOrigin() const {
2169 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
danno@chromium.orgd3c42102013-08-01 16:58:23 +00002170 ENTER_V8(isolate);
2171 i::HandleScope scope(isolate);
2172 i::Handle<i::JSMessageObject> message =
2173 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2174 i::Handle<i::JSValue> script =
2175 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2176 isolate));
2177 return i::Script::cast(script->value())->is_shared_cross_origin();
2178}
2179
2180
ager@chromium.org32912102009-01-16 10:38:43 +00002181Local<String> Message::GetSourceLine() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002182 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002183 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002184 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002185 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002186 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002187 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
2188 Utils::OpenHandle(this),
2189 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002190 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002191 if (result->IsString()) {
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002192 return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002193 } else {
2194 return Local<String>();
2195 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196}
2197
2198
machenbach@chromium.org37be4082013-11-26 13:50:38 +00002199void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
2200 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2201 ENTER_V8(i_isolate);
2202 i_isolate->PrintCurrentStackTrace(out);
2203}
2204
2205
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002206// --- S t a c k T r a c e ---
2207
2208Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002209 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002210 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002211 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002212 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00002213 i::Object* raw_object = self->GetElementNoExceptionThrown(isolate, index);
lrn@chromium.org303ada72010-10-27 09:33:13 +00002214 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002215 return scope.Escape(Utils::StackFrameToLocal(obj));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002216}
2217
2218
2219int StackTrace::GetFrameCount() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002220 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002221 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002222 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2223}
2224
2225
2226Local<Array> StackTrace::AsArray() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002227 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002228 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002229 return Utils::ToLocal(Utils::OpenHandle(this));
2230}
2231
2232
machenbach@chromium.org37be4082013-11-26 13:50:38 +00002233Local<StackTrace> StackTrace::CurrentStackTrace(
2234 Isolate* isolate,
2235 int frame_limit,
2236 StackTraceOptions options) {
2237 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2238 ENTER_V8(i_isolate);
2239 i::Handle<i::JSArray> stackTrace =
2240 i_isolate->CaptureCurrentStackTrace(frame_limit, options);
2241 return Utils::StackTraceToLocal(stackTrace);
2242}
2243
2244
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002245// --- S t a c k F r a m e ---
2246
2247int StackFrame::GetLineNumber() 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.orgea88ce92011-03-23 11:19:56 +00002250 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002251 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2252 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
2253 if (!line->IsSmi()) {
2254 return Message::kNoLineNumberInfo;
2255 }
2256 return i::Smi::cast(*line)->value();
2257}
2258
2259
2260int StackFrame::GetColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002261 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002262 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002263 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002264 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2265 i::Handle<i::Object> column = GetProperty(self, "column");
2266 if (!column->IsSmi()) {
2267 return Message::kNoColumnInfo;
2268 }
2269 return i::Smi::cast(*column)->value();
2270}
2271
2272
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00002273int StackFrame::GetScriptId() const {
2274 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00002275 ENTER_V8(isolate);
2276 i::HandleScope scope(isolate);
2277 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2278 i::Handle<i::Object> scriptId = GetProperty(self, "scriptId");
2279 if (!scriptId->IsSmi()) {
2280 return Message::kNoScriptIdInfo;
2281 }
2282 return i::Smi::cast(*scriptId)->value();
2283}
2284
2285
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002286Local<String> StackFrame::GetScriptName() 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);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002289 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002290 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2291 i::Handle<i::Object> name = GetProperty(self, "scriptName");
2292 if (!name->IsString()) {
2293 return Local<String>();
2294 }
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002295 return scope.Escape(Local<String>::Cast(Utils::ToLocal(name)));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002296}
2297
2298
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002299Local<String> StackFrame::GetScriptNameOrSourceURL() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002300 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002301 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002302 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002303 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2304 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
2305 if (!name->IsString()) {
2306 return Local<String>();
2307 }
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002308 return scope.Escape(Local<String>::Cast(Utils::ToLocal(name)));
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002309}
2310
2311
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002312Local<String> StackFrame::GetFunctionName() 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);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002315 EscapableHandleScope 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, "functionName");
2318 if (!name->IsString()) {
2319 return Local<String>();
2320 }
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00002321 return scope.Escape(Local<String>::Cast(Utils::ToLocal(name)));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002322}
2323
2324
2325bool StackFrame::IsEval() 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);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002328 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002329 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2330 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
2331 return is_eval->IsTrue();
2332}
2333
2334
2335bool StackFrame::IsConstructor() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002336 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002337 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002338 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002339 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2340 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
2341 return is_constructor->IsTrue();
2342}
2343
2344
danno@chromium.org59400602013-08-13 17:09:37 +00002345// --- J S O N ---
2346
2347Local<Value> JSON::Parse(Local<String> json_string) {
2348 i::Isolate* isolate = i::Isolate::Current();
2349 EnsureInitializedForIsolate(isolate, "v8::JSON::Parse");
2350 ENTER_V8(isolate);
2351 i::HandleScope scope(isolate);
2352 i::Handle<i::String> source = i::Handle<i::String>(
2353 FlattenGetString(Utils::OpenHandle(*json_string)));
2354 EXCEPTION_PREAMBLE(isolate);
2355 i::Handle<i::Object> result;
2356 if (source->IsSeqOneByteString()) {
2357 result = i::JsonParser<true>::Parse(source);
2358 } else {
2359 result = i::JsonParser<false>::Parse(source);
2360 }
2361 has_pending_exception = result.is_null();
2362 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
2363 return Utils::ToLocal(
2364 i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
2365}
2366
2367
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368// --- D a t a ---
2369
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002370bool Value::FullIsUndefined() const {
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002371 bool result = Utils::OpenHandle(this)->IsUndefined();
2372 ASSERT_EQ(result, QuickIsUndefined());
2373 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002374}
2375
2376
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002377bool Value::FullIsNull() const {
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002378 bool result = Utils::OpenHandle(this)->IsNull();
2379 ASSERT_EQ(result, QuickIsNull());
2380 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381}
2382
2383
ager@chromium.org32912102009-01-16 10:38:43 +00002384bool Value::IsTrue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002385 return Utils::OpenHandle(this)->IsTrue();
2386}
2387
2388
ager@chromium.org32912102009-01-16 10:38:43 +00002389bool Value::IsFalse() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002390 return Utils::OpenHandle(this)->IsFalse();
2391}
2392
2393
ager@chromium.org32912102009-01-16 10:38:43 +00002394bool Value::IsFunction() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002395 return Utils::OpenHandle(this)->IsJSFunction();
2396}
2397
2398
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002399bool Value::FullIsString() const {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002400 bool result = Utils::OpenHandle(this)->IsString();
2401 ASSERT_EQ(result, QuickIsString());
2402 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403}
2404
2405
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002406bool Value::IsSymbol() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002407 return Utils::OpenHandle(this)->IsSymbol();
2408}
2409
2410
ager@chromium.org32912102009-01-16 10:38:43 +00002411bool Value::IsArray() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002412 return Utils::OpenHandle(this)->IsJSArray();
2413}
2414
2415
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002416bool Value::IsArrayBuffer() const {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002417 return Utils::OpenHandle(this)->IsJSArrayBuffer();
2418}
2419
2420
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002421bool Value::IsArrayBufferView() const {
2422 return Utils::OpenHandle(this)->IsJSArrayBufferView();
2423}
2424
2425
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002426bool Value::IsTypedArray() const {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002427 return Utils::OpenHandle(this)->IsJSTypedArray();
2428}
2429
2430
2431#define TYPED_ARRAY_LIST(F) \
2432F(Uint8Array, kExternalUnsignedByteArray) \
2433F(Int8Array, kExternalByteArray) \
2434F(Uint16Array, kExternalUnsignedShortArray) \
2435F(Int16Array, kExternalShortArray) \
2436F(Uint32Array, kExternalUnsignedIntArray) \
2437F(Int32Array, kExternalIntArray) \
2438F(Float32Array, kExternalFloatArray) \
2439F(Float64Array, kExternalDoubleArray) \
2440F(Uint8ClampedArray, kExternalPixelArray)
2441
2442
2443#define VALUE_IS_TYPED_ARRAY(TypedArray, type_const) \
2444 bool Value::Is##TypedArray() const { \
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002445 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2446 if (!obj->IsJSTypedArray()) return false; \
2447 return i::JSTypedArray::cast(*obj)->type() == type_const; \
2448 }
2449
2450TYPED_ARRAY_LIST(VALUE_IS_TYPED_ARRAY)
2451
2452#undef VALUE_IS_TYPED_ARRAY
2453
2454
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002455bool Value::IsDataView() const {
2456 return Utils::OpenHandle(this)->IsJSDataView();
2457}
2458
2459
ager@chromium.org32912102009-01-16 10:38:43 +00002460bool Value::IsObject() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002461 return Utils::OpenHandle(this)->IsJSObject();
2462}
2463
2464
ager@chromium.org32912102009-01-16 10:38:43 +00002465bool Value::IsNumber() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002466 return Utils::OpenHandle(this)->IsNumber();
2467}
2468
2469
ager@chromium.org32912102009-01-16 10:38:43 +00002470bool Value::IsBoolean() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002471 return Utils::OpenHandle(this)->IsBoolean();
2472}
2473
2474
ager@chromium.org32912102009-01-16 10:38:43 +00002475bool Value::IsExternal() const {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002476 return Utils::OpenHandle(this)->IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002477}
2478
2479
ager@chromium.org32912102009-01-16 10:38:43 +00002480bool Value::IsInt32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002481 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2482 if (obj->IsSmi()) return true;
2483 if (obj->IsNumber()) {
hpayer@chromium.orgea9b8ba2013-12-20 19:22:39 +00002484 return i::IsInt32Double(obj->Number());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002485 }
2486 return false;
2487}
2488
2489
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002490bool Value::IsUint32() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002491 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2492 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2493 if (obj->IsNumber()) {
2494 double value = obj->Number();
hpayer@chromium.orgea9b8ba2013-12-20 19:22:39 +00002495 return !i::IsMinusZero(value) &&
2496 value >= 0 &&
2497 value <= i::kMaxUInt32 &&
2498 value == i::FastUI2D(i::FastD2UI(value));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002499 }
2500 return false;
2501}
2502
2503
ager@chromium.org32912102009-01-16 10:38:43 +00002504bool Value::IsDate() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002505 i::Isolate* isolate = i::Isolate::Current();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002506 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002507 return obj->HasSpecificClassOf(isolate->heap()->Date_string());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002508}
2509
2510
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002511bool Value::IsStringObject() const {
2512 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002513 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002514 return obj->HasSpecificClassOf(isolate->heap()->String_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002515}
2516
2517
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002518bool Value::IsSymbolObject() const {
2519 // TODO(svenpanne): these and other test functions should be written such
2520 // that they do not use Isolate::Current().
2521 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002522 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2523 return obj->HasSpecificClassOf(isolate->heap()->Symbol_string());
2524}
2525
2526
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002527bool Value::IsNumberObject() const {
2528 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002529 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002530 return obj->HasSpecificClassOf(isolate->heap()->Number_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002531}
2532
2533
2534static i::Object* LookupBuiltin(i::Isolate* isolate,
2535 const char* builtin_name) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002536 i::Handle<i::String> string =
2537 isolate->factory()->InternalizeUtf8String(builtin_name);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002538 i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002539 return builtins->GetPropertyNoExceptionThrown(*string);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002540}
2541
2542
2543static bool CheckConstructor(i::Isolate* isolate,
2544 i::Handle<i::JSObject> obj,
2545 const char* class_name) {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002546 i::Object* constr = obj->map()->constructor();
2547 if (!constr->IsJSFunction()) return false;
2548 i::JSFunction* func = i::JSFunction::cast(constr);
2549 return func->shared()->native() &&
2550 constr == LookupBuiltin(isolate, class_name);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002551}
2552
2553
2554bool Value::IsNativeError() const {
2555 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002556 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2557 if (obj->IsJSObject()) {
2558 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
2559 return CheckConstructor(isolate, js_obj, "$Error") ||
2560 CheckConstructor(isolate, js_obj, "$EvalError") ||
2561 CheckConstructor(isolate, js_obj, "$RangeError") ||
2562 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2563 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2564 CheckConstructor(isolate, js_obj, "$TypeError") ||
2565 CheckConstructor(isolate, js_obj, "$URIError");
2566 } else {
2567 return false;
2568 }
2569}
2570
2571
2572bool Value::IsBooleanObject() const {
2573 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002574 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002575 return obj->HasSpecificClassOf(isolate->heap()->Boolean_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002576}
2577
2578
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002579bool Value::IsRegExp() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002580 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2581 return obj->IsJSRegExp();
2582}
2583
2584
ager@chromium.org32912102009-01-16 10:38:43 +00002585Local<String> Value::ToString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002586 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2587 i::Handle<i::Object> str;
2588 if (obj->IsString()) {
2589 str = obj;
2590 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002591 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002592 LOG_API(isolate, "ToString");
2593 ENTER_V8(isolate);
2594 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002595 str = i::Execution::ToString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002596 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002597 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002598 return ToApiHandle<String>(str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002599}
2600
2601
ager@chromium.org32912102009-01-16 10:38:43 +00002602Local<String> Value::ToDetailString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2604 i::Handle<i::Object> str;
2605 if (obj->IsString()) {
2606 str = obj;
2607 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002608 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002609 LOG_API(isolate, "ToDetailString");
2610 ENTER_V8(isolate);
2611 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002612 str = i::Execution::ToDetailString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002613 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002614 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002615 return ToApiHandle<String>(str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002616}
2617
2618
ager@chromium.org32912102009-01-16 10:38:43 +00002619Local<v8::Object> Value::ToObject() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002620 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2621 i::Handle<i::Object> val;
2622 if (obj->IsJSObject()) {
2623 val = 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, "ToObject");
2627 ENTER_V8(isolate);
2628 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002629 val = i::Execution::ToObject(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002630 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002631 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002632 return ToApiHandle<Object>(val);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002633}
2634
2635
ager@chromium.org32912102009-01-16 10:38:43 +00002636Local<Boolean> Value::ToBoolean() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002637 i::Handle<i::Object> obj = Utils::OpenHandle(this);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002638 if (obj->IsBoolean()) {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002639 return ToApiHandle<Boolean>(obj);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002640 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002641 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002642 LOG_API(isolate, "ToBoolean");
2643 ENTER_V8(isolate);
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +00002644 i::Handle<i::Object> val =
2645 isolate->factory()->ToBoolean(obj->BooleanValue());
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002646 return ToApiHandle<Boolean>(val);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002647 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002648}
2649
2650
ager@chromium.org32912102009-01-16 10:38:43 +00002651Local<Number> Value::ToNumber() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002652 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2653 i::Handle<i::Object> num;
2654 if (obj->IsNumber()) {
2655 num = obj;
2656 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002657 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002658 LOG_API(isolate, "ToNumber");
2659 ENTER_V8(isolate);
2660 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002661 num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002662 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002663 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002664 return ToApiHandle<Number>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665}
2666
2667
ager@chromium.org32912102009-01-16 10:38:43 +00002668Local<Integer> Value::ToInteger() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002669 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2670 i::Handle<i::Object> num;
2671 if (obj->IsSmi()) {
2672 num = obj;
2673 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002674 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002675 LOG_API(isolate, "ToInteger");
2676 ENTER_V8(isolate);
2677 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002678 num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002679 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002680 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002681 return ToApiHandle<Integer>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002682}
2683
2684
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00002685void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002686 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002687 ApiCheck(isolate != NULL && isolate->IsInitialized() && !isolate->IsDead(),
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002688 "v8::internal::Internals::CheckInitialized()",
2689 "Isolate is not initialized or V8 has died");
2690}
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002691
2692
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002693void External::CheckCast(v8::Value* that) {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002694 ApiCheck(Utils::OpenHandle(that)->IsExternal(),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002695 "v8::External::Cast()",
2696 "Could not convert to external");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002697}
2698
2699
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002700void v8::Object::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002701 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2702 ApiCheck(obj->IsJSObject(),
2703 "v8::Object::Cast()",
2704 "Could not convert to object");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002705}
2706
2707
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002708void v8::Function::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002709 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2710 ApiCheck(obj->IsJSFunction(),
2711 "v8::Function::Cast()",
2712 "Could not convert to function");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002713}
2714
2715
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002716void v8::String::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002717 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2718 ApiCheck(obj->IsString(),
2719 "v8::String::Cast()",
2720 "Could not convert to string");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002721}
2722
2723
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002724void v8::Symbol::CheckCast(v8::Value* that) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002725 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2726 ApiCheck(obj->IsSymbol(),
2727 "v8::Symbol::Cast()",
2728 "Could not convert to symbol");
2729}
2730
2731
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002732void v8::Number::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002733 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2734 ApiCheck(obj->IsNumber(),
2735 "v8::Number::Cast()",
2736 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002737}
2738
2739
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002740void v8::Integer::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002741 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2742 ApiCheck(obj->IsNumber(),
2743 "v8::Integer::Cast()",
2744 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002745}
2746
2747
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002748void v8::Array::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002749 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2750 ApiCheck(obj->IsJSArray(),
2751 "v8::Array::Cast()",
2752 "Could not convert to array");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002753}
2754
2755
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002756void v8::ArrayBuffer::CheckCast(Value* that) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002757 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2758 ApiCheck(obj->IsJSArrayBuffer(),
2759 "v8::ArrayBuffer::Cast()",
2760 "Could not convert to ArrayBuffer");
2761}
2762
2763
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002764void v8::ArrayBufferView::CheckCast(Value* that) {
2765 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2766 ApiCheck(obj->IsJSArrayBufferView(),
2767 "v8::ArrayBufferView::Cast()",
2768 "Could not convert to ArrayBufferView");
2769}
2770
2771
danno@chromium.orgf005df62013-04-30 16:36:45 +00002772void v8::TypedArray::CheckCast(Value* that) {
danno@chromium.orgf005df62013-04-30 16:36:45 +00002773 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2774 ApiCheck(obj->IsJSTypedArray(),
2775 "v8::TypedArray::Cast()",
2776 "Could not convert to TypedArray");
2777}
2778
2779
2780#define CHECK_TYPED_ARRAY_CAST(ApiClass, typeConst) \
2781 void v8::ApiClass::CheckCast(Value* that) { \
danno@chromium.orgf005df62013-04-30 16:36:45 +00002782 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
2783 ApiCheck(obj->IsJSTypedArray() && \
2784 i::JSTypedArray::cast(*obj)->type() == typeConst, \
2785 "v8::" #ApiClass "::Cast()", \
2786 "Could not convert to " #ApiClass); \
2787 }
2788
2789
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002790TYPED_ARRAY_LIST(CHECK_TYPED_ARRAY_CAST)
danno@chromium.orgf005df62013-04-30 16:36:45 +00002791
2792#undef CHECK_TYPED_ARRAY_CAST
2793
2794
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002795void v8::DataView::CheckCast(Value* that) {
2796 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2797 ApiCheck(obj->IsJSDataView(),
2798 "v8::DataView::Cast()",
2799 "Could not convert to DataView");
2800}
2801
2802
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002803void v8::Date::CheckCast(v8::Value* that) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002804 i::Isolate* isolate = i::Isolate::Current();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002805 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002806 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_string()),
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002807 "v8::Date::Cast()",
2808 "Could not convert to date");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002809}
2810
2811
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002812void v8::StringObject::CheckCast(v8::Value* that) {
2813 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002814 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002815 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002816 "v8::StringObject::Cast()",
2817 "Could not convert to StringObject");
2818}
2819
2820
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002821void v8::SymbolObject::CheckCast(v8::Value* that) {
2822 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002823 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2824 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
2825 "v8::SymbolObject::Cast()",
2826 "Could not convert to SymbolObject");
2827}
2828
2829
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002830void v8::NumberObject::CheckCast(v8::Value* that) {
2831 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002832 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002833 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002834 "v8::NumberObject::Cast()",
2835 "Could not convert to NumberObject");
2836}
2837
2838
2839void v8::BooleanObject::CheckCast(v8::Value* that) {
2840 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002841 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002842 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002843 "v8::BooleanObject::Cast()",
2844 "Could not convert to BooleanObject");
2845}
2846
2847
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002848void v8::RegExp::CheckCast(v8::Value* that) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002849 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2850 ApiCheck(obj->IsJSRegExp(),
2851 "v8::RegExp::Cast()",
2852 "Could not convert to regular expression");
2853}
2854
2855
ager@chromium.org32912102009-01-16 10:38:43 +00002856bool Value::BooleanValue() const {
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +00002857 return Utils::OpenHandle(this)->BooleanValue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002858}
2859
2860
ager@chromium.org32912102009-01-16 10:38:43 +00002861double Value::NumberValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002862 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2863 i::Handle<i::Object> num;
2864 if (obj->IsNumber()) {
2865 num = obj;
2866 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002867 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002868 LOG_API(isolate, "NumberValue");
2869 ENTER_V8(isolate);
2870 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002871 num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002872 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002873 }
2874 return num->Number();
2875}
2876
2877
ager@chromium.org32912102009-01-16 10:38:43 +00002878int64_t Value::IntegerValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002879 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2880 i::Handle<i::Object> num;
2881 if (obj->IsNumber()) {
2882 num = obj;
2883 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002884 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002885 LOG_API(isolate, "IntegerValue");
2886 ENTER_V8(isolate);
2887 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002888 num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002889 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002890 }
2891 if (num->IsSmi()) {
2892 return i::Smi::cast(*num)->value();
2893 } else {
2894 return static_cast<int64_t>(num->Number());
2895 }
2896}
2897
2898
ager@chromium.org32912102009-01-16 10:38:43 +00002899Local<Int32> Value::ToInt32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002900 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2901 i::Handle<i::Object> num;
2902 if (obj->IsSmi()) {
2903 num = obj;
2904 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002905 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002906 LOG_API(isolate, "ToInt32");
2907 ENTER_V8(isolate);
2908 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002909 num = i::Execution::ToInt32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002910 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002911 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002912 return ToApiHandle<Int32>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913}
2914
2915
ager@chromium.org32912102009-01-16 10:38:43 +00002916Local<Uint32> Value::ToUint32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002917 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2918 i::Handle<i::Object> num;
2919 if (obj->IsSmi()) {
2920 num = obj;
2921 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002922 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002923 LOG_API(isolate, "ToUInt32");
2924 ENTER_V8(isolate);
2925 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002926 num = i::Execution::ToUint32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002927 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002928 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002929 return ToApiHandle<Uint32>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002930}
2931
2932
ager@chromium.org32912102009-01-16 10:38:43 +00002933Local<Uint32> Value::ToArrayIndex() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002934 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2935 if (obj->IsSmi()) {
2936 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2937 return Local<Uint32>();
2938 }
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, "ToArrayIndex");
2941 ENTER_V8(isolate);
2942 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002943 i::Handle<i::Object> string_obj =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002944 i::Execution::ToString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002945 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002946 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2947 uint32_t index;
2948 if (str->AsArrayIndex(&index)) {
2949 i::Handle<i::Object> value;
2950 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002951 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002952 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002953 value = isolate->factory()->NewNumber(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002954 }
2955 return Utils::Uint32ToLocal(value);
2956 }
2957 return Local<Uint32>();
2958}
2959
2960
ager@chromium.org32912102009-01-16 10:38:43 +00002961int32_t Value::Int32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002962 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2963 if (obj->IsSmi()) {
2964 return i::Smi::cast(*obj)->value();
2965 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002966 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002967 LOG_API(isolate, "Int32Value (slow)");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002968 ENTER_V8(isolate);
2969 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002970 i::Handle<i::Object> num =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002971 i::Execution::ToInt32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002972 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973 if (num->IsSmi()) {
2974 return i::Smi::cast(*num)->value();
2975 } else {
2976 return static_cast<int32_t>(num->Number());
2977 }
2978 }
2979}
2980
2981
ager@chromium.org32912102009-01-16 10:38:43 +00002982bool Value::Equals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002983 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00002984 if (EmptyCheck("v8::Value::Equals()", this) ||
2985 EmptyCheck("v8::Value::Equals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002987 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002988 LOG_API(isolate, "Equals");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002989 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002990 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2991 i::Handle<i::Object> other = Utils::OpenHandle(*that);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002992 // If both obj and other are JSObjects, we'd better compare by identity
2993 // immediately when going into JS builtin. The reason is Invoke
2994 // would overwrite global object receiver with global proxy.
2995 if (obj->IsJSObject() && other->IsJSObject()) {
2996 return *obj == *other;
2997 }
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002998 i::Handle<i::Object> args[] = { other };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002999 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003000 i::Handle<i::Object> result =
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003001 CallV8HeapFunction("EQUALS", obj, ARRAY_SIZE(args), args,
3002 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003003 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003004 return *result == i::Smi::FromInt(i::EQUAL);
3005}
3006
3007
ager@chromium.org32912102009-01-16 10:38:43 +00003008bool Value::StrictEquals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003009 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00003010 if (EmptyCheck("v8::Value::StrictEquals()", this) ||
3011 EmptyCheck("v8::Value::StrictEquals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003012 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00003013 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003014 LOG_API(isolate, "StrictEquals");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003015 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3016 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3017 // Must check HeapNumber first, since NaN !== NaN.
3018 if (obj->IsHeapNumber()) {
3019 if (!other->IsNumber()) return false;
3020 double x = obj->Number();
3021 double y = other->Number();
3022 // Must check explicitly for NaN:s on Windows, but -0 works fine.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00003023 return x == y && !std::isnan(x) && !std::isnan(y);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003024 } else if (*obj == *other) { // Also covers Booleans.
3025 return true;
3026 } else if (obj->IsSmi()) {
3027 return other->IsNumber() && obj->Number() == other->Number();
3028 } else if (obj->IsString()) {
3029 return other->IsString() &&
3030 i::String::cast(*obj)->Equals(i::String::cast(*other));
3031 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
3032 return other->IsUndefined() || other->IsUndetectableObject();
3033 } else {
3034 return false;
3035 }
3036}
3037
3038
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00003039bool Value::SameValue(Handle<Value> that) const {
3040 i::Isolate* isolate = i::Isolate::Current();
3041 if (EmptyCheck("v8::Value::SameValue()", this) ||
3042 EmptyCheck("v8::Value::SameValue()", that)) {
3043 return false;
3044 }
3045 LOG_API(isolate, "SameValue");
3046 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3047 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3048 return obj->SameValue(*other);
3049}
3050
3051
ager@chromium.org32912102009-01-16 10:38:43 +00003052uint32_t Value::Uint32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003053 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3054 if (obj->IsSmi()) {
3055 return i::Smi::cast(*obj)->value();
3056 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003057 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003058 LOG_API(isolate, "Uint32Value");
3059 ENTER_V8(isolate);
3060 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003061 i::Handle<i::Object> num =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003062 i::Execution::ToUint32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003063 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003064 if (num->IsSmi()) {
3065 return i::Smi::cast(*num)->value();
3066 } else {
3067 return static_cast<uint32_t>(num->Number());
3068 }
3069 }
3070}
3071
3072
3073bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003074 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003075 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003076 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003077 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003078 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003079 i::Handle<i::Object> self = Utils::OpenHandle(this);
3080 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3081 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003082 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.orge8412be2013-11-08 10:23:52 +00003083 i::Handle<i::Object> obj = i::Runtime::SetObjectProperty(
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00003084 isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003085 self,
3086 key_obj,
3087 value_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003088 static_cast<PropertyAttributes>(attribs),
3089 i::kNonStrictMode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003090 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003091 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003092 return true;
3093}
3094
3095
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003096bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003097 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003098 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003099 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003100 i::HandleScope scope(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003101 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3102 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003103 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003104 i::Handle<i::Object> obj = i::JSObject::SetElement(
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003105 self,
3106 index,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00003107 value_obj,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003108 NONE,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00003109 i::kNonStrictMode);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003110 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003111 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003112 return true;
3113}
3114
3115
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003116bool v8::Object::ForceSet(v8::Handle<Value> key,
3117 v8::Handle<Value> value,
3118 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003119 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003120 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003121 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003122 i::HandleScope scope(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003123 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3124 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3125 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003126 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003127 i::Handle<i::Object> obj = i::ForceSetProperty(
3128 self,
3129 key_obj,
3130 value_obj,
3131 static_cast<PropertyAttributes>(attribs));
3132 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003133 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003134 return true;
3135}
3136
3137
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00003138bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
3139 return Set(v8::Handle<Value>(reinterpret_cast<Value*>(*key)),
3140 value, DontEnum);
3141}
3142
3143
ager@chromium.orge2902be2009-06-08 12:21:35 +00003144bool v8::Object::ForceDelete(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003145 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003146 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003147 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003148 i::HandleScope scope(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003149 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3150 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00003152 // When deleting a property on the global object using ForceDelete
3153 // deoptimize all functions as optimized code does not check for the hole
3154 // value with DontDelete properties. We have to deoptimize all contexts
3155 // because of possible cross-context inlined functions.
3156 if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003157 i::Deoptimizer::DeoptimizeAll(isolate);
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00003158 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003160 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003161 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
3162 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003163 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003164 return obj->IsTrue();
3165}
3166
3167
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003168Local<Value> v8::Object::Get(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003169 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003170 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003171 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003172 i::Handle<i::Object> self = Utils::OpenHandle(this);
3173 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003174 EXCEPTION_PREAMBLE(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003175 i::Handle<i::Object> result = i::GetProperty(isolate, self, key_obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003176 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003177 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003178 return Utils::ToLocal(result);
3179}
3180
3181
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003182Local<Value> v8::Object::Get(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003183 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003184 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003185 ENTER_V8(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003186 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003187 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00003188 i::Handle<i::Object> result = i::Object::GetElement(isolate, self, index);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003189 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003190 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003191 return Utils::ToLocal(result);
3192}
3193
3194
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00003195Local<Value> v8::Object::GetPrivate(v8::Handle<Private> key) {
3196 return Get(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3197}
3198
3199
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003200PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
3201 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3202 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
3203 return static_cast<PropertyAttribute>(NONE));
3204 ENTER_V8(isolate);
3205 i::HandleScope scope(isolate);
3206 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3207 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003208 if (!key_obj->IsName()) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003209 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003210 key_obj = i::Execution::ToString(isolate, key_obj, &has_pending_exception);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003211 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3212 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003213 i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
3214 PropertyAttributes result = self->GetPropertyAttribute(*key_name);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003215 if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
3216 return static_cast<PropertyAttribute>(result);
3217}
3218
3219
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003220Local<Value> v8::Object::GetPrototype() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003221 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3222 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003223 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003224 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003225 i::Handle<i::Object> self = Utils::OpenHandle(this);
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003226 i::Handle<i::Object> result(self->GetPrototype(isolate), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003227 return Utils::ToLocal(result);
3228}
3229
3230
ager@chromium.org5c838252010-02-19 08:53:10 +00003231bool v8::Object::SetPrototype(Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003232 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003233 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003234 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00003235 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3236 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003237 // We do not allow exceptions thrown while setting the prototype
3238 // to propagate outside.
3239 TryCatch try_catch;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003240 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +00003241 i::Handle<i::Object> result = i::JSObject::SetPrototype(self, value_obj);
ager@chromium.org5c838252010-02-19 08:53:10 +00003242 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003243 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org5c838252010-02-19 08:53:10 +00003244 return true;
3245}
3246
3247
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003248Local<Object> v8::Object::FindInstanceInPrototypeChain(
3249 v8::Handle<FunctionTemplate> tmpl) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003250 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3251 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003252 "v8::Object::FindInstanceInPrototypeChain()",
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003253 return Local<v8::Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003254 ENTER_V8(isolate);
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003255 i::JSObject* object = *Utils::OpenHandle(this);
3256 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
machenbach@chromium.org9af454f2013-11-20 09:25:57 +00003257 while (!tmpl_info->IsTemplateFor(object)) {
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003258 i::Object* prototype = object->GetPrototype();
3259 if (!prototype->IsJSObject()) return Local<Object>();
3260 object = i::JSObject::cast(prototype);
3261 }
3262 return Utils::ToLocal(i::Handle<i::JSObject>(object));
3263}
3264
3265
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003266Local<Array> v8::Object::GetPropertyNames() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003267 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003268 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
3269 return Local<v8::Array>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003270 ENTER_V8(isolate);
3271 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003272 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003273 bool threw = false;
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00003274 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003275 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS, &threw);
3276 if (threw) return Local<v8::Array>();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003277 // Because we use caching to speed up enumeration it is important
3278 // to never change the result of the basic enumeration function so
3279 // we clone the result.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003280 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3281 i::Handle<i::JSArray> result =
3282 isolate->factory()->NewJSArrayWithElements(elms);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003283 return Utils::ToLocal(scope.CloseAndEscape(result));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003284}
3285
3286
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003287Local<Array> v8::Object::GetOwnPropertyNames() {
3288 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3289 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
3290 return Local<v8::Array>());
3291 ENTER_V8(isolate);
3292 i::HandleScope scope(isolate);
3293 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003294 bool threw = false;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003295 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003296 i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY, &threw);
3297 if (threw) return Local<v8::Array>();
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003298 // Because we use caching to speed up enumeration it is important
3299 // to never change the result of the basic enumeration function so
3300 // we clone the result.
3301 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3302 i::Handle<i::JSArray> result =
3303 isolate->factory()->NewJSArrayWithElements(elms);
3304 return Utils::ToLocal(scope.CloseAndEscape(result));
3305}
3306
3307
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003308Local<String> v8::Object::ObjectProtoToString() {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +00003309 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
3310 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
3311 ON_BAILOUT(i_isolate, "v8::Object::ObjectProtoToString()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003312 return Local<v8::String>());
machenbach@chromium.orgf9841892013-11-25 12:01:13 +00003313 ENTER_V8(i_isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003314 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3315
machenbach@chromium.orgf9841892013-11-25 12:01:13 +00003316 i::Handle<i::Object> name(self->class_name(), i_isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003317
3318 // Native implementation of Object.prototype.toString (v8natives.js):
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00003319 // var c = %_ClassOf(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003320 // if (c === 'Arguments') c = 'Object';
3321 // return "[object " + c + "]";
3322
3323 if (!name->IsString()) {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +00003324 return v8::String::NewFromUtf8(isolate, "[object ]");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003325 } else {
3326 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00003327 if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Arguments"))) {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +00003328 return v8::String::NewFromUtf8(isolate, "[object Object]");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329 } else {
3330 const char* prefix = "[object ";
3331 Local<String> str = Utils::ToLocal(class_name);
3332 const char* postfix = "]";
3333
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003334 int prefix_len = i::StrLength(prefix);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003335 int str_len = str->Utf8Length();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003336 int postfix_len = i::StrLength(postfix);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003337
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003338 int buf_len = prefix_len + str_len + postfix_len;
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003339 i::ScopedVector<char> buf(buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003340
3341 // Write prefix.
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003342 char* ptr = buf.start();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003343 i::OS::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003344 ptr += prefix_len;
3345
3346 // Write real content.
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003347 str->WriteUtf8(ptr, str_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003348 ptr += str_len;
3349
3350 // Write postfix.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003351 i::OS::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003352
3353 // Copy the buffer into a heap-allocated string and return it.
machenbach@chromium.orgf9841892013-11-25 12:01:13 +00003354 Local<String> result = v8::String::NewFromUtf8(
3355 isolate, buf.start(), String::kNormalString, buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003356 return result;
3357 }
3358 }
3359}
3360
3361
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00003362Local<Value> v8::Object::GetConstructor() {
3363 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3364 ON_BAILOUT(isolate, "v8::Object::GetConstructor()",
3365 return Local<v8::Function>());
3366 ENTER_V8(isolate);
3367 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003368 i::Handle<i::Object> constructor(self->GetConstructor(), isolate);
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00003369 return Utils::ToLocal(constructor);
3370}
3371
3372
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003373Local<String> v8::Object::GetConstructorName() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003374 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003375 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
3376 return Local<v8::String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003377 ENTER_V8(isolate);
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003378 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3379 i::Handle<i::String> name(self->constructor_name());
3380 return Utils::ToLocal(name);
3381}
3382
3383
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003384bool v8::Object::Delete(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003385 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003386 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003387 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003388 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003389 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003390 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3391 EXCEPTION_PREAMBLE(isolate);
3392 i::Handle<i::Object> obj = i::DeleteProperty(self, key_obj);
3393 has_pending_exception = obj.is_null();
3394 EXCEPTION_BAILOUT_CHECK(isolate, false);
3395 return obj->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003396}
3397
3398
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00003399bool v8::Object::DeletePrivate(v8::Handle<Private> key) {
3400 return Delete(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3401}
3402
3403
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003404bool v8::Object::Has(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003405 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3406 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
3407 ENTER_V8(isolate);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003408 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3409 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3410 EXCEPTION_PREAMBLE(isolate);
3411 i::Handle<i::Object> obj = i::HasProperty(self, key_obj);
3412 has_pending_exception = obj.is_null();
3413 EXCEPTION_BAILOUT_CHECK(isolate, false);
3414 return obj->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003415}
3416
3417
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00003418bool v8::Object::HasPrivate(v8::Handle<Private> key) {
3419 return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3420}
3421
3422
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003423bool v8::Object::Delete(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003424 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3425 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003426 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003427 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003428 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003429 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00003430 return i::JSReceiver::DeleteElement(self, index)->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003431}
3432
3433
3434bool v8::Object::Has(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003435 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3436 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003437 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003438 return i::JSReceiver::HasElement(self, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003439}
3440
3441
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003442template<typename Setter, typename Getter, typename Data>
3443static inline bool ObjectSetAccessor(Object* obj,
3444 Handle<String> name,
3445 Setter getter,
3446 Getter setter,
3447 Data data,
3448 AccessControl settings,
3449 PropertyAttribute attributes) {
3450 i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate();
3451 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3452 ENTER_V8(isolate);
3453 i::HandleScope scope(isolate);
3454 v8::Handle<AccessorSignature> signature;
3455 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(
3456 name, getter, setter, data, settings, attributes, signature);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003457 if (info.is_null()) return false;
3458 bool fast = Utils::OpenHandle(obj)->HasFastProperties();
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00003459 i::Handle<i::Object> result =
3460 i::JSObject::SetAccessor(Utils::OpenHandle(obj), info);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003461 if (result.is_null() || result->IsUndefined()) return false;
3462 if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(obj), 0);
3463 return true;
3464}
3465
3466
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003467bool Object::SetAccessor(Handle<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003468 AccessorGetterCallback getter,
3469 AccessorSetterCallback setter,
3470 v8::Handle<Value> data,
3471 AccessControl settings,
3472 PropertyAttribute attributes) {
3473 return ObjectSetAccessor(
3474 this, name, getter, setter, data, settings, attributes);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003475}
3476
3477
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00003478bool Object::SetDeclaredAccessor(Local<String> name,
3479 Local<DeclaredAccessorDescriptor> descriptor,
3480 PropertyAttribute attributes,
3481 AccessControl settings) {
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003482 void* null = NULL;
3483 return ObjectSetAccessor(
3484 this, name, descriptor, null, null, settings, attributes);
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003485}
3486
3487
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003488bool v8::Object::HasOwnProperty(Handle<String> key) {
3489 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3490 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3491 return false);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003492 return i::JSReceiver::HasLocalProperty(
3493 Utils::OpenHandle(this), Utils::OpenHandle(*key));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003494}
3495
3496
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003497bool v8::Object::HasRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003498 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3499 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003500 return false);
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +00003501 return i::JSObject::HasRealNamedProperty(Utils::OpenHandle(this),
3502 Utils::OpenHandle(*key));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503}
3504
3505
3506bool v8::Object::HasRealIndexedProperty(uint32_t index) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003507 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3508 ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003509 return false);
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +00003510 return i::JSObject::HasRealElementProperty(Utils::OpenHandle(this), index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003511}
3512
3513
3514bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003515 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3516 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003517 "v8::Object::HasRealNamedCallbackProperty()",
3518 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003519 ENTER_V8(isolate);
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +00003520 return i::JSObject::HasRealNamedCallbackProperty(Utils::OpenHandle(this),
3521 Utils::OpenHandle(*key));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003522}
3523
3524
3525bool v8::Object::HasNamedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003526 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3527 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003528 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003529 return Utils::OpenHandle(this)->HasNamedInterceptor();
3530}
3531
3532
3533bool v8::Object::HasIndexedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003534 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3535 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003536 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003537 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3538}
3539
3540
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003541static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
3542 i::Handle<i::JSObject> receiver,
3543 i::Handle<i::String> name,
3544 i::LookupResult* lookup) {
3545 if (!lookup->IsProperty()) {
3546 // No real property was found.
3547 return Local<Value>();
3548 }
3549
3550 // If the property being looked up is a callback, it can throw
3551 // an exception.
3552 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003553 PropertyAttributes ignored;
3554 i::Handle<i::Object> result =
3555 i::Object::GetProperty(receiver, receiver, lookup, name,
3556 &ignored);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003557 has_pending_exception = result.is_null();
3558 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3559
3560 return Utils::ToLocal(result);
3561}
3562
3563
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003564Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003565 Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003566 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3567 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003568 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003569 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003570 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003571 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3572 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003573 i::LookupResult lookup(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003574 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003575 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003576}
3577
3578
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003579Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003580 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3581 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003582 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003583 ENTER_V8(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003584 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3585 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003586 i::LookupResult lookup(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003587 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003588 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003589}
3590
3591
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003592// Turns on access checks by copying the map and setting the check flag.
3593// Because the object gets a new map, existing inline cache caching
3594// the old map of this object will fail.
3595void v8::Object::TurnOnAccessCheck() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003596 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003597 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003598 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003599 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003600 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3601
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003602 // When turning on access checks for a global object deoptimize all functions
3603 // as optimized code does not always handle access checks.
3604 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3605
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003606 i::Handle<i::Map> new_map =
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003607 isolate->factory()->CopyMap(i::Handle<i::Map>(obj->map()));
ager@chromium.org870a0b62008-11-04 11:43:05 +00003608 new_map->set_is_access_check_needed(true);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003609 obj->set_map(*new_map);
3610}
3611
3612
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00003613bool v8::Object::IsDirty() {
3614 return Utils::OpenHandle(this)->IsDirty();
3615}
3616
3617
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003618Local<v8::Object> v8::Object::Clone() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003619 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003620 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003621 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003622 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003623 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003624 i::Handle<i::JSObject> result = i::JSObject::Copy(self);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003625 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003626 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003627 return Utils::ToLocal(result);
3628}
3629
3630
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003631static i::Context* GetCreationContext(i::JSObject* object) {
3632 i::Object* constructor = object->map()->constructor();
3633 i::JSFunction* function;
3634 if (!constructor->IsJSFunction()) {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003635 // Functions have null as a constructor,
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003636 // but any JSFunction knows its context immediately.
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003637 ASSERT(object->IsJSFunction());
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003638 function = i::JSFunction::cast(object);
3639 } else {
3640 function = i::JSFunction::cast(constructor);
3641 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003642 return function->context()->native_context();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003643}
3644
3645
3646Local<v8::Context> v8::Object::CreationContext() {
3647 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3648 ON_BAILOUT(isolate,
3649 "v8::Object::CreationContext()", return Local<v8::Context>());
3650 ENTER_V8(isolate);
3651 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3652 i::Context* context = GetCreationContext(*self);
3653 return Utils::ToLocal(i::Handle<i::Context>(context));
3654}
3655
3656
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003657int v8::Object::GetIdentityHash() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003658 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003659 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003660 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003661 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003662 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
verwaest@chromium.org057bd502013-11-06 12:03:29 +00003663 return i::Handle<i::Smi>::cast(
3664 i::JSReceiver::GetOrCreateIdentityHash(self))->value();
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003665}
3666
3667
3668bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3669 v8::Handle<v8::Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003670 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003671 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00003672 if (value.IsEmpty()) return DeleteHiddenValue(key);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003673 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003674 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003675 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003676 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003677 i::Handle<i::String> key_string =
3678 isolate->factory()->InternalizeString(key_obj);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003679 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003680 i::Handle<i::Object> result =
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003681 i::JSObject::SetHiddenProperty(self, key_string, value_obj);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003682 return *result == *self;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003683}
3684
3685
3686v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003687 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003688 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3689 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003690 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003691 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003692 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00003693 i::Handle<i::String> key_string =
3694 isolate->factory()->InternalizeString(key_obj);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003695 i::Handle<i::Object> result(self->GetHiddenProperty(*key_string), isolate);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00003696 if (result->IsTheHole()) return v8::Local<v8::Value>();
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003697 return Utils::ToLocal(result);
3698}
3699
3700
3701bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003702 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003703 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003704 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003705 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003706 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003707 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00003708 i::Handle<i::String> key_string =
3709 isolate->factory()->InternalizeString(key_obj);
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00003710 i::JSObject::DeleteHiddenProperty(self, key_string);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003711 return true;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003712}
3713
3714
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003715namespace {
3716
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003717static i::ElementsKind GetElementsKindFromExternalArrayType(
3718 ExternalArrayType array_type) {
3719 switch (array_type) {
3720 case kExternalByteArray:
3721 return i::EXTERNAL_BYTE_ELEMENTS;
3722 break;
3723 case kExternalUnsignedByteArray:
3724 return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3725 break;
3726 case kExternalShortArray:
3727 return i::EXTERNAL_SHORT_ELEMENTS;
3728 break;
3729 case kExternalUnsignedShortArray:
3730 return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3731 break;
3732 case kExternalIntArray:
3733 return i::EXTERNAL_INT_ELEMENTS;
3734 break;
3735 case kExternalUnsignedIntArray:
3736 return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
3737 break;
3738 case kExternalFloatArray:
3739 return i::EXTERNAL_FLOAT_ELEMENTS;
3740 break;
3741 case kExternalDoubleArray:
3742 return i::EXTERNAL_DOUBLE_ELEMENTS;
3743 break;
3744 case kExternalPixelArray:
3745 return i::EXTERNAL_PIXEL_ELEMENTS;
3746 break;
3747 }
3748 UNREACHABLE();
3749 return i::DICTIONARY_ELEMENTS;
3750}
3751
3752
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003753void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3754 void* data,
3755 ExternalArrayType array_type,
3756 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003757 i::Isolate* isolate = object->GetIsolate();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003758 i::Handle<i::ExternalArray> array =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003759 isolate->factory()->NewExternalArray(length, array_type, data);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003760
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003761 i::Handle<i::Map> external_array_map =
3762 isolate->factory()->GetElementsTransitionMap(
3763 object,
3764 GetElementsKindFromExternalArrayType(array_type));
3765
3766 object->set_map(*external_array_map);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003767 object->set_elements(*array);
3768}
3769
3770} // namespace
3771
3772
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003773void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003774 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003775 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003776 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003777 i::HandleScope scope(isolate);
danno@chromium.org412fa512012-09-14 13:28:26 +00003778 if (!ApiCheck(length >= 0 && length <= i::ExternalPixelArray::kMaxLength,
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003779 "v8::Object::SetIndexedPropertiesToPixelData()",
3780 "length exceeds max acceptable value")) {
3781 return;
3782 }
3783 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3784 if (!ApiCheck(!self->IsJSArray(),
3785 "v8::Object::SetIndexedPropertiesToPixelData()",
3786 "JSArray is not supported")) {
3787 return;
3788 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003789 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003790}
3791
3792
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003793bool v8::Object::HasIndexedPropertiesInPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003794 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003795 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3796 return false);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003797 return self->HasExternalPixelElements();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003798}
3799
3800
3801uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003802 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003803 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3804 return NULL);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003805 if (self->HasExternalPixelElements()) {
3806 return i::ExternalPixelArray::cast(self->elements())->
3807 external_pixel_pointer();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003808 } else {
3809 return NULL;
3810 }
3811}
3812
3813
3814int v8::Object::GetIndexedPropertiesPixelDataLength() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003815 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003816 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3817 return -1);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003818 if (self->HasExternalPixelElements()) {
3819 return i::ExternalPixelArray::cast(self->elements())->length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003820 } else {
3821 return -1;
3822 }
3823}
3824
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003825
ager@chromium.org3811b432009-10-28 14:53:37 +00003826void v8::Object::SetIndexedPropertiesToExternalArrayData(
3827 void* data,
3828 ExternalArrayType array_type,
3829 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003830 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003831 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003832 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003833 i::HandleScope scope(isolate);
danno@chromium.org412fa512012-09-14 13:28:26 +00003834 if (!ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
ager@chromium.org3811b432009-10-28 14:53:37 +00003835 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3836 "length exceeds max acceptable value")) {
3837 return;
3838 }
3839 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3840 if (!ApiCheck(!self->IsJSArray(),
3841 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3842 "JSArray is not supported")) {
3843 return;
3844 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003845 PrepareExternalArrayElements(self, data, array_type, length);
ager@chromium.org3811b432009-10-28 14:53:37 +00003846}
3847
3848
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003849bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003850 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3851 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003852 "v8::HasIndexedPropertiesInExternalArrayData()",
3853 return false);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003854 return self->HasExternalArrayElements();
3855}
3856
3857
3858void* v8::Object::GetIndexedPropertiesExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003859 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3860 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003861 "v8::GetIndexedPropertiesExternalArrayData()",
3862 return NULL);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003863 if (self->HasExternalArrayElements()) {
3864 return i::ExternalArray::cast(self->elements())->external_pointer();
3865 } else {
3866 return NULL;
3867 }
3868}
3869
3870
3871ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003872 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3873 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003874 "v8::GetIndexedPropertiesExternalArrayDataType()",
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003875 return static_cast<ExternalArrayType>(-1));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003876 switch (self->elements()->map()->instance_type()) {
3877 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3878 return kExternalByteArray;
3879 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3880 return kExternalUnsignedByteArray;
3881 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3882 return kExternalShortArray;
3883 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3884 return kExternalUnsignedShortArray;
3885 case i::EXTERNAL_INT_ARRAY_TYPE:
3886 return kExternalIntArray;
3887 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3888 return kExternalUnsignedIntArray;
3889 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3890 return kExternalFloatArray;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003891 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3892 return kExternalDoubleArray;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003893 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3894 return kExternalPixelArray;
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003895 default:
3896 return static_cast<ExternalArrayType>(-1);
3897 }
3898}
3899
3900
3901int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003902 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3903 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003904 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3905 return 0);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003906 if (self->HasExternalArrayElements()) {
3907 return i::ExternalArray::cast(self->elements())->length();
3908 } else {
3909 return -1;
3910 }
3911}
3912
3913
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003914bool v8::Object::IsCallable() {
3915 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3916 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3917 ENTER_V8(isolate);
3918 i::HandleScope scope(isolate);
3919 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
machenbach@chromium.org9f18d912013-11-28 13:42:41 +00003920 return obj->IsCallable();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003921}
3922
3923
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00003924Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003925 int argc,
lrn@chromium.org1c092762011-05-09 09:42:16 +00003926 v8::Handle<v8::Value> argv[]) {
3927 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3928 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3929 return Local<v8::Value>());
3930 LOG_API(isolate, "Object::CallAsFunction");
3931 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00003932 i::Logger::TimerEventScope timer_scope(
3933 isolate, i::Logger::TimerEventScope::v8_execute);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003934 i::HandleScope scope(isolate);
3935 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3936 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3937 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003938 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003939 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3940 if (obj->IsJSFunction()) {
3941 fun = i::Handle<i::JSFunction>::cast(obj);
3942 } else {
3943 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003944 i::Handle<i::Object> delegate = i::Execution::TryGetFunctionDelegate(
3945 isolate, obj, &has_pending_exception);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003946 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3947 fun = i::Handle<i::JSFunction>::cast(delegate);
3948 recv_obj = obj;
3949 }
3950 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00003951 i::Handle<i::Object> returned = i::Execution::Call(
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00003952 isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003953 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003954 return Utils::ToLocal(scope.CloseAndEscape(returned));
3955}
3956
3957
3958Local<v8::Value> Object::CallAsConstructor(int argc,
3959 v8::Handle<v8::Value> argv[]) {
3960 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3961 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3962 return Local<v8::Object>());
3963 LOG_API(isolate, "Object::CallAsConstructor");
3964 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00003965 i::Logger::TimerEventScope timer_scope(
3966 isolate, i::Logger::TimerEventScope::v8_execute);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003967 i::HandleScope scope(isolate);
3968 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3969 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003970 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003971 if (obj->IsJSFunction()) {
3972 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
3973 EXCEPTION_PREAMBLE(isolate);
3974 i::Handle<i::Object> returned =
3975 i::Execution::New(fun, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003976 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003977 return Utils::ToLocal(scope.CloseAndEscape(
3978 i::Handle<i::JSObject>::cast(returned)));
3979 }
3980 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003981 i::Handle<i::Object> delegate = i::Execution::TryGetConstructorDelegate(
3982 isolate, obj, &has_pending_exception);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003983 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
3984 if (!delegate->IsUndefined()) {
3985 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
3986 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00003987 i::Handle<i::Object> returned = i::Execution::Call(
3988 isolate, fun, obj, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003989 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003990 ASSERT(!delegate->IsUndefined());
3991 return Utils::ToLocal(scope.CloseAndEscape(returned));
3992 }
3993 return Local<v8::Object>();
3994}
3995
3996
dslomov@chromium.org639bac02013-09-09 11:58:54 +00003997Local<Function> Function::New(Isolate* v8_isolate,
3998 FunctionCallback callback,
3999 Local<Value> data,
4000 int length) {
4001 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
4002 LOG_API(isolate, "Function::New");
4003 ENTER_V8(isolate);
4004 return FunctionTemplateNew(
4005 isolate, callback, data, Local<Signature>(), length, true)->
4006 GetFunction();
4007}
4008
4009
ager@chromium.org32912102009-01-16 10:38:43 +00004010Local<v8::Object> Function::NewInstance() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004011 return NewInstance(0, NULL);
4012}
4013
4014
4015Local<v8::Object> Function::NewInstance(int argc,
ager@chromium.org32912102009-01-16 10:38:43 +00004016 v8::Handle<v8::Value> argv[]) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004017 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004018 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
4019 return Local<v8::Object>());
4020 LOG_API(isolate, "Function::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004021 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00004022 i::Logger::TimerEventScope timer_scope(
4023 isolate, i::Logger::TimerEventScope::v8_execute);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00004024 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
4026 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00004027 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004028 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004029 i::Handle<i::Object> returned =
4030 i::Execution::New(function, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004031 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00004032 return scope.Escape(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004033}
4034
4035
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00004036Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004037 v8::Handle<v8::Value> argv[]) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004038 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004039 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
4040 LOG_API(isolate, "Function::Call");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004041 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00004042 i::Logger::TimerEventScope timer_scope(
4043 isolate, i::Logger::TimerEventScope::v8_execute);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004044 i::Object* raw_result = NULL;
4045 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004046 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004047 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
4048 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4049 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00004050 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004051 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00004052 i::Handle<i::Object> returned = i::Execution::Call(
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00004053 isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004054 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004055 raw_result = *returned;
4056 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004057 i::Handle<i::Object> result(raw_result, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004058 return Utils::ToLocal(result);
4059}
4060
4061
4062void Function::SetName(v8::Handle<v8::String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004063 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4064 ENTER_V8(isolate);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004065 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004066 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4067 func->shared()->set_name(*Utils::OpenHandle(*name));
4068}
4069
4070
ager@chromium.org32912102009-01-16 10:38:43 +00004071Handle<Value> Function::GetName() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004072 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004073 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name(),
4074 func->GetIsolate()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004075}
4076
4077
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004078Handle<Value> Function::GetInferredName() const {
4079 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004080 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4081 func->GetIsolate()));
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004082}
4083
4084
bmeurer@chromium.orgc9913f02013-10-24 06:31:36 +00004085Handle<Value> Function::GetDisplayName() const {
4086 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4087 ON_BAILOUT(isolate, "v8::Function::GetDisplayName()",
4088 return ToApiHandle<Primitive>(
4089 isolate->factory()->undefined_value()));
4090 ENTER_V8(isolate);
4091 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4092 i::Handle<i::String> property_name =
4093 isolate->factory()->InternalizeOneByteString(
4094 STATIC_ASCII_VECTOR("displayName"));
4095 i::LookupResult lookup(isolate);
4096 func->LookupRealNamedProperty(*property_name, &lookup);
4097 if (lookup.IsFound()) {
4098 i::Object* value = lookup.GetLazyValue();
4099 if (value && value->IsString()) {
4100 i::String* name = i::String::cast(value);
4101 if (name->length() > 0) return Utils::ToLocal(i::Handle<i::String>(name));
4102 }
4103 }
4104 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
4105}
4106
4107
ager@chromium.org5c838252010-02-19 08:53:10 +00004108ScriptOrigin Function::GetScriptOrigin() const {
4109 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4110 if (func->shared()->script()->IsScript()) {
4111 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00004112 i::Handle<i::Object> scriptName = GetScriptNameOrSourceURL(script);
ulan@chromium.org0f13e742014-01-03 15:51:11 +00004113 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(func->GetIsolate());
ager@chromium.org5c838252010-02-19 08:53:10 +00004114 v8::ScriptOrigin origin(
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00004115 Utils::ToLocal(scriptName),
ulan@chromium.org0f13e742014-01-03 15:51:11 +00004116 v8::Integer::New(isolate, script->line_offset()->value()),
4117 v8::Integer::New(isolate, script->column_offset()->value()));
ager@chromium.org5c838252010-02-19 08:53:10 +00004118 return origin;
4119 }
4120 return v8::ScriptOrigin(Handle<Value>());
4121}
4122
4123
4124const int Function::kLineOffsetNotFound = -1;
4125
4126
4127int Function::GetScriptLineNumber() const {
4128 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4129 if (func->shared()->script()->IsScript()) {
4130 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4131 return i::GetScriptLineNumber(script, func->shared()->start_position());
4132 }
4133 return kLineOffsetNotFound;
4134}
4135
4136
danno@chromium.orgc612e022011-11-10 11:38:15 +00004137int Function::GetScriptColumnNumber() const {
4138 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4139 if (func->shared()->script()->IsScript()) {
4140 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4141 return i::GetScriptColumnNumber(script, func->shared()->start_position());
4142 }
4143 return kLineOffsetNotFound;
4144}
4145
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004146
bmeurer@chromium.orgdb783292013-10-23 06:51:00 +00004147bool Function::IsBuiltin() const {
4148 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4149 return func->IsBuiltin();
4150}
4151
4152
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004153int Function::ScriptId() const {
4154 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4155 if (!func->shared()->script()->IsScript()) return v8::Script::kNoScriptId;
4156 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4157 return script->id()->value();
4158}
4159
4160
yangguo@chromium.org49546742013-12-23 16:17:49 +00004161Local<v8::Value> Function::GetBoundFunction() const {
4162 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4163 if (!func->shared()->bound()) {
4164 return v8::Undefined(reinterpret_cast<v8::Isolate*>(func->GetIsolate()));
4165 }
4166 i::Handle<i::FixedArray> bound_args = i::Handle<i::FixedArray>(
4167 i::FixedArray::cast(func->function_bindings()));
4168 i::Handle<i::Object> original(
4169 bound_args->get(i::JSFunction::kBoundFunctionIndex),
4170 func->GetIsolate());
4171 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(original));
4172}
4173
4174
ager@chromium.org32912102009-01-16 10:38:43 +00004175int String::Length() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004176 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004177 return str->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004178}
4179
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004180
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004181bool String::IsOneByte() const {
4182 i::Handle<i::String> str = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00004183 return str->HasOnlyOneByteChars();
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004184}
4185
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00004186
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004187// Helpers for ContainsOnlyOneByteHelper
4188template<size_t size> struct OneByteMask;
4189template<> struct OneByteMask<4> {
4190 static const uint32_t value = 0xFF00FF00;
4191};
4192template<> struct OneByteMask<8> {
4193 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4194};
4195static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4196static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4197static inline bool Unaligned(const uint16_t* chars) {
4198 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4199}
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00004200
4201
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004202static inline const uint16_t* Align(const uint16_t* chars) {
4203 return reinterpret_cast<uint16_t*>(
4204 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4205}
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004206
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004207class ContainsOnlyOneByteHelper {
4208 public:
4209 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4210 bool Check(i::String* string) {
4211 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4212 if (cons_string == NULL) return is_one_byte_;
4213 return CheckCons(cons_string);
4214 }
4215 void VisitOneByteString(const uint8_t* chars, int length) {
4216 // Nothing to do.
4217 }
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004218 void VisitTwoByteString(const uint16_t* chars, int length) {
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004219 // Accumulated bits.
4220 uintptr_t acc = 0;
4221 // Align to uintptr_t.
4222 const uint16_t* end = chars + length;
4223 while (Unaligned(chars) && chars != end) {
4224 acc |= *chars++;
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004225 }
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004226 // Read word aligned in blocks,
4227 // checking the return value at the end of each block.
4228 const uint16_t* aligned_end = Align(end);
4229 const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4230 const int inner_loops = 16;
4231 while (chars + inner_loops*increment < aligned_end) {
4232 for (int i = 0; i < inner_loops; i++) {
4233 acc |= *reinterpret_cast<const uintptr_t*>(chars);
4234 chars += increment;
4235 }
4236 // Check for early return.
4237 if ((acc & kOneByteMask) != 0) {
4238 is_one_byte_ = false;
4239 return;
4240 }
4241 }
4242 // Read the rest.
4243 while (chars != end) {
4244 acc |= *chars++;
4245 }
4246 // Check result.
4247 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004248 }
4249
4250 private:
4251 bool CheckCons(i::ConsString* cons_string) {
4252 while (true) {
4253 // Check left side if flat.
4254 i::String* left = cons_string->first();
4255 i::ConsString* left_as_cons =
4256 i::String::VisitFlat(this, left, 0);
4257 if (!is_one_byte_) return false;
4258 // Check right side if flat.
4259 i::String* right = cons_string->second();
4260 i::ConsString* right_as_cons =
4261 i::String::VisitFlat(this, right, 0);
4262 if (!is_one_byte_) return false;
4263 // Standard recurse/iterate trick.
4264 if (left_as_cons != NULL && right_as_cons != NULL) {
4265 if (left->length() < right->length()) {
4266 CheckCons(left_as_cons);
4267 cons_string = right_as_cons;
4268 } else {
4269 CheckCons(right_as_cons);
4270 cons_string = left_as_cons;
4271 }
4272 // Check fast return.
4273 if (!is_one_byte_) return false;
4274 continue;
4275 }
4276 // Descend left in place.
4277 if (left_as_cons != NULL) {
4278 cons_string = left_as_cons;
4279 continue;
4280 }
4281 // Descend right in place.
4282 if (right_as_cons != NULL) {
4283 cons_string = right_as_cons;
4284 continue;
4285 }
4286 // Terminate.
4287 break;
4288 }
4289 return is_one_byte_;
4290 }
4291 bool is_one_byte_;
4292 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4293};
4294
4295
4296bool String::ContainsOnlyOneByte() const {
4297 i::Handle<i::String> str = Utils::OpenHandle(this);
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004298 if (str->HasOnlyOneByteChars()) return true;
4299 ContainsOnlyOneByteHelper helper;
4300 return helper.Check(*str);
4301}
4302
4303
ulan@chromium.org750145a2013-03-07 15:14:13 +00004304class Utf8LengthHelper : public i::AllStatic {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004305 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004306 enum State {
4307 kEndsWithLeadingSurrogate = 1 << 0,
4308 kStartsWithTrailingSurrogate = 1 << 1,
4309 kLeftmostEdgeIsCalculated = 1 << 2,
4310 kRightmostEdgeIsCalculated = 1 << 3,
4311 kLeftmostEdgeIsSurrogate = 1 << 4,
4312 kRightmostEdgeIsSurrogate = 1 << 5
4313 };
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004314
ulan@chromium.org750145a2013-03-07 15:14:13 +00004315 static const uint8_t kInitialState = 0;
4316
4317 static inline bool EndsWithSurrogate(uint8_t state) {
4318 return state & kEndsWithLeadingSurrogate;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004319 }
4320
ulan@chromium.org750145a2013-03-07 15:14:13 +00004321 static inline bool StartsWithSurrogate(uint8_t state) {
4322 return state & kStartsWithTrailingSurrogate;
4323 }
4324
4325 class Visitor {
4326 public:
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004327 inline explicit Visitor()
ulan@chromium.org750145a2013-03-07 15:14:13 +00004328 : utf8_length_(0),
4329 state_(kInitialState) {}
4330
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004331 void VisitOneByteString(const uint8_t* chars, int length) {
4332 int utf8_length = 0;
4333 // Add in length 1 for each non-ASCII character.
4334 for (int i = 0; i < length; i++) {
4335 utf8_length += *chars++ >> 7;
4336 }
4337 // Add in length 1 for each character.
4338 utf8_length_ = utf8_length + length;
4339 state_ = kInitialState;
4340 }
4341
4342 void VisitTwoByteString(const uint16_t* chars, int length) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00004343 int utf8_length = 0;
4344 int last_character = unibrow::Utf16::kNoPreviousCharacter;
4345 for (int i = 0; i < length; i++) {
4346 uint16_t c = chars[i];
4347 utf8_length += unibrow::Utf8::Length(c, last_character);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004348 last_character = c;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004349 }
4350 utf8_length_ = utf8_length;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004351 uint8_t state = 0;
4352 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4353 state |= kStartsWithTrailingSurrogate;
4354 }
4355 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4356 state |= kEndsWithLeadingSurrogate;
4357 }
4358 state_ = state;
4359 }
4360
4361 static i::ConsString* VisitFlat(i::String* string,
4362 int* length,
4363 uint8_t* state) {
4364 Visitor visitor;
4365 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4366 *length = visitor.utf8_length_;
4367 *state = visitor.state_;
4368 return cons_string;
4369 }
4370
4371 private:
4372 int utf8_length_;
4373 uint8_t state_;
4374 DISALLOW_COPY_AND_ASSIGN(Visitor);
4375 };
4376
4377 static inline void MergeLeafLeft(int* length,
4378 uint8_t* state,
4379 uint8_t leaf_state) {
4380 bool edge_surrogate = StartsWithSurrogate(leaf_state);
4381 if (!(*state & kLeftmostEdgeIsCalculated)) {
4382 ASSERT(!(*state & kLeftmostEdgeIsSurrogate));
4383 *state |= kLeftmostEdgeIsCalculated
4384 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4385 } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4386 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4387 }
4388 if (EndsWithSurrogate(leaf_state)) {
4389 *state |= kEndsWithLeadingSurrogate;
4390 } else {
4391 *state &= ~kEndsWithLeadingSurrogate;
4392 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004393 }
4394
ulan@chromium.org750145a2013-03-07 15:14:13 +00004395 static inline void MergeLeafRight(int* length,
4396 uint8_t* state,
4397 uint8_t leaf_state) {
4398 bool edge_surrogate = EndsWithSurrogate(leaf_state);
4399 if (!(*state & kRightmostEdgeIsCalculated)) {
4400 ASSERT(!(*state & kRightmostEdgeIsSurrogate));
4401 *state |= (kRightmostEdgeIsCalculated
4402 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4403 } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4404 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4405 }
4406 if (StartsWithSurrogate(leaf_state)) {
4407 *state |= kStartsWithTrailingSurrogate;
4408 } else {
4409 *state &= ~kStartsWithTrailingSurrogate;
4410 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004411 }
4412
ulan@chromium.org750145a2013-03-07 15:14:13 +00004413 static inline void MergeTerminal(int* length,
4414 uint8_t state,
4415 uint8_t* state_out) {
4416 ASSERT((state & kLeftmostEdgeIsCalculated) &&
4417 (state & kRightmostEdgeIsCalculated));
4418 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4419 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4420 }
4421 *state_out = kInitialState |
4422 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4423 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4424 }
4425
4426 static int Calculate(i::ConsString* current, uint8_t* state_out) {
4427 using namespace internal;
4428 int total_length = 0;
4429 uint8_t state = kInitialState;
4430 while (true) {
4431 i::String* left = current->first();
4432 i::String* right = current->second();
4433 uint8_t right_leaf_state;
4434 uint8_t left_leaf_state;
4435 int leaf_length;
4436 ConsString* left_as_cons =
4437 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4438 if (left_as_cons == NULL) {
4439 total_length += leaf_length;
4440 MergeLeafLeft(&total_length, &state, left_leaf_state);
4441 }
4442 ConsString* right_as_cons =
4443 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4444 if (right_as_cons == NULL) {
4445 total_length += leaf_length;
4446 MergeLeafRight(&total_length, &state, right_leaf_state);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004447 if (left_as_cons != NULL) {
4448 // 1 Leaf node. Descend in place.
4449 current = left_as_cons;
4450 continue;
4451 } else {
4452 // Terminal node.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004453 MergeTerminal(&total_length, state, state_out);
4454 return total_length;
4455 }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004456 } else if (left_as_cons == NULL) {
4457 // 1 Leaf node. Descend in place.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004458 current = right_as_cons;
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004459 continue;
4460 }
4461 // Both strings are ConsStrings.
4462 // Recurse on smallest.
4463 if (left->length() < right->length()) {
4464 total_length += Calculate(left_as_cons, &left_leaf_state);
4465 MergeLeafLeft(&total_length, &state, left_leaf_state);
4466 current = right_as_cons;
4467 } else {
4468 total_length += Calculate(right_as_cons, &right_leaf_state);
4469 MergeLeafRight(&total_length, &state, right_leaf_state);
4470 current = left_as_cons;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004471 }
4472 }
4473 UNREACHABLE();
4474 return 0;
4475 }
4476
4477 static inline int Calculate(i::ConsString* current) {
4478 uint8_t state = kInitialState;
4479 return Calculate(current, &state);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004480 }
4481
4482 private:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004483 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004484};
4485
4486
4487static int Utf8Length(i::String* str, i::Isolate* isolate) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00004488 int length = str->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004489 if (length == 0) return 0;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004490 uint8_t state;
4491 i::ConsString* cons_string =
4492 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4493 if (cons_string == NULL) return length;
4494 return Utf8LengthHelper::Calculate(cons_string);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004495}
4496
4497
4498int String::Utf8Length() const {
4499 i::Handle<i::String> str = Utils::OpenHandle(this);
4500 i::Isolate* isolate = str->GetIsolate();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004501 return v8::Utf8Length(*str, isolate);
4502}
4503
4504
4505class Utf8WriterVisitor {
4506 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004507 Utf8WriterVisitor(
4508 char* buffer, int capacity, bool skip_capacity_check)
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004509 : early_termination_(false),
4510 last_character_(unibrow::Utf16::kNoPreviousCharacter),
4511 buffer_(buffer),
4512 start_(buffer),
4513 capacity_(capacity),
ulan@chromium.org750145a2013-03-07 15:14:13 +00004514 skip_capacity_check_(capacity == -1 || skip_capacity_check),
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004515 utf16_chars_read_(0) {
4516 }
4517
4518 static int WriteEndCharacter(uint16_t character,
4519 int last_character,
4520 int remaining,
4521 char* const buffer) {
4522 using namespace unibrow;
4523 ASSERT(remaining > 0);
4524 // We can't use a local buffer here because Encode needs to modify
4525 // previous characters in the stream. We know, however, that
4526 // exactly one character will be advanced.
4527 if (Utf16::IsTrailSurrogate(character) &&
4528 Utf16::IsLeadSurrogate(last_character)) {
4529 int written = Utf8::Encode(buffer, character, last_character);
4530 ASSERT(written == 1);
4531 return written;
4532 }
4533 // Use a scratch buffer to check the required characters.
4534 char temp_buffer[Utf8::kMaxEncodedSize];
4535 // Can't encode using last_character as gcc has array bounds issues.
4536 int written = Utf8::Encode(temp_buffer,
4537 character,
ulan@chromium.org750145a2013-03-07 15:14:13 +00004538 Utf16::kNoPreviousCharacter);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004539 // Won't fit.
4540 if (written > remaining) return 0;
4541 // Copy over the character from temp_buffer.
4542 for (int j = 0; j < written; j++) {
4543 buffer[j] = temp_buffer[j];
4544 }
4545 return written;
4546 }
4547
4548 template<typename Char>
4549 void Visit(const Char* chars, const int length) {
4550 using namespace unibrow;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004551 ASSERT(!early_termination_);
ulan@chromium.org750145a2013-03-07 15:14:13 +00004552 if (length == 0) return;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004553 // Copy state to stack.
4554 char* buffer = buffer_;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004555 int last_character =
4556 sizeof(Char) == 1 ? Utf16::kNoPreviousCharacter : last_character_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004557 int i = 0;
4558 // Do a fast loop where there is no exit capacity check.
4559 while (true) {
4560 int fast_length;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004561 if (skip_capacity_check_) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004562 fast_length = length;
4563 } else {
4564 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4565 // Need enough space to write everything but one character.
4566 STATIC_ASSERT(Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
ulan@chromium.org750145a2013-03-07 15:14:13 +00004567 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
4568 int writable_length =
4569 (remaining_capacity - max_size_per_char)/max_size_per_char;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004570 // Need to drop into slow loop.
4571 if (writable_length <= 0) break;
4572 fast_length = i + writable_length;
4573 if (fast_length > length) fast_length = length;
4574 }
4575 // Write the characters to the stream.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004576 if (sizeof(Char) == 1) {
4577 for (; i < fast_length; i++) {
4578 buffer +=
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004579 Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
ulan@chromium.org750145a2013-03-07 15:14:13 +00004580 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
4581 }
4582 } else {
4583 for (; i < fast_length; i++) {
4584 uint16_t character = *chars++;
4585 buffer += Utf8::Encode(buffer, character, last_character);
4586 last_character = character;
4587 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
4588 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004589 }
4590 // Array is fully written. Exit.
4591 if (fast_length == length) {
4592 // Write state back out to object.
4593 last_character_ = last_character;
4594 buffer_ = buffer;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004595 utf16_chars_read_ += length;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004596 return;
4597 }
4598 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004599 ASSERT(!skip_capacity_check_);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004600 // Slow loop. Must check capacity on each iteration.
4601 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4602 ASSERT(remaining_capacity >= 0);
4603 for (; i < length && remaining_capacity > 0; i++) {
4604 uint16_t character = *chars++;
4605 int written = WriteEndCharacter(character,
4606 last_character,
4607 remaining_capacity,
4608 buffer);
4609 if (written == 0) {
4610 early_termination_ = true;
4611 break;
4612 }
4613 buffer += written;
4614 remaining_capacity -= written;
4615 last_character = character;
4616 }
4617 // Write state back out to object.
4618 last_character_ = last_character;
4619 buffer_ = buffer;
4620 utf16_chars_read_ += i;
4621 }
4622
4623 inline bool IsDone() {
4624 return early_termination_;
4625 }
4626
ulan@chromium.org750145a2013-03-07 15:14:13 +00004627 inline void VisitOneByteString(const uint8_t* chars, int length) {
4628 Visit(chars, length);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004629 }
4630
ulan@chromium.org750145a2013-03-07 15:14:13 +00004631 inline void VisitTwoByteString(const uint16_t* chars, int length) {
4632 Visit(chars, length);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004633 }
4634
ulan@chromium.org750145a2013-03-07 15:14:13 +00004635 int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004636 // Write out number of utf16 characters written to the stream.
4637 if (utf16_chars_read_out != NULL) {
4638 *utf16_chars_read_out = utf16_chars_read_;
4639 }
4640 // Only null terminate if all of the string was written and there's space.
4641 if (write_null &&
4642 !early_termination_ &&
4643 (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
4644 *buffer_++ = '\0';
4645 }
4646 return static_cast<int>(buffer_ - start_);
4647 }
4648
4649 private:
4650 bool early_termination_;
4651 int last_character_;
4652 char* buffer_;
4653 char* const start_;
4654 int capacity_;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004655 bool const skip_capacity_check_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004656 int utf16_chars_read_;
4657 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
4658};
4659
4660
ulan@chromium.org750145a2013-03-07 15:14:13 +00004661static bool RecursivelySerializeToUtf8(i::String* current,
4662 Utf8WriterVisitor* writer,
4663 int recursion_budget) {
4664 while (!writer->IsDone()) {
4665 i::ConsString* cons_string = i::String::VisitFlat(writer, current);
4666 if (cons_string == NULL) return true; // Leaf node.
4667 if (recursion_budget <= 0) return false;
4668 // Must write the left branch first.
4669 i::String* first = cons_string->first();
4670 bool success = RecursivelySerializeToUtf8(first,
4671 writer,
4672 recursion_budget - 1);
4673 if (!success) return false;
4674 // Inline tail recurse for right branch.
4675 current = cons_string->second();
4676 }
4677 return true;
4678}
4679
4680
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00004681int String::WriteUtf8(char* buffer,
4682 int capacity,
4683 int* nchars_ref,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004684 int options) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004685 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004686 LOG_API(isolate, "String::WriteUtf8");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004687 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00004688 i::Handle<i::String> str = Utils::OpenHandle(this);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004689 if (options & HINT_MANY_WRITES_EXPECTED) {
4690 FlattenString(str); // Flatten the string for efficiency.
4691 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004692 const int string_length = str->length();
4693 bool write_null = !(options & NO_NULL_TERMINATION);
4694 // First check if we can just write the string without checking capacity.
4695 if (capacity == -1 || capacity / 3 >= string_length) {
4696 Utf8WriterVisitor writer(buffer, capacity, true);
4697 const int kMaxRecursion = 100;
4698 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
4699 if (success) return writer.CompleteWrite(write_null, nchars_ref);
4700 } else if (capacity >= string_length) {
4701 // First check that the buffer is large enough.
4702 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
4703 if (utf8_bytes <= capacity) {
4704 // ASCII fast path.
4705 if (utf8_bytes == string_length) {
4706 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
4707 if (nchars_ref != NULL) *nchars_ref = string_length;
4708 if (write_null && (utf8_bytes+1 <= capacity)) {
4709 return string_length + 1;
4710 }
4711 return string_length;
4712 }
4713 if (write_null && (utf8_bytes+1 > capacity)) {
4714 options |= NO_NULL_TERMINATION;
4715 }
4716 // Recurse once without a capacity limit.
4717 // This will get into the first branch above.
4718 // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
4719 return WriteUtf8(buffer, -1, nchars_ref, options);
danno@chromium.org88aa0582012-03-23 15:11:57 +00004720 }
4721 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004722 // Recursive slow path can potentially be unreasonable slow. Flatten.
4723 str = FlattenGetString(str);
4724 Utf8WriterVisitor writer(buffer, capacity, false);
4725 i::String::VisitFlat(&writer, *str);
4726 return writer.CompleteWrite(write_null, nchars_ref);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00004727}
4728
4729
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004730template<typename CharType>
4731static inline int WriteHelper(const String* string,
4732 CharType* buffer,
4733 int start,
4734 int length,
4735 int options) {
4736 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004737 LOG_API(isolate, "String::Write");
4738 ENTER_V8(isolate);
4739 ASSERT(start >= 0 && length >= -1);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004740 i::Handle<i::String> str = Utils::OpenHandle(string);
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004741 isolate->string_tracker()->RecordWrite(str);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004742 if (options & String::HINT_MANY_WRITES_EXPECTED) {
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004743 // Flatten the string for efficiency. This applies whether we are
4744 // using StringCharacterStream or Get(i) to access the characters.
4745 FlattenString(str);
4746 }
4747 int end = start + length;
4748 if ((length == -1) || (length > str->length() - start) )
4749 end = str->length();
4750 if (end < 0) return 0;
4751 i::String::WriteToFlat(*str, buffer, start, end);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004752 if (!(options & String::NO_NULL_TERMINATION) &&
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004753 (length == -1 || end - start < length)) {
4754 buffer[end - start] = '\0';
4755 }
4756 return end - start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004757}
4758
4759
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004760int String::WriteOneByte(uint8_t* buffer,
4761 int start,
4762 int length,
4763 int options) const {
4764 return WriteHelper(this, buffer, start, length, options);
4765}
4766
4767
4768int String::Write(uint16_t* buffer,
4769 int start,
4770 int length,
4771 int options) const {
4772 return WriteHelper(this, buffer, start, length, options);
4773}
4774
4775
ager@chromium.org32912102009-01-16 10:38:43 +00004776bool v8::String::IsExternal() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004777 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004778 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004779 return i::StringShape(*str).IsExternalTwoByte();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004780}
4781
4782
ager@chromium.org32912102009-01-16 10:38:43 +00004783bool v8::String::IsExternalAscii() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004784 i::Handle<i::String> str = Utils::OpenHandle(this);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004785 return i::StringShape(*str).IsExternalAscii();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004786}
4787
4788
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004789void v8::String::VerifyExternalStringResource(
4790 v8::String::ExternalStringResource* value) const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004791 i::Handle<i::String> str = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004792 const v8::String::ExternalStringResource* expected;
ager@chromium.org9085a012009-05-11 19:22:57 +00004793 if (i::StringShape(*str).IsExternalTwoByte()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004794 const void* resource =
4795 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4796 expected = reinterpret_cast<const ExternalStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004797 } else {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004798 expected = NULL;
ager@chromium.org9085a012009-05-11 19:22:57 +00004799 }
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004800 CHECK_EQ(expected, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004801}
4802
ulan@chromium.org56c14af2012-09-20 12:51:09 +00004803void v8::String::VerifyExternalStringResourceBase(
4804 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
4805 i::Handle<i::String> str = Utils::OpenHandle(this);
4806 const v8::String::ExternalStringResourceBase* expected;
4807 Encoding expectedEncoding;
4808 if (i::StringShape(*str).IsExternalAscii()) {
4809 const void* resource =
4810 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
4811 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4812 expectedEncoding = ASCII_ENCODING;
4813 } else if (i::StringShape(*str).IsExternalTwoByte()) {
4814 const void* resource =
4815 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4816 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4817 expectedEncoding = TWO_BYTE_ENCODING;
4818 } else {
4819 expected = NULL;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004820 expectedEncoding = str->IsOneByteRepresentation() ? ASCII_ENCODING
ulan@chromium.org56c14af2012-09-20 12:51:09 +00004821 : TWO_BYTE_ENCODING;
4822 }
4823 CHECK_EQ(expected, value);
4824 CHECK_EQ(expectedEncoding, encoding);
4825}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004826
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004827const v8::String::ExternalAsciiStringResource*
ager@chromium.org32912102009-01-16 10:38:43 +00004828 v8::String::GetExternalAsciiStringResource() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004829 i::Handle<i::String> str = Utils::OpenHandle(this);
ager@chromium.org9085a012009-05-11 19:22:57 +00004830 if (i::StringShape(*str).IsExternalAscii()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004831 const void* resource =
4832 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
4833 return reinterpret_cast<const ExternalAsciiStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004834 } else {
4835 return NULL;
4836 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004837}
4838
4839
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004840Local<Value> Symbol::Name() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004841 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
4842 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
4843 return Utils::ToLocal(name);
4844}
4845
4846
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00004847Local<Value> Private::Name() const {
4848 return reinterpret_cast<const Symbol*>(this)->Name();
4849}
4850
4851
ager@chromium.org32912102009-01-16 10:38:43 +00004852double Number::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004853 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4854 return obj->Number();
4855}
4856
4857
ager@chromium.org32912102009-01-16 10:38:43 +00004858bool Boolean::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004859 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4860 return obj->IsTrue();
4861}
4862
4863
ager@chromium.org32912102009-01-16 10:38:43 +00004864int64_t Integer::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004865 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4866 if (obj->IsSmi()) {
4867 return i::Smi::cast(*obj)->value();
4868 } else {
4869 return static_cast<int64_t>(obj->Number());
4870 }
4871}
4872
4873
ager@chromium.org32912102009-01-16 10:38:43 +00004874int32_t Int32::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004875 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4876 if (obj->IsSmi()) {
4877 return i::Smi::cast(*obj)->value();
4878 } else {
4879 return static_cast<int32_t>(obj->Number());
4880 }
4881}
4882
4883
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004884uint32_t Uint32::Value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004885 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4886 if (obj->IsSmi()) {
4887 return i::Smi::cast(*obj)->value();
4888 } else {
4889 return static_cast<uint32_t>(obj->Number());
4890 }
4891}
4892
4893
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004894int v8::Object::InternalFieldCount() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004895 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004896 return obj->GetInternalFieldCount();
4897}
4898
4899
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004900static bool InternalFieldOK(i::Handle<i::JSObject> obj,
4901 int index,
4902 const char* location) {
machenbach@chromium.orgae161032013-09-24 09:12:30 +00004903 return ApiCheck(index < obj->GetInternalFieldCount(),
4904 location,
4905 "Internal field out of bounds");
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004906}
4907
4908
4909Local<Value> v8::Object::SlowGetInternalField(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004910 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004911 const char* location = "v8::Object::GetInternalField()";
4912 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
4913 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
4914 return Utils::ToLocal(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004915}
4916
4917
kasper.lund212ac232008-07-16 07:07:30 +00004918void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004919 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004920 const char* location = "v8::Object::SetInternalField()";
4921 if (!InternalFieldOK(obj, index, location)) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004922 i::Handle<i::Object> val = Utils::OpenHandle(*value);
4923 obj->SetInternalField(index, *val);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004924 ASSERT_EQ(value, GetInternalField(index));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004925}
4926
4927
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004928void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
4929 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4930 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
4931 if (!InternalFieldOK(obj, index, location)) return NULL;
4932 return DecodeSmiToAligned(obj->GetInternalField(index), location);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004933}
4934
4935
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004936void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
4937 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4938 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
4939 if (!InternalFieldOK(obj, index, location)) return;
4940 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
4941 ASSERT_EQ(value, GetAlignedPointerFromInternalField(index));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004942}
4943
4944
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004945static void* ExternalValue(i::Object* obj) {
4946 // Obscure semantics for undefined, but somehow checked in our unit tests...
4947 if (obj->IsUndefined()) return NULL;
4948 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
4949 return i::Foreign::cast(foreign)->foreign_address();
4950}
4951
4952
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004953// --- E n v i r o n m e n t ---
4954
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004955
machenbach@chromium.org90dca012013-11-22 10:04:21 +00004956void v8::V8::InitializePlatform(Platform* platform) {
4957#ifdef V8_USE_DEFAULT_PLATFORM
4958 FATAL("Can't override v8::Platform when using default implementation");
4959#else
4960 i::V8::InitializePlatform(platform);
4961#endif
4962}
4963
4964
4965void v8::V8::ShutdownPlatform() {
4966#ifdef V8_USE_DEFAULT_PLATFORM
4967 FATAL("Can't override v8::Platform when using default implementation");
4968#else
4969 i::V8::ShutdownPlatform();
4970#endif
4971}
4972
4973
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004974bool v8::V8::Initialize() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00004975 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004976 if (isolate != NULL && isolate->IsInitialized()) {
4977 return true;
4978 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004979 return InitializeHelper(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004980}
4981
4982
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00004983void v8::V8::SetEntropySource(EntropySource entropy_source) {
4984 i::RandomNumberGenerator::SetEntropySource(entropy_source);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00004985}
4986
4987
ulan@chromium.org967e2702012-02-28 09:49:15 +00004988void v8::V8::SetReturnAddressLocationResolver(
4989 ReturnAddressLocationResolver return_address_resolver) {
4990 i::V8::SetReturnAddressLocationResolver(return_address_resolver);
4991}
4992
4993
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004994bool v8::V8::SetFunctionEntryHook(Isolate* ext_isolate,
4995 FunctionEntryHook entry_hook) {
4996 ASSERT(ext_isolate != NULL);
4997 ASSERT(entry_hook != NULL);
4998
4999 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(ext_isolate);
5000
5001 // The entry hook can only be set before the Isolate is initialized, as
5002 // otherwise the Isolate's code stubs generated at initialization won't
5003 // contain entry hooks.
5004 if (isolate->IsInitialized())
5005 return false;
5006
5007 // Setting an entry hook is a one-way operation, once set, it cannot be
5008 // changed or unset.
5009 if (isolate->function_entry_hook() != NULL)
5010 return false;
5011
5012 isolate->set_function_entry_hook(entry_hook);
5013 return true;
verwaest@chromium.org753aee42012-07-17 16:15:42 +00005014}
5015
5016
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00005017void v8::V8::SetJitCodeEventHandler(
5018 JitCodeEventOptions options, JitCodeEventHandler event_handler) {
5019 i::Isolate* isolate = i::Isolate::Current();
5020 // Ensure that logging is initialized for our isolate.
5021 isolate->InitializeLoggingAndCounters();
5022 isolate->logger()->SetCodeEventHandler(options, event_handler);
5023}
5024
ulan@chromium.org837a67e2013-06-11 15:39:48 +00005025void v8::V8::SetArrayBufferAllocator(
5026 ArrayBuffer::Allocator* allocator) {
5027 if (!ApiCheck(i::V8::ArrayBufferAllocator() == NULL,
5028 "v8::V8::SetArrayBufferAllocator",
5029 "ArrayBufferAllocator might only be set once"))
5030 return;
5031 i::V8::SetArrayBufferAllocator(allocator);
5032}
5033
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00005034
ager@chromium.org41826e72009-03-30 13:30:57 +00005035bool v8::V8::Dispose() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005036 i::Isolate* isolate = i::Isolate::Current();
5037 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
5038 "v8::V8::Dispose()",
5039 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
5040 return false;
5041 }
ager@chromium.org41826e72009-03-30 13:30:57 +00005042 i::V8::TearDown();
5043 return true;
5044}
5045
5046
ager@chromium.org01fe7df2010-11-10 11:59:11 +00005047HeapStatistics::HeapStatistics(): total_heap_size_(0),
5048 total_heap_size_executable_(0),
danno@chromium.org72204d52012-10-31 10:02:10 +00005049 total_physical_size_(0),
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005050 used_heap_size_(0),
5051 heap_size_limit_(0) { }
ager@chromium.org3811b432009-10-28 14:53:37 +00005052
5053
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005054void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
5055 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005056 isolate->heap()->VisitExternalResources(visitor);
5057}
5058
5059
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005060class VisitorAdapter : public i::ObjectVisitor {
5061 public:
5062 explicit VisitorAdapter(PersistentHandleVisitor* visitor)
5063 : visitor_(visitor) {}
5064 virtual void VisitPointers(i::Object** start, i::Object** end) {
5065 UNREACHABLE();
5066 }
5067 virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00005068 Value* value = ToApi<Value>(i::Handle<i::Object>(p));
5069 visitor_->VisitPersistentHandle(
5070 reinterpret_cast<Persistent<Value>*>(&value), class_id);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005071 }
5072 private:
5073 PersistentHandleVisitor* visitor_;
5074};
5075
5076
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005077void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
5078 i::Isolate* isolate = i::Isolate::Current();
rossberg@chromium.org79e79022013-06-03 15:43:46 +00005079 i::DisallowHeapAllocation no_allocation;
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005080
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005081 VisitorAdapter visitor_adapter(visitor);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005082 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
5083}
5084
5085
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005086void v8::V8::VisitHandlesForPartialDependence(
5087 Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
5088 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
5089 ASSERT(isolate == i::Isolate::Current());
rossberg@chromium.org79e79022013-06-03 15:43:46 +00005090 i::DisallowHeapAllocation no_allocation;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005091
5092 VisitorAdapter visitor_adapter(visitor);
5093 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
5094 &visitor_adapter);
5095}
5096
5097
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00005098bool v8::V8::IdleNotification(int hint) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00005099 // Returning true tells the caller that it need not
5100 // continue to call IdleNotification.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005101 i::Isolate* isolate = i::Isolate::Current();
5102 if (isolate == NULL || !isolate->IsInitialized()) return true;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00005103 if (!i::FLAG_use_idle_notification) return true;
5104 return isolate->heap()->IdleNotification(hint);
ager@chromium.orgadd848f2009-08-13 12:44:13 +00005105}
5106
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005107
5108void v8::V8::LowMemoryNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005109 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005110 if (isolate == NULL || !isolate->IsInitialized()) return;
rossberg@chromium.org994edf62012-02-06 10:12:55 +00005111 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005112}
5113
5114
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00005115int v8::V8::ContextDisposedNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005116 i::Isolate* isolate = i::Isolate::Current();
5117 if (!isolate->IsInitialized()) return 0;
5118 return isolate->heap()->NotifyContextDisposed();
kasperl@chromium.org8b2bb262010-03-01 09:46:28 +00005119}
5120
5121
danno@chromium.org169691d2013-07-15 08:01:13 +00005122bool v8::V8::InitializeICU() {
5123 return i::InitializeICU();
5124}
5125
5126
kasper.lund7276f142008-07-30 08:49:36 +00005127const char* v8::V8::GetVersion() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005128 return i::Version::GetVersion();
kasper.lund7276f142008-07-30 08:49:36 +00005129}
5130
5131
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005132static i::Handle<i::Context> CreateEnvironment(
5133 i::Isolate* isolate,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005134 v8::ExtensionConfiguration* extensions,
5135 v8::Handle<ObjectTemplate> global_template,
5136 v8::Handle<Value> global_object) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005137 i::Handle<i::Context> env;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005138
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005139 // Enter V8 via an ENTER_V8 scope.
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005140 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005141 ENTER_V8(isolate);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005142 v8::Handle<ObjectTemplate> proxy_template = global_template;
5143 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5144 i::Handle<i::FunctionTemplateInfo> global_constructor;
ager@chromium.org8bb60582008-12-11 12:02:20 +00005145
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005146 if (!global_template.IsEmpty()) {
5147 // Make sure that the global_template has a constructor.
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00005148 global_constructor = EnsureConstructor(isolate, *global_template);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005149
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005150 // Create a fresh template for the global proxy object.
5151 proxy_template = ObjectTemplate::New();
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00005152 proxy_constructor = EnsureConstructor(isolate, *proxy_template);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005153
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005154 // Set the global template to be the prototype template of
5155 // global proxy template.
5156 proxy_constructor->set_prototype_template(
5157 *Utils::OpenHandle(*global_template));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005158
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005159 // Migrate security handlers from global_template to
5160 // proxy_template. Temporarily removing access check
5161 // information from the global template.
5162 if (!global_constructor->access_check_info()->IsUndefined()) {
5163 proxy_constructor->set_access_check_info(
5164 global_constructor->access_check_info());
5165 proxy_constructor->set_needs_access_check(
5166 global_constructor->needs_access_check());
5167 global_constructor->set_needs_access_check(false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005168 global_constructor->set_access_check_info(
5169 isolate->heap()->undefined_value());
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005170 }
5171 }
5172
5173 // Create the environment.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005174 env = isolate->bootstrapper()->CreateEnvironment(
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00005175 Utils::OpenHandle(*global_object, true),
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005176 proxy_template,
5177 extensions);
5178
5179 // Restore the access check info on the global template.
5180 if (!global_template.IsEmpty()) {
5181 ASSERT(!global_constructor.is_null());
5182 ASSERT(!proxy_constructor.is_null());
5183 global_constructor->set_access_check_info(
5184 proxy_constructor->access_check_info());
5185 global_constructor->set_needs_access_check(
5186 proxy_constructor->needs_access_check());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005187 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005188 }
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005189 // Leave V8.
ager@chromium.org8bb60582008-12-11 12:02:20 +00005190
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005191 return env;
5192}
5193
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005194Local<Context> v8::Context::New(
5195 v8::Isolate* external_isolate,
5196 v8::ExtensionConfiguration* extensions,
5197 v8::Handle<ObjectTemplate> global_template,
5198 v8::Handle<Value> global_object) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005199 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5200 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
5201 LOG_API(isolate, "Context::New");
5202 ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
5203 i::HandleScope scope(isolate);
5204 i::Handle<i::Context> env =
5205 CreateEnvironment(isolate, extensions, global_template, global_object);
5206 if (env.is_null()) return Local<Context>();
5207 return Utils::ToLocal(scope.CloseAndEscape(env));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005208}
5209
5210
5211void v8::Context::SetSecurityToken(Handle<Value> token) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005212 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005213 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005214 i::Handle<i::Context> env = Utils::OpenHandle(this);
5215 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005216 env->set_security_token(*token_handle);
5217}
5218
5219
5220void v8::Context::UseDefaultSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005221 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005222 ENTER_V8(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005223 i::Handle<i::Context> env = Utils::OpenHandle(this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005224 env->set_security_token(env->global_object());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005225}
5226
5227
5228Handle<Value> v8::Context::GetSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005229 i::Isolate* isolate = i::Isolate::Current();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005230 i::Handle<i::Context> env = Utils::OpenHandle(this);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005231 i::Object* security_token = env->security_token();
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005232 i::Handle<i::Object> token_handle(security_token, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005233 return Utils::ToLocal(token_handle);
5234}
5235
5236
5237bool Context::HasOutOfMemoryException() {
5238 i::Handle<i::Context> env = Utils::OpenHandle(this);
5239 return env->has_out_of_memory();
5240}
5241
5242
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005243v8::Isolate* Context::GetIsolate() {
5244 i::Handle<i::Context> env = Utils::OpenHandle(this);
5245 return reinterpret_cast<Isolate*>(env->GetIsolate());
5246}
5247
5248
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005249v8::Local<v8::Object> Context::Global() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005250 i::Handle<i::Context> context = Utils::OpenHandle(this);
5251 i::Isolate* isolate = context->GetIsolate();
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005252 i::Handle<i::Object> global(context->global_proxy(), isolate);
jkummerow@chromium.org113035e2013-12-13 15:13:40 +00005253 // TODO(dcarney): This should always return the global proxy
5254 // but can't presently as calls to GetProtoype will return the wrong result.
5255 if (i::Handle<i::JSGlobalProxy>::cast(
5256 global)->IsDetachedFrom(context->global_object())) {
5257 global = i::Handle<i::Object>(context->global_object(), isolate);
5258 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005259 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5260}
5261
5262
5263void Context::DetachGlobal() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005264 i::Handle<i::Context> context = Utils::OpenHandle(this);
5265 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005266 ENTER_V8(isolate);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005267 isolate->bootstrapper()->DetachGlobal(context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005268}
5269
5270
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005271void Context::AllowCodeGenerationFromStrings(bool allow) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005272 i::Handle<i::Context> context = Utils::OpenHandle(this);
5273 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005274 ENTER_V8(isolate);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005275 context->set_allow_code_gen_from_strings(
5276 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5277}
5278
5279
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00005280bool Context::IsCodeGenerationFromStringsAllowed() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005281 i::Handle<i::Context> context = Utils::OpenHandle(this);
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00005282 return !context->allow_code_gen_from_strings()->IsFalse();
5283}
5284
5285
ulan@chromium.org56c14af2012-09-20 12:51:09 +00005286void Context::SetErrorMessageForCodeGenerationFromStrings(
5287 Handle<String> error) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005288 i::Handle<i::Context> context = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005289 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00005290 context->set_error_message_for_code_gen_from_strings(*error_handle);
5291}
5292
5293
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005294Local<v8::Object> ObjectTemplate::NewInstance() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005295 i::Isolate* isolate = i::Isolate::Current();
5296 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
5297 return Local<v8::Object>());
5298 LOG_API(isolate, "ObjectTemplate::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005299 ENTER_V8(isolate);
5300 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005301 i::Handle<i::Object> obj =
5302 i::Execution::InstantiateObject(Utils::OpenHandle(this),
5303 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005304 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005305 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
5306}
5307
5308
5309Local<v8::Function> FunctionTemplate::GetFunction() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005310 i::Isolate* isolate = i::Isolate::Current();
5311 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005312 return Local<v8::Function>());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005313 LOG_API(isolate, "FunctionTemplate::GetFunction");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005314 ENTER_V8(isolate);
5315 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005316 i::Handle<i::Object> obj =
5317 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
5318 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005319 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005320 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
5321}
5322
5323
5324bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005325 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
5326 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005327 i::Object* obj = *Utils::OpenHandle(*value);
machenbach@chromium.org9af454f2013-11-20 09:25:57 +00005328 return Utils::OpenHandle(this)->IsTemplateFor(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005329}
5330
5331
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00005332Local<External> v8::External::New(Isolate* isolate, void* value) {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005333 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00005334 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5335 EnsureInitializedForIsolate(i_isolate, "v8::External::New()");
5336 LOG_API(i_isolate, "External::New");
5337 ENTER_V8(i_isolate);
5338 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005339 return Utils::ExternalToLocal(external);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005340}
5341
5342
5343void* External::Value() const {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005344 return ExternalValue(*Utils::OpenHandle(this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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) {
ulan@chromium.org0f13e742014-01-03 15:51:11 +00005410 return String::Empty(v8_isolate);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00005411 }
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(
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005511 Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005512 v8::String::ExternalStringResource* resource) {
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005513 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5514 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()");
5515 LOG_API(i_isolate, "String::NewExternal");
5516 ENTER_V8(i_isolate);
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005517 CHECK(resource && resource->data());
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005518 i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource);
5519 i_isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005520 return Utils::ToLocal(result);
5521}
5522
5523
ager@chromium.org6f10e412009-02-13 10:11:16 +00005524bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005525 i::Handle<i::String> obj = Utils::OpenHandle(this);
5526 i::Isolate* isolate = obj->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005527 if (i::StringShape(*obj).IsExternalTwoByte()) {
5528 return false; // Already an external string.
5529 }
5530 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005531 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5532 return false;
5533 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005534 if (isolate->heap()->IsInGCPostProcessing()) {
5535 return false;
5536 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005537 CHECK(resource && resource->data());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005538
5539 bool result;
5540 i::Handle<i::String> external;
5541 if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
5542 // We do not allow external strings in the old pointer space. Instead of
5543 // converting the string in-place, we keep the cons/sliced string and
5544 // point it to a newly-allocated external string.
5545 external = NewExternalStringHandle(isolate, resource);
5546 result = RedirectToExternalString(isolate, obj, external);
5547 } else {
5548 result = obj->MakeExternal(resource);
5549 external = obj;
5550 }
5551
jkummerow@chromium.org113035e2013-12-13 15:13:40 +00005552 if (result) {
5553 ASSERT(external->IsExternalString());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005554 isolate->heap()->external_string_table()->AddString(*external);
ager@chromium.org6f10e412009-02-13 10:11:16 +00005555 }
5556 return result;
5557}
5558
5559
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005560Local<String> v8::String::NewExternal(
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005561 Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005562 v8::String::ExternalAsciiStringResource* resource) {
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005563 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5564 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()");
5565 LOG_API(i_isolate, "String::NewExternal");
5566 ENTER_V8(i_isolate);
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005567 CHECK(resource && resource->data());
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005568 i::Handle<i::String> result =
5569 NewExternalAsciiStringHandle(i_isolate, resource);
5570 i_isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005571 return Utils::ToLocal(result);
5572}
5573
5574
ager@chromium.org6f10e412009-02-13 10:11:16 +00005575bool v8::String::MakeExternal(
5576 v8::String::ExternalAsciiStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005577 i::Handle<i::String> obj = Utils::OpenHandle(this);
5578 i::Isolate* isolate = obj->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005579 if (i::StringShape(*obj).IsExternalTwoByte()) {
5580 return false; // Already an external string.
5581 }
5582 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005583 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5584 return false;
5585 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005586 if (isolate->heap()->IsInGCPostProcessing()) {
5587 return false;
5588 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005589 CHECK(resource && resource->data());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005590
5591 bool result;
5592 i::Handle<i::String> external;
5593 if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
5594 // We do not allow external strings in the old pointer space. Instead of
5595 // converting the string in-place, we keep the cons/sliced string and
5596 // point it to a newly-allocated external string.
5597 external = NewExternalAsciiStringHandle(isolate, resource);
5598 result = RedirectToExternalString(isolate, obj, external);
5599 } else {
5600 result = obj->MakeExternal(resource);
5601 external = obj;
5602 }
5603
jkummerow@chromium.org113035e2013-12-13 15:13:40 +00005604 if (result) {
5605 ASSERT(external->IsExternalString());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005606 isolate->heap()->external_string_table()->AddString(*external);
ager@chromium.org6f10e412009-02-13 10:11:16 +00005607 }
5608 return result;
5609}
5610
5611
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005612bool v8::String::CanMakeExternal() {
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00005613 if (!internal::FLAG_clever_optimizations) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005614 i::Handle<i::String> obj = Utils::OpenHandle(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005615 i::Isolate* isolate = obj->GetIsolate();
jkummerow@chromium.org32aa03c2013-10-01 08:21:50 +00005616
5617 // TODO(yangguo): Externalizing sliced/cons strings allocates.
5618 // This rule can be removed when all code that can
5619 // trigger an access check is handlified and therefore GC safe.
5620 if (isolate->heap()->old_pointer_space()->Contains(*obj)) return false;
5621
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005622 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005623 int size = obj->Size(); // Byte size of the original string.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005624 if (size < i::ExternalString::kShortSize) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005625 i::StringShape shape(*obj);
5626 return !shape.IsExternal();
5627}
5628
5629
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005630Local<v8::Object> v8::Object::New(Isolate* isolate) {
5631 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5632 EnsureInitializedForIsolate(i_isolate, "v8::Object::New()");
5633 LOG_API(i_isolate, "Object::New");
5634 ENTER_V8(i_isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005635 i::Handle<i::JSObject> obj =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005636 i_isolate->factory()->NewJSObject(i_isolate->object_function());
5637 return Utils::ToLocal(obj);
5638}
5639
5640
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005641Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
5642 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5643 EnsureInitializedForIsolate(i_isolate, "v8::NumberObject::New()");
5644 LOG_API(i_isolate, "NumberObject::New");
5645 ENTER_V8(i_isolate);
5646 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
5647 i::Handle<i::Object> obj = i_isolate->factory()->ToObject(number);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005648 return Utils::ToLocal(obj);
5649}
5650
5651
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005652double v8::NumberObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005653 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005654 LOG_API(isolate, "NumberObject::NumberValue");
5655 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5656 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5657 return jsvalue->value()->Number();
5658}
5659
5660
5661Local<v8::Value> v8::BooleanObject::New(bool value) {
5662 i::Isolate* isolate = i::Isolate::Current();
5663 EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
5664 LOG_API(isolate, "BooleanObject::New");
5665 ENTER_V8(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005666 i::Handle<i::Object> boolean(value
5667 ? isolate->heap()->true_value()
5668 : isolate->heap()->false_value(),
5669 isolate);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005670 i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
5671 return Utils::ToLocal(obj);
5672}
5673
5674
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005675bool v8::BooleanObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005676 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005677 LOG_API(isolate, "BooleanObject::BooleanValue");
5678 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5679 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5680 return jsvalue->value()->IsTrue();
5681}
5682
5683
5684Local<v8::Value> v8::StringObject::New(Handle<String> value) {
5685 i::Isolate* isolate = i::Isolate::Current();
5686 EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
5687 LOG_API(isolate, "StringObject::New");
5688 ENTER_V8(isolate);
5689 i::Handle<i::Object> obj =
5690 isolate->factory()->ToObject(Utils::OpenHandle(*value));
5691 return Utils::ToLocal(obj);
5692}
5693
5694
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005695Local<v8::String> v8::StringObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005696 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005697 LOG_API(isolate, "StringObject::StringValue");
5698 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5699 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5700 return Utils::ToLocal(
5701 i::Handle<i::String>(i::String::cast(jsvalue->value())));
5702}
5703
5704
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005705Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
5706 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5707 EnsureInitializedForIsolate(i_isolate, "v8::SymbolObject::New()");
5708 LOG_API(i_isolate, "SymbolObject::New");
5709 ENTER_V8(i_isolate);
5710 i::Handle<i::Object> obj =
5711 i_isolate->factory()->ToObject(Utils::OpenHandle(*value));
5712 return Utils::ToLocal(obj);
5713}
5714
5715
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005716Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005717 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005718 LOG_API(isolate, "SymbolObject::SymbolValue");
5719 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5720 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5721 return Utils::ToLocal(
5722 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
5723}
5724
5725
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005726Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
5727 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5728 EnsureInitializedForIsolate(i_isolate, "v8::Date::New()");
5729 LOG_API(i_isolate, "Date::New");
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00005730 if (std::isnan(time)) {
ager@chromium.org3811b432009-10-28 14:53:37 +00005731 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5732 time = i::OS::nan_value();
5733 }
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005734 ENTER_V8(i_isolate);
5735 EXCEPTION_PREAMBLE(i_isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005736 i::Handle<i::Object> obj =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005737 i::Execution::NewDate(i_isolate, time, &has_pending_exception);
5738 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005739 return Utils::ToLocal(obj);
5740}
5741
5742
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005743double v8::Date::ValueOf() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005744 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005745 LOG_API(isolate, "Date::NumberValue");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005746 i::Handle<i::Object> obj = Utils::OpenHandle(this);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005747 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
5748 return jsdate->value()->Number();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005749}
5750
5751
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005752void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
5753 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5754 ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005755 return);
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005756 LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
5757 ENTER_V8(i_isolate);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005758
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005759 i_isolate->date_cache()->ResetDateCache();
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005760
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005761 i::HandleScope scope(i_isolate);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005762 // Get the function ResetDateCache (defined in date.js).
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005763 i::Handle<i::String> func_name_str =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005764 i_isolate->factory()->InternalizeOneByteString(
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005765 STATIC_ASCII_VECTOR("ResetDateCache"));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005766 i::MaybeObject* result =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005767 i_isolate->js_builtins_object()->GetProperty(*func_name_str);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005768 i::Object* object_func;
5769 if (!result->ToObject(&object_func)) {
5770 return;
5771 }
5772
5773 if (object_func->IsJSFunction()) {
5774 i::Handle<i::JSFunction> func =
5775 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
5776
5777 // Call ResetDateCache(0 but expect no exceptions:
5778 bool caught_exception = false;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005779 i::Execution::TryCall(func,
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005780 i_isolate->js_builtins_object(),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005781 0,
5782 NULL,
5783 &caught_exception);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005784 }
5785}
5786
5787
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005788static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00005789 i::Isolate* isolate = i::Isolate::Current();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00005790 uint8_t flags_buf[3];
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005791 int num_flags = 0;
5792 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
5793 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
5794 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
5795 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00005796 return isolate->factory()->InternalizeOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00005797 i::Vector<const uint8_t>(flags_buf, num_flags));
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005798}
5799
5800
5801Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
5802 Flags flags) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005803 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005804 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
5805 LOG_API(isolate, "RegExp::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005806 ENTER_V8(isolate);
5807 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005808 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
5809 Utils::OpenHandle(*pattern),
5810 RegExpFlagsToString(flags),
5811 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005812 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005813 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
5814}
5815
5816
5817Local<v8::String> v8::RegExp::GetSource() const {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005818 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5819 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
5820}
5821
5822
5823// Assert that the static flags cast in GetFlags is valid.
5824#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
5825 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
5826 static_cast<int>(i::JSRegExp::internal_flag))
5827REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
5828REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
5829REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
5830REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
5831#undef REGEXP_FLAG_ASSERT_EQ
5832
5833v8::RegExp::Flags v8::RegExp::GetFlags() const {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005834 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5835 return static_cast<RegExp::Flags>(obj->GetFlags().value());
5836}
5837
5838
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005839Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
5840 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5841 EnsureInitializedForIsolate(i_isolate, "v8::Array::New()");
5842 LOG_API(i_isolate, "Array::New");
5843 ENTER_V8(i_isolate);
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00005844 int real_length = length > 0 ? length : 0;
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005845 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005846 i::Handle<i::Object> length_obj =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005847 i_isolate->factory()->NewNumberFromInt(real_length);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005848 obj->set_length(*length_obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005849 return Utils::ToLocal(obj);
5850}
5851
5852
ager@chromium.org32912102009-01-16 10:38:43 +00005853uint32_t v8::Array::Length() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005854 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
5855 i::Object* length = obj->length();
5856 if (length->IsSmi()) {
5857 return i::Smi::cast(length)->value();
5858 } else {
5859 return static_cast<uint32_t>(length->Number());
5860 }
5861}
5862
5863
ager@chromium.org3e875802009-06-29 08:26:34 +00005864Local<Object> Array::CloneElementAt(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005865 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005866 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005867 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005868 if (!self->HasFastObjectElements()) {
ager@chromium.org3e875802009-06-29 08:26:34 +00005869 return Local<Object>();
5870 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005871 i::FixedArray* elms = i::FixedArray::cast(self->elements());
ager@chromium.org3e875802009-06-29 08:26:34 +00005872 i::Object* paragon = elms->get(index);
5873 if (!paragon->IsJSObject()) {
5874 return Local<Object>();
5875 }
5876 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005877 EXCEPTION_PREAMBLE(isolate);
5878 ENTER_V8(isolate);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005879 i::Handle<i::JSObject> result = i::JSObject::Copy(paragon_handle);
ager@chromium.org3e875802009-06-29 08:26:34 +00005880 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005881 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005882 return Utils::ToLocal(result);
5883}
5884
5885
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005886bool v8::ArrayBuffer::IsExternal() const {
5887 return Utils::OpenHandle(this)->is_external();
5888}
5889
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00005890
ulan@chromium.org837a67e2013-06-11 15:39:48 +00005891v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005892 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5893 ApiCheck(!obj->is_external(),
5894 "v8::ArrayBuffer::Externalize",
5895 "ArrayBuffer already externalized");
5896 obj->set_is_external(true);
5897 size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
ulan@chromium.org837a67e2013-06-11 15:39:48 +00005898 Contents contents;
5899 contents.data_ = obj->backing_store();
5900 contents.byte_length_ = byte_length;
5901 return contents;
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005902}
5903
5904
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005905void v8::ArrayBuffer::Neuter() {
5906 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5907 i::Isolate* isolate = obj->GetIsolate();
5908 ApiCheck(obj->is_external(),
5909 "v8::ArrayBuffer::Neuter",
5910 "Only externalized ArrayBuffers can be neutered");
5911 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
5912 ENTER_V8(isolate);
5913
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005914 for (i::Handle<i::Object> view_obj(obj->weak_first_view(), isolate);
5915 !view_obj->IsUndefined();) {
5916 i::Handle<i::JSArrayBufferView> view(i::JSArrayBufferView::cast(*view_obj));
5917 if (view->IsJSTypedArray()) {
5918 i::JSTypedArray::cast(*view)->Neuter();
5919 } else if (view->IsJSDataView()) {
5920 i::JSDataView::cast(*view)->Neuter();
5921 } else {
5922 UNREACHABLE();
5923 }
5924 view_obj = i::handle(view->weak_next(), isolate);
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005925 }
5926 obj->Neuter();
5927}
5928
5929
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005930size_t v8::ArrayBuffer::ByteLength() const {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005931 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5932 return static_cast<size_t>(obj->byte_length()->Number());
5933}
5934
5935
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005936Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
5937 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5938 EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(size_t)");
5939 LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
5940 ENTER_V8(i_isolate);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005941 i::Handle<i::JSArrayBuffer> obj =
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005942 i_isolate->factory()->NewJSArrayBuffer();
5943 i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length);
5944 return Utils::ToLocal(obj);
5945}
5946
5947
machenbach@chromium.org37be4082013-11-26 13:50:38 +00005948Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
5949 size_t byte_length) {
5950 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5951 EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
5952 LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
5953 ENTER_V8(i_isolate);
5954 i::Handle<i::JSArrayBuffer> obj =
5955 i_isolate->factory()->NewJSArrayBuffer();
5956 i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005957 return Utils::ToLocal(obj);
5958}
5959
5960
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005961Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
5962 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005963 ASSERT(obj->buffer()->IsJSArrayBuffer());
5964 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(obj->buffer()));
5965 return Utils::ToLocal(buffer);
5966}
5967
5968
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005969size_t v8::ArrayBufferView::ByteOffset() {
5970 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005971 return static_cast<size_t>(obj->byte_offset()->Number());
5972}
5973
5974
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005975size_t v8::ArrayBufferView::ByteLength() {
5976 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005977 return static_cast<size_t>(obj->byte_length()->Number());
5978}
5979
5980
5981size_t v8::TypedArray::Length() {
danno@chromium.orgf005df62013-04-30 16:36:45 +00005982 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
5983 return static_cast<size_t>(obj->length()->Number());
5984}
5985
5986
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005987static inline void SetupArrayBufferView(
5988 i::Isolate* isolate,
5989 i::Handle<i::JSArrayBufferView> obj,
5990 i::Handle<i::JSArrayBuffer> buffer,
5991 size_t byte_offset,
5992 size_t byte_length) {
5993 ASSERT(byte_offset + byte_length <=
5994 static_cast<size_t>(buffer->byte_length()->Number()));
danno@chromium.orgf005df62013-04-30 16:36:45 +00005995
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005996 obj->set_buffer(*buffer);
5997
5998 obj->set_weak_next(buffer->weak_first_view());
5999 buffer->set_weak_first_view(*obj);
6000
6001 i::Handle<i::Object> byte_offset_object =
6002 isolate->factory()->NewNumberFromSize(byte_offset);
6003 obj->set_byte_offset(*byte_offset_object);
6004
6005 i::Handle<i::Object> byte_length_object =
6006 isolate->factory()->NewNumberFromSize(byte_length);
6007 obj->set_byte_length(*byte_length_object);
6008}
danno@chromium.orgf005df62013-04-30 16:36:45 +00006009
6010template<typename ElementType,
6011 ExternalArrayType array_type,
6012 i::ElementsKind elements_kind>
6013i::Handle<i::JSTypedArray> NewTypedArray(
6014 i::Isolate* isolate,
6015 Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
6016 i::Handle<i::JSTypedArray> obj =
6017 isolate->factory()->NewJSTypedArray(array_type);
6018 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6019
6020 ASSERT(byte_offset % sizeof(ElementType) == 0);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006021
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +00006022 CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
6023 size_t byte_length = length * sizeof(ElementType);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006024 SetupArrayBufferView(
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +00006025 isolate, obj, buffer, byte_offset, byte_length);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006026
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006027 i::Handle<i::Object> length_object =
6028 isolate->factory()->NewNumberFromSize(length);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006029 obj->set_length(*length_object);
6030
6031 i::Handle<i::ExternalArray> elements =
6032 isolate->factory()->NewExternalArray(
6033 static_cast<int>(length), array_type,
6034 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006035 obj->set_elements(*elements);
6036 return obj;
6037}
6038
6039
6040#define TYPED_ARRAY_NEW(TypedArray, element_type, array_type, elements_kind) \
6041 Local<TypedArray> TypedArray::New(Handle<ArrayBuffer> array_buffer, \
6042 size_t byte_offset, size_t length) { \
6043 i::Isolate* isolate = i::Isolate::Current(); \
6044 EnsureInitializedForIsolate(isolate, \
6045 "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
6046 LOG_API(isolate, \
6047 "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
6048 ENTER_V8(isolate); \
6049 i::Handle<i::JSTypedArray> obj = \
6050 NewTypedArray<element_type, array_type, elements_kind>( \
6051 isolate, array_buffer, byte_offset, length); \
6052 return Utils::ToLocal##TypedArray(obj); \
6053 }
6054
6055
6056TYPED_ARRAY_NEW(Uint8Array, uint8_t, kExternalUnsignedByteArray,
6057 i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS)
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006058TYPED_ARRAY_NEW(Uint8ClampedArray, uint8_t, kExternalPixelArray,
6059 i::EXTERNAL_PIXEL_ELEMENTS)
danno@chromium.orgf005df62013-04-30 16:36:45 +00006060TYPED_ARRAY_NEW(Int8Array, int8_t, kExternalByteArray,
6061 i::EXTERNAL_BYTE_ELEMENTS)
6062TYPED_ARRAY_NEW(Uint16Array, uint16_t, kExternalUnsignedShortArray,
6063 i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS)
6064TYPED_ARRAY_NEW(Int16Array, int16_t, kExternalShortArray,
6065 i::EXTERNAL_SHORT_ELEMENTS)
6066TYPED_ARRAY_NEW(Uint32Array, uint32_t, kExternalUnsignedIntArray,
6067 i::EXTERNAL_UNSIGNED_INT_ELEMENTS)
6068TYPED_ARRAY_NEW(Int32Array, int32_t, kExternalIntArray,
6069 i::EXTERNAL_INT_ELEMENTS)
6070TYPED_ARRAY_NEW(Float32Array, float, kExternalFloatArray,
6071 i::EXTERNAL_FLOAT_ELEMENTS)
6072TYPED_ARRAY_NEW(Float64Array, double, kExternalDoubleArray,
6073 i::EXTERNAL_DOUBLE_ELEMENTS)
6074
6075#undef TYPED_ARRAY_NEW
6076
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006077Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
6078 size_t byte_offset, size_t byte_length) {
6079 i::Isolate* isolate = i::Isolate::Current();
6080 EnsureInitializedForIsolate(
6081 isolate, "v8::DataView::New(void*, size_t, size_t)");
6082 LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
6083 ENTER_V8(isolate);
6084 i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
6085 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6086 SetupArrayBufferView(
6087 isolate, obj, buffer, byte_offset, byte_length);
6088 return Utils::ToLocal(obj);
6089}
6090
danno@chromium.orgf005df62013-04-30 16:36:45 +00006091
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00006092Local<Symbol> v8::Symbol::New(Isolate* isolate, const char* data, int length) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006093 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6094 EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()");
6095 LOG_API(i_isolate, "Symbol::New()");
6096 ENTER_V8(i_isolate);
6097 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00006098 if (data != NULL) {
6099 if (length == -1) length = i::StrLength(data);
6100 i::Handle<i::String> name = i_isolate->factory()->NewStringFromUtf8(
6101 i::Vector<const char>(data, length));
6102 result->set_name(*name);
6103 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006104 return Utils::ToLocal(result);
6105}
6106
6107
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00006108Local<Private> v8::Private::New(
6109 Isolate* isolate, const char* data, int length) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006110 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00006111 EnsureInitializedForIsolate(i_isolate, "v8::Private::New()");
6112 LOG_API(i_isolate, "Private::New()");
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006113 ENTER_V8(i_isolate);
machenbach@chromium.org0cc09502013-11-13 12:20:55 +00006114 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
6115 if (data != NULL) {
6116 if (length == -1) length = i::StrLength(data);
6117 i::Handle<i::String> name = i_isolate->factory()->NewStringFromUtf8(
6118 i::Vector<const char>(data, length));
6119 symbol->set_name(*name);
6120 }
6121 Local<Symbol> result = Utils::ToLocal(symbol);
6122 return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006123}
6124
6125
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00006126Local<Number> v8::Number::New(Isolate* isolate, double value) {
6127 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6128 ASSERT(internal_isolate->IsInitialized());
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00006129 if (std::isnan(value)) {
ager@chromium.org3811b432009-10-28 14:53:37 +00006130 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6131 value = i::OS::nan_value();
6132 }
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00006133 ENTER_V8(internal_isolate);
6134 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006135 return Utils::NumberToLocal(result);
6136}
6137
6138
machenbach@chromium.org37be4082013-11-26 13:50:38 +00006139Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006140 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6141 ASSERT(internal_isolate->IsInitialized());
6142 if (i::Smi::IsValid(value)) {
6143 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
6144 internal_isolate));
6145 }
6146 ENTER_V8(internal_isolate);
6147 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
6148 return Utils::IntegerToLocal(result);
6149}
6150
6151
machenbach@chromium.org37be4082013-11-26 13:50:38 +00006152Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006153 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6154 ASSERT(internal_isolate->IsInitialized());
ager@chromium.org3811b432009-10-28 14:53:37 +00006155 bool fits_into_int32_t = (value & (1 << 31)) == 0;
6156 if (fits_into_int32_t) {
ulan@chromium.org0f13e742014-01-03 15:51:11 +00006157 return Integer::New(isolate, static_cast<int32_t>(value));
ager@chromium.org3811b432009-10-28 14:53:37 +00006158 }
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006159 ENTER_V8(internal_isolate);
6160 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
ager@chromium.org3811b432009-10-28 14:53:37 +00006161 return Utils::IntegerToLocal(result);
6162}
6163
6164
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006165#ifdef DEBUG
rossberg@chromium.org79e79022013-06-03 15:43:46 +00006166v8::AssertNoGCScope::AssertNoGCScope(v8::Isolate* isolate) {
6167 disallow_heap_allocation_ = new i::DisallowHeapAllocation();
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006168}
6169
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006170
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006171v8::AssertNoGCScope::~AssertNoGCScope() {
rossberg@chromium.org79e79022013-06-03 15:43:46 +00006172 delete static_cast<i::DisallowHeapAllocation*>(disallow_heap_allocation_);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006173}
6174#endif
6175
6176
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006177void V8::IgnoreOutOfMemoryException() {
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00006178 EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006179}
6180
6181
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006182bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006183 i::Isolate* isolate = i::Isolate::Current();
6184 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
6185 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006186 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006187 i::HandleScope scope(isolate);
6188 NeanderArray listeners(isolate->factory()->message_listeners());
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006189 NeanderObject obj(2);
6190 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
6191 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
6192 : *Utils::OpenHandle(*data));
6193 listeners.add(obj.value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006194 return true;
6195}
6196
6197
6198void V8::RemoveMessageListeners(MessageCallback that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006199 i::Isolate* isolate = i::Isolate::Current();
6200 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
6201 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006202 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006203 i::HandleScope scope(isolate);
6204 NeanderArray listeners(isolate->factory()->message_listeners());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006205 for (int i = 0; i < listeners.length(); i++) {
6206 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
6207
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006208 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
6209 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00006210 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006211 listeners.set(i, isolate->heap()->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006212 }
6213 }
6214}
6215
6216
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00006217void V8::SetCaptureStackTraceForUncaughtExceptions(
6218 bool capture,
6219 int frame_limit,
6220 StackTrace::StackTraceOptions options) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006221 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00006222 capture,
6223 frame_limit,
6224 options);
6225}
6226
6227
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006228void V8::SetCounterFunction(CounterLookupCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006229 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006230 isolate->stats_table()->SetCounterFunction(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006231}
6232
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006233
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006234void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006235 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006236 isolate->stats_table()->SetCreateHistogramFunction(callback);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006237 isolate->InitializeLoggingAndCounters();
6238 isolate->counters()->ResetHistograms();
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006239}
6240
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006241
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006242void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006243 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006244 isolate->stats_table()->
6245 SetAddHistogramSampleFunction(callback);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006246}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006247
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006248void V8::SetFailedAccessCheckCallbackFunction(
6249 FailedAccessCheckCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006250 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006251 isolate->SetFailedAccessCheckCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006252}
6253
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00006254
machenbach@chromium.org7ff76072013-11-21 09:47:43 +00006255int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
6256 int64_t change_in_bytes) {
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00006257 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
6258 return heap->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
6259}
6260
6261
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006262HeapProfiler* Isolate::GetHeapProfiler() {
6263 i::HeapProfiler* heap_profiler =
6264 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
6265 return reinterpret_cast<HeapProfiler*>(heap_profiler);
6266}
6267
6268
6269CpuProfiler* Isolate::GetCpuProfiler() {
6270 i::CpuProfiler* cpu_profiler =
6271 reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
6272 return reinterpret_cast<CpuProfiler*>(cpu_profiler);
6273}
6274
6275
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006276bool Isolate::InContext() {
6277 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6278 return isolate->context() != NULL;
6279}
6280
6281
mvstanton@chromium.org40ce96b2013-04-09 09:52:22 +00006282v8::Local<v8::Context> Isolate::GetCurrentContext() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006283 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6284 i::Context* context = isolate->context();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006285 if (context == NULL) return Local<Context>();
6286 i::Context* native_context = context->global_object()->native_context();
6287 if (native_context == NULL) return Local<Context>();
6288 return Utils::ToLocal(i::Handle<i::Context>(native_context));
mvstanton@chromium.org40ce96b2013-04-09 09:52:22 +00006289}
6290
6291
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006292v8::Local<v8::Context> Isolate::GetCallingContext() {
6293 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6294 i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
6295 if (calling.is_null()) return Local<Context>();
6296 return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
6297}
6298
6299
6300v8::Local<v8::Context> Isolate::GetEnteredContext() {
6301 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6302 i::Handle<i::Object> last =
6303 isolate->handle_scope_implementer()->LastEnteredContext();
6304 if (last.is_null()) return Local<Context>();
6305 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
6306}
6307
6308
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00006309v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
6310 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6311 ENTER_V8(isolate);
6312 // If we're passed an empty handle, we throw an undefined exception
6313 // to deal more gracefully with out of memory situations.
6314 if (value.IsEmpty()) {
6315 isolate->ScheduleThrow(isolate->heap()->undefined_value());
6316 } else {
6317 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
6318 }
6319 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6320}
6321
6322
mstarzinger@chromium.org69008382013-10-18 10:34:25 +00006323void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006324 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6325 internal_isolate->global_handles()->SetObjectGroupId(
mstarzinger@chromium.org69008382013-10-18 10:34:25 +00006326 v8::internal::Handle<v8::internal::Object>(object).location(),
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006327 id);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006328}
6329
6330
mstarzinger@chromium.org69008382013-10-18 10:34:25 +00006331void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006332 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006333 internal_isolate->global_handles()->SetReferenceFromGroup(
6334 id,
mstarzinger@chromium.org69008382013-10-18 10:34:25 +00006335 v8::internal::Handle<v8::internal::Object>(object).location());
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006336}
6337
6338
mstarzinger@chromium.org69008382013-10-18 10:34:25 +00006339void Isolate::SetReference(internal::Object** parent,
6340 internal::Object** child) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006341 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
mstarzinger@chromium.org69008382013-10-18 10:34:25 +00006342 i::Object** parent_location =
6343 v8::internal::Handle<v8::internal::Object>(parent).location();
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006344 internal_isolate->global_handles()->SetReference(
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006345 reinterpret_cast<i::HeapObject**>(parent_location),
mstarzinger@chromium.org69008382013-10-18 10:34:25 +00006346 v8::internal::Handle<v8::internal::Object>(child).location());
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006347}
6348
6349
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006350void Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
6351 GCType gc_type) {
6352 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6353 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006354}
6355
6356
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006357void Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
6358 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6359 isolate->heap()->RemoveGCPrologueCallback(callback);
6360}
6361
6362
6363void Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
6364 GCType gc_type) {
6365 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6366 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
6367}
6368
6369
6370void Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
6371 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6372 isolate->heap()->RemoveGCEpilogueCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006373}
6374
6375
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006376void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006377 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006378 isolate->heap()->AddGCPrologueCallback(
6379 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
6380 gc_type,
6381 false);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006382}
6383
6384
6385void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006386 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006387 isolate->heap()->RemoveGCPrologueCallback(
6388 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006389}
6390
6391
6392void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006393 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006394 isolate->heap()->AddGCEpilogueCallback(
6395 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
6396 gc_type,
6397 false);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006398}
6399
6400
6401void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006402 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006403 isolate->heap()->RemoveGCEpilogueCallback(
6404 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006405}
6406
6407
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006408void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
6409 ObjectSpace space,
6410 AllocationAction action) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006411 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006412 isolate->memory_allocator()->AddMemoryAllocationCallback(
6413 callback, space, action);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006414}
6415
6416
6417void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006418 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006419 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
6420 callback);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006421}
6422
6423
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006424void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
6425 if (callback == NULL) return;
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006426 i::V8::AddCallCompletedCallback(callback);
6427}
6428
6429
6430void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006431 i::V8::RemoveCallCompletedCallback(callback);
6432}
6433
6434
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006435void V8::TerminateExecution(Isolate* isolate) {
6436 // If no isolate is supplied, use the default isolate.
6437 if (isolate != NULL) {
6438 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
6439 } else {
6440 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
6441 }
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00006442}
6443
6444
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00006445bool V8::IsExecutionTerminating(Isolate* isolate) {
6446 i::Isolate* i_isolate = isolate != NULL ?
6447 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
6448 return IsExecutionTerminatingCheck(i_isolate);
sgjesse@chromium.org2ab99522010-03-10 09:03:43 +00006449}
6450
6451
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006452void V8::CancelTerminateExecution(Isolate* isolate) {
6453 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6454 i_isolate->stack_guard()->CancelTerminateExecution();
6455}
6456
6457
hpayer@chromium.orgea9b8ba2013-12-20 19:22:39 +00006458void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
6459 reinterpret_cast<i::Isolate*>(this)->stack_guard()->RequestInterrupt(
6460 callback, data);
6461}
6462
6463
6464void Isolate::ClearInterrupt() {
6465 reinterpret_cast<i::Isolate*>(this)->stack_guard()->ClearInterrupt();
6466}
6467
6468
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006469Isolate* Isolate::GetCurrent() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00006470 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006471 return reinterpret_cast<Isolate*>(isolate);
6472}
6473
6474
6475Isolate* Isolate::New() {
6476 i::Isolate* isolate = new i::Isolate();
6477 return reinterpret_cast<Isolate*>(isolate);
6478}
6479
6480
6481void Isolate::Dispose() {
6482 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6483 if (!ApiCheck(!isolate->IsInUse(),
6484 "v8::Isolate::Dispose()",
6485 "Disposing the isolate that is entered by a thread.")) {
6486 return;
6487 }
6488 isolate->TearDown();
6489}
6490
6491
6492void Isolate::Enter() {
6493 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6494 isolate->Enter();
6495}
6496
6497
6498void Isolate::Exit() {
6499 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6500 isolate->Exit();
6501}
6502
6503
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00006504void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
6505 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006506 if (!isolate->IsInitialized()) {
6507 heap_statistics->total_heap_size_ = 0;
6508 heap_statistics->total_heap_size_executable_ = 0;
6509 heap_statistics->total_physical_size_ = 0;
6510 heap_statistics->used_heap_size_ = 0;
6511 heap_statistics->heap_size_limit_ = 0;
6512 return;
6513 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00006514 i::Heap* heap = isolate->heap();
6515 heap_statistics->total_heap_size_ = heap->CommittedMemory();
6516 heap_statistics->total_heap_size_executable_ =
6517 heap->CommittedMemoryExecutable();
6518 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
6519 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
6520 heap_statistics->heap_size_limit_ = heap->MaxReserved();
6521}
6522
6523
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006524String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
6525 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006526 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006527 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006528 ENTER_V8(isolate);
6529 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006530 TryCatch try_catch;
6531 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006532 if (str.IsEmpty()) return;
yangguo@chromium.org154ff992012-03-13 08:09:54 +00006533 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00006534 length_ = v8::Utf8Length(*i_str, isolate);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006535 str_ = i::NewArray<char>(length_ + 1);
6536 str->WriteUtf8(str_);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006537}
6538
6539
6540String::Utf8Value::~Utf8Value() {
6541 i::DeleteArray(str_);
6542}
6543
6544
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006545String::Value::Value(v8::Handle<v8::Value> obj)
6546 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006547 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006548 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006549 ENTER_V8(isolate);
6550 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006551 TryCatch try_catch;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006552 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006553 if (str.IsEmpty()) return;
6554 length_ = str->Length();
6555 str_ = i::NewArray<uint16_t>(length_ + 1);
6556 str->Write(str_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006557}
6558
6559
6560String::Value::~Value() {
6561 i::DeleteArray(str_);
6562}
6563
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006564
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006565Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006566 i::Isolate* isolate = i::Isolate::Current();
6567 LOG_API(isolate, "RangeError");
6568 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006569 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006570 i::Object* error;
6571 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006572 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006573 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006574 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006575 error = *result;
6576 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006577 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006578 return Utils::ToLocal(result);
6579}
6580
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006581
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006582Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006583 i::Isolate* isolate = i::Isolate::Current();
6584 LOG_API(isolate, "ReferenceError");
6585 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006586 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006587 i::Object* error;
6588 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006589 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006590 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006591 i::Handle<i::Object> result =
6592 isolate->factory()->NewReferenceError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006593 error = *result;
6594 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006595 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006596 return Utils::ToLocal(result);
6597}
6598
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006599
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006600Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006601 i::Isolate* isolate = i::Isolate::Current();
6602 LOG_API(isolate, "SyntaxError");
6603 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006604 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006605 i::Object* error;
6606 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006607 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006608 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006609 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006610 error = *result;
6611 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006612 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006613 return Utils::ToLocal(result);
6614}
6615
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006617Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006618 i::Isolate* isolate = i::Isolate::Current();
6619 LOG_API(isolate, "TypeError");
6620 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006621 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006622 i::Object* error;
6623 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006624 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006625 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006626 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006627 error = *result;
6628 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006629 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006630 return Utils::ToLocal(result);
6631}
6632
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006633
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006634Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006635 i::Isolate* isolate = i::Isolate::Current();
6636 LOG_API(isolate, "Error");
6637 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006638 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006639 i::Object* error;
6640 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006641 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006642 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006643 i::Handle<i::Object> result = isolate->factory()->NewError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006644 error = *result;
6645 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006646 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006647 return Utils::ToLocal(result);
6648}
6649
6650
6651// --- D e b u g S u p p o r t ---
6652
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006653#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00006654
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00006655bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006656 i::Isolate* isolate = i::Isolate::Current();
6657 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
6658 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006659 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006660 i::HandleScope scope(isolate);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006661 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
ager@chromium.org381abbb2009-02-25 13:23:22 +00006662 if (that != NULL) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006663 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
ager@chromium.org381abbb2009-02-25 13:23:22 +00006664 }
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00006665 isolate->debugger()->SetEventListener(foreign,
6666 Utils::OpenHandle(*data, true));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006667 return true;
6668}
6669
6670
iposva@chromium.org245aa852009-02-10 00:49:54 +00006671bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006672 Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006673 i::Isolate* isolate = i::Isolate::Current();
6674 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006675 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006676 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00006677 Utils::OpenHandle(*data, true));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006678 return true;
6679}
6680
6681
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006682void Debug::DebugBreak(Isolate* isolate) {
6683 // If no isolate is supplied, use the default isolate.
6684 if (isolate != NULL) {
6685 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
6686 } else {
6687 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
6688 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006689}
6690
6691
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006692void Debug::CancelDebugBreak(Isolate* isolate) {
6693 // If no isolate is supplied, use the default isolate.
6694 if (isolate != NULL) {
6695 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6696 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
6697 } else {
6698 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
6699 }
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00006700}
6701
6702
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006703void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
6704 // If no isolate is supplied, use the default isolate.
6705 if (isolate != NULL) {
6706 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6707 internal_isolate->debugger()->EnqueueDebugCommand(data);
6708 } else {
6709 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
6710 }
mikhail.naganov@gmail.com22762872010-07-14 09:29:05 +00006711}
6712
6713
ager@chromium.org5ec48922009-05-05 07:25:34 +00006714void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006715 i::Isolate* isolate = i::Isolate::Current();
6716 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
6717 ENTER_V8(isolate);
6718 isolate->debugger()->SetMessageHandler(handler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006719}
6720
6721
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006722void Debug::SendCommand(Isolate* isolate,
6723 const uint16_t* command,
6724 int length,
6725 ClientData* client_data) {
6726 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6727 internal_isolate->debugger()->ProcessCommand(
6728 i::Vector<const uint16_t>(command, length), client_data);
6729}
6730
6731
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006732void Debug::SendCommand(const uint16_t* command, int length,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006733 ClientData* client_data,
6734 Isolate* isolate) {
6735 // If no isolate is supplied, use the default isolate.
6736 if (isolate != NULL) {
6737 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6738 internal_isolate->debugger()->ProcessCommand(
6739 i::Vector<const uint16_t>(command, length), client_data);
6740 } else {
6741 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
6742 i::Vector<const uint16_t>(command, length), client_data);
6743 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006744}
6745
6746
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006747void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
6748 int period) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006749 i::Isolate* isolate = i::Isolate::Current();
6750 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
6751 ENTER_V8(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00006752 isolate->debugger()->SetHostDispatchHandler(
6753 handler, i::TimeDelta::FromMilliseconds(period));
ager@chromium.org381abbb2009-02-25 13:23:22 +00006754}
6755
6756
ager@chromium.orgc4c92722009-11-18 14:12:51 +00006757void Debug::SetDebugMessageDispatchHandler(
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006758 DebugMessageDispatchHandler handler, bool provide_locker) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006759 i::Isolate* isolate = i::Isolate::Current();
6760 EnsureInitializedForIsolate(isolate,
6761 "v8::Debug::SetDebugMessageDispatchHandler");
6762 ENTER_V8(isolate);
6763 isolate->debugger()->SetDebugMessageDispatchHandler(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006764 handler, provide_locker);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00006765}
6766
6767
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006768Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
6769 v8::Handle<v8::Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006770 i::Isolate* isolate = i::Isolate::Current();
6771 if (!isolate->IsInitialized()) return Local<Value>();
6772 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006773 ENTER_V8(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006774 i::Handle<i::Object> result;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006775 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006776 if (data.IsEmpty()) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006777 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
6778 isolate->factory()->undefined_value(),
6779 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006780 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006781 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
6782 Utils::OpenHandle(*data),
6783 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006784 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006785 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006786 return Utils::ToLocal(result);
6787}
6788
6789
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006790Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006791 i::Isolate* isolate = i::Isolate::Current();
6792 if (!isolate->IsInitialized()) return Local<Value>();
6793 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006794 ENTER_V8(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00006795 v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006796 i::Debug* isolate_debug = isolate->debug();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006797 isolate_debug->Load();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00006798 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00006799 i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00006800 STATIC_ASCII_VECTOR("MakeMirror"));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006801 i::Handle<i::Object> fun_obj = i::GetProperty(isolate, debug, name);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006802 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
6803 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
6804 const int kArgc = 1;
6805 v8::Handle<v8::Value> argv[kArgc] = { obj };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006806 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00006807 v8::Local<v8::Value> result =
6808 v8_fun->Call(Utils::ToLocal(debug), kArgc, argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006809 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00006810 return scope.Escape(result);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006811}
6812
6813
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00006814bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006815 return i::Isolate::Current()->debugger()->StartAgent(name, port,
6816 wait_for_connection);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00006817}
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006818
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006819
6820void Debug::DisableAgent() {
6821 return i::Isolate::Current()->debugger()->StopAgent();
6822}
6823
6824
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006825void Debug::ProcessDebugMessages() {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00006826 i::Execution::ProcessDebugMessages(i::Isolate::Current(), true);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006827}
6828
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00006829
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00006830Local<Context> Debug::GetDebugContext() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006831 i::Isolate* isolate = i::Isolate::Current();
6832 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
6833 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006834 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00006835}
6836
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00006837
6838void Debug::SetLiveEditEnabled(bool enable, Isolate* isolate) {
6839 // If no isolate is supplied, use the default isolate.
6840 i::Debugger* debugger;
6841 if (isolate != NULL) {
6842 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6843 debugger = internal_isolate->debugger();
6844 } else {
6845 debugger = i::Isolate::GetDefaultIsolateDebugger();
6846 }
6847 debugger->set_live_edit_enabled(enable);
6848}
6849
6850
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006851#endif // ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00006852
ager@chromium.org357bf652010-04-12 11:30:10 +00006853
ager@chromium.org357bf652010-04-12 11:30:10 +00006854Handle<String> CpuProfileNode::GetFunctionName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006855 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006856 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6857 const i::CodeEntry* entry = node->entry();
6858 if (!entry->has_name_prefix()) {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006859 return ToApiHandle<String>(
6860 isolate->factory()->InternalizeUtf8String(entry->name()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006861 } else {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006862 return ToApiHandle<String>(isolate->factory()->NewConsString(
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00006863 isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006864 isolate->factory()->InternalizeUtf8String(entry->name())));
ager@chromium.org357bf652010-04-12 11:30:10 +00006865 }
6866}
6867
6868
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00006869int CpuProfileNode::GetScriptId() const {
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00006870 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6871 const i::CodeEntry* entry = node->entry();
6872 return entry->script_id();
6873}
6874
6875
ager@chromium.org357bf652010-04-12 11:30:10 +00006876Handle<String> CpuProfileNode::GetScriptResourceName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006877 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006878 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006879 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
6880 node->entry()->resource_name()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006881}
6882
6883
6884int CpuProfileNode::GetLineNumber() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006885 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
6886}
6887
6888
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +00006889int CpuProfileNode::GetColumnNumber() const {
6890 return reinterpret_cast<const i::ProfileNode*>(this)->
6891 entry()->column_number();
6892}
6893
6894
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00006895const char* CpuProfileNode::GetBailoutReason() const {
6896 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6897 return node->entry()->bailout_reason();
6898}
6899
6900
danno@chromium.org59400602013-08-13 17:09:37 +00006901unsigned CpuProfileNode::GetHitCount() const {
6902 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
6903}
6904
6905
ager@chromium.org357bf652010-04-12 11:30:10 +00006906unsigned CpuProfileNode::GetCallUid() const {
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00006907 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
ager@chromium.org357bf652010-04-12 11:30:10 +00006908}
6909
6910
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006911unsigned CpuProfileNode::GetNodeId() const {
6912 return reinterpret_cast<const i::ProfileNode*>(this)->id();
6913}
6914
6915
ager@chromium.org357bf652010-04-12 11:30:10 +00006916int CpuProfileNode::GetChildrenCount() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006917 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
6918}
6919
6920
6921const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006922 const i::ProfileNode* child =
6923 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
6924 return reinterpret_cast<const CpuProfileNode*>(child);
6925}
6926
6927
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006928void CpuProfile::Delete() {
6929 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006930 i::CpuProfiler* profiler = isolate->cpu_profiler();
6931 ASSERT(profiler != NULL);
6932 profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006933}
6934
6935
ager@chromium.org357bf652010-04-12 11:30:10 +00006936Handle<String> CpuProfile::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006937 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006938 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006939 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
6940 profile->title()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006941}
6942
6943
ager@chromium.org357bf652010-04-12 11:30:10 +00006944const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006945 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
6946 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
6947}
6948
6949
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006950const CpuProfileNode* CpuProfile::GetSample(int index) const {
6951 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
6952 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
6953}
6954
6955
danno@chromium.org89acc0b2013-08-09 20:55:58 +00006956int64_t CpuProfile::GetStartTime() const {
6957 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00006958 return (profile->start_time() - i::Time::UnixEpoch()).InMicroseconds();
danno@chromium.org89acc0b2013-08-09 20:55:58 +00006959}
6960
6961
6962int64_t CpuProfile::GetEndTime() const {
6963 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00006964 return (profile->end_time() - i::Time::UnixEpoch()).InMicroseconds();
danno@chromium.org89acc0b2013-08-09 20:55:58 +00006965}
6966
6967
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006968int CpuProfile::GetSamplesCount() const {
6969 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
6970}
6971
6972
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00006973void CpuProfiler::SetSamplingInterval(int us) {
6974 ASSERT(us >= 0);
6975 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
6976 i::TimeDelta::FromMicroseconds(us));
6977}
6978
6979
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006980void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
6981 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
6982 *Utils::OpenHandle(*title), record_samples);
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +00006983}
6984
6985
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00006986const CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title) {
6987 return reinterpret_cast<const CpuProfile*>(
6988 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00006989 *Utils::OpenHandle(*title)));
6990}
6991
6992
danno@chromium.org59400602013-08-13 17:09:37 +00006993void CpuProfiler::SetIdle(bool is_idle) {
6994 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
6995 i::StateTag state = isolate->current_vm_state();
6996 ASSERT(state == i::EXTERNAL || state == i::IDLE);
6997 if (isolate->js_entry_sp() != NULL) return;
6998 if (is_idle) {
6999 isolate->set_current_vm_state(i::IDLE);
7000 } else if (state == i::IDLE) {
7001 isolate->set_current_vm_state(i::EXTERNAL);
7002 }
7003}
7004
7005
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007006static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
7007 return const_cast<i::HeapGraphEdge*>(
7008 reinterpret_cast<const i::HeapGraphEdge*>(edge));
7009}
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00007010
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007011
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007012HeapGraphEdge::Type HeapGraphEdge::GetType() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007013 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007014}
7015
7016
7017Handle<Value> HeapGraphEdge::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007018 i::Isolate* isolate = i::Isolate::Current();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007019 i::HeapGraphEdge* edge = ToInternal(this);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007020 switch (edge->type()) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007021 case i::HeapGraphEdge::kContextVariable:
7022 case i::HeapGraphEdge::kInternal:
7023 case i::HeapGraphEdge::kProperty:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00007024 case i::HeapGraphEdge::kShortcut:
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007025 return ToApiHandle<String>(
7026 isolate->factory()->InternalizeUtf8String(edge->name()));
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007027 case i::HeapGraphEdge::kElement:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00007028 case i::HeapGraphEdge::kHidden:
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00007029 case i::HeapGraphEdge::kWeak:
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007030 return ToApiHandle<Number>(
7031 isolate->factory()->NewNumberFromInt(edge->index()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007032 default: UNREACHABLE();
7033 }
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00007034 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007035}
7036
7037
7038const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00007039 const i::HeapEntry* from = ToInternal(this)->from();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007040 return reinterpret_cast<const HeapGraphNode*>(from);
7041}
7042
7043
7044const HeapGraphNode* HeapGraphEdge::GetToNode() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007045 const i::HeapEntry* to = ToInternal(this)->to();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007046 return reinterpret_cast<const HeapGraphNode*>(to);
7047}
7048
7049
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007050static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
7051 return const_cast<i::HeapEntry*>(
7052 reinterpret_cast<const i::HeapEntry*>(entry));
7053}
7054
7055
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007056HeapGraphNode::Type HeapGraphNode::GetType() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007057 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007058}
7059
7060
7061Handle<String> HeapGraphNode::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007062 i::Isolate* isolate = i::Isolate::Current();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007063 return ToApiHandle<String>(
7064 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007065}
7066
7067
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007068SnapshotObjectId HeapGraphNode::GetId() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007069 return ToInternal(this)->id();
ricow@chromium.org4980dff2010-07-19 08:33:45 +00007070}
7071
7072
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007073int HeapGraphNode::GetSelfSize() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007074 return ToInternal(this)->self_size();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007075}
7076
7077
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007078int HeapGraphNode::GetChildrenCount() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007079 return ToInternal(this)->children().length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007080}
7081
7082
7083const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007084 return reinterpret_cast<const HeapGraphEdge*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007085 ToInternal(this)->children()[index]);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007086}
7087
7088
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007089static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
7090 return const_cast<i::HeapSnapshot*>(
7091 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
7092}
7093
7094
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007095void HeapSnapshot::Delete() {
7096 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007097 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007098 ToInternal(this)->Delete();
7099 } else {
7100 // If this is the last snapshot, clean up all accessory data as well.
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007101 isolate->heap_profiler()->DeleteAllSnapshots();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007102 }
7103}
7104
7105
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007106unsigned HeapSnapshot::GetUid() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007107 return ToInternal(this)->uid();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007108}
7109
7110
7111Handle<String> HeapSnapshot::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007112 i::Isolate* isolate = i::Isolate::Current();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007113 return ToApiHandle<String>(
7114 isolate->factory()->InternalizeUtf8String(ToInternal(this)->title()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007115}
7116
7117
ricow@chromium.org4980dff2010-07-19 08:33:45 +00007118const HeapGraphNode* HeapSnapshot::GetRoot() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007119 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007120}
7121
7122
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007123const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007124 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007125 ToInternal(this)->GetEntryById(id));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007126}
7127
7128
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007129int HeapSnapshot::GetNodesCount() const {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007130 return ToInternal(this)->entries().length();
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007131}
7132
7133
7134const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007135 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007136 &ToInternal(this)->entries().at(index));
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007137}
7138
7139
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007140SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007141 return ToInternal(this)->max_snapshot_js_object_id();
7142}
7143
7144
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00007145void HeapSnapshot::Serialize(OutputStream* stream,
7146 HeapSnapshot::SerializationFormat format) const {
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00007147 ApiCheck(format == kJSON,
7148 "v8::HeapSnapshot::Serialize",
7149 "Unknown serialization format");
7150 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
7151 "v8::HeapSnapshot::Serialize",
7152 "Unsupported output encoding");
7153 ApiCheck(stream->GetChunkSize() > 0,
7154 "v8::HeapSnapshot::Serialize",
7155 "Invalid stream chunk size");
7156 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
7157 serializer.Serialize(stream);
7158}
7159
7160
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007161int HeapProfiler::GetSnapshotCount() {
7162 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007163}
7164
7165
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007166const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
7167 return reinterpret_cast<const HeapSnapshot*>(
7168 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007169}
7170
7171
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007172SnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
7173 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
7174 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00007175}
7176
7177
hpayer@chromium.org4f99be92013-12-18 16:23:55 +00007178Handle<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
7179 i::Handle<i::Object> obj =
7180 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
7181 if (obj.is_null()) return Local<Value>();
7182 return Utils::ToLocal(obj);
7183}
7184
7185
7186void HeapProfiler::ClearObjectIds() {
7187 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
7188}
7189
7190
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007191const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
7192 Handle<String> title,
7193 ActivityControl* control,
7194 ObjectNameResolver* resolver) {
7195 return reinterpret_cast<const HeapSnapshot*>(
7196 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
7197 *Utils::OpenHandle(*title), control, resolver));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007198}
7199
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007200
machenbach@chromium.orgce9c5142013-12-03 08:00:39 +00007201void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
7202 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
7203 track_allocations);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007204}
7205
7206
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007207void HeapProfiler::StopTrackingHeapObjects() {
7208 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007209}
7210
7211
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007212SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
7213 return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007214}
7215
7216
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007217void HeapProfiler::DeleteAllHeapSnapshots() {
7218 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007219}
7220
7221
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007222void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
7223 WrapperInfoCallback callback) {
7224 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
7225 callback);
7226}
7227
7228
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007229size_t HeapProfiler::GetProfilerMemorySize() {
7230 return reinterpret_cast<i::HeapProfiler*>(this)->
7231 GetMemorySizeUsedByProfiler();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00007232}
7233
7234
danno@chromium.orgca29dd82013-04-26 11:59:48 +00007235void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
7236 RetainedObjectInfo* info) {
7237 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
7238}
7239
7240
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007241v8::Testing::StressType internal::Testing::stress_type_ =
7242 v8::Testing::kStressTypeOpt;
7243
7244
7245void Testing::SetStressRunType(Testing::StressType type) {
7246 internal::Testing::set_stress_type(type);
7247}
7248
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00007249
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007250int Testing::GetStressRuns() {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00007251 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007252#ifdef DEBUG
7253 // In debug mode the code runs much slower so stressing will only make two
7254 // runs.
7255 return 2;
7256#else
7257 return 5;
7258#endif
7259}
7260
7261
7262static void SetFlagsFromString(const char* flags) {
7263 V8::SetFlagsFromString(flags, i::StrLength(flags));
7264}
7265
7266
7267void Testing::PrepareStressRun(int run) {
7268 static const char* kLazyOptimizations =
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00007269 "--prepare-always-opt "
7270 "--max-inlined-source-size=999999 "
7271 "--max-inlined-nodes=999999 "
7272 "--max-inlined-nodes-cumulative=999999 "
7273 "--noalways-opt";
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007274 static const char* kForcedOptimizations = "--always-opt";
7275
7276 // If deoptimization stressed turn on frequent deoptimization. If no value
7277 // is spefified through --deopt-every-n-times use a default default value.
7278 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
7279 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
7280 internal::FLAG_deopt_every_n_times == 0) {
7281 SetFlagsFromString(kDeoptEvery13Times);
7282 }
7283
7284#ifdef DEBUG
7285 // As stressing in debug mode only make two runs skip the deopt stressing
7286 // here.
7287 if (run == GetStressRuns() - 1) {
7288 SetFlagsFromString(kForcedOptimizations);
7289 } else {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007290 SetFlagsFromString(kLazyOptimizations);
7291 }
7292#else
7293 if (run == GetStressRuns() - 1) {
7294 SetFlagsFromString(kForcedOptimizations);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00007295 } else if (run != GetStressRuns() - 2) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007296 SetFlagsFromString(kLazyOptimizations);
7297 }
7298#endif
7299}
7300
7301
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00007302// TODO(svenpanne) Deprecate this.
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007303void Testing::DeoptimizeAll() {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00007304 i::Isolate* isolate = i::Isolate::Current();
7305 i::HandleScope scope(isolate);
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00007306 internal::Deoptimizer::DeoptimizeAll(isolate);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007307}
7308
7309
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007310namespace internal {
7311
7312
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007313void HandleScopeImplementer::FreeThreadResources() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007314 Free();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007315}
7316
7317
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007318char* HandleScopeImplementer::ArchiveThread(char* storage) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00007319 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00007320 isolate_->handle_scope_data();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007321 handle_scope_data_ = *current;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00007322 OS::MemCopy(storage, this, sizeof(*this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007323
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007324 ResetAfterArchive();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007325 current->Initialize();
7326
7327 return storage + ArchiveSpacePerThread();
7328}
7329
7330
7331int HandleScopeImplementer::ArchiveSpacePerThread() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007332 return sizeof(HandleScopeImplementer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007333}
7334
7335
7336char* HandleScopeImplementer::RestoreThread(char* storage) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00007337 OS::MemCopy(this, storage, sizeof(*this));
lrn@chromium.org1c092762011-05-09 09:42:16 +00007338 *isolate_->handle_scope_data() = handle_scope_data_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007339 return storage + ArchiveSpacePerThread();
7340}
7341
7342
ager@chromium.orga1645e22009-09-09 19:27:10 +00007343void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007344#ifdef DEBUG
7345 bool found_block_before_deferred = false;
7346#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007347 // Iterate over all handles in the blocks except for the last.
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007348 for (int i = blocks()->length() - 2; i >= 0; --i) {
7349 Object** block = blocks()->at(i);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007350 if (last_handle_before_deferred_block_ != NULL &&
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00007351 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007352 (last_handle_before_deferred_block_ >= block)) {
7353 v->VisitPointers(block, last_handle_before_deferred_block_);
7354 ASSERT(!found_block_before_deferred);
7355#ifdef DEBUG
7356 found_block_before_deferred = true;
7357#endif
7358 } else {
7359 v->VisitPointers(block, &block[kHandleBlockSize]);
7360 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007361 }
7362
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007363 ASSERT(last_handle_before_deferred_block_ == NULL ||
7364 found_block_before_deferred);
7365
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007366 // Iterate over live handles in the last block (if any).
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007367 if (!blocks()->is_empty()) {
7368 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
ager@chromium.orga1645e22009-09-09 19:27:10 +00007369 }
7370
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00007371 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
7372 for (unsigned i = 0; i < ARRAY_SIZE(context_lists); i++) {
7373 if (context_lists[i]->is_empty()) continue;
7374 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
7375 v->VisitPointers(start, start + context_lists[i]->length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007376 }
7377}
7378
7379
7380void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00007381 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00007382 isolate_->handle_scope_data();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007383 handle_scope_data_ = *current;
7384 IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007385}
7386
7387
7388char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
lrn@chromium.org7516f052011-03-30 08:52:27 +00007389 HandleScopeImplementer* scope_implementer =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007390 reinterpret_cast<HandleScopeImplementer*>(storage);
lrn@chromium.org7516f052011-03-30 08:52:27 +00007391 scope_implementer->IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007392 return storage + ArchiveSpacePerThread();
7393}
7394
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007395
7396DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007397 DeferredHandles* deferred =
7398 new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007399
7400 while (!blocks_.is_empty()) {
7401 Object** block_start = blocks_.last();
7402 Object** block_limit = &block_start[kHandleBlockSize];
rossberg@chromium.org79e79022013-06-03 15:43:46 +00007403 // We should not need to check for SealHandleScope here. Assert this.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007404 ASSERT(prev_limit == block_limit ||
7405 !(block_start <= prev_limit && prev_limit <= block_limit));
7406 if (prev_limit == block_limit) break;
7407 deferred->blocks_.Add(blocks_.last());
7408 blocks_.RemoveLast();
7409 }
7410
7411 // deferred->blocks_ now contains the blocks installed on the
7412 // HandleScope stack since BeginDeferredScope was called, but in
7413 // reverse order.
7414
7415 ASSERT(prev_limit == NULL || !blocks_.is_empty());
7416
7417 ASSERT(!blocks_.is_empty() && prev_limit != NULL);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007418 ASSERT(last_handle_before_deferred_block_ != NULL);
7419 last_handle_before_deferred_block_ = NULL;
7420 return deferred;
7421}
7422
7423
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007424void HandleScopeImplementer::BeginDeferredScope() {
7425 ASSERT(last_handle_before_deferred_block_ == NULL);
7426 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
7427}
7428
7429
7430DeferredHandles::~DeferredHandles() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007431 isolate_->UnlinkDeferredHandles(this);
7432
7433 for (int i = 0; i < blocks_.length(); i++) {
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00007434#ifdef ENABLE_HANDLE_ZAPPING
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007435 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
7436#endif
7437 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
7438 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007439}
7440
7441
7442void DeferredHandles::Iterate(ObjectVisitor* v) {
7443 ASSERT(!blocks_.is_empty());
7444
7445 ASSERT((first_block_limit_ >= blocks_.first()) &&
verwaest@chromium.org753aee42012-07-17 16:15:42 +00007446 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007447
7448 v->VisitPointers(blocks_.first(), first_block_limit_);
7449
7450 for (int i = 1; i < blocks_.length(); i++) {
7451 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
7452 }
7453}
7454
7455
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007456void InvokeAccessorGetterCallback(
7457 v8::Local<v8::String> property,
7458 const v8::PropertyCallbackInfo<v8::Value>& info,
7459 v8::AccessorGetterCallback getter) {
7460 // Leaving JavaScript.
7461 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7462 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
7463 getter));
7464 VMState<EXTERNAL> state(isolate);
7465 ExternalCallbackScope call_scope(isolate, getter_address);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00007466 getter(property, info);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007467}
7468
7469
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007470void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
7471 v8::FunctionCallback callback) {
7472 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7473 Address callback_address =
7474 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
7475 VMState<EXTERNAL> state(isolate);
7476 ExternalCallbackScope call_scope(isolate, callback_address);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00007477 callback(info);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007478}
7479
7480
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007481} } // namespace v8::internal