blob: 0f33bc815fe7bec76663be4ae7e2fb48dc558e50 [file] [log] [blame]
yangguo@chromium.org659ceec2012-01-26 07:37:54 +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
28#ifndef V8_API_H_
29#define V8_API_H_
30
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000031#include "v8.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000032
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "../include/v8-testing.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000034#include "apiutils.h"
35#include "contexts.h"
36#include "factory.h"
37#include "isolate.h"
38#include "list-inl.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000039
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040namespace v8 {
41
42// Constants used in the implementation of the API. The most natural thing
43// would usually be to place these with the classes that use them, but
44// we want to keep them out of v8.h because it is an externally
45// visible file.
46class Consts {
47 public:
48 enum TemplateType {
49 FUNCTION_TEMPLATE = 0,
50 OBJECT_TEMPLATE = 1
51 };
52};
53
54
55// Utilities for working with neander-objects, primitive
56// env-independent JSObjects used by the api.
57class NeanderObject {
58 public:
59 explicit NeanderObject(int size);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000060 explicit inline NeanderObject(v8::internal::Handle<v8::internal::Object> obj);
61 explicit inline NeanderObject(v8::internal::Object* obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000062 inline v8::internal::Object* get(int index);
63 inline void set(int index, v8::internal::Object* value);
64 inline v8::internal::Handle<v8::internal::JSObject> value() { return value_; }
65 int size();
66 private:
67 v8::internal::Handle<v8::internal::JSObject> value_;
68};
69
70
71// Utilities for working with neander-arrays, a simple extensible
72// array abstraction built on neander-objects.
73class NeanderArray {
74 public:
75 NeanderArray();
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000076 explicit inline NeanderArray(v8::internal::Handle<v8::internal::Object> obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077 inline v8::internal::Handle<v8::internal::JSObject> value() {
78 return obj_.value();
79 }
80
81 void add(v8::internal::Handle<v8::internal::Object> value);
82
83 int length();
84
85 v8::internal::Object* get(int index);
86 // Change the value at an index to undefined value. If the index is
87 // out of bounds, the request is ignored. Returns the old value.
88 void set(int index, v8::internal::Object* value);
89 private:
90 NeanderObject obj_;
91};
92
93
94NeanderObject::NeanderObject(v8::internal::Handle<v8::internal::Object> obj)
95 : value_(v8::internal::Handle<v8::internal::JSObject>::cast(obj)) { }
96
97
98NeanderObject::NeanderObject(v8::internal::Object* obj)
99 : value_(v8::internal::Handle<v8::internal::JSObject>(
100 v8::internal::JSObject::cast(obj))) { }
101
102
103NeanderArray::NeanderArray(v8::internal::Handle<v8::internal::Object> obj)
104 : obj_(obj) { }
105
106
107v8::internal::Object* NeanderObject::get(int offset) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000108 ASSERT(value()->HasFastObjectElements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000109 return v8::internal::FixedArray::cast(value()->elements())->get(offset);
110}
111
112
113void NeanderObject::set(int offset, v8::internal::Object* value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000114 ASSERT(value_->HasFastObjectElements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000115 v8::internal::FixedArray::cast(value_->elements())->set(offset, value);
116}
117
118
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000119template <typename T> inline T ToCData(v8::internal::Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000120 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
121 return reinterpret_cast<T>(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000122 reinterpret_cast<intptr_t>(
123 v8::internal::Foreign::cast(obj)->foreign_address()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000124}
125
126
127template <typename T>
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000128inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000129 v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000130 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000131 return isolate->factory()->NewForeign(
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000132 reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000133}
134
135
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000136class ApiFunction {
137 public:
138 explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { }
139 v8::internal::Address address() { return addr_; }
140 private:
141 v8::internal::Address addr_;
142};
143
144
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000145
146class RegisteredExtension {
147 public:
148 explicit RegisteredExtension(Extension* extension);
149 static void Register(RegisteredExtension* that);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000150 static void UnregisterAll();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000151 Extension* extension() { return extension_; }
152 RegisteredExtension* next() { return next_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000153 static RegisteredExtension* first_extension() { return first_extension_; }
154 private:
155 Extension* extension_;
156 RegisteredExtension* next_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000157 static RegisteredExtension* first_extension_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158};
159
160
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000161#define OPEN_HANDLE_LIST(V) \
162 V(Template, TemplateInfo) \
163 V(FunctionTemplate, FunctionTemplateInfo) \
164 V(ObjectTemplate, ObjectTemplateInfo) \
165 V(Signature, SignatureInfo) \
166 V(AccessorSignature, FunctionTemplateInfo) \
167 V(TypeSwitch, TypeSwitchInfo) \
168 V(Data, Object) \
169 V(RegExp, JSRegExp) \
170 V(Object, JSObject) \
171 V(Array, JSArray) \
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000172 V(ArrayBuffer, JSArrayBuffer) \
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000173 V(ArrayBufferView, JSArrayBufferView) \
danno@chromium.orgf005df62013-04-30 16:36:45 +0000174 V(TypedArray, JSTypedArray) \
175 V(Uint8Array, JSTypedArray) \
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000176 V(Uint8ClampedArray, JSTypedArray) \
danno@chromium.orgf005df62013-04-30 16:36:45 +0000177 V(Int8Array, JSTypedArray) \
178 V(Uint16Array, JSTypedArray) \
179 V(Int16Array, JSTypedArray) \
180 V(Uint32Array, JSTypedArray) \
181 V(Int32Array, JSTypedArray) \
182 V(Float32Array, JSTypedArray) \
183 V(Float64Array, JSTypedArray) \
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000184 V(DataView, JSDataView) \
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000185 V(String, String) \
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000186 V(Symbol, Symbol) \
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000187 V(Script, Object) \
188 V(Function, JSFunction) \
189 V(Message, JSObject) \
190 V(Context, Context) \
191 V(External, Foreign) \
192 V(StackTrace, JSArray) \
ulan@chromium.org750145a2013-03-07 15:14:13 +0000193 V(StackFrame, JSObject) \
194 V(DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000195
196
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000197class Utils {
198 public:
199 static bool ReportApiFailure(const char* location, const char* message);
200
201 static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj);
202 static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj);
203
204 static inline Local<Context> ToLocal(
205 v8::internal::Handle<v8::internal::Context> obj);
206 static inline Local<Value> ToLocal(
207 v8::internal::Handle<v8::internal::Object> obj);
208 static inline Local<Function> ToLocal(
209 v8::internal::Handle<v8::internal::JSFunction> obj);
210 static inline Local<String> ToLocal(
211 v8::internal::Handle<v8::internal::String> obj);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000212 static inline Local<Symbol> ToLocal(
213 v8::internal::Handle<v8::internal::Symbol> obj);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000214 static inline Local<RegExp> ToLocal(
215 v8::internal::Handle<v8::internal::JSRegExp> obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000216 static inline Local<Object> ToLocal(
217 v8::internal::Handle<v8::internal::JSObject> obj);
218 static inline Local<Array> ToLocal(
219 v8::internal::Handle<v8::internal::JSArray> obj);
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000220 static inline Local<ArrayBuffer> ToLocal(
221 v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000222 static inline Local<ArrayBufferView> ToLocal(
223 v8::internal::Handle<v8::internal::JSArrayBufferView> obj);
224 static inline Local<DataView> ToLocal(
225 v8::internal::Handle<v8::internal::JSDataView> obj);
danno@chromium.orgf005df62013-04-30 16:36:45 +0000226
227 static inline Local<TypedArray> ToLocal(
228 v8::internal::Handle<v8::internal::JSTypedArray> obj);
229 static inline Local<Uint8Array> ToLocalUint8Array(
230 v8::internal::Handle<v8::internal::JSTypedArray> obj);
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000231 static inline Local<Uint8ClampedArray> ToLocalUint8ClampedArray(
232 v8::internal::Handle<v8::internal::JSTypedArray> obj);
danno@chromium.orgf005df62013-04-30 16:36:45 +0000233 static inline Local<Int8Array> ToLocalInt8Array(
234 v8::internal::Handle<v8::internal::JSTypedArray> obj);
235 static inline Local<Uint16Array> ToLocalUint16Array(
236 v8::internal::Handle<v8::internal::JSTypedArray> obj);
237 static inline Local<Int16Array> ToLocalInt16Array(
238 v8::internal::Handle<v8::internal::JSTypedArray> obj);
239 static inline Local<Uint32Array> ToLocalUint32Array(
240 v8::internal::Handle<v8::internal::JSTypedArray> obj);
241 static inline Local<Int32Array> ToLocalInt32Array(
242 v8::internal::Handle<v8::internal::JSTypedArray> obj);
243 static inline Local<Float32Array> ToLocalFloat32Array(
244 v8::internal::Handle<v8::internal::JSTypedArray> obj);
245 static inline Local<Float64Array> ToLocalFloat64Array(
246 v8::internal::Handle<v8::internal::JSTypedArray> obj);
247
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000248 static inline Local<Message> MessageToLocal(
249 v8::internal::Handle<v8::internal::Object> obj);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000250 static inline Local<StackTrace> StackTraceToLocal(
251 v8::internal::Handle<v8::internal::JSArray> obj);
252 static inline Local<StackFrame> StackFrameToLocal(
253 v8::internal::Handle<v8::internal::JSObject> obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000254 static inline Local<Number> NumberToLocal(
255 v8::internal::Handle<v8::internal::Object> obj);
256 static inline Local<Integer> IntegerToLocal(
257 v8::internal::Handle<v8::internal::Object> obj);
258 static inline Local<Uint32> Uint32ToLocal(
259 v8::internal::Handle<v8::internal::Object> obj);
260 static inline Local<FunctionTemplate> ToLocal(
261 v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
262 static inline Local<ObjectTemplate> ToLocal(
263 v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj);
264 static inline Local<Signature> ToLocal(
265 v8::internal::Handle<v8::internal::SignatureInfo> obj);
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000266 static inline Local<AccessorSignature> AccessorSignatureToLocal(
267 v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268 static inline Local<TypeSwitch> ToLocal(
269 v8::internal::Handle<v8::internal::TypeSwitchInfo> obj);
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000270 static inline Local<External> ExternalToLocal(
271 v8::internal::Handle<v8::internal::JSObject> obj);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000272 static inline Local<DeclaredAccessorDescriptor> ToLocal(
273 v8::internal::Handle<v8::internal::DeclaredAccessorDescriptor> obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000274
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000275#define DECLARE_OPEN_HANDLE(From, To) \
276 static inline v8::internal::Handle<v8::internal::To> \
277 OpenHandle(const From* that, bool allow_empty_handle = false);
278
279OPEN_HANDLE_LIST(DECLARE_OPEN_HANDLE)
280
281#undef DECLARE_OPEN_HANDLE
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000282
283 template<class From, class To>
284 static inline Local<To> Convert(v8::internal::Handle<From> obj) {
285 ASSERT(obj.is_null() || !obj->IsTheHole());
286 return Local<To>(reinterpret_cast<To*>(obj.location()));
287 }
288
289 template <class T>
290 static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
291 const v8::Persistent<T>& persistent) {
292 return v8::internal::Handle<v8::internal::Object>(
293 reinterpret_cast<v8::internal::Object**>(persistent.val_));
294 }
295
296 template <class T>
297 static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
298 v8::Persistent<T>* persistent) {
299 return OpenPersistent(*persistent);
300 }
301
302 template <class From, class To>
303 static inline v8::internal::Handle<To> OpenHandle(v8::Local<From> handle) {
304 return OpenHandle(*handle);
305 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000306};
307
308
309template <class T>
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000310v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000311 v8::HandleScope* scope) {
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000312 v8::internal::Handle<T> handle;
313 if (!is_null()) {
314 handle = *this;
315 }
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000316 return Utils::OpenHandle(*scope->Close(Utils::ToLocal(handle)), true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000317}
318
319
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000320template <class T>
321inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
322 return reinterpret_cast<T*>(obj.location());
323}
324
325template <class T>
326inline v8::Local<T> ToApiHandle(
327 v8::internal::Handle<v8::internal::Object> obj) {
328 return Utils::Convert<v8::internal::Object, T>(obj);
329}
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000330
331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000332// Implementations of ToLocal
333
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000334#define MAKE_TO_LOCAL(Name, From, To) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000335 Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000336 return Convert<v8::internal::From, v8::To>(obj); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000337 }
338
danno@chromium.orgf005df62013-04-30 16:36:45 +0000339
340#define MAKE_TO_LOCAL_TYPED_ARRAY(TypedArray, typeConst) \
341 Local<v8::TypedArray> Utils::ToLocal##TypedArray( \
342 v8::internal::Handle<v8::internal::JSTypedArray> obj) { \
danno@chromium.orgf005df62013-04-30 16:36:45 +0000343 ASSERT(obj->type() == typeConst); \
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000344 return Convert<v8::internal::JSTypedArray, v8::TypedArray>(obj); \
danno@chromium.orgf005df62013-04-30 16:36:45 +0000345 }
346
347
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000348MAKE_TO_LOCAL(ToLocal, Context, Context)
349MAKE_TO_LOCAL(ToLocal, Object, Value)
350MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
351MAKE_TO_LOCAL(ToLocal, String, String)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000352MAKE_TO_LOCAL(ToLocal, Symbol, Symbol)
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000353MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000354MAKE_TO_LOCAL(ToLocal, JSObject, Object)
355MAKE_TO_LOCAL(ToLocal, JSArray, Array)
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000356MAKE_TO_LOCAL(ToLocal, JSArrayBuffer, ArrayBuffer)
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000357MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView)
358MAKE_TO_LOCAL(ToLocal, JSDataView, DataView)
danno@chromium.orgf005df62013-04-30 16:36:45 +0000359MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray)
360
361MAKE_TO_LOCAL_TYPED_ARRAY(Uint8Array, kExternalUnsignedByteArray)
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000362MAKE_TO_LOCAL_TYPED_ARRAY(Uint8ClampedArray, kExternalPixelArray)
danno@chromium.orgf005df62013-04-30 16:36:45 +0000363MAKE_TO_LOCAL_TYPED_ARRAY(Int8Array, kExternalByteArray)
364MAKE_TO_LOCAL_TYPED_ARRAY(Uint16Array, kExternalUnsignedShortArray)
365MAKE_TO_LOCAL_TYPED_ARRAY(Int16Array, kExternalShortArray)
366MAKE_TO_LOCAL_TYPED_ARRAY(Uint32Array, kExternalUnsignedIntArray)
367MAKE_TO_LOCAL_TYPED_ARRAY(Int32Array, kExternalIntArray)
368MAKE_TO_LOCAL_TYPED_ARRAY(Float32Array, kExternalFloatArray)
369MAKE_TO_LOCAL_TYPED_ARRAY(Float64Array, kExternalDoubleArray)
370
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000371MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
372MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
373MAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature)
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000374MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000375MAKE_TO_LOCAL(ToLocal, TypeSwitchInfo, TypeSwitch)
376MAKE_TO_LOCAL(MessageToLocal, Object, Message)
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000377MAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace)
378MAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000379MAKE_TO_LOCAL(NumberToLocal, Object, Number)
380MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
381MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000382MAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
ulan@chromium.org750145a2013-03-07 15:14:13 +0000383MAKE_TO_LOCAL(ToLocal, DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000384
danno@chromium.orgf005df62013-04-30 16:36:45 +0000385#undef MAKE_TO_LOCAL_TYPED_ARRAY
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000386#undef MAKE_TO_LOCAL
387
388
389// Implementations of OpenHandle
390
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000391#define MAKE_OPEN_HANDLE(From, To) \
392 v8::internal::Handle<v8::internal::To> Utils::OpenHandle( \
393 const v8::From* that, bool allow_empty_handle) { \
394 EXTRA_CHECK(allow_empty_handle || that != NULL); \
danno@chromium.orgc99cd482013-03-21 15:26:42 +0000395 EXTRA_CHECK(that == NULL || \
396 !(*reinterpret_cast<v8::internal::To**>( \
397 const_cast<v8::From*>(that)))->IsFailure()); \
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000398 return v8::internal::Handle<v8::internal::To>( \
ager@chromium.org32912102009-01-16 10:38:43 +0000399 reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000400 }
401
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000402OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000403
404#undef MAKE_OPEN_HANDLE
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000405#undef OPEN_HANDLE_LIST
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000406
407
408namespace internal {
409
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000410// Tracks string usage to help make better decisions when
411// externalizing strings.
412//
413// Implementation note: internally this class only tracks fresh
414// strings and keeps a single use counter for them.
415class StringTracker {
416 public:
417 // Records that the given string's characters were copied to some
418 // external buffer. If this happens often we should honor
419 // externalization requests for the string.
420 void RecordWrite(Handle<String> string) {
421 Address address = reinterpret_cast<Address>(*string);
422 Address top = isolate_->heap()->NewSpaceTop();
423 if (IsFreshString(address, top)) {
424 IncrementUseCount(top);
425 }
426 }
427
428 // Estimates freshness and use frequency of the given string based
429 // on how close it is to the new space top and the recorded usage
430 // history.
431 inline bool IsFreshUnusedString(Handle<String> string) {
432 Address address = reinterpret_cast<Address>(*string);
433 Address top = isolate_->heap()->NewSpaceTop();
434 return IsFreshString(address, top) && IsUseCountLow(top);
435 }
436
437 private:
438 StringTracker() : use_count_(0), last_top_(NULL), isolate_(NULL) { }
439
440 static inline bool IsFreshString(Address string, Address top) {
441 return top - kFreshnessLimit <= string && string <= top;
442 }
443
444 inline bool IsUseCountLow(Address top) {
445 if (last_top_ != top) return true;
446 return use_count_ < kUseLimit;
447 }
448
449 inline void IncrementUseCount(Address top) {
450 if (last_top_ != top) {
451 use_count_ = 0;
452 last_top_ = top;
453 }
454 ++use_count_;
455 }
456
457 // Single use counter shared by all fresh strings.
458 int use_count_;
459
460 // Last new space top when the use count above was valid.
461 Address last_top_;
462
463 Isolate* isolate_;
464
465 // How close to the new space top a fresh string has to be.
466 static const int kFreshnessLimit = 1024;
467
468 // The number of uses required to consider a string useful.
469 static const int kUseLimit = 32;
470
471 friend class Isolate;
472
473 DISALLOW_COPY_AND_ASSIGN(StringTracker);
474};
475
476
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000477class DeferredHandles {
478 public:
479 ~DeferredHandles();
480
481 private:
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000482 DeferredHandles(Object** first_block_limit, Isolate* isolate)
483 : next_(NULL),
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000484 previous_(NULL),
485 first_block_limit_(first_block_limit),
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000486 isolate_(isolate) {
487 isolate->LinkDeferredHandles(this);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000488 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000489
490 void Iterate(ObjectVisitor* v);
491
492 List<Object**> blocks_;
493 DeferredHandles* next_;
494 DeferredHandles* previous_;
495 Object** first_block_limit_;
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000496 Isolate* isolate_;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000497
498 friend class HandleScopeImplementer;
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000499 friend class Isolate;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000500};
501
502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503// This class is here in order to be able to declare it a friend of
504// HandleScope. Moving these methods to be members of HandleScope would be
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000505// neat in some ways, but it would expose internal implementation details in
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000506// our public header file, which is undesirable.
507//
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000508// An isolate has a single instance of this class to hold the current thread's
509// data. In multithreaded V8 programs this data is copied in and out of storage
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510// so that the currently executing thread always has its own copy of this
511// data.
danno@chromium.org40cb8782011-05-25 07:58:50 +0000512class HandleScopeImplementer {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000513 public:
lrn@chromium.org1c092762011-05-09 09:42:16 +0000514 explicit HandleScopeImplementer(Isolate* isolate)
515 : isolate_(isolate),
516 blocks_(0),
kasper.lund44510672008-07-25 07:37:58 +0000517 entered_contexts_(0),
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000518 saved_contexts_(0),
519 spare_(NULL),
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000520 call_depth_(0),
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000521 last_handle_before_deferred_block_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000522
rossberg@chromium.org28a37082011-08-22 11:03:23 +0000523 ~HandleScopeImplementer() {
524 DeleteArray(spare_);
525 }
526
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000527 // Threading support for handle data.
528 static int ArchiveSpacePerThread();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000529 char* RestoreThread(char* from);
530 char* ArchiveThread(char* to);
531 void FreeThreadResources();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000532
533 // Garbage collection support.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000534 void Iterate(v8::internal::ObjectVisitor* v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000535 static char* Iterate(v8::internal::ObjectVisitor* v, char* data);
536
537
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000538 inline internal::Object** GetSpareOrNewBlock();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000539 inline void DeleteExtensions(internal::Object** prev_limit);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000540
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000541 inline void IncrementCallDepth() {call_depth_++;}
542 inline void DecrementCallDepth() {call_depth_--;}
543 inline bool CallDepthIsZero() { return call_depth_ == 0; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000544
kasper.lund44510672008-07-25 07:37:58 +0000545 inline void EnterContext(Handle<Object> context);
546 inline bool LeaveLastContext();
547
548 // Returns the last entered context or an empty handle if no
549 // contexts have been entered.
550 inline Handle<Object> LastEnteredContext();
551
ager@chromium.orga1645e22009-09-09 19:27:10 +0000552 inline void SaveContext(Context* context);
553 inline Context* RestoreContext();
kasper.lund44510672008-07-25 07:37:58 +0000554 inline bool HasSavedContexts();
555
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000556 inline List<internal::Object**>* blocks() { return &blocks_; }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000557 Isolate* isolate() const { return isolate_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000559 void ReturnBlock(Object** block) {
560 ASSERT(block != NULL);
561 if (spare_ != NULL) DeleteArray(spare_);
562 spare_ = block;
563 }
564
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000565 private:
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000566 void ResetAfterArchive() {
567 blocks_.Initialize(0);
568 entered_contexts_.Initialize(0);
569 saved_contexts_.Initialize(0);
570 spare_ = NULL;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000571 last_handle_before_deferred_block_ = NULL;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000572 call_depth_ = 0;
573 }
574
575 void Free() {
576 ASSERT(blocks_.length() == 0);
577 ASSERT(entered_contexts_.length() == 0);
578 ASSERT(saved_contexts_.length() == 0);
579 blocks_.Free();
580 entered_contexts_.Free();
581 saved_contexts_.Free();
582 if (spare_ != NULL) {
583 DeleteArray(spare_);
584 spare_ = NULL;
585 }
586 ASSERT(call_depth_ == 0);
587 }
588
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000589 void BeginDeferredScope();
590 DeferredHandles* Detach(Object** prev_limit);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000591
lrn@chromium.org1c092762011-05-09 09:42:16 +0000592 Isolate* isolate_;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000593 List<internal::Object**> blocks_;
kasper.lund44510672008-07-25 07:37:58 +0000594 // Used as a stack to keep track of entered contexts.
595 List<Handle<Object> > entered_contexts_;
596 // Used as a stack to keep track of saved contexts.
ager@chromium.orga1645e22009-09-09 19:27:10 +0000597 List<Context*> saved_contexts_;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000598 Object** spare_;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000599 int call_depth_;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000600 Object** last_handle_before_deferred_block_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000601 // This is only used for threading support.
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000602 v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000603
ager@chromium.orga1645e22009-09-09 19:27:10 +0000604 void IterateThis(ObjectVisitor* v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605 char* RestoreThreadHelper(char* from);
606 char* ArchiveThreadHelper(char* to);
607
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000608 friend class DeferredHandles;
609 friend class DeferredHandleScope;
610
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000611 DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612};
613
614
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000615const int kHandleBlockSize = v8::internal::KB - 2; // fit in one page
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616
617
ager@chromium.orga1645e22009-09-09 19:27:10 +0000618void HandleScopeImplementer::SaveContext(Context* context) {
kasper.lund44510672008-07-25 07:37:58 +0000619 saved_contexts_.Add(context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620}
621
622
ager@chromium.orga1645e22009-09-09 19:27:10 +0000623Context* HandleScopeImplementer::RestoreContext() {
kasper.lund44510672008-07-25 07:37:58 +0000624 return saved_contexts_.RemoveLast();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000625}
626
627
kasper.lund44510672008-07-25 07:37:58 +0000628bool HandleScopeImplementer::HasSavedContexts() {
629 return !saved_contexts_.is_empty();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630}
631
632
kasper.lund44510672008-07-25 07:37:58 +0000633void HandleScopeImplementer::EnterContext(Handle<Object> context) {
634 entered_contexts_.Add(context);
635}
636
637
638bool HandleScopeImplementer::LeaveLastContext() {
639 if (entered_contexts_.is_empty()) return false;
640 entered_contexts_.RemoveLast();
641 return true;
642}
643
644
645Handle<Object> HandleScopeImplementer::LastEnteredContext() {
646 if (entered_contexts_.is_empty()) return Handle<Object>::null();
647 return entered_contexts_.last();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000648}
649
650
651// If there's a spare block, use it for growing the current scope.
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000652internal::Object** HandleScopeImplementer::GetSpareOrNewBlock() {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000653 internal::Object** block = (spare_ != NULL) ?
654 spare_ :
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000655 NewArray<internal::Object*>(kHandleBlockSize);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000656 spare_ = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657 return block;
658}
659
660
lrn@chromium.org303ada72010-10-27 09:33:13 +0000661void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) {
662 while (!blocks_.is_empty()) {
663 internal::Object** block_start = blocks_.last();
664 internal::Object** block_limit = block_start + kHandleBlockSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000665#ifdef DEBUG
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000666 // SealHandleScope may make the prev_limit to point inside the block.
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000667 if (block_start <= prev_limit && prev_limit <= block_limit) {
668#ifdef ENABLE_EXTRA_CHECKS
669 internal::HandleScope::ZapRange(prev_limit, block_limit);
670#endif
671 break;
672 }
lrn@chromium.org303ada72010-10-27 09:33:13 +0000673#else
674 if (prev_limit == block_limit) break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000675#endif
lrn@chromium.org303ada72010-10-27 09:33:13 +0000676
677 blocks_.RemoveLast();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000678#ifdef ENABLE_EXTRA_CHECKS
679 internal::HandleScope::ZapRange(block_start, block_limit);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000680#endif
lrn@chromium.org303ada72010-10-27 09:33:13 +0000681 if (spare_ != NULL) {
682 DeleteArray(spare_);
683 }
684 spare_ = block_start;
685 }
686 ASSERT((blocks_.is_empty() && prev_limit == NULL) ||
687 (!blocks_.is_empty() && prev_limit != NULL));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000688}
689
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000690
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000691// Interceptor functions called from generated inline caches to notify
692// CPU profiler that external callbacks are invoked.
693v8::Handle<v8::Value> InvokeAccessorGetter(
694 v8::Local<v8::String> property,
695 const v8::AccessorInfo& info,
696 v8::AccessorGetter getter);
697
698
699void InvokeAccessorGetterCallback(
700 v8::Local<v8::String> property,
701 const v8::PropertyCallbackInfo<v8::Value>& info,
702 v8::AccessorGetterCallback getter);
703
704v8::Handle<v8::Value> InvokeInvocationCallback(const v8::Arguments& args,
705 v8::InvocationCallback callback);
706void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
707 v8::FunctionCallback callback);
708
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000709class Testing {
710 public:
711 static v8::Testing::StressType stress_type() { return stress_type_; }
712 static void set_stress_type(v8::Testing::StressType stress_type) {
713 stress_type_ = stress_type;
714 }
715
716 private:
717 static v8::Testing::StressType stress_type_;
718};
719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720} } // namespace v8::internal
721
722#endif // V8_API_H_