nan_callbacks_pre_12_inl.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. /*********************************************************************
  2. * NAN - Native Abstractions for Node.js
  3. *
  4. * Copyright (c) 2016 NAN contributors
  5. *
  6. * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
  7. ********************************************************************/
  8. #ifndef NAN_CALLBACKS_PRE_12_INL_H_
  9. #define NAN_CALLBACKS_PRE_12_INL_H_
  10. namespace imp {
  11. template<typename T> class ReturnValueImp;
  12. } // end of namespace imp
  13. template<typename T>
  14. class ReturnValue {
  15. v8::Isolate *isolate_;
  16. v8::Persistent<T> *value_;
  17. friend class imp::ReturnValueImp<T>;
  18. public:
  19. template <class S>
  20. explicit inline ReturnValue(v8::Isolate *isolate, v8::Persistent<S> *p) :
  21. isolate_(isolate), value_(p) {}
  22. template <class S>
  23. explicit inline ReturnValue(const ReturnValue<S>& that)
  24. : isolate_(that.isolate_), value_(that.value_) {
  25. TYPE_CHECK(T, S);
  26. }
  27. // Handle setters
  28. template <typename S> inline void Set(const v8::Local<S> &handle) {
  29. TYPE_CHECK(T, S);
  30. value_->Dispose();
  31. *value_ = v8::Persistent<T>::New(handle);
  32. }
  33. template <typename S> inline void Set(const Global<S> &handle) {
  34. TYPE_CHECK(T, S);
  35. value_->Dispose();
  36. *value_ = v8::Persistent<T>::New(handle.persistent);
  37. const_cast<Global<S> &>(handle).Reset();
  38. }
  39. // Fast primitive setters
  40. inline void Set(bool value) {
  41. TYPE_CHECK(T, v8::Boolean);
  42. value_->Dispose();
  43. *value_ = v8::Persistent<T>::New(v8::Boolean::New(value));
  44. }
  45. inline void Set(double i) {
  46. TYPE_CHECK(T, v8::Number);
  47. value_->Dispose();
  48. *value_ = v8::Persistent<T>::New(v8::Number::New(i));
  49. }
  50. inline void Set(int32_t i) {
  51. TYPE_CHECK(T, v8::Integer);
  52. value_->Dispose();
  53. *value_ = v8::Persistent<T>::New(v8::Int32::New(i));
  54. }
  55. inline void Set(uint32_t i) {
  56. TYPE_CHECK(T, v8::Integer);
  57. value_->Dispose();
  58. *value_ = v8::Persistent<T>::New(v8::Uint32::NewFromUnsigned(i));
  59. }
  60. // Fast JS primitive setters
  61. inline void SetNull() {
  62. TYPE_CHECK(T, v8::Primitive);
  63. value_->Dispose();
  64. *value_ = v8::Persistent<T>::New(v8::Null());
  65. }
  66. inline void SetUndefined() {
  67. TYPE_CHECK(T, v8::Primitive);
  68. value_->Dispose();
  69. *value_ = v8::Persistent<T>::New(v8::Undefined());
  70. }
  71. inline void SetEmptyString() {
  72. TYPE_CHECK(T, v8::String);
  73. value_->Dispose();
  74. *value_ = v8::Persistent<T>::New(v8::String::Empty());
  75. }
  76. // Convenience getter for isolate
  77. inline v8::Isolate *GetIsolate() const {
  78. return isolate_;
  79. }
  80. // Pointer setter: Uncompilable to prevent inadvertent misuse.
  81. template<typename S>
  82. inline void Set(S *whatever) { TYPE_CHECK(S*, v8::Primitive); }
  83. };
  84. template<typename T>
  85. class FunctionCallbackInfo {
  86. const v8::Arguments &args_;
  87. v8::Local<v8::Value> data_;
  88. ReturnValue<T> return_value_;
  89. v8::Persistent<T> retval_;
  90. public:
  91. explicit inline FunctionCallbackInfo(
  92. const v8::Arguments &args
  93. , v8::Local<v8::Value> data) :
  94. args_(args)
  95. , data_(data)
  96. , return_value_(args.GetIsolate(), &retval_)
  97. , retval_(v8::Persistent<T>::New(v8::Undefined())) {}
  98. inline ~FunctionCallbackInfo() {
  99. retval_.Dispose();
  100. retval_.Clear();
  101. }
  102. inline ReturnValue<T> GetReturnValue() const {
  103. return ReturnValue<T>(return_value_);
  104. }
  105. inline v8::Local<v8::Function> Callee() const { return args_.Callee(); }
  106. inline v8::Local<v8::Value> Data() const { return data_; }
  107. inline v8::Local<v8::Object> Holder() const { return args_.Holder(); }
  108. inline bool IsConstructCall() const { return args_.IsConstructCall(); }
  109. inline int Length() const { return args_.Length(); }
  110. inline v8::Local<v8::Value> operator[](int i) const { return args_[i]; }
  111. inline v8::Local<v8::Object> This() const { return args_.This(); }
  112. inline v8::Isolate *GetIsolate() const { return args_.GetIsolate(); }
  113. protected:
  114. static const int kHolderIndex = 0;
  115. static const int kIsolateIndex = 1;
  116. static const int kReturnValueDefaultValueIndex = 2;
  117. static const int kReturnValueIndex = 3;
  118. static const int kDataIndex = 4;
  119. static const int kCalleeIndex = 5;
  120. static const int kContextSaveIndex = 6;
  121. static const int kArgsLength = 7;
  122. private:
  123. NAN_DISALLOW_ASSIGN_COPY_MOVE(FunctionCallbackInfo)
  124. };
  125. template<typename T>
  126. class PropertyCallbackInfoBase {
  127. const v8::AccessorInfo &info_;
  128. const v8::Local<v8::Value> data_;
  129. public:
  130. explicit inline PropertyCallbackInfoBase(
  131. const v8::AccessorInfo &info
  132. , const v8::Local<v8::Value> data) :
  133. info_(info)
  134. , data_(data) {}
  135. inline v8::Isolate* GetIsolate() const { return info_.GetIsolate(); }
  136. inline v8::Local<v8::Value> Data() const { return data_; }
  137. inline v8::Local<v8::Object> This() const { return info_.This(); }
  138. inline v8::Local<v8::Object> Holder() const { return info_.Holder(); }
  139. protected:
  140. static const int kHolderIndex = 0;
  141. static const int kIsolateIndex = 1;
  142. static const int kReturnValueDefaultValueIndex = 2;
  143. static const int kReturnValueIndex = 3;
  144. static const int kDataIndex = 4;
  145. static const int kThisIndex = 5;
  146. static const int kArgsLength = 6;
  147. private:
  148. NAN_DISALLOW_ASSIGN_COPY_MOVE(PropertyCallbackInfoBase)
  149. };
  150. template<typename T>
  151. class PropertyCallbackInfo : public PropertyCallbackInfoBase<T> {
  152. ReturnValue<T> return_value_;
  153. v8::Persistent<T> retval_;
  154. public:
  155. explicit inline PropertyCallbackInfo(
  156. const v8::AccessorInfo &info
  157. , const v8::Local<v8::Value> data) :
  158. PropertyCallbackInfoBase<T>(info, data)
  159. , return_value_(info.GetIsolate(), &retval_)
  160. , retval_(v8::Persistent<T>::New(v8::Undefined())) {}
  161. inline ~PropertyCallbackInfo() {
  162. retval_.Dispose();
  163. retval_.Clear();
  164. }
  165. inline ReturnValue<T> GetReturnValue() const { return return_value_; }
  166. };
  167. template<>
  168. class PropertyCallbackInfo<v8::Array> :
  169. public PropertyCallbackInfoBase<v8::Array> {
  170. ReturnValue<v8::Array> return_value_;
  171. v8::Persistent<v8::Array> retval_;
  172. public:
  173. explicit inline PropertyCallbackInfo(
  174. const v8::AccessorInfo &info
  175. , const v8::Local<v8::Value> data) :
  176. PropertyCallbackInfoBase<v8::Array>(info, data)
  177. , return_value_(info.GetIsolate(), &retval_)
  178. , retval_(v8::Persistent<v8::Array>::New(v8::Local<v8::Array>())) {}
  179. inline ~PropertyCallbackInfo() {
  180. retval_.Dispose();
  181. retval_.Clear();
  182. }
  183. inline ReturnValue<v8::Array> GetReturnValue() const {
  184. return return_value_;
  185. }
  186. };
  187. template<>
  188. class PropertyCallbackInfo<v8::Boolean> :
  189. public PropertyCallbackInfoBase<v8::Boolean> {
  190. ReturnValue<v8::Boolean> return_value_;
  191. v8::Persistent<v8::Boolean> retval_;
  192. public:
  193. explicit inline PropertyCallbackInfo(
  194. const v8::AccessorInfo &info
  195. , const v8::Local<v8::Value> data) :
  196. PropertyCallbackInfoBase<v8::Boolean>(info, data)
  197. , return_value_(info.GetIsolate(), &retval_)
  198. , retval_(v8::Persistent<v8::Boolean>::New(v8::Local<v8::Boolean>())) {}
  199. inline ~PropertyCallbackInfo() {
  200. retval_.Dispose();
  201. retval_.Clear();
  202. }
  203. inline ReturnValue<v8::Boolean> GetReturnValue() const {
  204. return return_value_;
  205. }
  206. };
  207. template<>
  208. class PropertyCallbackInfo<v8::Integer> :
  209. public PropertyCallbackInfoBase<v8::Integer> {
  210. ReturnValue<v8::Integer> return_value_;
  211. v8::Persistent<v8::Integer> retval_;
  212. public:
  213. explicit inline PropertyCallbackInfo(
  214. const v8::AccessorInfo &info
  215. , const v8::Local<v8::Value> data) :
  216. PropertyCallbackInfoBase<v8::Integer>(info, data)
  217. , return_value_(info.GetIsolate(), &retval_)
  218. , retval_(v8::Persistent<v8::Integer>::New(v8::Local<v8::Integer>())) {}
  219. inline ~PropertyCallbackInfo() {
  220. retval_.Dispose();
  221. retval_.Clear();
  222. }
  223. inline ReturnValue<v8::Integer> GetReturnValue() const {
  224. return return_value_;
  225. }
  226. };
  227. namespace imp {
  228. template<typename T>
  229. class ReturnValueImp : public ReturnValue<T> {
  230. public:
  231. explicit ReturnValueImp(ReturnValue<T> that) :
  232. ReturnValue<T>(that) {}
  233. inline v8::Handle<T> Value() {
  234. return *ReturnValue<T>::value_;
  235. }
  236. };
  237. static
  238. v8::Handle<v8::Value> FunctionCallbackWrapper(const v8::Arguments &args) {
  239. v8::Local<v8::Object> obj = args.Data().As<v8::Object>();
  240. FunctionCallback callback = reinterpret_cast<FunctionCallback>(
  241. reinterpret_cast<intptr_t>(
  242. obj->GetInternalField(kFunctionIndex).As<v8::External>()->Value()));
  243. FunctionCallbackInfo<v8::Value>
  244. cbinfo(args, obj->GetInternalField(kDataIndex));
  245. callback(cbinfo);
  246. return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
  247. }
  248. typedef v8::Handle<v8::Value> (*NativeFunction)(const v8::Arguments &);
  249. static
  250. v8::Handle<v8::Value> GetterCallbackWrapper(
  251. v8::Local<v8::String> property, const v8::AccessorInfo &info) {
  252. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  253. PropertyCallbackInfo<v8::Value>
  254. cbinfo(info, obj->GetInternalField(kDataIndex));
  255. GetterCallback callback = reinterpret_cast<GetterCallback>(
  256. reinterpret_cast<intptr_t>(
  257. obj->GetInternalField(kGetterIndex).As<v8::External>()->Value()));
  258. callback(property, cbinfo);
  259. return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
  260. }
  261. typedef v8::Handle<v8::Value> (*NativeGetter)
  262. (v8::Local<v8::String>, const v8::AccessorInfo &);
  263. static
  264. void SetterCallbackWrapper(
  265. v8::Local<v8::String> property
  266. , v8::Local<v8::Value> value
  267. , const v8::AccessorInfo &info) {
  268. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  269. PropertyCallbackInfo<void>
  270. cbinfo(info, obj->GetInternalField(kDataIndex));
  271. SetterCallback callback = reinterpret_cast<SetterCallback>(
  272. reinterpret_cast<intptr_t>(
  273. obj->GetInternalField(kSetterIndex).As<v8::External>()->Value()));
  274. callback(property, value, cbinfo);
  275. }
  276. typedef void (*NativeSetter)
  277. (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
  278. static
  279. v8::Handle<v8::Value> PropertyGetterCallbackWrapper(
  280. v8::Local<v8::String> property, const v8::AccessorInfo &info) {
  281. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  282. PropertyCallbackInfo<v8::Value>
  283. cbinfo(info, obj->GetInternalField(kDataIndex));
  284. PropertyGetterCallback callback = reinterpret_cast<PropertyGetterCallback>(
  285. reinterpret_cast<intptr_t>(
  286. obj->GetInternalField(kPropertyGetterIndex)
  287. .As<v8::External>()->Value()));
  288. callback(property, cbinfo);
  289. return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
  290. }
  291. typedef v8::Handle<v8::Value> (*NativePropertyGetter)
  292. (v8::Local<v8::String>, const v8::AccessorInfo &);
  293. static
  294. v8::Handle<v8::Value> PropertySetterCallbackWrapper(
  295. v8::Local<v8::String> property
  296. , v8::Local<v8::Value> value
  297. , const v8::AccessorInfo &info) {
  298. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  299. PropertyCallbackInfo<v8::Value>
  300. cbinfo(info, obj->GetInternalField(kDataIndex));
  301. PropertySetterCallback callback = reinterpret_cast<PropertySetterCallback>(
  302. reinterpret_cast<intptr_t>(
  303. obj->GetInternalField(kPropertySetterIndex)
  304. .As<v8::External>()->Value()));
  305. callback(property, value, cbinfo);
  306. return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
  307. }
  308. typedef v8::Handle<v8::Value> (*NativePropertySetter)
  309. (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
  310. static
  311. v8::Handle<v8::Array> PropertyEnumeratorCallbackWrapper(
  312. const v8::AccessorInfo &info) {
  313. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  314. PropertyCallbackInfo<v8::Array>
  315. cbinfo(info, obj->GetInternalField(kDataIndex));
  316. PropertyEnumeratorCallback callback =
  317. reinterpret_cast<PropertyEnumeratorCallback>(reinterpret_cast<intptr_t>(
  318. obj->GetInternalField(kPropertyEnumeratorIndex)
  319. .As<v8::External>()->Value()));
  320. callback(cbinfo);
  321. return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
  322. }
  323. typedef v8::Handle<v8::Array> (*NativePropertyEnumerator)
  324. (const v8::AccessorInfo &);
  325. static
  326. v8::Handle<v8::Boolean> PropertyDeleterCallbackWrapper(
  327. v8::Local<v8::String> property
  328. , const v8::AccessorInfo &info) {
  329. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  330. PropertyCallbackInfo<v8::Boolean>
  331. cbinfo(info, obj->GetInternalField(kDataIndex));
  332. PropertyDeleterCallback callback = reinterpret_cast<PropertyDeleterCallback>(
  333. reinterpret_cast<intptr_t>(
  334. obj->GetInternalField(kPropertyDeleterIndex)
  335. .As<v8::External>()->Value()));
  336. callback(property, cbinfo);
  337. return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value();
  338. }
  339. typedef v8::Handle<v8::Boolean> (NativePropertyDeleter)
  340. (v8::Local<v8::String>, const v8::AccessorInfo &);
  341. static
  342. v8::Handle<v8::Integer> PropertyQueryCallbackWrapper(
  343. v8::Local<v8::String> property, const v8::AccessorInfo &info) {
  344. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  345. PropertyCallbackInfo<v8::Integer>
  346. cbinfo(info, obj->GetInternalField(kDataIndex));
  347. PropertyQueryCallback callback = reinterpret_cast<PropertyQueryCallback>(
  348. reinterpret_cast<intptr_t>(
  349. obj->GetInternalField(kPropertyQueryIndex)
  350. .As<v8::External>()->Value()));
  351. callback(property, cbinfo);
  352. return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value();
  353. }
  354. typedef v8::Handle<v8::Integer> (*NativePropertyQuery)
  355. (v8::Local<v8::String>, const v8::AccessorInfo &);
  356. static
  357. v8::Handle<v8::Value> IndexGetterCallbackWrapper(
  358. uint32_t index, const v8::AccessorInfo &info) {
  359. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  360. PropertyCallbackInfo<v8::Value>
  361. cbinfo(info, obj->GetInternalField(kDataIndex));
  362. IndexGetterCallback callback = reinterpret_cast<IndexGetterCallback>(
  363. reinterpret_cast<intptr_t>(
  364. obj->GetInternalField(kIndexPropertyGetterIndex)
  365. .As<v8::External>()->Value()));
  366. callback(index, cbinfo);
  367. return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
  368. }
  369. typedef v8::Handle<v8::Value> (*NativeIndexGetter)
  370. (uint32_t, const v8::AccessorInfo &);
  371. static
  372. v8::Handle<v8::Value> IndexSetterCallbackWrapper(
  373. uint32_t index
  374. , v8::Local<v8::Value> value
  375. , const v8::AccessorInfo &info) {
  376. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  377. PropertyCallbackInfo<v8::Value>
  378. cbinfo(info, obj->GetInternalField(kDataIndex));
  379. IndexSetterCallback callback = reinterpret_cast<IndexSetterCallback>(
  380. reinterpret_cast<intptr_t>(
  381. obj->GetInternalField(kIndexPropertySetterIndex)
  382. .As<v8::External>()->Value()));
  383. callback(index, value, cbinfo);
  384. return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
  385. }
  386. typedef v8::Handle<v8::Value> (*NativeIndexSetter)
  387. (uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo &);
  388. static
  389. v8::Handle<v8::Array> IndexEnumeratorCallbackWrapper(
  390. const v8::AccessorInfo &info) {
  391. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  392. PropertyCallbackInfo<v8::Array>
  393. cbinfo(info, obj->GetInternalField(kDataIndex));
  394. IndexEnumeratorCallback callback = reinterpret_cast<IndexEnumeratorCallback>(
  395. reinterpret_cast<intptr_t>(
  396. obj->GetInternalField(kIndexPropertyEnumeratorIndex)
  397. .As<v8::External>()->Value()));
  398. callback(cbinfo);
  399. return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
  400. }
  401. typedef v8::Handle<v8::Array> (*NativeIndexEnumerator)
  402. (const v8::AccessorInfo &);
  403. static
  404. v8::Handle<v8::Boolean> IndexDeleterCallbackWrapper(
  405. uint32_t index, const v8::AccessorInfo &info) {
  406. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  407. PropertyCallbackInfo<v8::Boolean>
  408. cbinfo(info, obj->GetInternalField(kDataIndex));
  409. IndexDeleterCallback callback = reinterpret_cast<IndexDeleterCallback>(
  410. reinterpret_cast<intptr_t>(
  411. obj->GetInternalField(kIndexPropertyDeleterIndex)
  412. .As<v8::External>()->Value()));
  413. callback(index, cbinfo);
  414. return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value();
  415. }
  416. typedef v8::Handle<v8::Boolean> (*NativeIndexDeleter)
  417. (uint32_t, const v8::AccessorInfo &);
  418. static
  419. v8::Handle<v8::Integer> IndexQueryCallbackWrapper(
  420. uint32_t index, const v8::AccessorInfo &info) {
  421. v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
  422. PropertyCallbackInfo<v8::Integer>
  423. cbinfo(info, obj->GetInternalField(kDataIndex));
  424. IndexQueryCallback callback = reinterpret_cast<IndexQueryCallback>(
  425. reinterpret_cast<intptr_t>(
  426. obj->GetInternalField(kIndexPropertyQueryIndex)
  427. .As<v8::External>()->Value()));
  428. callback(index, cbinfo);
  429. return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value();
  430. }
  431. typedef v8::Handle<v8::Integer> (*NativeIndexQuery)
  432. (uint32_t, const v8::AccessorInfo &);
  433. } // end of namespace imp
  434. #endif // NAN_CALLBACKS_PRE_12_INL_H_