nan_weak.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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_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<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
  250. assert((*self_v)->IsObject());
  251. v8::Local<v8::Object> self((*self_v).As<v8::Object>());
  252. int count = self->InternalFieldCount();
  253. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  254. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  255. internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
  256. }
  257. wcbd = new WeakCallbackInfo<P>(
  258. reinterpret_cast<Persistent<v8::Value>*>(this)
  259. , callback
  260. , 0
  261. , internal_fields[0]
  262. , internal_fields[1]);
  263. self->SetAlignedPointerInInternalField(0, wcbd);
  264. v8::PersistentBase<T>::SetWeak(
  265. static_cast<WeakCallbackInfo<P>*>(0)
  266. , WeakCallbackInfo<P>::template invoketwofield<true>
  267. , type);
  268. }
  269. }
  270. #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
  271. template<typename T, typename M>
  272. template<typename P>
  273. inline void Persistent<T, M>::SetWeak(
  274. P *parameter
  275. , typename WeakCallbackInfo<P>::Callback callback
  276. , WeakCallbackType type) {
  277. WeakCallbackInfo<P> *wcbd;
  278. if (type == WeakCallbackType::kParameter) {
  279. wcbd = new WeakCallbackInfo<P>(
  280. reinterpret_cast<Persistent<v8::Value>*>(this)
  281. , callback
  282. , parameter);
  283. v8::PersistentBase<T>::SetPhantom(
  284. wcbd
  285. , WeakCallbackInfo<P>::invokeparameter);
  286. } else {
  287. v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
  288. assert((*self_v)->IsObject());
  289. v8::Local<v8::Object> self((*self_v).As<v8::Object>());
  290. int count = self->InternalFieldCount();
  291. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  292. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  293. internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
  294. }
  295. wcbd = new WeakCallbackInfo<P>(
  296. reinterpret_cast<Persistent<v8::Value>*>(this)
  297. , callback
  298. , 0
  299. , internal_fields[0]
  300. , internal_fields[1]);
  301. self->SetAlignedPointerInInternalField(0, wcbd);
  302. v8::PersistentBase<T>::SetPhantom(
  303. static_cast<WeakCallbackInfo<P>*>(0)
  304. , WeakCallbackInfo<P>::invoketwofield
  305. , 0
  306. , count > 1 ? 1 : kNoInternalFieldIndex);
  307. }
  308. }
  309. #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
  310. template<typename T, typename M>
  311. template<typename P>
  312. inline void Persistent<T, M>::SetWeak(
  313. P *parameter
  314. , typename WeakCallbackInfo<P>::Callback callback
  315. , WeakCallbackType type) {
  316. WeakCallbackInfo<P> *wcbd;
  317. if (type == WeakCallbackType::kParameter) {
  318. wcbd = new WeakCallbackInfo<P>(
  319. reinterpret_cast<Persistent<v8::Value>*>(this)
  320. , callback
  321. , parameter);
  322. v8::PersistentBase<T>::SetPhantom(
  323. wcbd
  324. , WeakCallbackInfo<P>::invokeparameter);
  325. } else {
  326. v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
  327. assert((*self_v)->IsObject());
  328. v8::Local<v8::Object> self((*self_v).As<v8::Object>());
  329. int count = self->InternalFieldCount();
  330. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  331. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  332. internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
  333. }
  334. wcbd = new WeakCallbackInfo<P>(
  335. reinterpret_cast<Persistent<v8::Value>*>(this)
  336. , callback
  337. , 0
  338. , internal_fields[0]
  339. , internal_fields[1]);
  340. self->SetAlignedPointerInInternalField(0, wcbd);
  341. v8::PersistentBase<T>::SetPhantom(
  342. WeakCallbackInfo<P>::invoketwofield
  343. , 0
  344. , count > 1 ? 1 : kNoInternalFieldIndex);
  345. }
  346. }
  347. #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
  348. template<typename T, typename M>
  349. template<typename P>
  350. inline void Persistent<T, M>::SetWeak(
  351. P *parameter
  352. , typename WeakCallbackInfo<P>::Callback callback
  353. , WeakCallbackType type) {
  354. WeakCallbackInfo<P> *wcbd;
  355. if (type == WeakCallbackType::kParameter) {
  356. wcbd = new WeakCallbackInfo<P>(
  357. reinterpret_cast<Persistent<v8::Value>*>(this)
  358. , callback
  359. , parameter);
  360. v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
  361. } else {
  362. v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
  363. assert((*self_v)->IsObject());
  364. v8::Local<v8::Object> self((*self_v).As<v8::Object>());
  365. int count = self->InternalFieldCount();
  366. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  367. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  368. internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
  369. }
  370. wcbd = new WeakCallbackInfo<P>(
  371. reinterpret_cast<Persistent<v8::Value>*>(this)
  372. , callback
  373. , 0
  374. , internal_fields[0]
  375. , internal_fields[1]);
  376. v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
  377. }
  378. }
  379. #else
  380. template<typename T>
  381. template<typename P>
  382. inline void PersistentBase<T>::SetWeak(
  383. P *parameter
  384. , typename WeakCallbackInfo<P>::Callback callback
  385. , WeakCallbackType type) {
  386. WeakCallbackInfo<P> *wcbd;
  387. if (type == WeakCallbackType::kParameter) {
  388. wcbd = new WeakCallbackInfo<P>(
  389. reinterpret_cast<Persistent<v8::Value>*>(this)
  390. , callback
  391. , parameter);
  392. persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
  393. } else {
  394. v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
  395. assert((*self_v)->IsObject());
  396. v8::Local<v8::Object> self((*self_v).As<v8::Object>());
  397. int count = self->InternalFieldCount();
  398. void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
  399. for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
  400. internal_fields[i] = self->GetPointerFromInternalField(i);
  401. }
  402. wcbd = new WeakCallbackInfo<P>(
  403. reinterpret_cast<Persistent<v8::Value>*>(this)
  404. , callback
  405. , 0
  406. , internal_fields[0]
  407. , internal_fields[1]);
  408. persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
  409. }
  410. }
  411. #endif
  412. #endif // NAN_WEAK_H_