|
9 | 9 | #include "runtime/tl/rpc_function.h" |
10 | 10 | #include "runtime/tl/rpc_response.h" |
11 | 11 | #include "runtime/tl/tl_builtins.h" |
| 12 | +#include "runtime/tl/tl_func_base.h" |
| 13 | + |
| 14 | +int64_t f$VK$TL$RpcFunction$$getTLFunctionMagic(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept; |
| 15 | +class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedStore(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept; |
| 16 | +class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedFetch(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept; |
| 17 | + |
| 18 | +class_instance<C$VK$TL$RpcFunctionReturnResult> f$VK$TL$RpcFunctionFetcher$$typedFetch(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher) noexcept; |
| 19 | +void f$VK$TL$RpcFunctionFetcher$$typedStore(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher, |
| 20 | + class_instance<C$VK$TL$RpcFunctionReturnResult> const& result) noexcept; |
12 | 21 |
|
13 | 22 | class RpcRequestResult; |
14 | 23 |
|
@@ -79,6 +88,32 @@ class RpcRequestResultUntyped final : public RpcRequestResult { |
79 | 88 | } |
80 | 89 | }; |
81 | 90 |
|
| 91 | +// should be in header, because C$VK$TL$* classes are unknown on runtime compilation |
| 92 | +struct tl_func_base_simple_wrapper : public tl_func_base { |
| 93 | + explicit tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped) |
| 94 | + : wrapped_(std::move(wrapped)) {} |
| 95 | + |
| 96 | + virtual mixed fetch() { |
| 97 | + php_critical_error("this function should never be called for typed RPC function."); |
| 98 | + return mixed{}; |
| 99 | + } |
| 100 | + |
| 101 | + virtual class_instance<C$VK$TL$RpcFunctionReturnResult> typed_fetch() { |
| 102 | + return f$VK$TL$RpcFunctionFetcher$$typedFetch(wrapped_); |
| 103 | + } |
| 104 | + |
| 105 | + virtual void rpc_server_typed_store(const class_instance<C$VK$TL$RpcFunctionReturnResult>& result) { |
| 106 | + return f$VK$TL$RpcFunctionFetcher$$typedStore(wrapped_, result); |
| 107 | + } |
| 108 | + |
| 109 | +private: |
| 110 | + class_instance<C$VK$TL$RpcFunctionFetcher> wrapped_; |
| 111 | +}; |
| 112 | + |
| 113 | +inline std::unique_ptr<tl_func_base> make_tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped) { |
| 114 | + return std::make_unique<tl_func_base_simple_wrapper>(std::move(wrapped)); |
| 115 | +} |
| 116 | + |
82 | 117 | namespace impl_ { |
83 | 118 | // use template, because t_ReqResult_ is unknown on runtime compilation |
84 | 119 | template<template<typename, unsigned int> class t_ReqResult_> |
@@ -110,7 +145,15 @@ class KphpRpcRequest final : public RpcRequest { |
110 | 145 | std::unique_ptr<RpcRequestResult> store_request() const final { |
111 | 146 | php_assert(CurException.is_null()); |
112 | 147 | CurrentTlQuery::get().set_current_tl_function(tl_function_name()); |
113 | | - std::unique_ptr<tl_func_base> stored_fetcher = storing_function_.get()->store(); |
| 148 | + std::unique_ptr<tl_func_base> stored_fetcher; |
| 149 | + auto custom_fetcher = f$VK$TL$RpcFunction$$typedStore(storing_function_); |
| 150 | + if (custom_fetcher.is_null()) { |
| 151 | + stored_fetcher = storing_function_.get()->store(); |
| 152 | + } else { |
| 153 | + stored_fetcher = std::make_unique<tl_func_base_simple_wrapper>(std::move(custom_fetcher)); |
| 154 | + auto magic = f$VK$TL$RpcFunction$$getTLFunctionMagic(storing_function_); |
| 155 | + CurrentTlQuery::get().set_last_stored_tl_function_magic(magic); |
| 156 | + } |
114 | 157 | CurrentTlQuery::get().reset(); |
115 | 158 | if (!CurException.is_null()) { |
116 | 159 | CurException = Optional<bool>{}; |
|
0 commit comments