blob: 469c7a1814df85e35e1e409684be5c22efa3437c [file] [log] [blame]
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000028#include "api.h"
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000029
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000030#include <string.h> // For memcpy, strlen.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000031#include <cmath> // For isnan.
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000032#include "../include/v8-debug.h"
33#include "../include/v8-profiler.h"
34#include "../include/v8-testing.h"
rossberg@chromium.org79e79022013-06-03 15:43:46 +000035#include "assert-scope.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036#include "bootstrapper.h"
verwaest@chromium.org753aee42012-07-17 16:15:42 +000037#include "code-stubs.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038#include "compiler.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000039#include "conversions-inl.h"
40#include "counters.h"
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000041#include "cpu-profiler.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042#include "debug.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000043#include "deoptimizer.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "execution.h"
45#include "global-handles.h"
whesse@chromium.org2c186ca2010-06-16 11:32:39 +000046#include "heap-profiler.h"
ulan@chromium.org2e04b582013-02-21 14:06:02 +000047#include "heap-snapshot-generator-inl.h"
danno@chromium.org169691d2013-07-15 08:01:13 +000048#include "icu_util.h"
danno@chromium.org59400602013-08-13 17:09:37 +000049#include "json-parser.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000050#include "messages.h"
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +000051#ifdef COMPRESS_STARTUP_DATA_BZ2
52#include "natives.h"
53#endif
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000054#include "parser.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000055#include "platform.h"
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000056#include "platform/time.h"
ager@chromium.org357bf652010-04-12 11:30:10 +000057#include "profile-generator-inl.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000058#include "property-details.h"
59#include "property.h"
danno@chromium.orgca29dd82013-04-26 11:59:48 +000060#include "runtime.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000061#include "runtime-profiler.h"
ricow@chromium.org55ee8072011-09-08 16:33:10 +000062#include "scanner-character-streams.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063#include "snapshot.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000064#include "unicode-inl.h"
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +000065#include "utils/random-number-generator.h"
ager@chromium.orgddb913d2009-01-27 10:01:48 +000066#include "v8threads.h"
ager@chromium.org5ec48922009-05-05 07:25:34 +000067#include "version.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000068#include "vm-state-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000069
70
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000071#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072
danno@chromium.orgca29dd82013-04-26 11:59:48 +000073#define ENTER_V8(isolate) \
74 ASSERT((isolate)->IsInitialized()); \
75 i::VMState<i::OTHER> __state__((isolate))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000076
77namespace v8 {
78
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000079#define ON_BAILOUT(isolate, location, code) \
machenbach@chromium.orgae161032013-09-24 09:12:30 +000080 if (IsExecutionTerminatingCheck(isolate)) { \
kmillikin@chromium.org9155e252010-05-26 13:27:57 +000081 code; \
82 UNREACHABLE(); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000083 }
84
85
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000086#define EXCEPTION_PREAMBLE(isolate) \
87 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
88 ASSERT(!(isolate)->external_caught_exception()); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000089 bool has_pending_exception = false
90
91
rossberg@chromium.orgfab14982012-01-05 15:02:15 +000092#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093 do { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000094 i::HandleScopeImplementer* handle_scope_implementer = \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000095 (isolate)->handle_scope_implementer(); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000096 handle_scope_implementer->DecrementCallDepth(); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000097 if (has_pending_exception) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000098 if (handle_scope_implementer->CallDepthIsZero() && \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000099 (isolate)->is_out_of_memory()) { \
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000100 if (!(isolate)->ignore_out_of_memory()) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 i::V8::FatalProcessOutOfMemory(NULL); \
102 } \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000103 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000104 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000105 do_callback \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106 return value; \
107 } \
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000108 do_callback \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000109 } while (false)
110
111
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000112#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
113 EXCEPTION_BAILOUT_CHECK_GENERIC( \
114 isolate, value, i::V8::FireCallCompletedCallback(isolate);)
115
116
117#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
118 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
119
120
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000121#define API_ENTRY_CHECK(isolate, msg) \
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000122 do { \
123 if (v8::Locker::IsActive()) { \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000124 ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(), \
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000125 msg, \
126 "Entering the V8 API without proper locking in place"); \
127 } \
128 } while (false)
129
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000131// --- E x c e p t i o n B e h a v i o r ---
132
133
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000134static void DefaultFatalErrorHandler(const char* location,
135 const char* message) {
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000136 i::Isolate* isolate = i::Isolate::Current();
137 if (isolate->IsInitialized()) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000138 i::VMState<i::OTHER> state(isolate);
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000139 API_Fatal(location, message);
140 } else {
141 API_Fatal(location, message);
142 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000143}
144
145
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000146static FatalErrorCallback GetFatalErrorHandler() {
147 i::Isolate* isolate = i::Isolate::Current();
148 if (isolate->exception_behavior() == NULL) {
149 isolate->set_exception_behavior(DefaultFatalErrorHandler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000151 return isolate->exception_behavior();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000152}
153
154
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000155void i::FatalProcessOutOfMemory(const char* location) {
156 i::V8::FatalProcessOutOfMemory(location, false);
157}
158
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159
160// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
161// The default fatal error handler is called and execution is stopped.
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000162void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000163 i::HeapStats heap_stats;
164 int start_marker;
165 heap_stats.start_marker = &start_marker;
166 int new_space_size;
167 heap_stats.new_space_size = &new_space_size;
168 int new_space_capacity;
169 heap_stats.new_space_capacity = &new_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000170 intptr_t old_pointer_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000171 heap_stats.old_pointer_space_size = &old_pointer_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000172 intptr_t old_pointer_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000173 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000174 intptr_t old_data_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000175 heap_stats.old_data_space_size = &old_data_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000176 intptr_t old_data_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000177 heap_stats.old_data_space_capacity = &old_data_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000178 intptr_t code_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000179 heap_stats.code_space_size = &code_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000180 intptr_t code_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000181 heap_stats.code_space_capacity = &code_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000182 intptr_t map_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000183 heap_stats.map_space_size = &map_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000184 intptr_t map_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000185 heap_stats.map_space_capacity = &map_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000186 intptr_t cell_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000187 heap_stats.cell_space_size = &cell_space_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000188 intptr_t cell_space_capacity;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000189 heap_stats.cell_space_capacity = &cell_space_capacity;
danno@chromium.org41728482013-06-12 22:31:22 +0000190 intptr_t property_cell_space_size;
191 heap_stats.property_cell_space_size = &property_cell_space_size;
192 intptr_t property_cell_space_capacity;
193 heap_stats.property_cell_space_capacity = &property_cell_space_capacity;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000194 intptr_t lo_space_size;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000195 heap_stats.lo_space_size = &lo_space_size;
196 int global_handle_count;
197 heap_stats.global_handle_count = &global_handle_count;
198 int weak_global_handle_count;
199 heap_stats.weak_global_handle_count = &weak_global_handle_count;
200 int pending_global_handle_count;
201 heap_stats.pending_global_handle_count = &pending_global_handle_count;
202 int near_death_global_handle_count;
203 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000204 int free_global_handle_count;
205 heap_stats.free_global_handle_count = &free_global_handle_count;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000206 intptr_t memory_allocator_size;
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000207 heap_stats.memory_allocator_size = &memory_allocator_size;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000208 intptr_t memory_allocator_capacity;
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000209 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
210 int objects_per_type[LAST_TYPE + 1] = {0};
211 heap_stats.objects_per_type = objects_per_type;
212 int size_per_type[LAST_TYPE + 1] = {0};
213 heap_stats.size_per_type = size_per_type;
ager@chromium.orgea4f62e2010-08-16 16:28:43 +0000214 int os_error;
215 heap_stats.os_error = &os_error;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000216 int end_marker;
217 heap_stats.end_marker = &end_marker;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000218 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000219 if (isolate->heap()->HasBeenSetUp()) {
220 // BUG(1718): Don't use the take_snapshot since we don't support
221 // HeapIterator here without doing a special GC.
222 isolate->heap()->RecordStats(&heap_stats, false);
223 }
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000224 isolate->SignalFatalError();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225 FatalErrorCallback callback = GetFatalErrorHandler();
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000226 const char* message = "Allocation failed - process out of memory";
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000227 callback(location, message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000228 // If the callback returns, we stop execution.
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000229 FATAL("API fatal error handler returned after process out of memory");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230}
231
232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000233bool Utils::ReportApiFailure(const char* location, const char* message) {
234 FatalErrorCallback callback = GetFatalErrorHandler();
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000235 callback(location, message);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000236 i::Isolate* isolate = i::Isolate::Current();
237 isolate->SignalFatalError();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000238 return false;
239}
240
241
242bool V8::IsDead() {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000243 i::Isolate* isolate = i::Isolate::Current();
244 return isolate->IsDead();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000245}
246
247
248static inline bool ApiCheck(bool condition,
249 const char* location,
250 const char* message) {
251 return condition ? true : Utils::ReportApiFailure(location, message);
252}
253
254
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000255static bool ReportEmptyHandle(const char* location) {
256 FatalErrorCallback callback = GetFatalErrorHandler();
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000257 callback(location, "Reading from empty handle");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000258 return true;
259}
260
261
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000262static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
263 if (!isolate->IsInitialized()) return false;
264 if (isolate->has_scheduled_exception()) {
265 return isolate->scheduled_exception() ==
266 isolate->heap()->termination_exception();
267 }
268 return false;
269}
270
271
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
273 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
274}
275
276
ager@chromium.org32912102009-01-16 10:38:43 +0000277static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000278 return (obj == 0) ? ReportEmptyHandle(location) : false;
279}
280
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000281
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000282// --- S t a t i c s ---
283
284
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000285static bool InitializeHelper(i::Isolate* isolate) {
286 // If the isolate has a function entry hook, it needs to re-build all its
287 // code stubs with entry hooks embedded, so let's deserialize a snapshot.
288 if (isolate == NULL || isolate->function_entry_hook() == NULL) {
289 if (i::Snapshot::Initialize())
290 return true;
291 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000292 return i::V8::Initialize(NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000293}
294
295
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000296static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
297 const char* location) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000298 if (isolate != NULL) {
299 if (isolate->IsInitialized()) return true;
300 }
lrn@chromium.org1c092762011-05-09 09:42:16 +0000301 ASSERT(isolate == i::Isolate::Current());
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000302 return ApiCheck(InitializeHelper(isolate), location, "Error initializing V8");
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000303}
304
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000305
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000306// Some initializing API functions are called early and may be
307// called on a thread different from static initializer thread.
308// If Isolate API is used, Isolate::Enter() will initialize TLS so
309// Isolate::Current() works. If it's a legacy case, then the thread
310// may not have TLS initialized yet. However, in initializing APIs it
311// may be too early to call EnsureInitialized() - some pre-init
312// parameters still have to be configured.
313static inline i::Isolate* EnterIsolateIfNeeded() {
314 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
315 if (isolate != NULL)
316 return isolate;
317
318 i::Isolate::EnterDefaultIsolate();
319 isolate = i::Isolate::Current();
320 return isolate;
321}
322
323
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000324StartupDataDecompressor::StartupDataDecompressor()
325 : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
326 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
327 raw_data[i] = NULL;
328 }
329}
330
331
332StartupDataDecompressor::~StartupDataDecompressor() {
333 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
334 i::DeleteArray(raw_data[i]);
335 }
336 i::DeleteArray(raw_data);
337}
338
339
340int StartupDataDecompressor::Decompress() {
341 int compressed_data_count = V8::GetCompressedStartupDataCount();
342 StartupData* compressed_data =
343 i::NewArray<StartupData>(compressed_data_count);
344 V8::GetCompressedStartupData(compressed_data);
345 for (int i = 0; i < compressed_data_count; ++i) {
346 char* decompressed = raw_data[i] =
347 i::NewArray<char>(compressed_data[i].raw_size);
348 if (compressed_data[i].compressed_size != 0) {
349 int result = DecompressData(decompressed,
350 &compressed_data[i].raw_size,
351 compressed_data[i].data,
352 compressed_data[i].compressed_size);
353 if (result != 0) return result;
354 } else {
355 ASSERT_EQ(0, compressed_data[i].raw_size);
356 }
357 compressed_data[i].data = decompressed;
358 }
359 V8::SetDecompressedStartupData(compressed_data);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000360 i::DeleteArray(compressed_data);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000361 return 0;
362}
363
364
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000365StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
366#ifdef COMPRESS_STARTUP_DATA_BZ2
367 return StartupData::kBZip2;
368#else
369 return StartupData::kUncompressed;
370#endif
371}
372
373
374enum CompressedStartupDataItems {
375 kSnapshot = 0,
376 kSnapshotContext,
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000377 kLibraries,
378 kExperimentalLibraries,
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000379 kCompressedStartupDataCount
380};
381
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000382
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000383int V8::GetCompressedStartupDataCount() {
384#ifdef COMPRESS_STARTUP_DATA_BZ2
385 return kCompressedStartupDataCount;
386#else
387 return 0;
388#endif
389}
390
391
392void V8::GetCompressedStartupData(StartupData* compressed_data) {
393#ifdef COMPRESS_STARTUP_DATA_BZ2
394 compressed_data[kSnapshot].data =
395 reinterpret_cast<const char*>(i::Snapshot::data());
396 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
397 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
398
399 compressed_data[kSnapshotContext].data =
400 reinterpret_cast<const char*>(i::Snapshot::context_data());
401 compressed_data[kSnapshotContext].compressed_size =
402 i::Snapshot::context_size();
403 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000404
405 i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
406 compressed_data[kLibraries].data =
407 reinterpret_cast<const char*>(libraries_source.start());
408 compressed_data[kLibraries].compressed_size = libraries_source.length();
409 compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
410
411 i::Vector<const i::byte> exp_libraries_source =
412 i::ExperimentalNatives::GetScriptsSource();
413 compressed_data[kExperimentalLibraries].data =
414 reinterpret_cast<const char*>(exp_libraries_source.start());
415 compressed_data[kExperimentalLibraries].compressed_size =
416 exp_libraries_source.length();
417 compressed_data[kExperimentalLibraries].raw_size =
418 i::ExperimentalNatives::GetRawScriptsSize();
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000419#endif
420}
421
422
423void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
424#ifdef COMPRESS_STARTUP_DATA_BZ2
425 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
426 i::Snapshot::set_raw_data(
427 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
428
429 ASSERT_EQ(i::Snapshot::context_raw_size(),
430 decompressed_data[kSnapshotContext].raw_size);
431 i::Snapshot::set_context_raw_data(
432 reinterpret_cast<const i::byte*>(
433 decompressed_data[kSnapshotContext].data));
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000434
435 ASSERT_EQ(i::Natives::GetRawScriptsSize(),
436 decompressed_data[kLibraries].raw_size);
437 i::Vector<const char> libraries_source(
438 decompressed_data[kLibraries].data,
439 decompressed_data[kLibraries].raw_size);
440 i::Natives::SetRawScriptsSource(libraries_source);
441
442 ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
443 decompressed_data[kExperimentalLibraries].raw_size);
444 i::Vector<const char> exp_libraries_source(
445 decompressed_data[kExperimentalLibraries].data,
446 decompressed_data[kExperimentalLibraries].raw_size);
447 i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000448#endif
449}
450
451
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000452void V8::SetFatalErrorHandler(FatalErrorCallback that) {
453 i::Isolate* isolate = EnterIsolateIfNeeded();
454 isolate->set_exception_behavior(that);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000455}
456
457
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000458void V8::SetAllowCodeGenerationFromStringsCallback(
459 AllowCodeGenerationFromStringsCallback callback) {
460 i::Isolate* isolate = EnterIsolateIfNeeded();
461 isolate->set_allow_code_gen_callback(callback);
462}
463
464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465void V8::SetFlagsFromString(const char* str, int length) {
466 i::FlagList::SetFlagsFromString(str, length);
467}
468
469
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000470void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
471 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
472}
473
474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000475v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000476 return v8::Isolate::GetCurrent()->ThrowException(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477}
478
479
480RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
481
482
483RegisteredExtension::RegisteredExtension(Extension* extension)
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000484 : extension_(extension) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000485
486
487void RegisteredExtension::Register(RegisteredExtension* that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000488 that->next_ = first_extension_;
489 first_extension_ = that;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000490}
491
492
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000493void RegisteredExtension::UnregisterAll() {
494 RegisteredExtension* re = first_extension_;
495 while (re != NULL) {
496 RegisteredExtension* next = re->next();
497 delete re;
498 re = next;
499 }
500}
501
502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503void RegisterExtension(Extension* that) {
504 RegisteredExtension* extension = new RegisteredExtension(that);
505 RegisteredExtension::Register(extension);
506}
507
508
509Extension::Extension(const char* name,
510 const char* source,
511 int dep_count,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000512 const char** deps,
513 int source_length)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514 : name_(name),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000515 source_length_(source_length >= 0 ?
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000516 source_length :
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000517 (source ? static_cast<int>(strlen(source)) : 0)),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000518 source_(source, source_length_),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000519 dep_count_(dep_count),
520 deps_(deps),
danno@chromium.org412fa512012-09-14 13:28:26 +0000521 auto_enable_(false) {
522 CHECK(source != NULL || source_length_ == 0);
523}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524
525
526v8::Handle<Primitive> Undefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000527 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000528 if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
529 return v8::Handle<v8::Primitive>();
530 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000531 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000532}
533
534
535v8::Handle<Primitive> Null() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000536 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000537 if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
538 return v8::Handle<v8::Primitive>();
539 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000540 return ToApiHandle<Primitive>(isolate->factory()->null_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000541}
542
543
544v8::Handle<Boolean> True() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000545 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000546 if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
547 return v8::Handle<Boolean>();
548 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000549 return ToApiHandle<Boolean>(isolate->factory()->true_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550}
551
552
553v8::Handle<Boolean> False() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000554 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000555 if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
556 return v8::Handle<Boolean>();
557 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000558 return ToApiHandle<Boolean>(isolate->factory()->false_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000559}
560
561
562ResourceConstraints::ResourceConstraints()
563 : max_young_space_size_(0),
564 max_old_space_size_(0),
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000565 max_executable_size_(0),
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000566 stack_limit_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567
568
569bool SetResourceConstraints(ResourceConstraints* constraints) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000570 i::Isolate* isolate = EnterIsolateIfNeeded();
571
ager@chromium.org3811b432009-10-28 14:53:37 +0000572 int young_space_size = constraints->max_young_space_size();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000573 int old_gen_size = constraints->max_old_space_size();
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000574 int max_executable_size = constraints->max_executable_size();
575 if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000576 // After initialization it's too late to change Heap constraints.
577 ASSERT(!isolate->IsInitialized());
578 bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
579 old_gen_size,
580 max_executable_size);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000581 if (!result) return false;
582 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000583 if (constraints->stack_limit() != NULL) {
584 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000585 isolate->stack_guard()->SetStackLimit(limit);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586 }
587 return true;
588}
589
590
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000591i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000592 LOG_API(isolate, "Persistent::New");
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000593 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000594#ifdef DEBUG
595 (*obj)->Verify();
596#endif // DEBUG
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000597 return result.location();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000598}
599
600
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000601i::Object** V8::CopyPersistent(i::Object** obj) {
602 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
603#ifdef DEBUG
604 (*obj)->Verify();
605#endif // DEBUG
606 return result.location();
607}
608
609
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000610void V8::MakeWeak(i::Object** object,
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000611 void* parameters,
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000612 WeakCallback weak_callback,
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000613 RevivableCallback weak_reference_callback) {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000614 i::GlobalHandles::MakeWeak(object,
615 parameters,
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000616 weak_callback,
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000617 weak_reference_callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618}
619
620
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000621void V8::ClearWeak(i::Object** obj) {
622 i::GlobalHandles::ClearWeakness(obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000626void V8::DisposeGlobal(i::Object** obj) {
627 i::GlobalHandles::Destroy(obj);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000628}
629
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000630
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000631void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
632 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
633 i::Object* object = *Utils::OpenHandle(value);
634 isolate->eternal_handles()->Create(isolate, object, index);
danno@chromium.org59400602013-08-13 17:09:37 +0000635}
636
637
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000638Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
639 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
640 return Utils::ToLocal(isolate->eternal_handles()->Get(index));
danno@chromium.org59400602013-08-13 17:09:37 +0000641}
642
643
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644// --- H a n d l e s ---
645
646
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000647HandleScope::HandleScope(Isolate* isolate) {
648 Initialize(isolate);
649}
650
651
652void HandleScope::Initialize(Isolate* isolate) {
653 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
654 API_ENTRY_CHECK(internal_isolate, "HandleScope::HandleScope");
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000655 v8::ImplementationUtilities::HandleScopeData* current =
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000656 internal_isolate->handle_scope_data();
657 isolate_ = internal_isolate;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000658 prev_next_ = current->next;
659 prev_limit_ = current->limit;
660 is_closed_ = false;
661 current->level++;
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000662}
663
664
665HandleScope::~HandleScope() {
666 if (!is_closed_) {
lrn@chromium.org303ada72010-10-27 09:33:13 +0000667 Leave();
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000668 }
669}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670
671
lrn@chromium.org303ada72010-10-27 09:33:13 +0000672void HandleScope::Leave() {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000673 return i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000674}
675
676
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000677int HandleScope::NumberOfHandles() {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000678 i::Isolate* isolate = i::Isolate::Current();
679 if (!EnsureInitializedForIsolate(isolate, "HandleScope::NumberOfHandles")) {
680 return 0;
681 }
682 return i::HandleScope::NumberOfHandles(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000683}
684
685
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000686i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000687 return i::HandleScope::CreateHandle(isolate, value);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000688}
689
690
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +0000691i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
692 i::Object* value) {
693 ASSERT(heap_object->IsHeapObject());
694 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
695}
696
697
698EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
699 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
700 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
701 Initialize(v8_isolate);
702}
703
704
705i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
706 ApiCheck(*escape_slot_ == isolate_->heap()->the_hole_value(),
707 "EscapeableHandleScope::Escape",
708 "Escape value set twice");
709 if (escape_value == NULL) {
710 *escape_slot_ = isolate_->heap()->undefined_value();
711 return NULL;
712 }
713 *escape_slot_ = *escape_value;
714 return escape_slot_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000715}
716
717
718void Context::Enter() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000719 i::Handle<i::Context> env = Utils::OpenHandle(this);
720 i::Isolate* isolate = env->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000721 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000722 isolate->handle_scope_implementer()->EnterContext(env);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000723 isolate->handle_scope_implementer()->SaveContext(isolate->context());
724 isolate->set_context(*env);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000725}
726
727
728void Context::Exit() {
machenbach@chromium.orgae161032013-09-24 09:12:30 +0000729 // TODO(dcarney): fix this once chrome is fixed.
730 i::Isolate* isolate = i::Isolate::Current();
731 i::Handle<i::Context> context = i::Handle<i::Context>::null();
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000732 ENTER_V8(isolate);
733 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveContext(context),
kasper.lund44510672008-07-25 07:37:58 +0000734 "v8::Context::Exit()",
735 "Cannot exit non-entered context")) {
736 return;
737 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000738 // Content of 'last_context' could be NULL.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000739 i::Context* last_context =
740 isolate->handle_scope_implementer()->RestoreContext();
741 isolate->set_context(last_context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742}
743
744
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000745static void* DecodeSmiToAligned(i::Object* value, const char* location) {
746 ApiCheck(value->IsSmi(), location, "Not a Smi");
747 return reinterpret_cast<void*>(value);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000748}
749
750
mstarzinger@chromium.org0c977e02013-07-26 10:45:47 +0000751static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
752 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000753 ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
754 return smi;
755}
756
757
758static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
759 int index,
760 bool can_grow,
761 const char* location) {
762 i::Handle<i::Context> env = Utils::OpenHandle(context);
machenbach@chromium.orgae161032013-09-24 09:12:30 +0000763 bool ok =
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000764 ApiCheck(env->IsNativeContext(), location, "Not a native context") &&
765 ApiCheck(index >= 0, location, "Negative index");
766 if (!ok) return i::Handle<i::FixedArray>();
767 i::Handle<i::FixedArray> data(env->embedder_data());
768 if (index < data->length()) return data;
769 if (!can_grow) {
770 Utils::ReportApiFailure(location, "Index too large");
771 return i::Handle<i::FixedArray>();
svenpanne@chromium.orgfc2a4f42012-11-07 09:25:55 +0000772 }
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000773 int new_size = i::Max(index, data->length() << 1) + 1;
774 data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size);
775 env->set_embedder_data(*data);
776 return data;
777}
778
779
780v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
781 const char* location = "v8::Context::GetEmbedderData()";
782 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
783 if (data.is_null()) return Local<Value>();
784 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
ager@chromium.org9085a012009-05-11 19:22:57 +0000785 return Utils::ToLocal(result);
786}
787
788
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000789void Context::SetEmbedderData(int index, v8::Handle<Value> value) {
790 const char* location = "v8::Context::SetEmbedderData()";
791 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
792 if (data.is_null()) return;
793 i::Handle<i::Object> val = Utils::OpenHandle(*value);
794 data->set(index, *val);
795 ASSERT_EQ(*Utils::OpenHandle(*value),
796 *Utils::OpenHandle(*GetEmbedderData(index)));
797}
798
799
800void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
801 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
802 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
803 if (data.is_null()) return NULL;
804 return DecodeSmiToAligned(data->get(index), location);
805}
806
807
808void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
809 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
810 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
811 data->set(index, EncodeAlignedAsSmi(value, location));
812 ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index));
813}
814
815
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000816i::Object** v8::HandleScope::RawClose(i::Object** value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000817 if (!ApiCheck(!is_closed_,
818 "v8::HandleScope::Close()",
819 "Local scope has already been closed")) {
820 return 0;
821 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000822 LOG_API(isolate_, "CloseHandleScope");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000823
824 // Read the result before popping the handle block.
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000825 i::Object* result = NULL;
826 if (value != NULL) {
827 result = *value;
828 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000829 is_closed_ = true;
lrn@chromium.org303ada72010-10-27 09:33:13 +0000830 Leave();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000831
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000832 if (value == NULL) {
833 return NULL;
834 }
835
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 // Allocate a new handle on the previous handle block.
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000837 i::Handle<i::Object> handle(result, isolate_);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000838 return handle.location();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000839}
840
841
842// --- N e a n d e r ---
843
844
845// A constructor cannot easily return an error value, therefore it is necessary
846// to check for a dead VM with ON_BAILOUT before constructing any Neander
847// objects. To remind you about this there is no HandleScope in the
848// NeanderObject constructor. When you add one to the site calling the
849// constructor you should check that you ensured the VM was not dead first.
850NeanderObject::NeanderObject(int size) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000851 i::Isolate* isolate = i::Isolate::Current();
852 EnsureInitializedForIsolate(isolate, "v8::Nowhere");
853 ENTER_V8(isolate);
854 value_ = isolate->factory()->NewNeanderObject();
855 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000856 value_->set_elements(*elements);
857}
858
859
860int NeanderObject::size() {
861 return i::FixedArray::cast(value_->elements())->length();
862}
863
864
865NeanderArray::NeanderArray() : obj_(2) {
866 obj_.set(0, i::Smi::FromInt(0));
867}
868
869
870int NeanderArray::length() {
871 return i::Smi::cast(obj_.get(0))->value();
872}
873
874
875i::Object* NeanderArray::get(int offset) {
876 ASSERT(0 <= offset);
877 ASSERT(offset < length());
878 return obj_.get(offset + 1);
879}
880
881
882// This method cannot easily return an error value, therefore it is necessary
883// to check for a dead VM with ON_BAILOUT before calling it. To remind you
884// about this there is no HandleScope in this method. When you add one to the
885// site calling this method you should check that you ensured the VM was not
886// dead first.
887void NeanderArray::add(i::Handle<i::Object> value) {
888 int length = this->length();
889 int size = obj_.size();
890 if (length == size - 1) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000891 i::Factory* factory = i::Isolate::Current()->factory();
892 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000893 for (int i = 0; i < length; i++)
894 new_elms->set(i + 1, get(i));
895 obj_.value()->set_elements(*new_elms);
896 }
897 obj_.set(length + 1, *value);
898 obj_.set(0, i::Smi::FromInt(length + 1));
899}
900
901
902void NeanderArray::set(int index, i::Object* value) {
903 if (index < 0 || index >= this->length()) return;
904 obj_.set(index + 1, value);
905}
906
907
908// --- T e m p l a t e ---
909
910
911static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
912 that->set_tag(i::Smi::FromInt(type));
913}
914
915
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000916static void TemplateSet(i::Isolate* isolate,
917 v8::Template* templ,
918 int length,
919 v8::Handle<v8::Data>* data) {
920 i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
921 if (list->IsUndefined()) {
922 list = NeanderArray().value();
923 Utils::OpenHandle(templ)->set_property_list(*list);
924 }
925 NeanderArray array(list);
926 array.add(Utils::OpenHandle(*v8::Integer::New(length)));
927 for (int i = 0; i < length; i++) {
928 i::Handle<i::Object> value = data[i].IsEmpty() ?
929 i::Handle<i::Object>(isolate->factory()->undefined_value()) :
930 Utils::OpenHandle(*data[i]);
931 array.add(value);
932 }
933}
934
935
936void Template::Set(v8::Handle<String> name,
937 v8::Handle<Data> value,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000938 v8::PropertyAttribute attribute) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000939 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000940 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000941 i::HandleScope scope(isolate);
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000942 const int kSize = 3;
943 v8::Handle<v8::Data> data[kSize] = {
944 name,
945 value,
946 v8::Integer::New(attribute)};
947 TemplateSet(isolate, this, kSize, data);
948}
949
950
951void Template::SetAccessorProperty(
952 v8::Local<v8::String> name,
953 v8::Local<FunctionTemplate> getter,
954 v8::Local<FunctionTemplate> setter,
955 v8::PropertyAttribute attribute,
956 v8::AccessControl access_control) {
957 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000958 ENTER_V8(isolate);
959 ASSERT(!name.IsEmpty());
960 ASSERT(!getter.IsEmpty() || !setter.IsEmpty());
961 i::HandleScope scope(isolate);
962 const int kSize = 5;
963 v8::Handle<v8::Data> data[kSize] = {
964 name,
965 getter,
966 setter,
967 v8::Integer::New(attribute),
968 v8::Integer::New(access_control)};
969 TemplateSet(isolate, this, kSize, data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970}
971
972
973// --- F u n c t i o n T e m p l a t e ---
974static void InitializeFunctionTemplate(
975 i::Handle<i::FunctionTemplateInfo> info) {
976 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
977 info->set_flag(0);
978}
979
980
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000981Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000982 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000983 ENTER_V8(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000984 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
985 isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986 if (result->IsUndefined()) {
987 result = Utils::OpenHandle(*ObjectTemplate::New());
988 Utils::OpenHandle(this)->set_prototype_template(*result);
989 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000990 return ToApiHandle<ObjectTemplate>(result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000991}
992
993
994void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000995 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000996 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000997 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
998}
999
1000
dslomov@chromium.org639bac02013-09-09 11:58:54 +00001001static Local<FunctionTemplate> FunctionTemplateNew(
1002 i::Isolate* isolate,
1003 FunctionCallback callback,
1004 v8::Handle<Value> data,
1005 v8::Handle<Signature> signature,
1006 int length,
1007 bool do_not_cache) {
1008 i::Handle<i::Struct> struct_obj =
1009 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
1010 i::Handle<i::FunctionTemplateInfo> obj =
1011 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1012 InitializeFunctionTemplate(obj);
1013 obj->set_do_not_cache(do_not_cache);
1014 int next_serial_number = 0;
1015 if (!do_not_cache) {
1016 next_serial_number = isolate->next_serial_number() + 1;
1017 isolate->set_next_serial_number(next_serial_number);
1018 }
1019 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
1020 if (callback != 0) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001021 if (data.IsEmpty()) {
1022 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1023 }
dslomov@chromium.org639bac02013-09-09 11:58:54 +00001024 Utils::ToLocal(obj)->SetCallHandler(callback, data);
1025 }
1026 obj->set_length(length);
1027 obj->set_undetectable(false);
1028 obj->set_needs_access_check(false);
1029 if (!signature.IsEmpty())
1030 obj->set_signature(*Utils::OpenHandle(*signature));
1031 return Utils::ToLocal(obj);
1032}
1033
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001034Local<FunctionTemplate> FunctionTemplate::New(
1035 FunctionCallback callback,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001036 v8::Handle<Value> data,
1037 v8::Handle<Signature> signature,
1038 int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001039 i::Isolate* isolate = i::Isolate::Current();
1040 EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
1041 LOG_API(isolate, "FunctionTemplate::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001042 ENTER_V8(isolate);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00001043 return FunctionTemplateNew(
1044 isolate, callback, data, signature, length, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045}
1046
1047
1048Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
1049 int argc, Handle<FunctionTemplate> argv[]) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001050 i::Isolate* isolate = i::Isolate::Current();
1051 EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
1052 LOG_API(isolate, "Signature::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001053 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001054 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001055 isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056 i::Handle<i::SignatureInfo> obj =
1057 i::Handle<i::SignatureInfo>::cast(struct_obj);
1058 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
1059 if (argc > 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001060 i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061 for (int i = 0; i < argc; i++) {
1062 if (!argv[i].IsEmpty())
1063 args->set(i, *Utils::OpenHandle(*argv[i]));
1064 }
1065 obj->set_args(*args);
1066 }
1067 return Utils::ToLocal(obj);
1068}
1069
1070
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001071Local<AccessorSignature> AccessorSignature::New(
1072 Handle<FunctionTemplate> receiver) {
1073 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1074}
1075
1076
ulan@chromium.org750145a2013-03-07 15:14:13 +00001077template<typename Operation>
1078static Local<Operation> NewDescriptor(
1079 Isolate* isolate,
1080 const i::DeclaredAccessorDescriptorData& data,
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001081 Data* previous_descriptor) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001082 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
1083 i::Handle<i::DeclaredAccessorDescriptor> previous =
1084 i::Handle<i::DeclaredAccessorDescriptor>();
1085 if (previous_descriptor != NULL) {
1086 previous = Utils::OpenHandle(
1087 static_cast<DeclaredAccessorDescriptor*>(previous_descriptor));
1088 }
1089 i::Handle<i::DeclaredAccessorDescriptor> descriptor =
1090 i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001091 return Utils::Convert<i::DeclaredAccessorDescriptor, Operation>(descriptor);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001092}
1093
1094
1095Local<RawOperationDescriptor>
1096 ObjectOperationDescriptor::NewInternalFieldDereference(
1097 Isolate* isolate,
1098 int internal_field) {
1099 i::DeclaredAccessorDescriptorData data;
1100 data.type = i::kDescriptorObjectDereference;
1101 data.object_dereference_descriptor.internal_field = internal_field;
1102 return NewDescriptor<RawOperationDescriptor>(isolate, data, NULL);
1103}
1104
1105
1106Local<RawOperationDescriptor> RawOperationDescriptor::NewRawShift(
1107 Isolate* isolate,
1108 int16_t byte_offset) {
1109 i::DeclaredAccessorDescriptorData data;
1110 data.type = i::kDescriptorPointerShift;
1111 data.pointer_shift_descriptor.byte_offset = byte_offset;
1112 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1113}
1114
1115
1116Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewHandleDereference(
1117 Isolate* isolate) {
1118 i::DeclaredAccessorDescriptorData data;
1119 data.type = i::kDescriptorReturnObject;
1120 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1121}
1122
1123
1124Local<RawOperationDescriptor> RawOperationDescriptor::NewRawDereference(
1125 Isolate* isolate) {
1126 i::DeclaredAccessorDescriptorData data;
1127 data.type = i::kDescriptorPointerDereference;
1128 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1129}
1130
1131
1132Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPointerCompare(
1133 Isolate* isolate,
1134 void* compare_value) {
1135 i::DeclaredAccessorDescriptorData data;
1136 data.type = i::kDescriptorPointerCompare;
1137 data.pointer_compare_descriptor.compare_value = compare_value;
1138 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1139}
1140
1141
1142Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPrimitiveValue(
1143 Isolate* isolate,
1144 DeclaredAccessorDescriptorDataType data_type,
1145 uint8_t bool_offset) {
1146 i::DeclaredAccessorDescriptorData data;
1147 data.type = i::kDescriptorPrimitiveValue;
1148 data.primitive_value_descriptor.data_type = data_type;
1149 data.primitive_value_descriptor.bool_offset = bool_offset;
1150 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1151}
1152
1153
1154template<typename T>
1155static Local<DeclaredAccessorDescriptor> NewBitmaskCompare(
1156 Isolate* isolate,
1157 T bitmask,
1158 T compare_value,
1159 RawOperationDescriptor* operation) {
1160 i::DeclaredAccessorDescriptorData data;
1161 data.type = i::kDescriptorBitmaskCompare;
1162 data.bitmask_compare_descriptor.bitmask = bitmask;
1163 data.bitmask_compare_descriptor.compare_value = compare_value;
1164 data.bitmask_compare_descriptor.size = sizeof(T);
1165 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, operation);
1166}
1167
1168
1169Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare8(
1170 Isolate* isolate,
1171 uint8_t bitmask,
1172 uint8_t compare_value) {
1173 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1174}
1175
1176
1177Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare16(
1178 Isolate* isolate,
1179 uint16_t bitmask,
1180 uint16_t compare_value) {
1181 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1182}
1183
1184
1185Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare32(
1186 Isolate* isolate,
1187 uint32_t bitmask,
1188 uint32_t compare_value) {
1189 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1190}
1191
1192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
1194 Handle<FunctionTemplate> types[1] = { type };
1195 return TypeSwitch::New(1, types);
1196}
1197
1198
1199Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001200 i::Isolate* isolate = i::Isolate::Current();
1201 EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
1202 LOG_API(isolate, "TypeSwitch::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001203 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001204 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001205 for (int i = 0; i < argc; i++)
1206 vector->set(i, *Utils::OpenHandle(*types[i]));
1207 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001208 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001209 i::Handle<i::TypeSwitchInfo> obj =
1210 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
1211 obj->set_types(*vector);
1212 return Utils::ToLocal(obj);
1213}
1214
1215
1216int TypeSwitch::match(v8::Handle<Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001217 i::Isolate* isolate = i::Isolate::Current();
1218 LOG_API(isolate, "TypeSwitch::match");
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001219 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001220 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
1221 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
1222 i::FixedArray* types = i::FixedArray::cast(info->types());
1223 for (int i = 0; i < types->length(); i++) {
1224 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
1225 return i + 1;
1226 }
1227 return 0;
1228}
1229
1230
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001231#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00001232 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001233 (obj)->setter(*foreign); \
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001234 } while (false)
1235
1236
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001237void FunctionTemplate::SetCallHandler(FunctionCallback callback,
1238 v8::Handle<Value> data) {
1239 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001240 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001241 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001242 i::Handle<i::Struct> struct_obj =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001243 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244 i::Handle<i::CallHandlerInfo> obj =
1245 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001246 SET_FIELD_WRAPPED(obj, set_callback, callback);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001247 if (data.IsEmpty()) {
1248 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1249 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001250 obj->set_data(*Utils::OpenHandle(*data));
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001251 Utils::OpenHandle(this)->set_call_code(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001252}
1253
1254
ulan@chromium.org750145a2013-03-07 15:14:13 +00001255static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1256 i::Handle<i::AccessorInfo> obj,
1257 v8::Handle<String> name,
1258 v8::AccessControl settings,
1259 v8::PropertyAttribute attributes,
1260 v8::Handle<AccessorSignature> signature) {
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001261 obj->set_name(*Utils::OpenHandle(*name));
1262 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1263 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1264 if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true);
1265 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001266 if (!signature.IsEmpty()) {
1267 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1268 }
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001269 return obj;
1270}
1271
1272
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001273template<typename Getter, typename Setter>
ulan@chromium.org750145a2013-03-07 15:14:13 +00001274static i::Handle<i::AccessorInfo> MakeAccessorInfo(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275 v8::Handle<String> name,
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001276 Getter getter,
1277 Setter setter,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001278 v8::Handle<Value> data,
1279 v8::AccessControl settings,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001280 v8::PropertyAttribute attributes,
1281 v8::Handle<AccessorSignature> signature) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001282 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1283 i::Handle<i::ExecutableAccessorInfo> obj =
1284 isolate->factory()->NewExecutableAccessorInfo();
1285 SET_FIELD_WRAPPED(obj, set_getter, getter);
1286 SET_FIELD_WRAPPED(obj, set_setter, setter);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001287 if (data.IsEmpty()) {
1288 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1289 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00001290 obj->set_data(*Utils::OpenHandle(*data));
1291 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1292}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001293
ulan@chromium.org750145a2013-03-07 15:14:13 +00001294
1295static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1296 v8::Handle<String> name,
1297 v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001298 void* setter_ignored,
1299 void* data_ignored,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001300 v8::AccessControl settings,
1301 v8::PropertyAttribute attributes,
1302 v8::Handle<AccessorSignature> signature) {
1303 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1304 if (descriptor.IsEmpty()) return i::Handle<i::DeclaredAccessorInfo>();
1305 i::Handle<i::DeclaredAccessorInfo> obj =
1306 isolate->factory()->NewDeclaredAccessorInfo();
1307 obj->set_descriptor(*Utils::OpenHandle(*descriptor));
1308 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001309}
1310
1311
1312Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001313 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00001314 if (EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001315 return Local<ObjectTemplate>();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001316 ENTER_V8(isolate);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001317 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this);
1318 if (handle->instance_template()->IsUndefined()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319 Local<ObjectTemplate> templ =
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001320 ObjectTemplate::New(ToApiHandle<FunctionTemplate>(handle));
1321 handle->set_instance_template(*Utils::OpenHandle(*templ));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001322 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001323 i::Handle<i::ObjectTemplateInfo> result(
1324 i::ObjectTemplateInfo::cast(handle->instance_template()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001325 return Utils::ToLocal(result);
1326}
1327
1328
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001329void FunctionTemplate::SetLength(int length) {
1330 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001331 ENTER_V8(isolate);
1332 Utils::OpenHandle(this)->set_length(length);
1333}
1334
1335
kasper.lund212ac232008-07-16 07:07:30 +00001336void FunctionTemplate::SetClassName(Handle<String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001337 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001338 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001339 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1340}
1341
1342
1343void FunctionTemplate::SetHiddenPrototype(bool value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001344 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001345 ENTER_V8(isolate);
kasper.lund212ac232008-07-16 07:07:30 +00001346 Utils::OpenHandle(this)->set_hidden_prototype(value);
1347}
1348
1349
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001350void FunctionTemplate::ReadOnlyPrototype() {
ager@chromium.org04921a82011-06-27 13:21:41 +00001351 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ager@chromium.org04921a82011-06-27 13:21:41 +00001352 ENTER_V8(isolate);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001353 Utils::OpenHandle(this)->set_read_only_prototype(true);
ager@chromium.org04921a82011-06-27 13:21:41 +00001354}
1355
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001356
1357void FunctionTemplate::RemovePrototype() {
1358 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001359 ENTER_V8(isolate);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001360 Utils::OpenHandle(this)->set_remove_prototype(true);
kasper.lund212ac232008-07-16 07:07:30 +00001361}
1362
1363
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001364// --- O b j e c t T e m p l a t e ---
1365
1366
1367Local<ObjectTemplate> ObjectTemplate::New() {
1368 return New(Local<FunctionTemplate>());
1369}
1370
1371
1372Local<ObjectTemplate> ObjectTemplate::New(
1373 v8::Handle<FunctionTemplate> constructor) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001374 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001375 EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
1376 LOG_API(isolate, "ObjectTemplate::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001377 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001378 i::Handle<i::Struct> struct_obj =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001379 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 i::Handle<i::ObjectTemplateInfo> obj =
1381 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1382 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1383 if (!constructor.IsEmpty())
1384 obj->set_constructor(*Utils::OpenHandle(*constructor));
kasper.lund212ac232008-07-16 07:07:30 +00001385 obj->set_internal_field_count(i::Smi::FromInt(0));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001386 return Utils::ToLocal(obj);
1387}
1388
1389
1390// Ensure that the object template has a constructor. If no
1391// constructor is available we create one.
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001392static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1393 ObjectTemplate* object_template) {
1394 i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1395 if (!obj ->IsUndefined()) {
1396 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1397 return i::Handle<i::FunctionTemplateInfo>(info, info->GetIsolate());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398 }
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001399 Local<FunctionTemplate> templ = FunctionTemplate::New();
1400 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1401 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1402 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1403 return constructor;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001404}
1405
1406
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001407static inline void AddPropertyToTemplate(
1408 i::Handle<i::TemplateInfo> info,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001409 i::Handle<i::AccessorInfo> obj) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001410 i::Handle<i::Object> list(info->property_accessors(), info->GetIsolate());
ulan@chromium.org750145a2013-03-07 15:14:13 +00001411 if (list->IsUndefined()) {
1412 list = NeanderArray().value();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001413 info->set_property_accessors(*list);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001414 }
1415 NeanderArray array(list);
1416 array.add(obj);
1417}
1418
1419
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001420static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1421 Template* template_obj) {
1422 return Utils::OpenHandle(template_obj);
1423}
1424
1425
1426// TODO(dcarney): remove this with ObjectTemplate::SetAccessor
1427static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1428 ObjectTemplate* object_template) {
1429 EnsureConstructor(object_template);
1430 return Utils::OpenHandle(object_template);
1431}
1432
1433
1434template<typename Setter, typename Getter, typename Data, typename Template>
1435static bool TemplateSetAccessor(
1436 Template* template_obj,
1437 v8::Local<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001438 Getter getter,
1439 Setter setter,
1440 Data data,
1441 AccessControl settings,
1442 PropertyAttribute attribute,
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001443 v8::Local<AccessorSignature> signature) {
1444 i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001445 ENTER_V8(isolate);
1446 i::HandleScope scope(isolate);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001447 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
1448 name, getter, setter, data, settings, attribute, signature);
1449 if (obj.is_null()) return false;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001450 i::Handle<i::TemplateInfo> info = GetTemplateInfo(template_obj);
1451 AddPropertyToTemplate(info, obj);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001452 return true;
1453}
1454
1455
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001456bool Template::SetDeclaredAccessor(
1457 Local<String> name,
1458 Local<DeclaredAccessorDescriptor> descriptor,
1459 PropertyAttribute attribute,
1460 Local<AccessorSignature> signature,
1461 AccessControl settings) {
1462 void* null = NULL;
1463 return TemplateSetAccessor(
1464 this, name, descriptor, null, null, settings, attribute, signature);
1465}
1466
1467
1468void Template::SetNativeDataProperty(v8::Local<String> name,
1469 AccessorGetterCallback getter,
1470 AccessorSetterCallback setter,
1471 v8::Handle<Value> data,
1472 PropertyAttribute attribute,
1473 v8::Local<AccessorSignature> signature,
1474 AccessControl settings) {
1475 TemplateSetAccessor(
1476 this, name, getter, setter, data, settings, attribute, signature);
1477}
1478
1479
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001480void ObjectTemplate::SetAccessor(v8::Handle<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001481 AccessorGetterCallback getter,
1482 AccessorSetterCallback setter,
1483 v8::Handle<Value> data,
1484 AccessControl settings,
1485 PropertyAttribute attribute,
1486 v8::Handle<AccessorSignature> signature) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001487 TemplateSetAccessor(
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001488 this, name, getter, setter, data, settings, attribute, signature);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001489}
1490
1491
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001492void ObjectTemplate::SetNamedPropertyHandler(
1493 NamedPropertyGetterCallback getter,
1494 NamedPropertySetterCallback setter,
1495 NamedPropertyQueryCallback query,
1496 NamedPropertyDeleterCallback remover,
1497 NamedPropertyEnumeratorCallback enumerator,
1498 Handle<Value> data) {
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001499 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001500 ENTER_V8(isolate);
1501 i::HandleScope scope(isolate);
1502 EnsureConstructor(this);
1503 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1504 Utils::OpenHandle(this)->constructor());
1505 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1506 i::Handle<i::Struct> struct_obj =
1507 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1508 i::Handle<i::InterceptorInfo> obj =
1509 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1510
1511 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1512 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1513 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1514 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1515 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1516
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001517 if (data.IsEmpty()) {
1518 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1519 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001520 obj->set_data(*Utils::OpenHandle(*data));
1521 cons->set_named_property_handler(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001522}
1523
1524
1525void ObjectTemplate::MarkAsUndetectable() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001526 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001527 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001528 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001529 EnsureConstructor(this);
1530 i::FunctionTemplateInfo* constructor =
1531 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1532 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1533 cons->set_undetectable(true);
1534}
1535
1536
1537void ObjectTemplate::SetAccessCheckCallbacks(
1538 NamedSecurityCallback named_callback,
1539 IndexedSecurityCallback indexed_callback,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001540 Handle<Value> data,
1541 bool turned_on_by_default) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001542 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001543 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001544 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001545 EnsureConstructor(this);
1546
1547 i::Handle<i::Struct> struct_info =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001548 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001549 i::Handle<i::AccessCheckInfo> info =
1550 i::Handle<i::AccessCheckInfo>::cast(struct_info);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001551
1552 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1553 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1554
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001555 if (data.IsEmpty()) {
1556 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1557 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001558 info->set_data(*Utils::OpenHandle(*data));
1559
1560 i::FunctionTemplateInfo* constructor =
1561 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1562 i::Handle<i::FunctionTemplateInfo> cons(constructor);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001563 cons->set_access_check_info(*info);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001564 cons->set_needs_access_check(turned_on_by_default);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001565}
1566
1567
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001568void ObjectTemplate::SetIndexedPropertyHandler(
1569 IndexedPropertyGetterCallback getter,
1570 IndexedPropertySetterCallback setter,
1571 IndexedPropertyQueryCallback query,
1572 IndexedPropertyDeleterCallback remover,
1573 IndexedPropertyEnumeratorCallback enumerator,
1574 Handle<Value> data) {
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001575 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001576 ENTER_V8(isolate);
1577 i::HandleScope scope(isolate);
1578 EnsureConstructor(this);
1579 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1580 Utils::OpenHandle(this)->constructor());
1581 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1582 i::Handle<i::Struct> struct_obj =
1583 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1584 i::Handle<i::InterceptorInfo> obj =
1585 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1586
1587 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1588 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1589 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1590 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1591 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1592
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001593 if (data.IsEmpty()) {
1594 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1595 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001596 obj->set_data(*Utils::OpenHandle(*data));
1597 cons->set_indexed_property_handler(*obj);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001598}
1599
1600
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001601void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1602 Handle<Value> data) {
1603 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001604 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001605 i::HandleScope scope(isolate);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001606 EnsureConstructor(this);
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001607 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001608 Utils::OpenHandle(this)->constructor());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609 i::Handle<i::FunctionTemplateInfo> cons(constructor);
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001610 i::Handle<i::Struct> struct_obj =
1611 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1612 i::Handle<i::CallHandlerInfo> obj =
1613 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1614 SET_FIELD_WRAPPED(obj, set_callback, callback);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001615 if (data.IsEmpty()) {
1616 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1617 }
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001618 obj->set_data(*Utils::OpenHandle(*data));
1619 cons->set_instance_call_handler(*obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620}
1621
1622
kasper.lund212ac232008-07-16 07:07:30 +00001623int ObjectTemplate::InternalFieldCount() {
kasper.lund212ac232008-07-16 07:07:30 +00001624 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625}
1626
1627
kasper.lund212ac232008-07-16 07:07:30 +00001628void ObjectTemplate::SetInternalFieldCount(int value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001629 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
kasper.lund212ac232008-07-16 07:07:30 +00001630 if (!ApiCheck(i::Smi::IsValid(value),
1631 "v8::ObjectTemplate::SetInternalFieldCount()",
1632 "Invalid internal field count")) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001633 return;
1634 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001635 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001636 if (value > 0) {
1637 // The internal field count is set by the constructor function's
1638 // construct code, so we ensure that there is a constructor
1639 // function to do the setting.
1640 EnsureConstructor(this);
1641 }
kasper.lund212ac232008-07-16 07:07:30 +00001642 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001643}
1644
1645
kasper.lund212ac232008-07-16 07:07:30 +00001646// --- S c r i p t D a t a ---
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001647
1648
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001649ScriptData* ScriptData::PreCompile(v8::Isolate* isolate,
1650 const char* input,
1651 int length) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001652 i::Utf8ToUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001653 reinterpret_cast<const unsigned char*>(input), length);
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001654 return i::PreParserApi::PreParse(
1655 reinterpret_cast<i::Isolate*>(isolate), &stream);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001656}
1657
1658
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001659ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
1660 i::Handle<i::String> str = Utils::OpenHandle(*source);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001661 i::Isolate* isolate = str->GetIsolate();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001662 if (str->IsExternalTwoByteString()) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001663 i::ExternalTwoByteStringUtf16CharacterStream stream(
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001664 i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001665 return i::PreParserApi::PreParse(isolate, &stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001666 } else {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00001667 i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001668 return i::PreParserApi::PreParse(isolate, &stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001669 }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001670}
1671
1672
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001673ScriptData* ScriptData::New(const char* data, int length) {
1674 // Return an empty ScriptData if the length is obviously invalid.
1675 if (length % sizeof(unsigned) != 0) {
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001676 return new i::ScriptDataImpl();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001677 }
1678
1679 // Copy the data to ensure it is properly aligned.
1680 int deserialized_data_length = length / sizeof(unsigned);
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00001681 // If aligned, don't create a copy of the data.
1682 if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
1683 return new i::ScriptDataImpl(data, length);
1684 }
1685 // Copy the data to align it.
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001686 unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001687 i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
1688 data, static_cast<size_t>(length));
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00001689
1690 return new i::ScriptDataImpl(
1691 i::Vector<unsigned>(deserialized_data, deserialized_data_length));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692}
1693
1694
1695// --- S c r i p t ---
1696
1697
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001698Local<Script> Script::New(v8::Handle<String> source,
1699 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001700 v8::ScriptData* pre_data,
1701 v8::Handle<String> script_data) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001702 i::Handle<i::String> str = Utils::OpenHandle(*source);
1703 i::Isolate* isolate = str->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001704 ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
1705 LOG_API(isolate, "Script::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001706 ENTER_V8(isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001707 i::SharedFunctionInfo* raw_result = NULL;
1708 { i::HandleScope scope(isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001709 i::Handle<i::Object> name_obj;
1710 int line_offset = 0;
1711 int column_offset = 0;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001712 bool is_shared_cross_origin = false;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001713 if (origin != NULL) {
1714 if (!origin->ResourceName().IsEmpty()) {
1715 name_obj = Utils::OpenHandle(*origin->ResourceName());
1716 }
1717 if (!origin->ResourceLineOffset().IsEmpty()) {
1718 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1719 }
1720 if (!origin->ResourceColumnOffset().IsEmpty()) {
1721 column_offset =
1722 static_cast<int>(origin->ResourceColumnOffset()->Value());
1723 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001724 if (!origin->ResourceIsSharedCrossOrigin().IsEmpty()) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001725 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001726 is_shared_cross_origin =
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001727 origin->ResourceIsSharedCrossOrigin() == v8::True(v8_isolate);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001728 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001729 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001730 EXCEPTION_PREAMBLE(isolate);
1731 i::ScriptDataImpl* pre_data_impl =
1732 static_cast<i::ScriptDataImpl*>(pre_data);
1733 // We assert that the pre-data is sane, even though we can actually
1734 // handle it if it turns out not to be in release mode.
1735 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
1736 // If the pre-data isn't sane we simply ignore it
1737 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1738 pre_data_impl = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001739 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001740 i::Handle<i::SharedFunctionInfo> result =
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001741 i::Compiler::Compile(str,
1742 name_obj,
1743 line_offset,
1744 column_offset,
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001745 is_shared_cross_origin,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001746 isolate->global_context(),
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001747 NULL,
1748 pre_data_impl,
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00001749 Utils::OpenHandle(*script_data, true),
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001750 i::NOT_NATIVES_CODE);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001751 has_pending_exception = result.is_null();
1752 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
1753 raw_result = *result;
1754 }
1755 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001756 return ToApiHandle<Script>(result);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001757}
1758
1759
1760Local<Script> Script::New(v8::Handle<String> source,
1761 v8::Handle<Value> file_name) {
1762 ScriptOrigin origin(file_name);
1763 return New(source, &origin);
1764}
1765
1766
1767Local<Script> Script::Compile(v8::Handle<String> source,
1768 v8::ScriptOrigin* origin,
ager@chromium.org5c838252010-02-19 08:53:10 +00001769 v8::ScriptData* pre_data,
1770 v8::Handle<String> script_data) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001771 i::Handle<i::String> str = Utils::OpenHandle(*source);
1772 i::Isolate* isolate = str->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001773 ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
1774 LOG_API(isolate, "Script::Compile");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001775 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00001776 Local<Script> generic = New(source, origin, pre_data, script_data);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001777 if (generic.IsEmpty())
1778 return generic;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001779 i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
1780 i::Handle<i::SharedFunctionInfo> function =
1781 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 i::Handle<i::JSFunction> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001783 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1784 function,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001785 isolate->global_context());
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001786 return ToApiHandle<Script>(result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787}
1788
1789
mads.s.agercbaa0602008-08-14 13:41:48 +00001790Local<Script> Script::Compile(v8::Handle<String> source,
ager@chromium.org5c838252010-02-19 08:53:10 +00001791 v8::Handle<Value> file_name,
1792 v8::Handle<String> script_data) {
mads.s.agercbaa0602008-08-14 13:41:48 +00001793 ScriptOrigin origin(file_name);
ager@chromium.org5c838252010-02-19 08:53:10 +00001794 return Compile(source, &origin, 0, script_data);
mads.s.agercbaa0602008-08-14 13:41:48 +00001795}
1796
1797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798Local<Value> Script::Run() {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001799 // If execution is terminating, Compile(script)->Run() requires this check.
1800 if (this == NULL) return Local<Value>();
1801 i::Handle<i::HeapObject> obj =
1802 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1803 i::Isolate* isolate = obj->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001804 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1805 LOG_API(isolate, "Script::Run");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001806 ENTER_V8(isolate);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001807 i::Logger::TimerEventScope timer_scope(
danno@chromium.org1f34ad32012-11-26 14:53:56 +00001808 isolate, i::Logger::TimerEventScope::v8_execute);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001809 i::Object* raw_result = NULL;
1810 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001811 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001812 i::Handle<i::JSFunction> fun;
1813 if (obj->IsSharedFunctionInfo()) {
1814 i::Handle<i::SharedFunctionInfo>
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001815 function_info(i::SharedFunctionInfo::cast(*obj), isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001817 function_info, isolate->global_context());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001818 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001819 fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001820 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001821 EXCEPTION_PREAMBLE(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 i::Handle<i::Object> receiver(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001823 isolate->context()->global_proxy(), isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00001824 i::Handle<i::Object> result = i::Execution::Call(
1825 isolate, fun, receiver, 0, NULL, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00001826 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001827 raw_result = *result;
1828 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001829 i::Handle<i::Object> result(raw_result, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830 return Utils::ToLocal(result);
1831}
1832
1833
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001834static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) {
1835 i::Handle<i::Object> obj = Utils::OpenHandle(script);
1836 i::Handle<i::SharedFunctionInfo> result;
1837 if (obj->IsSharedFunctionInfo()) {
1838 result =
1839 i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
1840 } else {
1841 result =
1842 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared());
1843 }
1844 return result;
1845}
1846
1847
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001848Local<Value> Script::Id() {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001849 i::Handle<i::HeapObject> obj =
1850 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1851 i::Isolate* isolate = obj->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001852 ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
1853 LOG_API(isolate, "Script::Id");
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001854 i::Object* raw_id = NULL;
1855 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001856 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001857 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1858 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00001859 i::Handle<i::Object> id(script->id(), isolate);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001860 raw_id = *id;
1861 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00001862 i::Handle<i::Object> id(raw_id, isolate);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001863 return Utils::ToLocal(id);
1864}
1865
1866
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001867int Script::GetId() {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001868 i::Handle<i::HeapObject> obj =
1869 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1870 i::Isolate* isolate = obj->GetIsolate();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001871 ON_BAILOUT(isolate, "v8::Script::Id()", return -1);
1872 LOG_API(isolate, "Script::Id");
1873 {
1874 i::HandleScope scope(isolate);
1875 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
1876 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1877 return script->id()->value();
1878 }
1879}
1880
1881
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001882int Script::GetLineNumber(int code_pos) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001883 i::Handle<i::HeapObject> obj =
1884 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1885 i::Isolate* isolate = obj->GetIsolate();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001886 ON_BAILOUT(isolate, "v8::Script::GetLineNumber()", return -1);
1887 LOG_API(isolate, "Script::GetLineNumber");
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001888 if (obj->IsScript()) {
1889 i::Handle<i::Script> script = i::Handle<i::Script>(i::Script::cast(*obj));
1890 return i::GetScriptLineNumber(script, code_pos);
1891 } else {
1892 return -1;
1893 }
1894}
1895
1896
1897Handle<Value> Script::GetScriptName() {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001898 i::Handle<i::HeapObject> obj =
1899 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1900 i::Isolate* isolate = obj->GetIsolate();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001901 ON_BAILOUT(isolate, "v8::Script::GetName()", return Handle<String>());
1902 LOG_API(isolate, "Script::GetName");
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001903 if (obj->IsScript()) {
1904 i::Object* name = i::Script::cast(*obj)->name();
1905 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1906 } else {
1907 return Handle<String>();
1908 }
1909}
1910
1911
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00001912void Script::SetData(v8::Handle<String> data) {
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +00001913 i::Handle<i::HeapObject> obj =
1914 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1915 i::Isolate* isolate = obj->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001916 ON_BAILOUT(isolate, "v8::Script::SetData()", return);
1917 LOG_API(isolate, "Script::SetData");
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001918 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001919 i::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001920 i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001921 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001922 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001923 script->set_data(*raw_data);
1924 }
1925}
1926
1927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928// --- E x c e p t i o n s ---
1929
1930
1931v8::TryCatch::TryCatch()
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001932 : isolate_(i::Isolate::Current()),
1933 next_(isolate_->try_catch_handler_address()),
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001934 is_verbose_(false),
ager@chromium.org68e7ab72009-09-23 09:40:39 +00001935 can_continue_(true),
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001936 capture_message_(true),
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001937 rethrow_(false),
1938 has_terminated_(false) {
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001939 Reset();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001940 isolate_->RegisterTryCatchHandler(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001941}
1942
1943
1944v8::TryCatch::~TryCatch() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001945 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001946 if (rethrow_) {
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001947 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
1948 v8::HandleScope scope(isolate);
1949 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001950 if (HasCaught() && capture_message_) {
1951 // If an exception was caught and rethrow_ is indicated, the saved
1952 // message, script, and location need to be restored to Isolate TLS
1953 // for reuse. capture_message_ needs to be disabled so that DoThrow()
1954 // does not create a new message.
1955 isolate_->thread_local_top()->rethrowing_message_ = true;
1956 isolate_->RestorePendingMessageFromTryCatch(this);
1957 }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001958 isolate_->UnregisterTryCatchHandler(this);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001959 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00001960 ASSERT(!isolate_->thread_local_top()->rethrowing_message_);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001961 } else {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001962 isolate_->UnregisterTryCatchHandler(this);
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001963 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001964}
1965
1966
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001967bool v8::TryCatch::HasCaught() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001968 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1969}
1970
1971
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001972bool v8::TryCatch::CanContinue() const {
1973 return can_continue_;
1974}
1975
1976
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001977bool v8::TryCatch::HasTerminated() const {
1978 return has_terminated_;
1979}
1980
1981
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001982v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1983 if (!HasCaught()) return v8::Local<v8::Value>();
1984 rethrow_ = true;
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00001985 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
christian.plesner.hansen@gmail.comb9ce6372009-11-03 11:38:18 +00001986}
1987
1988
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001989v8::Local<Value> v8::TryCatch::Exception() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001990 ASSERT(isolate_ == i::Isolate::Current());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001991 if (HasCaught()) {
1992 // Check for out of memory exception.
1993 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001994 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995 } else {
1996 return v8::Local<Value>();
1997 }
1998}
1999
2000
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002001v8::Local<Value> v8::TryCatch::StackTrace() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002002 ASSERT(isolate_ == i::Isolate::Current());
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002003 if (HasCaught()) {
2004 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
2005 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002006 i::HandleScope scope(isolate_);
2007 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002008 i::Handle<i::String> name = isolate_->factory()->stack_string();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00002009 if (!i::JSReceiver::HasProperty(obj, name)) return v8::Local<Value>();
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002010 i::Handle<i::Object> value = i::GetProperty(isolate_, obj, name);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002011 if (value.is_null()) return v8::Local<Value>();
2012 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002013 } else {
2014 return v8::Local<Value>();
2015 }
2016}
2017
2018
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002019v8::Local<v8::Message> v8::TryCatch::Message() const {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002020 ASSERT(isolate_ == i::Isolate::Current());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00002021 i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2022 ASSERT(message->IsJSMessageObject() || message->IsTheHole());
2023 if (HasCaught() && !message->IsTheHole()) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002024 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002025 } else {
2026 return v8::Local<v8::Message>();
2027 }
2028}
2029
2030
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002031void v8::TryCatch::Reset() {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002032 ASSERT(isolate_ == i::Isolate::Current());
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00002033 i::Object* the_hole = isolate_->heap()->the_hole_value();
2034 exception_ = the_hole;
2035 message_obj_ = the_hole;
2036 message_script_ = the_hole;
2037 message_start_pos_ = 0;
2038 message_end_pos_ = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002039}
2040
2041
2042void v8::TryCatch::SetVerbose(bool value) {
2043 is_verbose_ = value;
2044}
2045
2046
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002047void v8::TryCatch::SetCaptureMessage(bool value) {
2048 capture_message_ = value;
2049}
2050
2051
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002052// --- M e s s a g e ---
2053
2054
ager@chromium.org32912102009-01-16 10:38:43 +00002055Local<String> Message::Get() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002056 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002057 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002058 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002059 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002060 i::Handle<i::Object> obj = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002061 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002062 Local<String> result = Utils::ToLocal(raw_result);
2063 return scope.Close(result);
2064}
2065
2066
ager@chromium.org32912102009-01-16 10:38:43 +00002067v8::Handle<Value> Message::GetScriptResourceName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002068 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002069 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002070 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002071 i::Handle<i::JSMessageObject> message =
2072 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002073 // Return this.script.name.
2074 i::Handle<i::JSValue> script =
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002075 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2076 isolate));
2077 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name(),
2078 isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002079 return scope.Close(Utils::ToLocal(resource_name));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002080}
2081
2082
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002083v8::Handle<Value> Message::GetScriptData() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002084 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002085 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002086 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002087 i::Handle<i::JSMessageObject> message =
2088 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002089 // Return this.script.data.
2090 i::Handle<i::JSValue> script =
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002091 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2092 isolate));
2093 i::Handle<i::Object> data(i::Script::cast(script->value())->data(), isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002094 return scope.Close(Utils::ToLocal(data));
2095}
2096
2097
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002098v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002099 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002100 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002101 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002102 i::Handle<i::JSMessageObject> message =
2103 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002104 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002105 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
2106 i::Handle<i::JSArray> stackTrace =
2107 i::Handle<i::JSArray>::cast(stackFramesObj);
2108 return scope.Close(Utils::StackTraceToLocal(stackTrace));
2109}
2110
2111
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112static i::Handle<i::Object> CallV8HeapFunction(const char* name,
2113 i::Handle<i::Object> recv,
2114 int argc,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002115 i::Handle<i::Object> argv[],
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002116 bool* has_pending_exception) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002117 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002118 i::Handle<i::String> fmt_str =
2119 isolate->factory()->InternalizeUtf8String(name);
lrn@chromium.org303ada72010-10-27 09:33:13 +00002120 i::Object* object_fun =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002121 isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122 i::Handle<i::JSFunction> fun =
2123 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00002124 i::Handle<i::Object> value = i::Execution::Call(
2125 isolate, fun, recv, argc, argv, has_pending_exception);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002126 return value;
2127}
2128
2129
2130static i::Handle<i::Object> CallV8HeapFunction(const char* name,
2131 i::Handle<i::Object> data,
2132 bool* has_pending_exception) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002133 i::Handle<i::Object> argv[] = { data };
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134 return CallV8HeapFunction(name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002135 i::Isolate::Current()->js_builtins_object(),
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00002136 ARRAY_SIZE(argv),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137 argv,
2138 has_pending_exception);
2139}
2140
2141
ager@chromium.org32912102009-01-16 10:38:43 +00002142int Message::GetLineNumber() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002143 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002144 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002145 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002146 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002147
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002148 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
2150 Utils::OpenHandle(this),
2151 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002152 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153 return static_cast<int>(result->Number());
2154}
2155
2156
ager@chromium.org32912102009-01-16 10:38:43 +00002157int Message::GetStartPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002158 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002159 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002160 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002161 i::Handle<i::JSMessageObject> message =
2162 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2163 return message->start_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002164}
2165
2166
ager@chromium.org32912102009-01-16 10:38:43 +00002167int Message::GetEndPosition() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002168 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002169 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002170 i::HandleScope scope(isolate);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002171 i::Handle<i::JSMessageObject> message =
2172 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2173 return message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002174}
2175
2176
ager@chromium.org32912102009-01-16 10:38:43 +00002177int Message::GetStartColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002178 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002179 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002180 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002181 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002182 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002183 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
2184 "GetPositionInLine",
2185 data_obj,
2186 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002187 EXCEPTION_BAILOUT_CHECK(isolate, 0);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002188 return static_cast<int>(start_col_obj->Number());
2189}
2190
2191
ager@chromium.org32912102009-01-16 10:38:43 +00002192int Message::GetEndColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002193 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002194 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002195 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002196 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002197 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002198 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
2199 "GetPositionInLine",
2200 data_obj,
2201 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002202 EXCEPTION_BAILOUT_CHECK(isolate, 0);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002203 i::Handle<i::JSMessageObject> message =
2204 i::Handle<i::JSMessageObject>::cast(data_obj);
2205 int start = message->start_position();
2206 int end = message->end_position();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002207 return static_cast<int>(start_col_obj->Number()) + (end - start);
2208}
2209
2210
danno@chromium.orgd3c42102013-08-01 16:58:23 +00002211bool Message::IsSharedCrossOrigin() const {
2212 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
danno@chromium.orgd3c42102013-08-01 16:58:23 +00002213 ENTER_V8(isolate);
2214 i::HandleScope scope(isolate);
2215 i::Handle<i::JSMessageObject> message =
2216 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2217 i::Handle<i::JSValue> script =
2218 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2219 isolate));
2220 return i::Script::cast(script->value())->is_shared_cross_origin();
2221}
2222
2223
ager@chromium.org32912102009-01-16 10:38:43 +00002224Local<String> Message::GetSourceLine() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002225 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002226 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002227 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002228 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002229 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002230 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
2231 Utils::OpenHandle(this),
2232 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002233 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002234 if (result->IsString()) {
2235 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
2236 } else {
2237 return Local<String>();
2238 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239}
2240
2241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242void Message::PrintCurrentStackTrace(FILE* out) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002243 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002244 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002245 isolate->PrintCurrentStackTrace(out);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002246}
2247
2248
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002249// --- S t a c k T r a c e ---
2250
2251Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002252 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002253 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002254 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002255 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00002256 i::Object* raw_object = self->GetElementNoExceptionThrown(isolate, index);
lrn@chromium.org303ada72010-10-27 09:33:13 +00002257 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002258 return scope.Close(Utils::StackFrameToLocal(obj));
2259}
2260
2261
2262int StackTrace::GetFrameCount() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002263 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002264 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002265 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2266}
2267
2268
2269Local<Array> StackTrace::AsArray() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002270 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002271 ENTER_V8(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002272 return Utils::ToLocal(Utils::OpenHandle(this));
2273}
2274
2275
2276Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
2277 StackTraceOptions options) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002278 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002279 ENTER_V8(isolate);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002280 i::Handle<i::JSArray> stackTrace =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002281 isolate->CaptureCurrentStackTrace(frame_limit, options);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002282 return Utils::StackTraceToLocal(stackTrace);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002283}
2284
2285
2286// --- S t a c k F r a m e ---
2287
2288int StackFrame::GetLineNumber() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002289 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002290 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002291 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002292 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2293 i::Handle<i::Object> line = GetProperty(self, "lineNumber");
2294 if (!line->IsSmi()) {
2295 return Message::kNoLineNumberInfo;
2296 }
2297 return i::Smi::cast(*line)->value();
2298}
2299
2300
2301int StackFrame::GetColumn() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002302 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002303 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002304 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002305 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2306 i::Handle<i::Object> column = GetProperty(self, "column");
2307 if (!column->IsSmi()) {
2308 return Message::kNoColumnInfo;
2309 }
2310 return i::Smi::cast(*column)->value();
2311}
2312
2313
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00002314int StackFrame::GetScriptId() const {
2315 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00002316 ENTER_V8(isolate);
2317 i::HandleScope scope(isolate);
2318 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2319 i::Handle<i::Object> scriptId = GetProperty(self, "scriptId");
2320 if (!scriptId->IsSmi()) {
2321 return Message::kNoScriptIdInfo;
2322 }
2323 return i::Smi::cast(*scriptId)->value();
2324}
2325
2326
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002327Local<String> StackFrame::GetScriptName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002328 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002329 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002330 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002331 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2332 i::Handle<i::Object> name = GetProperty(self, "scriptName");
2333 if (!name->IsString()) {
2334 return Local<String>();
2335 }
2336 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2337}
2338
2339
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002340Local<String> StackFrame::GetScriptNameOrSourceURL() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002341 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002342 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002343 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002344 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2345 i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
2346 if (!name->IsString()) {
2347 return Local<String>();
2348 }
2349 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2350}
2351
2352
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002353Local<String> StackFrame::GetFunctionName() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002354 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002355 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00002356 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002357 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2358 i::Handle<i::Object> name = GetProperty(self, "functionName");
2359 if (!name->IsString()) {
2360 return Local<String>();
2361 }
2362 return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
2363}
2364
2365
2366bool StackFrame::IsEval() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002367 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002368 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002369 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002370 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2371 i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
2372 return is_eval->IsTrue();
2373}
2374
2375
2376bool StackFrame::IsConstructor() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002377 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002378 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002379 i::HandleScope scope(isolate);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002380 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2381 i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
2382 return is_constructor->IsTrue();
2383}
2384
2385
danno@chromium.org59400602013-08-13 17:09:37 +00002386// --- J S O N ---
2387
2388Local<Value> JSON::Parse(Local<String> json_string) {
2389 i::Isolate* isolate = i::Isolate::Current();
2390 EnsureInitializedForIsolate(isolate, "v8::JSON::Parse");
2391 ENTER_V8(isolate);
2392 i::HandleScope scope(isolate);
2393 i::Handle<i::String> source = i::Handle<i::String>(
2394 FlattenGetString(Utils::OpenHandle(*json_string)));
2395 EXCEPTION_PREAMBLE(isolate);
2396 i::Handle<i::Object> result;
2397 if (source->IsSeqOneByteString()) {
2398 result = i::JsonParser<true>::Parse(source);
2399 } else {
2400 result = i::JsonParser<false>::Parse(source);
2401 }
2402 has_pending_exception = result.is_null();
2403 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
2404 return Utils::ToLocal(
2405 i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
2406}
2407
2408
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002409// --- D a t a ---
2410
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002411bool Value::FullIsUndefined() const {
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002412 bool result = Utils::OpenHandle(this)->IsUndefined();
2413 ASSERT_EQ(result, QuickIsUndefined());
2414 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002415}
2416
2417
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002418bool Value::FullIsNull() const {
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002419 bool result = Utils::OpenHandle(this)->IsNull();
2420 ASSERT_EQ(result, QuickIsNull());
2421 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002422}
2423
2424
ager@chromium.org32912102009-01-16 10:38:43 +00002425bool Value::IsTrue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002426 return Utils::OpenHandle(this)->IsTrue();
2427}
2428
2429
ager@chromium.org32912102009-01-16 10:38:43 +00002430bool Value::IsFalse() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002431 return Utils::OpenHandle(this)->IsFalse();
2432}
2433
2434
ager@chromium.org32912102009-01-16 10:38:43 +00002435bool Value::IsFunction() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002436 return Utils::OpenHandle(this)->IsJSFunction();
2437}
2438
2439
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002440bool Value::FullIsString() const {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002441 bool result = Utils::OpenHandle(this)->IsString();
2442 ASSERT_EQ(result, QuickIsString());
2443 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002444}
2445
2446
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002447bool Value::IsSymbol() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002448 return Utils::OpenHandle(this)->IsSymbol();
2449}
2450
2451
ager@chromium.org32912102009-01-16 10:38:43 +00002452bool Value::IsArray() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453 return Utils::OpenHandle(this)->IsJSArray();
2454}
2455
2456
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002457bool Value::IsArrayBuffer() const {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002458 return Utils::OpenHandle(this)->IsJSArrayBuffer();
2459}
2460
2461
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002462bool Value::IsArrayBufferView() const {
2463 return Utils::OpenHandle(this)->IsJSArrayBufferView();
2464}
2465
2466
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002467bool Value::IsTypedArray() const {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002468 return Utils::OpenHandle(this)->IsJSTypedArray();
2469}
2470
2471
2472#define TYPED_ARRAY_LIST(F) \
2473F(Uint8Array, kExternalUnsignedByteArray) \
2474F(Int8Array, kExternalByteArray) \
2475F(Uint16Array, kExternalUnsignedShortArray) \
2476F(Int16Array, kExternalShortArray) \
2477F(Uint32Array, kExternalUnsignedIntArray) \
2478F(Int32Array, kExternalIntArray) \
2479F(Float32Array, kExternalFloatArray) \
2480F(Float64Array, kExternalDoubleArray) \
2481F(Uint8ClampedArray, kExternalPixelArray)
2482
2483
2484#define VALUE_IS_TYPED_ARRAY(TypedArray, type_const) \
2485 bool Value::Is##TypedArray() const { \
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002486 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2487 if (!obj->IsJSTypedArray()) return false; \
2488 return i::JSTypedArray::cast(*obj)->type() == type_const; \
2489 }
2490
2491TYPED_ARRAY_LIST(VALUE_IS_TYPED_ARRAY)
2492
2493#undef VALUE_IS_TYPED_ARRAY
2494
2495
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002496bool Value::IsDataView() const {
2497 return Utils::OpenHandle(this)->IsJSDataView();
2498}
2499
2500
ager@chromium.org32912102009-01-16 10:38:43 +00002501bool Value::IsObject() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002502 return Utils::OpenHandle(this)->IsJSObject();
2503}
2504
2505
ager@chromium.org32912102009-01-16 10:38:43 +00002506bool Value::IsNumber() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002507 return Utils::OpenHandle(this)->IsNumber();
2508}
2509
2510
ager@chromium.org32912102009-01-16 10:38:43 +00002511bool Value::IsBoolean() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002512 return Utils::OpenHandle(this)->IsBoolean();
2513}
2514
2515
ager@chromium.org32912102009-01-16 10:38:43 +00002516bool Value::IsExternal() const {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002517 return Utils::OpenHandle(this)->IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002518}
2519
2520
ager@chromium.org32912102009-01-16 10:38:43 +00002521bool Value::IsInt32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002522 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2523 if (obj->IsSmi()) return true;
2524 if (obj->IsNumber()) {
2525 double value = obj->Number();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002526 static const i::DoubleRepresentation minus_zero(-0.0);
2527 i::DoubleRepresentation rep(value);
2528 if (rep.bits == minus_zero.bits) {
2529 return false;
2530 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002531 return i::FastI2D(i::FastD2I(value)) == value;
2532 }
2533 return false;
2534}
2535
2536
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002537bool Value::IsUint32() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002538 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2539 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2540 if (obj->IsNumber()) {
2541 double value = obj->Number();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002542 static const i::DoubleRepresentation minus_zero(-0.0);
2543 i::DoubleRepresentation rep(value);
2544 if (rep.bits == minus_zero.bits) {
2545 return false;
2546 }
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002547 return i::FastUI2D(i::FastD2UI(value)) == value;
2548 }
2549 return false;
2550}
2551
2552
ager@chromium.org32912102009-01-16 10:38:43 +00002553bool Value::IsDate() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002554 i::Isolate* isolate = i::Isolate::Current();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002555 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002556 return obj->HasSpecificClassOf(isolate->heap()->Date_string());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002557}
2558
2559
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002560bool Value::IsStringObject() const {
2561 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002562 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002563 return obj->HasSpecificClassOf(isolate->heap()->String_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002564}
2565
2566
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002567bool Value::IsSymbolObject() const {
2568 // TODO(svenpanne): these and other test functions should be written such
2569 // that they do not use Isolate::Current().
2570 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002571 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2572 return obj->HasSpecificClassOf(isolate->heap()->Symbol_string());
2573}
2574
2575
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002576bool Value::IsNumberObject() const {
2577 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002578 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002579 return obj->HasSpecificClassOf(isolate->heap()->Number_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002580}
2581
2582
2583static i::Object* LookupBuiltin(i::Isolate* isolate,
2584 const char* builtin_name) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002585 i::Handle<i::String> string =
2586 isolate->factory()->InternalizeUtf8String(builtin_name);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002587 i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002588 return builtins->GetPropertyNoExceptionThrown(*string);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002589}
2590
2591
2592static bool CheckConstructor(i::Isolate* isolate,
2593 i::Handle<i::JSObject> obj,
2594 const char* class_name) {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002595 i::Object* constr = obj->map()->constructor();
2596 if (!constr->IsJSFunction()) return false;
2597 i::JSFunction* func = i::JSFunction::cast(constr);
2598 return func->shared()->native() &&
2599 constr == LookupBuiltin(isolate, class_name);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002600}
2601
2602
2603bool Value::IsNativeError() const {
2604 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002605 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2606 if (obj->IsJSObject()) {
2607 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
2608 return CheckConstructor(isolate, js_obj, "$Error") ||
2609 CheckConstructor(isolate, js_obj, "$EvalError") ||
2610 CheckConstructor(isolate, js_obj, "$RangeError") ||
2611 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2612 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2613 CheckConstructor(isolate, js_obj, "$TypeError") ||
2614 CheckConstructor(isolate, js_obj, "$URIError");
2615 } else {
2616 return false;
2617 }
2618}
2619
2620
2621bool Value::IsBooleanObject() const {
2622 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002623 i::Handle<i::Object> obj = Utils::OpenHandle(this);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002624 return obj->HasSpecificClassOf(isolate->heap()->Boolean_string());
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002625}
2626
2627
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002628bool Value::IsRegExp() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002629 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2630 return obj->IsJSRegExp();
2631}
2632
2633
ager@chromium.org32912102009-01-16 10:38:43 +00002634Local<String> Value::ToString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002635 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2636 i::Handle<i::Object> str;
2637 if (obj->IsString()) {
2638 str = obj;
2639 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002640 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002641 LOG_API(isolate, "ToString");
2642 ENTER_V8(isolate);
2643 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002644 str = i::Execution::ToString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002645 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002646 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002647 return ToApiHandle<String>(str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002648}
2649
2650
ager@chromium.org32912102009-01-16 10:38:43 +00002651Local<String> Value::ToDetailString() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002652 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2653 i::Handle<i::Object> str;
2654 if (obj->IsString()) {
2655 str = 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, "ToDetailString");
2659 ENTER_V8(isolate);
2660 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002661 str = i::Execution::ToDetailString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002662 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002663 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002664 return ToApiHandle<String>(str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665}
2666
2667
ager@chromium.org32912102009-01-16 10:38:43 +00002668Local<v8::Object> Value::ToObject() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002669 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2670 i::Handle<i::Object> val;
2671 if (obj->IsJSObject()) {
2672 val = 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, "ToObject");
2676 ENTER_V8(isolate);
2677 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002678 val = i::Execution::ToObject(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002679 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002680 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002681 return ToApiHandle<Object>(val);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002682}
2683
2684
ager@chromium.org32912102009-01-16 10:38:43 +00002685Local<Boolean> Value::ToBoolean() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002686 i::Handle<i::Object> obj = Utils::OpenHandle(this);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002687 if (obj->IsBoolean()) {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002688 return ToApiHandle<Boolean>(obj);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002689 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002690 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002691 LOG_API(isolate, "ToBoolean");
2692 ENTER_V8(isolate);
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +00002693 i::Handle<i::Object> val =
2694 isolate->factory()->ToBoolean(obj->BooleanValue());
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002695 return ToApiHandle<Boolean>(val);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00002696 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002697}
2698
2699
ager@chromium.org32912102009-01-16 10:38:43 +00002700Local<Number> Value::ToNumber() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002701 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2702 i::Handle<i::Object> num;
2703 if (obj->IsNumber()) {
2704 num = obj;
2705 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002706 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002707 LOG_API(isolate, "ToNumber");
2708 ENTER_V8(isolate);
2709 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002710 num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002711 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002712 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002713 return ToApiHandle<Number>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002714}
2715
2716
ager@chromium.org32912102009-01-16 10:38:43 +00002717Local<Integer> Value::ToInteger() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002718 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2719 i::Handle<i::Object> num;
2720 if (obj->IsSmi()) {
2721 num = obj;
2722 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002723 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002724 LOG_API(isolate, "ToInteger");
2725 ENTER_V8(isolate);
2726 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002727 num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002728 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002729 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002730 return ToApiHandle<Integer>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002731}
2732
2733
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00002734void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002735 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002736 ApiCheck(isolate != NULL && isolate->IsInitialized() && !isolate->IsDead(),
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002737 "v8::internal::Internals::CheckInitialized()",
2738 "Isolate is not initialized or V8 has died");
2739}
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002740
2741
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002742void External::CheckCast(v8::Value* that) {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00002743 ApiCheck(Utils::OpenHandle(that)->IsExternal(),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002744 "v8::External::Cast()",
2745 "Could not convert to external");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002746}
2747
2748
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002749void v8::Object::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002750 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2751 ApiCheck(obj->IsJSObject(),
2752 "v8::Object::Cast()",
2753 "Could not convert to object");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754}
2755
2756
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002757void v8::Function::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002758 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2759 ApiCheck(obj->IsJSFunction(),
2760 "v8::Function::Cast()",
2761 "Could not convert to function");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002762}
2763
2764
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002765void v8::String::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2767 ApiCheck(obj->IsString(),
2768 "v8::String::Cast()",
2769 "Could not convert to string");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002770}
2771
2772
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002773void v8::Symbol::CheckCast(v8::Value* that) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002774 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2775 ApiCheck(obj->IsSymbol(),
2776 "v8::Symbol::Cast()",
2777 "Could not convert to symbol");
2778}
2779
2780
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002781void v8::Number::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002782 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2783 ApiCheck(obj->IsNumber(),
2784 "v8::Number::Cast()",
2785 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786}
2787
2788
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002789void v8::Integer::CheckCast(v8::Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002790 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2791 ApiCheck(obj->IsNumber(),
2792 "v8::Integer::Cast()",
2793 "Could not convert to number");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002794}
2795
2796
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002797void v8::Array::CheckCast(Value* that) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002798 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2799 ApiCheck(obj->IsJSArray(),
2800 "v8::Array::Cast()",
2801 "Could not convert to array");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802}
2803
2804
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002805void v8::ArrayBuffer::CheckCast(Value* that) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002806 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2807 ApiCheck(obj->IsJSArrayBuffer(),
2808 "v8::ArrayBuffer::Cast()",
2809 "Could not convert to ArrayBuffer");
2810}
2811
2812
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002813void v8::ArrayBufferView::CheckCast(Value* that) {
2814 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2815 ApiCheck(obj->IsJSArrayBufferView(),
2816 "v8::ArrayBufferView::Cast()",
2817 "Could not convert to ArrayBufferView");
2818}
2819
2820
danno@chromium.orgf005df62013-04-30 16:36:45 +00002821void v8::TypedArray::CheckCast(Value* that) {
danno@chromium.orgf005df62013-04-30 16:36:45 +00002822 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2823 ApiCheck(obj->IsJSTypedArray(),
2824 "v8::TypedArray::Cast()",
2825 "Could not convert to TypedArray");
2826}
2827
2828
2829#define CHECK_TYPED_ARRAY_CAST(ApiClass, typeConst) \
2830 void v8::ApiClass::CheckCast(Value* that) { \
danno@chromium.orgf005df62013-04-30 16:36:45 +00002831 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
2832 ApiCheck(obj->IsJSTypedArray() && \
2833 i::JSTypedArray::cast(*obj)->type() == typeConst, \
2834 "v8::" #ApiClass "::Cast()", \
2835 "Could not convert to " #ApiClass); \
2836 }
2837
2838
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002839TYPED_ARRAY_LIST(CHECK_TYPED_ARRAY_CAST)
danno@chromium.orgf005df62013-04-30 16:36:45 +00002840
2841#undef CHECK_TYPED_ARRAY_CAST
2842
2843
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002844void v8::DataView::CheckCast(Value* that) {
2845 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2846 ApiCheck(obj->IsJSDataView(),
2847 "v8::DataView::Cast()",
2848 "Could not convert to DataView");
2849}
2850
2851
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002852void v8::Date::CheckCast(v8::Value* that) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002853 i::Isolate* isolate = i::Isolate::Current();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002854 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002855 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_string()),
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002856 "v8::Date::Cast()",
2857 "Could not convert to date");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002858}
2859
2860
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002861void v8::StringObject::CheckCast(v8::Value* that) {
2862 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002863 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002864 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002865 "v8::StringObject::Cast()",
2866 "Could not convert to StringObject");
2867}
2868
2869
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002870void v8::SymbolObject::CheckCast(v8::Value* that) {
2871 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002872 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2873 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
2874 "v8::SymbolObject::Cast()",
2875 "Could not convert to SymbolObject");
2876}
2877
2878
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002879void v8::NumberObject::CheckCast(v8::Value* that) {
2880 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002881 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002882 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002883 "v8::NumberObject::Cast()",
2884 "Could not convert to NumberObject");
2885}
2886
2887
2888void v8::BooleanObject::CheckCast(v8::Value* that) {
2889 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002890 i::Handle<i::Object> obj = Utils::OpenHandle(that);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002891 ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00002892 "v8::BooleanObject::Cast()",
2893 "Could not convert to BooleanObject");
2894}
2895
2896
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002897void v8::RegExp::CheckCast(v8::Value* that) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002898 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2899 ApiCheck(obj->IsJSRegExp(),
2900 "v8::RegExp::Cast()",
2901 "Could not convert to regular expression");
2902}
2903
2904
ager@chromium.org32912102009-01-16 10:38:43 +00002905bool Value::BooleanValue() const {
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +00002906 return Utils::OpenHandle(this)->BooleanValue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002907}
2908
2909
ager@chromium.org32912102009-01-16 10:38:43 +00002910double Value::NumberValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002911 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2912 i::Handle<i::Object> num;
2913 if (obj->IsNumber()) {
2914 num = obj;
2915 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002916 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002917 LOG_API(isolate, "NumberValue");
2918 ENTER_V8(isolate);
2919 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002920 num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002921 EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002922 }
2923 return num->Number();
2924}
2925
2926
ager@chromium.org32912102009-01-16 10:38:43 +00002927int64_t Value::IntegerValue() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002928 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2929 i::Handle<i::Object> num;
2930 if (obj->IsNumber()) {
2931 num = obj;
2932 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002933 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002934 LOG_API(isolate, "IntegerValue");
2935 ENTER_V8(isolate);
2936 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002937 num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002938 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002939 }
2940 if (num->IsSmi()) {
2941 return i::Smi::cast(*num)->value();
2942 } else {
2943 return static_cast<int64_t>(num->Number());
2944 }
2945}
2946
2947
ager@chromium.org32912102009-01-16 10:38:43 +00002948Local<Int32> Value::ToInt32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002949 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2950 i::Handle<i::Object> num;
2951 if (obj->IsSmi()) {
2952 num = obj;
2953 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002954 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002955 LOG_API(isolate, "ToInt32");
2956 ENTER_V8(isolate);
2957 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002958 num = i::Execution::ToInt32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002959 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002960 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002961 return ToApiHandle<Int32>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002962}
2963
2964
ager@chromium.org32912102009-01-16 10:38:43 +00002965Local<Uint32> Value::ToUint32() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002966 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2967 i::Handle<i::Object> num;
2968 if (obj->IsSmi()) {
2969 num = obj;
2970 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002971 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002972 LOG_API(isolate, "ToUInt32");
2973 ENTER_V8(isolate);
2974 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002975 num = i::Execution::ToUint32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002976 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002977 }
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00002978 return ToApiHandle<Uint32>(num);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002979}
2980
2981
ager@chromium.org32912102009-01-16 10:38:43 +00002982Local<Uint32> Value::ToArrayIndex() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002983 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2984 if (obj->IsSmi()) {
2985 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2986 return Local<Uint32>();
2987 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002988 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002989 LOG_API(isolate, "ToArrayIndex");
2990 ENTER_V8(isolate);
2991 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002992 i::Handle<i::Object> string_obj =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00002993 i::Execution::ToString(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002994 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002995 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2996 uint32_t index;
2997 if (str->AsArrayIndex(&index)) {
2998 i::Handle<i::Object> value;
2999 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003000 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003001 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003002 value = isolate->factory()->NewNumber(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003003 }
3004 return Utils::Uint32ToLocal(value);
3005 }
3006 return Local<Uint32>();
3007}
3008
3009
ager@chromium.org32912102009-01-16 10:38:43 +00003010int32_t Value::Int32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003011 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3012 if (obj->IsSmi()) {
3013 return i::Smi::cast(*obj)->value();
3014 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003015 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003016 LOG_API(isolate, "Int32Value (slow)");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003017 ENTER_V8(isolate);
3018 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003019 i::Handle<i::Object> num =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003020 i::Execution::ToInt32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003021 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003022 if (num->IsSmi()) {
3023 return i::Smi::cast(*num)->value();
3024 } else {
3025 return static_cast<int32_t>(num->Number());
3026 }
3027 }
3028}
3029
3030
ager@chromium.org32912102009-01-16 10:38:43 +00003031bool Value::Equals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003032 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00003033 if (EmptyCheck("v8::Value::Equals()", this) ||
3034 EmptyCheck("v8::Value::Equals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003035 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00003036 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003037 LOG_API(isolate, "Equals");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003038 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003039 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3040 i::Handle<i::Object> other = Utils::OpenHandle(*that);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003041 // If both obj and other are JSObjects, we'd better compare by identity
3042 // immediately when going into JS builtin. The reason is Invoke
3043 // would overwrite global object receiver with global proxy.
3044 if (obj->IsJSObject() && other->IsJSObject()) {
3045 return *obj == *other;
3046 }
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003047 i::Handle<i::Object> args[] = { other };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003048 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003049 i::Handle<i::Object> result =
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003050 CallV8HeapFunction("EQUALS", obj, ARRAY_SIZE(args), args,
3051 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003052 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003053 return *result == i::Smi::FromInt(i::EQUAL);
3054}
3055
3056
ager@chromium.org32912102009-01-16 10:38:43 +00003057bool Value::StrictEquals(Handle<Value> that) const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003058 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00003059 if (EmptyCheck("v8::Value::StrictEquals()", this) ||
3060 EmptyCheck("v8::Value::StrictEquals()", that)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003061 return false;
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00003062 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003063 LOG_API(isolate, "StrictEquals");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003064 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3065 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3066 // Must check HeapNumber first, since NaN !== NaN.
3067 if (obj->IsHeapNumber()) {
3068 if (!other->IsNumber()) return false;
3069 double x = obj->Number();
3070 double y = other->Number();
3071 // Must check explicitly for NaN:s on Windows, but -0 works fine.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00003072 return x == y && !std::isnan(x) && !std::isnan(y);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003073 } else if (*obj == *other) { // Also covers Booleans.
3074 return true;
3075 } else if (obj->IsSmi()) {
3076 return other->IsNumber() && obj->Number() == other->Number();
3077 } else if (obj->IsString()) {
3078 return other->IsString() &&
3079 i::String::cast(*obj)->Equals(i::String::cast(*other));
3080 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
3081 return other->IsUndefined() || other->IsUndetectableObject();
3082 } else {
3083 return false;
3084 }
3085}
3086
3087
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00003088bool Value::SameValue(Handle<Value> that) const {
3089 i::Isolate* isolate = i::Isolate::Current();
3090 if (EmptyCheck("v8::Value::SameValue()", this) ||
3091 EmptyCheck("v8::Value::SameValue()", that)) {
3092 return false;
3093 }
3094 LOG_API(isolate, "SameValue");
3095 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3096 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3097 return obj->SameValue(*other);
3098}
3099
3100
ager@chromium.org32912102009-01-16 10:38:43 +00003101uint32_t Value::Uint32Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003102 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3103 if (obj->IsSmi()) {
3104 return i::Smi::cast(*obj)->value();
3105 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003106 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003107 LOG_API(isolate, "Uint32Value");
3108 ENTER_V8(isolate);
3109 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003110 i::Handle<i::Object> num =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003111 i::Execution::ToUint32(isolate, obj, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003112 EXCEPTION_BAILOUT_CHECK(isolate, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003113 if (num->IsSmi()) {
3114 return i::Smi::cast(*num)->value();
3115 } else {
3116 return static_cast<uint32_t>(num->Number());
3117 }
3118 }
3119}
3120
3121
3122bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003123 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003124 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003125 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003126 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003127 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003128 i::Handle<i::Object> self = Utils::OpenHandle(this);
3129 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3130 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003131 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003132 i::Handle<i::Object> obj = i::SetProperty(
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00003133 isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003134 self,
3135 key_obj,
3136 value_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003137 static_cast<PropertyAttributes>(attribs),
3138 i::kNonStrictMode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003139 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003140 EXCEPTION_BAILOUT_CHECK(isolate, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003141 return true;
3142}
3143
3144
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003145bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003146 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003147 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003148 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003149 i::HandleScope scope(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003150 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3151 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003152 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003153 i::Handle<i::Object> obj = i::JSObject::SetElement(
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003154 self,
3155 index,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00003156 value_obj,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003157 NONE,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00003158 i::kNonStrictMode);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003159 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003160 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003161 return true;
3162}
3163
3164
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003165bool v8::Object::ForceSet(v8::Handle<Value> key,
3166 v8::Handle<Value> value,
3167 v8::PropertyAttribute attribs) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003168 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003169 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003170 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003171 i::HandleScope scope(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003172 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3173 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3174 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003175 EXCEPTION_PREAMBLE(isolate);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003176 i::Handle<i::Object> obj = i::ForceSetProperty(
3177 self,
3178 key_obj,
3179 value_obj,
3180 static_cast<PropertyAttributes>(attribs));
3181 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003182 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003183 return true;
3184}
3185
3186
ager@chromium.orge2902be2009-06-08 12:21:35 +00003187bool v8::Object::ForceDelete(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003188 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003189 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003190 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003191 i::HandleScope scope(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003192 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3193 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00003195 // When deleting a property on the global object using ForceDelete
3196 // deoptimize all functions as optimized code does not check for the hole
3197 // value with DontDelete properties. We have to deoptimize all contexts
3198 // because of possible cross-context inlined functions.
3199 if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003200 i::Deoptimizer::DeoptimizeAll(isolate);
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00003201 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003202
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003203 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003204 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
3205 has_pending_exception = obj.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003206 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.orge2902be2009-06-08 12:21:35 +00003207 return obj->IsTrue();
3208}
3209
3210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003211Local<Value> v8::Object::Get(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003212 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003213 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003214 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003215 i::Handle<i::Object> self = Utils::OpenHandle(this);
3216 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003217 EXCEPTION_PREAMBLE(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003218 i::Handle<i::Object> result = i::GetProperty(isolate, self, key_obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003219 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003220 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003221 return Utils::ToLocal(result);
3222}
3223
3224
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003225Local<Value> v8::Object::Get(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003226 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003227 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003228 ENTER_V8(isolate);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003229 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003230 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00003231 i::Handle<i::Object> result = i::Object::GetElement(isolate, self, index);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003232 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003233 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003234 return Utils::ToLocal(result);
3235}
3236
3237
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003238PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
3239 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3240 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
3241 return static_cast<PropertyAttribute>(NONE));
3242 ENTER_V8(isolate);
3243 i::HandleScope scope(isolate);
3244 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3245 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003246 if (!key_obj->IsName()) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003247 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003248 key_obj = i::Execution::ToString(isolate, key_obj, &has_pending_exception);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003249 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3250 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003251 i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
3252 PropertyAttributes result = self->GetPropertyAttribute(*key_name);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003253 if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
3254 return static_cast<PropertyAttribute>(result);
3255}
3256
3257
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003258Local<Value> v8::Object::GetPrototype() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003259 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3260 ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003261 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003262 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003263 i::Handle<i::Object> self = Utils::OpenHandle(this);
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003264 i::Handle<i::Object> result(self->GetPrototype(isolate), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003265 return Utils::ToLocal(result);
3266}
3267
3268
ager@chromium.org5c838252010-02-19 08:53:10 +00003269bool v8::Object::SetPrototype(Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003270 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003271 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003272 ENTER_V8(isolate);
ager@chromium.org5c838252010-02-19 08:53:10 +00003273 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3274 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003275 // We do not allow exceptions thrown while setting the prototype
3276 // to propagate outside.
3277 TryCatch try_catch;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003278 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +00003279 i::Handle<i::Object> result = i::JSObject::SetPrototype(self, value_obj);
ager@chromium.org5c838252010-02-19 08:53:10 +00003280 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003281 EXCEPTION_BAILOUT_CHECK(isolate, false);
ager@chromium.org5c838252010-02-19 08:53:10 +00003282 return true;
3283}
3284
3285
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003286Local<Object> v8::Object::FindInstanceInPrototypeChain(
3287 v8::Handle<FunctionTemplate> tmpl) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003288 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3289 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003290 "v8::Object::FindInstanceInPrototypeChain()",
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003291 return Local<v8::Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003292 ENTER_V8(isolate);
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +00003293 i::JSObject* object = *Utils::OpenHandle(this);
3294 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
3295 while (!object->IsInstanceOf(tmpl_info)) {
3296 i::Object* prototype = object->GetPrototype();
3297 if (!prototype->IsJSObject()) return Local<Object>();
3298 object = i::JSObject::cast(prototype);
3299 }
3300 return Utils::ToLocal(i::Handle<i::JSObject>(object));
3301}
3302
3303
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003304Local<Array> v8::Object::GetPropertyNames() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003305 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003306 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
3307 return Local<v8::Array>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003308 ENTER_V8(isolate);
3309 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003310 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003311 bool threw = false;
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00003312 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003313 i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS, &threw);
3314 if (threw) return Local<v8::Array>();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003315 // Because we use caching to speed up enumeration it is important
3316 // to never change the result of the basic enumeration function so
3317 // we clone the result.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003318 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3319 i::Handle<i::JSArray> result =
3320 isolate->factory()->NewJSArrayWithElements(elms);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003321 return Utils::ToLocal(scope.CloseAndEscape(result));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003322}
3323
3324
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003325Local<Array> v8::Object::GetOwnPropertyNames() {
3326 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3327 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
3328 return Local<v8::Array>());
3329 ENTER_V8(isolate);
3330 i::HandleScope scope(isolate);
3331 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003332 bool threw = false;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003333 i::Handle<i::FixedArray> value =
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003334 i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY, &threw);
3335 if (threw) return Local<v8::Array>();
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003336 // Because we use caching to speed up enumeration it is important
3337 // to never change the result of the basic enumeration function so
3338 // we clone the result.
3339 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3340 i::Handle<i::JSArray> result =
3341 isolate->factory()->NewJSArrayWithElements(elms);
3342 return Utils::ToLocal(scope.CloseAndEscape(result));
3343}
3344
3345
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003346Local<String> v8::Object::ObjectProtoToString() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003347 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3348 ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003349 return Local<v8::String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003350 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3352
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003353 i::Handle<i::Object> name(self->class_name(), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003354
3355 // Native implementation of Object.prototype.toString (v8natives.js):
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00003356 // var c = %_ClassOf(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003357 // if (c === 'Arguments') c = 'Object';
3358 // return "[object " + c + "]";
3359
3360 if (!name->IsString()) {
3361 return v8::String::New("[object ]");
3362
3363 } else {
3364 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00003365 if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Arguments"))) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366 return v8::String::New("[object Object]");
3367
3368 } else {
3369 const char* prefix = "[object ";
3370 Local<String> str = Utils::ToLocal(class_name);
3371 const char* postfix = "]";
3372
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003373 int prefix_len = i::StrLength(prefix);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003374 int str_len = str->Utf8Length();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003375 int postfix_len = i::StrLength(postfix);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003377 int buf_len = prefix_len + str_len + postfix_len;
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003378 i::ScopedVector<char> buf(buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003379
3380 // Write prefix.
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003381 char* ptr = buf.start();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003382 i::OS::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003383 ptr += prefix_len;
3384
3385 // Write real content.
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003386 str->WriteUtf8(ptr, str_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003387 ptr += str_len;
3388
3389 // Write postfix.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003390 i::OS::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391
3392 // Copy the buffer into a heap-allocated string and return it.
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003393 Local<String> result = v8::String::New(buf.start(), buf_len);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003394 return result;
3395 }
3396 }
3397}
3398
3399
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00003400Local<Value> v8::Object::GetConstructor() {
3401 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3402 ON_BAILOUT(isolate, "v8::Object::GetConstructor()",
3403 return Local<v8::Function>());
3404 ENTER_V8(isolate);
3405 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003406 i::Handle<i::Object> constructor(self->GetConstructor(), isolate);
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00003407 return Utils::ToLocal(constructor);
3408}
3409
3410
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003411Local<String> v8::Object::GetConstructorName() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003412 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003413 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
3414 return Local<v8::String>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003415 ENTER_V8(isolate);
ager@chromium.orgbeb25712010-11-29 08:02:25 +00003416 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3417 i::Handle<i::String> name(self->constructor_name());
3418 return Utils::ToLocal(name);
3419}
3420
3421
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003422bool v8::Object::Delete(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003423 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003424 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003425 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003426 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003428 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3429 EXCEPTION_PREAMBLE(isolate);
3430 i::Handle<i::Object> obj = i::DeleteProperty(self, key_obj);
3431 has_pending_exception = obj.is_null();
3432 EXCEPTION_BAILOUT_CHECK(isolate, false);
3433 return obj->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003434}
3435
3436
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003437bool v8::Object::Has(v8::Handle<Value> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003438 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3439 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
3440 ENTER_V8(isolate);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003441 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3442 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3443 EXCEPTION_PREAMBLE(isolate);
3444 i::Handle<i::Object> obj = i::HasProperty(self, key_obj);
3445 has_pending_exception = obj.is_null();
3446 EXCEPTION_BAILOUT_CHECK(isolate, false);
3447 return obj->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003448}
3449
3450
3451bool v8::Object::Delete(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003452 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3453 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003454 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003455 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003456 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003457 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00003458 return i::JSReceiver::DeleteElement(self, index)->IsTrue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003459}
3460
3461
3462bool v8::Object::Has(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003463 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3464 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003466 return i::JSReceiver::HasElement(self, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003467}
3468
3469
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003470template<typename Setter, typename Getter, typename Data>
3471static inline bool ObjectSetAccessor(Object* obj,
3472 Handle<String> name,
3473 Setter getter,
3474 Getter setter,
3475 Data data,
3476 AccessControl settings,
3477 PropertyAttribute attributes) {
3478 i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate();
3479 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3480 ENTER_V8(isolate);
3481 i::HandleScope scope(isolate);
3482 v8::Handle<AccessorSignature> signature;
3483 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(
3484 name, getter, setter, data, settings, attributes, signature);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003485 if (info.is_null()) return false;
3486 bool fast = Utils::OpenHandle(obj)->HasFastProperties();
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00003487 i::Handle<i::Object> result =
3488 i::JSObject::SetAccessor(Utils::OpenHandle(obj), info);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003489 if (result.is_null() || result->IsUndefined()) return false;
3490 if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(obj), 0);
3491 return true;
3492}
3493
3494
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003495bool Object::SetAccessor(Handle<String> name,
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003496 AccessorGetterCallback getter,
3497 AccessorSetterCallback setter,
3498 v8::Handle<Value> data,
3499 AccessControl settings,
3500 PropertyAttribute attributes) {
3501 return ObjectSetAccessor(
3502 this, name, getter, setter, data, settings, attributes);
ulan@chromium.org750145a2013-03-07 15:14:13 +00003503}
3504
3505
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00003506bool Object::SetDeclaredAccessor(Local<String> name,
3507 Local<DeclaredAccessorDescriptor> descriptor,
3508 PropertyAttribute attributes,
3509 AccessControl settings) {
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00003510 void* null = NULL;
3511 return ObjectSetAccessor(
3512 this, name, descriptor, null, null, settings, attributes);
kmillikin@chromium.org9155e252010-05-26 13:27:57 +00003513}
3514
3515
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003516bool v8::Object::HasOwnProperty(Handle<String> key) {
3517 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3518 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3519 return false);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003520 return i::JSReceiver::HasLocalProperty(
3521 Utils::OpenHandle(this), Utils::OpenHandle(*key));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003522}
3523
3524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003525bool v8::Object::HasRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003526 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3527 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003528 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003529 return Utils::OpenHandle(this)->HasRealNamedProperty(
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003530 isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003531 *Utils::OpenHandle(*key));
3532}
3533
3534
3535bool v8::Object::HasRealIndexedProperty(uint32_t index) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003536 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3537 ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003538 return false);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003539 return Utils::OpenHandle(this)->HasRealElementProperty(isolate, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003540}
3541
3542
3543bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003544 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3545 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003546 "v8::Object::HasRealNamedCallbackProperty()",
3547 return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003548 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003549 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003550 isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003551 *Utils::OpenHandle(*key));
3552}
3553
3554
3555bool v8::Object::HasNamedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003556 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3557 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003558 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003559 return Utils::OpenHandle(this)->HasNamedInterceptor();
3560}
3561
3562
3563bool v8::Object::HasIndexedLookupInterceptor() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003564 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3565 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003566 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003567 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3568}
3569
3570
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003571static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
3572 i::Handle<i::JSObject> receiver,
3573 i::Handle<i::String> name,
3574 i::LookupResult* lookup) {
3575 if (!lookup->IsProperty()) {
3576 // No real property was found.
3577 return Local<Value>();
3578 }
3579
3580 // If the property being looked up is a callback, it can throw
3581 // an exception.
3582 EXCEPTION_PREAMBLE(isolate);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003583 PropertyAttributes ignored;
3584 i::Handle<i::Object> result =
3585 i::Object::GetProperty(receiver, receiver, lookup, name,
3586 &ignored);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003587 has_pending_exception = result.is_null();
3588 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3589
3590 return Utils::ToLocal(result);
3591}
3592
3593
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003594Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003595 Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003596 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3597 ON_BAILOUT(isolate,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003598 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003599 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003600 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003601 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3602 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003603 i::LookupResult lookup(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003604 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003605 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003606}
3607
3608
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003609Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003610 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3611 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003612 return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003613 ENTER_V8(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003614 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3615 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003616 i::LookupResult lookup(isolate);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003617 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003618 return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
sgjesse@chromium.org98aff2f2009-09-30 08:27:10 +00003619}
3620
3621
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003622// Turns on access checks by copying the map and setting the check flag.
3623// Because the object gets a new map, existing inline cache caching
3624// the old map of this object will fail.
3625void v8::Object::TurnOnAccessCheck() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003626 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003627 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003628 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003629 i::HandleScope scope(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003630 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3631
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632 // When turning on access checks for a global object deoptimize all functions
3633 // as optimized code does not always handle access checks.
3634 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3635
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003636 i::Handle<i::Map> new_map =
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003637 isolate->factory()->CopyMap(i::Handle<i::Map>(obj->map()));
ager@chromium.org870a0b62008-11-04 11:43:05 +00003638 new_map->set_is_access_check_needed(true);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003639 obj->set_map(*new_map);
3640}
3641
3642
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +00003643bool v8::Object::IsDirty() {
3644 return Utils::OpenHandle(this)->IsDirty();
3645}
3646
3647
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003648Local<v8::Object> v8::Object::Clone() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003649 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003650 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003651 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003652 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003653 EXCEPTION_PREAMBLE(isolate);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00003654 i::Handle<i::JSObject> result = i::JSObject::Copy(self);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003655 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003656 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003657 return Utils::ToLocal(result);
3658}
3659
3660
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003661static i::Context* GetCreationContext(i::JSObject* object) {
3662 i::Object* constructor = object->map()->constructor();
3663 i::JSFunction* function;
3664 if (!constructor->IsJSFunction()) {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003665 // Functions have null as a constructor,
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003666 // but any JSFunction knows its context immediately.
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003667 ASSERT(object->IsJSFunction());
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003668 function = i::JSFunction::cast(object);
3669 } else {
3670 function = i::JSFunction::cast(constructor);
3671 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003672 return function->context()->native_context();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003673}
3674
3675
3676Local<v8::Context> v8::Object::CreationContext() {
3677 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3678 ON_BAILOUT(isolate,
3679 "v8::Object::CreationContext()", return Local<v8::Context>());
3680 ENTER_V8(isolate);
3681 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3682 i::Context* context = GetCreationContext(*self);
3683 return Utils::ToLocal(i::Handle<i::Context>(context));
3684}
3685
3686
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003687int v8::Object::GetIdentityHash() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003688 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003689 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003690 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003691 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003692 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003693 return i::JSObject::GetIdentityHash(self);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003694}
3695
3696
3697bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3698 v8::Handle<v8::Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003699 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003700 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00003701 if (value.IsEmpty()) return DeleteHiddenValue(key);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003702 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003703 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003704 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003705 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003706 i::Handle<i::String> key_string =
3707 isolate->factory()->InternalizeString(key_obj);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003708 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003709 i::Handle<i::Object> result =
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003710 i::JSObject::SetHiddenProperty(self, key_string, value_obj);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003711 return *result == *self;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003712}
3713
3714
3715v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003716 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003717 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3718 return Local<v8::Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003719 ENTER_V8(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003720 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003721 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00003722 i::Handle<i::String> key_string =
3723 isolate->factory()->InternalizeString(key_obj);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003724 i::Handle<i::Object> result(self->GetHiddenProperty(*key_string), isolate);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00003725 if (result->IsTheHole()) return v8::Local<v8::Value>();
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003726 return Utils::ToLocal(result);
3727}
3728
3729
3730bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003731 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003732 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003733 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003734 i::HandleScope scope(isolate);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003735 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003736 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00003737 i::Handle<i::String> key_string =
3738 isolate->factory()->InternalizeString(key_obj);
jkummerow@chromium.org8fa5bd92013-09-02 11:45:09 +00003739 i::JSObject::DeleteHiddenProperty(self, key_string);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003740 return true;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003741}
3742
3743
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003744namespace {
3745
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003746static i::ElementsKind GetElementsKindFromExternalArrayType(
3747 ExternalArrayType array_type) {
3748 switch (array_type) {
3749 case kExternalByteArray:
3750 return i::EXTERNAL_BYTE_ELEMENTS;
3751 break;
3752 case kExternalUnsignedByteArray:
3753 return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3754 break;
3755 case kExternalShortArray:
3756 return i::EXTERNAL_SHORT_ELEMENTS;
3757 break;
3758 case kExternalUnsignedShortArray:
3759 return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3760 break;
3761 case kExternalIntArray:
3762 return i::EXTERNAL_INT_ELEMENTS;
3763 break;
3764 case kExternalUnsignedIntArray:
3765 return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
3766 break;
3767 case kExternalFloatArray:
3768 return i::EXTERNAL_FLOAT_ELEMENTS;
3769 break;
3770 case kExternalDoubleArray:
3771 return i::EXTERNAL_DOUBLE_ELEMENTS;
3772 break;
3773 case kExternalPixelArray:
3774 return i::EXTERNAL_PIXEL_ELEMENTS;
3775 break;
3776 }
3777 UNREACHABLE();
3778 return i::DICTIONARY_ELEMENTS;
3779}
3780
3781
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003782void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3783 void* data,
3784 ExternalArrayType array_type,
3785 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003786 i::Isolate* isolate = object->GetIsolate();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003787 i::Handle<i::ExternalArray> array =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003788 isolate->factory()->NewExternalArray(length, array_type, data);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003789
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003790 i::Handle<i::Map> external_array_map =
3791 isolate->factory()->GetElementsTransitionMap(
3792 object,
3793 GetElementsKindFromExternalArrayType(array_type));
3794
3795 object->set_map(*external_array_map);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003796 object->set_elements(*array);
3797}
3798
3799} // namespace
3800
3801
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003802void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003803 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003804 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003805 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003806 i::HandleScope scope(isolate);
danno@chromium.org412fa512012-09-14 13:28:26 +00003807 if (!ApiCheck(length >= 0 && length <= i::ExternalPixelArray::kMaxLength,
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003808 "v8::Object::SetIndexedPropertiesToPixelData()",
3809 "length exceeds max acceptable value")) {
3810 return;
3811 }
3812 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3813 if (!ApiCheck(!self->IsJSArray(),
3814 "v8::Object::SetIndexedPropertiesToPixelData()",
3815 "JSArray is not supported")) {
3816 return;
3817 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003818 PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003819}
3820
3821
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003822bool v8::Object::HasIndexedPropertiesInPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003823 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003824 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3825 return false);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003826 return self->HasExternalPixelElements();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003827}
3828
3829
3830uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003831 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003832 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3833 return NULL);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003834 if (self->HasExternalPixelElements()) {
3835 return i::ExternalPixelArray::cast(self->elements())->
3836 external_pixel_pointer();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003837 } else {
3838 return NULL;
3839 }
3840}
3841
3842
3843int v8::Object::GetIndexedPropertiesPixelDataLength() {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003844 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003845 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3846 return -1);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003847 if (self->HasExternalPixelElements()) {
3848 return i::ExternalPixelArray::cast(self->elements())->length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003849 } else {
3850 return -1;
3851 }
3852}
3853
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003854
ager@chromium.org3811b432009-10-28 14:53:37 +00003855void v8::Object::SetIndexedPropertiesToExternalArrayData(
3856 void* data,
3857 ExternalArrayType array_type,
3858 int length) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003859 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003860 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003861 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003862 i::HandleScope scope(isolate);
danno@chromium.org412fa512012-09-14 13:28:26 +00003863 if (!ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
ager@chromium.org3811b432009-10-28 14:53:37 +00003864 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3865 "length exceeds max acceptable value")) {
3866 return;
3867 }
3868 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3869 if (!ApiCheck(!self->IsJSArray(),
3870 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3871 "JSArray is not supported")) {
3872 return;
3873 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003874 PrepareExternalArrayElements(self, data, array_type, length);
ager@chromium.org3811b432009-10-28 14:53:37 +00003875}
3876
3877
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003878bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003879 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3880 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003881 "v8::HasIndexedPropertiesInExternalArrayData()",
3882 return false);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003883 return self->HasExternalArrayElements();
3884}
3885
3886
3887void* v8::Object::GetIndexedPropertiesExternalArrayData() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003888 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3889 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003890 "v8::GetIndexedPropertiesExternalArrayData()",
3891 return NULL);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003892 if (self->HasExternalArrayElements()) {
3893 return i::ExternalArray::cast(self->elements())->external_pointer();
3894 } else {
3895 return NULL;
3896 }
3897}
3898
3899
3900ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003901 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3902 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003903 "v8::GetIndexedPropertiesExternalArrayDataType()",
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003904 return static_cast<ExternalArrayType>(-1));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003905 switch (self->elements()->map()->instance_type()) {
3906 case i::EXTERNAL_BYTE_ARRAY_TYPE:
3907 return kExternalByteArray;
3908 case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3909 return kExternalUnsignedByteArray;
3910 case i::EXTERNAL_SHORT_ARRAY_TYPE:
3911 return kExternalShortArray;
3912 case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3913 return kExternalUnsignedShortArray;
3914 case i::EXTERNAL_INT_ARRAY_TYPE:
3915 return kExternalIntArray;
3916 case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3917 return kExternalUnsignedIntArray;
3918 case i::EXTERNAL_FLOAT_ARRAY_TYPE:
3919 return kExternalFloatArray;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003920 case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
3921 return kExternalDoubleArray;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003922 case i::EXTERNAL_PIXEL_ARRAY_TYPE:
3923 return kExternalPixelArray;
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003924 default:
3925 return static_cast<ExternalArrayType>(-1);
3926 }
3927}
3928
3929
3930int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003931 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3932 ON_BAILOUT(self->GetIsolate(),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003933 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3934 return 0);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00003935 if (self->HasExternalArrayElements()) {
3936 return i::ExternalArray::cast(self->elements())->length();
3937 } else {
3938 return -1;
3939 }
3940}
3941
3942
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003943bool v8::Object::IsCallable() {
3944 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3945 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3946 ENTER_V8(isolate);
3947 i::HandleScope scope(isolate);
3948 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3949 if (obj->IsJSFunction()) return true;
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003950 return i::Execution::GetFunctionDelegate(isolate, obj)->IsJSFunction();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003951}
3952
3953
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00003954Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003955 int argc,
lrn@chromium.org1c092762011-05-09 09:42:16 +00003956 v8::Handle<v8::Value> argv[]) {
3957 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3958 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3959 return Local<v8::Value>());
3960 LOG_API(isolate, "Object::CallAsFunction");
3961 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00003962 i::Logger::TimerEventScope timer_scope(
3963 isolate, i::Logger::TimerEventScope::v8_execute);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003964 i::HandleScope scope(isolate);
3965 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3966 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3967 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00003968 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003969 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3970 if (obj->IsJSFunction()) {
3971 fun = i::Handle<i::JSFunction>::cast(obj);
3972 } else {
3973 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00003974 i::Handle<i::Object> delegate = i::Execution::TryGetFunctionDelegate(
3975 isolate, obj, &has_pending_exception);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003976 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3977 fun = i::Handle<i::JSFunction>::cast(delegate);
3978 recv_obj = obj;
3979 }
3980 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00003981 i::Handle<i::Object> returned = i::Execution::Call(
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00003982 isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00003983 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00003984 return Utils::ToLocal(scope.CloseAndEscape(returned));
3985}
3986
3987
3988Local<v8::Value> Object::CallAsConstructor(int argc,
3989 v8::Handle<v8::Value> argv[]) {
3990 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3991 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
3992 return Local<v8::Object>());
3993 LOG_API(isolate, "Object::CallAsConstructor");
3994 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00003995 i::Logger::TimerEventScope timer_scope(
3996 isolate, i::Logger::TimerEventScope::v8_execute);
lrn@chromium.org1c092762011-05-09 09:42:16 +00003997 i::HandleScope scope(isolate);
3998 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3999 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00004000 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
lrn@chromium.org1c092762011-05-09 09:42:16 +00004001 if (obj->IsJSFunction()) {
4002 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
4003 EXCEPTION_PREAMBLE(isolate);
4004 i::Handle<i::Object> returned =
4005 i::Execution::New(fun, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004006 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00004007 return Utils::ToLocal(scope.CloseAndEscape(
4008 i::Handle<i::JSObject>::cast(returned)));
4009 }
4010 EXCEPTION_PREAMBLE(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00004011 i::Handle<i::Object> delegate = i::Execution::TryGetConstructorDelegate(
4012 isolate, obj, &has_pending_exception);
lrn@chromium.org1c092762011-05-09 09:42:16 +00004013 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
4014 if (!delegate->IsUndefined()) {
4015 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
4016 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00004017 i::Handle<i::Object> returned = i::Execution::Call(
4018 isolate, fun, obj, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004019 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
lrn@chromium.org1c092762011-05-09 09:42:16 +00004020 ASSERT(!delegate->IsUndefined());
4021 return Utils::ToLocal(scope.CloseAndEscape(returned));
4022 }
4023 return Local<v8::Object>();
4024}
4025
4026
dslomov@chromium.org639bac02013-09-09 11:58:54 +00004027Local<Function> Function::New(Isolate* v8_isolate,
4028 FunctionCallback callback,
4029 Local<Value> data,
4030 int length) {
4031 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
4032 LOG_API(isolate, "Function::New");
4033 ENTER_V8(isolate);
4034 return FunctionTemplateNew(
4035 isolate, callback, data, Local<Signature>(), length, true)->
4036 GetFunction();
4037}
4038
4039
ager@chromium.org32912102009-01-16 10:38:43 +00004040Local<v8::Object> Function::NewInstance() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004041 return NewInstance(0, NULL);
4042}
4043
4044
4045Local<v8::Object> Function::NewInstance(int argc,
ager@chromium.org32912102009-01-16 10:38:43 +00004046 v8::Handle<v8::Value> argv[]) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004047 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004048 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
4049 return Local<v8::Object>());
4050 LOG_API(isolate, "Function::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004051 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00004052 i::Logger::TimerEventScope timer_scope(
4053 isolate, i::Logger::TimerEventScope::v8_execute);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004054 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004055 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
4056 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00004057 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004058 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004059 i::Handle<i::Object> returned =
4060 i::Execution::New(function, argc, args, &has_pending_exception);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004061 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004062 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
4063}
4064
4065
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00004066Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004067 v8::Handle<v8::Value> argv[]) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004068 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004069 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
4070 LOG_API(isolate, "Function::Call");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004071 ENTER_V8(isolate);
danno@chromium.org1f34ad32012-11-26 14:53:56 +00004072 i::Logger::TimerEventScope timer_scope(
4073 isolate, i::Logger::TimerEventScope::v8_execute);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004074 i::Object* raw_result = NULL;
4075 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004076 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004077 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
4078 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4079 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00004080 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004081 EXCEPTION_PREAMBLE(isolate);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00004082 i::Handle<i::Object> returned = i::Execution::Call(
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00004083 isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004084 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004085 raw_result = *returned;
4086 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004087 i::Handle<i::Object> result(raw_result, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004088 return Utils::ToLocal(result);
4089}
4090
4091
4092void Function::SetName(v8::Handle<v8::String> name) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004093 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4094 ENTER_V8(isolate);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004095 USE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004096 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4097 func->shared()->set_name(*Utils::OpenHandle(*name));
4098}
4099
4100
ager@chromium.org32912102009-01-16 10:38:43 +00004101Handle<Value> Function::GetName() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004102 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004103 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name(),
4104 func->GetIsolate()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004105}
4106
4107
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004108Handle<Value> Function::GetInferredName() const {
4109 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004110 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4111 func->GetIsolate()));
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004112}
4113
4114
ager@chromium.org5c838252010-02-19 08:53:10 +00004115ScriptOrigin Function::GetScriptOrigin() const {
4116 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4117 if (func->shared()->script()->IsScript()) {
4118 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00004119 i::Handle<i::Object> scriptName = GetScriptNameOrSourceURL(script);
ager@chromium.org5c838252010-02-19 08:53:10 +00004120 v8::ScriptOrigin origin(
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00004121 Utils::ToLocal(scriptName),
ager@chromium.org5c838252010-02-19 08:53:10 +00004122 v8::Integer::New(script->line_offset()->value()),
4123 v8::Integer::New(script->column_offset()->value()));
4124 return origin;
4125 }
4126 return v8::ScriptOrigin(Handle<Value>());
4127}
4128
4129
4130const int Function::kLineOffsetNotFound = -1;
4131
4132
4133int Function::GetScriptLineNumber() const {
4134 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4135 if (func->shared()->script()->IsScript()) {
4136 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4137 return i::GetScriptLineNumber(script, func->shared()->start_position());
4138 }
4139 return kLineOffsetNotFound;
4140}
4141
4142
danno@chromium.orgc612e022011-11-10 11:38:15 +00004143int Function::GetScriptColumnNumber() const {
4144 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4145 if (func->shared()->script()->IsScript()) {
4146 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4147 return i::GetScriptColumnNumber(script, func->shared()->start_position());
4148 }
4149 return kLineOffsetNotFound;
4150}
4151
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004152
danno@chromium.orgc612e022011-11-10 11:38:15 +00004153Handle<Value> Function::GetScriptId() const {
4154 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00004155 i::Isolate* isolate = func->GetIsolate();
4156 if (!func->shared()->script()->IsScript()) {
4157 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4158 }
danno@chromium.orgc612e022011-11-10 11:38:15 +00004159 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00004160 return Utils::ToLocal(i::Handle<i::Object>(script->id(), isolate));
danno@chromium.orgc612e022011-11-10 11:38:15 +00004161}
4162
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004163
4164int Function::ScriptId() const {
4165 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4166 if (!func->shared()->script()->IsScript()) return v8::Script::kNoScriptId;
4167 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4168 return script->id()->value();
4169}
4170
4171
ager@chromium.org32912102009-01-16 10:38:43 +00004172int String::Length() const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004173 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004174 return str->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004175}
4176
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004177
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004178bool String::IsOneByte() const {
4179 i::Handle<i::String> str = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00004180 return str->HasOnlyOneByteChars();
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004181}
4182
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00004183
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004184// Helpers for ContainsOnlyOneByteHelper
4185template<size_t size> struct OneByteMask;
4186template<> struct OneByteMask<4> {
4187 static const uint32_t value = 0xFF00FF00;
4188};
4189template<> struct OneByteMask<8> {
4190 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4191};
4192static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4193static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4194static inline bool Unaligned(const uint16_t* chars) {
4195 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4196}
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00004197
4198
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004199static inline const uint16_t* Align(const uint16_t* chars) {
4200 return reinterpret_cast<uint16_t*>(
4201 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4202}
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004203
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004204class ContainsOnlyOneByteHelper {
4205 public:
4206 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4207 bool Check(i::String* string) {
4208 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4209 if (cons_string == NULL) return is_one_byte_;
4210 return CheckCons(cons_string);
4211 }
4212 void VisitOneByteString(const uint8_t* chars, int length) {
4213 // Nothing to do.
4214 }
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004215 void VisitTwoByteString(const uint16_t* chars, int length) {
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004216 // Accumulated bits.
4217 uintptr_t acc = 0;
4218 // Align to uintptr_t.
4219 const uint16_t* end = chars + length;
4220 while (Unaligned(chars) && chars != end) {
4221 acc |= *chars++;
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004222 }
verwaest@chromium.org8a00e822013-06-10 15:11:22 +00004223 // Read word aligned in blocks,
4224 // checking the return value at the end of each block.
4225 const uint16_t* aligned_end = Align(end);
4226 const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4227 const int inner_loops = 16;
4228 while (chars + inner_loops*increment < aligned_end) {
4229 for (int i = 0; i < inner_loops; i++) {
4230 acc |= *reinterpret_cast<const uintptr_t*>(chars);
4231 chars += increment;
4232 }
4233 // Check for early return.
4234 if ((acc & kOneByteMask) != 0) {
4235 is_one_byte_ = false;
4236 return;
4237 }
4238 }
4239 // Read the rest.
4240 while (chars != end) {
4241 acc |= *chars++;
4242 }
4243 // Check result.
4244 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004245 }
4246
4247 private:
4248 bool CheckCons(i::ConsString* cons_string) {
4249 while (true) {
4250 // Check left side if flat.
4251 i::String* left = cons_string->first();
4252 i::ConsString* left_as_cons =
4253 i::String::VisitFlat(this, left, 0);
4254 if (!is_one_byte_) return false;
4255 // Check right side if flat.
4256 i::String* right = cons_string->second();
4257 i::ConsString* right_as_cons =
4258 i::String::VisitFlat(this, right, 0);
4259 if (!is_one_byte_) return false;
4260 // Standard recurse/iterate trick.
4261 if (left_as_cons != NULL && right_as_cons != NULL) {
4262 if (left->length() < right->length()) {
4263 CheckCons(left_as_cons);
4264 cons_string = right_as_cons;
4265 } else {
4266 CheckCons(right_as_cons);
4267 cons_string = left_as_cons;
4268 }
4269 // Check fast return.
4270 if (!is_one_byte_) return false;
4271 continue;
4272 }
4273 // Descend left in place.
4274 if (left_as_cons != NULL) {
4275 cons_string = left_as_cons;
4276 continue;
4277 }
4278 // Descend right in place.
4279 if (right_as_cons != NULL) {
4280 cons_string = right_as_cons;
4281 continue;
4282 }
4283 // Terminate.
4284 break;
4285 }
4286 return is_one_byte_;
4287 }
4288 bool is_one_byte_;
4289 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4290};
4291
4292
4293bool String::ContainsOnlyOneByte() const {
4294 i::Handle<i::String> str = Utils::OpenHandle(this);
ulan@chromium.orgdfe53072013-06-06 14:14:51 +00004295 if (str->HasOnlyOneByteChars()) return true;
4296 ContainsOnlyOneByteHelper helper;
4297 return helper.Check(*str);
4298}
4299
4300
ulan@chromium.org750145a2013-03-07 15:14:13 +00004301class Utf8LengthHelper : public i::AllStatic {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004302 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004303 enum State {
4304 kEndsWithLeadingSurrogate = 1 << 0,
4305 kStartsWithTrailingSurrogate = 1 << 1,
4306 kLeftmostEdgeIsCalculated = 1 << 2,
4307 kRightmostEdgeIsCalculated = 1 << 3,
4308 kLeftmostEdgeIsSurrogate = 1 << 4,
4309 kRightmostEdgeIsSurrogate = 1 << 5
4310 };
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004311
ulan@chromium.org750145a2013-03-07 15:14:13 +00004312 static const uint8_t kInitialState = 0;
4313
4314 static inline bool EndsWithSurrogate(uint8_t state) {
4315 return state & kEndsWithLeadingSurrogate;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004316 }
4317
ulan@chromium.org750145a2013-03-07 15:14:13 +00004318 static inline bool StartsWithSurrogate(uint8_t state) {
4319 return state & kStartsWithTrailingSurrogate;
4320 }
4321
4322 class Visitor {
4323 public:
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004324 inline explicit Visitor()
ulan@chromium.org750145a2013-03-07 15:14:13 +00004325 : utf8_length_(0),
4326 state_(kInitialState) {}
4327
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004328 void VisitOneByteString(const uint8_t* chars, int length) {
4329 int utf8_length = 0;
4330 // Add in length 1 for each non-ASCII character.
4331 for (int i = 0; i < length; i++) {
4332 utf8_length += *chars++ >> 7;
4333 }
4334 // Add in length 1 for each character.
4335 utf8_length_ = utf8_length + length;
4336 state_ = kInitialState;
4337 }
4338
4339 void VisitTwoByteString(const uint16_t* chars, int length) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00004340 int utf8_length = 0;
4341 int last_character = unibrow::Utf16::kNoPreviousCharacter;
4342 for (int i = 0; i < length; i++) {
4343 uint16_t c = chars[i];
4344 utf8_length += unibrow::Utf8::Length(c, last_character);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004345 last_character = c;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004346 }
4347 utf8_length_ = utf8_length;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004348 uint8_t state = 0;
4349 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4350 state |= kStartsWithTrailingSurrogate;
4351 }
4352 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4353 state |= kEndsWithLeadingSurrogate;
4354 }
4355 state_ = state;
4356 }
4357
4358 static i::ConsString* VisitFlat(i::String* string,
4359 int* length,
4360 uint8_t* state) {
4361 Visitor visitor;
4362 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4363 *length = visitor.utf8_length_;
4364 *state = visitor.state_;
4365 return cons_string;
4366 }
4367
4368 private:
4369 int utf8_length_;
4370 uint8_t state_;
4371 DISALLOW_COPY_AND_ASSIGN(Visitor);
4372 };
4373
4374 static inline void MergeLeafLeft(int* length,
4375 uint8_t* state,
4376 uint8_t leaf_state) {
4377 bool edge_surrogate = StartsWithSurrogate(leaf_state);
4378 if (!(*state & kLeftmostEdgeIsCalculated)) {
4379 ASSERT(!(*state & kLeftmostEdgeIsSurrogate));
4380 *state |= kLeftmostEdgeIsCalculated
4381 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4382 } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4383 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4384 }
4385 if (EndsWithSurrogate(leaf_state)) {
4386 *state |= kEndsWithLeadingSurrogate;
4387 } else {
4388 *state &= ~kEndsWithLeadingSurrogate;
4389 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004390 }
4391
ulan@chromium.org750145a2013-03-07 15:14:13 +00004392 static inline void MergeLeafRight(int* length,
4393 uint8_t* state,
4394 uint8_t leaf_state) {
4395 bool edge_surrogate = EndsWithSurrogate(leaf_state);
4396 if (!(*state & kRightmostEdgeIsCalculated)) {
4397 ASSERT(!(*state & kRightmostEdgeIsSurrogate));
4398 *state |= (kRightmostEdgeIsCalculated
4399 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4400 } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4401 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4402 }
4403 if (StartsWithSurrogate(leaf_state)) {
4404 *state |= kStartsWithTrailingSurrogate;
4405 } else {
4406 *state &= ~kStartsWithTrailingSurrogate;
4407 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004408 }
4409
ulan@chromium.org750145a2013-03-07 15:14:13 +00004410 static inline void MergeTerminal(int* length,
4411 uint8_t state,
4412 uint8_t* state_out) {
4413 ASSERT((state & kLeftmostEdgeIsCalculated) &&
4414 (state & kRightmostEdgeIsCalculated));
4415 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4416 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4417 }
4418 *state_out = kInitialState |
4419 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4420 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4421 }
4422
4423 static int Calculate(i::ConsString* current, uint8_t* state_out) {
4424 using namespace internal;
4425 int total_length = 0;
4426 uint8_t state = kInitialState;
4427 while (true) {
4428 i::String* left = current->first();
4429 i::String* right = current->second();
4430 uint8_t right_leaf_state;
4431 uint8_t left_leaf_state;
4432 int leaf_length;
4433 ConsString* left_as_cons =
4434 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4435 if (left_as_cons == NULL) {
4436 total_length += leaf_length;
4437 MergeLeafLeft(&total_length, &state, left_leaf_state);
4438 }
4439 ConsString* right_as_cons =
4440 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4441 if (right_as_cons == NULL) {
4442 total_length += leaf_length;
4443 MergeLeafRight(&total_length, &state, right_leaf_state);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004444 if (left_as_cons != NULL) {
4445 // 1 Leaf node. Descend in place.
4446 current = left_as_cons;
4447 continue;
4448 } else {
4449 // Terminal node.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004450 MergeTerminal(&total_length, state, state_out);
4451 return total_length;
4452 }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004453 } else if (left_as_cons == NULL) {
4454 // 1 Leaf node. Descend in place.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004455 current = right_as_cons;
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004456 continue;
4457 }
4458 // Both strings are ConsStrings.
4459 // Recurse on smallest.
4460 if (left->length() < right->length()) {
4461 total_length += Calculate(left_as_cons, &left_leaf_state);
4462 MergeLeafLeft(&total_length, &state, left_leaf_state);
4463 current = right_as_cons;
4464 } else {
4465 total_length += Calculate(right_as_cons, &right_leaf_state);
4466 MergeLeafRight(&total_length, &state, right_leaf_state);
4467 current = left_as_cons;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004468 }
4469 }
4470 UNREACHABLE();
4471 return 0;
4472 }
4473
4474 static inline int Calculate(i::ConsString* current) {
4475 uint8_t state = kInitialState;
4476 return Calculate(current, &state);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004477 }
4478
4479 private:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004480 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004481};
4482
4483
4484static int Utf8Length(i::String* str, i::Isolate* isolate) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00004485 int length = str->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004486 if (length == 0) return 0;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004487 uint8_t state;
4488 i::ConsString* cons_string =
4489 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4490 if (cons_string == NULL) return length;
4491 return Utf8LengthHelper::Calculate(cons_string);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004492}
4493
4494
4495int String::Utf8Length() const {
4496 i::Handle<i::String> str = Utils::OpenHandle(this);
4497 i::Isolate* isolate = str->GetIsolate();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004498 return v8::Utf8Length(*str, isolate);
4499}
4500
4501
4502class Utf8WriterVisitor {
4503 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +00004504 Utf8WriterVisitor(
4505 char* buffer, int capacity, bool skip_capacity_check)
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004506 : early_termination_(false),
4507 last_character_(unibrow::Utf16::kNoPreviousCharacter),
4508 buffer_(buffer),
4509 start_(buffer),
4510 capacity_(capacity),
ulan@chromium.org750145a2013-03-07 15:14:13 +00004511 skip_capacity_check_(capacity == -1 || skip_capacity_check),
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004512 utf16_chars_read_(0) {
4513 }
4514
4515 static int WriteEndCharacter(uint16_t character,
4516 int last_character,
4517 int remaining,
4518 char* const buffer) {
4519 using namespace unibrow;
4520 ASSERT(remaining > 0);
4521 // We can't use a local buffer here because Encode needs to modify
4522 // previous characters in the stream. We know, however, that
4523 // exactly one character will be advanced.
4524 if (Utf16::IsTrailSurrogate(character) &&
4525 Utf16::IsLeadSurrogate(last_character)) {
4526 int written = Utf8::Encode(buffer, character, last_character);
4527 ASSERT(written == 1);
4528 return written;
4529 }
4530 // Use a scratch buffer to check the required characters.
4531 char temp_buffer[Utf8::kMaxEncodedSize];
4532 // Can't encode using last_character as gcc has array bounds issues.
4533 int written = Utf8::Encode(temp_buffer,
4534 character,
ulan@chromium.org750145a2013-03-07 15:14:13 +00004535 Utf16::kNoPreviousCharacter);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004536 // Won't fit.
4537 if (written > remaining) return 0;
4538 // Copy over the character from temp_buffer.
4539 for (int j = 0; j < written; j++) {
4540 buffer[j] = temp_buffer[j];
4541 }
4542 return written;
4543 }
4544
4545 template<typename Char>
4546 void Visit(const Char* chars, const int length) {
4547 using namespace unibrow;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004548 ASSERT(!early_termination_);
ulan@chromium.org750145a2013-03-07 15:14:13 +00004549 if (length == 0) return;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004550 // Copy state to stack.
4551 char* buffer = buffer_;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004552 int last_character =
4553 sizeof(Char) == 1 ? Utf16::kNoPreviousCharacter : last_character_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004554 int i = 0;
4555 // Do a fast loop where there is no exit capacity check.
4556 while (true) {
4557 int fast_length;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004558 if (skip_capacity_check_) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004559 fast_length = length;
4560 } else {
4561 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4562 // Need enough space to write everything but one character.
4563 STATIC_ASSERT(Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
ulan@chromium.org750145a2013-03-07 15:14:13 +00004564 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
4565 int writable_length =
4566 (remaining_capacity - max_size_per_char)/max_size_per_char;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004567 // Need to drop into slow loop.
4568 if (writable_length <= 0) break;
4569 fast_length = i + writable_length;
4570 if (fast_length > length) fast_length = length;
4571 }
4572 // Write the characters to the stream.
ulan@chromium.org750145a2013-03-07 15:14:13 +00004573 if (sizeof(Char) == 1) {
4574 for (; i < fast_length; i++) {
4575 buffer +=
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004576 Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
ulan@chromium.org750145a2013-03-07 15:14:13 +00004577 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
4578 }
4579 } else {
4580 for (; i < fast_length; i++) {
4581 uint16_t character = *chars++;
4582 buffer += Utf8::Encode(buffer, character, last_character);
4583 last_character = character;
4584 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
4585 }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004586 }
4587 // Array is fully written. Exit.
4588 if (fast_length == length) {
4589 // Write state back out to object.
4590 last_character_ = last_character;
4591 buffer_ = buffer;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004592 utf16_chars_read_ += length;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004593 return;
4594 }
4595 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004596 ASSERT(!skip_capacity_check_);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004597 // Slow loop. Must check capacity on each iteration.
4598 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4599 ASSERT(remaining_capacity >= 0);
4600 for (; i < length && remaining_capacity > 0; i++) {
4601 uint16_t character = *chars++;
4602 int written = WriteEndCharacter(character,
4603 last_character,
4604 remaining_capacity,
4605 buffer);
4606 if (written == 0) {
4607 early_termination_ = true;
4608 break;
4609 }
4610 buffer += written;
4611 remaining_capacity -= written;
4612 last_character = character;
4613 }
4614 // Write state back out to object.
4615 last_character_ = last_character;
4616 buffer_ = buffer;
4617 utf16_chars_read_ += i;
4618 }
4619
4620 inline bool IsDone() {
4621 return early_termination_;
4622 }
4623
ulan@chromium.org750145a2013-03-07 15:14:13 +00004624 inline void VisitOneByteString(const uint8_t* chars, int length) {
4625 Visit(chars, length);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004626 }
4627
ulan@chromium.org750145a2013-03-07 15:14:13 +00004628 inline void VisitTwoByteString(const uint16_t* chars, int length) {
4629 Visit(chars, length);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004630 }
4631
ulan@chromium.org750145a2013-03-07 15:14:13 +00004632 int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004633 // Write out number of utf16 characters written to the stream.
4634 if (utf16_chars_read_out != NULL) {
4635 *utf16_chars_read_out = utf16_chars_read_;
4636 }
4637 // Only null terminate if all of the string was written and there's space.
4638 if (write_null &&
4639 !early_termination_ &&
4640 (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
4641 *buffer_++ = '\0';
4642 }
4643 return static_cast<int>(buffer_ - start_);
4644 }
4645
4646 private:
4647 bool early_termination_;
4648 int last_character_;
4649 char* buffer_;
4650 char* const start_;
4651 int capacity_;
ulan@chromium.org750145a2013-03-07 15:14:13 +00004652 bool const skip_capacity_check_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00004653 int utf16_chars_read_;
4654 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
4655};
4656
4657
ulan@chromium.org750145a2013-03-07 15:14:13 +00004658static bool RecursivelySerializeToUtf8(i::String* current,
4659 Utf8WriterVisitor* writer,
4660 int recursion_budget) {
4661 while (!writer->IsDone()) {
4662 i::ConsString* cons_string = i::String::VisitFlat(writer, current);
4663 if (cons_string == NULL) return true; // Leaf node.
4664 if (recursion_budget <= 0) return false;
4665 // Must write the left branch first.
4666 i::String* first = cons_string->first();
4667 bool success = RecursivelySerializeToUtf8(first,
4668 writer,
4669 recursion_budget - 1);
4670 if (!success) return false;
4671 // Inline tail recurse for right branch.
4672 current = cons_string->second();
4673 }
4674 return true;
4675}
4676
4677
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00004678int String::WriteUtf8(char* buffer,
4679 int capacity,
4680 int* nchars_ref,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004681 int options) const {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004682 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004683 LOG_API(isolate, "String::WriteUtf8");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004684 ENTER_V8(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00004685 i::Handle<i::String> str = Utils::OpenHandle(this);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004686 if (options & HINT_MANY_WRITES_EXPECTED) {
4687 FlattenString(str); // Flatten the string for efficiency.
4688 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004689 const int string_length = str->length();
4690 bool write_null = !(options & NO_NULL_TERMINATION);
4691 // First check if we can just write the string without checking capacity.
4692 if (capacity == -1 || capacity / 3 >= string_length) {
4693 Utf8WriterVisitor writer(buffer, capacity, true);
4694 const int kMaxRecursion = 100;
4695 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
4696 if (success) return writer.CompleteWrite(write_null, nchars_ref);
4697 } else if (capacity >= string_length) {
4698 // First check that the buffer is large enough.
4699 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
4700 if (utf8_bytes <= capacity) {
4701 // ASCII fast path.
4702 if (utf8_bytes == string_length) {
4703 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
4704 if (nchars_ref != NULL) *nchars_ref = string_length;
4705 if (write_null && (utf8_bytes+1 <= capacity)) {
4706 return string_length + 1;
4707 }
4708 return string_length;
4709 }
4710 if (write_null && (utf8_bytes+1 > capacity)) {
4711 options |= NO_NULL_TERMINATION;
4712 }
4713 // Recurse once without a capacity limit.
4714 // This will get into the first branch above.
4715 // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
4716 return WriteUtf8(buffer, -1, nchars_ref, options);
danno@chromium.org88aa0582012-03-23 15:11:57 +00004717 }
4718 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00004719 // Recursive slow path can potentially be unreasonable slow. Flatten.
4720 str = FlattenGetString(str);
4721 Utf8WriterVisitor writer(buffer, capacity, false);
4722 i::String::VisitFlat(&writer, *str);
4723 return writer.CompleteWrite(write_null, nchars_ref);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00004724}
4725
4726
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004727template<typename CharType>
4728static inline int WriteHelper(const String* string,
4729 CharType* buffer,
4730 int start,
4731 int length,
4732 int options) {
4733 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004734 LOG_API(isolate, "String::Write");
4735 ENTER_V8(isolate);
4736 ASSERT(start >= 0 && length >= -1);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004737 i::Handle<i::String> str = Utils::OpenHandle(string);
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004738 isolate->string_tracker()->RecordWrite(str);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004739 if (options & String::HINT_MANY_WRITES_EXPECTED) {
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004740 // Flatten the string for efficiency. This applies whether we are
4741 // using StringCharacterStream or Get(i) to access the characters.
4742 FlattenString(str);
4743 }
4744 int end = start + length;
4745 if ((length == -1) || (length > str->length() - start) )
4746 end = str->length();
4747 if (end < 0) return 0;
4748 i::String::WriteToFlat(*str, buffer, start, end);
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004749 if (!(options & String::NO_NULL_TERMINATION) &&
yangguo@chromium.orge19986e2013-01-16 09:48:20 +00004750 (length == -1 || end - start < length)) {
4751 buffer[end - start] = '\0';
4752 }
4753 return end - start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004754}
4755
4756
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00004757int String::WriteOneByte(uint8_t* buffer,
4758 int start,
4759 int length,
4760 int options) const {
4761 return WriteHelper(this, buffer, start, length, options);
4762}
4763
4764
4765int String::Write(uint16_t* buffer,
4766 int start,
4767 int length,
4768 int options) const {
4769 return WriteHelper(this, buffer, start, length, options);
4770}
4771
4772
ager@chromium.org32912102009-01-16 10:38:43 +00004773bool v8::String::IsExternal() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004774 i::Handle<i::String> str = Utils::OpenHandle(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004775 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004776 return i::StringShape(*str).IsExternalTwoByte();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004777}
4778
4779
ager@chromium.org32912102009-01-16 10:38:43 +00004780bool v8::String::IsExternalAscii() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004781 i::Handle<i::String> str = Utils::OpenHandle(this);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004782 return i::StringShape(*str).IsExternalAscii();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004783}
4784
4785
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004786void v8::String::VerifyExternalStringResource(
4787 v8::String::ExternalStringResource* value) const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004788 i::Handle<i::String> str = Utils::OpenHandle(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004789 const v8::String::ExternalStringResource* expected;
ager@chromium.org9085a012009-05-11 19:22:57 +00004790 if (i::StringShape(*str).IsExternalTwoByte()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004791 const void* resource =
4792 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4793 expected = reinterpret_cast<const ExternalStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004794 } else {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004795 expected = NULL;
ager@chromium.org9085a012009-05-11 19:22:57 +00004796 }
ager@chromium.org18ad94b2009-09-02 08:22:29 +00004797 CHECK_EQ(expected, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004798}
4799
ulan@chromium.org56c14af2012-09-20 12:51:09 +00004800void v8::String::VerifyExternalStringResourceBase(
4801 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
4802 i::Handle<i::String> str = Utils::OpenHandle(this);
4803 const v8::String::ExternalStringResourceBase* expected;
4804 Encoding expectedEncoding;
4805 if (i::StringShape(*str).IsExternalAscii()) {
4806 const void* resource =
4807 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
4808 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4809 expectedEncoding = ASCII_ENCODING;
4810 } else if (i::StringShape(*str).IsExternalTwoByte()) {
4811 const void* resource =
4812 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4813 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4814 expectedEncoding = TWO_BYTE_ENCODING;
4815 } else {
4816 expected = NULL;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004817 expectedEncoding = str->IsOneByteRepresentation() ? ASCII_ENCODING
ulan@chromium.org56c14af2012-09-20 12:51:09 +00004818 : TWO_BYTE_ENCODING;
4819 }
4820 CHECK_EQ(expected, value);
4821 CHECK_EQ(expectedEncoding, encoding);
4822}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004823
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004824const v8::String::ExternalAsciiStringResource*
ager@chromium.org32912102009-01-16 10:38:43 +00004825 v8::String::GetExternalAsciiStringResource() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004826 i::Handle<i::String> str = Utils::OpenHandle(this);
ager@chromium.org9085a012009-05-11 19:22:57 +00004827 if (i::StringShape(*str).IsExternalAscii()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004828 const void* resource =
4829 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
4830 return reinterpret_cast<const ExternalAsciiStringResource*>(resource);
ager@chromium.org9085a012009-05-11 19:22:57 +00004831 } else {
4832 return NULL;
4833 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004834}
4835
4836
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004837Local<Value> Symbol::Name() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004838 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
4839 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
4840 return Utils::ToLocal(name);
4841}
4842
4843
ager@chromium.org32912102009-01-16 10:38:43 +00004844double Number::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004845 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4846 return obj->Number();
4847}
4848
4849
ager@chromium.org32912102009-01-16 10:38:43 +00004850bool Boolean::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004851 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4852 return obj->IsTrue();
4853}
4854
4855
ager@chromium.org32912102009-01-16 10:38:43 +00004856int64_t Integer::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004857 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4858 if (obj->IsSmi()) {
4859 return i::Smi::cast(*obj)->value();
4860 } else {
4861 return static_cast<int64_t>(obj->Number());
4862 }
4863}
4864
4865
ager@chromium.org32912102009-01-16 10:38:43 +00004866int32_t Int32::Value() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004867 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4868 if (obj->IsSmi()) {
4869 return i::Smi::cast(*obj)->value();
4870 } else {
4871 return static_cast<int32_t>(obj->Number());
4872 }
4873}
4874
4875
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004876uint32_t Uint32::Value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004877 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4878 if (obj->IsSmi()) {
4879 return i::Smi::cast(*obj)->value();
4880 } else {
4881 return static_cast<uint32_t>(obj->Number());
4882 }
4883}
4884
4885
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004886int v8::Object::InternalFieldCount() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004887 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004888 return obj->GetInternalFieldCount();
4889}
4890
4891
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004892static bool InternalFieldOK(i::Handle<i::JSObject> obj,
4893 int index,
4894 const char* location) {
machenbach@chromium.orgae161032013-09-24 09:12:30 +00004895 return ApiCheck(index < obj->GetInternalFieldCount(),
4896 location,
4897 "Internal field out of bounds");
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004898}
4899
4900
4901Local<Value> v8::Object::SlowGetInternalField(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004902 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004903 const char* location = "v8::Object::GetInternalField()";
4904 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
4905 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
4906 return Utils::ToLocal(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004907}
4908
4909
kasper.lund212ac232008-07-16 07:07:30 +00004910void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004911 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004912 const char* location = "v8::Object::SetInternalField()";
4913 if (!InternalFieldOK(obj, index, location)) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004914 i::Handle<i::Object> val = Utils::OpenHandle(*value);
4915 obj->SetInternalField(index, *val);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004916 ASSERT_EQ(value, GetInternalField(index));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004917}
4918
4919
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004920void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
4921 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4922 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
4923 if (!InternalFieldOK(obj, index, location)) return NULL;
4924 return DecodeSmiToAligned(obj->GetInternalField(index), location);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004925}
4926
4927
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004928void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
4929 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4930 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
4931 if (!InternalFieldOK(obj, index, location)) return;
4932 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
4933 ASSERT_EQ(value, GetAlignedPointerFromInternalField(index));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004934}
4935
4936
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00004937static void* ExternalValue(i::Object* obj) {
4938 // Obscure semantics for undefined, but somehow checked in our unit tests...
4939 if (obj->IsUndefined()) return NULL;
4940 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
4941 return i::Foreign::cast(foreign)->foreign_address();
4942}
4943
4944
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004945// --- E n v i r o n m e n t ---
4946
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004947
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004948bool v8::V8::Initialize() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00004949 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004950 if (isolate != NULL && isolate->IsInitialized()) {
4951 return true;
4952 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004953 return InitializeHelper(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004954}
4955
4956
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00004957void v8::V8::SetEntropySource(EntropySource entropy_source) {
4958 i::RandomNumberGenerator::SetEntropySource(entropy_source);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00004959}
4960
4961
ulan@chromium.org967e2702012-02-28 09:49:15 +00004962void v8::V8::SetReturnAddressLocationResolver(
4963 ReturnAddressLocationResolver return_address_resolver) {
4964 i::V8::SetReturnAddressLocationResolver(return_address_resolver);
4965}
4966
4967
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004968bool v8::V8::SetFunctionEntryHook(Isolate* ext_isolate,
4969 FunctionEntryHook entry_hook) {
4970 ASSERT(ext_isolate != NULL);
4971 ASSERT(entry_hook != NULL);
4972
4973 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(ext_isolate);
4974
4975 // The entry hook can only be set before the Isolate is initialized, as
4976 // otherwise the Isolate's code stubs generated at initialization won't
4977 // contain entry hooks.
4978 if (isolate->IsInitialized())
4979 return false;
4980
4981 // Setting an entry hook is a one-way operation, once set, it cannot be
4982 // changed or unset.
4983 if (isolate->function_entry_hook() != NULL)
4984 return false;
4985
4986 isolate->set_function_entry_hook(entry_hook);
4987 return true;
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004988}
4989
4990
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004991void v8::V8::SetJitCodeEventHandler(
4992 JitCodeEventOptions options, JitCodeEventHandler event_handler) {
4993 i::Isolate* isolate = i::Isolate::Current();
4994 // Ensure that logging is initialized for our isolate.
4995 isolate->InitializeLoggingAndCounters();
4996 isolate->logger()->SetCodeEventHandler(options, event_handler);
4997}
4998
ulan@chromium.org837a67e2013-06-11 15:39:48 +00004999void v8::V8::SetArrayBufferAllocator(
5000 ArrayBuffer::Allocator* allocator) {
5001 if (!ApiCheck(i::V8::ArrayBufferAllocator() == NULL,
5002 "v8::V8::SetArrayBufferAllocator",
5003 "ArrayBufferAllocator might only be set once"))
5004 return;
5005 i::V8::SetArrayBufferAllocator(allocator);
5006}
5007
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00005008
ager@chromium.org41826e72009-03-30 13:30:57 +00005009bool v8::V8::Dispose() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005010 i::Isolate* isolate = i::Isolate::Current();
5011 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
5012 "v8::V8::Dispose()",
5013 "Use v8::Isolate::Dispose() for a non-default isolate.")) {
5014 return false;
5015 }
ager@chromium.org41826e72009-03-30 13:30:57 +00005016 i::V8::TearDown();
5017 return true;
5018}
5019
5020
ager@chromium.org01fe7df2010-11-10 11:59:11 +00005021HeapStatistics::HeapStatistics(): total_heap_size_(0),
5022 total_heap_size_executable_(0),
danno@chromium.org72204d52012-10-31 10:02:10 +00005023 total_physical_size_(0),
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005024 used_heap_size_(0),
5025 heap_size_limit_(0) { }
ager@chromium.org3811b432009-10-28 14:53:37 +00005026
5027
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005028void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
5029 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005030 isolate->heap()->VisitExternalResources(visitor);
5031}
5032
5033
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005034class VisitorAdapter : public i::ObjectVisitor {
5035 public:
5036 explicit VisitorAdapter(PersistentHandleVisitor* visitor)
5037 : visitor_(visitor) {}
5038 virtual void VisitPointers(i::Object** start, i::Object** end) {
5039 UNREACHABLE();
5040 }
5041 virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00005042 Value* value = ToApi<Value>(i::Handle<i::Object>(p));
5043 visitor_->VisitPersistentHandle(
5044 reinterpret_cast<Persistent<Value>*>(&value), class_id);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005045 }
5046 private:
5047 PersistentHandleVisitor* visitor_;
5048};
5049
5050
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005051void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
5052 i::Isolate* isolate = i::Isolate::Current();
rossberg@chromium.org79e79022013-06-03 15:43:46 +00005053 i::DisallowHeapAllocation no_allocation;
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005054
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005055 VisitorAdapter visitor_adapter(visitor);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005056 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
5057}
5058
5059
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005060void v8::V8::VisitHandlesForPartialDependence(
5061 Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
5062 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
5063 ASSERT(isolate == i::Isolate::Current());
rossberg@chromium.org79e79022013-06-03 15:43:46 +00005064 i::DisallowHeapAllocation no_allocation;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005065
5066 VisitorAdapter visitor_adapter(visitor);
5067 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
5068 &visitor_adapter);
5069}
5070
5071
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00005072bool v8::V8::IdleNotification(int hint) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00005073 // Returning true tells the caller that it need not
5074 // continue to call IdleNotification.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005075 i::Isolate* isolate = i::Isolate::Current();
5076 if (isolate == NULL || !isolate->IsInitialized()) return true;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00005077 if (!i::FLAG_use_idle_notification) return true;
5078 return isolate->heap()->IdleNotification(hint);
ager@chromium.orgadd848f2009-08-13 12:44:13 +00005079}
5080
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005081
5082void v8::V8::LowMemoryNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005083 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005084 if (isolate == NULL || !isolate->IsInitialized()) return;
rossberg@chromium.org994edf62012-02-06 10:12:55 +00005085 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00005086}
5087
5088
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00005089int v8::V8::ContextDisposedNotification() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005090 i::Isolate* isolate = i::Isolate::Current();
5091 if (!isolate->IsInitialized()) return 0;
5092 return isolate->heap()->NotifyContextDisposed();
kasperl@chromium.org8b2bb262010-03-01 09:46:28 +00005093}
5094
5095
danno@chromium.org169691d2013-07-15 08:01:13 +00005096bool v8::V8::InitializeICU() {
5097 return i::InitializeICU();
5098}
5099
5100
kasper.lund7276f142008-07-30 08:49:36 +00005101const char* v8::V8::GetVersion() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005102 return i::Version::GetVersion();
kasper.lund7276f142008-07-30 08:49:36 +00005103}
5104
5105
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005106static i::Handle<i::Context> CreateEnvironment(
5107 i::Isolate* isolate,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005108 v8::ExtensionConfiguration* extensions,
5109 v8::Handle<ObjectTemplate> global_template,
5110 v8::Handle<Value> global_object) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005111 i::Handle<i::Context> env;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005112
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005113 // Enter V8 via an ENTER_V8 scope.
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005114 {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005115 ENTER_V8(isolate);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005116 v8::Handle<ObjectTemplate> proxy_template = global_template;
5117 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5118 i::Handle<i::FunctionTemplateInfo> global_constructor;
ager@chromium.org8bb60582008-12-11 12:02:20 +00005119
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005120 if (!global_template.IsEmpty()) {
5121 // Make sure that the global_template has a constructor.
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00005122 global_constructor = EnsureConstructor(*global_template);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005123
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005124 // Create a fresh template for the global proxy object.
5125 proxy_template = ObjectTemplate::New();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00005126 proxy_constructor = EnsureConstructor(*proxy_template);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005127
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005128 // Set the global template to be the prototype template of
5129 // global proxy template.
5130 proxy_constructor->set_prototype_template(
5131 *Utils::OpenHandle(*global_template));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005132
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005133 // Migrate security handlers from global_template to
5134 // proxy_template. Temporarily removing access check
5135 // information from the global template.
5136 if (!global_constructor->access_check_info()->IsUndefined()) {
5137 proxy_constructor->set_access_check_info(
5138 global_constructor->access_check_info());
5139 proxy_constructor->set_needs_access_check(
5140 global_constructor->needs_access_check());
5141 global_constructor->set_needs_access_check(false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005142 global_constructor->set_access_check_info(
5143 isolate->heap()->undefined_value());
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005144 }
5145 }
5146
5147 // Create the environment.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005148 env = isolate->bootstrapper()->CreateEnvironment(
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00005149 Utils::OpenHandle(*global_object, true),
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005150 proxy_template,
5151 extensions);
5152
5153 // Restore the access check info on the global template.
5154 if (!global_template.IsEmpty()) {
5155 ASSERT(!global_constructor.is_null());
5156 ASSERT(!proxy_constructor.is_null());
5157 global_constructor->set_access_check_info(
5158 proxy_constructor->access_check_info());
5159 global_constructor->set_needs_access_check(
5160 proxy_constructor->needs_access_check());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005161 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005162 isolate->runtime_profiler()->Reset();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005163 }
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +00005164 // Leave V8.
ager@chromium.org8bb60582008-12-11 12:02:20 +00005165
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005166 return env;
5167}
5168
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005169Local<Context> v8::Context::New(
5170 v8::Isolate* external_isolate,
5171 v8::ExtensionConfiguration* extensions,
5172 v8::Handle<ObjectTemplate> global_template,
5173 v8::Handle<Value> global_object) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005174 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5175 EnsureInitializedForIsolate(isolate, "v8::Context::New()");
5176 LOG_API(isolate, "Context::New");
5177 ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
5178 i::HandleScope scope(isolate);
5179 i::Handle<i::Context> env =
5180 CreateEnvironment(isolate, extensions, global_template, global_object);
5181 if (env.is_null()) return Local<Context>();
5182 return Utils::ToLocal(scope.CloseAndEscape(env));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005183}
5184
5185
5186void v8::Context::SetSecurityToken(Handle<Value> token) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005187 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005188 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005189 i::Handle<i::Context> env = Utils::OpenHandle(this);
5190 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005191 env->set_security_token(*token_handle);
5192}
5193
5194
5195void v8::Context::UseDefaultSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005196 i::Isolate* isolate = i::Isolate::Current();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005197 ENTER_V8(isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005198 i::Handle<i::Context> env = Utils::OpenHandle(this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005199 env->set_security_token(env->global_object());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005200}
5201
5202
5203Handle<Value> v8::Context::GetSecurityToken() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005204 i::Isolate* isolate = i::Isolate::Current();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005205 i::Handle<i::Context> env = Utils::OpenHandle(this);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005206 i::Object* security_token = env->security_token();
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005207 i::Handle<i::Object> token_handle(security_token, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005208 return Utils::ToLocal(token_handle);
5209}
5210
5211
5212bool Context::HasOutOfMemoryException() {
5213 i::Handle<i::Context> env = Utils::OpenHandle(this);
5214 return env->has_out_of_memory();
5215}
5216
5217
5218bool Context::InContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005219 return i::Isolate::Current()->context() != NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005220}
5221
5222
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005223v8::Isolate* Context::GetIsolate() {
5224 i::Handle<i::Context> env = Utils::OpenHandle(this);
5225 return reinterpret_cast<Isolate*>(env->GetIsolate());
5226}
5227
5228
kasper.lund44510672008-07-25 07:37:58 +00005229v8::Local<v8::Context> Context::GetEntered() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005230 i::Isolate* isolate = i::Isolate::Current();
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00005231 if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005232 return Local<Context>();
5233 }
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005234 return reinterpret_cast<Isolate*>(isolate)->GetEnteredContext();
kasper.lund44510672008-07-25 07:37:58 +00005235}
5236
5237
5238v8::Local<v8::Context> Context::GetCurrent() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005239 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005240 return reinterpret_cast<Isolate*>(isolate)->GetCurrentContext();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005241}
5242
5243
ager@chromium.org1bf0cd02009-05-20 11:34:19 +00005244v8::Local<v8::Context> Context::GetCalling() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005245 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005246 return reinterpret_cast<Isolate*>(isolate)->GetCallingContext();
ager@chromium.org1bf0cd02009-05-20 11:34:19 +00005247}
5248
5249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005250v8::Local<v8::Object> Context::Global() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005251 i::Handle<i::Context> context = Utils::OpenHandle(this);
5252 i::Isolate* isolate = context->GetIsolate();
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005253 i::Handle<i::Object> global(context->global_proxy(), isolate);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005254 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5255}
5256
5257
5258void Context::DetachGlobal() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005259 i::Handle<i::Context> context = Utils::OpenHandle(this);
5260 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005261 ENTER_V8(isolate);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005262 isolate->bootstrapper()->DetachGlobal(context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005263}
5264
5265
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00005266void Context::ReattachGlobal(Handle<Object> global_object) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005267 i::Handle<i::Context> context = Utils::OpenHandle(this);
5268 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005269 ENTER_V8(isolate);
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00005270 i::Handle<i::JSGlobalProxy> global_proxy =
5271 i::Handle<i::JSGlobalProxy>::cast(Utils::OpenHandle(*global_object));
5272 isolate->bootstrapper()->ReattachGlobal(context, global_proxy);
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00005273}
5274
5275
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005276void Context::AllowCodeGenerationFromStrings(bool allow) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005277 i::Handle<i::Context> context = Utils::OpenHandle(this);
5278 i::Isolate* isolate = context->GetIsolate();
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005279 ENTER_V8(isolate);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00005280 context->set_allow_code_gen_from_strings(
5281 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5282}
5283
5284
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00005285bool Context::IsCodeGenerationFromStringsAllowed() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005286 i::Handle<i::Context> context = Utils::OpenHandle(this);
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00005287 return !context->allow_code_gen_from_strings()->IsFalse();
5288}
5289
5290
ulan@chromium.org56c14af2012-09-20 12:51:09 +00005291void Context::SetErrorMessageForCodeGenerationFromStrings(
5292 Handle<String> error) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005293 i::Handle<i::Context> context = Utils::OpenHandle(this);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005294 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00005295 context->set_error_message_for_code_gen_from_strings(*error_handle);
5296}
5297
5298
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005299Local<v8::Object> ObjectTemplate::NewInstance() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005300 i::Isolate* isolate = i::Isolate::Current();
5301 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
5302 return Local<v8::Object>());
5303 LOG_API(isolate, "ObjectTemplate::NewInstance");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005304 ENTER_V8(isolate);
5305 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005306 i::Handle<i::Object> obj =
5307 i::Execution::InstantiateObject(Utils::OpenHandle(this),
5308 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005309 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005310 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
5311}
5312
5313
5314Local<v8::Function> FunctionTemplate::GetFunction() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005315 i::Isolate* isolate = i::Isolate::Current();
5316 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005317 return Local<v8::Function>());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005318 LOG_API(isolate, "FunctionTemplate::GetFunction");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005319 ENTER_V8(isolate);
5320 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005321 i::Handle<i::Object> obj =
5322 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
5323 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005324 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005325 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
5326}
5327
5328
5329bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005330 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
5331 return false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005332 i::Object* obj = *Utils::OpenHandle(*value);
5333 return obj->IsInstanceOf(*Utils::OpenHandle(this));
5334}
5335
5336
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005337Local<External> v8::External::New(void* value) {
5338 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005339 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005340 EnsureInitializedForIsolate(isolate, "v8::External::New()");
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005341 LOG_API(isolate, "External::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005342 ENTER_V8(isolate);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005343 i::Handle<i::JSObject> external = isolate->factory()->NewExternal(value);
5344 return Utils::ExternalToLocal(external);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005345}
5346
5347
5348void* External::Value() const {
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00005349 return ExternalValue(*Utils::OpenHandle(this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005350}
5351
5352
ager@chromium.org563b8dc2009-03-20 14:23:52 +00005353Local<String> v8::String::Empty() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005354 i::Isolate* isolate = i::Isolate::Current();
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00005355 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) {
5356 return v8::Local<String>();
5357 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005358 LOG_API(isolate, "String::Empty()");
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005359 return Utils::ToLocal(isolate->factory()->empty_string());
ager@chromium.org563b8dc2009-03-20 14:23:52 +00005360}
5361
5362
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00005363// anonymous namespace for string creation helper functions
5364namespace {
5365
5366inline int StringLength(const char* string) {
5367 return i::StrLength(string);
5368}
5369
5370
5371inline int StringLength(const uint8_t* string) {
5372 return i::StrLength(reinterpret_cast<const char*>(string));
5373}
5374
5375
5376inline int StringLength(const uint16_t* string) {
5377 int length = 0;
5378 while (string[length] != '\0')
5379 length++;
5380 return length;
5381}
5382
5383
5384inline i::Handle<i::String> NewString(i::Factory* factory,
5385 String::NewStringType type,
5386 i::Vector<const char> string) {
5387 if (type ==String::kInternalizedString) {
5388 return factory->InternalizeUtf8String(string);
5389 }
5390 return factory->NewStringFromUtf8(string);
5391}
5392
5393
5394inline i::Handle<i::String> NewString(i::Factory* factory,
5395 String::NewStringType type,
5396 i::Vector<const uint8_t> string) {
5397 if (type == String::kInternalizedString) {
5398 return factory->InternalizeOneByteString(string);
5399 }
5400 return factory->NewStringFromOneByte(string);
5401}
5402
5403
5404inline i::Handle<i::String> NewString(i::Factory* factory,
5405 String::NewStringType type,
5406 i::Vector<const uint16_t> string) {
5407 if (type == String::kInternalizedString) {
5408 return factory->InternalizeTwoByteString(string);
5409 }
5410 return factory->NewStringFromTwoByte(string);
5411}
5412
5413
5414template<typename Char>
5415inline Local<String> NewString(Isolate* v8_isolate,
5416 const char* location,
5417 const char* env,
5418 const Char* data,
5419 String::NewStringType type,
5420 int length) {
5421 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
5422 EnsureInitializedForIsolate(isolate, location);
5423 LOG_API(isolate, env);
5424 if (length == 0 && type != String::kUndetectableString) {
5425 return String::Empty();
5426 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005427 ENTER_V8(isolate);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00005428 if (length == -1) length = StringLength(data);
5429 i::Handle<i::String> result = NewString(
5430 isolate->factory(), type, i::Vector<const Char>(data, length));
5431 if (type == String::kUndetectableString) {
5432 result->MarkAsUndetectable();
5433 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005434 return Utils::ToLocal(result);
5435}
5436
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00005437} // anonymous namespace
5438
5439
5440Local<String> String::NewFromUtf8(Isolate* isolate,
5441 const char* data,
5442 NewStringType type,
5443 int length) {
5444 return NewString(isolate,
5445 "v8::String::NewFromUtf8()",
5446 "String::NewFromUtf8",
5447 data,
5448 type,
5449 length);
5450}
5451
5452
5453Local<String> String::NewFromOneByte(Isolate* isolate,
5454 const uint8_t* data,
5455 NewStringType type,
5456 int length) {
5457 return NewString(isolate,
5458 "v8::String::NewFromOneByte()",
5459 "String::NewFromOneByte",
5460 data,
5461 type,
5462 length);
5463}
5464
5465
5466Local<String> String::NewFromTwoByte(Isolate* isolate,
5467 const uint16_t* data,
5468 NewStringType type,
5469 int length) {
5470 return NewString(isolate,
5471 "v8::String::NewFromTwoByte()",
5472 "String::NewFromTwoByte",
5473 data,
5474 type,
5475 length);
5476}
5477
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005478
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005479Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005480 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005481 i::Isolate* isolate = left_string->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005482 EnsureInitializedForIsolate(isolate, "v8::String::New()");
5483 LOG_API(isolate, "String::New(char)");
5484 ENTER_V8(isolate);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005485 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005486 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
5487 right_string);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00005488 return Utils::ToLocal(result);
5489}
5490
5491
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005492i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005493 v8::String::ExternalStringResource* resource) {
5494 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005495 isolate->factory()->NewExternalStringFromTwoByte(resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005496 return result;
5497}
5498
5499
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005500i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005501 v8::String::ExternalAsciiStringResource* resource) {
5502 i::Handle<i::String> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005503 isolate->factory()->NewExternalStringFromAscii(resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005504 return result;
5505}
5506
5507
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005508bool RedirectToExternalString(i::Isolate* isolate,
5509 i::Handle<i::String> parent,
5510 i::Handle<i::String> external) {
5511 if (parent->IsConsString()) {
5512 i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent);
5513 cons->set_first(*external);
5514 cons->set_second(isolate->heap()->empty_string());
5515 } else {
5516 ASSERT(parent->IsSlicedString());
5517 i::Handle<i::SlicedString> slice = i::Handle<i::SlicedString>::cast(parent);
5518 slice->set_parent(*external);
5519 slice->set_offset(0);
5520 }
5521 return true;
5522}
5523
5524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005525Local<String> v8::String::NewExternal(
5526 v8::String::ExternalStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005527 i::Isolate* isolate = i::Isolate::Current();
5528 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
5529 LOG_API(isolate, "String::NewExternal");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005530 ENTER_V8(isolate);
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005531 CHECK(resource && resource->data());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005532 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
5533 isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005534 return Utils::ToLocal(result);
5535}
5536
5537
ager@chromium.org6f10e412009-02-13 10:11:16 +00005538bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005539 i::Handle<i::String> obj = Utils::OpenHandle(this);
5540 i::Isolate* isolate = obj->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005541 if (i::StringShape(*obj).IsExternalTwoByte()) {
5542 return false; // Already an external string.
5543 }
5544 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005545 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5546 return false;
5547 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005548 if (isolate->heap()->IsInGCPostProcessing()) {
5549 return false;
5550 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005551 CHECK(resource && resource->data());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005552
5553 bool result;
5554 i::Handle<i::String> external;
5555 if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
5556 // We do not allow external strings in the old pointer space. Instead of
5557 // converting the string in-place, we keep the cons/sliced string and
5558 // point it to a newly-allocated external string.
5559 external = NewExternalStringHandle(isolate, resource);
5560 result = RedirectToExternalString(isolate, obj, external);
5561 } else {
5562 result = obj->MakeExternal(resource);
5563 external = obj;
5564 }
5565
5566 ASSERT(external->IsExternalString());
5567 if (result && !external->IsInternalizedString()) {
5568 isolate->heap()->external_string_table()->AddString(*external);
ager@chromium.org6f10e412009-02-13 10:11:16 +00005569 }
5570 return result;
5571}
5572
5573
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005574Local<String> v8::String::NewExternal(
5575 v8::String::ExternalAsciiStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005576 i::Isolate* isolate = i::Isolate::Current();
5577 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
5578 LOG_API(isolate, "String::NewExternal");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005579 ENTER_V8(isolate);
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005580 CHECK(resource && resource->data());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005581 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
5582 isolate->heap()->external_string_table()->AddString(*result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005583 return Utils::ToLocal(result);
5584}
5585
5586
ager@chromium.org6f10e412009-02-13 10:11:16 +00005587bool v8::String::MakeExternal(
5588 v8::String::ExternalAsciiStringResource* resource) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005589 i::Handle<i::String> obj = Utils::OpenHandle(this);
5590 i::Isolate* isolate = obj->GetIsolate();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005591 if (i::StringShape(*obj).IsExternalTwoByte()) {
5592 return false; // Already an external string.
5593 }
5594 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005595 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5596 return false;
5597 }
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005598 if (isolate->heap()->IsInGCPostProcessing()) {
5599 return false;
5600 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00005601 CHECK(resource && resource->data());
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005602
5603 bool result;
5604 i::Handle<i::String> external;
5605 if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
5606 // We do not allow external strings in the old pointer space. Instead of
5607 // converting the string in-place, we keep the cons/sliced string and
5608 // point it to a newly-allocated external string.
5609 external = NewExternalAsciiStringHandle(isolate, resource);
5610 result = RedirectToExternalString(isolate, obj, external);
5611 } else {
5612 result = obj->MakeExternal(resource);
5613 external = obj;
5614 }
5615
5616 ASSERT(external->IsExternalString());
5617 if (result && !external->IsInternalizedString()) {
5618 isolate->heap()->external_string_table()->AddString(*external);
ager@chromium.org6f10e412009-02-13 10:11:16 +00005619 }
5620 return result;
5621}
5622
5623
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005624bool v8::String::CanMakeExternal() {
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00005625 if (!internal::FLAG_clever_optimizations) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005626 i::Handle<i::String> obj = Utils::OpenHandle(this);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005627 i::Isolate* isolate = obj->GetIsolate();
jkummerow@chromium.org32aa03c2013-10-01 08:21:50 +00005628
5629 // TODO(yangguo): Externalizing sliced/cons strings allocates.
5630 // This rule can be removed when all code that can
5631 // trigger an access check is handlified and therefore GC safe.
5632 if (isolate->heap()->old_pointer_space()->Contains(*obj)) return false;
5633
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005634 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005635 int size = obj->Size(); // Byte size of the original string.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005636 if (size < i::ExternalString::kShortSize) return false;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +00005637 i::StringShape shape(*obj);
5638 return !shape.IsExternal();
5639}
5640
5641
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005642Local<v8::Object> v8::Object::New() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005643 i::Isolate* isolate = i::Isolate::Current();
5644 EnsureInitializedForIsolate(isolate, "v8::Object::New()");
5645 LOG_API(isolate, "Object::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005646 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005647 i::Handle<i::JSObject> obj =
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005648 isolate->factory()->NewJSObject(isolate->object_function());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005649 return Utils::ToLocal(obj);
5650}
5651
5652
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005653Local<v8::Value> v8::NumberObject::New(double value) {
5654 i::Isolate* isolate = i::Isolate::Current();
5655 EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
5656 LOG_API(isolate, "NumberObject::New");
5657 ENTER_V8(isolate);
5658 i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
5659 i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
5660 return Utils::ToLocal(obj);
5661}
5662
5663
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005664double v8::NumberObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005665 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005666 LOG_API(isolate, "NumberObject::NumberValue");
5667 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5668 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5669 return jsvalue->value()->Number();
5670}
5671
5672
5673Local<v8::Value> v8::BooleanObject::New(bool value) {
5674 i::Isolate* isolate = i::Isolate::Current();
5675 EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
5676 LOG_API(isolate, "BooleanObject::New");
5677 ENTER_V8(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00005678 i::Handle<i::Object> boolean(value
5679 ? isolate->heap()->true_value()
5680 : isolate->heap()->false_value(),
5681 isolate);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005682 i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
5683 return Utils::ToLocal(obj);
5684}
5685
5686
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005687bool v8::BooleanObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005688 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005689 LOG_API(isolate, "BooleanObject::BooleanValue");
5690 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5691 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5692 return jsvalue->value()->IsTrue();
5693}
5694
5695
5696Local<v8::Value> v8::StringObject::New(Handle<String> value) {
5697 i::Isolate* isolate = i::Isolate::Current();
5698 EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
5699 LOG_API(isolate, "StringObject::New");
5700 ENTER_V8(isolate);
5701 i::Handle<i::Object> obj =
5702 isolate->factory()->ToObject(Utils::OpenHandle(*value));
5703 return Utils::ToLocal(obj);
5704}
5705
5706
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005707Local<v8::String> v8::StringObject::ValueOf() const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005708 i::Isolate* isolate = i::Isolate::Current();
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00005709 LOG_API(isolate, "StringObject::StringValue");
5710 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5711 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5712 return Utils::ToLocal(
5713 i::Handle<i::String>(i::String::cast(jsvalue->value())));
5714}
5715
5716
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005717Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
5718 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5719 EnsureInitializedForIsolate(i_isolate, "v8::SymbolObject::New()");
5720 LOG_API(i_isolate, "SymbolObject::New");
5721 ENTER_V8(i_isolate);
5722 i::Handle<i::Object> obj =
5723 i_isolate->factory()->ToObject(Utils::OpenHandle(*value));
5724 return Utils::ToLocal(obj);
5725}
5726
5727
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005728Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005729 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005730 LOG_API(isolate, "SymbolObject::SymbolValue");
5731 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5732 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5733 return Utils::ToLocal(
5734 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
5735}
5736
5737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005738Local<v8::Value> v8::Date::New(double time) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005739 i::Isolate* isolate = i::Isolate::Current();
5740 EnsureInitializedForIsolate(isolate, "v8::Date::New()");
5741 LOG_API(isolate, "Date::New");
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00005742 if (std::isnan(time)) {
ager@chromium.org3811b432009-10-28 14:53:37 +00005743 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5744 time = i::OS::nan_value();
5745 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005746 ENTER_V8(isolate);
5747 EXCEPTION_PREAMBLE(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005748 i::Handle<i::Object> obj =
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00005749 i::Execution::NewDate(isolate, time, &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005750 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005751 return Utils::ToLocal(obj);
5752}
5753
5754
danno@chromium.orgd3c42102013-08-01 16:58:23 +00005755double v8::Date::ValueOf() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005756 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005757 LOG_API(isolate, "Date::NumberValue");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005758 i::Handle<i::Object> obj = Utils::OpenHandle(this);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005759 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
5760 return jsdate->value()->Number();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005761}
5762
5763
whesse@chromium.org023421e2010-12-21 12:19:12 +00005764void v8::Date::DateTimeConfigurationChangeNotification() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005765 i::Isolate* isolate = i::Isolate::Current();
5766 ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
5767 return);
5768 LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005769 ENTER_V8(isolate);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005770
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005771 isolate->date_cache()->ResetDateCache();
5772
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005773 i::HandleScope scope(isolate);
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005774 // Get the function ResetDateCache (defined in date.js).
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005775 i::Handle<i::String> func_name_str =
5776 isolate->factory()->InternalizeOneByteString(
5777 STATIC_ASCII_VECTOR("ResetDateCache"));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005778 i::MaybeObject* result =
5779 isolate->js_builtins_object()->GetProperty(*func_name_str);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005780 i::Object* object_func;
5781 if (!result->ToObject(&object_func)) {
5782 return;
5783 }
5784
5785 if (object_func->IsJSFunction()) {
5786 i::Handle<i::JSFunction> func =
5787 i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
5788
5789 // Call ResetDateCache(0 but expect no exceptions:
5790 bool caught_exception = false;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005791 i::Execution::TryCall(func,
5792 isolate->js_builtins_object(),
5793 0,
5794 NULL,
5795 &caught_exception);
whesse@chromium.org023421e2010-12-21 12:19:12 +00005796 }
5797}
5798
5799
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005800static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00005801 i::Isolate* isolate = i::Isolate::Current();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00005802 uint8_t flags_buf[3];
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005803 int num_flags = 0;
5804 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
5805 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
5806 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
5807 ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00005808 return isolate->factory()->InternalizeOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00005809 i::Vector<const uint8_t>(flags_buf, num_flags));
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005810}
5811
5812
5813Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
5814 Flags flags) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005815 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005816 EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
5817 LOG_API(isolate, "RegExp::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005818 ENTER_V8(isolate);
5819 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005820 i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
5821 Utils::OpenHandle(*pattern),
5822 RegExpFlagsToString(flags),
5823 &has_pending_exception);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005824 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005825 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
5826}
5827
5828
5829Local<v8::String> v8::RegExp::GetSource() const {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005830 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5831 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
5832}
5833
5834
5835// Assert that the static flags cast in GetFlags is valid.
5836#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
5837 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
5838 static_cast<int>(i::JSRegExp::internal_flag))
5839REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
5840REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
5841REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
5842REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
5843#undef REGEXP_FLAG_ASSERT_EQ
5844
5845v8::RegExp::Flags v8::RegExp::GetFlags() const {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00005846 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5847 return static_cast<RegExp::Flags>(obj->GetFlags().value());
5848}
5849
5850
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005851Local<v8::Array> v8::Array::New(int length) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005852 i::Isolate* isolate = i::Isolate::Current();
5853 EnsureInitializedForIsolate(isolate, "v8::Array::New()");
5854 LOG_API(isolate, "Array::New");
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005855 ENTER_V8(isolate);
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00005856 int real_length = length > 0 ? length : 0;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005857 i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00005858 i::Handle<i::Object> length_obj =
5859 isolate->factory()->NewNumberFromInt(real_length);
5860 obj->set_length(*length_obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005861 return Utils::ToLocal(obj);
5862}
5863
5864
ager@chromium.org32912102009-01-16 10:38:43 +00005865uint32_t v8::Array::Length() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005866 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
5867 i::Object* length = obj->length();
5868 if (length->IsSmi()) {
5869 return i::Smi::cast(length)->value();
5870 } else {
5871 return static_cast<uint32_t>(length->Number());
5872 }
5873}
5874
5875
ager@chromium.org3e875802009-06-29 08:26:34 +00005876Local<Object> Array::CloneElementAt(uint32_t index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005877 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005878 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005879 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005880 if (!self->HasFastObjectElements()) {
ager@chromium.org3e875802009-06-29 08:26:34 +00005881 return Local<Object>();
5882 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005883 i::FixedArray* elms = i::FixedArray::cast(self->elements());
ager@chromium.org3e875802009-06-29 08:26:34 +00005884 i::Object* paragon = elms->get(index);
5885 if (!paragon->IsJSObject()) {
5886 return Local<Object>();
5887 }
5888 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005889 EXCEPTION_PREAMBLE(isolate);
5890 ENTER_V8(isolate);
machenbach@chromium.org528ce022013-09-23 14:09:36 +00005891 i::Handle<i::JSObject> result = i::JSObject::Copy(paragon_handle);
ager@chromium.org3e875802009-06-29 08:26:34 +00005892 has_pending_exception = result.is_null();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005893 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
ager@chromium.org3e875802009-06-29 08:26:34 +00005894 return Utils::ToLocal(result);
5895}
5896
5897
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005898bool v8::ArrayBuffer::IsExternal() const {
5899 return Utils::OpenHandle(this)->is_external();
5900}
5901
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00005902
ulan@chromium.org837a67e2013-06-11 15:39:48 +00005903v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005904 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5905 ApiCheck(!obj->is_external(),
5906 "v8::ArrayBuffer::Externalize",
5907 "ArrayBuffer already externalized");
5908 obj->set_is_external(true);
5909 size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
ulan@chromium.org837a67e2013-06-11 15:39:48 +00005910 Contents contents;
5911 contents.data_ = obj->backing_store();
5912 contents.byte_length_ = byte_length;
5913 return contents;
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005914}
5915
5916
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005917void v8::ArrayBuffer::Neuter() {
5918 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5919 i::Isolate* isolate = obj->GetIsolate();
5920 ApiCheck(obj->is_external(),
5921 "v8::ArrayBuffer::Neuter",
5922 "Only externalized ArrayBuffers can be neutered");
5923 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
5924 ENTER_V8(isolate);
5925
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005926 for (i::Handle<i::Object> view_obj(obj->weak_first_view(), isolate);
5927 !view_obj->IsUndefined();) {
5928 i::Handle<i::JSArrayBufferView> view(i::JSArrayBufferView::cast(*view_obj));
5929 if (view->IsJSTypedArray()) {
5930 i::JSTypedArray::cast(*view)->Neuter();
5931 } else if (view->IsJSDataView()) {
5932 i::JSDataView::cast(*view)->Neuter();
5933 } else {
5934 UNREACHABLE();
5935 }
5936 view_obj = i::handle(view->weak_next(), isolate);
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005937 }
5938 obj->Neuter();
5939}
5940
5941
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005942size_t v8::ArrayBuffer::ByteLength() const {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005943 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5944 return static_cast<size_t>(obj->byte_length()->Number());
5945}
5946
5947
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005948Local<ArrayBuffer> v8::ArrayBuffer::New(size_t byte_length) {
5949 i::Isolate* isolate = i::Isolate::Current();
5950 EnsureInitializedForIsolate(isolate, "v8::ArrayBuffer::New(size_t)");
5951 LOG_API(isolate, "v8::ArrayBuffer::New(size_t)");
5952 ENTER_V8(isolate);
5953 i::Handle<i::JSArrayBuffer> obj =
5954 isolate->factory()->NewJSArrayBuffer();
5955 i::Runtime::SetupArrayBufferAllocatingData(isolate, obj, byte_length);
5956 return Utils::ToLocal(obj);
5957}
5958
5959
5960Local<ArrayBuffer> v8::ArrayBuffer::New(void* data, size_t byte_length) {
5961 i::Isolate* isolate = i::Isolate::Current();
5962 EnsureInitializedForIsolate(isolate, "v8::ArrayBuffer::New(void*, size_t)");
5963 LOG_API(isolate, "v8::ArrayBuffer::New(void*, size_t)");
5964 ENTER_V8(isolate);
5965 i::Handle<i::JSArrayBuffer> obj =
5966 isolate->factory()->NewJSArrayBuffer();
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005967 i::Runtime::SetupArrayBuffer(isolate, obj, true, data, byte_length);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005968 return Utils::ToLocal(obj);
5969}
5970
5971
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005972Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
5973 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005974 ASSERT(obj->buffer()->IsJSArrayBuffer());
5975 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(obj->buffer()));
5976 return Utils::ToLocal(buffer);
5977}
5978
5979
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005980size_t v8::ArrayBufferView::ByteOffset() {
5981 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005982 return static_cast<size_t>(obj->byte_offset()->Number());
5983}
5984
5985
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005986size_t v8::ArrayBufferView::ByteLength() {
5987 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
danno@chromium.orgf005df62013-04-30 16:36:45 +00005988 return static_cast<size_t>(obj->byte_length()->Number());
5989}
5990
5991
5992size_t v8::TypedArray::Length() {
danno@chromium.orgf005df62013-04-30 16:36:45 +00005993 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
5994 return static_cast<size_t>(obj->length()->Number());
5995}
5996
5997
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005998static inline void SetupArrayBufferView(
5999 i::Isolate* isolate,
6000 i::Handle<i::JSArrayBufferView> obj,
6001 i::Handle<i::JSArrayBuffer> buffer,
6002 size_t byte_offset,
6003 size_t byte_length) {
6004 ASSERT(byte_offset + byte_length <=
6005 static_cast<size_t>(buffer->byte_length()->Number()));
danno@chromium.orgf005df62013-04-30 16:36:45 +00006006
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006007 obj->set_buffer(*buffer);
6008
6009 obj->set_weak_next(buffer->weak_first_view());
6010 buffer->set_weak_first_view(*obj);
6011
6012 i::Handle<i::Object> byte_offset_object =
6013 isolate->factory()->NewNumberFromSize(byte_offset);
6014 obj->set_byte_offset(*byte_offset_object);
6015
6016 i::Handle<i::Object> byte_length_object =
6017 isolate->factory()->NewNumberFromSize(byte_length);
6018 obj->set_byte_length(*byte_length_object);
6019}
danno@chromium.orgf005df62013-04-30 16:36:45 +00006020
6021template<typename ElementType,
6022 ExternalArrayType array_type,
6023 i::ElementsKind elements_kind>
6024i::Handle<i::JSTypedArray> NewTypedArray(
6025 i::Isolate* isolate,
6026 Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
6027 i::Handle<i::JSTypedArray> obj =
6028 isolate->factory()->NewJSTypedArray(array_type);
6029 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6030
6031 ASSERT(byte_offset % sizeof(ElementType) == 0);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006032
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006033 SetupArrayBufferView(
6034 isolate, obj, buffer, byte_offset, length * sizeof(ElementType));
danno@chromium.orgf005df62013-04-30 16:36:45 +00006035
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006036 i::Handle<i::Object> length_object =
6037 isolate->factory()->NewNumberFromSize(length);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006038 obj->set_length(*length_object);
6039
6040 i::Handle<i::ExternalArray> elements =
6041 isolate->factory()->NewExternalArray(
6042 static_cast<int>(length), array_type,
6043 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
danno@chromium.orgf005df62013-04-30 16:36:45 +00006044 obj->set_elements(*elements);
6045 return obj;
6046}
6047
6048
6049#define TYPED_ARRAY_NEW(TypedArray, element_type, array_type, elements_kind) \
6050 Local<TypedArray> TypedArray::New(Handle<ArrayBuffer> array_buffer, \
6051 size_t byte_offset, size_t length) { \
6052 i::Isolate* isolate = i::Isolate::Current(); \
6053 EnsureInitializedForIsolate(isolate, \
6054 "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
6055 LOG_API(isolate, \
6056 "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
6057 ENTER_V8(isolate); \
6058 i::Handle<i::JSTypedArray> obj = \
6059 NewTypedArray<element_type, array_type, elements_kind>( \
6060 isolate, array_buffer, byte_offset, length); \
6061 return Utils::ToLocal##TypedArray(obj); \
6062 }
6063
6064
6065TYPED_ARRAY_NEW(Uint8Array, uint8_t, kExternalUnsignedByteArray,
6066 i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS)
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006067TYPED_ARRAY_NEW(Uint8ClampedArray, uint8_t, kExternalPixelArray,
6068 i::EXTERNAL_PIXEL_ELEMENTS)
danno@chromium.orgf005df62013-04-30 16:36:45 +00006069TYPED_ARRAY_NEW(Int8Array, int8_t, kExternalByteArray,
6070 i::EXTERNAL_BYTE_ELEMENTS)
6071TYPED_ARRAY_NEW(Uint16Array, uint16_t, kExternalUnsignedShortArray,
6072 i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS)
6073TYPED_ARRAY_NEW(Int16Array, int16_t, kExternalShortArray,
6074 i::EXTERNAL_SHORT_ELEMENTS)
6075TYPED_ARRAY_NEW(Uint32Array, uint32_t, kExternalUnsignedIntArray,
6076 i::EXTERNAL_UNSIGNED_INT_ELEMENTS)
6077TYPED_ARRAY_NEW(Int32Array, int32_t, kExternalIntArray,
6078 i::EXTERNAL_INT_ELEMENTS)
6079TYPED_ARRAY_NEW(Float32Array, float, kExternalFloatArray,
6080 i::EXTERNAL_FLOAT_ELEMENTS)
6081TYPED_ARRAY_NEW(Float64Array, double, kExternalDoubleArray,
6082 i::EXTERNAL_DOUBLE_ELEMENTS)
6083
6084#undef TYPED_ARRAY_NEW
6085
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006086Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
6087 size_t byte_offset, size_t byte_length) {
6088 i::Isolate* isolate = i::Isolate::Current();
6089 EnsureInitializedForIsolate(
6090 isolate, "v8::DataView::New(void*, size_t, size_t)");
6091 LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
6092 ENTER_V8(isolate);
6093 i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
6094 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6095 SetupArrayBufferView(
6096 isolate, obj, buffer, byte_offset, byte_length);
6097 return Utils::ToLocal(obj);
6098}
6099
danno@chromium.orgf005df62013-04-30 16:36:45 +00006100
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006101Local<Symbol> v8::Symbol::New(Isolate* isolate) {
6102 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6103 EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()");
6104 LOG_API(i_isolate, "Symbol::New()");
6105 ENTER_V8(i_isolate);
6106 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6107 return Utils::ToLocal(result);
6108}
6109
6110
6111Local<Symbol> v8::Symbol::New(Isolate* isolate, const char* data, int length) {
6112 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6113 EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()");
6114 LOG_API(i_isolate, "Symbol::New(char)");
6115 ENTER_V8(i_isolate);
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 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6120 result->set_name(*name);
6121 return Utils::ToLocal(result);
6122}
6123
6124
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006125Local<Number> v8::Number::New(double value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006126 i::Isolate* isolate = i::Isolate::Current();
6127 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00006128 return Number::New(reinterpret_cast<Isolate*>(isolate), value);
6129}
6130
6131
6132Local<Number> v8::Number::New(Isolate* isolate, double value) {
6133 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6134 ASSERT(internal_isolate->IsInitialized());
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00006135 if (std::isnan(value)) {
ager@chromium.org3811b432009-10-28 14:53:37 +00006136 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6137 value = i::OS::nan_value();
6138 }
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00006139 ENTER_V8(internal_isolate);
6140 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006141 return Utils::NumberToLocal(result);
6142}
6143
6144
6145Local<Integer> v8::Integer::New(int32_t value) {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00006146 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006147 EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006148 return v8::Integer::New(value, reinterpret_cast<Isolate*>(isolate));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006149}
6150
6151
ager@chromium.org3811b432009-10-28 14:53:37 +00006152Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006153 i::Isolate* isolate = i::Isolate::Current();
6154 EnsureInitializedForIsolate(isolate, "v8::Integer::NewFromUnsigned()");
6155 return Integer::NewFromUnsigned(value, reinterpret_cast<Isolate*>(isolate));
6156}
6157
6158
6159Local<Integer> v8::Integer::New(int32_t value, Isolate* isolate) {
6160 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6161 ASSERT(internal_isolate->IsInitialized());
6162 if (i::Smi::IsValid(value)) {
6163 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
6164 internal_isolate));
6165 }
6166 ENTER_V8(internal_isolate);
6167 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
6168 return Utils::IntegerToLocal(result);
6169}
6170
6171
6172Local<Integer> v8::Integer::NewFromUnsigned(uint32_t value, Isolate* isolate) {
6173 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6174 ASSERT(internal_isolate->IsInitialized());
ager@chromium.org3811b432009-10-28 14:53:37 +00006175 bool fits_into_int32_t = (value & (1 << 31)) == 0;
6176 if (fits_into_int32_t) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006177 return Integer::New(static_cast<int32_t>(value), isolate);
ager@chromium.org3811b432009-10-28 14:53:37 +00006178 }
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00006179 ENTER_V8(internal_isolate);
6180 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
ager@chromium.org3811b432009-10-28 14:53:37 +00006181 return Utils::IntegerToLocal(result);
6182}
6183
6184
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006185#ifdef DEBUG
rossberg@chromium.org79e79022013-06-03 15:43:46 +00006186v8::AssertNoGCScope::AssertNoGCScope(v8::Isolate* isolate) {
6187 disallow_heap_allocation_ = new i::DisallowHeapAllocation();
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006188}
6189
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006190
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006191v8::AssertNoGCScope::~AssertNoGCScope() {
rossberg@chromium.org79e79022013-06-03 15:43:46 +00006192 delete static_cast<i::DisallowHeapAllocation*>(disallow_heap_allocation_);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006193}
6194#endif
6195
6196
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006197void V8::IgnoreOutOfMemoryException() {
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00006198 EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006199}
6200
6201
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006202bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006203 i::Isolate* isolate = i::Isolate::Current();
6204 EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
6205 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006206 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006207 i::HandleScope scope(isolate);
6208 NeanderArray listeners(isolate->factory()->message_listeners());
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006209 NeanderObject obj(2);
6210 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
6211 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
6212 : *Utils::OpenHandle(*data));
6213 listeners.add(obj.value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006214 return true;
6215}
6216
6217
6218void V8::RemoveMessageListeners(MessageCallback that) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006219 i::Isolate* isolate = i::Isolate::Current();
6220 EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
6221 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006222 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006223 i::HandleScope scope(isolate);
6224 NeanderArray listeners(isolate->factory()->message_listeners());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006225 for (int i = 0; i < listeners.length(); i++) {
6226 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
6227
hpayer@chromium.org8432c912013-02-28 15:55:26 +00006228 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
6229 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00006230 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006231 listeners.set(i, isolate->heap()->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006232 }
6233 }
6234}
6235
6236
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00006237void V8::SetCaptureStackTraceForUncaughtExceptions(
6238 bool capture,
6239 int frame_limit,
6240 StackTrace::StackTraceOptions options) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006241 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00006242 capture,
6243 frame_limit,
6244 options);
6245}
6246
6247
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006248void V8::SetCounterFunction(CounterLookupCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006249 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006250 isolate->stats_table()->SetCounterFunction(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006251}
6252
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006253
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006254void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006255 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006256 isolate->stats_table()->SetCreateHistogramFunction(callback);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006257 isolate->InitializeLoggingAndCounters();
6258 isolate->counters()->ResetHistograms();
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006259}
6260
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006261
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006262void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
sgjesse@chromium.orge0599052011-03-25 07:34:35 +00006263 i::Isolate* isolate = EnterIsolateIfNeeded();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006264 isolate->stats_table()->
6265 SetAddHistogramSampleFunction(callback);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00006266}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006267
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006268void V8::SetFailedAccessCheckCallbackFunction(
6269 FailedAccessCheckCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006270 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006271 isolate->SetFailedAccessCheckCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006272}
6273
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00006274
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00006275intptr_t Isolate::AdjustAmountOfExternalAllocatedMemory(
6276 intptr_t change_in_bytes) {
6277 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
6278 return heap->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
6279}
6280
6281
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00006282intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006283 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
machenbach@chromium.orgae161032013-09-24 09:12:30 +00006284 if (isolate == NULL || !isolate->IsInitialized()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006285 return 0;
6286 }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00006287 Isolate* isolate_ext = reinterpret_cast<Isolate*>(isolate);
6288 return isolate_ext->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
kasper.lund7276f142008-07-30 08:49:36 +00006289}
6290
6291
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006292HeapProfiler* Isolate::GetHeapProfiler() {
6293 i::HeapProfiler* heap_profiler =
6294 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
6295 return reinterpret_cast<HeapProfiler*>(heap_profiler);
6296}
6297
6298
6299CpuProfiler* Isolate::GetCpuProfiler() {
6300 i::CpuProfiler* cpu_profiler =
6301 reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
6302 return reinterpret_cast<CpuProfiler*>(cpu_profiler);
6303}
6304
6305
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006306bool Isolate::InContext() {
6307 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6308 return isolate->context() != NULL;
6309}
6310
6311
mvstanton@chromium.org40ce96b2013-04-09 09:52:22 +00006312v8::Local<v8::Context> Isolate::GetCurrentContext() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006313 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6314 i::Context* context = isolate->context();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00006315 if (context == NULL) return Local<Context>();
6316 i::Context* native_context = context->global_object()->native_context();
6317 if (native_context == NULL) return Local<Context>();
6318 return Utils::ToLocal(i::Handle<i::Context>(native_context));
mvstanton@chromium.org40ce96b2013-04-09 09:52:22 +00006319}
6320
6321
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006322v8::Local<v8::Context> Isolate::GetCallingContext() {
6323 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6324 i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
6325 if (calling.is_null()) return Local<Context>();
6326 return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
6327}
6328
6329
6330v8::Local<v8::Context> Isolate::GetEnteredContext() {
6331 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6332 i::Handle<i::Object> last =
6333 isolate->handle_scope_implementer()->LastEnteredContext();
6334 if (last.is_null()) return Local<Context>();
6335 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
6336}
6337
6338
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00006339v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
6340 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6341 ENTER_V8(isolate);
6342 // If we're passed an empty handle, we throw an undefined exception
6343 // to deal more gracefully with out of memory situations.
6344 if (value.IsEmpty()) {
6345 isolate->ScheduleThrow(isolate->heap()->undefined_value());
6346 } else {
6347 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
6348 }
6349 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6350}
6351
6352
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006353void Isolate::SetObjectGroupId(const Persistent<Value>& object,
6354 UniqueId id) {
6355 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6356 internal_isolate->global_handles()->SetObjectGroupId(
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006357 Utils::OpenPersistent(object).location(),
6358 id);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006359}
6360
6361
6362void Isolate::SetReferenceFromGroup(UniqueId id,
6363 const Persistent<Value>& object) {
6364 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006365 internal_isolate->global_handles()->SetReferenceFromGroup(
6366 id,
6367 Utils::OpenPersistent(object).location());
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006368}
6369
6370
6371void Isolate::SetReference(const Persistent<Object>& parent,
6372 const Persistent<Value>& child) {
6373 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006374 i::Object** parent_location = Utils::OpenPersistent(parent).location();
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006375 internal_isolate->global_handles()->SetReference(
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006376 reinterpret_cast<i::HeapObject**>(parent_location),
6377 Utils::OpenPersistent(child).location());
danno@chromium.orgca29dd82013-04-26 11:59:48 +00006378}
6379
6380
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006381void Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
6382 GCType gc_type) {
6383 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6384 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006385}
6386
6387
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006388void Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
6389 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6390 isolate->heap()->RemoveGCPrologueCallback(callback);
6391}
6392
6393
6394void Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
6395 GCType gc_type) {
6396 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6397 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
6398}
6399
6400
6401void Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
6402 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6403 isolate->heap()->RemoveGCEpilogueCallback(callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006404}
6405
6406
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006407void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006408 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006409 isolate->heap()->AddGCPrologueCallback(
6410 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
6411 gc_type,
6412 false);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006413}
6414
6415
6416void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006417 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006418 isolate->heap()->RemoveGCPrologueCallback(
6419 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006420}
6421
6422
6423void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006424 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006425 isolate->heap()->AddGCEpilogueCallback(
6426 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
6427 gc_type,
6428 false);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006429}
6430
6431
6432void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006433 i::Isolate* isolate = i::Isolate::Current();
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006434 isolate->heap()->RemoveGCEpilogueCallback(
6435 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00006436}
6437
6438
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006439void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
6440 ObjectSpace space,
6441 AllocationAction action) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006442 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006443 isolate->memory_allocator()->AddMemoryAllocationCallback(
6444 callback, space, action);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006445}
6446
6447
6448void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006449 i::Isolate* isolate = i::Isolate::Current();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006450 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
6451 callback);
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00006452}
6453
6454
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006455void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
6456 if (callback == NULL) return;
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006457 i::V8::AddCallCompletedCallback(callback);
6458}
6459
6460
6461void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00006462 i::V8::RemoveCallCompletedCallback(callback);
6463}
6464
6465
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006466void V8::TerminateExecution(Isolate* isolate) {
6467 // If no isolate is supplied, use the default isolate.
6468 if (isolate != NULL) {
6469 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
6470 } else {
6471 i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
6472 }
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00006473}
6474
6475
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00006476bool V8::IsExecutionTerminating(Isolate* isolate) {
6477 i::Isolate* i_isolate = isolate != NULL ?
6478 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
6479 return IsExecutionTerminatingCheck(i_isolate);
sgjesse@chromium.org2ab99522010-03-10 09:03:43 +00006480}
6481
6482
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006483void V8::CancelTerminateExecution(Isolate* isolate) {
6484 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6485 i_isolate->stack_guard()->CancelTerminateExecution();
6486}
6487
6488
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006489Isolate* Isolate::GetCurrent() {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00006490 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006491 return reinterpret_cast<Isolate*>(isolate);
6492}
6493
6494
6495Isolate* Isolate::New() {
6496 i::Isolate* isolate = new i::Isolate();
6497 return reinterpret_cast<Isolate*>(isolate);
6498}
6499
6500
6501void Isolate::Dispose() {
6502 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6503 if (!ApiCheck(!isolate->IsInUse(),
6504 "v8::Isolate::Dispose()",
6505 "Disposing the isolate that is entered by a thread.")) {
6506 return;
6507 }
6508 isolate->TearDown();
6509}
6510
6511
6512void Isolate::Enter() {
6513 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6514 isolate->Enter();
6515}
6516
6517
6518void Isolate::Exit() {
6519 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6520 isolate->Exit();
6521}
6522
6523
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00006524void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
6525 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006526 if (!isolate->IsInitialized()) {
6527 heap_statistics->total_heap_size_ = 0;
6528 heap_statistics->total_heap_size_executable_ = 0;
6529 heap_statistics->total_physical_size_ = 0;
6530 heap_statistics->used_heap_size_ = 0;
6531 heap_statistics->heap_size_limit_ = 0;
6532 return;
6533 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00006534 i::Heap* heap = isolate->heap();
6535 heap_statistics->total_heap_size_ = heap->CommittedMemory();
6536 heap_statistics->total_heap_size_executable_ =
6537 heap->CommittedMemoryExecutable();
6538 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
6539 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
6540 heap_statistics->heap_size_limit_ = heap->MaxReserved();
6541}
6542
6543
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006544String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
6545 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006546 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006547 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006548 ENTER_V8(isolate);
6549 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006550 TryCatch try_catch;
6551 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006552 if (str.IsEmpty()) return;
yangguo@chromium.org154ff992012-03-13 08:09:54 +00006553 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00006554 length_ = v8::Utf8Length(*i_str, isolate);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006555 str_ = i::NewArray<char>(length_ + 1);
6556 str->WriteUtf8(str_);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006557}
6558
6559
6560String::Utf8Value::~Utf8Value() {
6561 i::DeleteArray(str_);
6562}
6563
6564
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006565String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
6566 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006567 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006568 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006569 ENTER_V8(isolate);
6570 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006571 TryCatch try_catch;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006572 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006573 if (str.IsEmpty()) return;
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006574 length_ = str->Utf8Length();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006575 str_ = i::NewArray<char>(length_ + 1);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006576 str->WriteUtf8(str_);
6577 ASSERT(i::String::NonAsciiStart(str_, length_) >= length_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006578}
6579
6580
6581String::AsciiValue::~AsciiValue() {
6582 i::DeleteArray(str_);
6583}
6584
6585
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006586String::Value::Value(v8::Handle<v8::Value> obj)
6587 : str_(NULL), length_(0) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006588 i::Isolate* isolate = i::Isolate::Current();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006589 if (obj.IsEmpty()) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006590 ENTER_V8(isolate);
6591 i::HandleScope scope(isolate);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00006592 TryCatch try_catch;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006593 Handle<String> str = obj->ToString();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00006594 if (str.IsEmpty()) return;
6595 length_ = str->Length();
6596 str_ = i::NewArray<uint16_t>(length_ + 1);
6597 str->Write(str_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006598}
6599
6600
6601String::Value::~Value() {
6602 i::DeleteArray(str_);
6603}
6604
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006605
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006606Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006607 i::Isolate* isolate = i::Isolate::Current();
6608 LOG_API(isolate, "RangeError");
6609 ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006610 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006611 i::Object* error;
6612 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006613 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006614 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006615 i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006616 error = *result;
6617 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006618 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006619 return Utils::ToLocal(result);
6620}
6621
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006623Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006624 i::Isolate* isolate = i::Isolate::Current();
6625 LOG_API(isolate, "ReferenceError");
6626 ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006627 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006628 i::Object* error;
6629 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006630 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006631 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006632 i::Handle<i::Object> result =
6633 isolate->factory()->NewReferenceError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006634 error = *result;
6635 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006636 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006637 return Utils::ToLocal(result);
6638}
6639
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006640
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006641Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006642 i::Isolate* isolate = i::Isolate::Current();
6643 LOG_API(isolate, "SyntaxError");
6644 ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006645 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006646 i::Object* error;
6647 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006648 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006649 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006650 i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006651 error = *result;
6652 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006653 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006654 return Utils::ToLocal(result);
6655}
6656
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006657
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006658Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006659 i::Isolate* isolate = i::Isolate::Current();
6660 LOG_API(isolate, "TypeError");
6661 ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006662 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006663 i::Object* error;
6664 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006665 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006666 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006667 i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006668 error = *result;
6669 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006670 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006671 return Utils::ToLocal(result);
6672}
6673
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006674
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006675Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006676 i::Isolate* isolate = i::Isolate::Current();
6677 LOG_API(isolate, "Error");
6678 ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006679 ENTER_V8(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006680 i::Object* error;
6681 {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006682 i::HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006683 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006684 i::Handle<i::Object> result = isolate->factory()->NewError(message);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006685 error = *result;
6686 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006687 i::Handle<i::Object> result(error, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006688 return Utils::ToLocal(result);
6689}
6690
6691
6692// --- D e b u g S u p p o r t ---
6693
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006694#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00006695
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00006696bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006697 i::Isolate* isolate = i::Isolate::Current();
6698 EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
6699 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006700 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006701 i::HandleScope scope(isolate);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006702 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
ager@chromium.org381abbb2009-02-25 13:23:22 +00006703 if (that != NULL) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006704 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
ager@chromium.org381abbb2009-02-25 13:23:22 +00006705 }
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00006706 isolate->debugger()->SetEventListener(foreign,
6707 Utils::OpenHandle(*data, true));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006708 return true;
6709}
6710
6711
iposva@chromium.org245aa852009-02-10 00:49:54 +00006712bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006713 Handle<Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006714 i::Isolate* isolate = i::Isolate::Current();
6715 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006716 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006717 isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
jkummerow@chromium.org67255be2012-09-05 16:44:50 +00006718 Utils::OpenHandle(*data, true));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006719 return true;
6720}
6721
6722
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006723void Debug::DebugBreak(Isolate* isolate) {
6724 // If no isolate is supplied, use the default isolate.
6725 if (isolate != NULL) {
6726 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
6727 } else {
6728 i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
6729 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006730}
6731
6732
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006733void Debug::CancelDebugBreak(Isolate* isolate) {
6734 // If no isolate is supplied, use the default isolate.
6735 if (isolate != NULL) {
6736 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6737 internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
6738 } else {
6739 i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
6740 }
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00006741}
6742
6743
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006744void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
6745 // If no isolate is supplied, use the default isolate.
6746 if (isolate != NULL) {
6747 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6748 internal_isolate->debugger()->EnqueueDebugCommand(data);
6749 } else {
6750 i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
6751 }
mikhail.naganov@gmail.com22762872010-07-14 09:29:05 +00006752}
6753
6754
ager@chromium.org5ec48922009-05-05 07:25:34 +00006755void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006756 i::Isolate* isolate = i::Isolate::Current();
6757 EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
6758 ENTER_V8(isolate);
6759 isolate->debugger()->SetMessageHandler(handler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006760}
6761
6762
machenbach@chromium.org528ce022013-09-23 14:09:36 +00006763void Debug::SendCommand(Isolate* isolate,
6764 const uint16_t* command,
6765 int length,
6766 ClientData* client_data) {
6767 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6768 internal_isolate->debugger()->ProcessCommand(
6769 i::Vector<const uint16_t>(command, length), client_data);
6770}
6771
6772
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006773void Debug::SendCommand(const uint16_t* command, int length,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006774 ClientData* client_data,
6775 Isolate* isolate) {
6776 // If no isolate is supplied, use the default isolate.
6777 if (isolate != NULL) {
6778 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6779 internal_isolate->debugger()->ProcessCommand(
6780 i::Vector<const uint16_t>(command, length), client_data);
6781 } else {
6782 i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
6783 i::Vector<const uint16_t>(command, length), client_data);
6784 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006785}
6786
6787
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006788void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
6789 int period) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006790 i::Isolate* isolate = i::Isolate::Current();
6791 EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
6792 ENTER_V8(isolate);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00006793 isolate->debugger()->SetHostDispatchHandler(
6794 handler, i::TimeDelta::FromMilliseconds(period));
ager@chromium.org381abbb2009-02-25 13:23:22 +00006795}
6796
6797
ager@chromium.orgc4c92722009-11-18 14:12:51 +00006798void Debug::SetDebugMessageDispatchHandler(
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006799 DebugMessageDispatchHandler handler, bool provide_locker) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006800 i::Isolate* isolate = i::Isolate::Current();
6801 EnsureInitializedForIsolate(isolate,
6802 "v8::Debug::SetDebugMessageDispatchHandler");
6803 ENTER_V8(isolate);
6804 isolate->debugger()->SetDebugMessageDispatchHandler(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006805 handler, provide_locker);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00006806}
6807
6808
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006809Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
6810 v8::Handle<v8::Value> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006811 i::Isolate* isolate = i::Isolate::Current();
6812 if (!isolate->IsInitialized()) return Local<Value>();
6813 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006814 ENTER_V8(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006815 i::Handle<i::Object> result;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006816 EXCEPTION_PREAMBLE(isolate);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006817 if (data.IsEmpty()) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006818 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
6819 isolate->factory()->undefined_value(),
6820 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006821 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006822 result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
6823 Utils::OpenHandle(*data),
6824 &has_pending_exception);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006825 }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006826 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00006827 return Utils::ToLocal(result);
6828}
6829
6830
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006831Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006832 i::Isolate* isolate = i::Isolate::Current();
6833 if (!isolate->IsInitialized()) return Local<Value>();
6834 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006835 ENTER_V8(isolate);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00006836 v8::HandleScope scope(reinterpret_cast<Isolate*>(isolate));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006837 i::Debug* isolate_debug = isolate->debug();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006838 isolate_debug->Load();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00006839 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00006840 i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00006841 STATIC_ASCII_VECTOR("MakeMirror"));
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00006842 i::Handle<i::Object> fun_obj = i::GetProperty(isolate, debug, name);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006843 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
6844 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
6845 const int kArgc = 1;
6846 v8::Handle<v8::Value> argv[kArgc] = { obj };
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006847 EXCEPTION_PREAMBLE(isolate);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006848 v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
6849 kArgc,
6850 argv);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006851 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00006852 return scope.Close(result);
6853}
6854
6855
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00006856bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006857 return i::Isolate::Current()->debugger()->StartAgent(name, port,
6858 wait_for_connection);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00006859}
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006860
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006861
6862void Debug::DisableAgent() {
6863 return i::Isolate::Current()->debugger()->StopAgent();
6864}
6865
6866
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006867void Debug::ProcessDebugMessages() {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +00006868 i::Execution::ProcessDebugMessages(i::Isolate::Current(), true);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00006869}
6870
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00006871
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00006872Local<Context> Debug::GetDebugContext() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00006873 i::Isolate* isolate = i::Isolate::Current();
6874 EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
6875 ENTER_V8(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006876 return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +00006877}
6878
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00006879
6880void Debug::SetLiveEditEnabled(bool enable, Isolate* isolate) {
6881 // If no isolate is supplied, use the default isolate.
6882 i::Debugger* debugger;
6883 if (isolate != NULL) {
6884 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6885 debugger = internal_isolate->debugger();
6886 } else {
6887 debugger = i::Isolate::GetDefaultIsolateDebugger();
6888 }
6889 debugger->set_live_edit_enabled(enable);
6890}
6891
6892
ager@chromium.org65dad4b2009-04-23 08:48:43 +00006893#endif // ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00006894
ager@chromium.org357bf652010-04-12 11:30:10 +00006895
ager@chromium.org357bf652010-04-12 11:30:10 +00006896Handle<String> CpuProfileNode::GetFunctionName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006897 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006898 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6899 const i::CodeEntry* entry = node->entry();
6900 if (!entry->has_name_prefix()) {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006901 return ToApiHandle<String>(
6902 isolate->factory()->InternalizeUtf8String(entry->name()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006903 } else {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006904 return ToApiHandle<String>(isolate->factory()->NewConsString(
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00006905 isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006906 isolate->factory()->InternalizeUtf8String(entry->name())));
ager@chromium.org357bf652010-04-12 11:30:10 +00006907 }
6908}
6909
6910
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00006911int CpuProfileNode::GetScriptId() const {
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +00006912 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6913 const i::CodeEntry* entry = node->entry();
6914 return entry->script_id();
6915}
6916
6917
ager@chromium.org357bf652010-04-12 11:30:10 +00006918Handle<String> CpuProfileNode::GetScriptResourceName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006919 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006920 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006921 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
6922 node->entry()->resource_name()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006923}
6924
6925
6926int CpuProfileNode::GetLineNumber() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006927 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
6928}
6929
6930
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +00006931int CpuProfileNode::GetColumnNumber() const {
6932 return reinterpret_cast<const i::ProfileNode*>(this)->
6933 entry()->column_number();
6934}
6935
6936
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00006937const char* CpuProfileNode::GetBailoutReason() const {
6938 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
6939 return node->entry()->bailout_reason();
6940}
6941
6942
danno@chromium.org59400602013-08-13 17:09:37 +00006943unsigned CpuProfileNode::GetHitCount() const {
6944 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
6945}
6946
6947
ager@chromium.org357bf652010-04-12 11:30:10 +00006948unsigned CpuProfileNode::GetCallUid() const {
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00006949 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
ager@chromium.org357bf652010-04-12 11:30:10 +00006950}
6951
6952
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006953unsigned CpuProfileNode::GetNodeId() const {
6954 return reinterpret_cast<const i::ProfileNode*>(this)->id();
6955}
6956
6957
ager@chromium.org357bf652010-04-12 11:30:10 +00006958int CpuProfileNode::GetChildrenCount() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006959 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
6960}
6961
6962
6963const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006964 const i::ProfileNode* child =
6965 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
6966 return reinterpret_cast<const CpuProfileNode*>(child);
6967}
6968
6969
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006970void CpuProfile::Delete() {
6971 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006972 i::CpuProfiler* profiler = isolate->cpu_profiler();
6973 ASSERT(profiler != NULL);
6974 profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00006975 if (profiler->GetProfilesCount() == 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006976 // If this was the last profile, clean up all accessory data as well.
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00006977 profiler->DeleteAllProfiles();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006978 }
6979}
6980
6981
ager@chromium.org357bf652010-04-12 11:30:10 +00006982unsigned CpuProfile::GetUid() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006983 return reinterpret_cast<const i::CpuProfile*>(this)->uid();
6984}
6985
6986
6987Handle<String> CpuProfile::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006988 i::Isolate* isolate = i::Isolate::Current();
ager@chromium.org357bf652010-04-12 11:30:10 +00006989 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00006990 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
6991 profile->title()));
ager@chromium.org357bf652010-04-12 11:30:10 +00006992}
6993
6994
ager@chromium.org357bf652010-04-12 11:30:10 +00006995const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
ager@chromium.org357bf652010-04-12 11:30:10 +00006996 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
6997 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
6998}
6999
7000
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007001const CpuProfileNode* CpuProfile::GetSample(int index) const {
7002 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7003 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
7004}
7005
7006
danno@chromium.org89acc0b2013-08-09 20:55:58 +00007007int64_t CpuProfile::GetStartTime() const {
7008 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00007009 return (profile->start_time() - i::Time::UnixEpoch()).InMicroseconds();
danno@chromium.org89acc0b2013-08-09 20:55:58 +00007010}
7011
7012
7013int64_t CpuProfile::GetEndTime() const {
7014 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00007015 return (profile->end_time() - i::Time::UnixEpoch()).InMicroseconds();
danno@chromium.org89acc0b2013-08-09 20:55:58 +00007016}
7017
7018
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007019int CpuProfile::GetSamplesCount() const {
7020 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
7021}
7022
7023
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007024int CpuProfiler::GetProfileCount() {
7025 return reinterpret_cast<i::CpuProfiler*>(this)->GetProfilesCount();
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +00007026}
7027
7028
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00007029void CpuProfiler::SetSamplingInterval(int us) {
7030 ASSERT(us >= 0);
7031 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
7032 i::TimeDelta::FromMicroseconds(us));
7033}
7034
7035
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00007036const CpuProfile* CpuProfiler::GetCpuProfile(int index) {
7037 return reinterpret_cast<const CpuProfile*>(
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00007038 reinterpret_cast<i::CpuProfiler*>(this)->GetProfile(index));
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007039}
7040
7041
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007042void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
7043 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
7044 *Utils::OpenHandle(*title), record_samples);
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +00007045}
7046
7047
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00007048const CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title) {
7049 return reinterpret_cast<const CpuProfile*>(
7050 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +00007051 *Utils::OpenHandle(*title)));
7052}
7053
7054
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007055void CpuProfiler::DeleteAllCpuProfiles() {
7056 reinterpret_cast<i::CpuProfiler*>(this)->DeleteAllProfiles();
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +00007057}
7058
7059
danno@chromium.org59400602013-08-13 17:09:37 +00007060void CpuProfiler::SetIdle(bool is_idle) {
7061 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
7062 i::StateTag state = isolate->current_vm_state();
7063 ASSERT(state == i::EXTERNAL || state == i::IDLE);
7064 if (isolate->js_entry_sp() != NULL) return;
7065 if (is_idle) {
7066 isolate->set_current_vm_state(i::IDLE);
7067 } else if (state == i::IDLE) {
7068 isolate->set_current_vm_state(i::EXTERNAL);
7069 }
7070}
7071
7072
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007073static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
7074 return const_cast<i::HeapGraphEdge*>(
7075 reinterpret_cast<const i::HeapGraphEdge*>(edge));
7076}
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00007077
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007078
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007079HeapGraphEdge::Type HeapGraphEdge::GetType() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007080 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007081}
7082
7083
7084Handle<Value> HeapGraphEdge::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007085 i::Isolate* isolate = i::Isolate::Current();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007086 i::HeapGraphEdge* edge = ToInternal(this);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007087 switch (edge->type()) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007088 case i::HeapGraphEdge::kContextVariable:
7089 case i::HeapGraphEdge::kInternal:
7090 case i::HeapGraphEdge::kProperty:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00007091 case i::HeapGraphEdge::kShortcut:
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007092 return ToApiHandle<String>(
7093 isolate->factory()->InternalizeUtf8String(edge->name()));
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007094 case i::HeapGraphEdge::kElement:
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00007095 case i::HeapGraphEdge::kHidden:
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00007096 case i::HeapGraphEdge::kWeak:
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007097 return ToApiHandle<Number>(
7098 isolate->factory()->NewNumberFromInt(edge->index()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007099 default: UNREACHABLE();
7100 }
machenbach@chromium.orgcfdf67d2013-09-27 07:27:26 +00007101 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007102}
7103
7104
7105const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00007106 const i::HeapEntry* from = ToInternal(this)->from();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007107 return reinterpret_cast<const HeapGraphNode*>(from);
7108}
7109
7110
7111const HeapGraphNode* HeapGraphEdge::GetToNode() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007112 const i::HeapEntry* to = ToInternal(this)->to();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007113 return reinterpret_cast<const HeapGraphNode*>(to);
7114}
7115
7116
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007117static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
7118 return const_cast<i::HeapEntry*>(
7119 reinterpret_cast<const i::HeapEntry*>(entry));
7120}
7121
7122
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007123HeapGraphNode::Type HeapGraphNode::GetType() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007124 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007125}
7126
7127
7128Handle<String> HeapGraphNode::GetName() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007129 i::Isolate* isolate = i::Isolate::Current();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007130 return ToApiHandle<String>(
7131 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007132}
7133
7134
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007135SnapshotObjectId HeapGraphNode::GetId() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007136 return ToInternal(this)->id();
ricow@chromium.org4980dff2010-07-19 08:33:45 +00007137}
7138
7139
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007140int HeapGraphNode::GetSelfSize() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007141 return ToInternal(this)->self_size();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007142}
7143
7144
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007145int HeapGraphNode::GetChildrenCount() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007146 return ToInternal(this)->children().length();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007147}
7148
7149
7150const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007151 return reinterpret_cast<const HeapGraphEdge*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007152 ToInternal(this)->children()[index]);
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007153}
7154
7155
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00007156v8::Handle<v8::Value> HeapGraphNode::GetHeapValue() const {
7157 i::Isolate* isolate = i::Isolate::Current();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00007158 i::Handle<i::HeapObject> object = ToInternal(this)->GetHeapObject();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007159 return !object.is_null() ?
7160 ToApiHandle<Value>(object) :
7161 ToApiHandle<Value>(isolate->factory()->undefined_value());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00007162}
7163
7164
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007165static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
7166 return const_cast<i::HeapSnapshot*>(
7167 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
7168}
7169
7170
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007171void HeapSnapshot::Delete() {
7172 i::Isolate* isolate = i::Isolate::Current();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007173 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007174 ToInternal(this)->Delete();
7175 } else {
7176 // If this is the last snapshot, clean up all accessory data as well.
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007177 isolate->heap_profiler()->DeleteAllSnapshots();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007178 }
7179}
7180
7181
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007182unsigned HeapSnapshot::GetUid() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007183 return ToInternal(this)->uid();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007184}
7185
7186
7187Handle<String> HeapSnapshot::GetTitle() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007188 i::Isolate* isolate = i::Isolate::Current();
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00007189 return ToApiHandle<String>(
7190 isolate->factory()->InternalizeUtf8String(ToInternal(this)->title()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007191}
7192
7193
ricow@chromium.org4980dff2010-07-19 08:33:45 +00007194const HeapGraphNode* HeapSnapshot::GetRoot() const {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00007195 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007196}
7197
7198
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007199const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007200 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007201 ToInternal(this)->GetEntryById(id));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007202}
7203
7204
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007205int HeapSnapshot::GetNodesCount() const {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007206 return ToInternal(this)->entries().length();
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007207}
7208
7209
7210const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007211 return reinterpret_cast<const HeapGraphNode*>(
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00007212 &ToInternal(this)->entries().at(index));
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00007213}
7214
7215
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007216SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00007217 return ToInternal(this)->max_snapshot_js_object_id();
7218}
7219
7220
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00007221void HeapSnapshot::Serialize(OutputStream* stream,
7222 HeapSnapshot::SerializationFormat format) const {
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00007223 ApiCheck(format == kJSON,
7224 "v8::HeapSnapshot::Serialize",
7225 "Unknown serialization format");
7226 ApiCheck(stream->GetOutputEncoding() == OutputStream::kAscii,
7227 "v8::HeapSnapshot::Serialize",
7228 "Unsupported output encoding");
7229 ApiCheck(stream->GetChunkSize() > 0,
7230 "v8::HeapSnapshot::Serialize",
7231 "Invalid stream chunk size");
7232 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
7233 serializer.Serialize(stream);
7234}
7235
7236
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007237int HeapProfiler::GetSnapshotCount() {
7238 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007239}
7240
7241
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007242const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
7243 return reinterpret_cast<const HeapSnapshot*>(
7244 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007245}
7246
7247
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007248SnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
7249 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
7250 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00007251}
7252
7253
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007254const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
7255 Handle<String> title,
7256 ActivityControl* control,
7257 ObjectNameResolver* resolver) {
7258 return reinterpret_cast<const HeapSnapshot*>(
7259 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
7260 *Utils::OpenHandle(*title), control, resolver));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +00007261}
7262
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007263
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007264void HeapProfiler::StartTrackingHeapObjects() {
7265 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007266}
7267
7268
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007269void HeapProfiler::StopTrackingHeapObjects() {
7270 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007271}
7272
7273
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007274SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
7275 return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00007276}
7277
7278
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007279void HeapProfiler::DeleteAllHeapSnapshots() {
7280 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007281}
7282
7283
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007284void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
7285 WrapperInfoCallback callback) {
7286 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
7287 callback);
7288}
7289
7290
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00007291size_t HeapProfiler::GetProfilerMemorySize() {
7292 return reinterpret_cast<i::HeapProfiler*>(this)->
7293 GetMemorySizeUsedByProfiler();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00007294}
7295
7296
danno@chromium.orgca29dd82013-04-26 11:59:48 +00007297void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
7298 RetainedObjectInfo* info) {
7299 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
7300}
7301
7302
mstarzinger@chromium.orga2e1a402013-10-15 08:25:05 +00007303void HeapProfiler::StartRecordingHeapAllocations() {
7304 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapAllocationsRecording();
7305}
7306
7307
7308void HeapProfiler::StopRecordingHeapAllocations() {
7309 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapAllocationsRecording();
7310}
7311
7312
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007313v8::Testing::StressType internal::Testing::stress_type_ =
7314 v8::Testing::kStressTypeOpt;
7315
7316
7317void Testing::SetStressRunType(Testing::StressType type) {
7318 internal::Testing::set_stress_type(type);
7319}
7320
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00007321
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007322int Testing::GetStressRuns() {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00007323 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007324#ifdef DEBUG
7325 // In debug mode the code runs much slower so stressing will only make two
7326 // runs.
7327 return 2;
7328#else
7329 return 5;
7330#endif
7331}
7332
7333
7334static void SetFlagsFromString(const char* flags) {
7335 V8::SetFlagsFromString(flags, i::StrLength(flags));
7336}
7337
7338
7339void Testing::PrepareStressRun(int run) {
7340 static const char* kLazyOptimizations =
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00007341 "--prepare-always-opt "
7342 "--max-inlined-source-size=999999 "
7343 "--max-inlined-nodes=999999 "
7344 "--max-inlined-nodes-cumulative=999999 "
7345 "--noalways-opt";
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007346 static const char* kForcedOptimizations = "--always-opt";
7347
7348 // If deoptimization stressed turn on frequent deoptimization. If no value
7349 // is spefified through --deopt-every-n-times use a default default value.
7350 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
7351 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
7352 internal::FLAG_deopt_every_n_times == 0) {
7353 SetFlagsFromString(kDeoptEvery13Times);
7354 }
7355
7356#ifdef DEBUG
7357 // As stressing in debug mode only make two runs skip the deopt stressing
7358 // here.
7359 if (run == GetStressRuns() - 1) {
7360 SetFlagsFromString(kForcedOptimizations);
7361 } else {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007362 SetFlagsFromString(kLazyOptimizations);
7363 }
7364#else
7365 if (run == GetStressRuns() - 1) {
7366 SetFlagsFromString(kForcedOptimizations);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00007367 } else if (run != GetStressRuns() - 2) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00007368 SetFlagsFromString(kLazyOptimizations);
7369 }
7370#endif
7371}
7372
7373
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00007374// TODO(svenpanne) Deprecate this.
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007375void Testing::DeoptimizeAll() {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00007376 i::Isolate* isolate = i::Isolate::Current();
7377 i::HandleScope scope(isolate);
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00007378 internal::Deoptimizer::DeoptimizeAll(isolate);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00007379}
7380
7381
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007382namespace internal {
7383
7384
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007385void HandleScopeImplementer::FreeThreadResources() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007386 Free();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007387}
7388
7389
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007390char* HandleScopeImplementer::ArchiveThread(char* storage) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00007391 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00007392 isolate_->handle_scope_data();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007393 handle_scope_data_ = *current;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00007394 OS::MemCopy(storage, this, sizeof(*this));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007395
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007396 ResetAfterArchive();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007397 current->Initialize();
7398
7399 return storage + ArchiveSpacePerThread();
7400}
7401
7402
7403int HandleScopeImplementer::ArchiveSpacePerThread() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007404 return sizeof(HandleScopeImplementer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007405}
7406
7407
7408char* HandleScopeImplementer::RestoreThread(char* storage) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00007409 OS::MemCopy(this, storage, sizeof(*this));
lrn@chromium.org1c092762011-05-09 09:42:16 +00007410 *isolate_->handle_scope_data() = handle_scope_data_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007411 return storage + ArchiveSpacePerThread();
7412}
7413
7414
ager@chromium.orga1645e22009-09-09 19:27:10 +00007415void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007416#ifdef DEBUG
7417 bool found_block_before_deferred = false;
7418#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007419 // Iterate over all handles in the blocks except for the last.
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007420 for (int i = blocks()->length() - 2; i >= 0; --i) {
7421 Object** block = blocks()->at(i);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007422 if (last_handle_before_deferred_block_ != NULL &&
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00007423 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007424 (last_handle_before_deferred_block_ >= block)) {
7425 v->VisitPointers(block, last_handle_before_deferred_block_);
7426 ASSERT(!found_block_before_deferred);
7427#ifdef DEBUG
7428 found_block_before_deferred = true;
7429#endif
7430 } else {
7431 v->VisitPointers(block, &block[kHandleBlockSize]);
7432 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007433 }
7434
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007435 ASSERT(last_handle_before_deferred_block_ == NULL ||
7436 found_block_before_deferred);
7437
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007438 // Iterate over live handles in the last block (if any).
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00007439 if (!blocks()->is_empty()) {
7440 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
ager@chromium.orga1645e22009-09-09 19:27:10 +00007441 }
7442
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00007443 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
7444 for (unsigned i = 0; i < ARRAY_SIZE(context_lists); i++) {
7445 if (context_lists[i]->is_empty()) continue;
7446 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
7447 v->VisitPointers(start, start + context_lists[i]->length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007448 }
7449}
7450
7451
7452void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00007453 v8::ImplementationUtilities::HandleScopeData* current =
lrn@chromium.org1c092762011-05-09 09:42:16 +00007454 isolate_->handle_scope_data();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00007455 handle_scope_data_ = *current;
7456 IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007457}
7458
7459
7460char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
lrn@chromium.org7516f052011-03-30 08:52:27 +00007461 HandleScopeImplementer* scope_implementer =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007462 reinterpret_cast<HandleScopeImplementer*>(storage);
lrn@chromium.org7516f052011-03-30 08:52:27 +00007463 scope_implementer->IterateThis(v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007464 return storage + ArchiveSpacePerThread();
7465}
7466
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007467
7468DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007469 DeferredHandles* deferred =
7470 new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007471
7472 while (!blocks_.is_empty()) {
7473 Object** block_start = blocks_.last();
7474 Object** block_limit = &block_start[kHandleBlockSize];
rossberg@chromium.org79e79022013-06-03 15:43:46 +00007475 // We should not need to check for SealHandleScope here. Assert this.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007476 ASSERT(prev_limit == block_limit ||
7477 !(block_start <= prev_limit && prev_limit <= block_limit));
7478 if (prev_limit == block_limit) break;
7479 deferred->blocks_.Add(blocks_.last());
7480 blocks_.RemoveLast();
7481 }
7482
7483 // deferred->blocks_ now contains the blocks installed on the
7484 // HandleScope stack since BeginDeferredScope was called, but in
7485 // reverse order.
7486
7487 ASSERT(prev_limit == NULL || !blocks_.is_empty());
7488
7489 ASSERT(!blocks_.is_empty() && prev_limit != NULL);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007490 ASSERT(last_handle_before_deferred_block_ != NULL);
7491 last_handle_before_deferred_block_ = NULL;
7492 return deferred;
7493}
7494
7495
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007496void HandleScopeImplementer::BeginDeferredScope() {
7497 ASSERT(last_handle_before_deferred_block_ == NULL);
7498 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
7499}
7500
7501
7502DeferredHandles::~DeferredHandles() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007503 isolate_->UnlinkDeferredHandles(this);
7504
7505 for (int i = 0; i < blocks_.length(); i++) {
jkummerow@chromium.orgc3669762013-09-30 13:42:25 +00007506#ifdef ENABLE_HANDLE_ZAPPING
yangguo@chromium.org304cc332012-07-24 07:59:48 +00007507 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
7508#endif
7509 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
7510 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007511}
7512
7513
7514void DeferredHandles::Iterate(ObjectVisitor* v) {
7515 ASSERT(!blocks_.is_empty());
7516
7517 ASSERT((first_block_limit_ >= blocks_.first()) &&
verwaest@chromium.org753aee42012-07-17 16:15:42 +00007518 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00007519
7520 v->VisitPointers(blocks_.first(), first_block_limit_);
7521
7522 for (int i = 1; i < blocks_.length(); i++) {
7523 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
7524 }
7525}
7526
7527
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007528void InvokeAccessorGetterCallback(
7529 v8::Local<v8::String> property,
7530 const v8::PropertyCallbackInfo<v8::Value>& info,
7531 v8::AccessorGetterCallback getter) {
7532 // Leaving JavaScript.
7533 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7534 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
7535 getter));
7536 VMState<EXTERNAL> state(isolate);
7537 ExternalCallbackScope call_scope(isolate, getter_address);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00007538 getter(property, info);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007539}
7540
7541
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007542void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
7543 v8::FunctionCallback callback) {
7544 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7545 Address callback_address =
7546 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
7547 VMState<EXTERNAL> state(isolate);
7548 ExternalCallbackScope call_scope(isolate, callback_address);
dslomov@chromium.org639bac02013-09-09 11:58:54 +00007549 callback(info);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00007550}
7551
7552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00007553} } // namespace v8::internal