00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef V8_API_H_
00029 #define V8_API_H_
00030
00031 #include "factory.h"
00032
00033 namespace v8 {
00034
00035
00036
00037
00038
00039 class Consts {
00040 public:
00041 enum TemplateType {
00042 FUNCTION_TEMPLATE = 0,
00043 OBJECT_TEMPLATE = 1
00044 };
00045 };
00046
00047
00048
00049
00050 class NeanderObject {
00051 public:
00052 explicit NeanderObject(int size);
00053 inline NeanderObject(v8::internal::Handle<v8::internal::Object> obj);
00054 inline NeanderObject(v8::internal::Object* obj);
00055 inline v8::internal::Object* get(int index);
00056 inline void set(int index, v8::internal::Object* value);
00057 inline v8::internal::Handle<v8::internal::JSObject> value() { return value_; }
00058 int size();
00059 private:
00060 v8::internal::Handle<v8::internal::JSObject> value_;
00061 };
00062
00063
00064
00065
00066 class NeanderArray {
00067 public:
00068 NeanderArray();
00069 inline NeanderArray(v8::internal::Handle<v8::internal::Object> obj);
00070 inline v8::internal::Handle<v8::internal::JSObject> value() {
00071 return obj_.value();
00072 }
00073
00074 void add(v8::internal::Handle<v8::internal::Object> value);
00075
00076 int length();
00077
00078 v8::internal::Object* get(int index);
00079
00080
00081 void set(int index, v8::internal::Object* value);
00082 private:
00083 NeanderObject obj_;
00084 };
00085
00086
00087 NeanderObject::NeanderObject(v8::internal::Handle<v8::internal::Object> obj)
00088 : value_(v8::internal::Handle<v8::internal::JSObject>::cast(obj)) { }
00089
00090
00091 NeanderObject::NeanderObject(v8::internal::Object* obj)
00092 : value_(v8::internal::Handle<v8::internal::JSObject>(
00093 v8::internal::JSObject::cast(obj))) { }
00094
00095
00096 NeanderArray::NeanderArray(v8::internal::Handle<v8::internal::Object> obj)
00097 : obj_(obj) { }
00098
00099
00100 v8::internal::Object* NeanderObject::get(int offset) {
00101 ASSERT(value()->HasFastElements());
00102 return v8::internal::FixedArray::cast(value()->elements())->get(offset);
00103 }
00104
00105
00106 void NeanderObject::set(int offset, v8::internal::Object* value) {
00107 ASSERT(value_->HasFastElements());
00108 v8::internal::FixedArray::cast(value_->elements())->set(offset, value);
00109 }
00110
00111
00112 template <typename T> static inline T ToCData(v8::internal::Object* obj) {
00113 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
00114 return reinterpret_cast<T>(
00115 reinterpret_cast<intptr_t>(v8::internal::Proxy::cast(obj)->proxy()));
00116 }
00117
00118
00119 template <typename T>
00120 static inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) {
00121 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
00122 return v8::internal::Factory::NewProxy(
00123 reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
00124 }
00125
00126
00127 v8::Arguments::Arguments(v8::Local<v8::Value> data,
00128 v8::Local<v8::Object> holder,
00129 v8::Local<v8::Function> callee,
00130 bool is_construct_call,
00131 void** values, int length)
00132 : data_(data), holder_(holder), callee_(callee),
00133 is_construct_call_(is_construct_call),
00134 values_(values), length_(length) { }
00135
00136
00137 enum ExtensionTraversalState {
00138 UNVISITED, VISITED, INSTALLED
00139 };
00140
00141
00142 class RegisteredExtension {
00143 public:
00144 explicit RegisteredExtension(Extension* extension);
00145 static void Register(RegisteredExtension* that);
00146 Extension* extension() { return extension_; }
00147 RegisteredExtension* next() { return next_; }
00148 RegisteredExtension* next_auto() { return next_auto_; }
00149 ExtensionTraversalState state() { return state_; }
00150 void set_state(ExtensionTraversalState value) { state_ = value; }
00151 static RegisteredExtension* first_extension() { return first_extension_; }
00152 private:
00153 Extension* extension_;
00154 RegisteredExtension* next_;
00155 RegisteredExtension* next_auto_;
00156 ExtensionTraversalState state_;
00157 static RegisteredExtension* first_extension_;
00158 static RegisteredExtension* first_auto_extension_;
00159 };
00160
00161
00162 class ImplementationUtilities {
00163 public:
00164 static v8::Handle<v8::Primitive> Undefined();
00165 static v8::Handle<v8::Primitive> Null();
00166 static v8::Handle<v8::Boolean> True();
00167 static v8::Handle<v8::Boolean> False();
00168
00169 static int GetNameCount(ExtensionConfiguration* that) {
00170 return that->name_count_;
00171 }
00172
00173 static const char** GetNames(ExtensionConfiguration* that) {
00174 return that->names_;
00175 }
00176
00177 static v8::Arguments NewArguments(Local<Value> data,
00178 Local<Object> holder,
00179 Local<Function> callee,
00180 bool is_construct_call,
00181 void** argv, int argc) {
00182 return v8::Arguments(data, holder, callee, is_construct_call, argv, argc);
00183 }
00184
00185
00186
00187 typedef v8::HandleScope::Data HandleScopeData;
00188
00189 static HandleScopeData* CurrentHandleScope() {
00190 return &v8::HandleScope::current_;
00191 }
00192
00193 #ifdef DEBUG
00194 static void ZapHandleRange(void** begin, void** end) {
00195 v8::HandleScope::ZapRange(begin, end);
00196 }
00197 #endif
00198 };
00199
00200
00201 class Utils {
00202 public:
00203 static bool ReportApiFailure(const char* location, const char* message);
00204
00205 static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj);
00206 static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj);
00207
00208 static inline Local<Context> ToLocal(
00209 v8::internal::Handle<v8::internal::Context> obj);
00210 static inline Local<Value> ToLocal(
00211 v8::internal::Handle<v8::internal::Object> obj);
00212 static inline Local<Function> ToLocal(
00213 v8::internal::Handle<v8::internal::JSFunction> obj);
00214 static inline Local<String> ToLocal(
00215 v8::internal::Handle<v8::internal::String> obj);
00216 static inline Local<Object> ToLocal(
00217 v8::internal::Handle<v8::internal::JSObject> obj);
00218 static inline Local<Array> ToLocal(
00219 v8::internal::Handle<v8::internal::JSArray> obj);
00220 static inline Local<External> ToLocal(
00221 v8::internal::Handle<v8::internal::Proxy> obj);
00222 static inline Local<Message> MessageToLocal(
00223 v8::internal::Handle<v8::internal::Object> obj);
00224 static inline Local<Number> NumberToLocal(
00225 v8::internal::Handle<v8::internal::Object> obj);
00226 static inline Local<Integer> IntegerToLocal(
00227 v8::internal::Handle<v8::internal::Object> obj);
00228 static inline Local<Uint32> Uint32ToLocal(
00229 v8::internal::Handle<v8::internal::Object> obj);
00230 static inline Local<FunctionTemplate> ToLocal(
00231 v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
00232 static inline Local<ObjectTemplate> ToLocal(
00233 v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj);
00234 static inline Local<Signature> ToLocal(
00235 v8::internal::Handle<v8::internal::SignatureInfo> obj);
00236 static inline Local<TypeSwitch> ToLocal(
00237 v8::internal::Handle<v8::internal::TypeSwitchInfo> obj);
00238
00239 static inline v8::internal::Handle<v8::internal::TemplateInfo>
00240 OpenHandle(Template* that);
00241 static inline v8::internal::Handle<v8::internal::FunctionTemplateInfo>
00242 OpenHandle(FunctionTemplate* that);
00243 static inline v8::internal::Handle<v8::internal::ObjectTemplateInfo>
00244 OpenHandle(ObjectTemplate* that);
00245 static inline v8::internal::Handle<v8::internal::Object>
00246 OpenHandle(Data* data);
00247 static inline v8::internal::Handle<v8::internal::JSObject>
00248 OpenHandle(v8::Object* data);
00249 static inline v8::internal::Handle<v8::internal::JSArray>
00250 OpenHandle(v8::Array* data);
00251 static inline v8::internal::Handle<v8::internal::String>
00252 OpenHandle(String* data);
00253 static inline v8::internal::Handle<v8::internal::JSFunction>
00254 OpenHandle(Script* data);
00255 static inline v8::internal::Handle<v8::internal::JSFunction>
00256 OpenHandle(Function* data);
00257 static inline v8::internal::Handle<v8::internal::JSObject>
00258 OpenHandle(Message* message);
00259 static inline v8::internal::Handle<v8::internal::Context>
00260 OpenHandle(v8::Context* context);
00261 static inline v8::internal::Handle<v8::internal::SignatureInfo>
00262 OpenHandle(v8::Signature* sig);
00263 static inline v8::internal::Handle<v8::internal::TypeSwitchInfo>
00264 OpenHandle(v8::TypeSwitch* that);
00265 static inline v8::internal::Handle<v8::internal::Proxy>
00266 OpenHandle(v8::External* that);
00267 };
00268
00269
00270 template <class T>
00271 static inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
00272 return reinterpret_cast<T*>(obj.location());
00273 }
00274
00275
00276 template <class T>
00277 v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
00278 HandleScope* scope) {
00279 return Utils::OpenHandle(*scope->Close(Utils::ToLocal(*this)));
00280 }
00281
00282
00283
00284
00285 #define MAKE_TO_LOCAL(Name, From, To) \
00286 Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
00287 return Local<To>(reinterpret_cast<To*>(obj.location())); \
00288 }
00289
00290 MAKE_TO_LOCAL(ToLocal, Context, Context)
00291 MAKE_TO_LOCAL(ToLocal, Object, Value)
00292 MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
00293 MAKE_TO_LOCAL(ToLocal, String, String)
00294 MAKE_TO_LOCAL(ToLocal, JSObject, Object)
00295 MAKE_TO_LOCAL(ToLocal, JSArray, Array)
00296 MAKE_TO_LOCAL(ToLocal, Proxy, External)
00297 MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
00298 MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
00299 MAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature)
00300 MAKE_TO_LOCAL(ToLocal, TypeSwitchInfo, TypeSwitch)
00301 MAKE_TO_LOCAL(MessageToLocal, Object, Message)
00302 MAKE_TO_LOCAL(NumberToLocal, Object, Number)
00303 MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
00304 MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
00305
00306 #undef MAKE_TO_LOCAL
00307
00308
00309
00310
00311 #define MAKE_OPEN_HANDLE(From, To) \
00312 v8::internal::Handle<v8::internal::To> Utils::OpenHandle(v8::From* that) { \
00313 return v8::internal::Handle<v8::internal::To>( \
00314 reinterpret_cast<v8::internal::To**>(that)); \
00315 }
00316
00317 MAKE_OPEN_HANDLE(Template, TemplateInfo)
00318 MAKE_OPEN_HANDLE(FunctionTemplate, FunctionTemplateInfo)
00319 MAKE_OPEN_HANDLE(ObjectTemplate, ObjectTemplateInfo)
00320 MAKE_OPEN_HANDLE(Signature, SignatureInfo)
00321 MAKE_OPEN_HANDLE(TypeSwitch, TypeSwitchInfo)
00322 MAKE_OPEN_HANDLE(Data, Object)
00323 MAKE_OPEN_HANDLE(Object, JSObject)
00324 MAKE_OPEN_HANDLE(Array, JSArray)
00325 MAKE_OPEN_HANDLE(String, String)
00326 MAKE_OPEN_HANDLE(Script, JSFunction)
00327 MAKE_OPEN_HANDLE(Function, JSFunction)
00328 MAKE_OPEN_HANDLE(Message, JSObject)
00329 MAKE_OPEN_HANDLE(Context, Context)
00330 MAKE_OPEN_HANDLE(External, Proxy)
00331
00332 #undef MAKE_OPEN_HANDLE
00333
00334
00335 namespace internal {
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 class HandleScopeImplementer {
00347 public:
00348
00349 HandleScopeImplementer()
00350 : blocks(0),
00351 entered_contexts_(0),
00352 saved_contexts_(0) {
00353 Initialize();
00354 }
00355
00356 void Initialize() {
00357 blocks.Initialize(0);
00358 entered_contexts_.Initialize(0);
00359 saved_contexts_.Initialize(0);
00360 spare = NULL;
00361 ignore_out_of_memory = false;
00362 call_depth = 0;
00363 }
00364
00365 static HandleScopeImplementer* instance();
00366
00367
00368 static int ArchiveSpacePerThread();
00369 static char* RestoreThread(char* from);
00370 static char* ArchiveThread(char* to);
00371
00372
00373 static void Iterate(v8::internal::ObjectVisitor* v);
00374 static char* Iterate(v8::internal::ObjectVisitor* v, char* data);
00375
00376
00377 inline void** GetSpareOrNewBlock();
00378 inline void DeleteExtensions(int extensions);
00379
00380 inline void IncrementCallDepth() {call_depth++;}
00381 inline void DecrementCallDepth() {call_depth--;}
00382 inline bool CallDepthIsZero() { return call_depth == 0; }
00383
00384 inline void EnterContext(Handle<Object> context);
00385 inline bool LeaveLastContext();
00386
00387
00388
00389 inline Handle<Object> LastEnteredContext();
00390
00391 inline void SaveContext(Handle<Object> context);
00392 inline Handle<Object> RestoreContext();
00393 inline bool HasSavedContexts();
00394
00395 inline List<void**>* Blocks() { return &blocks; }
00396
00397 inline bool IgnoreOutOfMemory() { return ignore_out_of_memory; }
00398 inline void SetIgnoreOutOfMemory(bool value) { ignore_out_of_memory = value; }
00399
00400 private:
00401 List<void**> blocks;
00402 Object** spare;
00403 int call_depth;
00404
00405 List<Handle<Object> > entered_contexts_;
00406
00407 List<Handle<Object> > saved_contexts_;
00408 bool ignore_out_of_memory;
00409
00410 ImplementationUtilities::HandleScopeData handle_scope_data_;
00411
00412 static void Iterate(ObjectVisitor* v,
00413 List<void**>* blocks,
00414 ImplementationUtilities::HandleScopeData* handle_data);
00415 char* RestoreThreadHelper(char* from);
00416 char* ArchiveThreadHelper(char* to);
00417
00418 DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
00419 };
00420
00421
00422 static const int kHandleBlockSize = v8::internal::KB - 2;
00423
00424
00425 void HandleScopeImplementer::SaveContext(Handle<Object> context) {
00426 saved_contexts_.Add(context);
00427 }
00428
00429
00430 Handle<Object> HandleScopeImplementer::RestoreContext() {
00431 return saved_contexts_.RemoveLast();
00432 }
00433
00434
00435 bool HandleScopeImplementer::HasSavedContexts() {
00436 return !saved_contexts_.is_empty();
00437 }
00438
00439
00440 void HandleScopeImplementer::EnterContext(Handle<Object> context) {
00441 entered_contexts_.Add(context);
00442 }
00443
00444
00445 bool HandleScopeImplementer::LeaveLastContext() {
00446 if (entered_contexts_.is_empty()) return false;
00447 entered_contexts_.RemoveLast();
00448 return true;
00449 }
00450
00451
00452 Handle<Object> HandleScopeImplementer::LastEnteredContext() {
00453 if (entered_contexts_.is_empty()) return Handle<Object>::null();
00454 return entered_contexts_.last();
00455 }
00456
00457
00458
00459 void** HandleScopeImplementer::GetSpareOrNewBlock() {
00460 void** block = (spare != NULL) ?
00461 reinterpret_cast<void**>(spare) :
00462 NewArray<void*>(kHandleBlockSize);
00463 spare = NULL;
00464 return block;
00465 }
00466
00467
00468 void HandleScopeImplementer::DeleteExtensions(int extensions) {
00469 if (spare != NULL) {
00470 DeleteArray(spare);
00471 spare = NULL;
00472 }
00473 for (int i = extensions; i > 1; --i) {
00474 void** block = blocks.RemoveLast();
00475 #ifdef DEBUG
00476 ImplementationUtilities::ZapHandleRange(block, &block[kHandleBlockSize]);
00477 #endif
00478 DeleteArray(block);
00479 }
00480 spare = reinterpret_cast<Object**>(blocks.RemoveLast());
00481 #ifdef DEBUG
00482 ImplementationUtilities::ZapHandleRange(
00483 reinterpret_cast<void**>(spare),
00484 reinterpret_cast<void**>(&spare[kHandleBlockSize]));
00485 #endif
00486 }
00487
00488 } }
00489
00490 #endif // V8_API_H_