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
5 changes: 2 additions & 3 deletions builtin-functions/kphp-light/stdlib/rpc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ function rpc_queue_push ($queue_id ::: int, $request_id ::: int) ::: void;

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

function rpc_parse ($data) ::: bool;

/** @kphp-extern-func-info interruptible */
function rpc_queue_next ($queue_id ::: int, $timeout ::: float = -1.0) ::: int | false;

Expand All @@ -121,9 +123,6 @@ function rpc_queue_next ($queue_id ::: int, $timeout ::: float = -1.0) ::: int |
/** @kphp-extern-func-info interruptible stub generation-required */
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

/** @kphp-extern-func-info stub */
function rpc_parse ($data) ::: bool;

/** @kphp-extern-func-info interruptible stub generation-required */
function store_finish() ::: bool;

Expand Down
10 changes: 6 additions & 4 deletions builtin-functions/kphp-light/stdlib/serialize-functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ function msgpack_serialize($v ::: mixed) ::: string | null;

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

/** @kphp-extern-func-info can_throw */
function instance_serialize_safe(object $instance) ::: string;

/** @kphp-extern-func-info cpp_template_call can_throw */
function instance_deserialize_safe($serialized ::: string, $to_type ::: string) ::: instance<^2>;

// ===== UNSUPPORTED =====

/** @kphp-extern-func-info can_throw stub generation-required */
function msgpack_serialize_safe($v ::: mixed) ::: string;
/** @kphp-extern-func-info can_throw stub generation-required */
function msgpack_deserialize_safe($v ::: string) ::: mixed;
/** @kphp-extern-func-info can_throw stub */
function instance_serialize_safe(object $instance) ::: string;
/** @kphp-extern-func-info cpp_template_call can_throw stub */
function instance_deserialize_safe($serialized ::: string, $to_type ::: string) ::: instance<^2>;
9 changes: 4 additions & 5 deletions builtin-functions/kphp-light/stdlib/server-functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ function memory_get_usage ($real_usage ::: bool = false) ::: int;

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

function setlocale ($category ::: int, $locale ::: string) ::: string | false;

function memory_get_detailed_stats() ::: int[];

// ===== UNSUPPORTED =====

/** @kphp-extern-func-info stub */
Expand Down Expand Up @@ -94,8 +98,6 @@ function inet_pton ($address ::: string) ::: string | false;
function memory_get_total_usage() ::: int;
/** @kphp-extern-func-info stub generation-required */
function memory_get_static_usage() ::: int;
/** @kphp-extern-func-info stub generation-required */
function memory_get_detailed_stats() ::: int[];

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

/** @kphp-extern-func-info stub generation-required */
function setlocale ($category ::: int, $locale ::: string) ::: string | false;

function debug_backtrace() ::: string[][];

/** @kphp-extern-func-info stub generation-required */
Expand Down
12 changes: 12 additions & 0 deletions runtime-light/k2-platform/k2-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,18 @@ inline struct tm* localtime_r(const time_t* timer, struct tm* result) noexcept {
return k2_localtime_r(timer, result);
}

inline int32_t uselocale(int32_t category, std::string_view locale) noexcept {
return k2_uselocale(category, locale.data());
}

inline std::optional<std::string_view> current_locale_name(int32_t category) noexcept {
auto* name{k2_current_locale_name(category)};
if (name == nullptr) [[unlikely]] {
return std::nullopt;
}
return std::string_view{name};
}

inline int32_t udp_connect(k2::descriptor* descriptor, const char* host, size_t host_len) noexcept {
return k2_udp_connect(descriptor, host, host_len);
}
Expand Down
18 changes: 13 additions & 5 deletions runtime-light/stdlib/diagnostics/exception-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <concepts>
#include <cstdint>
#include <source_location>
#include <utility>

#include "runtime-common/core/runtime-core.h"
#include "runtime-light/stdlib/diagnostics/exception-types.h"
Expand Down Expand Up @@ -65,17 +67,22 @@
namespace kphp::exception {

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

auto* instance_ptr{instance.get()};
instance_ptr->$file = file;
instance_ptr->$file = std::move(file);
instance_ptr->$line = line;
instance_ptr->$code = code;
instance_ptr->$message = desc;
instance_ptr->$message = std::move(desc);
return instance;
}

