Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion builtin-functions/kphp-full/_functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -991,9 +991,15 @@ function rpc_tl_query_result ($query_ids ::: array) ::: mixed[][];
function rpc_tl_query_result_synchronously ($query_ids ::: array) ::: mixed[][];
function rpc_tl_pending_queries_count () ::: int;

/** @kphp-tl-class */
/**
* @kphp-required
* @kphp-tl-class
*/
interface RpcFunction {
public function getTLFunctionMagic() : int;
public function getTLFunctionName() : string;
public function typedStore() : @tl\RpcFunctionFetcher;
public function typedFetch() : @tl\RpcFunctionFetcher;
}

/** @kphp-tl-class */
Expand Down
8 changes: 7 additions & 1 deletion builtin-functions/kphp-light/stdlib/rpc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ require_once __DIR__ . '/rpc_fetcher.txt';

// ===== SUPPORTED =====

/** @kphp-tl-class */
/**
* @kphp-required
* @kphp-tl-class
*/
interface RpcFunction {
public function getTLFunctionMagic() : int;
public function getTLFunctionName() : string;
public function typedStore() : @tl\RpcFunctionFetcher;
public function typedFetch() : @tl\RpcFunctionFetcher;
}

/** @kphp-tl-class */
Expand Down
5 changes: 5 additions & 0 deletions compiler/code-gen/files/tl2cpp/tl2cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,12 @@ void write_rpc_server_functions(CodeGenerator &W) {
W << fmt_format("case {:#010x}: ", static_cast<unsigned int>(f->id)) << BEGIN;
W << get_php_runtime_type(f, true) << " request;" << NL
<< "request.alloc();" << NL
<< "auto custom_fetcher = f$VK$TL$RpcFunction$$typedFetch(request);" << NL
<< "if (custom_fetcher.is_null()) " << BEGIN
<< "CurrentRpcServerQuery::get().save(" << cpp_tl_struct_name("f_", f->name) << "::rpc_server_typed_fetch(request.get()));" << NL
<< END << "else" << BEGIN
<< "CurrentRpcServerQuery::get().save(make_tl_func_base_simple_wrapper(std::move(custom_fetcher)));" << NL
<< END << NL
<< "return request;" << NL
<< END << NL;
}
Expand Down
45 changes: 43 additions & 2 deletions runtime-light/stdlib/rpc/rpc-tl-kphp-request.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,40 @@
#include "runtime-light/stdlib/rpc/rpc-tl-query.h"
#include "runtime-light/stdlib/rpc/rpc-tl-request.h"

