diff --git a/builtin-functions/kphp-light/functions.txt b/builtin-functions/kphp-light/functions.txt index 1a0d360a82..e06ff06ba3 100644 --- a/builtin-functions/kphp-light/functions.txt +++ b/builtin-functions/kphp-light/functions.txt @@ -11,6 +11,9 @@ define('PHP_INT_MIN', -9223372036854775808); define('PHP_INT_SIZE', 8); define('PHP_EOL', "\n"); +if (0) { + define('PHP_SAPI', php_sapi_name());//"Defined in source code" +} /** @var mixed $_SERVER */ global $_SERVER; @@ -36,10 +39,16 @@ function intval ($v ::: mixed) ::: int; function floatval ($v ::: mixed) ::: float; function strval ($v ::: mixed) ::: string; -/** @kphp-extern-func-info interruptible */ +/** + * @kphp-no-return + * @kphp-extern-func-info interruptible + */ function exit($code = 0) ::: void; -/** @kphp-extern-func-info interruptible */ +/** + * @kphp-no-return + * @kphp-extern-func-info interruptible + */ function die($code = 0) ::: void; function ob_clean() ::: void; diff --git a/builtin-functions/kphp-light/unsupported-functions.txt b/builtin-functions/kphp-light/unsupported-functions.txt index bc71685454..3328705451 100644 --- a/builtin-functions/kphp-light/unsupported-functions.txt +++ b/builtin-functions/kphp-light/unsupported-functions.txt @@ -12,11 +12,13 @@ require_once __DIR__ . '/unsupported/kphp-toggles.txt'; require_once __DIR__ . '/unsupported/kphp-tracing.txt'; require_once __DIR__ . '/unsupported/kphp_internal.txt'; require_once __DIR__ . '/unsupported/math.txt'; +require_once __DIR__ . '/unsupported/memcache.txt'; require_once __DIR__ . '/unsupported/misc.txt'; require_once __DIR__ . '/unsupported/regex.txt'; require_once __DIR__ . '/unsupported/rpc.txt'; require_once __DIR__ . '/unsupported/serialize.txt'; require_once __DIR__ . '/unsupported/server.txt'; +require_once __DIR__ . '/unsupported/spl.txt'; require_once __DIR__ . '/unsupported/string.txt'; require_once __DIR__ . '/unsupported/time.txt'; require_once __DIR__ . '/unsupported/uberh3.txt'; diff --git a/builtin-functions/kphp-light/unsupported/crypto.txt b/builtin-functions/kphp-light/unsupported/crypto.txt index 6c8c0becc1..bc495881e8 100644 --- a/builtin-functions/kphp-light/unsupported/crypto.txt +++ b/builtin-functions/kphp-light/unsupported/crypto.txt @@ -26,6 +26,16 @@ define('OPENSSL_RAW_DATA', 1); define('OPENSSL_ZERO_PADDING', 2); define('OPENSSL_DONT_ZERO_PAD_KEY', 4); +define('PKCS7_TEXT', 0x1); +define('PKCS7_NOCERTS', 0x2); +define('PKCS7_NOSIGS', 0x4); +define('PKCS7_NOCHAIN', 0x8); +define('PKCS7_NOINTERN', 0x10); +define('PKCS7_NOVERIFY', 0x20); +define('PKCS7_BINARY', 0x80); +define('PKCS7_DETACHED', 0x40); +define('PKCS7_NOATTR', 0x100); + /** @kphp-extern-func-info generate-stub */ function openssl_public_encrypt ($data ::: string, &$result ::: mixed, $key ::: string) ::: bool; /** @kphp-extern-func-info generate-stub */ diff --git a/builtin-functions/kphp-light/unsupported/file.txt b/builtin-functions/kphp-light/unsupported/file.txt index 4d7db32feb..fc5017da9d 100644 --- a/builtin-functions/kphp-light/unsupported/file.txt +++ b/builtin-functions/kphp-light/unsupported/file.txt @@ -45,7 +45,7 @@ function unlink ($name ::: string) ::: bool; /** @kphp-extern-func-info generate-stub */ -function fgetcsv ($stream, $length = 0, $delimiter = ",", $enclosure = "\"", $escape = "\\") ::: mixed[] | false; +function fgetcsv ($stream ::: mixed, $length ::: int = 0, $delimiter ::: string = ",", $enclosure ::: string = "\"", $escape ::: string = "\\") ::: mixed[] | false; define('STDIN', 'php://stdin'); define('STDOUT', 'php://stdout'); @@ -59,29 +59,35 @@ define('SEEK_CUR', 2); /** @kphp-extern-func-info generate-stub */ function fopen ($filename ::: string, $mode ::: string) ::: mixed; /** @kphp-extern-func-info generate-stub */ -function fwrite ($stream, $text ::: string) ::: int | false; +function fwrite ($stream ::: mixed, $text ::: string) ::: int | false; /** @kphp-extern-func-info generate-stub */ -function fseek ($stream, $offset ::: int, $whence ::: int = SEEK_SET) ::: int; +function fseek ($stream ::: mixed, $offset ::: int, $whence ::: int = SEEK_SET) ::: int; /** @kphp-extern-func-info generate-stub */ -function rewind ($stream) ::: bool; +function rewind ($stream ::: mixed) ::: bool; /** @kphp-extern-func-info generate-stub */ -function ftell ($stream) ::: int | false; +function ftell ($stream ::: mixed) ::: int | false; /** @kphp-extern-func-info generate-stub */ -function fread ($stream, $length ::: int) ::: string | false; +function fread ($stream ::: mixed, $length ::: int) ::: string | false; /** @kphp-extern-func-info generate-stub */ -function fgetc ($stream) ::: string | false; +function fgetc ($stream ::: mixed) ::: string | false; /** @kphp-extern-func-info generate-stub */ -function fpassthru ($stream) ::: int | false; +function fpassthru ($stream ::: mixed) ::: int | false; /** @kphp-extern-func-info generate-stub */ -function fgets ($stream, $length ::: int = -1) ::: string | false; +function fgets ($stream ::: mixed, $length ::: int = -1) ::: string | false; /** @kphp-extern-func-info generate-stub */ -function fflush ($stream) ::: bool; +function fflush ($stream ::: mixed) ::: bool; /** @kphp-extern-func-info generate-stub */ -function feof ($stream) ::: bool; +function feof ($stream ::: mixed) ::: bool; /** @kphp-extern-func-info generate-stub */ -function fclose ($stream) ::: bool; +function fclose ($stream ::: mixed) ::: bool; +define('STREAM_CLIENT_CONNECT', 1); +define('DEFAULT_SOCKET_TIMEOUT', 60); +/** @kphp-extern-func-info generate-stub */ +function stream_context_create ($options ::: mixed = array()) ::: mixed; + +function stream_socket_client ($url ::: string, &$error_number ::: mixed = TODO, &$error_description ::: mixed = TODO, $timeout ::: float = DEFAULT_SOCKET_TIMEOUT, $flags ::: int = STREAM_CLIENT_CONNECT, $context ::: mixed = null) ::: mixed; function fprintf ($stream, $format ::: string, ...$args) ::: int; function fputcsv ($stream, $fields ::: array, $delimiter = ",", $enclosure = "\"", $escape = "\\") ::: int | false; diff --git a/builtin-functions/kphp-light/unsupported/fork.txt b/builtin-functions/kphp-light/unsupported/fork.txt index 5b2c576b4a..71edd7bd79 100644 --- a/builtin-functions/kphp-light/unsupported/fork.txt +++ b/builtin-functions/kphp-light/unsupported/fork.txt @@ -6,11 +6,11 @@ function wait_concurrently ($id ::: future) ::: bool; /** @kphp-extern-func-info can_throw generate-stub cpp_template_call */ function wait_multi (future[] $resumables) ::: (^1[*][*] | null)[]; -/** @kphp-extern-func-info generate-stub */ + function wait_queue_create (array< future | false > $request_ids = []) ::: future_queue<^1[*][*]>; -/** @kphp-extern-func-info generate-stub */ + function wait_queue_push (future_queue &$queue_id, future | false $request_ids) ::: void; -/** @kphp-extern-func-info generate-stub */ + function wait_queue_empty (future_queue $queue_id) ::: bool; -/** @kphp-extern-func-info generate-stub */ + function wait_queue_next (future_queue $queue_id, $timeout ::: float = -1.0) ::: future<^1[*]> | false; diff --git a/builtin-functions/kphp-light/unsupported/hash.txt b/builtin-functions/kphp-light/unsupported/hash.txt index 26ec14bebf..0e67b84a1d 100644 --- a/builtin-functions/kphp-light/unsupported/hash.txt +++ b/builtin-functions/kphp-light/unsupported/hash.txt @@ -30,10 +30,32 @@ function md5_file ($s ::: string, $raw_output ::: bool = false) ::: string | fal function sha1 ($s ::: string, $raw_output ::: bool = false) ::: string; +define('ZLIB_ENCODING_RAW', -0x0f); +define('ZLIB_ENCODING_DEFLATE', 0x0f); +define('ZLIB_ENCODING_GZIP', 0x1f); + +define('ZLIB_NO_FLUSH', 0); +define('ZLIB_PARTIAL_FLUSH', 1); define('ZLIB_SYNC_FLUSH', 2); +define('ZLIB_FULL_FLUSH', 3); +define('ZLIB_FINISH', 4); +define('ZLIB_BLOCK', 5); +define('ZLIB_TREES', 6); + +define('ZLIB_FILTERED', 1); +define('ZLIB_HUFFMAN_ONLY', 2); +define('ZLIB_RLE', 3); +define('ZLIB_FIXED', 4); +define('ZLIB_DEFAULT_STRATEGY', 0); + +/** @kphp-generate-stub-class */ +final class DeflateContext { + private function __construct() ::: DeflateContext; +} +// todo: deflate_init php signature has type array instead mixed /** @kphp-extern-func-info generate-stub */ -function deflate_init(int $encoding, array $options = []) ::: ?DeflateContext; +function deflate_init(int $encoding, mixed $options = []) ::: ?DeflateContext; /** @kphp-extern-func-info generate-stub */ function deflate_add(DeflateContext $context, string $data, int $flush_mode = ZLIB_SYNC_FLUSH) ::: string | false; /** @kphp-extern-func-info generate-stub */ diff --git a/builtin-functions/kphp-light/unsupported/kphp_internal.txt b/builtin-functions/kphp-light/unsupported/kphp_internal.txt index ab53b80817..7700a372d3 100644 --- a/builtin-functions/kphp-light/unsupported/kphp_internal.txt +++ b/builtin-functions/kphp-light/unsupported/kphp_internal.txt @@ -4,6 +4,29 @@ function _exception_set_location($e, string $filename, int $line): ^1; +// microtime(false) specialization +/** @kphp-extern-func-info generate-stub */ +function _microtime_string(): string; +// microtime(true) specialization +/** @kphp-extern-func-info generate-stub */ +function _microtime_float(): float; + +// hrtime(true) specialization +/** @kphp-extern-func-info generate-stub */ +function _hrtime_int(): int; +// hrtime(false) specialization +/** @kphp-extern-func-info generate-stub */ +function _hrtime_array(): int[]; + +// `new $c(...)` => `_by_name_construct($c, ...)` +function _by_name_construct(string $class_name, ...$args) ::: instance<^1>; +// `$c::method()` => `_by_name_call_method($c, 'method')` +function _by_name_call_method(string $class_name, string $method_name, ...$args); +// `$c::CONST` => `_by_name_get_const($c, 'CONST')` +function _by_name_get_const(string $class_name, string $constant); +// `$c::$field` => `_by_name_get_field($c, 'field')` +function _by_name_get_field(string $class_name, string $field); + /** * @kphp-extern-func-info generate-stub diff --git a/builtin-functions/kphp-light/unsupported/memcache.txt b/builtin-functions/kphp-light/unsupported/memcache.txt new file mode 100644 index 0000000000..40140ffe17 --- /dev/null +++ b/builtin-functions/kphp-light/unsupported/memcache.txt @@ -0,0 +1,46 @@ +is_output_mode_k2()) { + // The current version of runtime-light does not support visitors + return; + } if (!klass->is_serializable) { return; } diff --git a/compiler/code-gen/files/function-header.cpp b/compiler/code-gen/files/function-header.cpp index 8a17edc921..f75890d0e4 100644 --- a/compiler/code-gen/files/function-header.cpp +++ b/compiler/code-gen/files/function-header.cpp @@ -37,9 +37,6 @@ void FunctionH::compile(CodeGenerator &W) const { W << "inline "; } W << FunctionDeclaration(function, true); - if (function->is_no_return) { - W << " __attribute__((noreturn))"; - } if (function->is_flatten) { W << " __attribute__((flatten))"; } diff --git a/compiler/code-gen/files/function-source.cpp b/compiler/code-gen/files/function-source.cpp index a5afbcd157..d464e457fc 100644 --- a/compiler/code-gen/files/function-source.cpp +++ b/compiler/code-gen/files/function-source.cpp @@ -41,6 +41,9 @@ void FunctionCpp::compile(CodeGenerator &W) const { W << includes; W << OpenNamespace(); + if (function->is_no_return) { + W << "[[noreturn]] "; + } declare_const_vars(function, W); W << UnlockComments(); diff --git a/compiler/code-gen/vertex-compiler.cpp b/compiler/code-gen/vertex-compiler.cpp index 16b2210ae7..2a2b56c60a 100644 --- a/compiler/code-gen/vertex-compiler.cpp +++ b/compiler/code-gen/vertex-compiler.cpp @@ -291,6 +291,10 @@ void compile_noerr(VertexAdaptor root, CodeGenerator &W) { } void compile_throw(VertexAdaptor root, CodeGenerator &W) { + if (G->is_output_mode_k2()) { + // The current version of runtime-light does not support exception throw + return; + } W << BEGIN << "THROW_EXCEPTION " << MacroBegin{} << root->exception() << MacroEnd{} << ";" << NL << ThrowAction() << ";" << NL << @@ -298,6 +302,10 @@ void compile_throw(VertexAdaptor root, CodeGenerator &W) { } void compile_try(VertexAdaptor root, CodeGenerator &W) { + if (G->is_output_mode_k2()) { + // The current version of runtime-light does not support try blocks + return; + } auto move_exception = [&](ClassPtr caught_class, VertexAdaptor dst) { if (caught_class->name == "Throwable") { W << dst << " = std::move(CurException);" << NL; diff --git a/compiler/pipes/parse-and-apply-phpdoc.cpp b/compiler/pipes/parse-and-apply-phpdoc.cpp index 559bda7096..aa2dc9cc4c 100644 --- a/compiler/pipes/parse-and-apply-phpdoc.cpp +++ b/compiler/pipes/parse-and-apply-phpdoc.cpp @@ -266,7 +266,8 @@ class ParseAndApplyPhpDocForFunction { } case PhpDocType::kphp_extern_func_info: { - kphp_error(f_->is_extern(), "@kphp-extern-func-info used for regular function"); + // This is temporary solution for generate-stub + bool doc_is_generated_stub = false; std::istringstream is(tag.value_as_string()); std::string token; while (is >> token) { @@ -285,10 +286,12 @@ class ParseAndApplyPhpDocForFunction { f_->is_interruptible = true; } else if (token == "generate-stub") { f_->need_generated_stub = true; + doc_is_generated_stub = true; } else { kphp_error(0, fmt_format("Unknown @kphp-extern-func-info {}", token)); } } + kphp_error(f_->is_extern() || (f_->is_constructor() && doc_is_generated_stub), "@kphp-extern-func-info used for regular function"); break; } diff --git a/runtime/null_coalesce.h b/runtime-core/core-types/definition/null_coalesce.h similarity index 100% rename from runtime/null_coalesce.h rename to runtime-core/core-types/definition/null_coalesce.h diff --git a/runtime-light/component/component.h b/runtime-light/component/component.h index 27cfb1cff3..83c88b3f30 100644 --- a/runtime-light/component/component.h +++ b/runtime-light/component/component.h @@ -16,12 +16,14 @@ #include "runtime-light/coroutine/task.h" #include "runtime-light/header.h" #include "runtime-light/scheduler/scheduler.h" +#include "runtime-light/stdlib/curl/curl-context.h" +#include "runtime-light/stdlib/file/file-stream-context.h" #include "runtime-light/stdlib/fork/fork-context.h" #include "runtime-light/stdlib/job-worker/job-worker-context.h" #include "runtime-light/stdlib/output/output-buffer.h" -#include "runtime-light/stdlib/regex/regex-functions.h" -#include "runtime-light/stdlib/curl/curl.h" +#include "runtime-light/stdlib/regex/regex-context.h" #include "runtime-light/stdlib/rpc/rpc-context.h" +#include "runtime-light/stdlib/string/string-context.h" constexpr uint64_t INVALID_PLATFORM_DESCRIPTOR = 0; @@ -102,8 +104,10 @@ struct ComponentState { JobWorkerClientComponentContext job_worker_client_component_context{}; JobWorkerServerComponentContext job_worker_server_component_context{}; - RegexComponentState regex_component_context; - CurlComponentState curl_component_state; + RegexComponentContext regex_component_context; + CurlComponentContext curl_component_context; + StringComponentContext string_component_context; + FileStreamComponentContext file_stream_component_context; private: task_t main_task_; diff --git a/runtime-light/stdlib/array/array-functions.h b/runtime-light/stdlib/array/array-functions.h index 4eec86f6df..34f0edcc64 100644 --- a/runtime-light/stdlib/array/array-functions.h +++ b/runtime-light/stdlib/array/array-functions.h @@ -536,3 +536,18 @@ auto f$array_column(const Optional &a, const mixed &column_key, const mixed &index_key = {}) -> decltype(f$array_column(std::declval(), column_key, index_key)) { php_critical_error("call to unsupported function"); } + +template +mixed f$array_key_first(const array &a) { + php_critical_error("call to unsupported function"); +} + +template +mixed f$array_key_last(const array &a) { + php_critical_error("call to unsupported function"); +} + +template +std::tuple::key_type, T> f$array_find(const array &a, const T1 &callback) { + php_critical_error("call to unsupported function"); +} diff --git a/runtime-light/stdlib/curl/curl.cpp b/runtime-light/stdlib/curl/curl-context.cpp similarity index 57% rename from runtime-light/stdlib/curl/curl.cpp rename to runtime-light/stdlib/curl/curl-context.cpp index d774c103e6..3e68fcb3e6 100644 --- a/runtime-light/stdlib/curl/curl.cpp +++ b/runtime-light/stdlib/curl/curl-context.cpp @@ -2,11 +2,11 @@ // Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt -#include "runtime-light/stdlib/curl/curl.h" +#include "runtime-light/stdlib/curl/curl-context.h" #include "runtime-light/component/component.h" #include "runtime-light/utils/context.h" -CurlComponentState &CurlComponentState::get() noexcept { - return get_component_context()->curl_component_state; +CurlComponentContext &CurlComponentContext::get() noexcept { + return get_component_context()->curl_component_context; } diff --git a/runtime-light/stdlib/curl/curl-context.h b/runtime-light/stdlib/curl/curl-context.h new file mode 100644 index 0000000000..e6a13a208f --- /dev/null +++ b/runtime-light/stdlib/curl/curl-context.h @@ -0,0 +1,13 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include + +struct CurlComponentContext { + int64_t curl_multi_info_read_msgs_in_queue_stub{}; + + static CurlComponentContext &get() noexcept; +}; diff --git a/runtime-light/stdlib/curl/curl.h b/runtime-light/stdlib/curl/curl-functions.h similarity index 70% rename from runtime-light/stdlib/curl/curl.h rename to runtime-light/stdlib/curl/curl-functions.h index 6a4f91bb76..3618779984 100644 --- a/runtime-light/stdlib/curl/curl.h +++ b/runtime-light/stdlib/curl/curl-functions.h @@ -7,14 +7,9 @@ #include #include "runtime-core/runtime-core.h" +#include "runtime-light/stdlib/curl/curl-context.h" -struct CurlComponentState { - int64_t curl_multi_info_read_msgs_in_queue_stub{}; - - static CurlComponentState &get() noexcept; -}; - -inline Optional> f$curl_multi_info_read(int64_t, int64_t & = CurlComponentState::get().curl_multi_info_read_msgs_in_queue_stub) { +inline Optional> f$curl_multi_info_read(int64_t, int64_t & = CurlComponentContext::get().curl_multi_info_read_msgs_in_queue_stub) { php_critical_error("call to unsupported function : curl_multi_info_read"); } diff --git a/runtime-light/stdlib/exception/exception-functions.h b/runtime-light/stdlib/exception/exception-functions.h index a45eb14837..3b93f85c62 100644 --- a/runtime-light/stdlib/exception/exception-functions.h +++ b/runtime-light/stdlib/exception/exception-functions.h @@ -7,7 +7,32 @@ #include "runtime-core/runtime-core.h" +#define THROW_EXCEPTION(e) {php_critical_error("Exceptions unsupported");} + +#define CHECK_EXCEPTION(action) + +#ifdef __clang__ + #define TRY_CALL_RET_(x) x +#else + #define TRY_CALL_RET_(x) std::move(x) +#endif + +#define TRY_CALL_(CallT, call, action) ({ \ +CallT x_tmp___ = (call); \ +CHECK_EXCEPTION(action); \ +TRY_CALL_RET_(x_tmp___); \ +}) + +#define TRY_CALL_VOID_(call, action) ({(call); CHECK_EXCEPTION(action); void();}) + +#define TRY_CALL(CallT, ResT, call) TRY_CALL_(CallT, call, return (ResT())) +#define TRY_CALL_VOID(ResT, call) TRY_CALL_VOID_(call, return (ResT())) + +#define TRY_CALL_EXIT(CallT, message, call) TRY_CALL_(CallT, call, php_critical_error (message)) +#define TRY_CALL_VOID_EXIT(message, call) TRY_CALL_VOID_(call, php_critical_error (message)) + + template T f$_exception_set_location(const T &e, const string &file, int64_t line) { - php_critical_error("call to unsupported function : _exception_set_location"); + php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/file/file-stream-context.cpp b/runtime-light/stdlib/file/file-stream-context.cpp new file mode 100644 index 0000000000..9edf534b8e --- /dev/null +++ b/runtime-light/stdlib/file/file-stream-context.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/file/file-stream-context.h" + +#include "runtime-light/component/component.h" + +FileStreamComponentContext &FileStreamComponentContext::get() noexcept { + return get_component_context()->file_stream_component_context; +} diff --git a/runtime-light/stdlib/file/file-stream-context.h b/runtime-light/stdlib/file/file-stream-context.h new file mode 100644 index 0000000000..7648c61cae --- /dev/null +++ b/runtime-light/stdlib/file/file-stream-context.h @@ -0,0 +1,14 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include "runtime-core/runtime-core.h" + +struct FileStreamComponentContext { + mixed error_number_dummy; + mixed error_description_dummy; + + static FileStreamComponentContext &get() noexcept; +}; diff --git a/runtime-light/stdlib/file/file-stream-functions.h b/runtime-light/stdlib/file/file-stream-functions.h new file mode 100644 index 0000000000..43ef4f4cd9 --- /dev/null +++ b/runtime-light/stdlib/file/file-stream-functions.h @@ -0,0 +1,15 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include + +#include "runtime-light/stdlib/file/file-stream-context.h" + +inline mixed f$stream_socket_client(const string &, mixed & = FileStreamComponentContext::get().error_number_dummy, + mixed & = FileStreamComponentContext::get().error_description_dummy, double = -1, int64_t = 1, + const mixed & = mixed()) { + php_critical_error("call to unsupported function"); +} diff --git a/runtime-light/stdlib/fork/fork-functions.h b/runtime-light/stdlib/fork/fork-functions.h index 5e98a6d6cb..348b4471cc 100644 --- a/runtime-light/stdlib/fork/fork-functions.h +++ b/runtime-light/stdlib/fork/fork-functions.h @@ -27,7 +27,7 @@ inline constexpr auto DEFAULT_TIMEOUT_NS = std::chrono::duration_cast -requires(is_optional::value || std::same_as) task_t f$wait(int64_t fork_id, double timeout = -1.0) noexcept { +requires(is_optional::value || std::same_as || is_class_instance::value) task_t f$wait(int64_t fork_id, double timeout = -1.0) noexcept { auto &fork_ctx{ForkComponentContext::get()}; if (!fork_ctx.contains(fork_id)) { php_warning("can't find fork %" PRId64, fork_id); @@ -42,7 +42,7 @@ requires(is_optional::value || std::same_as) task_t f$wait(int64 } template -requires(is_optional::value || std::same_as) task_t f$wait(Optional fork_id_opt, double timeout = -1.0) noexcept { +requires(is_optional::value || std::same_as || is_class_instance::value) task_t f$wait(Optional fork_id_opt, double timeout = -1.0) noexcept { co_return co_await f$wait(fork_id_opt.has_value() ? fork_id_opt.val() : INVALID_FORK_ID, timeout); } @@ -63,3 +63,23 @@ inline task_t f$sched_yield_sleep(double duration) noexcept { inline int64_t f$get_running_fork_id() noexcept { return ForkComponentContext::get().running_fork_id; } + +inline int64_t f$wait_queue_create() { + php_critical_error("call to unsupported function"); +} + +inline int64_t f$wait_queue_create(const mixed &resumable_ids) { + php_critical_error("call to unsupported function"); +} + +inline int64_t f$wait_queue_push(int64_t queue_id, const mixed &resumable_ids) { + php_critical_error("call to unsupported function"); +} + +inline bool f$wait_queue_empty(int64_t queue_id) { + php_critical_error("call to unsupported function"); +} + +inline Optional f$wait_queue_next(int64_t queue_id, double timeout = -1.0) { + php_critical_error("call to unsupported function"); +} diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index bc14fb1cad..ba5dfa3ecb 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -5,6 +5,3 @@ #include #include -inline int64_t f$rand() noexcept { - return static_cast(std::random_device{}()); -} diff --git a/runtime-light/stdlib/output/http-functions.h b/runtime-light/stdlib/output/http-functions.h new file mode 100644 index 0000000000..797204fbaa --- /dev/null +++ b/runtime-light/stdlib/output/http-functions.h @@ -0,0 +1,14 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include + +#include "runtime-core/runtime-core.h" + +template +string f$http_build_query(const array &a, const string &numeric_prefix = {}, const string &arg_separator = string(), int64_t enc_type = 1) { + php_critical_error("call to unsupported function"); +} diff --git a/runtime-light/stdlib/regex/regex-functions.cpp b/runtime-light/stdlib/regex/regex-context.cpp similarity index 82% rename from runtime-light/stdlib/regex/regex-functions.cpp rename to runtime-light/stdlib/regex/regex-context.cpp index 561d3493c5..ef73837c1e 100644 --- a/runtime-light/stdlib/regex/regex-functions.cpp +++ b/runtime-light/stdlib/regex/regex-context.cpp @@ -6,6 +6,6 @@ #include "runtime-light/component/component.h" -RegexComponentState &RegexComponentState::get() noexcept { +RegexComponentContext &RegexComponentContext::get() noexcept { return get_component_context()->regex_component_context; } diff --git a/runtime-light/stdlib/regex/regex-context.h b/runtime-light/stdlib/regex/regex-context.h new file mode 100644 index 0000000000..3fb8d15303 --- /dev/null +++ b/runtime-light/stdlib/regex/regex-context.h @@ -0,0 +1,13 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include + +struct RegexComponentContext { + int64_t preg_replace_count_dummy{}; + + static RegexComponentContext &get() noexcept; +}; diff --git a/runtime-light/stdlib/regex/regex-functions.h b/runtime-light/stdlib/regex/regex-functions.h index 5c0c2e6369..7f28cf729c 100644 --- a/runtime-light/stdlib/regex/regex-functions.h +++ b/runtime-light/stdlib/regex/regex-functions.h @@ -5,12 +5,7 @@ #pragma once #include "runtime-core/runtime-core.h" - -struct RegexComponentState { - int64_t preg_replace_count_dummy{}; - - static RegexComponentState &get() noexcept; -}; +#include "runtime-light/stdlib/regex/regex-context.h" class regexp final : private vk::not_copyable { public: @@ -25,83 +20,83 @@ class regexp final : private vk::not_copyable { template> auto f$preg_replace(const T1 ®ex, const T2 &replace_val, const T3 &subject, int64_t limit = -1, - int64_t &replace_count = RegexComponentState::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { return f$preg_replace(regex, replace_val, subject.val(), limit, replace_count); } inline Optional f$preg_replace(const regexp &, const string &, const string &, int64_t = -1, - int64_t & = RegexComponentState::get().preg_replace_count_dummy) { + int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } inline Optional f$preg_replace(const regexp &, const mixed &, const string &, int64_t = -1, - int64_t & = RegexComponentState::get().preg_replace_count_dummy) { + int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const regexp &, const string &, const mixed &, int64_t = -1, int64_t & = RegexComponentState::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const regexp &, const string &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const regexp &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexComponentState::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const regexp &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template auto f$preg_replace(const string ®ex, const T1 &replace_val, const T2 &subject, int64_t limit, - int64_t &replace_count = RegexComponentState::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { return f$preg_replace(regexp(regex), replace_val, subject, limit, replace_count); } inline Optional f$preg_replace(const mixed &, const string &, const string &, int64_t = -1, - int64_t & = RegexComponentState::get().preg_replace_count_dummy) { + int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const mixed &, const string &, const mixed &, int64_t = -1, int64_t & = RegexComponentState::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const mixed &, const string &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } inline Optional f$preg_replace(const mixed &, const mixed &, const string &, int64_t = -1, - int64_t & = RegexComponentState::get().preg_replace_count_dummy) { + int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const mixed &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexComponentState::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const mixed &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template> auto f$preg_replace_callback(const T1 ®ex, const T2 &replace_val, const T3 &subject, int64_t limit = -1, - int64_t &replace_count = RegexComponentState::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { return f$preg_replace_callback(regex, replace_val, subject.val(), limit, replace_count); } template Optional f$preg_replace_callback(const regexp &, const T &, const string &, int64_t = -1, - int64_t & = RegexComponentState::get().preg_replace_count_dummy) { + int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template -mixed f$preg_replace_callback(const regexp &, const T &, const mixed &, int64_t = -1, int64_t & = RegexComponentState::get().preg_replace_count_dummy) { +mixed f$preg_replace_callback(const regexp &, const T &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template auto f$preg_replace_callback(const string ®ex, const T &replace_val, const T2 &subject, int64_t limit = -1, - int64_t &replace_count = RegexComponentState::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { return f$preg_replace_callback(regexp(regex), replace_val, subject, limit, replace_count); } template Optional f$preg_replace_callback(const mixed &, const T &, const string &, int64_t = -1, - int64_t & = RegexComponentState::get().preg_replace_count_dummy) { + int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template -mixed f$preg_replace_callback(const mixed &, const T &, const mixed &, int64_t = -1, int64_t & = RegexComponentState::get().preg_replace_count_dummy) { +mixed f$preg_replace_callback(const mixed &, const T &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/serialization/instance-serialize.h b/runtime-light/stdlib/serialization/instance-serialize.h new file mode 100644 index 0000000000..ab54777838 --- /dev/null +++ b/runtime-light/stdlib/serialization/instance-serialize.h @@ -0,0 +1,29 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include "runtime-core/runtime-core.h" + + +template +Optional f$instance_serialize(const class_instance &instance) noexcept { + php_critical_error("call to unsupported function"); +} + + +template +string f$instance_serialize_safe(const class_instance &instance) noexcept { + php_critical_error("call to unsupported function"); +} + +template +ResultClass f$instance_deserialize(const string &buffer, const string&) noexcept { + php_critical_error("call to unsupported function"); +} + +template +ResultClass f$instance_deserialize_safe(const string &buffer, const string&) noexcept { + php_critical_error("call to unsupported function"); +} diff --git a/runtime-light/stdlib/stdlib.cmake b/runtime-light/stdlib/stdlib.cmake index abefe33df5..3c0118261a 100644 --- a/runtime-light/stdlib/stdlib.cmake +++ b/runtime-light/stdlib/stdlib.cmake @@ -3,14 +3,14 @@ prepend( stdlib/ component/component-api.cpp crypto/crypto-functions.cpp - curl/curl.cpp + curl/curl-context.cpp exit/exit-functions.cpp fork/fork-context.cpp job-worker/job-worker-api.cpp job-worker/job-worker-context.cpp output/output-buffer.cpp output/print-functions.cpp - regex/regex-functions.cpp + regex/regex-context.cpp rpc/rpc-api.cpp rpc/rpc-context.cpp rpc/rpc-extra-headers.cpp @@ -18,4 +18,6 @@ prepend( rpc/rpc-tl-error.cpp rpc/rpc-tl-query.cpp rpc/rpc-tl-request.cpp - string/concat.cpp) + string/concat.cpp + string/string-context.cpp + file/file-stream-context.cpp) diff --git a/runtime-light/stdlib/string/concat.h b/runtime-light/stdlib/string/concat.h index 7f00179b56..6d0a2fbd41 100644 --- a/runtime-light/stdlib/string/concat.h +++ b/runtime-light/stdlib/string/concat.h @@ -6,16 +6,6 @@ #include "runtime-core/runtime-core.h" -template -string f$strtr(const string &, const array &) { - php_critical_error("call to unsupported function"); -} - -template -Optional f$strpos(const string &, const Optional &, int64_t = 0) { - php_critical_error("call to unsupported function"); -} - // str_concat_arg generalizes both tmp_string and string arguments; // it can be constructed from both of them, so concat functions can operate // on both tmp_string and string types diff --git a/runtime-light/stdlib/string/string-context.cpp b/runtime-light/stdlib/string/string-context.cpp new file mode 100644 index 0000000000..1509af2676 --- /dev/null +++ b/runtime-light/stdlib/string/string-context.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/string/string-context.h" + +#include "runtime-light/component/component.h" + +StringComponentContext &StringComponentContext::get() noexcept { + return get_component_context()->string_component_context; +} diff --git a/runtime-light/stdlib/string/string-context.h b/runtime-light/stdlib/string/string-context.h new file mode 100644 index 0000000000..3ebe9ef171 --- /dev/null +++ b/runtime-light/stdlib/string/string-context.h @@ -0,0 +1,16 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include + +#include "runtime-core/runtime-core.h" + +struct StringComponentContext { + int64_t str_replace_count_dummy{}; + double default_similar_text_percent_stub{}; + + static StringComponentContext &get() noexcept; +}; diff --git a/runtime-light/stdlib/string/string-functions.h b/runtime-light/stdlib/string/string-functions.h index 7063a939e9..da0e045ffb 100644 --- a/runtime-light/stdlib/string/string-functions.h +++ b/runtime-light/stdlib/string/string-functions.h @@ -2,51 +2,107 @@ // Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt +#pragma once + #include -#include "runtime-core/runtime-core.h" +#include "runtime-light/stdlib/string/string-context.h" + +template +Optional f$strpos(const string &, const Optional &, int64_t = 0) { + php_critical_error("call to unsupported function"); +} inline int64_t f$strlen(const string &s) noexcept { return s.size(); } -inline tmp_string f$_tmp_substr(const string &str, int64_t start, int64_t length = std::numeric_limits::max()) { +inline tmp_string f$_tmp_substr(const string &, int64_t, int64_t = std::numeric_limits::max()) { + php_critical_error("call to unsupported function"); +} + +inline tmp_string f$_tmp_substr(tmp_string, int64_t, int64_t = std::numeric_limits::max()) { + php_critical_error("call to unsupported function"); +} + +inline tmp_string f$_tmp_trim(tmp_string, const string & = string()) { + php_critical_error("call to unsupported function"); +} + +inline tmp_string f$_tmp_trim(const string &, const string & = string()) { + php_critical_error("call to unsupported function"); +} + +inline string f$trim(tmp_string, const string & = string()) { + php_critical_error("call to unsupported function"); +} + +inline string f$trim(const string &, const string & = string()) { + php_critical_error("call to unsupported function"); +} + +inline Optional f$substr(const string &, int64_t, int64_t = std::numeric_limits::max()) { php_critical_error("call to unsupported function"); } -inline tmp_string f$_tmp_substr(tmp_string str, int64_t start, int64_t length = std::numeric_limits::max()) { +inline Optional f$substr(tmp_string, int64_t, int64_t = std::numeric_limits::max()) { php_critical_error("call to unsupported function"); } -inline tmp_string f$_tmp_trim(tmp_string s, const string &what = string()) { +inline string f$pack(const string &, const array &) { php_critical_error("call to unsupported function"); } -inline tmp_string f$_tmp_trim(const string &s, const string &what = string()) { +inline Optional> f$unpack(const string &, const string &) { php_critical_error("call to unsupported function"); } -inline string f$trim(tmp_string s, const string &what = string()) { +inline mixed f$str_replace(const mixed &, const mixed &, const mixed &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline string f$trim(const string &s, const string &what = string()) { +inline string f$str_replace(const string &, const string &, const string &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline Optional f$substr(const string &str, int64_t start, int64_t length = std::numeric_limits::max()) { +template +string f$str_replace(const array &, const array &, const string &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline Optional f$substr(tmp_string, int64_t start, int64_t length = std::numeric_limits::max()) { +inline string f$str_replace(const mixed &, const mixed &, const string &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { php_critical_error("call to unsupported function"); } +template> +SubjectT f$str_replace(const T1 &search, const T2 &replace, const SubjectT &subject, + int64_t &replace_count = StringComponentContext::get().str_replace_count_dummy) { + return f$str_replace(search, replace, subject.val(), replace_count); +} + +inline string f$str_ireplace(const string &, const string &, const string &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { + php_critical_error("call to unsupported function"); +} + +template +string f$str_ireplace(const array &, const array &, const string &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { + php_critical_error("call to unsupported function"); +} + +inline string f$str_ireplace(const mixed &, const mixed &, const string &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { + php_critical_error("call to unsupported function"); +} + +template> +SubjectT f$str_ireplace(const T1 &search, const T2 &replace, const SubjectT &subject, + int64_t &replace_count = StringComponentContext::get().str_replace_count_dummy) { + return f$str_ireplace(search, replace, subject.val(), replace_count); +} -inline string f$pack(const string &pattern, const array &a) { +inline mixed f$str_ireplace(const mixed &, const mixed &, const mixed &, int64_t & = StringComponentContext::get().str_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline Optional> f$unpack(const string &pattern, const string &data) { +inline int64_t f$similar_text(const string &, const string &, double & = StringComponentContext::get().default_similar_text_percent_stub) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/tl/tl-builtins.h b/runtime-light/tl/tl-builtins.h index 1b524fe2b5..a2e037079e 100644 --- a/runtime-light/tl/tl-builtins.h +++ b/runtime-light/tl/tl-builtins.h @@ -14,9 +14,6 @@ #include "runtime-light/stdlib/rpc/rpc-api.h" #include "runtime-light/stdlib/rpc/rpc-tl-defs.h" -// TODO: get rid of it here -#define CHECK_EXCEPTION(action) - void register_tl_storers_table_and_fetcher(const array &gen$ht, tl_fetch_wrapper_ptr gen$t_ReqResult_fetch); int32_t tl_parse_save_pos(); diff --git a/runtime-light/utils/to-array-processor.h b/runtime-light/utils/to-array-processor.h index 1824313c0b..32072472c4 100644 --- a/runtime-light/utils/to-array-processor.h +++ b/runtime-light/utils/to-array-processor.h @@ -8,7 +8,7 @@ #include "common/mixin/not_copyable.h" #include "common/smart_ptrs/singleton.h" -#include "runtime-core/runtime-core.h" +#include "runtime-core/core-types/definition/null_coalesce.h" class ShapeKeyDemangle : vk::not_copyable { public: diff --git a/tests/phpt/fork/007_fork_instance.php b/tests/phpt/fork/007_fork_instance.php index a04bc14ade..5161bb97f8 100644 --- a/tests/phpt/fork/007_fork_instance.php +++ b/tests/phpt/fork/007_fork_instance.php @@ -1,4 +1,4 @@ -@ok k2_skip +@ok