Mercurial > hg > sv-dependency-builds
comparison osx/include/kj/async-inl.h @ 147:45360b968bf4
Cap'n Proto v0.6 + build for OSX
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Mon, 22 May 2017 10:01:37 +0100 |
parents | 41e769c91eca |
children |
comparison
equal
deleted
inserted
replaced
146:206f0eb279b8 | 147:45360b968bf4 |
---|---|
253 | 253 |
254 template <typename... ParamTypes> | 254 template <typename... ParamTypes> |
255 friend struct GetFunctorStartAddress; | 255 friend struct GetFunctorStartAddress; |
256 | 256 |
257 #if __GNUG__ | 257 #if __GNUG__ |
258 | |
258 void* ptr; | 259 void* ptr; |
259 ptrdiff_t adj; | 260 ptrdiff_t adj; |
260 // Layout of a pointer-to-member-function used by GCC and compatible compilers. | 261 // Layout of a pointer-to-member-function used by GCC and compatible compilers. |
261 #else | |
262 #error "TODO(port): PTMF instruction address extraction" | |
263 #endif | |
264 | |
265 #define BODY \ | |
266 PtmfHelper result; \ | |
267 static_assert(sizeof(p) == sizeof(result), "unknown ptmf layout"); \ | |
268 memcpy(&result, &p, sizeof(result)); \ | |
269 return result | |
270 | |
271 template <typename R, typename C, typename... P, typename F> | |
272 static PtmfHelper from(F p) { BODY; } | |
273 // Create a PtmfHelper from some arbitrary pointer-to-member-function which is not | |
274 // overloaded nor a template. In this case the compiler is able to deduce the full function | |
275 // signature directly given the name since there is only one function with that name. | |
276 | |
277 template <typename R, typename C, typename... P> | |
278 static PtmfHelper from(R (C::*p)(NoInfer<P>...)) { BODY; } | |
279 template <typename R, typename C, typename... P> | |
280 static PtmfHelper from(R (C::*p)(NoInfer<P>...) const) { BODY; } | |
281 // Create a PtmfHelper from some poniter-to-member-function which is a template. In this case | |
282 // the function must match exactly the containing type C, return type R, and parameter types P... | |
283 // GetFunctorStartAddress normally specifies exactly the correct C and R, but can only make a | |
284 // guess at P. Luckily, if the function parameters are template parameters then it's not | |
285 // necessary to be precise about P. | |
286 #undef BODY | |
287 | 262 |
288 void* apply(void* obj) { | 263 void* apply(void* obj) { |
289 #if defined(__arm__) || defined(__mips__) || defined(__aarch64__) | 264 #if defined(__arm__) || defined(__mips__) || defined(__aarch64__) |
290 if (adj & 1) { | 265 if (adj & 1) { |
291 ptrdiff_t voff = (ptrdiff_t)ptr; | 266 ptrdiff_t voff = (ptrdiff_t)ptr; |
297 return *(void**)(*(char**)obj + voff); | 272 return *(void**)(*(char**)obj + voff); |
298 } else { | 273 } else { |
299 return ptr; | 274 return ptr; |
300 } | 275 } |
301 } | 276 } |
277 | |
278 #define BODY \ | |
279 PtmfHelper result; \ | |
280 static_assert(sizeof(p) == sizeof(result), "unknown ptmf layout"); \ | |
281 memcpy(&result, &p, sizeof(result)); \ | |
282 return result | |
283 | |
284 #else // __GNUG__ | |
285 | |
286 void* apply(void* obj) { return nullptr; } | |
287 // TODO(port): PTMF instruction address extraction | |
288 | |
289 #define BODY return PtmfHelper{} | |
290 | |
291 #endif // __GNUG__, else | |
292 | |
293 template <typename R, typename C, typename... P, typename F> | |
294 static PtmfHelper from(F p) { BODY; } | |
295 // Create a PtmfHelper from some arbitrary pointer-to-member-function which is not | |
296 // overloaded nor a template. In this case the compiler is able to deduce the full function | |
297 // signature directly given the name since there is only one function with that name. | |
298 | |
299 template <typename R, typename C, typename... P> | |
300 static PtmfHelper from(R (C::*p)(NoInfer<P>...)) { BODY; } | |
301 template <typename R, typename C, typename... P> | |
302 static PtmfHelper from(R (C::*p)(NoInfer<P>...) const) { BODY; } | |
303 // Create a PtmfHelper from some poniter-to-member-function which is a template. In this case | |
304 // the function must match exactly the containing type C, return type R, and parameter types P... | |
305 // GetFunctorStartAddress normally specifies exactly the correct C and R, but can only make a | |
306 // guess at P. Luckily, if the function parameters are template parameters then it's not | |
307 // necessary to be precise about P. | |
308 #undef BODY | |
302 }; | 309 }; |
303 | 310 |
304 template <typename... ParamTypes> | 311 template <typename... ParamTypes> |
305 struct GetFunctorStartAddress { | 312 struct GetFunctorStartAddress { |
306 // Given a functor (any object defining operator()), return the start address of the function, | 313 // Given a functor (any object defining operator()), return the start address of the function, |
854 throwRecoverableException(kj::mv(*exception)); | 861 throwRecoverableException(kj::mv(*exception)); |
855 } | 862 } |
856 return _::returnMaybeVoid(kj::mv(*value)); | 863 return _::returnMaybeVoid(kj::mv(*value)); |
857 } else KJ_IF_MAYBE(exception, result.exception) { | 864 } else KJ_IF_MAYBE(exception, result.exception) { |
858 throwFatalException(kj::mv(*exception)); | 865 throwFatalException(kj::mv(*exception)); |
866 } else { | |
867 // Result contained neither a value nor an exception? | |
868 KJ_UNREACHABLE; | |
869 } | |
870 } | |
871 | |
872 template <> | |
873 inline void Promise<void>::wait(WaitScope& waitScope) { | |
874 // Override <void> case to use throwRecoverableException(). | |
875 | |
876 _::ExceptionOr<_::Void> result; | |
877 | |
878 waitImpl(kj::mv(node), result, waitScope); | |
879 | |
880 if (result.value != nullptr) { | |
881 KJ_IF_MAYBE(exception, result.exception) { | |
882 throwRecoverableException(kj::mv(*exception)); | |
883 } | |
884 } else KJ_IF_MAYBE(exception, result.exception) { | |
885 throwRecoverableException(kj::mv(*exception)); | |
859 } else { | 886 } else { |
860 // Result contained neither a value nor an exception? | 887 // Result contained neither a value nor an exception? |
861 KJ_UNREACHABLE; | 888 KJ_UNREACHABLE; |
862 } | 889 } |
863 } | 890 } |