int64_t f$VK$TL$RpcFunction$$getTLFunctionMagic(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;
class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedStore(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;
class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedFetch(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;

class_instance<C$VK$TL$RpcFunctionReturnResult> f$VK$TL$RpcFunctionFetcher$$typedFetch(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher) noexcept;
void f$VK$TL$RpcFunctionFetcher$$typedStore(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher,
class_instance<C$VK$TL$RpcFunctionReturnResult> const& result) noexcept;

// should be in header, because C$VK$TL$* classes are unknown on runtime compilation
struct tl_func_base_simple_wrapper : public tl_func_base {
explicit tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped)
: wrapped_(std::move(wrapped)) {}

virtual mixed fetch() {
php_critical_error("this function should never be called for typed RPC function.");
return mixed{};
}

virtual class_instance<C$VK$TL$RpcFunctionReturnResult> typed_fetch() {
return f$VK$TL$RpcFunctionFetcher$$typedFetch(wrapped_);
}

virtual void rpc_server_typed_store(const class_instance<C$VK$TL$RpcFunctionReturnResult>& result) {
return f$VK$TL$RpcFunctionFetcher$$typedStore(wrapped_, result);
}

private:
class_instance<C$VK$TL$RpcFunctionFetcher> wrapped_;
};

inline std::unique_ptr<tl_func_base> make_tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped) {
return std::make_unique<tl_func_base_simple_wrapper>(std::move(wrapped));
}

namespace kphp::rpc::rpc_impl {
// use template, because t_ReqResult_ is unknown on runtime compilation
template<template<typename, uint32_t> class t_ReqResult_>
Expand Down Expand Up @@ -47,8 +81,15 @@ class KphpRpcRequest final : public RpcRequest {
auto& cur_query{CurrentTlQuery::get()};
cur_query.set_current_tl_function(tl_function_name());
const vk::final_action finalizer{[&cur_query] noexcept { cur_query.reset(); }};

std::unique_ptr<tl_func_base> stored_fetcher{storing_function.get()->store()};
std::unique_ptr<tl_func_base> stored_fetcher;
auto custom_fetcher = f$VK$TL$RpcFunction$$typedStore(storing_function);
if (custom_fetcher.is_null()) {
stored_fetcher = storing_function.get()->store();
} else {
stored_fetcher = make_tl_func_base_simple_wrapper(std::move(custom_fetcher));
auto magic = f$VK$TL$RpcFunction$$getTLFunctionMagic(storing_function);
CurrentTlQuery::get().set_last_stored_tl_function_magic(magic);
}
CHECK_EXCEPTION(return {});
return make_unique_on_script_memory<KphpRpcRequestResult<t_ReqResult_>>(std::move(stored_fetcher));
}
Expand Down
45 changes: 44 additions & 1 deletion runtime/tl/rpc_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
#include "runtime/tl/rpc_function.h"
#include "runtime/tl/rpc_response.h"
#include "runtime/tl/tl_builtins.h"
#include "runtime/tl/tl_func_base.h"

int64_t f$VK$TL$RpcFunction$$getTLFunctionMagic(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;
class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedStore(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;
class_instance<C$VK$TL$RpcFunctionFetcher> f$VK$TL$RpcFunction$$typedFetch(class_instance<C$VK$TL$RpcFunction> const& arg) noexcept;

class_instance<C$VK$TL$RpcFunctionReturnResult> f$VK$TL$RpcFunctionFetcher$$typedFetch(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher) noexcept;
void f$VK$TL$RpcFunctionFetcher$$typedStore(class_instance<C$VK$TL$RpcFunctionFetcher> const& fetcher,
class_instance<C$VK$TL$RpcFunctionReturnResult> const& result) noexcept;

class RpcRequestResult;

Expand Down Expand Up @@ -79,6 +88,32 @@ class RpcRequestResultUntyped final : public RpcRequestResult {
}
};

// should be in header, because C$VK$TL$* classes are unknown on runtime compilation
struct tl_func_base_simple_wrapper : public tl_func_base {
explicit tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped)
: wrapped_(std::move(wrapped)) {}

virtual mixed fetch() {
php_critical_error("this function should never be called for typed RPC function.");
return mixed{};
}

virtual class_instance<C$VK$TL$RpcFunctionReturnResult> typed_fetch() {
return f$VK$TL$RpcFunctionFetcher$$typedFetch(wrapped_);
}

virtual void rpc_server_typed_store(const class_instance<C$VK$TL$RpcFunctionReturnResult>& result) {
return f$VK$TL$RpcFunctionFetcher$$typedStore(wrapped_, result);
}

private:
class_instance<C$VK$TL$RpcFunctionFetcher> wrapped_;
};

inline std::unique_ptr<tl_func_base> make_tl_func_base_simple_wrapper(class_instance<C$VK$TL$RpcFunctionFetcher>&& wrapped) {
return std::make_unique<tl_func_base_simple_wrapper>(std::move(wrapped));
}

namespace impl_ {
// use template, because t_ReqResult_ is unknown on runtime compilation
template<template<typename, unsigned int> class t_ReqResult_>
Expand Down Expand Up @@ -110,7 +145,15 @@ class KphpRpcRequest final : public RpcRequest {
std::unique_ptr<RpcRequestResult> store_request() const final {
php_assert(CurException.is_null());
CurrentTlQuery::get().set_current_tl_function(tl_function_name());
std::unique_ptr<tl_func_base> stored_fetcher = storing_function_.get()->store();
std::unique_ptr<tl_func_base> stored_fetcher;
auto custom_fetcher = f$VK$TL$RpcFunction$$typedStore(storing_function_);
if (custom_fetcher.is_null()) {
stored_fetcher = storing_function_.get()->store();
} else {
stored_fetcher = std::make_unique<tl_func_base_simple_wrapper>(std::move(custom_fetcher));
auto magic = f$VK$TL$RpcFunction$$getTLFunctionMagic(storing_function_);
CurrentTlQuery::get().set_last_stored_tl_function_magic(magic);
}
CurrentTlQuery::get().reset();
if (!CurException.is_null()) {
CurException = Optional<bool>{};
Expand Down
Loading