template<std::derived_from<C$Throwable> T>
class_instance<T> make_throwable(string err_msg, int64_t code = 0, std::source_location loc = std::source_location::current()) noexcept {
return make_throwable<T>(string{loc.file_name()}, loc.line(), code, std::move(err_msg));
}

} // namespace kphp::exception

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

inline Exception f$err(const string& file, int64_t line, const string& code, const string& desc = {}) noexcept {
return kphp::exception::make_throwable<C$Exception>(file, line, 0, (RuntimeContext::get().static_SB.clean() << "ERR_" << code << ": " << desc).str());
inline Exception f$err(string file, int64_t line, const string& code, const string& desc = {}) noexcept {
return kphp::exception::make_throwable<C$Exception>(std::move(file), line, 0,
(RuntimeContext::get().static_SB.clean() << "ERR_" << code << ": " << desc).str());
}
15 changes: 15 additions & 0 deletions runtime-light/stdlib/memory/memory-usage.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#pragma once

#include <cstdint>
#include <utility>

#include "runtime-common/core/allocator/runtime-allocator.h"
#include "runtime-common/core/runtime-core.h"

inline int64_t f$memory_get_peak_usage(bool real_usage = false) noexcept {
if (real_usage) {
Expand All @@ -19,3 +21,16 @@ inline int64_t f$memory_get_peak_usage(bool real_usage = false) noexcept {
inline int64_t f$memory_get_usage([[maybe_unused]] bool real_usage = false) noexcept {
return static_cast<int64_t>(RuntimeAllocator::get().memory_resource.get_memory_stats().memory_used);
}

inline array<int64_t> f$memory_get_detailed_stats() noexcept {
const auto& stats{RuntimeAllocator::get().memory_resource.get_memory_stats()};
return array<int64_t>({std::make_pair(string{"memory_limit"}, static_cast<int64_t>(stats.memory_limit)),
std::make_pair(string{"real_memory_used"}, static_cast<int64_t>(stats.real_memory_used)),
std::make_pair(string{"memory_used"}, static_cast<int64_t>(stats.memory_used)),
std::make_pair(string{"max_real_memory_used"}, static_cast<int64_t>(stats.max_real_memory_used)),
std::make_pair(string{"max_memory_used"}, static_cast<int64_t>(stats.max_memory_used)),
std::make_pair(string{"defragmentation_calls"}, static_cast<int64_t>(stats.defragmentation_calls)),
std::make_pair(string{"huge_memory_pieces"}, static_cast<int64_t>(stats.huge_memory_pieces)),
std::make_pair(string{"small_memory_pieces"}, static_cast<int64_t>(stats.small_memory_pieces)),
std::make_pair(string{"heap_memory_used"}, static_cast<int64_t>(0))});
}
30 changes: 27 additions & 3 deletions runtime-light/stdlib/rpc/rpc-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,33 @@ inline bool f$rpc_clean() noexcept {
return true;
}

template<typename T>
bool f$rpc_parse(T /*unused*/) {
kphp::log::error("call to unsupported function");
inline bool f$rpc_parse(const string& new_rpc_data) noexcept {
if (new_rpc_data.size() % sizeof(int32_t) != 0) {
kphp::log::warning("wrong parameter \"new_rpc_data\" of len {} passed to function rpc_parse", new_rpc_data.size());
return false;
}

const std::span<const std::byte> spn{reinterpret_cast<const std::byte*>(new_rpc_data.c_str()), new_rpc_data.size()};
RpcServerInstanceState::get().tl_storer.store_bytes(spn);
return true;
}

inline bool f$rpc_parse(const mixed& new_rpc_data) noexcept {
if (!new_rpc_data.is_string()) {
kphp::log::warning("parameter 1 of function rpc_parse must be a string, {} is given", new_rpc_data.get_type_c_str());
return false;
}

return f$rpc_parse(new_rpc_data.to_string());
}

inline bool f$rpc_parse(bool new_rpc_data) noexcept {
return f$rpc_parse(mixed{new_rpc_data});
}

inline bool f$rpc_parse(const Optional<string>& new_rpc_data) noexcept {
constexpr auto rpc_parse_lambda{[](const auto& v) noexcept { return f$rpc_parse(v); }};
return call_fun_on_optional_value(rpc_parse_lambda, new_rpc_data);
}

// f$rpc_server_fetch_request() definition is generated into the tl/rpc_server_fetch_request.cpp file.
Expand Down
26 changes: 22 additions & 4 deletions runtime-light/stdlib/serialization/msgpack-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

#pragma once

#include <memory>
#include <utility>

#include "runtime-common/core/runtime-core.h"
#include "runtime-common/stdlib/msgpack/unpacker.h"
#include "runtime-common/stdlib/serialization/msgpack-functions.h"
#include "runtime-light/stdlib/diagnostics/exception-functions.h"
#include "runtime-light/stdlib/diagnostics/logs.h"
#include "runtime-light/stdlib/serialization/serialization-state.h"

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

template<class InstanceClass>
string f$instance_serialize_safe(const class_instance<InstanceClass>& /*instance*/) noexcept {
kphp::log::error("call to unsupported function");
string f$instance_serialize_safe(const class_instance<InstanceClass>& instance) noexcept {
string err_msg;
auto result{msgpack_functions_impl_::common_instance_serialize(instance, std::addressof(err_msg))};
if (!err_msg.empty()) {
THROW_EXCEPTION(kphp::exception::make_throwable<C$Exception>(std::move(err_msg)));
return {};
}
kphp::log::assertion(result.has_value());
return result.val();
}

template<class ResultClass>
ResultClass f$instance_deserialize_safe(const string& /*buffer*/, const string& /*unused*/) noexcept {
kphp::log::error("call to unsupported function");
ResultClass f$instance_deserialize_safe(const string& buffer, const string& /*unused*/) noexcept {
string err_msg;
auto res{f$msgpack_deserialize<ResultClass>(buffer, std::addressof(err_msg))};
if (!err_msg.empty()) {
THROW_EXCEPTION(kphp::exception::make_throwable<C$Exception>(std::move(err_msg)));
return {};
}
return res;
}
22 changes: 22 additions & 0 deletions runtime-light/stdlib/string/string-functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Compiler for PHP (aka KPHP)
// Copyright (c) 2025 LLC «V Kontakte»
// Distributed under the GPL v3 License, see LICENSE.notice.txt

#pragma once

#include <cstdint>

#include "runtime-common/core/runtime-core.h"
#include "runtime-light/k2-platform/k2-api.h"

inline Optional<string> f$setlocale(int64_t category, const string& locale) noexcept {
const int32_t i32category{static_cast<int32_t>(category)};
if (k2::uselocale(i32category, {locale.c_str(), locale.size()}) != k2::errno_ok) {
return false;
}
const auto opt_locale_name{k2::current_locale_name(i32category)};
if (!opt_locale_name.has_value()) [[unlikely]] {
return false;
}
return opt_locale_name->data();
}
10 changes: 5 additions & 5 deletions runtime/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void rpc_parse(const int32_t* new_rpc_data, int32_t new_rpc_data_len) {
rpc_data_len = new_rpc_data_len;
}

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

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

bool f$rpc_parse(bool new_rpc_data) {
bool f$rpc_parse(bool new_rpc_data) noexcept {
return f$rpc_parse(mixed{new_rpc_data});
}

bool f$rpc_parse(const Optional<string>& new_rpc_data) {
auto rpc_parse_lambda = [](const auto& v) { return f$rpc_parse(v); };
bool f$rpc_parse(const Optional<string>& new_rpc_data) noexcept {
constexpr auto rpc_parse_lambda = [](const auto& v) noexcept { return f$rpc_parse(v); };
return call_fun_on_optional_value(rpc_parse_lambda, new_rpc_data);
}

Expand Down
8 changes: 4 additions & 4 deletions runtime/rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ void last_rpc_error_reset();

void rpc_parse(const int32_t* new_rpc_data, int32_t new_rpc_data_len);

bool f$rpc_parse(const string& new_rpc_data);
bool f$rpc_parse(const string& new_rpc_data) noexcept;

bool f$rpc_parse(const mixed& new_rpc_data);
bool f$rpc_parse(const mixed& new_rpc_data) noexcept;

bool f$rpc_parse(bool new_rpc_data);
bool f$rpc_parse(bool new_rpc_data) noexcept;

bool f$rpc_parse(const Optional<string>& new_rpc_data);
bool f$rpc_parse(const Optional<string>& new_rpc_data) noexcept;

int32_t rpc_get_pos();

Expand Down
Loading