nan_weak.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*********************************************************************
  2. * NAN - Native Abstractions for Node.js
  3. *
  4. * Copyright (c) 2017 NAN contributors
  5. *
  6. * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
  7. ********************************************************************/
  8. #ifndef NAN_WEAK_H_
  9. #define NAN_WEAK_H_
  10. static const int kInternalFieldsInWeakCallback = 2;
  11. static const int kNoInternalFieldIndex = -1;
  12. #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
  13. (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
  14. # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
  15. v8::WeakCallbackInfo<WeakCallbackInfo<T> > const&
  16. # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
  17. NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
  18. # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
  19. # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
  20. #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
  21. # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
  22. v8::PhantomCallbackData<WeakCallbackInfo<T> > const&
  23. # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
  24. NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
  25. # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
  26. # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
  27. #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
  28. # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
  29. v8::PhantomCallbackData<WeakCallbackInfo<T> > const&
  30. # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
  31. v8::InternalFieldsCallbackData<WeakCallbackInfo<T>, void> const&
  32. # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
  33. # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
  34. #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
  35. # define NAN_WEAK_CALLBACK_DATA_TYPE_ \
  36. v8::WeakCallbackData<S, WeakCallbackInfo<T> > const&
  37. # define NAN_WEAK_CALLBACK_SIG_ NAN_WEAK_CALLBACK_DATA_TYPE_
  38. #else
  39. # define NAN_WEAK_CALLBACK_DATA_TYPE_ void *
  40. # define NAN_WEAK_CALLBACK_SIG_ \
  41. v8::Persistent<v8::Value>, NAN_WEAK_CALLBACK_DATA_TYPE_
  42. #endif
  43. template<typename T>
  44. class WeakCallbackInfo {
  45. public:
  46. typedef void (*Callback)(const WeakCallbackInfo<T>& data);
  47. WeakCallbackInfo(
  48. Persistent<v8::Value> *persistent
  49. , Callback callback
  50. , void *parameter
  51. , void *field1 = 0
  52. , void *field2 = 0) :
  53. callback_(callback), isolate_(0), parameter_(parameter) {
  54. std::memcpy(&persistent_, persistent, sizeof (v8::Persistent<v8::Value>));
  55. internal_fields_[0] = field1;
  56. internal_fields_[1] = field2;
  57. }
  58. inline v8::Isolate *GetIsolate() const { return isolate_; }
  59. inline T *GetParameter() const { return static_cast<T*>(parameter_); }
  60. inline void *GetInternalField(int index) const {
  61. assert((index == 0 || index == 1) && "internal field index out of bounds");
  62. if (index == 0) {
  63. return internal_fields_[0];
  64. } else {
  65. return internal_fields_[1];
  66. }
  67. }
  68. private:
  69. NAN_DISALLOW_ASSIGN_COPY_MOVE(WeakCallbackInfo)
  70. Callback callback_;
  71. v8::Isolate *isolate_;
  72. void *parameter_;
  73. void *internal_fields_[kInternalFieldsInWeakCallback];
  74. v8::Persistent<v8::Value> persistent_;
  75. template<typename S, typename M> friend class Persistent;
  76. template<typename S> friend class PersistentBase;
  77. #if NODE_MODULE_VERSION <= NODE_0_12_MODULE_VERSION
  78. # if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
  79. template<typename S>
  80. static void invoke(NAN_WEAK_CALLBACK_SIG_ data);
  81. template<typename S>
  82. static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);
  83. # else
  84. static void invoke(NAN_WEAK_CALLBACK_SIG_ data);
  85. static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);
  86. # endif
  87. #else
  88. # if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
  89. (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
  90. template<bool isFirstPass>
  91. static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);
  92. template<bool isFirstPass>
  93. static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);
  94. # else
  95. static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);
  96. static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);
  97. # endif
  98. static WeakCallbackInfo *unwrapparameter(
  99. NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data);
  100. static WeakCallbackInfo *unwraptwofield(
  101. NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data);
  102. #endif
  103. };
  104. #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
  105. (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
  106. template<typename T>
  107. template<bool isFirstPass>
  108. void
  109. WeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
  110. WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);
  111. if (isFirstPass) {
  112. cbinfo->persistent_.Reset();
  113. data.SetSecondPassCallback(invokeparameter<false>);
  114. } else {
  115. cbinfo->callback_(*cbinfo);
  116. delete cbinfo;
  117. }
  118. }
  119. template<typename T>
  120. template<bool isFirstPass>
  121. void
  122. WeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
  123. WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);
  124. if (isFirstPass) {
  125. cbinfo->persistent_.Reset();
  126. data.SetSecondPassCallback(invoketwofield<false>);
  127. } else {
  128. cbinfo->callback_(*cbinfo);
  129. delete cbinfo;
  130. }
  131. }
  132. template<typename T>
  133. WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(
  134. NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
  135. WeakCallbackInfo<T> *cbinfo =
  136. static_cast<WeakCallbackInfo<T>*>(data.GetParameter());
  137. cbinfo->isolate_ = data.GetIsolate();
  138. return cbinfo;
  139. }
  140. template<typename T>
  141. WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(
  142. NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
  143. WeakCallbackInfo<T> *cbinfo =
  144. static_cast<WeakCallbackInfo<T>*>(data.GetInternalField(0));
  145. cbinfo->isolate_ = data.GetIsolate();
  146. return cbinfo;
  147. }
  148. #undef NAN_WEAK_PARAMETER_CALLBACK_SIG_
  149. #undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_
  150. #undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
  151. #undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
  152. # elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
  153. template<typename T>
  154. void
  155. WeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
  156. WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);
  157. cbinfo->persistent_.Reset();
  158. cbinfo->callback_(*cbinfo);
  159. delete cbinfo;
  160. }
  161. template<typename T>
  162. void
  163. WeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
  164. WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);
  165. cbinfo->persistent_.Reset();
  166. cbinfo->callback_(*cbinfo);
  167. delete cbinfo;
  168. }
  169. template<typename T>
  170. WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(
  171. NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
  172. WeakCallbackInfo<T> *cbinfo =
  173. static_cast<WeakCallbackInfo<T>*>(data.GetParameter());
  174. cbinfo->isolate_ = data.GetIsolate();
  175. return cbinfo;
  176. }
  177. template<typename T>
  178. WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(
  179. NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
  180. WeakCallbackInfo<T> *cbinfo =
  181. static_cast<WeakCallbackInfo<T>*>(data.GetInternalField1());
  182. cbinfo->isolate_ = data.GetIsolate();
  183. return cbinfo;
  184. }
  185. #undef NAN_WEAK_PARAMETER_CALLBACK_SIG_
  186. #undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_
  187. #undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
  188. #undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
  189. #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
  190. template<typename T>
  191. template<typename S>
  192. void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
  193. WeakCallbackInfo<T> *cbinfo = unwrap(data);
  194. cbinfo->persistent_.Reset();
  195. cbinfo->callback_(*cbinfo);
  196. delete cbinfo;
  197. }
  198. template<typename T>
  199. template<typename S>
  200. WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(
  201. NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
  202. void *parameter = data.GetParameter();
  203. WeakCallbackInfo<T> *cbinfo =
  204. static_cast<WeakCallbackInfo<T>*>(parameter);
  205. cbinfo->isolate_ = data.GetIsolate();
  206. return cbinfo;
  207. }
  208. #undef NAN_WEAK_CALLBACK_SIG_
  209. #undef NAN_WEAK_CALLBACK_DATA_TYPE_
  210. #else
  211. template<typename T>
  212. void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
  213. WeakCallbackInfo<T> *cbinfo = unwrap(data);
  214. cbinfo->persistent_.Dispose();
  215. cbinfo->persistent_.Clear();
  216. cbinfo->callback_(*cbinfo);
  217. delete cbinfo;
  218. }
  219. template<typename T>
  220. WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(
  221. NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
  222. WeakCallbackInfo<T> *cbinfo =
  223. static_cast<WeakCallbackInfo<T>*>(data);
  224. cbinfo->isolate_ = v8::Isolate::GetCurrent();
  225. return cbinfo;
  226. }
  227. #undef NAN_WEAK_CALLBACK_SIG_
  228. #undef NAN_WEAK_CALLBACK_DATA_TYPE_
  229. #endif
  230. #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
  231. (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
  232. template<typename T, typename M>
  233. template<typename P>
  234. inline void Persistent<T, M>::SetWeak(
  235. P *parameter
  236. , typename WeakCallbackInfo<P>::Callback callback
  237. , WeakCallbackType type) {
  238. WeakCallbackInfo<P> *wcbd;
  239. if (type == WeakCallbackType::kParameter) {
  240. wcbd = new WeakCallbackInfo<P>(
  241. reinterpret_cast<Persistent<v8::Value>*>(this)
  242. , callback
  243. , parameter);
  244. v8::PersistentBase<T>::SetWeak(
  245. wcbd
  246. , WeakCallbackInfo<P>::template invokeparameter<true>
  247. , type);
  248. } else {
  249. v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
  250. assert((*self)->IsObject());
  251. int count = (*self)->InternalFieldCount();
  252. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  253. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  254. internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
  255. }
  256. wcbd = new WeakCallbackInfo<P>(
  257. reinterpret_cast<Persistent<v8::Value>*>(this)
  258. , callback
  259. , 0
  260. , internal_fields[0]
  261. , internal_fields[1]);
  262. (*self)->SetAlignedPointerInInternalField(0, wcbd);
  263. v8::PersistentBase<T>::SetWeak(
  264. static_cast<WeakCallbackInfo<P>*>(0)
  265. , WeakCallbackInfo<P>::template invoketwofield<true>
  266. , type);
  267. }
  268. }
  269. #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
  270. template<typename T, typename M>
  271. template<typename P>
  272. inline void Persistent<T, M>::SetWeak(
  273. P *parameter
  274. , typename WeakCallbackInfo<P>::Callback callback
  275. , WeakCallbackType type) {
  276. WeakCallbackInfo<P> *wcbd;
  277. if (type == WeakCallbackType::kParameter) {
  278. wcbd = new WeakCallbackInfo<P>(
  279. reinterpret_cast<Persistent<v8::Value>*>(this)
  280. , callback
  281. , parameter);
  282. v8::PersistentBase<T>::SetPhantom(
  283. wcbd
  284. , WeakCallbackInfo<P>::invokeparameter);
  285. } else {
  286. v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
  287. assert((*self)->IsObject());
  288. int count = (*self)->InternalFieldCount();
  289. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  290. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  291. internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
  292. }
  293. wcbd = new WeakCallbackInfo<P>(
  294. reinterpret_cast<Persistent<v8::Value>*>(this)
  295. , callback
  296. , 0
  297. , internal_fields[0]
  298. , internal_fields[1]);
  299. (*self)->SetAlignedPointerInInternalField(0, wcbd);
  300. v8::PersistentBase<T>::SetPhantom(
  301. static_cast<WeakCallbackInfo<P>*>(0)
  302. , WeakCallbackInfo<P>::invoketwofield
  303. , 0
  304. , count > 1 ? 1 : kNoInternalFieldIndex);
  305. }
  306. }
  307. #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
  308. template<typename T, typename M>
  309. template<typename P>
  310. inline void Persistent<T, M>::SetWeak(
  311. P *parameter
  312. , typename WeakCallbackInfo<P>::Callback callback
  313. , WeakCallbackType type) {
  314. WeakCallbackInfo<P> *wcbd;
  315. if (type == WeakCallbackType::kParameter) {
  316. wcbd = new WeakCallbackInfo<P>(
  317. reinterpret_cast<Persistent<v8::Value>*>(this)
  318. , callback
  319. , parameter);
  320. v8::PersistentBase<T>::SetPhantom(
  321. wcbd
  322. , WeakCallbackInfo<P>::invokeparameter);
  323. } else {
  324. v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
  325. assert((*self)->IsObject());
  326. int count = (*self)->InternalFieldCount();
  327. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  328. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  329. internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
  330. }
  331. wcbd = new WeakCallbackInfo<P>(
  332. reinterpret_cast<Persistent<v8::Value>*>(this)
  333. , callback
  334. , 0
  335. , internal_fields[0]
  336. , internal_fields[1]);
  337. (*self)->SetAlignedPointerInInternalField(0, wcbd);
  338. v8::PersistentBase<T>::SetPhantom(
  339. WeakCallbackInfo<P>::invoketwofield
  340. , 0
  341. , count > 1 ? 1 : kNoInternalFieldIndex);
  342. }
  343. }
  344. #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
  345. template<typename T, typename M>
  346. template<typename P>
  347. inline void Persistent<T, M>::SetWeak(
  348. P *parameter
  349. , typename WeakCallbackInfo<P>::Callback callback
  350. , WeakCallbackType type) {
  351. WeakCallbackInfo<P> *wcbd;
  352. if (type == WeakCallbackType::kParameter) {
  353. wcbd = new WeakCallbackInfo<P>(
  354. reinterpret_cast<Persistent<v8::Value>*>(this)
  355. , callback
  356. , parameter);
  357. v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
  358. } else {
  359. v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
  360. assert((*self)->IsObject());
  361. int count = (*self)->InternalFieldCount();
  362. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  363. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  364. internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
  365. }
  366. wcbd = new WeakCallbackInfo<P>(
  367. reinterpret_cast<Persistent<v8::Value>*>(this)
  368. , callback
  369. , 0
  370. , internal_fields[0]
  371. , internal_fields[1]);
  372. v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
  373. }
  374. }
  375. #else
  376. template<typename T>
  377. template<typename P>
  378. inline void PersistentBase<T>::SetWeak(
  379. P *parameter
  380. , typename WeakCallbackInfo<P>::Callback callback
  381. , WeakCallbackType type) {
  382. WeakCallbackInfo<P> *wcbd;
  383. if (type == WeakCallbackType::kParameter) {
  384. wcbd = new WeakCallbackInfo<P>(
  385. reinterpret_cast<Persistent<v8::Value>*>(this)
  386. , callback
  387. , parameter);
  388. persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
  389. } else {
  390. v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
  391. assert((*self)->IsObject());
  392. int count = (*self)->InternalFieldCount();
  393. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  394. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  395. internal_fields[i] = (*self)->GetPointerFromInternalField(i);
  396. }
  397. wcbd = new WeakCallbackInfo<P>(
  398. reinterpret_cast<Persistent<v8::Value>*>(this)
  399. , callback
  400. , 0
  401. , internal_fields[0]
  402. , internal_fields[1]);
  403. persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
  404. }
  405. }
  406. #endif
  407. #endif // NAN_WEAK_H_