| 53 | }; |
| 54 | |
| 55 | struct FuncRuntime |
| 56 | { |
| 57 | // Pull the address of the function to call from the |
| 58 | // Duktape function object at run time. |
| 59 | static duk_ret_t call_native_function(duk_context* ctx) |
| 60 | { |
| 61 | duk_push_current_function(ctx); |
| 62 | duk_get_prop_string(ctx, -1, "\xFF" "func_ptr"); |
| 63 | void* fp_void = duk_require_pointer(ctx, -1); |
| 64 | if (fp_void == NULL) { |
| 65 | duk_error(ctx, DUK_RET_TYPE_ERROR, "what even"); |
| 66 | return DUK_RET_TYPE_ERROR; |
| 67 | } |
| 68 | |
| 69 | duk_pop_2(ctx); |
| 70 | |
| 71 | static_assert(sizeof(RetType(*)(Ts...)) == sizeof(void*), "Function pointer and data pointer are different sizes"); |
| 72 | RetType(*funcToCall)(Ts...) = reinterpret_cast<RetType(*)(Ts...)>(fp_void); |
| 73 | |
| 74 | actually_call(ctx, funcToCall, dukglue::detail::get_stack_values<Ts...>(ctx)); |
| 75 | return std::is_void<RetType>::value ? 0 : 1; |
| 76 | } |
| 77 | |
| 78 | // this mess is to support functions with void return values |
| 79 | template<typename Dummy = RetType, typename... BakedTs> |
| 80 | static typename std::enable_if<!std::is_void<Dummy>::value>::type actually_call(duk_context* ctx, RetType(*funcToCall)(Ts...), const std::tuple<BakedTs...>& args) |
| 81 | { |
| 82 | // ArgStorage has some static_asserts in it that validate value types, |
| 83 | // so we typedef it to force ArgStorage<RetType> to compile and run the asserts |
| 84 | typedef typename dukglue::types::ArgStorage<RetType>::type ValidateReturnType; |
| 85 | |
| 86 | RetType return_val = dukglue::detail::apply_fp(funcToCall, args); |
| 87 | |
| 88 | using namespace dukglue::types; |
| 89 | DukType<typename Bare<RetType>::type>::template push<RetType>(ctx, std::move(return_val)); |
| 90 | } |
| 91 | |
| 92 | template<typename Dummy = RetType, typename... BakedTs> |
| 93 | static typename std::enable_if<std::is_void<Dummy>::value>::type actually_call(duk_context* ctx, RetType(*funcToCall)(Ts...), const std::tuple<BakedTs...>& args) |
| 94 | { |
| 95 | dukglue::detail::apply_fp(funcToCall, args); |
| 96 | } |
| 97 | }; |
| 98 | }; |
| 99 | } |
| 100 | } |
nothing calls this directly
no outgoing calls
no test coverage detected