nan_callbacks_pre_12_inl.h 17 KB

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