You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

nan_callbacks_pre_12_inl.h 17KB

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