Skip to content

Commit fc92607

Browse files
committed
vkext custom TL parsing by PHP code
1 parent e847fe3 commit fc92607

11 files changed

Lines changed: 295 additions & 26 deletions

File tree

common/tl-files/common.tl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,5 @@ right {X:Type} {Y:Type} value:Y = Either X Y;
114114
@any engine.pid = net.Pid;
115115
@any engine.version = String;
116116

117+
117118
@kphp kphp.pingRpcCluster#a677ee41 id:int = Int;

compiler/code-gen/files/tl2cpp/tl2cpp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,12 @@ void write_rpc_server_functions(CodeGenerator &W) {
9696
W << fmt_format("case {:#010x}: ", static_cast<unsigned int>(f->id)) << BEGIN;
9797
W << get_php_runtime_type(f, true) << " request;" << NL
9898
<< "request.alloc();" << NL
99+
<< "auto custom_fetcher = f$VK$TL$RpcFunction$$typedFetch(request);" << NL
100+
<< "if (custom_fetcher.is_null()) " << BEGIN
99101
<< "CurrentRpcServerQuery::get().save(" << cpp_tl_struct_name("f_", f->name) << "::rpc_server_typed_fetch(request.get()));" << NL
102+
<< END << "else" << BEGIN
103+
<< "CurrentRpcServerQuery::get().save(make_tl_func_base_simple_wrapper(std::move(custom_fetcher)));" << NL
104+
<< END << NL
100105
<< "return request;" << NL
101106
<< END << NL;
102107
}

runtime-light/stdlib/rpc/rpc-tl-kphp-request.h

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,40 @@
1515
#include "runtime-light/stdlib/rpc/rpc-tl-query.h"
1616
#include "runtime-light/stdlib/rpc/rpc-tl-request.h"
1717

