Skip to content

Commit 9d3d3cc

Browse files
authored
[k2] add some builtins (#1455)
1 parent 37ccd17 commit 9d3d3cc

11 files changed

Lines changed: 132 additions & 33 deletions

File tree

builtin-functions/kphp-light/stdlib/rpc.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ function rpc_queue_push ($queue_id ::: int, $request_id ::: int) ::: void;
113113

114114
function rpc_queue_empty ($queue_id ::: int) ::: bool;
115115

116+
function rpc_parse ($data) ::: bool;
117+
116118
/** @kphp-extern-func-info interruptible */
117119
function rpc_queue_next ($queue_id ::: int, $timeout ::: float = -1.0) ::: int | false;
118120

@@ -121,9 +123,6 @@ function rpc_queue_next ($queue_id ::: int, $timeout ::: float = -1.0) ::: int |
121123
/** @kphp-extern-func-info interruptible stub generation-required */
122124
function new_rpc_connection ($str ::: string, $port ::: int, $actor_id ::: mixed = 0, $timeout ::: float = 0.3, $connect_timeout ::: float = 0.3, $reconnect_timeout ::: float = 17.0) ::: \RpcConnection; // TODO: make actor_id int
123125

124-
/** @kphp-extern-func-info stub */
125-
function rpc_parse ($data) ::: bool;
126-
127126
/** @kphp-extern-func-info interruptible stub generation-required */
128127
function store_finish() ::: bool;
129128

builtin-functions/kphp-light/stdlib/serialize-functions.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ function msgpack_serialize($v ::: mixed) ::: string | null;
4848

4949
function msgpack_deserialize($v ::: string) ::: mixed;
5050

51+
/** @kphp-extern-func-info can_throw */
52+
function instance_serialize_safe(object $instance) ::: string;
53+
54+
/** @kphp-extern-func-info cpp_template_call can_throw */
55+
function instance_deserialize_safe($serialized ::: string, $to_type ::: string) ::: instance<^2>;
56+
5157
// ===== UNSUPPORTED =====
5258

5359
/** @kphp-extern-func-info can_throw stub generation-required */
5460
function msgpack_serialize_safe($v ::: mixed) ::: string;
5561
/** @kphp-extern-func-info can_throw stub generation-required */
5662
function msgpack_deserialize_safe($v ::: string) ::: mixed;
57-
/** @kphp-extern-func-info can_throw stub */
58-
function instance_serialize_safe(object $instance) ::: string;
59-
/** @kphp-extern-func-info cpp_template_call can_throw stub */
60-
function instance_deserialize_safe($serialized ::: string, $to_type ::: string) ::: instance<^2>;

builtin-functions/kphp-light/stdlib/server-functions.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ function memory_get_usage ($real_usage ::: bool = false) ::: int;
6565

6666
function memory_get_peak_usage ($real_usage ::: bool = false) ::: int;
6767

68+
function setlocale ($category ::: int, $locale ::: string) ::: string | false;
69+
70+
function memory_get_detailed_stats() ::: int[];
71+
6872
// ===== UNSUPPORTED =====
6973

7074
/** @kphp-extern-func-info stub */
@@ -94,8 +98,6 @@ function inet_pton ($address ::: string) ::: string | false;
9498
function memory_get_total_usage() ::: int;
9599
/** @kphp-extern-func-info stub generation-required */
96100
function memory_get_static_usage() ::: int;
97-
/** @kphp-extern-func-info stub generation-required */
98-
function memory_get_detailed_stats() ::: int[];
99101

100102
/** @kphp-extern-func-info stub */
101103
function kphp_extended_instance_cache_metrics_init(callable(string $key):string $normalization_function) ::: void;
@@ -118,9 +120,6 @@ define('LC_NUMERIC', 1);
118120
define('LC_TIME', 2);
119121
define('LC_MESSAGES', 5);
120122

121-
/** @kphp-extern-func-info stub generation-required */
122-
function setlocale ($category ::: int, $locale ::: string) ::: string | false;
123-
124123
function debug_backtrace() ::: string[][];
125124

126125
/** @kphp-extern-func-info stub generation-required */

runtime-light/k2-platform/k2-api.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,18 @@ inline struct tm* localtime_r(const time_t* timer, struct tm* result) noexcept {
300300
return k2_localtime_r(timer, result);
301301
}
302302

303+
inline int32_t uselocale(int32_t category, std::string_view locale) noexcept {
304+
return k2_uselocale(category, locale.data());
305+
}
306+
307+
inline std::optional<std::string_view> current_locale_name(int32_t category) noexcept {
308+
auto* name{k2_current_locale_name(category)};
309+
if (name == nullptr) [[unlikely]] {
310+
return std::nullopt;
311+
}
312+
return std::string_view{name};
313+
}
314+
303315
inline int32_t udp_connect(k2::descriptor* descriptor, const char* host, size_t host_len) noexcept {
304316
return k2_udp_connect(descriptor, host, host_len);
305317
}

runtime-light/stdlib/diagnostics/exception-functions.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
#include <concepts>
88
#include <cstdint>
9+
#include <source_location>
10+
#include <utility>
911

1012
#include "runtime-common/core/runtime-core.h"
1113
#include "runtime-light/stdlib/diagnostics/exception-types.h"
@@ -65,17 +67,22 @@
6567
namespace kphp::exception {
6668

6769
template<std::derived_from<C$Throwable> T>
68-
class_instance<T> make_throwable(const string& file, int64_t line, int64_t code, const string& desc) noexcept {
70+
class_instance<T> make_throwable(string file, int64_t line, int64_t code, string desc) noexcept {
6971
auto instance{make_instance<T>()};
7072

7173
auto* instance_ptr{instance.get()};
72-
instance_ptr->$file = file;
74+
instance_ptr->$file = std::move(file);
7375
instance_ptr->$line = line;
7476
instance_ptr->$code = code;
75-
instance_ptr->$message = desc;
77+
instance_ptr->$message = std::move(desc);
7678
return instance;
7779
}
7880

81+
template<std::derived_from<C$Throwable> T>
82+
class_instance<T> make_throwable(string err_msg, int64_t code = 0, std::source_location loc = std::source_location::current()) noexcept {
83+
return make_throwable<T>(string{loc.file_name()}, loc.line(), code, std::move(err_msg));
84+
}
85+
7986
} // namespace kphp::exception
8087

8188
// ================================================================================================
@@ -87,6 +94,7 @@ T f$_exception_set_location(const T& e, const string& file, int64_t line) noexce
8794
return e;
8895
}
8996

90-
inline Exception f$err(const string& file, int64_t line, const string& code, const string& desc = {}) noexcept {
91-
return kphp::exception::make_throwable<C$Exception>(file, line, 0, (RuntimeContext::get().static_SB.clean() << "ERR_" << code << ": " << desc).str());
97+
inline Exception f$err(string file, int64_t line, const string& code, const string& desc = {}) noexcept {
98+
return kphp::exception::make_throwable<C$Exception>(std::move(file), line, 0,
99+
(RuntimeContext::get().static_SB.clean() << "ERR_" << code << ": " << desc).str());
92100
}

runtime-light/stdlib/memory/memory-usage.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
#pragma once
66

77
#include <cstdint>
8+
#include <utility>
89

910
#include "runtime-common/core/allocator/runtime-allocator.h"
11+
#include "runtime-common/core/runtime-core.h"
1012

1113
inline int64_t f$memory_get_peak_usage(bool real_usage = false) noexcept {
1214
if (real_usage) {
@@ -19,3 +21,16 @@ inline int64_t f$memory_get_peak_usage(bool real_usage = false) noexcept {
1921
inline int64_t f$memory_get_usage([[maybe_unused]] bool real_usage = false) noexcept {
2022
return static_cast<int64_t>(RuntimeAllocator::get().memory_resource.get_memory_stats().memory_used);
2123
}
24+
25+
inline array<int64_t> f$memory_get_detailed_stats() noexcept {
26+
const auto& stats{RuntimeAllocator::get().memory_resource.get_memory_stats()};
27+
return array<int64_t>({std::make_pair(string{"memory_limit"}, static_cast<int64_t>(stats.memory_limit)),
28+
std::make_pair(string{"real_memory_used"}, static_cast<int64_t>(stats.real_memory_used)),
29+
std::make_pair(string{"memory_used"}, static_cast<int64_t>(stats.memory_used)),
30+
std::make_pair(string{"max_real_memory_used"}, static_cast<int64_t>(stats.max_real_memory_used)),
31+
std::make_pair(string{"max_memory_used"}, static_cast<int64_t>(stats.max_memory_used)),
32+
std::make_pair(string{"defragmentation_calls"}, static_cast<int64_t>(stats.defragmentation_calls)),
33+
std::make_pair(string{"huge_memory_pieces"}, static_cast<int64_t>(stats.huge_memory_pieces)),
34+
std::make_pair(string{"small_memory_pieces"}, static_cast<int64_t>(stats.small_memory_pieces)),
35+
std::make_pair(string{"heap_memory_used"}, static_cast<int64_t>(0))});
36+
}

runtime-light/stdlib/rpc/rpc-api.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,33 @@ inline bool f$rpc_clean() noexcept {
170170
return true;
171171
}
172172

173-
template<typename T>
174-
bool f$rpc_parse(T /*unused*/) {
175-
kphp::log::error("call to unsupported function");
173+
inline bool f$rpc_parse(const string& new_rpc_data) noexcept {
174+
if (new_rpc_data.size() % sizeof(int32_t) != 0) {
175+
kphp::log::warning("wrong parameter \"new_rpc_data\" of len {} passed to function rpc_parse", new_rpc_data.size());
176+
return false;
177+
}
178+
179+
const std::span<const std::byte> spn{reinterpret_cast<const std::byte*>(new_rpc_data.c_str()), new_rpc_data.size()};
180+
RpcServerInstanceState::get().tl_storer.store_bytes(spn);
181+
return true;
182+
}
183+
184+
inline bool f$rpc_parse(const mixed& new_rpc_data) noexcept {
185+
if (!new_rpc_data.is_string()) {
186+
kphp::log::warning("parameter 1 of function rpc_parse must be a string, {} is given", new_rpc_data.get_type_c_str());
187+
return false;
188+
}
189+
190+
return f$rpc_parse(new_rpc_data.to_string());
191+
}
192+
193+
inline bool f$rpc_parse(bool new_rpc_data) noexcept {
194+
return f$rpc_parse(mixed{new_rpc_data});
195+
}
196+
197+
inline bool f$rpc_parse(const Optional<string>& new_rpc_data) noexcept {
198+
constexpr auto rpc_parse_lambda{[](const auto& v) noexcept { return f$rpc_parse(v); }};
199+
return call_fun_on_optional_value(rpc_parse_lambda, new_rpc_data);
176200
}
177201

178202
// f$rpc_server_fetch_request() definition is generated into the tl/rpc_server_fetch_request.cpp file.

runtime-light/stdlib/serialization/msgpack-functions.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44

55
#pragma once
66

7+
#include <memory>
8+
#include <utility>
9+
710
#include "runtime-common/core/runtime-core.h"
811
#include "runtime-common/stdlib/msgpack/unpacker.h"
12+
#include "runtime-common/stdlib/serialization/msgpack-functions.h"
13+
#include "runtime-light/stdlib/diagnostics/exception-functions.h"
914
#include "runtime-light/stdlib/diagnostics/logs.h"
1015
#include "runtime-light/stdlib/serialization/serialization-state.h"
1116

@@ -51,11 +56,24 @@ ResultClass f$instance_deserialize(const string& buffer, const string& /*unused*
5156
}
5257

5358
template<class InstanceClass>
54-
string f$instance_serialize_safe(const class_instance<InstanceClass>& /*instance*/) noexcept {
55-
kphp::log::error("call to unsupported function");
59+
string f$instance_serialize_safe(const class_instance<InstanceClass>& instance) noexcept {
60+
string err_msg;
61+
auto result{msgpack_functions_impl_::common_instance_serialize(instance, std::addressof(err_msg))};
62+
if (!err_msg.empty()) {
63+
THROW_EXCEPTION(kphp::exception::make_throwable<C$Exception>(std::move(err_msg)));
64+
return {};
65+
}
66+
kphp::log::assertion(result.has_value());
67+
return result.val();
5668
}
5769

5870
template<class ResultClass>
59-
ResultClass f$instance_deserialize_safe(const string& /*buffer*/, const string& /*unused*/) noexcept {
60-
kphp::log::error("call to unsupported function");
71+
ResultClass f$instance_deserialize_safe(const string& buffer, const string& /*unused*/) noexcept {
72+
string err_msg;
73+
auto res{f$msgpack_deserialize<ResultClass>(buffer, std::addressof(err_msg))};
74+
if (!err_msg.empty()) {
75+
THROW_EXCEPTION(kphp::exception::make_throwable<C$Exception>(std::move(err_msg)));
76+
return {};
77+
}
78+
return res;
6179
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Compiler for PHP (aka KPHP)
2+
// Copyright (c) 2025 LLC «V Kontakte»
3+
// Distributed under the GPL v3 License, see LICENSE.notice.txt
4+
5+
#pragma once
6+
7+
#include <cstdint>
8+
9+
#include "runtime-common/core/runtime-core.h"
10+
#include "runtime-light/k2-platform/k2-api.h"
11+
12+
inline Optional<string> f$setlocale(int64_t category, const string& locale) noexcept {
13+
const int32_t i32category{static_cast<int32_t>(category)};
14+
if (k2::uselocale(i32category, {locale.c_str(), locale.size()}) != k2::errno_ok) {
15+
return false;
16+
}
17+
const auto opt_locale_name{k2::current_locale_name(i32category)};
18+
if (!opt_locale_name.has_value()) [[unlikely]] {
19+
return false;
20+
}
21+
return opt_locale_name->data();
22+
}

runtime/rpc.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void rpc_parse(const int32_t* new_rpc_data, int32_t new_rpc_data_len) {
138138
rpc_data_len = new_rpc_data_len;
139139
}
140140

141-
bool f$rpc_parse(const string& new_rpc_data) {
141+
bool f$rpc_parse(const string& new_rpc_data) noexcept {
142142
if (new_rpc_data.size() % sizeof(int) != 0) {
143143
php_warning("Wrong parameter \"new_rpc_data\" of len %d passed to function rpc_parse", (int)new_rpc_data.size());
144144
last_rpc_error = "Result's length is not divisible by 4";
@@ -157,7 +157,7 @@ bool f$rpc_parse(const string& new_rpc_data) {
157157
return true;
158158
}
159159

160-
bool f$rpc_parse(const mixed& new_rpc_data) {
160+
bool f$rpc_parse(const mixed& new_rpc_data) noexcept {
161161
if (!new_rpc_data.is_string()) {
162162
php_warning("Parameter 1 of function rpc_parse must be a string, %s is given", new_rpc_data.get_type_c_str());
163163
return false;
@@ -166,12 +166,12 @@ bool f$rpc_parse(const mixed& new_rpc_data) {
166166
return f$rpc_parse(new_rpc_data.to_string());
167167
}
168168

169-
bool f$rpc_parse(bool new_rpc_data) {
169+
bool f$rpc_parse(bool new_rpc_data) noexcept {
170170
return f$rpc_parse(mixed{new_rpc_data});
171171
}
172172

173-
bool f$rpc_parse(const Optional<string>& new_rpc_data) {
174-
auto rpc_parse_lambda = [](const auto& v) { return f$rpc_parse(v); };
173+
bool f$rpc_parse(const Optional<string>& new_rpc_data) noexcept {
174+
constexpr auto rpc_parse_lambda = [](const auto& v) noexcept { return f$rpc_parse(v); };
175175
return call_fun_on_optional_value(rpc_parse_lambda, new_rpc_data);
176176
}
177177

0 commit comments

Comments
 (0)