comparison osx/include/kj/async-inl.h @ 62:0994c39f1e94

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 3ab5a40c4e3b
children
comparison
equal deleted inserted replaced
61:d101c4099725 62:0994c39f1e94
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 }