00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef NAN_CALLBACKS_PRE_12_INL_H_
00010 #define NAN_CALLBACKS_PRE_12_INL_H_
00011
00012 namespace imp {
00013 template<typename T> class ReturnValueImp;
00014 }
00015
00016 template<typename T>
00017 class ReturnValue {
00018 v8::Isolate *isolate_;
00019 v8::Persistent<T> *value_;
00020 friend class imp::ReturnValueImp<T>;
00021
00022 public:
00023 template <class S>
00024 explicit inline ReturnValue(v8::Isolate *isolate, v8::Persistent<S> *p) :
00025 isolate_(isolate), value_(p) {}
00026 template <class S>
00027 explicit inline ReturnValue(const ReturnValue<S>& that)
00028 : isolate_(that.isolate_), value_(that.value_) {
00029 TYPE_CHECK(T, S);
00030 }
00031
00032
00033 template <typename S> inline void Set(const v8::Local<S> &handle) {
00034 TYPE_CHECK(T, S);
00035 value_->Dispose();
00036 *value_ = v8::Persistent<T>::New(handle);
00037 }
00038
00039 template <typename S> inline void Set(const Global<S> &handle) {
00040 TYPE_CHECK(T, S);
00041 value_->Dispose();
00042 *value_ = v8::Persistent<T>::New(handle.persistent);
00043 const_cast<Global<S> &>(handle).Reset();
00044 }
00045
00046
00047 inline void Set(bool value) {
00048 TYPE_CHECK(T, v8::Boolean);
00049 value_->Dispose();
00050 *value_ = v8::Persistent<T>::New(v8::Boolean::New(value));
00051 }
00052
00053 inline void Set(double i) {
00054 TYPE_CHECK(T, v8::Number);
00055 value_->Dispose();
00056 *value_ = v8::Persistent<T>::New(v8::Number::New(i));
00057 }
00058
00059 inline void Set(int32_t i) {
00060 TYPE_CHECK(T, v8::Integer);
00061 value_->Dispose();
00062 *value_ = v8::Persistent<T>::New(v8::Int32::New(i));
00063 }
00064
00065 inline void Set(uint32_t i) {
00066 TYPE_CHECK(T, v8::Integer);
00067 value_->Dispose();
00068 *value_ = v8::Persistent<T>::New(v8::Uint32::NewFromUnsigned(i));
00069 }
00070
00071
00072 inline void SetNull() {
00073 TYPE_CHECK(T, v8::Primitive);
00074 value_->Dispose();
00075 *value_ = v8::Persistent<T>::New(v8::Null());
00076 }
00077
00078 inline void SetUndefined() {
00079 TYPE_CHECK(T, v8::Primitive);
00080 value_->Dispose();
00081 *value_ = v8::Persistent<T>::New(v8::Undefined());
00082 }
00083
00084 inline void SetEmptyString() {
00085 TYPE_CHECK(T, v8::String);
00086 value_->Dispose();
00087 *value_ = v8::Persistent<T>::New(v8::String::Empty());
00088 }
00089
00090
00091 inline v8::Isolate *GetIsolate() const {
00092 return isolate_;
00093 }
00094
00095
00096 template<typename S>
00097 inline void Set(S *whatever) { TYPE_CHECK(S*, v8::Primitive); }
00098 };
00099
00100 template<typename T>
00101 class FunctionCallbackInfo {
00102 const v8::Arguments &args_;
00103 v8::Local<v8::Value> data_;
00104 ReturnValue<T> return_value_;
00105 v8::Persistent<T> retval_;
00106
00107 public:
00108 explicit inline FunctionCallbackInfo(
00109 const v8::Arguments &args
00110 , v8::Local<v8::Value> data) :
00111 args_(args)
00112 , data_(data)
00113 , return_value_(args.GetIsolate(), &retval_)
00114 , retval_(v8::Persistent<T>::New(v8::Undefined())) {}
00115
00116 inline ~FunctionCallbackInfo() {
00117 retval_.Dispose();
00118 retval_.Clear();
00119 }
00120
00121 inline ReturnValue<T> GetReturnValue() const {
00122 return ReturnValue<T>(return_value_);
00123 }
00124
00125 inline v8::Local<v8::Function> Callee() const { return args_.Callee(); }
00126 inline v8::Local<v8::Value> Data() const { return data_; }
00127 inline v8::Local<v8::Object> Holder() const { return args_.Holder(); }
00128 inline bool IsConstructCall() const { return args_.IsConstructCall(); }
00129 inline int Length() const { return args_.Length(); }
00130 inline v8::Local<v8::Value> operator[](int i) const { return args_[i]; }
00131 inline v8::Local<v8::Object> This() const { return args_.This(); }
00132 inline v8::Isolate *GetIsolate() const { return args_.GetIsolate(); }
00133
00134
00135 protected:
00136 static const int kHolderIndex = 0;
00137 static const int kIsolateIndex = 1;
00138 static const int kReturnValueDefaultValueIndex = 2;
00139 static const int kReturnValueIndex = 3;
00140 static const int kDataIndex = 4;
00141 static const int kCalleeIndex = 5;
00142 static const int kContextSaveIndex = 6;
00143 static const int kArgsLength = 7;
00144
00145 private:
00146 NAN_DISALLOW_ASSIGN_COPY_MOVE(FunctionCallbackInfo)
00147 };
00148
00149 template<typename T>
00150 class PropertyCallbackInfoBase {
00151 const v8::AccessorInfo &info_;
00152 const v8::Local<v8::Value> data_;
00153
00154 public:
00155 explicit inline PropertyCallbackInfoBase(
00156 const v8::AccessorInfo &info
00157 , const v8::Local<v8::Value> data) :
00158 info_(info)
00159 , data_(data) {}
00160
00161 inline v8::Isolate* GetIsolate() const { return info_.GetIsolate(); }
00162 inline v8::Local<v8::Value> Data() const { return data_; }
00163 inline v8::Local<v8::Object> This() const { return info_.This(); }
00164 inline v8::Local<v8::Object> Holder() const { return info_.Holder(); }
00165
00166 protected:
00167 static const int kHolderIndex = 0;
00168 static const int kIsolateIndex = 1;
00169 static const int kReturnValueDefaultValueIndex = 2;
00170 static const int kReturnValueIndex = 3;
00171 static const int kDataIndex = 4;
00172 static const int kThisIndex = 5;
00173 static const int kArgsLength = 6;
00174
00175 private:
00176 NAN_DISALLOW_ASSIGN_COPY_MOVE(PropertyCallbackInfoBase)
00177 };
00178
00179 template<typename T>
00180 class PropertyCallbackInfo : public PropertyCallbackInfoBase<T> {
00181 ReturnValue<T> return_value_;
00182 v8::Persistent<T> retval_;
00183
00184 public:
00185 explicit inline PropertyCallbackInfo(
00186 const v8::AccessorInfo &info
00187 , const v8::Local<v8::Value> data) :
00188 PropertyCallbackInfoBase<T>(info, data)
00189 , return_value_(info.GetIsolate(), &retval_)
00190 , retval_(v8::Persistent<T>::New(v8::Undefined())) {}
00191
00192 inline ~PropertyCallbackInfo() {
00193 retval_.Dispose();
00194 retval_.Clear();
00195 }
00196
00197 inline ReturnValue<T> GetReturnValue() const { return return_value_; }
00198 };
00199
00200 template<>
00201 class PropertyCallbackInfo<v8::Array> :
00202 public PropertyCallbackInfoBase<v8::Array> {
00203 ReturnValue<v8::Array> return_value_;
00204 v8::Persistent<v8::Array> retval_;
00205
00206 public:
00207 explicit inline PropertyCallbackInfo(
00208 const v8::AccessorInfo &info
00209 , const v8::Local<v8::Value> data) :
00210 PropertyCallbackInfoBase<v8::Array>(info, data)
00211 , return_value_(info.GetIsolate(), &retval_)
00212 , retval_(v8::Persistent<v8::Array>::New(v8::Local<v8::Array>())) {}
00213
00214 inline ~PropertyCallbackInfo() {
00215 retval_.Dispose();
00216 retval_.Clear();
00217 }
00218
00219 inline ReturnValue<v8::Array> GetReturnValue() const {
00220 return return_value_;
00221 }
00222 };
00223
00224 template<>
00225 class PropertyCallbackInfo<v8::Boolean> :
00226 public PropertyCallbackInfoBase<v8::Boolean> {
00227 ReturnValue<v8::Boolean> return_value_;
00228 v8::Persistent<v8::Boolean> retval_;
00229
00230 public:
00231 explicit inline PropertyCallbackInfo(
00232 const v8::AccessorInfo &info
00233 , const v8::Local<v8::Value> data) :
00234 PropertyCallbackInfoBase<v8::Boolean>(info, data)
00235 , return_value_(info.GetIsolate(), &retval_)
00236 , retval_(v8::Persistent<v8::Boolean>::New(v8::Local<v8::Boolean>())) {}
00237
00238 inline ~PropertyCallbackInfo() {
00239 retval_.Dispose();
00240 retval_.Clear();
00241 }
00242
00243 inline ReturnValue<v8::Boolean> GetReturnValue() const {
00244 return return_value_;
00245 }
00246 };
00247
00248 template<>
00249 class PropertyCallbackInfo<v8::Integer> :
00250 public PropertyCallbackInfoBase<v8::Integer> {
00251 ReturnValue<v8::Integer> return_value_;
00252 v8::Persistent<v8::Integer> retval_;
00253
00254 public:
00255 explicit inline PropertyCallbackInfo(
00256 const v8::AccessorInfo &info
00257 , const v8::Local<v8::Value> data) :
00258 PropertyCallbackInfoBase<v8::Integer>(info, data)
00259 , return_value_(info.GetIsolate(), &retval_)
00260 , retval_(v8::Persistent<v8::Integer>::New(v8::Local<v8::Integer>())) {}
00261
00262 inline ~PropertyCallbackInfo() {
00263 retval_.Dispose();
00264 retval_.Clear();
00265 }
00266
00267 inline ReturnValue<v8::Integer> GetReturnValue() const {
00268 return return_value_;
00269 }
00270 };
00271
00272 namespace imp {
00273 template<typename T>
00274 class ReturnValueImp : public ReturnValue<T> {
00275 public:
00276 explicit ReturnValueImp(ReturnValue<T> that) :
00277 ReturnValue<T>(that) {}
00278 inline v8::Handle<T> Value() {
00279 return *ReturnValue<T>::value_;
00280 }
00281 };
00282
00283 static
00284 v8::Handle<v8::Value> FunctionCallbackWrapper(const v8::Arguments &args) {
00285 v8::Local<v8::Object> obj = args.Data().As<v8::Object>();
00286 FunctionCallback callback = reinterpret_cast<FunctionCallback>(
00287 reinterpret_cast<intptr_t>(
00288 obj->GetInternalField(kFunctionIndex).As<v8::External>()->Value()));
00289 FunctionCallbackInfo<v8::Value>
00290 cbinfo(args, obj->GetInternalField(kDataIndex));
00291 callback(cbinfo);
00292 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
00293 }
00294
00295 typedef v8::Handle<v8::Value> (*NativeFunction)(const v8::Arguments &);
00296
00297 static
00298 v8::Handle<v8::Value> GetterCallbackWrapper(
00299 v8::Local<v8::String> property, const v8::AccessorInfo &info) {
00300 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00301 PropertyCallbackInfo<v8::Value>
00302 cbinfo(info, obj->GetInternalField(kDataIndex));
00303 GetterCallback callback = reinterpret_cast<GetterCallback>(
00304 reinterpret_cast<intptr_t>(
00305 obj->GetInternalField(kGetterIndex).As<v8::External>()->Value()));
00306 callback(property, cbinfo);
00307 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
00308 }
00309
00310 typedef v8::Handle<v8::Value> (*NativeGetter)
00311 (v8::Local<v8::String>, const v8::AccessorInfo &);
00312
00313 static
00314 void SetterCallbackWrapper(
00315 v8::Local<v8::String> property
00316 , v8::Local<v8::Value> value
00317 , const v8::AccessorInfo &info) {
00318 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00319 PropertyCallbackInfo<void>
00320 cbinfo(info, obj->GetInternalField(kDataIndex));
00321 SetterCallback callback = reinterpret_cast<SetterCallback>(
00322 reinterpret_cast<intptr_t>(
00323 obj->GetInternalField(kSetterIndex).As<v8::External>()->Value()));
00324 callback(property, value, cbinfo);
00325 }
00326
00327 typedef void (*NativeSetter)
00328 (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
00329
00330 static
00331 v8::Handle<v8::Value> PropertyGetterCallbackWrapper(
00332 v8::Local<v8::String> property, const v8::AccessorInfo &info) {
00333 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00334 PropertyCallbackInfo<v8::Value>
00335 cbinfo(info, obj->GetInternalField(kDataIndex));
00336 PropertyGetterCallback callback = reinterpret_cast<PropertyGetterCallback>(
00337 reinterpret_cast<intptr_t>(
00338 obj->GetInternalField(kPropertyGetterIndex)
00339 .As<v8::External>()->Value()));
00340 callback(property, cbinfo);
00341 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
00342 }
00343
00344 typedef v8::Handle<v8::Value> (*NativePropertyGetter)
00345 (v8::Local<v8::String>, const v8::AccessorInfo &);
00346
00347 static
00348 v8::Handle<v8::Value> PropertySetterCallbackWrapper(
00349 v8::Local<v8::String> property
00350 , v8::Local<v8::Value> value
00351 , const v8::AccessorInfo &info) {
00352 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00353 PropertyCallbackInfo<v8::Value>
00354 cbinfo(info, obj->GetInternalField(kDataIndex));
00355 PropertySetterCallback callback = reinterpret_cast<PropertySetterCallback>(
00356 reinterpret_cast<intptr_t>(
00357 obj->GetInternalField(kPropertySetterIndex)
00358 .As<v8::External>()->Value()));
00359 callback(property, value, cbinfo);
00360 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
00361 }
00362
00363 typedef v8::Handle<v8::Value> (*NativePropertySetter)
00364 (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
00365
00366 static
00367 v8::Handle<v8::Array> PropertyEnumeratorCallbackWrapper(
00368 const v8::AccessorInfo &info) {
00369 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00370 PropertyCallbackInfo<v8::Array>
00371 cbinfo(info, obj->GetInternalField(kDataIndex));
00372 PropertyEnumeratorCallback callback =
00373 reinterpret_cast<PropertyEnumeratorCallback>(reinterpret_cast<intptr_t>(
00374 obj->GetInternalField(kPropertyEnumeratorIndex)
00375 .As<v8::External>()->Value()));
00376 callback(cbinfo);
00377 return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
00378 }
00379
00380 typedef v8::Handle<v8::Array> (*NativePropertyEnumerator)
00381 (const v8::AccessorInfo &);
00382
00383 static
00384 v8::Handle<v8::Boolean> PropertyDeleterCallbackWrapper(
00385 v8::Local<v8::String> property
00386 , const v8::AccessorInfo &info) {
00387 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00388 PropertyCallbackInfo<v8::Boolean>
00389 cbinfo(info, obj->GetInternalField(kDataIndex));
00390 PropertyDeleterCallback callback = reinterpret_cast<PropertyDeleterCallback>(
00391 reinterpret_cast<intptr_t>(
00392 obj->GetInternalField(kPropertyDeleterIndex)
00393 .As<v8::External>()->Value()));
00394 callback(property, cbinfo);
00395 return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value();
00396 }
00397
00398 typedef v8::Handle<v8::Boolean> (NativePropertyDeleter)
00399 (v8::Local<v8::String>, const v8::AccessorInfo &);
00400
00401 static
00402 v8::Handle<v8::Integer> PropertyQueryCallbackWrapper(
00403 v8::Local<v8::String> property, const v8::AccessorInfo &info) {
00404 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00405 PropertyCallbackInfo<v8::Integer>
00406 cbinfo(info, obj->GetInternalField(kDataIndex));
00407 PropertyQueryCallback callback = reinterpret_cast<PropertyQueryCallback>(
00408 reinterpret_cast<intptr_t>(
00409 obj->GetInternalField(kPropertyQueryIndex)
00410 .As<v8::External>()->Value()));
00411 callback(property, cbinfo);
00412 return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value();
00413 }
00414
00415 typedef v8::Handle<v8::Integer> (*NativePropertyQuery)
00416 (v8::Local<v8::String>, const v8::AccessorInfo &);
00417
00418 static
00419 v8::Handle<v8::Value> IndexGetterCallbackWrapper(
00420 uint32_t index, const v8::AccessorInfo &info) {
00421 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00422 PropertyCallbackInfo<v8::Value>
00423 cbinfo(info, obj->GetInternalField(kDataIndex));
00424 IndexGetterCallback callback = reinterpret_cast<IndexGetterCallback>(
00425 reinterpret_cast<intptr_t>(
00426 obj->GetInternalField(kIndexPropertyGetterIndex)
00427 .As<v8::External>()->Value()));
00428 callback(index, cbinfo);
00429 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
00430 }
00431
00432 typedef v8::Handle<v8::Value> (*NativeIndexGetter)
00433 (uint32_t, const v8::AccessorInfo &);
00434
00435 static
00436 v8::Handle<v8::Value> IndexSetterCallbackWrapper(
00437 uint32_t index
00438 , v8::Local<v8::Value> value
00439 , const v8::AccessorInfo &info) {
00440 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00441 PropertyCallbackInfo<v8::Value>
00442 cbinfo(info, obj->GetInternalField(kDataIndex));
00443 IndexSetterCallback callback = reinterpret_cast<IndexSetterCallback>(
00444 reinterpret_cast<intptr_t>(
00445 obj->GetInternalField(kIndexPropertySetterIndex)
00446 .As<v8::External>()->Value()));
00447 callback(index, value, cbinfo);
00448 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
00449 }
00450
00451 typedef v8::Handle<v8::Value> (*NativeIndexSetter)
00452 (uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo &);
00453
00454 static
00455 v8::Handle<v8::Array> IndexEnumeratorCallbackWrapper(
00456 const v8::AccessorInfo &info) {
00457 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00458 PropertyCallbackInfo<v8::Array>
00459 cbinfo(info, obj->GetInternalField(kDataIndex));
00460 IndexEnumeratorCallback callback = reinterpret_cast<IndexEnumeratorCallback>(
00461 reinterpret_cast<intptr_t>(
00462 obj->GetInternalField(kIndexPropertyEnumeratorIndex)
00463 .As<v8::External>()->Value()));
00464 callback(cbinfo);
00465 return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
00466 }
00467
00468 typedef v8::Handle<v8::Array> (*NativeIndexEnumerator)
00469 (const v8::AccessorInfo &);
00470
00471 static
00472 v8::Handle<v8::Boolean> IndexDeleterCallbackWrapper(
00473 uint32_t index, const v8::AccessorInfo &info) {
00474 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00475 PropertyCallbackInfo<v8::Boolean>
00476 cbinfo(info, obj->GetInternalField(kDataIndex));
00477 IndexDeleterCallback callback = reinterpret_cast<IndexDeleterCallback>(
00478 reinterpret_cast<intptr_t>(
00479 obj->GetInternalField(kIndexPropertyDeleterIndex)
00480 .As<v8::External>()->Value()));
00481 callback(index, cbinfo);
00482 return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value();
00483 }
00484
00485 typedef v8::Handle<v8::Boolean> (*NativeIndexDeleter)
00486 (uint32_t, const v8::AccessorInfo &);
00487
00488 static
00489 v8::Handle<v8::Integer> IndexQueryCallbackWrapper(
00490 uint32_t index, const v8::AccessorInfo &info) {
00491 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
00492 PropertyCallbackInfo<v8::Integer>
00493 cbinfo(info, obj->GetInternalField(kDataIndex));
00494 IndexQueryCallback callback = reinterpret_cast<IndexQueryCallback>(
00495 reinterpret_cast<intptr_t>(
00496 obj->GetInternalField(kIndexPropertyQueryIndex)
00497 .As<v8::External>()->Value()));
00498 callback(index, cbinfo);
00499 return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value();
00500 }
00501
00502 typedef v8::Handle<v8::Integer> (*NativeIndexQuery)
00503 (uint32_t, const v8::AccessorInfo &);
00504 }
00505
00506 #endif // NAN_CALLBACKS_PRE_12_INL_H_