18+
int64_t f$VK$TL$RpcFunction$$getTLFunctionMagic(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;
19+
class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedStore(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;
20+
class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedFetch(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;
21+
22+
class_instance<C$VK$TL$RpcFunctionReturnResult> f$VK$TL$RpcFunctionFetcher$$typedFetch(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher) noexcept;
23+
void f$VK$TL$RpcFunctionFetcher$$typedStore(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher,
24+
class_instance<C$VK$TL$RpcFunctionReturnResult> const& result) noexcept;
25+
26+
// should be in header, because C$VK$TL$* classes are unknown on runtime compilation
27+
struct tl_func_base_simple_wrapper : public tl_func_base {
28+
explicit tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped)
29+
: wrapped_(std::move(wrapped)) {}
30+
31+
virtual mixed fetch() {
32+
php_critical_error("this function should never be called for typed RPC function.");
33+
return mixed{};
34+
}
35+
36+
virtual class_instance<C$VK$TL$RpcFunctionReturnResult> typed_fetch() {
37+
return f$VK$TL$RpcFunctionFetcher$$typedFetch(wrapped_);
38+
}
39+
40+
virtual void rpc_server_typed_store(const class_instance<C$VK$TL$RpcFunctionReturnResult>& result) {
41+
return f$VK$TL$RpcFunctionFetcher$$typedStore(wrapped_, result);
42+
}
43+
44+
private:
45+
class_instance<C$VK$TL$RpcFunctionFetcher> wrapped_;
46+
};
47+
48+
inline std::unique_ptr<tl_func_base> make_tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped) {
49+
return std::make_unique<tl_func_base_simple_wrapper>(std::move(wrapped));
50+
}
51+
1852
namespace kphp::rpc::rpc_impl {
1953
// use template, because t_ReqResult_ is unknown on runtime compilation
2054
template<template<typename, uint32_t> class t_ReqResult_>
@@ -47,8 +81,15 @@ class KphpRpcRequest final : public RpcRequest {
4781
auto& cur_query{CurrentTlQuery::get()};
4882
cur_query.set_current_tl_function(tl_function_name());
4983
const vk::final_action finalizer{[&cur_query] noexcept { cur_query.reset(); }};
50-
51-
std::unique_ptr<tl_func_base> stored_fetcher{storing_function.get()->store()};
84+
std::unique_ptr<tl_func_base> stored_fetcher;
85+
auto custom_fetcher = f$VK$TL$RpcFunction$$typedStore(storing_function);
86+
if (custom_fetcher.is_null()) {
87+
stored_fetcher = storing_function.get()->store();
88+
} else {
89+
stored_fetcher = make_tl_func_base_simple_wrapper(std::move(custom_fetcher));
90+
auto magic = f$VK$TL$RpcFunction$$getTLFunctionMagic(storing_function);
91+
CurrentTlQuery::get().set_last_stored_tl_function_magic(magic);
92+
}
5293
CHECK_EXCEPTION(return {});
5394
return make_unique_on_script_memory<KphpRpcRequestResult<t_ReqResult_>>(std::move(stored_fetcher));
5495
}

runtime/tl/rpc_request.h

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
#include "runtime/tl/rpc_function.h"
1010
#include "runtime/tl/rpc_response.h"
1111
#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;
1221

1322
class RpcRequestResult;
1423

@@ -79,6 +88,32 @@ class RpcRequestResultUntyped final : public RpcRequestResult {
7988
}
8089
};
8190

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+
82117
namespace impl_ {
83118
// use template, because t_ReqResult_ is unknown on runtime compilation
84119
template<template<typename, unsigned int> class t_ReqResult_>
@@ -110,7 +145,15 @@ class KphpRpcRequest final : public RpcRequest {
110145
std::unique_ptr<RpcRequestResult> store_request() const final {
111146
php_assert(CurException.is_null());
112147
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+
}
114157
CurrentTlQuery::get().reset();
115158
if (!CurException.is_null()) {
116159
CurException = Optional<bool>{};

vkext/vk_zend.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,24 @@ static zend_always_inline void vk_zend_update_public_property_long(zval *object,
226226
#endif
227227
}
228228

229+
static zend_always_inline void vk_zend_call_known_instance_method(zval *object,
230+
const char * name, size_t name_len, zval *retval_ptr,
231+
uint32_t param_count, zval *params) {
232+
zend_object* zobj = Z_OBJ_P(object);
233+
zend_string* method_name = zend_string_init(name, name_len, 0);
234+
zend_function* fun = Z_OBJ_HANDLER_P(object, get_method)(&zobj, method_name, 0);
235+
zend_string_release(method_name);
236+
if (!fun) {
237+
return; // retval stays UNDEF
238+
}
239+
#if PHP_MAJOR_VERSION >= 8
240+
zend_call_known_instance_method(fun, zobj, retval_ptr, param_count, params);
241+
#else
242+
// TODO - this branch is not tested yet
243+
zend_call_known_instance_method(fun, object, retval_ptr, param_count, params);
244+
#endif
245+
}
246+
229247
#define ZAPI_TO_PP(az) (&(az))
230248
#define ZP_TO_API_P(az) (az)
231249
#define SMART_STRDATA(ss) ((ss).s)

vkext/vkext-rpc-req-error.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ void tl::RpcReqError::tl_fetch() {
5959
}
6060

6161
void RpcError::try_fetch() {
62-
int op = tl_parse_int();
62+
int op = tl_lookup_int();
6363
if (op == TL_REQ_RESULT_HEADER) {
64+
(void)tl_parse_int(); // skip op
6465
flags = tl_parse_int();
6566
header.emplace().tl_fetch(flags);
66-
op = tl_parse_int();
67+
op = tl_lookup_int();
6768
}
6869
if (op == TL_RPC_REQ_ERROR) {
70+
(void)tl_parse_int(); // skip op
6971
error.emplace().tl_fetch();
7072
}
7173
}

0 commit comments

Comments
 (0)