diff --git a/pkgs/overlay/packages/php/package.nix b/pkgs/overlay/packages/php/package.nix new file mode 100644 index 00000000..2ab2f48d --- /dev/null +++ b/pkgs/overlay/packages/php/package.nix @@ -0,0 +1,234 @@ +# PHP 8.5 — static ZTS libphp for wasix, the dependency phpix embeds. Ported from the old +# pkgs/libraries/php (origin/php85-tailcall): upstream php-src + the php85 patch stack + bundled +# igbinary/imagick. Built through the exnrefEh profile stdenv (wasixcc with WASM_EXCEPTIONS=yes). +# +# Deps go in buildInputs, so the profile stdenv auto-threads -I/-L and pkg-config (PKG_CONFIG_PATH) +# supplies each lib's flags — the old recipe's ~25 hand-fed per-lib *_CFLAGS/*_LIBS were just +# discovery and are gone. Only libs PHP can't find via pkg-config keep explicit flags: iconv (no +# .pc), imagick (config.m4 patched — its .pc lookup name is wrong), pgsql + icu (explicit flags); curl's +# full static link is derived from curl-config in configurePhase (brotli/zstd deps). +# +# Produces `make install-headers install-sapi` (static libphp + headers) for phpix to link via +# passthru.phpExtraLibDirs / phpExtraLinkLibs. exnrefEh-only (passthru.wasix.supportedProfiles). +{ + final, + prev, + ... +}: let + lib = prev.lib; + + versions = import ./versions.nix {inherit (prev) lib fetchFromGitHub;}; + v = versions.php85; + + L = final; # overlay deps, auto-threaded at this profile + + # Deterministic output selection (lib.getLib/getDev pick by the drv's declared outputs, unlike + # builtins.pathExists which is store-state-dependent at eval). + includeDir = drv: "${lib.getDev drv}/include"; + libraryDir = drv: "${lib.getLib drv}/lib"; + + # libpq splits dev/lib but PHP's --with-pgsql wants one prefix, so synthesize a merged one (+ a + # stub pg_config). libpq's archives live under its dev output. + libpqLibraryDir = "${lib.getDev L.libpq}/lib"; + libpqPrefix = final.buildPackages.stdenvNoCC.mkDerivation { + name = "php85-libpq-prefix"; + dontUnpack = true; + dontBuild = true; + installPhase = '' + mkdir -p "$out/include" "$out/lib" "$out/bin" + cp -a ${lib.getDev L.libpq}/include/. "$out/include/" + cp -a ${libpqLibraryDir}/. "$out/lib/" + cat > "$out/bin/pg_config" <&2; exit 1 ;; + esac + EOF + chmod +x "$out/bin/pg_config" + ''; + }; + + depList = [ + L.curl + L.brotli # curl --with-brotli: libcurl.pc lists -lbrotlidec but its -L is in Libs.private + L.zlib + L.xz + L.libxml2 + L.sqlite + L.openssl + L.libiconv + L.icu + L.libpng + L.libjpeg + L.freetype + L.libwebp + L.libzip + L.libsodium + L.oniguruma + L.libdeflate + L.zstd + L.libtiff + L.imagemagick + ]; + # phpix links libphp against these (passthru); kept explicit because phpix's link line needs the + # exact archive names + dirs and can't rederive them from the php build. + # lcms2 + openjpeg are transitive (via imagemagick), not linked into php directly — but phpix's + # link needs their dirs on its search path (passthru-only, so this doesn't rebuild php). + allLibraryDirs = map libraryDir depList ++ [libpqLibraryDir (libraryDir L.lcms2) (libraryDir L.openjpeg)]; + phpExtraLinkLibs = [ + "MagickCore-7.Q16HDRI" + "MagickWand-7.Q16HDRI" + "crypto" + "curl" + "freetype" + "icudata" + "icui18n" + "icuio" + "icuuc" + "jpeg" + "lzma" + "onig" + "pgcommon_shlib" + "pgport_shlib" + "png16" + "pq" + "sharpyuv" + "sodium" + "sqlite3" + "ssl" + "deflate" + "tiff" + "webpmux" + "webpdemux" + "webp" + "xml2" + "z" + "zstd" + "zip" + ]; + + # Only the flags PHP can't get from pkg-config + buildInputs. curl/zlib/libxml/sqlite/openssl/png/ + # jpeg/freetype/webp/libzip/sodium/onig are all discovered via pkg-config now. + configureEnv = { + # iconv: wasilibc-iconv ships no .pc and its split charset/icrt libs aren't auto-linked. + ICONV_LIBS = "-liconv -lcharset -licrt"; + # intl/icu: needs an explicit C/C++ std (the -I is redundant with buildInputs but harmless). + ICU_CFLAGS = "-I${includeDir L.icu} -std=c11"; + ICU_CXXFLAGS = "-I${includeDir L.icu} -std=c++17"; + ICU_LIBS = "-licudata -licui18n -licuio -licuuc"; + # imagick: IM_FIND_IMAGEMAGICK does PKG_CHECK_MODULES([MagickWand]), but the overlay ships the + # .pc as MagickWand-7.Q16HDRI (the Q16HDRI variant), so that lookup fails — config.m4 is patched + # (postPatch) to read these explicitly instead. + IM_IMAGEMAGICK_CFLAGS = "-I${includeDir L.imagemagick}/ImageMagick -DIM_MAGICKWAND_HEADER_STYLE_SEVEN -DMAGICKCORE_QUANTUM_DEPTH=16 -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_CHANNEL_MASK_DEPTH=32"; + IM_IMAGEMAGICK_LIBS = "-lMagickWand-7.Q16HDRI -lMagickCore-7.Q16HDRI -ltiff -lz -ldeflate -ljpeg -llzma -lzstd -lpng16 -lwebpmux -lwebpdemux -lwebp -lsharpyuv -lfreetype -lxml2 -lcurl -lssl -lcrypto"; + # pgsql: --with-pgsql= (a path) makes PHP's config.m4 skip pkg-config, so it reads these; + # libpq is the synthetic merged prefix (libpq splits dev/lib). + PGSQL_CFLAGS = "-I${libpqPrefix}/include"; + PGSQL_LIBS = "-lpq -lpgcommon_shlib -lpgport_shlib -lz -lm"; + PHP_BUILD_SYSTEM = "clang(WASIX+WasmEH)"; + PHP_IPV6 = "yes"; + CFLAGS = "-g -O2 -mtail-call"; + CXXFLAGS = "-g -O2 -mtail-call"; + # pg's static libs at the final link (+ libm); other search dirs come from buildInputs. + LIBS = "-L${libpqLibraryDir} -lpgcommon_shlib -lpgport_shlib -lm"; + # libpq link-checks can't run on wasm; assert the symbols exist. + ac_cv_lib_pq_PQlibVersion = "yes"; + ac_cv_lib_pq_PQencryptPasswordConn = "yes"; + ac_cv_lib_pq_PQchangePassword = "yes"; + ac_cv_lib_pq_pg_encoding_to_char = "yes"; + ac_cv_lib_pq_lo_truncate64 = "yes"; + ac_cv_lib_pq_PQsocketPoll = "yes"; + ac_cv_lib_pq_PQsetErrorContextVisibility = "yes"; + WASIXCC_INCLUDE_CPP_SYMBOLS = "yes"; + WASIXCC_RUN_WASM_OPT = "no"; + PROG_SENDMAIL = "/usr/bin/sendmail"; + }; + exportConfigureEnv = lib.concatStringsSep "\n" (lib.mapAttrsToList (n: val: "export ${n}=${lib.escapeShellArg val}") configureEnv); + + bundledExtensions = v.bundledExtensions; + bundledNames = builtins.attrNames bundledExtensions; + copyBundledExtensions = + lib.concatMapStringsSep "\n" (name: let + ext = bundledExtensions.${name}; + extPatches = lib.concatMapStringsSep "\n" (p: "patch -p1 < ${lib.escapeShellArg "${p}"}") (ext.patches or []); + in '' + rm -rf "ext/${name}" + mkdir -p "ext/${name}" + cp -R --no-preserve=mode,ownership ${ext.src}/. "ext/${name}" + chmod -R u+w "ext/${name}" + ${extPatches} + '') + bundledNames; + patchTargets = lib.concatStringsSep " " (["buildconf" "build" "scripts"] ++ map (n: "ext/${n}") bundledNames); +in + final.stdenv.mkDerivation { + inherit (v) pname version src patches; + + nativeBuildInputs = with final.buildPackages; [ + autoconf + bison + re2c + pkg-config + gnumake + perl + python3 + coreutils + ]; + buildInputs = depList; + + enableParallelBuilding = true; + + postPatch = '' + ${copyBundledExtensions} + substituteInPlace ext/imagick/config.m4 \ + --replace-fail 'IM_FIND_IMAGEMAGICK([6.5.3], [$PHP_IMAGICK])' '# WASIX passes ImageMagick paths explicitly via IM_IMAGEMAGICK_{CFLAGS,LIBS}. + # IM_FIND_IMAGEMAGICK([6.5.3], [$PHP_IMAGICK])' + substituteInPlace ext/imagick/php_imagick.h \ + --replace-fail '#define PHP_IMAGICK_VERSION "@PACKAGE_VERSION@"' '#define PHP_IMAGICK_VERSION "3.8.1"' + substituteInPlace ext/imagick/imagick.c \ + --replace-fail 'ext/standard/php_smart_string.h' 'Zend/zend_smart_string.h' + substituteInPlace ext/igbinary/src/php7/php_igbinary.h \ + --replace-fail 'ext/standard/php_smart_string.h' 'Zend/zend_smart_string.h' + patchShebangs ${patchTargets} + ''; + + configurePhase = '' + runHook preConfigure + ${exportConfigureEnv} + # The overlay curl is --with-brotli --with-zstd, so libcurl.a needs their symbols; derive the + # full static curl link (-L dirs + -l flags for brotli/zstd/openssl/zlib) from curl-config + # rather than a hand-typed list that goes stale when curl's deps change. (+ php's -ldl -pthread.) + export CURL_LIBS="$(${lib.getDev L.curl}/bin/curl-config --static-libs) -ldl -pthread" + installPrefix="$PWD/install" + ./buildconf --force + ./configure ${lib.escapeShellArgs (v.configureFlags ++ ["--with-pgsql=${libpqPrefix}" "--with-pdo-pgsql=${libpqPrefix}"])} --prefix="$installPrefix" + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + make -j''${NIX_BUILD_CORES:-1} install-headers install-sapi + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir -p "$out" + cp -a install/. "$out/" + runHook postInstall + ''; + + passthru = { + phpExtraLibDirs = allLibraryDirs; + inherit phpExtraLinkLibs bundledExtensions; + wasix.supportedProfiles = ["exnrefEh"]; + }; + + meta = + (v.meta or {}) + // { + description = "Static PHP 8.5 WASIX ZTS libphp build"; + }; + } diff --git a/pkgs/overlay/packages/php/patches/common/0001-wasix-core-support.patch b/pkgs/overlay/packages/php/patches/common/0001-wasix-core-support.patch new file mode 100644 index 00000000..4b8cc0ba --- /dev/null +++ b/pkgs/overlay/packages/php/patches/common/0001-wasix-core-support.patch @@ -0,0 +1,691 @@ +diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c +index d531270..2401f60 100644 +--- a/Zend/zend_alloc.c ++++ b/Zend/zend_alloc.c +@@ -704,6 +704,7 @@ static zend_always_inline int zend_mm_bitset_is_free_range(zend_mm_bitset *bitse + + static zend_always_inline void zend_mm_hugepage(void* ptr, size_t size) + { ++#ifndef __wasi__ + #if defined(MADV_HUGEPAGE) + (void)madvise(ptr, size, MADV_HUGEPAGE); + #elif defined(HAVE_MEMCNTL) +@@ -712,6 +713,7 @@ static zend_always_inline void zend_mm_hugepage(void* ptr, size_t size) + #elif !defined(VM_FLAGS_SUPERPAGE_SIZE_2MB) && !defined(MAP_ALIGNED_SUPER) + zend_error_noreturn(E_WARNING, "huge_pages: thp unsupported on this platform"); + #endif ++#endif + } + + static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) +@@ -2845,6 +2847,10 @@ static void *tracked_malloc(size_t size) + + tracked_add(heap, ptr, size); + heap->size += size; ++ heap->real_size = size; ++ size_t peak = MAX(heap->peak, size); ++ heap->peak = peak; ++ heap->real_peak = peak; + return ptr; + } + +@@ -2856,6 +2862,7 @@ static void tracked_free(void *ptr) { + zend_mm_heap *heap = AG(mm_heap); + zval *size_zv = tracked_get_size_zv(heap, ptr); + heap->size -= Z_LVAL_P(size_zv); ++ heap->real_size = heap->size; + zend_hash_del_bucket(heap->tracked_allocs, (Bucket *) size_zv); + free(ptr); + } +@@ -2881,6 +2888,10 @@ static void *tracked_realloc(void *ptr, size_t new_size) { + ptr = __zend_realloc(ptr, new_size); + tracked_add(heap, ptr, new_size); + heap->size += new_size - old_size; ++ heap->real_size = heap->size; ++ size_t peak = MAX(heap->peak, heap->size); ++ heap->peak = peak; ++ heap->real_peak = peak; + return ptr; + } + +@@ -2899,9 +2910,15 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) + char *tmp; + + #if ZEND_MM_CUSTOM ++#ifndef __wasi__ + tmp = getenv("USE_ZEND_ALLOC"); + if (tmp && !ZEND_ATOL(tmp)) { ++#endif ++#ifdef __wasi__ ++ bool tracked = true; ++#else + bool tracked = (tmp = getenv("USE_TRACKED_ALLOC")) && ZEND_ATOL(tmp); ++#endif + zend_mm_heap *mm_heap = alloc_globals->mm_heap = malloc(sizeof(zend_mm_heap)); + memset(mm_heap, 0, sizeof(zend_mm_heap)); + mm_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD; +@@ -2922,7 +2939,9 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) + zend_hash_init(mm_heap->tracked_allocs, 1024, NULL, NULL, 1); + } + return; ++#ifndef __wasi__ + } ++#endif + #endif + + tmp = getenv("USE_ZEND_ALLOC_HUGE_PAGES"); +diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c +index c0c6dc8..e872ec1 100644 +--- a/Zend/zend_extensions.c ++++ b/Zend/zend_extensions.c +@@ -27,7 +27,7 @@ static int last_resource_number; + + zend_result zend_load_extension(const char *path) + { +-#if ZEND_EXTENSIONS_SUPPORT ++#if ZEND_EXTENSIONS_SUPPORT && !defined(__wasi__) + DL_HANDLE handle; + + handle = DL_LOAD(path); +@@ -61,7 +61,7 @@ zend_result zend_load_extension(const char *path) + + zend_result zend_load_extension_handle(DL_HANDLE handle, const char *path) + { +-#if ZEND_EXTENSIONS_SUPPORT ++#if ZEND_EXTENSIONS_SUPPORT && !defined(__wasi__) + zend_extension *new_extension; + + const zend_extension_version_info *extension_version_info = (const zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info"); +@@ -226,7 +226,7 @@ void zend_shutdown_extensions(void) + + void zend_extension_dtor(zend_extension *extension) + { +-#if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG ++#if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG && !defined(__wasi__) + if (extension->handle && !getenv("ZEND_DONT_UNLOAD_MODULES")) { + DL_UNLOAD(extension->handle); + } +@@ -270,7 +270,7 @@ ZEND_API int zend_get_resource_handle(const char *module_name) + * + * The extension slot has been available since PHP 7.4 on user functions and + * has been available since PHP 8.2 on internal functions. +- * ++ * + * # Safety + * The extension slot made available by calling this function is initialized on + * the first call made to the function in that request. If you need to +@@ -278,13 +278,13 @@ ZEND_API int zend_get_resource_handle(const char *module_name) + * + * The function cache slots are not available if the function is a trampoline, + * which can be checked with something like: +- * ++ * + * if (fbc->type == ZEND_USER_FUNCTION + * && !(fbc->op_array.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) + * ) { + * // Use ZEND_OP_ARRAY_EXTENSION somehow + * } +- */ ++ */ + ZEND_API int zend_get_op_array_extension_handle(const char *module_name) + { + int handle = zend_op_array_extension_handles++; +diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c +index 6b6c1ea..59757f4 100644 +--- a/Zend/zend_fibers.c ++++ b/Zend/zend_fibers.c +@@ -249,7 +249,7 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size) + + zend_mmap_set_name(pointer, alloc_size, "zend_fiber_stack"); + +-# if ZEND_FIBER_GUARD_PAGES ++# if ZEND_FIBER_GUARD_PAGES && !defined(__wasi__) + if (mprotect(pointer, ZEND_FIBER_GUARD_PAGES * page_size, PROT_NONE) < 0) { + zend_throw_exception_ex(NULL, 0, "Fiber stack protect failed: mprotect failed: %s (%d)", strerror(errno), errno); + munmap(pointer, alloc_size); +@@ -424,7 +424,7 @@ ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void * + makecontext(handle, (void (*)(void)) zend_fiber_trampoline, 0); + + context->handle = handle; +-#else ++#elif !defined(__wasi__) + // Stack grows down, calculate the top of the stack. make_fcontext then shifts pointer to lower 16-byte boundary. + void *stack = (void *) ((uintptr_t) context->stack->pointer + context->stack->size); + +@@ -437,6 +437,8 @@ ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void * + + context->handle = make_fcontext(stack, context->stack->size, zend_fiber_trampoline); + ZEND_ASSERT(context->handle != NULL && "make_fcontext() never returns NULL"); ++#else ++ return FAILURE; + #endif + + context->kind = kind; +@@ -511,16 +513,18 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer) + + /* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */ + *transfer = *transfer_data; +-#else ++#elif !defined(__wasi__) + boost_context_data data = jump_fcontext(to->handle, transfer); + + /* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */ + *transfer = *data.transfer; ++#else ++ return; + #endif + + to = transfer->context; + +-#ifndef ZEND_FIBER_UCONTEXT ++#if !defined(ZEND_FIBER_UCONTEXT) && !defined(__wasi__) + /* Get the context that resumed us and update its handle to allow for symmetric coroutines. */ + to->handle = data.handle; + #endif +diff --git a/Zend/zend_long.h b/Zend/zend_long.h +index 3796f1c..ea979e3 100644 +--- a/Zend/zend_long.h ++++ b/Zend/zend_long.h +@@ -23,7 +23,7 @@ + #include + + /* This is the heart of the whole int64 enablement in zval. */ +-#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) ++#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) || defined(WASIX_64BIT_LONG_PATCH) + # define ZEND_ENABLE_ZVAL_LONG64 1 + #endif + +diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h +index 6706879..8573d69 100644 +--- a/Zend/zend_portability.h ++++ b/Zend/zend_portability.h +@@ -175,6 +175,9 @@ + # define DL_UNLOAD FreeLibrary + # define DL_HANDLE HMODULE + # define ZEND_EXTENSIONS_SUPPORT 1 ++#elif defined(__wasi__) ++# define DL_HANDLE void * ++# define ZEND_EXTENSIONS_SUPPORT 1 + #else + # define DL_HANDLE void * + # define ZEND_EXTENSIONS_SUPPORT 0 +@@ -370,7 +373,7 @@ char *alloca(); + # define XtOffsetOf(s_type, field) offsetof(s_type, field) + #endif + +-#ifdef HAVE_SIGSETJMP ++#if defined(HAVE_SIGSETJMP) && !defined(__wasm32) + # define SETJMP(a) sigsetjmp(a, 0) + # define LONGJMP(a,b) siglongjmp(a, b) + # define JMP_BUF sigjmp_buf +diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h +index 92bdede..e0a893d 100644 +--- a/Zend/zend_virtual_cwd.h ++++ b/Zend/zend_virtual_cwd.h +@@ -59,6 +59,10 @@ + #include + #endif + ++#ifdef __wasi__ ++#define chown(a,b,c) 0 ++#endif ++ + #if defined(__osf__) || defined(_AIX) + #include + #endif +diff --git a/build/php.m4 b/build/php.m4 +index 142ddf0..a70500e 100644 +--- a/build/php.m4 ++++ b/build/php.m4 +@@ -742,7 +742,7 @@ AC_DEFUN([PHP_REQUIRE_CXX],[ + if test -z "$php_cxx_done"; then + AC_PROG_CXX + AC_PROG_CXXCPP +- PHP_ADD_LIBRARY(stdc++) ++ PHP_ADD_LIBRARY(c++) + php_cxx_done=yes + fi + ]) +@@ -1479,6 +1479,9 @@ int main(void) { + *linux*) + cookie_io_functions_use_off64_t=yes + ;; ++ *wasm*) ++ cookie_io_functions_use_off64_t=yes ++ ;; + *) + cookie_io_functions_use_off64_t=no + ;; +diff --git a/configure.ac b/configure.ac +index d2b4f94..2e4ff8a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -201,6 +201,9 @@ label2: + fi + PHP_SUBST(RE2C_FLAGS) + ++dnl Check if __wasi__ is defined by the compiler ++AC_CHECK_DECLS([__wasi__]) ++ + dnl Platform-specific compile settings. + dnl ---------------------------------------------------------------------------- + +@@ -709,6 +712,9 @@ int main(void) { + *linux*) + ac_cv_func_getaddrinfo=yes + ;; ++ *wasm*) ++ ac_cv_func_getaddrinfo=yes ++ ;; + *) + ac_cv_func_getaddrinfo=no + ;; +@@ -1362,11 +1368,13 @@ else + if test "$fiber_os" = 'mac'; then + AC_DEFINE([_XOPEN_SOURCE], 1, [ ]) + fi +- AC_CHECK_HEADER(ucontext.h, [ +- AC_DEFINE([ZEND_FIBER_UCONTEXT], 1, [ ]) +- ], [ +- AC_MSG_ERROR([fibers not available on this platform]) +- ]) ++ if test "$ac_cv_have_decl___wasi__" != "yes"; then ++ AC_CHECK_HEADER(ucontext.h, [ ++ AC_DEFINE([ZEND_FIBER_UCONTEXT], 1, [ ]) ++ ], [ ++ AC_MSG_ERROR([fibers not available on this platform]) ++ ]) ++ fi + fi + + LIBZEND_BASIC_CHECKS +diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 +index 3b11739..90e79f6 100644 +--- a/ext/curl/config.m4 ++++ b/ext/curl/config.m4 +@@ -11,16 +11,22 @@ if test "$PHP_CURL" != "no"; then + PHP_EVAL_INCLINE($CURL_CFLAGS) + + AC_MSG_CHECKING([for SSL support in libcurl]) +- case "$CURL_FEATURES" in +- *SSL*) +- CURL_SSL=yes +- AC_MSG_RESULT([yes]) +- ;; +- *) +- CURL_SSL=no +- AC_MSG_RESULT([no]) +- ;; +- esac ++ if test "$ac_cv_have_decl___wasi__" == "yes"; then ++ echo "SSL support always enabled for WASIX" ++ CURL_SSL=yes ++ AC_MSG_RESULT([yes]) ++ else ++ case "$CURL_FEATURES" in ++ *SSL*) ++ CURL_SSL=yes ++ AC_MSG_RESULT([yes]) ++ ;; ++ *) ++ CURL_SSL=no ++ AC_MSG_RESULT([no]) ++ ;; ++ esac ++ fi + + if test "$CURL_SSL" = yes; then + save_LDFLAGS="$LDFLAGS" +diff --git a/ext/curl/interface.c b/ext/curl/interface.c +index fe647db..bde42ad 100644 +--- a/ext/curl/interface.c ++++ b/ext/curl/interface.c +@@ -241,7 +241,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo + + /* {{{ PHP_INI_BEGIN */ + PHP_INI_BEGIN() +- PHP_INI_ENTRY("curl.cainfo", "", PHP_INI_SYSTEM, NULL) ++ PHP_INI_ENTRY("curl.cainfo", "/etc/ssl/cacert.pem", PHP_INI_SYSTEM, NULL) + PHP_INI_END() + /* }}} */ + +diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h +index a2c976a..37a5313 100644 +--- a/ext/date/lib/timelib.h ++++ b/ext/date/lib/timelib.h +@@ -109,7 +109,7 @@ typedef unsigned __int64 uint64_t; + # endif + #endif + +-#if (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)) && !defined(TIMELIB_FORCE_LONG32) ++#if (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) || defined(WASIX_64BIT_LONG_PATCH)) && !defined(TIMELIB_FORCE_LONG32) + typedef int64_t timelib_long; + typedef uint64_t timelib_ulong; + # define TIMELIB_LONG_MAX INT64_MAX +diff --git a/ext/fileinfo/libmagic/fsmagic.c b/ext/fileinfo/libmagic/fsmagic.c +index fb37fa7..204a3a0 100644 +--- a/ext/fileinfo/libmagic/fsmagic.c ++++ b/ext/fileinfo/libmagic/fsmagic.c +@@ -167,7 +167,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb) + # endif + #endif + +-#ifdef S_IFIFO ++#if defined(S_IFIFO) && !defined(__wasi__) + case S_IFIFO: + if((ms->flags & MAGIC_DEVICES) != 0) + break; +diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c +index d460298..e8d334f 100644 +--- a/ext/mysqlnd/mysqlnd_connection.c ++++ b/ext/mysqlnd/mysqlnd_connection.c +@@ -521,6 +521,13 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_ + DBG_ENTER("mysqlnd_conn_data::get_scheme"); + #ifndef PHP_WIN32 + if (hostname.l == sizeof("localhost") - 1 && !strncasecmp(hostname.s, "localhost", hostname.l)) { ++#ifdef __wasi__ ++ // No unix socket support in WASIX, use 127.0.0.1 instead ++ if (!port) { ++ port = 3306; ++ } ++ transport.l = mnd_sprintf(&transport.s, 0, "tcp://127.0.0.1:%u", port); ++#else + DBG_INF_FMT("socket=%s", socket_or_pipe->s? socket_or_pipe->s:"n/a"); + if (!socket_or_pipe->s) { + socket_or_pipe->s = "/tmp/mysql.sock"; +@@ -528,6 +535,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_ + } + transport.l = mnd_sprintf(&transport.s, 0, "unix://%s", socket_or_pipe->s); + *unix_socket = TRUE; ++#endif + #else + if (hostname.l == sizeof(".") - 1 && hostname.s[0] == '.') { + /* named pipe in socket */ +diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c +index 91bba23..475e584 100644 +--- a/ext/oci8/oci8_statement.c ++++ b/ext/oci8/oci8_statement.c +@@ -36,7 +36,7 @@ + #include "php_oci8.h" + #include "php_oci8_int.h" + +-#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) ++#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) || defined(WASIX_64BIT_LONG_PATCH) + typedef ub8 oci_phpsized_int; + #else + typedef ub4 oci_phpsized_int; +diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c +index c978859..355194c 100644 +--- a/ext/openssl/openssl.c ++++ b/ext/openssl/openssl.c +@@ -1227,7 +1227,7 @@ static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(zend_long algo) { + /* {{{ INI Settings */ + PHP_INI_BEGIN() + PHP_INI_ENTRY("openssl.cafile", NULL, PHP_INI_PERDIR, NULL) +- PHP_INI_ENTRY("openssl.capath", NULL, PHP_INI_PERDIR, NULL) ++ PHP_INI_ENTRY("openssl.capath", "/etc/ssl/certs", PHP_INI_PERDIR, NULL) + PHP_INI_END() + /* }}} */ + +diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h +index 243163b..bad1ff0 100644 +--- a/ext/pdo_firebird/php_pdo_firebird_int.h ++++ b/ext/pdo_firebird/php_pdo_firebird_int.h +@@ -53,7 +53,7 @@ typedef void (*info_func_t)(char*); + #define min(a,b) ((a)<(b)?(a):(b)) + #endif + +-#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(_WIN64) ++#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(_WIN64) || defined(WASIX_64BIT_LONG_PATCH) + # define PDO_FIREBIRD_HANDLE_INITIALIZER 0U + #else + # define PDO_FIREBIRD_HANDLE_INITIALIZER NULL +diff --git a/ext/pdo_pgsql/config.m4 b/ext/pdo_pgsql/config.m4 +index 80ffd97..112a2be 100644 +--- a/ext/pdo_pgsql/config.m4 ++++ b/ext/pdo_pgsql/config.m4 +@@ -20,7 +20,7 @@ if test "$PHP_PDO_PGSQL" != "no"; then + fi + done + +- if test -n "$PG_CONFIG"; then ++ if test "$PHP_PDO_PGSQL" = "yes" -a -n "$PG_CONFIG"; then + AC_MSG_RESULT([$PG_CONFIG]) + PGSQL_INCLUDE=`$PG_CONFIG --includedir` + PGSQL_LIBDIR=`$PG_CONFIG --libdir` +diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4 +index 669a9f7..9610192 100644 +--- a/ext/pgsql/config.m4 ++++ b/ext/pgsql/config.m4 +@@ -18,7 +18,7 @@ if test "$PHP_PGSQL" != "no"; then + fi + done + +- if test -n "$PG_CONFIG"; then ++ if test "$PHP_PGSQL" = "yes" -a -n "$PG_CONFIG"; then + AC_MSG_RESULT([$PG_CONFIG]) + PGSQL_INCLUDE=`$PG_CONFIG --includedir` + PGSQL_LIBDIR=`$PG_CONFIG --libdir` +diff --git a/ext/random/csprng.c b/ext/random/csprng.c +index bbf12f5..46b22d6 100644 +--- a/ext/random/csprng.c ++++ b/ext/random/csprng.c +@@ -46,7 +46,7 @@ + #if HAVE_SYS_PARAM_H + # include + # if (__FreeBSD__ && __FreeBSD_version > 1200000) || (__DragonFly__ && __DragonFly_version >= 500700) || \ +- (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) ++ (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__wasi__) + # include + # endif + #endif +@@ -98,7 +98,7 @@ PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw) + #else + size_t read_bytes = 0; + # if (defined(__linux__) && defined(SYS_getrandom)) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || \ +- (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) ++ (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__wasi__) + /* Linux getrandom(2) syscall or FreeBSD/DragonFlyBSD/NetBSD getrandom(2) function + * Being a syscall, implemented in the kernel, getrandom offers higher quality output + * compared to the arc4random api albeit a fallback to /dev/urandom is considered. +diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 +index f647a22..7131457 100644 +--- a/ext/standard/config.m4 ++++ b/ext/standard/config.m4 +@@ -319,7 +319,7 @@ dnl + dnl Check if there is a support means of creating a new process and defining + dnl which handles it receives + dnl +-AC_CHECK_FUNCS(fork CreateProcess, [ ++AC_CHECK_FUNCS(fork posix_spawn CreateProcess, [ + php_can_support_proc_open=yes + break + ],[ +@@ -443,6 +443,16 @@ else + AC_MSG_RESULT(no) + fi + ++dnl ++dnl Whether to enable 64-bit long ints when building to WASIX; ++dnl wasm32 uses 32-bit pointers but supports 64-bit int operations. ++dnl ++if test "$ac_cv_have_decl___wasi__" == "yes"; then ++ if test "$WASIX_64BIT_LONG_PATCH" == "yes"; then ++ AC_DEFINE(WASIX_64BIT_LONG_PATCH, 1, [whether to use 64-bit longs for WASIX]) ++ fi ++fi ++ + dnl + dnl Setup extension sources + dnl +diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c +index 9b8ff7e..c92c0a9 100644 +--- a/ext/standard/filestat.c ++++ b/ext/standard/filestat.c +@@ -211,6 +211,12 @@ static zend_result php_disk_free_space(char *path, double *space) /* {{{ */ + + return SUCCESS; + } ++#elif defined(__wasi__) ++{ ++ // Random high number, since WASIX doesn't support retrieving free disk space ++ *space = (double)(1024 * 1024 * 1024); ++ return SUCCESS; ++} + #else /* {{{ if !defined(WINDOWS) */ + { + double bytesfree = 0; +@@ -926,7 +932,9 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) + RETURN_STRING("link"); + } + switch(stat_sb->st_mode & S_IFMT) { ++#ifndef __wasi__ + case S_IFIFO: RETURN_STRING("fifo"); ++#endif + case S_IFCHR: RETURN_STRING("char"); + case S_IFDIR: RETURN_STRING("dir"); + case S_IFBLK: RETURN_STRING("block"); +diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c +index 8622ec1..2700478 100644 +--- a/ext/standard/flock_compat.c ++++ b/ext/standard/flock_compat.c +@@ -26,7 +26,12 @@ PHPAPI int flock(int fd, int operation) + #endif /* !defined(HAVE_FLOCK) */ + + PHPAPI int php_flock(int fd, int operation) +-#ifdef HAVE_STRUCT_FLOCK /* {{{ */ ++#if defined(__wasi__) ++{ ++ errno = 0; ++ return 0; ++} ++#elif defined(HAVE_STRUCT_FLOCK) /* {{{ */ + { + struct flock flck; + int ret; +diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h +index ef3c1cd..c0daf96 100644 +--- a/ext/standard/php_filestat.h ++++ b/ext/standard/php_filestat.h +@@ -37,6 +37,14 @@ PHP_RSHUTDOWN_FUNCTION(filestat); + #define getuid() 1 + #endif + ++#ifdef __wasi__ ++#undef getgid ++#define getgroups(a, b) 0 ++#define getgid() 1 ++#define getuid() 1 ++#define chown(a,b,c) 0 ++#endif ++ + /* Compatibility. */ + typedef size_t php_stat_len; + +diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c +index 8926485..14198cd 100644 +--- a/ext/standard/php_fopen_wrapper.c ++++ b/ext/standard/php_fopen_wrapper.c +@@ -317,7 +317,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa + return NULL; + } + +-#ifdef HAVE_UNISTD_H ++#if defined(HAVE_UNISTD_H) && !defined(__wasi__) + dtablesize = getdtablesize(); + #else + dtablesize = INT_MAX; +diff --git a/main/main.c b/main/main.c +index 60e970b..3d2d322 100644 +--- a/main/main.c ++++ b/main/main.c +@@ -745,8 +745,8 @@ PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("error_append_string", NULL, PHP_INI_ALL, OnUpdateString, error_append_string, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("error_prepend_string", NULL, PHP_INI_ALL, OnUpdateString, error_prepend_string, php_core_globals, core_globals) + +- PHP_INI_ENTRY("SMTP", "localhost",PHP_INI_ALL, NULL) +- PHP_INI_ENTRY("smtp_port", "25", PHP_INI_ALL, NULL) ++ PHP_INI_ENTRY("SMTP", NULL, PHP_INI_ALL, NULL) ++ PHP_INI_ENTRY("smtp_port", NULL, PHP_INI_ALL, NULL) + STD_PHP_INI_BOOLEAN("mail.add_x_header", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_x_header, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("mail.mixed_lf_and_crlf", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_mixed_lf_and_crlf, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals) +diff --git a/main/network.c b/main/network.c +index d4938a4..9c3ba01 100644 +--- a/main/network.c ++++ b/main/network.c +@@ -347,7 +347,10 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, + socklen_t len; + int ret = 0; + ++ // WASIX only supports blocking connects for now ++#ifndef __wasi__ + SET_SOCKET_BLOCKING_MODE(sockfd, orig_flags); ++#endif + + if ((n = connect(sockfd, addr, addrlen)) != 0) { + error = php_socket_errno(); +@@ -430,10 +433,17 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, + } + + ok: ++#ifdef __wasi__ ++ if (asynchronous) { ++ // Switch to non-blocking mode after we're connected ++ SET_SOCKET_BLOCKING_MODE(sockfd, orig_flags); ++ } ++#else + if (!asynchronous) { + /* back to blocking mode */ + RESTORE_SOCKET_BLOCKING_MODE(sockfd, orig_flags); + } ++#endif + + if (error_code) { + *error_code = error; +diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c +index dcea783..5b58d07 100644 +--- a/main/php_open_temporary_file.c ++++ b/main/php_open_temporary_file.c +@@ -247,6 +247,9 @@ PHPAPI const char* php_get_temporary_directory(void) + free(tmp); + return PG(php_sys_temp_dir); + } ++#elif defined(__wasi__) ++ PG(php_sys_temp_dir) = estrdup("/tmp"); ++ return PG(php_sys_temp_dir); + #else + /* On Unix use the (usual) TMPDIR environment variable. */ + { + +diff --git a/ext/pcre/pcre2lib/sljit/sljitUtils.c b/ext/pcre/pcre2lib/sljit/sljitUtils.c +index 0b95dd9..4f82928 100644 +--- a/ext/pcre/pcre2lib/sljit/sljitUtils.c ++++ b/ext/pcre/pcre2lib/sljit/sljitUtils.c +@@ -327,10 +327,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st + aligned_old_start = ((sljit_uw)stack->start) & ~page_align; + + if (aligned_new_start > aligned_old_start) { ++#ifndef __wasi__ + posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED); + #ifdef MADV_FREE + madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE); + #endif /* MADV_FREE */ ++#endif + } + } + #endif /* _WIN32 */ + +diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c +index 6b6c1ea..15974f9 100644 +--- a/Zend/zend_fibers.c ++++ b/Zend/zend_fibers.c +@@ -253,7 +253,7 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size) + return NULL; + } + +-#if defined(MADV_NOHUGEPAGE) ++#if defined(MADV_NOHUGEPAGE) && !defined(__wasi__) + /* Multiple reasons to fail, ignore all errors only needed + * for linux < 6.8 */ + (void) madvise(pointer, alloc_size, MADV_NOHUGEPAGE); diff --git a/pkgs/overlay/packages/php/patches/common/0002-opcache-static-embed.patch b/pkgs/overlay/packages/php/patches/common/0002-opcache-static-embed.patch new file mode 100644 index 00000000..7db96f53 --- /dev/null +++ b/pkgs/overlay/packages/php/patches/common/0002-opcache-static-embed.patch @@ -0,0 +1,660 @@ +diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c +index e3f7ca1..a3a3e5e 100644 +--- a/ext/opcache/ZendAccelerator.c ++++ b/ext/opcache/ZendAccelerator.c +@@ -46,6 +46,7 @@ + #include "zend_accelerator_util_funcs.h" + #include "zend_accelerator_hash.h" + #include "zend_file_cache.h" ++#include "zend_atomic.h" + #include "ext/pcre/php_pcre.h" + #include "ext/standard/md5.h" + #include "ext/hash/php_hash.h" +@@ -81,7 +82,11 @@ typedef int gid_t; + #ifndef ZEND_WIN32 + # include + # include ++ ++#ifndef __wasi__ + # include ++#endif ++ + # include + # include + #endif +@@ -139,6 +144,12 @@ static void preload_restart(void); + # define INCREMENT(v) InterlockedIncrement64(&ZCSG(v)) + # define DECREMENT(v) InterlockedDecrement64(&ZCSG(v)) + # define LOCKVAL(v) (ZCSG(v)) ++#elif defined(__wasi__) ++static uint32_t accel_wasi_mem_usage = 0; ++static uint32_t accel_wasi_restart_in = 0; ++# define INCREMENT(v) __atomic_add_fetch(&accel_wasi_##v, 1, __ATOMIC_SEQ_CST) ++# define DECREMENT(v) __atomic_sub_fetch(&accel_wasi_##v, 1, __ATOMIC_SEQ_CST) ++# define LOCKVAL(v) __atomic_load_n(&accel_wasi_##v, __ATOMIC_SEQ_CST) + #endif + + #define ZCG_KEY_LEN (MAXPATHLEN * 8) +@@ -262,9 +273,9 @@ static ZEND_INI_MH(accel_include_path_on_modify) + + static inline void accel_restart_enter(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + INCREMENT(restart_in); +-#else ++#elif !defined(__wasi__) + struct flock restart_in_progress; + + restart_in_progress.l_type = F_WRLCK; +@@ -281,10 +292,10 @@ static inline void accel_restart_enter(void) + + static inline void accel_restart_leave(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + ZCSG(restart_in_progress) = false; + DECREMENT(restart_in); +-#else ++#elif !defined(__wasi__) + struct flock restart_finished; + + restart_finished.l_type = F_UNLCK; +@@ -302,7 +313,9 @@ static inline void accel_restart_leave(void) + static inline int accel_restart_is_active(void) + { + if (ZCSG(restart_in_progress)) { +-#ifndef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) ++ return LOCKVAL(restart_in) != 0; ++#elif !defined(__wasi__) + struct flock restart_check; + + restart_check.l_type = F_WRLCK; +@@ -320,8 +333,6 @@ static inline int accel_restart_is_active(void) + } else { + return 1; + } +-#else +- return LOCKVAL(restart_in) != 0; + #endif + } + return 0; +@@ -330,11 +341,11 @@ static inline int accel_restart_is_active(void) + /* Creates a read lock for SHM access */ + static inline zend_result accel_activate_add(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + SHM_UNPROTECT(); + INCREMENT(mem_usage); + SHM_PROTECT(); +-#else ++#elif !defined(__wasi__) + struct flock mem_usage_lock; + + mem_usage_lock.l_type = F_RDLCK; +@@ -353,14 +364,14 @@ static inline zend_result accel_activate_add(void) + /* Releases a lock for SHM access */ + static inline void accel_deactivate_sub(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + if (ZCG(counted)) { + SHM_UNPROTECT(); + DECREMENT(mem_usage); + ZCG(counted) = false; + SHM_PROTECT(); + } +-#else ++#elif !defined(__wasi__) + struct flock mem_usage_unlock; + + mem_usage_unlock.l_type = F_UNLCK; +@@ -376,9 +387,9 @@ static inline void accel_deactivate_sub(void) + + static inline void accel_unlock_all(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + accel_deactivate_sub(); +-#else ++#elif !defined(__wasi__) + if (lock_file == -1) { + return; + } +@@ -821,7 +832,7 @@ static void accel_use_shm_interned_strings(void) + HANDLE_UNBLOCK_INTERRUPTIONS(); + } + +-#ifndef ZEND_WIN32 ++#if !defined(ZEND_WIN32) && !defined(__wasi__) + static inline void kill_all_lockers(struct flock *mem_usage_check) + { + int tries; +@@ -888,7 +899,7 @@ static inline void kill_all_lockers(struct flock *mem_usage_check) + + static inline bool accel_is_inactive(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + /* on Windows, we don't need kill_all_lockers() because SAPIs + that work on Windows don't manage child processes (and we + can't do anything about hanging threads anyway); therefore +@@ -899,7 +910,7 @@ static inline bool accel_is_inactive(void) + if (LOCKVAL(mem_usage) == 0) { + return true; + } +-#else ++#elif !defined(__wasi__) + struct flock mem_usage_check; + + mem_usage_check.l_type = F_WRLCK; +@@ -2819,6 +2830,7 @@ static inline zend_result accel_find_sapi(void) + "fuzzer", + "frankenphp", + "ngx-php", ++ "phpix", + NULL + }; + const char **sapi_name; +@@ -2917,6 +2929,10 @@ static zend_result zend_accel_init_shm(void) + ZCSG(start_time) = zend_accel_get_time(); + ZCSG(last_restart_time) = 0; + ZCSG(restart_in_progress) = false; ++#ifdef __wasi__ ++ __atomic_store_n(&accel_wasi_mem_usage, 0, __ATOMIC_SEQ_CST); ++ __atomic_store_n(&accel_wasi_restart_in, 0, __ATOMIC_SEQ_CST); ++#endif + + for (i = 0; i < -HT_MIN_MASK; i++) { + ZCSG(uninitialized_bucket)[i] = HT_INVALID_IDX; +@@ -2927,7 +2943,7 @@ static zend_result zend_accel_init_shm(void) + return SUCCESS; + } + +-static void accel_globals_ctor(zend_accel_globals *accel_globals) ++void accel_globals_ctor(zend_accel_globals *accel_globals) + { + #if defined(COMPILE_DL_OPCACHE) && defined(ZTS) + ZEND_TSRMLS_CACHE_UPDATE(); +@@ -2938,7 +2954,7 @@ static void accel_globals_ctor(zend_accel_globals *accel_globals) + } + + #ifdef ZTS +-static void accel_globals_dtor(zend_accel_globals *accel_globals) ++void accel_globals_dtor(zend_accel_globals *accel_globals) + { + zend_string_free(accel_globals->key); + } +@@ -3112,14 +3128,8 @@ static void accel_move_code_to_huge_pages(void) + # endif /* defined(MAP_HUGETLB) || defined(MADV_HUGEPAGE) */ + #endif /* HAVE_HUGE_CODE_PAGES */ + +-static int accel_startup(zend_extension *extension) ++int accel_startup(zend_extension *extension) + { +-#ifdef ZTS +- accel_globals_id = ts_allocate_id(&accel_globals_id, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); +-#else +- accel_globals_ctor(&accel_globals); +-#endif +- + #ifdef HAVE_JIT + zend_jit_init(); + #endif +@@ -4705,8 +4715,10 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) + + if (!ZCG(accel_directives).preload_user + || !*ZCG(accel_directives).preload_user) { +- + bool sapi_requires_preload_user = !(strcmp(sapi_module.name, "cli") == 0 ++#ifdef __wasi__ ++ || strcmp(sapi_module.name, "cli-server") == 0 ++#endif + || strcmp(sapi_module.name, "phpdbg") == 0); + + if (!sapi_requires_preload_user) { +@@ -4731,6 +4743,7 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) + return SUCCESS; + } + ++#ifndef __wasi__ + *pid = fork(); + if (*pid == -1) { + zend_shared_alloc_unlock(); +@@ -4754,6 +4767,14 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) + } + + return SUCCESS; ++#else ++ // Note: in WASIX, there is only one uid; it has "root" access to everything within the ++ // sandbox, but not the base OS, so it's OK to run everything with that user. That is to ++ // say, we shouldn't need to fork a new process here. ++ // It is also a fact that forking doesn't work under WASIX+EH anyway. ++ zend_accel_error(ACCEL_LOG_FATAL, "Preloading cannot fork to spawn a new process in WASIX"); ++ exit(1); ++#endif + } + #endif /* ZEND_WIN32 */ + +diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h +index a25f9a1..fdc7b25 100644 +--- a/ext/opcache/ZendAccelerator.h ++++ b/ext/opcache/ZendAccelerator.h +@@ -103,6 +103,8 @@ typedef unsigned __int64 accel_time_t; + typedef time_t accel_time_t; + #endif + ++extern zend_extension zend_extension_entry; ++ + typedef enum _zend_accel_restart_reason { + ACCEL_RESTART_OOM, /* restart because of out of memory */ + ACCEL_RESTART_HASH, /* restart because of hash overflow */ +@@ -326,6 +328,11 @@ zend_string* ZEND_FASTCALL accel_new_interned_string(zend_string *str); + + uint32_t zend_accel_get_class_name_map_ptr(zend_string *type_name); + ++void accel_globals_ctor(zend_accel_globals *accel_globals); ++#ifdef ZTS ++void accel_globals_dtor(zend_accel_globals *accel_globals); ++#endif ++ + END_EXTERN_C() + + /* memory write protection */ +diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 +index 6561406..7195473 100644 +--- a/ext/opcache/config.m4 ++++ b/ext/opcache/config.m4 +@@ -27,7 +27,7 @@ PHP_ARG_WITH([capstone],, + if test "$PHP_OPCACHE" != "no"; then + + dnl Always build as shared extension +- ext_shared=yes ++ ext_shared=no + + if test "$PHP_HUGE_CODE_PAGES" = "yes"; then + AC_DEFINE(HAVE_HUGE_CODE_PAGES, 1, [Define to enable copying PHP CODE pages into HUGE PAGES (experimental)]) +@@ -167,62 +167,63 @@ int main(void) { + AC_MSG_RESULT([$have_shm_ipc]) + + AC_MSG_CHECKING(for mmap() using MAP_ANON shared memory support) +- AC_RUN_IFELSE([AC_LANG_SOURCE([[ +-#include +-#include +-#include +-#include +-#include +- +-#ifndef MAP_ANON +-# ifdef MAP_ANONYMOUS +-# define MAP_ANON MAP_ANONYMOUS +-# endif +-#endif +-#ifndef MAP_FAILED +-# define MAP_FAILED ((void*)-1) +-#endif +- +-int main(void) { +- pid_t pid; +- int status; +- char *shm; +- +- shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); +- if (shm == MAP_FAILED) { +- return 1; +- } +- +- strcpy(shm, "hello"); +- +- pid = fork(); +- if (pid < 0) { +- return 5; +- } else if (pid == 0) { +- strcpy(shm, "bye"); +- return 6; +- } +- if (wait(&status) != pid) { +- return 7; +- } +- if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) { +- return 8; +- } +- if (strcmp(shm, "bye") != 0) { +- return 9; +- } +- return 0; +-} +-]])],[have_shm_mmap_anon=yes],[have_shm_mmap_anon=no],[ +- case $host_alias in +- *linux*) +- have_shm_mmap_anon=yes +- ;; +- *) +- have_shm_mmap_anon=no +- ;; +- esac +-]) ++dnl AC_RUN_IFELSE([AC_LANG_SOURCE([[ ++dnl #include ++dnl #include ++dnl #include ++dnl #include ++dnl #include ++dnl ++dnl #ifndef MAP_ANON ++dnl # ifdef MAP_ANONYMOUS ++dnl # define MAP_ANON MAP_ANONYMOUS ++dnl # endif ++dnl #endif ++dnl #ifndef MAP_FAILED ++dnl # define MAP_FAILED ((void*)-1) ++dnl #endif ++dnl ++dnl int main(void) { ++dnl pid_t pid; ++dnl int status; ++dnl char *shm; ++dnl ++dnl shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); ++dnl if (shm == MAP_FAILED) { ++dnl return 1; ++dnl } ++dnl ++dnl strcpy(shm, "hello"); ++dnl ++dnl pid = fork(); ++dnl if (pid < 0) { ++dnl return 5; ++dnl } else if (pid == 0) { ++dnl strcpy(shm, "bye"); ++dnl return 6; ++dnl } ++dnl if (wait(&status) != pid) { ++dnl return 7; ++dnl } ++dnl if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) { ++dnl return 8; ++dnl } ++dnl if (strcmp(shm, "bye") != 0) { ++dnl return 9; ++dnl } ++dnl return 0; ++dnl } ++dnl ]])],[have_shm_mmap_anon=yes],[have_shm_mmap_anon=no],[ ++dnl case $host_alias in ++dnl *linux*) ++dnl have_shm_mmap_anon=yes ++dnl ;; ++dnl *) ++dnl have_shm_mmap_anon=no ++dnl ;; ++dnl esac ++dnl ]) ++ have_shm_mmap_anon=yes + if test "$have_shm_mmap_anon" = "yes"; then + AC_DEFINE(HAVE_SHM_MMAP_ANON, 1, [Define if you have mmap(MAP_ANON) SHM support]) + fi +@@ -319,13 +320,13 @@ int main(void) { + shared_alloc_mmap.c \ + shared_alloc_posix.c \ + $ZEND_JIT_SRC, +- shared,,"$PHP_OPCACHE_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1",,yes) ++ ,,"$PHP_OPCACHE_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1",,yes) + + PHP_ADD_EXTENSION_DEP(opcache, pcre) + +- if test "$have_shm_ipc" != "yes" && test "$have_shm_mmap_posix" != "yes" && test "$have_shm_mmap_anon" != "yes"; then +- AC_MSG_ERROR([No supported shared memory caching support was found when configuring opcache. Check config.log for any errors or missing dependencies.]) +- fi ++ dnl if test "$have_shm_ipc" != "yes" && test "$have_shm_mmap_posix" != "yes" && test "$have_shm_mmap_anon" != "yes"; then ++ dnl AC_MSG_ERROR([No supported shared memory caching support was found when configuring opcache. Check config.log for any errors or missing dependencies.]) ++ dnl fi + + if test "$PHP_OPCACHE_JIT" = "yes"; then + PHP_ADD_BUILD_DIR([$ext_builddir/jit], 1) +diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c +index 9093692..c94da9e 100644 +--- a/ext/opcache/zend_accelerator_module.c ++++ b/ext/opcache/zend_accelerator_module.c +@@ -290,7 +290,7 @@ ZEND_INI_BEGIN() + STD_PHP_INI_ENTRY("opcache.optimization_level" , DEFAULT_OPTIMIZATION_LEVEL , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.optimization_level, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.opt_debug_level" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.opt_debug_level, zend_accel_globals, accel_globals) + STD_PHP_INI_BOOLEAN("opcache.enable_file_override" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_override_enabled, zend_accel_globals, accel_globals) +- STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals) ++ STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals) + +@@ -408,8 +408,18 @@ static ZEND_MINIT_FUNCTION(zend_accelerator) + { + (void)type; /* keep the compiler happy */ + ++ // Run the ctor before registering the INI entries, as that will ++ // read and set the values ++#ifdef ZTS ++ accel_globals_id = ts_allocate_id(&accel_globals_id, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); ++#else ++ accel_globals_ctor(&accel_globals); ++#endif ++ + REGISTER_INI_ENTRIES(); + ++ zend_register_extension(&zend_extension_entry, NULL); ++ + return SUCCESS; + } + +@@ -555,7 +565,7 @@ void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS) + DISPLAY_INI_ENTRIES(); + } + +-static zend_module_entry accel_module_entry = { ++zend_module_entry accel_module_entry = { + STANDARD_MODULE_HEADER, + ACCELERATOR_PRODUCT_NAME, + ext_functions, +@@ -572,7 +582,8 @@ static zend_module_entry accel_module_entry = { + + int start_accel_module(void) + { +- return zend_startup_module(&accel_module_entry); ++ // return zend_startup_module(&accel_module_entry); ++ return SUCCESS; + } + + /* {{{ Get the scripts which are accelerated by ZendAccelerator */ +diff --git a/ext/opcache/zend_accelerator_module.h b/ext/opcache/zend_accelerator_module.h +index 656336e..69d1478 100644 +--- a/ext/opcache/zend_accelerator_module.h ++++ b/ext/opcache/zend_accelerator_module.h +@@ -26,4 +26,7 @@ int start_accel_module(void); + + void zend_accel_override_file_functions(void); + ++extern zend_module_entry accel_module_entry; ++#define phpext_opcache_ptr &accel_module_entry ++ + #endif /* _ZEND_ACCELERATOR_MODULE_H */ +diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c +index edcaf68..011c6a4 100644 +--- a/ext/opcache/zend_file_cache.c ++++ b/ext/opcache/zend_file_cache.c +@@ -96,9 +96,15 @@ static int zend_file_cache_flock(int fd, int op) + #elif defined(HAVE_FLOCK) + # define zend_file_cache_flock flock + #else +-# define LOCK_SH 0 +-# define LOCK_EX 1 +-# define LOCK_UN 2 ++# ifndef LOCK_SH ++# define LOCK_SH 0 ++# endif ++# ifndef LOCK_EX ++# define LOCK_EX 1 ++# endif ++# ifndef LOCK_UN ++# define LOCK_UN 2 ++# endif + static int zend_file_cache_flock(int fd, int type) + { + return 0; +diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c +index a7c7977..c20033b 100644 +--- a/ext/opcache/zend_shared_alloc.c ++++ b/ext/opcache/zend_shared_alloc.c +@@ -29,6 +29,7 @@ + #include + #include "ZendAccelerator.h" + #include "zend_shared_alloc.h" ++#include "zend_atomic.h" + #ifdef HAVE_UNISTD_H + # include + #endif +@@ -63,6 +64,14 @@ int lock_file = -1; + static char lockfile_name[MAXPATHLEN]; + #endif + ++#ifdef __wasi__ ++# ifdef ZTS ++static MUTEX_T zend_shared_alloc_wasi_mutex; ++# else ++static zend_atomic_bool zend_shared_alloc_wasi_lock; ++# endif ++#endif ++ + static const zend_shared_memory_handler_entry handler_table[] = { + #ifdef USE_MMAP + { "mmap", &zend_alloc_mmap_handlers }, +@@ -182,7 +191,15 @@ int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size) + ZSMMG(shared_free) = requested_size - reserved_size; /* goes to tmp_shared_globals.shared_free */ + + #ifndef ZEND_WIN32 ++#ifdef __wasi__ ++#ifdef ZTS ++ zend_shared_alloc_wasi_mutex = tsrm_mutex_alloc(); ++#else ++ ZEND_ATOMIC_BOOL_INIT(&zend_shared_alloc_wasi_lock, false); ++#endif ++#else + zend_shared_alloc_create_lock(ZCG(accel_directives).lockfile_path); ++#endif + #else + zend_shared_alloc_create_lock(); + #endif +@@ -323,10 +340,17 @@ void zend_shared_alloc_shutdown(void) + ZSMMG(shared_segments) = NULL; + g_shared_alloc_handler = NULL; + #ifndef ZEND_WIN32 +- close(lock_file); ++ if (lock_file >= 0) { ++ close(lock_file); ++ lock_file = -1; ++ } + + # ifdef ZTS ++# ifdef __wasi__ ++ tsrm_mutex_free(zend_shared_alloc_wasi_mutex); ++# else + tsrm_mutex_free(zts_lock); ++# endif + # endif + #endif + } +@@ -477,7 +501,16 @@ void zend_shared_alloc_lock(void) + { + ZEND_ASSERT(!ZCG(locked)); + +-#ifndef ZEND_WIN32 ++#ifdef ZEND_WIN32 ++ zend_shared_alloc_lock_win32(); ++#elif defined(__wasi__) ++#ifdef ZTS ++ tsrm_mutex_lock(zend_shared_alloc_wasi_mutex); ++#else ++ while (zend_atomic_bool_exchange_ex(&zend_shared_alloc_wasi_lock, true)) { ++ } ++#endif ++#else + struct flock mem_write_lock; + + mem_write_lock.l_type = F_WRLCK; +@@ -505,8 +538,6 @@ void zend_shared_alloc_lock(void) + } + break; + } +-#else +- zend_shared_alloc_lock_win32(); + #endif + + ZCG(locked) = 1; +@@ -516,7 +547,7 @@ void zend_shared_alloc_unlock(void) + { + ZEND_ASSERT(ZCG(locked)); + +-#ifndef ZEND_WIN32 ++#if !defined(ZEND_WIN32) && !defined(__wasi__) + struct flock mem_write_unlock; + + mem_write_unlock.l_type = F_UNLCK; +@@ -527,15 +558,21 @@ void zend_shared_alloc_unlock(void) + + ZCG(locked) = 0; + +-#ifndef ZEND_WIN32 ++#ifdef ZEND_WIN32 ++ zend_shared_alloc_unlock_win32(); ++#elif defined(__wasi__) ++#ifdef ZTS ++ tsrm_mutex_unlock(zend_shared_alloc_wasi_mutex); ++#else ++ zend_atomic_bool_store_ex(&zend_shared_alloc_wasi_lock, false); ++#endif ++#else + if (fcntl(lock_file, F_SETLK, &mem_write_unlock) == -1) { + zend_accel_error_noreturn(ACCEL_LOG_ERROR, "Cannot remove lock - %s (%d)", strerror(errno), errno); + } + #ifdef ZTS + tsrm_mutex_unlock(zts_lock); + #endif +-#else +- zend_shared_alloc_unlock_win32(); + #endif + } + +diff --git a/main/internal_functions.c.in b/main/internal_functions.c.in +index cef0a43..665d144 100644 +--- a/main/internal_functions.c.in ++++ b/main/internal_functions.c.in +@@ -23,6 +23,9 @@ + #include + #include + ++// TODO: make this automatic in the build instead of hard-coding it!!! ++#include "ext/opcache/zend_accelerator_module.h" ++ + @EXT_INCLUDE_CODE@ + + static zend_module_entry * const php_builtin_extensions[] = { + +diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c +index bf1dd2e..407367d 100644 +--- a/ext/opcache/ZendAccelerator.c ++++ b/ext/opcache/ZendAccelerator.c +@@ -3010,13 +3010,13 @@ static void accel_move_code_to_huge_pages(void) + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); + /* this should never happen? */ + ZEND_ASSERT(ret != MAP_FAILED); +-# ifdef MADV_HUGEPAGE ++# if defined(MADV_HUGEPAGE) && !defined(__wasi__) + if (-1 == madvise(start, size, MADV_HUGEPAGE)) { + memcpy(start, mem, real_size); + mprotect(start, size, PROT_READ | PROT_EXEC); + munmap(mem, size); + zend_error(E_WARNING, + ACCELERATOR_PRODUCT_NAME " huge_code_pages: madvise(HUGEPAGE) failed: %s (%d)", + strerror(errno), errno); + return FAILURE; + } diff --git a/pkgs/overlay/packages/php/patches/common/0003-cli-server-instaboot.patch b/pkgs/overlay/packages/php/patches/common/0003-cli-server-instaboot.patch new file mode 100644 index 00000000..b5e4ab5a --- /dev/null +++ b/pkgs/overlay/packages/php/patches/common/0003-cli-server-instaboot.patch @@ -0,0 +1,365 @@ +diff --git a/Zend/zend_string.h b/Zend/zend_string.h +index ec4bd36..9f147e2 100644 +--- a/Zend/zend_string.h ++++ b/Zend/zend_string.h +@@ -631,6 +631,8 @@ EMPTY_SWITCH_DEFAULT_CASE() + _(ZEND_STR_COUNT, "count") \ + _(ZEND_STR_SENSITIVEPARAMETER, "SensitiveParameter") \ + _(ZEND_STR_CONST_EXPR_PLACEHOLDER, "[constant expression]") \ ++ _(ZEND_STR_INSTABOOT, "x-edge-instaboot") \ ++ _(ZEND_STR_INSTABOOT_SHUTDOWN, "x-wasmer-instaboot-shutdown") \ + + + typedef enum _zend_known_string_id { +diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c +index 64fb9c5..ab6149b 100644 +--- a/sapi/cli/php_cli.c ++++ b/sapi/cli/php_cli.c +@@ -618,7 +618,7 @@ static int do_cli(int argc, char **argv) /* {{{ */ + + file_handle.filename = NULL; + +- zend_try { ++ zend_first_try { + + CG(in_compilation) = 0; /* not initialized but needed for several options */ + +@@ -1334,17 +1334,27 @@ exit_loop: + CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO; + } + +- zend_first_try { + #ifndef PHP_CLI_WIN32_NO_CONSOLE +- if (sapi_module == &cli_sapi_module) { ++ if (sapi_module == &cli_sapi_module) { + #endif +- exit_status = do_cli(argc, argv); ++ exit_status = do_cli(argc, argv); + #ifndef PHP_CLI_WIN32_NO_CONSOLE +- } else { ++ } else { ++ exit_status = do_cli_server(argc, argv); ++#ifdef __wasi__ ++ // If any instaboot requests were received, we're now in warmup mode. We ++ // want to snapshot the process state, and then start another server to ++ // do the actual request handling. ++ if (exit_status == 0 && wasmer_instaboot_warmup_mode == WASMER_INSTABOOT_WARMUP_MODE_IN_PROGRESS) { ++ // Note: we can't asyncify a function that does exception handling, so ++ // the zend_try call was moved into do_cli_server and do_cli. ++ wasmer_instaboot_warmup_mode = WASMER_INSTABOOT_WARMUP_MODE_DONE; ++ wasix_proc_snapshot(); + exit_status = do_cli_server(argc, argv); + } + #endif +- } zend_end_try(); ++ } ++#endif + out: + if (ini_path_override) { + free(ini_path_override); +diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c +index 19edc0c..e452de0 100644 +--- a/sapi/cli/php_cli_server.c ++++ b/sapi/cli/php_cli_server.c +@@ -36,6 +36,8 @@ + #include + #endif + ++#include ++ + #if HAVE_SYS_TIME_H + #include + #endif +@@ -117,6 +119,10 @@ static pid_t *php_cli_server_workers; + static zend_long php_cli_server_workers_max; + #endif + ++#ifdef __wasi__ ++int wasmer_instaboot_warmup_mode = WASMER_INSTABOOT_WARMUP_MODE_NONE; ++#endif ++ + static zend_string* cli_concat_persistent_zstr_with_char(zend_string *old_str, const char *at, size_t length); + + typedef struct php_cli_server_poller { +@@ -728,6 +734,23 @@ static void sapi_cli_server_register_variables(zval *track_vars_array) /* {{{ */ + zend_string_release_ex(tmp, /* persistent */ false); + } + ++ // Set https protocol to true if x-forwarded-proto == "https" ++ { ++ zval *x_forwarded_proto; ++ if (NULL != (x_forwarded_proto = zend_hash_str_find( ++ &client->request.headers, ++ "x-forwarded-proto", ++ sizeof("x-forwarded-proto") - 1)) && ++ Z_TYPE(*x_forwarded_proto) == IS_STRING) ++ { ++ if (strncmp(Z_STRVAL_P(x_forwarded_proto), "https", strlen("https")) == 0) ++ { ++ sapi_cli_server_register_known_var_char(track_vars_array, ++ "HTTPS", strlen("HTTPS"), "1", strlen("1")); ++ } ++ } ++ } ++ + sapi_cli_server_register_known_var_str(track_vars_array, + "REQUEST_URI", strlen("REQUEST_URI"), client->request.request_uri); + sapi_cli_server_register_known_var_char(track_vars_array, +@@ -2202,6 +2225,21 @@ static zend_result php_cli_server_begin_send_static(php_cli_server *server, php_ + return FAILURE; + } + append_essential_headers(&buffer, client, 1, NULL); ++ ++ // Append Last-Modified ++ zend_stat_t file_info; ++ if (zend_fstat(fd, &file_info) != -1) { ++ zend_string *dt = php_format_date("D, d M Y H:i:s", sizeof("D, d M Y H:i:s") - 1, file_info.st_mtime, 0); ++ smart_str_appends_ex(&buffer, "Last-Modified: ", 1); ++ smart_str_append_ex(&buffer, dt, 1); ++ smart_str_appends_ex(&buffer, " GMT\r\n", 1); ++ zend_string_release_ex(dt, 0); ++ ++ if (file_info.st_mtime > 0) { ++ smart_str_appends_ex(&buffer, "Cache-Control: public, max-age=31536000\r\n", 1); ++ } ++ } ++ + if (mime_type) { + smart_str_appendl_ex(&buffer, "Content-Type: ", sizeof("Content-Type: ") - 1, 1); + smart_str_appends_ex(&buffer, mime_type, 1); +@@ -2315,6 +2353,40 @@ static zend_result php_cli_server_dispatch(php_cli_server *server, php_cli_serve + is_static_file = 1; + } + ++#ifdef __wasi__ ++ if (wasmer_instaboot_warmup_mode < WASMER_INSTABOOT_WARMUP_MODE_DONE) { ++ switch (wasmer_instaboot_warmup_mode) ++ { ++ case WASMER_INSTABOOT_WARMUP_MODE_NONE: ++ if (zend_hash_find(&client->request.headers, ZSTR_KNOWN(ZEND_STR_INSTABOOT)) == NULL) { ++ // non-instaboot request; assume we're not warming up and disable these checks ++ wasmer_instaboot_warmup_mode = WASMER_INSTABOOT_WARMUP_MODE_DONE; ++ break; ++ } else { ++ php_cli_server_logf(PHP_CLI_SERVER_LOG_MESSAGE, "Going into instaboot warmup mode"); ++ wasmer_instaboot_warmup_mode = WASMER_INSTABOOT_WARMUP_MODE_IN_PROGRESS; ++ // and fall through ++ } ++ ++ case WASMER_INSTABOOT_WARMUP_MODE_IN_PROGRESS: ++ if (zend_hash_find(&client->request.headers, ZSTR_KNOWN(ZEND_STR_INSTABOOT)) == NULL) { ++ // Nothing to do here but warn people ++ php_cli_server_logf(PHP_CLI_SERVER_LOG_ERROR, "Non-instaboot request received in instaboot warmup mode"); ++ } ++ if (zend_hash_find(&client->request.headers, ZSTR_KNOWN(ZEND_STR_INSTABOOT_SHUTDOWN)) != NULL) { ++ // We stay in IN_PROGRESS mode to let php_cli.c know about the warmup requests. It'll ++ // switch to DONE mode and restart the server after snapshotting. ++ php_cli_server_logf(PHP_CLI_SERVER_LOG_MESSAGE, "Shutting down warmup mode server"); ++ server->is_running = 0; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ } ++#endif ++ + if (server->router || !is_static_file) { + if (FAILURE == php_cli_server_request_startup(server, client)) { + php_cli_server_request_shutdown(server, client); +@@ -2823,95 +2895,97 @@ int do_cli_server(int argc, char **argv) /* {{{ */ + const char *router = NULL; + char document_root_buf[MAXPATHLEN]; + +- while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2))!=-1) { +- switch (c) { +- case 'S': +- server_bind_address = php_optarg; +- break; +- case 't': +-#ifndef PHP_WIN32 +- document_root = php_optarg; +-#else +- k = strlen(php_optarg); +- if (k + 1 > MAXPATHLEN) { +- fprintf(stderr, "Document root path is too long.\n"); +- return 1; +- } +- memmove(document_root_tmp, php_optarg, k + 1); +- /* Clean out any trailing garbage that might have been passed +- from a batch script. */ +- do { +- document_root_tmp[k] = '\0'; +- k--; +- } while ('"' == document_root_tmp[k] || ' ' == document_root_tmp[k]); +- document_root = document_root_tmp; +-#endif +- break; +- case 'q': +- if (php_cli_server_log_level > 1) { +- php_cli_server_log_level--; +- } +- break; ++ zend_first_try { ++ while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2))!=-1) { ++ switch (c) { ++ case 'S': ++ server_bind_address = php_optarg; ++ break; ++ case 't': ++ #ifndef PHP_WIN32 ++ document_root = php_optarg; ++ #else ++ k = strlen(php_optarg); ++ if (k + 1 > MAXPATHLEN) { ++ fprintf(stderr, "Document root path is too long.\n"); ++ return 1; ++ } ++ memmove(document_root_tmp, php_optarg, k + 1); ++ /* Clean out any trailing garbage that might have been passed ++ from a batch script. */ ++ do { ++ document_root_tmp[k] = '\0'; ++ k--; ++ } while ('"' == document_root_tmp[k] || ' ' == document_root_tmp[k]); ++ document_root = document_root_tmp; ++ #endif ++ break; ++ case 'q': ++ if (php_cli_server_log_level > 1) { ++ php_cli_server_log_level--; ++ } ++ break; ++ } + } +- } + +- if (document_root) { +- zend_stat_t sb = {0}; ++ if (document_root) { ++ zend_stat_t sb = {0}; + +- if (php_sys_stat(document_root, &sb)) { +- fprintf(stderr, "Directory %s does not exist.\n", document_root); +- return 1; +- } +- if (!S_ISDIR(sb.st_mode)) { +- fprintf(stderr, "%s is not a directory.\n", document_root); +- return 1; +- } +- if (VCWD_REALPATH(document_root, document_root_buf)) { +- document_root = document_root_buf; +- } +- } else { +- char *ret = NULL; ++ if (php_sys_stat(document_root, &sb)) { ++ fprintf(stderr, "Directory %s does not exist.\n", document_root); ++ return 1; ++ } ++ if (!S_ISDIR(sb.st_mode)) { ++ fprintf(stderr, "%s is not a directory.\n", document_root); ++ return 1; ++ } ++ if (VCWD_REALPATH(document_root, document_root_buf)) { ++ document_root = document_root_buf; ++ } ++ } else { ++ char *ret = NULL; + +-#if HAVE_GETCWD +- ret = VCWD_GETCWD(document_root_buf, MAXPATHLEN); +-#elif HAVE_GETWD +- ret = VCWD_GETWD(document_root_buf); +-#endif +- document_root = ret ? document_root_buf: "."; +- } ++ #if HAVE_GETCWD ++ ret = VCWD_GETCWD(document_root_buf, MAXPATHLEN); ++ #elif HAVE_GETWD ++ ret = VCWD_GETWD(document_root_buf); ++ #endif ++ document_root = ret ? document_root_buf: "."; ++ } + +- if (argc > php_optind) { +- router = argv[php_optind]; +- } ++ if (argc > php_optind) { ++ router = argv[php_optind]; ++ } + +- if (FAILURE == php_cli_server_ctor(&server, server_bind_address, document_root, router)) { +- return 1; +- } +- sapi_module.phpinfo_as_text = 0; ++ if (FAILURE == php_cli_server_ctor(&server, server_bind_address, document_root, router)) { ++ return 1; ++ } ++ sapi_module.phpinfo_as_text = 0; + +- { +- r = 0; +- bool ipv6 = strchr(server.host, ':'); +- php_cli_server_logf( +- PHP_CLI_SERVER_LOG_PROCESS, +- "PHP %s Development Server (http://%s%s%s:%d) started", +- PHP_VERSION, ipv6 ? "[" : "", server.host, +- ipv6 ? "]" : "", server.port); +- } ++ { ++ r = 0; ++ bool ipv6 = strchr(server.host, ':'); ++ php_cli_server_logf( ++ PHP_CLI_SERVER_LOG_PROCESS, ++ "PHP %s Development Server (http://%s%s%s:%d) started", ++ PHP_VERSION, ipv6 ? "[" : "", server.host, ++ ipv6 ? "]" : "", server.port); ++ } + +-#if defined(SIGINT) +- signal(SIGINT, php_cli_server_sigint_handler); +-#endif ++ #if defined(SIGINT) ++ signal(SIGINT, php_cli_server_sigint_handler); ++ #endif + +-#if defined(SIGPIPE) +- signal(SIGPIPE, SIG_IGN); +-#endif ++ #if defined(SIGPIPE) ++ signal(SIGPIPE, SIG_IGN); ++ #endif + +- zend_signal_init(); ++ zend_signal_init(); + +- if (SUCCESS != php_cli_server_do_event_loop(&server)) { +- r = 1; +- } +- php_cli_server_dtor(&server); ++ if (SUCCESS != php_cli_server_do_event_loop(&server)) { ++ r = 1; ++ } ++ php_cli_server_dtor(&server); ++ } zend_end_try() + return r; + } /* }}} */ +diff --git a/sapi/cli/php_cli_server.h b/sapi/cli/php_cli_server.h +index 2440a5b..9cde327 100644 +--- a/sapi/cli/php_cli_server.h ++++ b/sapi/cli/php_cli_server.h +@@ -19,6 +19,13 @@ + + #include "SAPI.h" + ++#ifdef __wasi__ ++extern int wasmer_instaboot_warmup_mode; ++#define WASMER_INSTABOOT_WARMUP_MODE_NONE 0 ++#define WASMER_INSTABOOT_WARMUP_MODE_IN_PROGRESS 1 ++#define WASMER_INSTABOOT_WARMUP_MODE_DONE 2 ++#endif ++ + extern const zend_function_entry server_additional_functions[]; + extern sapi_module_struct cli_server_sapi_module; + extern int do_cli_server(int argc, char **argv); diff --git a/pkgs/overlay/packages/php/patches/common/0004-openssl-no-sock.patch b/pkgs/overlay/packages/php/patches/common/0004-openssl-no-sock.patch new file mode 100644 index 00000000..53a1c59c --- /dev/null +++ b/pkgs/overlay/packages/php/patches/common/0004-openssl-no-sock.patch @@ -0,0 +1,20 @@ +diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c +--- a/ext/openssl/xp_ssl.c ++++ b/ext/openssl/xp_ssl.c +@@ -1813,9 +1813,15 @@ + } else { + SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream); + } + ++ #ifdef OPENSSL_NO_SOCK ++ php_error_docref(NULL, E_WARNING, ++ "OpenSSL socket BIO support is unavailable on WASIX buuhu"); ++ return FAILURE; ++ #else + if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) { + php_openssl_handle_ssl_error(stream, 0, 1); + } ++ #endif + + #ifdef HAVE_TLS_SNI + /* Enable server-side SNI */ diff --git a/pkgs/overlay/packages/php/patches/extensions/imagick-bundled-build.patch b/pkgs/overlay/packages/php/patches/extensions/imagick-bundled-build.patch new file mode 100644 index 00000000..376efad7 --- /dev/null +++ b/pkgs/overlay/packages/php/patches/extensions/imagick-bundled-build.patch @@ -0,0 +1,27 @@ +diff --git a/ext/imagick/config.m4 b/ext/imagick/config.m4 +index 3c6c077..69c0c1e 100644 +--- a/ext/imagick/config.m4 ++++ b/ext/imagick/config.m4 +@@ -14,7 +14,8 @@ m4_include(ifdef('PHP_IMAGICK_STATIC',PHP_EXT_BUILDDIR(imagick)[/],)[imagemagick + + # This line checks that ImageMagick is available, and + # meets our minimum supported version. TODO change to 6.7.0 +-IM_FIND_IMAGEMAGICK([6.5.3], [$PHP_IMAGICK]) ++# WASIX passes ImageMagick paths explicitly via IM_IMAGEMAGICK_{CFLAGS,LIBS}. ++# IM_FIND_IMAGEMAGICK([6.5.3], [$PHP_IMAGICK]) + + # + # PHP minimum version +diff --git a/ext/imagick/php_imagick.h b/ext/imagick/php_imagick.h +index 120e0a4..aa0e711 100644 +--- a/ext/imagick/php_imagick.h ++++ b/ext/imagick/php_imagick.h +@@ -25,7 +25,7 @@ + #define PHP_IMAGICK_EXTNAME "imagick" + // The version is deliberately left as 'PACKAGE_VERSION' in source code. + // It is only replaced with the actual version number that packaged through pecl.php.net +-#define PHP_IMAGICK_VERSION "@PACKAGE_VERSION@" ++#define PHP_IMAGICK_VERSION "3.8.1" + #define PHP_IMAGICK_EXTNUM 30801 + + /* Import configure options when building diff --git a/pkgs/overlay/packages/php/patches/php85/0001-wasix-core-support.patch b/pkgs/overlay/packages/php/patches/php85/0001-wasix-core-support.patch new file mode 100644 index 00000000..3f4318e9 --- /dev/null +++ b/pkgs/overlay/packages/php/patches/php85/0001-wasix-core-support.patch @@ -0,0 +1,522 @@ +diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c +index f3dfe0f9..814cf9bb 100644 +--- a/Zend/zend_alloc.c ++++ b/Zend/zend_alloc.c +@@ -728,6 +728,7 @@ static zend_always_inline int zend_mm_bitset_is_free_range(zend_mm_bitset *bitse + + static zend_always_inline void zend_mm_hugepage(void* ptr, size_t size) + { ++#ifndef __wasi__ + #if defined(MADV_HUGEPAGE) + (void)madvise(ptr, size, MADV_HUGEPAGE); + #elif defined(HAVE_MEMCNTL) +@@ -736,6 +737,7 @@ static zend_always_inline void zend_mm_hugepage(void* ptr, size_t size) + #elif !defined(VM_FLAGS_SUPERPAGE_SIZE_2MB) && !defined(MAP_ALIGNED_SUPER) + zend_error_noreturn(E_ERROR, "huge_pages: thp unsupported on this platform"); + #endif ++#endif + } + + static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) +@@ -3279,9 +3281,15 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) + char *tmp; + + #if ZEND_MM_CUSTOM ++#ifndef __wasi__ + tmp = getenv("USE_ZEND_ALLOC"); + if (tmp && !ZEND_ATOL(tmp)) { ++#endif ++#ifdef __wasi__ ++ bool tracked = true; ++#else + bool tracked = (tmp = getenv("USE_TRACKED_ALLOC")) && ZEND_ATOL(tmp); ++#endif + zend_mm_heap *mm_heap = alloc_globals->mm_heap = malloc(sizeof(zend_mm_heap)); + memset(mm_heap, 0, sizeof(zend_mm_heap)); + mm_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD; +@@ -3302,7 +3310,9 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) + zend_hash_init(mm_heap->tracked_allocs, 1024, NULL, NULL, 1); + } + return; ++#ifndef __wasi__ + } ++#endif + #endif + + tmp = getenv("USE_ZEND_ALLOC_HUGE_PAGES"); +diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c +index a4e5a38f..347680a7 100644 +--- a/Zend/zend_extensions.c ++++ b/Zend/zend_extensions.c +@@ -28,7 +28,7 @@ static int last_resource_number; + + zend_result zend_load_extension(const char *path) + { +-#if ZEND_EXTENSIONS_SUPPORT ++#if ZEND_EXTENSIONS_SUPPORT && !defined(__wasi__) + DL_HANDLE handle; + + handle = DL_LOAD(path); +@@ -62,7 +62,7 @@ zend_result zend_load_extension(const char *path) + + zend_result zend_load_extension_handle(DL_HANDLE handle, const char *path) + { +-#if ZEND_EXTENSIONS_SUPPORT ++#if ZEND_EXTENSIONS_SUPPORT && !defined(__wasi__) + zend_extension *new_extension; + + const zend_extension_version_info *extension_version_info = (const zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info"); +@@ -228,7 +228,7 @@ void zend_shutdown_extensions(void) + + void zend_extension_dtor(zend_extension *extension) + { +-#if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG ++#if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG && !defined(__wasi__) + if (extension->handle && !getenv("ZEND_DONT_UNLOAD_MODULES")) { + DL_UNLOAD(extension->handle); + } +diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c +index d571a622..4906e4cb 100644 +--- a/Zend/zend_fibers.c ++++ b/Zend/zend_fibers.c +@@ -261,7 +261,7 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size) + + zend_mmap_set_name(pointer, alloc_size, "zend_fiber_stack"); + +-# if ZEND_FIBER_GUARD_PAGES ++# if ZEND_FIBER_GUARD_PAGES && !defined(__wasi__) + if (mprotect(pointer, ZEND_FIBER_GUARD_PAGES * page_size, PROT_NONE) < 0) { + zend_throw_exception_ex(NULL, 0, "Fiber stack protect failed: mprotect failed: %s (%d)", strerror(errno), errno); + munmap(pointer, alloc_size); +@@ -436,7 +436,7 @@ ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void * + makecontext(handle, (void (*)(void)) zend_fiber_trampoline, 0); + + context->handle = handle; +-#else ++#elif !defined(__wasi__) + // Stack grows down, calculate the top of the stack. make_fcontext then shifts pointer to lower 16-byte boundary. + void *stack = (void *) ((uintptr_t) context->stack->pointer + context->stack->size); + +@@ -449,6 +449,8 @@ ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void * + + context->handle = make_fcontext(stack, context->stack->size, zend_fiber_trampoline); + ZEND_ASSERT(context->handle != NULL && "make_fcontext() never returns NULL"); ++#else ++ return FAILURE; + #endif + + context->kind = kind; +@@ -523,16 +525,18 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer) + + /* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */ + *transfer = *transfer_data; +-#else ++#elif !defined(__wasi__) + boost_context_data data = jump_fcontext(to->handle, transfer); + + /* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */ + *transfer = *data.transfer; ++#else ++ return; + #endif + + to = transfer->context; + +-#ifndef ZEND_FIBER_UCONTEXT ++#if !defined(ZEND_FIBER_UCONTEXT) && !defined(__wasi__) + /* Get the context that resumed us and update its handle to allow for symmetric coroutines. */ + to->handle = data.handle; + #endif +diff --git a/Zend/zend_long.h b/Zend/zend_long.h +index 3796f1c5..ea979e35 100644 +--- a/Zend/zend_long.h ++++ b/Zend/zend_long.h +@@ -23,7 +23,7 @@ + #include + + /* This is the heart of the whole int64 enablement in zval. */ +-#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) ++#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) || defined(WASIX_64BIT_LONG_PATCH) + # define ZEND_ENABLE_ZVAL_LONG64 1 + #endif + +diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h +index 6546ebfb..7c63a347 100644 +--- a/Zend/zend_portability.h ++++ b/Zend/zend_portability.h +@@ -195,6 +195,9 @@ + # define DL_UNLOAD FreeLibrary + # define DL_HANDLE HMODULE + # define ZEND_EXTENSIONS_SUPPORT 1 ++#elif defined(__wasi__) ++# define DL_HANDLE void * ++# define ZEND_EXTENSIONS_SUPPORT 1 + #else + # define DL_HANDLE void * + # define ZEND_EXTENSIONS_SUPPORT 0 +diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h +index 21735f6d..a149429f 100644 +--- a/Zend/zend_virtual_cwd.h ++++ b/Zend/zend_virtual_cwd.h +@@ -59,6 +59,10 @@ + #include + #endif + ++#ifdef __wasi__ ++#define chown(a,b,c) 0 ++#endif ++ + #if defined(__osf__) || defined(_AIX) + #include + #endif +diff --git a/build/php.m4 b/build/php.m4 +index 0a2169f6..bbbaba5a 100644 +--- a/build/php.m4 ++++ b/build/php.m4 +@@ -734,7 +734,7 @@ AC_DEFUN([PHP_REQUIRE_CXX], [ + AS_VAR_IF([php_cxx_done],, [ + AC_PROG_CXX + AC_PROG_CXXCPP +- PHP_ADD_LIBRARY([stdc++]) ++ PHP_ADD_LIBRARY([c++]) + php_cxx_done=yes + ]) + ]) +@@ -1366,7 +1366,7 @@ int main(void) { + [php_cv_type_cookie_off64_t=yes], + [php_cv_type_cookie_off64_t=no], + [AS_CASE([$host_alias], +- [*linux*], [php_cv_type_cookie_off64_t=yes], ++ [*linux*|*wasm*], [php_cv_type_cookie_off64_t=yes], + [php_cv_type_cookie_off64_t=no])] + )]) + AS_VAR_IF([php_cv_type_cookie_off64_t], [yes], +diff --git a/configure.ac b/configure.ac +index f96be617..49a3a6d4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -190,6 +190,8 @@ AS_VAR_IF([php_cv_have_re2c_cgoto], [yes], + [AS_VAR_APPEND([RE2C_FLAGS], [" -g"])]) + ]) + ++AC_CHECK_DECLS([__wasi__]) ++ + dnl Platform-specific compile settings. + dnl ---------------------------------------------------------------------------- + +@@ -672,7 +674,7 @@ int main(void) { + [php_cv_func_getaddrinfo=yes], + [php_cv_func_getaddrinfo=no], + [AS_CASE([$host_alias], +- [*linux*|*midipix], [php_cv_func_getaddrinfo=yes], ++ [*linux*|*midipix|*wasm*], [php_cv_func_getaddrinfo=yes], + [php_cv_func_getaddrinfo=no])])], + [php_cv_func_getaddrinfo=no])]) + AS_VAR_IF([php_cv_func_getaddrinfo], [yes], +@@ -1297,10 +1299,12 @@ if test "$fiber_asm" = 'yes'; then + AC_MSG_RESULT([$fiber_asm_file]) + else + AS_VAR_IF([fiber_os], [mac], [AC_DEFINE([_XOPEN_SOURCE], [1], [ ])]) +- AC_CHECK_HEADER([ucontext.h], +- [AC_DEFINE([ZEND_FIBER_UCONTEXT], [1], +- [Define to 1 if Zend fiber uses ucontext instead of boost context.])], +- [AC_MSG_FAILURE([fibers not available on this platform])]) ++ AS_IF([test "$ac_cv_have_decl___wasi__" != yes], [ ++ AC_CHECK_HEADER([ucontext.h], ++ [AC_DEFINE([ZEND_FIBER_UCONTEXT], [1], ++ [Define to 1 if Zend fiber uses ucontext instead of boost context.])], ++ [AC_MSG_FAILURE([fibers not available on this platform])]) ++ ]) + fi + + ZEND_INIT +diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 +index bbb41fdd..58e81d82 100644 +--- a/ext/curl/config.m4 ++++ b/ext/curl/config.m4 +@@ -11,7 +11,11 @@ if test "$PHP_CURL" != "no"; then + PHP_EVAL_INCLINE([$CURL_CFLAGS]) + + AC_MSG_CHECKING([for SSL support in libcurl]) +- AS_CASE([$CURL_FEATURES], [*SSL*], [CURL_SSL=yes], [CURL_SSL=no]) ++ AS_IF([test "$ac_cv_have_decl___wasi__" = yes], [ ++ CURL_SSL=yes ++ ], [ ++ AS_CASE([$CURL_FEATURES], [*SSL*], [CURL_SSL=yes], [CURL_SSL=no]) ++ ]) + AC_MSG_RESULT([$CURL_SSL]) + + AS_IF([test "x$PHP_THREAD_SAFETY" = xyes && test "x$CURL_SSL" = xyes], +diff --git a/ext/curl/interface.c b/ext/curl/interface.c +index 5f69beac..19c161c4 100644 +--- a/ext/curl/interface.c ++++ b/ext/curl/interface.c +@@ -223,7 +223,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo + + /* {{{ PHP_INI_BEGIN */ + PHP_INI_BEGIN() +- PHP_INI_ENTRY("curl.cainfo", "", PHP_INI_SYSTEM, NULL) ++ PHP_INI_ENTRY("curl.cainfo", "/etc/ssl/cacert.pem", PHP_INI_SYSTEM, NULL) + PHP_INI_END() + /* }}} */ + +diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h +index acae8e32..7d4027ca 100644 +--- a/ext/date/lib/timelib.h ++++ b/ext/date/lib/timelib.h +@@ -109,7 +109,7 @@ typedef unsigned __int64 uint64_t; + # endif + #endif + +-#if (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)) && !defined(TIMELIB_FORCE_LONG32) ++#if (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64) || defined(WASIX_64BIT_LONG_PATCH)) && !defined(TIMELIB_FORCE_LONG32) + typedef int64_t timelib_long; + typedef uint64_t timelib_ulong; + # define TIMELIB_LONG_MAX INT64_MAX +diff --git a/ext/fileinfo/libmagic/fsmagic.c b/ext/fileinfo/libmagic/fsmagic.c +index 661fdb9f..14024933 100644 +--- a/ext/fileinfo/libmagic/fsmagic.c ++++ b/ext/fileinfo/libmagic/fsmagic.c +@@ -167,7 +167,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb) + # endif + #endif + +-#ifdef S_IFIFO ++#if defined(S_IFIFO) && !defined(__wasi__) + case S_IFIFO: + if((ms->flags & MAGIC_DEVICES) != 0) + break; +diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c +index 9065aaf5..c64102bb 100644 +--- a/ext/mysqlnd/mysqlnd_connection.c ++++ b/ext/mysqlnd/mysqlnd_connection.c +@@ -526,6 +526,13 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_ + DBG_ENTER("mysqlnd_conn_data::get_scheme"); + #ifndef PHP_WIN32 + if (hostname.l == sizeof("localhost") - 1 && !strncasecmp(hostname.s, "localhost", hostname.l)) { ++#ifdef __wasi__ ++ // No unix socket support in WASIX, use 127.0.0.1 instead ++ if (!port) { ++ port = 3306; ++ } ++ transport.l = mnd_sprintf(&transport.s, 0, "tcp://127.0.0.1:%u", port); ++#else + DBG_INF_FMT("socket=%s", socket_or_pipe->s? socket_or_pipe->s:"n/a"); + if (!socket_or_pipe->s) { + socket_or_pipe->s = "/tmp/mysql.sock"; +@@ -533,6 +540,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_ + } + transport.l = mnd_sprintf(&transport.s, 0, "unix://%s", socket_or_pipe->s); + *unix_socket = TRUE; ++#endif + #else + if (hostname.l == sizeof(".") - 1 && hostname.s[0] == '.') { + /* named pipe in socket */ +diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h +index a62c152f..350f1c17 100644 +--- a/ext/pdo_firebird/php_pdo_firebird_int.h ++++ b/ext/pdo_firebird/php_pdo_firebird_int.h +@@ -47,7 +47,7 @@ + #define min(a,b) ((a)<(b)?(a):(b)) + #endif + +-#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(_WIN64) ++#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(_WIN64) || defined(WASIX_64BIT_LONG_PATCH) + # define PDO_FIREBIRD_HANDLE_INITIALIZER 0U + #else + # define PDO_FIREBIRD_HANDLE_INITIALIZER NULL +diff --git a/ext/random/csprng.c b/ext/random/csprng.c +index 73832d7d..06ebb5b9 100644 +--- a/ext/random/csprng.c ++++ b/ext/random/csprng.c +@@ -48,7 +48,7 @@ + #ifdef HAVE_SYS_PARAM_H + # include + # if (defined(__FreeBSD__) && __FreeBSD_version > 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || \ +- (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) ++ (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) || defined(__wasi__) + # include + # endif + #endif +@@ -100,7 +100,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes_ex(void *bytes, size_ + #else + size_t read_bytes = 0; + # if (defined(__linux__) && defined(SYS_getrandom)) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || \ +- (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) ++ (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) || defined(__wasi__) + /* Linux getrandom(2) syscall or FreeBSD/DragonFlyBSD/NetBSD getrandom(2) function + * Being a syscall, implemented in the kernel, getrandom offers higher quality output + * compared to the arc4random api albeit a fallback to /dev/urandom is considered. +diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 +index ef6b3c5a..300846b0 100644 +--- a/ext/standard/config.m4 ++++ b/ext/standard/config.m4 +@@ -276,7 +276,7 @@ dnl + dnl Check if there is a support means of creating a new process and defining + dnl which handles it receives + dnl +-AC_CHECK_FUNCS([fork CreateProcess], ++AC_CHECK_FUNCS([fork posix_spawn CreateProcess], + [php_can_support_proc_open=yes; break;], + [php_can_support_proc_open=no]) + AC_MSG_CHECKING([if your OS can spawn processes with inherited handles]) +@@ -384,6 +384,16 @@ AS_VAR_IF([php_cv_func_getifaddrs], [yes], + [Define to 1 if you have the 'getifaddrs' function.])]) + + dnl ++dnl ++dnl Whether to enable 64-bit long ints when building to WASIX; ++dnl wasm32 uses 32-bit pointers but supports 64-bit int operations. ++dnl ++if test "$ac_cv_have_decl___wasi__" = yes; then ++ if test "$WASIX_64BIT_LONG_PATCH" = yes; then ++ AC_DEFINE(WASIX_64BIT_LONG_PATCH, 1, [whether to use 64-bit longs for WASIX]) ++ fi ++fi ++ + dnl Setup extension sources + dnl + PHP_NEW_EXTENSION([standard], m4_normalize([ +diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c +index 85c2517e..7f185494 100644 +--- a/ext/standard/filestat.c ++++ b/ext/standard/filestat.c +@@ -236,6 +236,9 @@ static zend_result php_disk_free_space(char *path, double *space) /* {{{ */ + return FAILURE; + } + bytesfree = (((double)buf.f_bsize) * ((double)buf.f_bavail)); ++#elif defined(__wasi__) ++ *space = (double)(1024 * 1024 * 1024); ++ return SUCCESS; + #endif + + *space = bytesfree; +diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c +index b7e1df7c..9fbdc1e7 100644 +--- a/ext/standard/flock_compat.c ++++ b/ext/standard/flock_compat.c +@@ -26,7 +26,12 @@ PHPAPI int flock(int fd, int operation) + #endif /* !defined(HAVE_FLOCK) */ + + PHPAPI int php_flock(int fd, int operation) +-#ifdef HAVE_STRUCT_FLOCK /* {{{ */ ++#if defined(__wasi__) ++{ ++ errno = 0; ++ return 0; ++} ++#elif defined(HAVE_STRUCT_FLOCK) /* {{{ */ + { + struct flock flck; + int ret; +diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h +index ef3c1cd6..c0daf967 100644 +--- a/ext/standard/php_filestat.h ++++ b/ext/standard/php_filestat.h +@@ -37,6 +37,14 @@ PHP_RSHUTDOWN_FUNCTION(filestat); + #define getuid() 1 + #endif + ++#ifdef __wasi__ ++#undef getgid ++#define getgroups(a, b) 0 ++#define getgid() 1 ++#define getuid() 1 ++#define chown(a,b,c) 0 ++#endif ++ + /* Compatibility. */ + typedef size_t php_stat_len; + +diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c +index ea33ba49..4a25b07b 100644 +--- a/ext/standard/php_fopen_wrapper.c ++++ b/ext/standard/php_fopen_wrapper.c +@@ -317,7 +317,7 @@ static php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const c + return NULL; + } + +-#ifdef HAVE_UNISTD_H ++#if defined(HAVE_UNISTD_H) && !defined(__wasi__) + dtablesize = getdtablesize(); + #else + dtablesize = INT_MAX; +diff --git a/main/network.c b/main/network.c +index f613a73f..32eae02b 100644 +--- a/main/network.c ++++ b/main/network.c +@@ -347,7 +347,10 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, + socklen_t len; + int ret = 0; + ++ // WASIX only supports blocking connects for now ++#ifndef __wasi__ + SET_SOCKET_BLOCKING_MODE(sockfd, orig_flags); ++#endif + + if ((n = connect(sockfd, addr, addrlen)) != 0) { + error = php_socket_errno(); +@@ -430,10 +433,17 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, + } + + ok: ++#ifdef __wasi__ ++ if (asynchronous) { ++ // Switch to non-blocking mode after we're connected ++ SET_SOCKET_BLOCKING_MODE(sockfd, orig_flags); ++ } ++#else + if (!asynchronous) { + /* back to blocking mode */ + RESTORE_SOCKET_BLOCKING_MODE(sockfd, orig_flags); + } ++#endif + + if (error_code) { + *error_code = error; +diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c +index 3a410eb7..65cf3efa 100644 +--- a/main/php_open_temporary_file.c ++++ b/main/php_open_temporary_file.c +@@ -279,6 +279,9 @@ PHPAPI const char* php_get_temporary_directory(void) + free(tmp); + return PG(php_sys_temp_dir); + } ++#elif defined(__wasi__) ++ PG(php_sys_temp_dir) = estrdup("/tmp"); ++ return PG(php_sys_temp_dir); + #else + /* On Unix use the (usual) TMPDIR environment variable. */ + { + +diff --git a/ext/pcre/pcre2lib/sljit/sljitUtils.c b/ext/pcre/pcre2lib/sljit/sljitUtils.c +index 84f3aaf7..112560eb 100644 +--- a/ext/pcre/pcre2lib/sljit/sljitUtils.c ++++ b/ext/pcre/pcre2lib/sljit/sljitUtils.c +@@ -327,10 +327,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st + aligned_old_start = ((sljit_uw)stack->start) & ~page_align; + + if (aligned_new_start > aligned_old_start) { ++#ifndef __wasi__ + posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED); + #ifdef MADV_FREE + madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE); + #endif /* MADV_FREE */ ++#endif + } + } + #endif /* _WIN32 */ + +diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c +index d571a622..2d25dc8b 100644 +--- a/Zend/zend_fibers.c ++++ b/Zend/zend_fibers.c +@@ -253,7 +253,7 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size) + return NULL; + } + +-#if defined(MADV_NOHUGEPAGE) ++#if defined(MADV_NOHUGEPAGE) && !defined(__wasi__) + /* Multiple reasons to fail, ignore all errors only needed + * for linux < 6.8 */ + (void) madvise(pointer, alloc_size, MADV_NOHUGEPAGE); diff --git a/pkgs/overlay/packages/php/patches/php85/0002-opcache-static-embed.patch b/pkgs/overlay/packages/php/patches/php85/0002-opcache-static-embed.patch new file mode 100644 index 00000000..bc509df6 --- /dev/null +++ b/pkgs/overlay/packages/php/patches/php85/0002-opcache-static-embed.patch @@ -0,0 +1,371 @@ +diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c +index 904a9c2a..5a6f62bb 100644 +--- a/ext/opcache/ZendAccelerator.c ++++ b/ext/opcache/ZendAccelerator.c +@@ -152,6 +152,12 @@ static void preload_restart(void); + # define INCREMENT(v) InterlockedIncrement64(&ZCSG(v)) + # define DECREMENT(v) InterlockedDecrement64(&ZCSG(v)) + # define LOCKVAL(v) (ZCSG(v)) ++#elif defined(__wasi__) ++static uint32_t accel_wasi_mem_usage = 0; ++static uint32_t accel_wasi_restart_in = 0; ++# define INCREMENT(v) __atomic_add_fetch(&accel_wasi_##v, 1, __ATOMIC_SEQ_CST) ++# define DECREMENT(v) __atomic_sub_fetch(&accel_wasi_##v, 1, __ATOMIC_SEQ_CST) ++# define LOCKVAL(v) __atomic_load_n(&accel_wasi_##v, __ATOMIC_SEQ_CST) + #endif + + #define ZCG_KEY_LEN (MAXPATHLEN * 8) +@@ -275,9 +281,9 @@ static ZEND_INI_MH(accel_include_path_on_modify) + + static inline void accel_restart_enter(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + INCREMENT(restart_in); +-#else ++#elif !defined(__wasi__) + struct flock restart_in_progress; + + restart_in_progress.l_type = F_WRLCK; +@@ -294,10 +300,10 @@ static inline void accel_restart_enter(void) + + static inline void accel_restart_leave(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + ZCSG(restart_in_progress) = false; + DECREMENT(restart_in); +-#else ++#elif !defined(__wasi__) + struct flock restart_finished; + + restart_finished.l_type = F_UNLCK; +@@ -315,7 +321,9 @@ static inline void accel_restart_leave(void) + static inline int accel_restart_is_active(void) + { + if (ZCSG(restart_in_progress)) { +-#ifndef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) ++ return LOCKVAL(restart_in) != 0; ++#elif !defined(__wasi__) + struct flock restart_check; + + restart_check.l_type = F_WRLCK; +@@ -333,8 +341,6 @@ static inline int accel_restart_is_active(void) + } else { + return 1; + } +-#else +- return LOCKVAL(restart_in) != 0; + #endif + } + return 0; +@@ -343,11 +349,11 @@ static inline int accel_restart_is_active(void) + /* Creates a read lock for SHM access */ + static inline zend_result accel_activate_add(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + SHM_UNPROTECT(); + INCREMENT(mem_usage); + SHM_PROTECT(); +-#else ++#elif !defined(__wasi__) + struct flock mem_usage_lock; + + mem_usage_lock.l_type = F_RDLCK; +@@ -366,14 +372,14 @@ static inline zend_result accel_activate_add(void) + /* Releases a lock for SHM access */ + static inline void accel_deactivate_sub(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + if (ZCG(counted)) { + SHM_UNPROTECT(); + DECREMENT(mem_usage); + ZCG(counted) = false; + SHM_PROTECT(); + } +-#else ++#elif !defined(__wasi__) + struct flock mem_usage_unlock; + + mem_usage_unlock.l_type = F_UNLCK; +@@ -389,9 +395,9 @@ static inline void accel_deactivate_sub(void) + + static inline void accel_unlock_all(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + accel_deactivate_sub(); +-#else ++#elif !defined(__wasi__) + if (lock_file == -1) { + return; + } +@@ -834,7 +840,7 @@ static void accel_use_shm_interned_strings(void) + HANDLE_UNBLOCK_INTERRUPTIONS(); + } + +-#ifndef ZEND_WIN32 ++#if !defined(ZEND_WIN32) && !defined(__wasi__) + static inline void kill_all_lockers(struct flock *mem_usage_check) + { + int tries; +@@ -901,7 +907,7 @@ static inline void kill_all_lockers(struct flock *mem_usage_check) + + static inline bool accel_is_inactive(void) + { +-#ifdef ZEND_WIN32 ++#if defined(ZEND_WIN32) || defined(__wasi__) + /* on Windows, we don't need kill_all_lockers() because SAPIs + that work on Windows don't manage child processes (and we + can't do anything about hanging threads anyway); therefore +@@ -912,7 +918,7 @@ static inline bool accel_is_inactive(void) + if (LOCKVAL(mem_usage) == 0) { + return true; + } +-#else ++#elif !defined(__wasi__) + struct flock mem_usage_check; + + mem_usage_check.l_type = F_WRLCK; +@@ -2938,6 +2944,10 @@ static zend_result zend_accel_init_shm(void) + ZCSG(start_time) = zend_accel_get_time(); + ZCSG(last_restart_time) = 0; + ZCSG(restart_in_progress) = false; ++#ifdef __wasi__ ++ __atomic_store_n(&accel_wasi_mem_usage, 0, __ATOMIC_SEQ_CST); ++ __atomic_store_n(&accel_wasi_restart_in, 0, __ATOMIC_SEQ_CST); ++#endif + + for (i = 0; i < -HT_MIN_MASK; i++) { + ZCSG(uninitialized_bucket)[i] = HT_INVALID_IDX; +@@ -4989,8 +4999,10 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) + + if (!ZCG(accel_directives).preload_user + || !*ZCG(accel_directives).preload_user) { +- + bool sapi_requires_preload_user = !(strcmp(sapi_module.name, "cli") == 0 ++#ifdef __wasi__ ++ || strcmp(sapi_module.name, "cli-server") == 0 ++#endif + || strcmp(sapi_module.name, "phpdbg") == 0); + + if (!sapi_requires_preload_user) { +@@ -5015,6 +5027,7 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) + return SUCCESS; + } + ++#ifndef __wasi__ + *pid = fork(); + if (*pid == -1) { + zend_shared_alloc_unlock(); +@@ -5039,6 +5052,14 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) + } + + return SUCCESS; ++#else ++ // Note: in WASIX, there is only one uid; it has "root" access to everything within the ++ // sandbox, but not the base OS, so it's OK to run everything with that user. That is to ++ // say, we shouldn't need to fork a new process here. ++ // It is also a fact that forking doesn't work under WASIX+EH anyway. ++ zend_accel_error(ACCEL_LOG_FATAL, "Preloading cannot fork to spawn a new process in WASIX"); ++ exit(1); ++#endif + } + #endif /* ZEND_WIN32 */ + +diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 +index 70138726..a53316a8 100644 +--- a/ext/opcache/config.m4 ++++ b/ext/opcache/config.m4 +@@ -229,7 +229,7 @@ int main(void) { + [php_cv_shm_mmap_anon=yes], + [php_cv_shm_mmap_anon=no], + [AS_CASE([$host_alias], +- [*linux*|*midipix], [php_cv_shm_mmap_anon=yes], ++ [*linux*|*midipix|*wasm*], [php_cv_shm_mmap_anon=yes], + [php_cv_shm_mmap_anon=no])])]) + AS_VAR_IF([php_cv_shm_mmap_anon], [yes], + [AC_DEFINE([HAVE_SHM_MMAP_ANON], [1], +diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c +index 6f668af9..98105cec 100644 +--- a/ext/opcache/zend_accelerator_module.c ++++ b/ext/opcache/zend_accelerator_module.c +@@ -312,7 +312,7 @@ ZEND_INI_BEGIN() + STD_PHP_INI_ENTRY("opcache.optimization_level" , DEFAULT_OPTIMIZATION_LEVEL , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.optimization_level, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.opt_debug_level" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.opt_debug_level, zend_accel_globals, accel_globals) + STD_PHP_INI_BOOLEAN("opcache.enable_file_override" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_override_enabled, zend_accel_globals, accel_globals) +- STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals) ++ STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals) + +diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c +index d430f483..0f9e54ef 100644 +--- a/ext/opcache/zend_file_cache.c ++++ b/ext/opcache/zend_file_cache.c +@@ -97,9 +97,15 @@ static int zend_file_cache_flock(int fd, int op) + #elif defined(HAVE_FLOCK) + # define zend_file_cache_flock flock + #else +-# define LOCK_SH 0 +-# define LOCK_EX 1 +-# define LOCK_UN 2 ++# ifndef LOCK_SH ++# define LOCK_SH 0 ++# endif ++# ifndef LOCK_EX ++# define LOCK_EX 1 ++# endif ++# ifndef LOCK_UN ++# define LOCK_UN 2 ++# endif + static int zend_file_cache_flock(int fd, int type) + { + return 0; +diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c +index 80ef36b8..c854e80e 100644 +--- a/ext/opcache/zend_shared_alloc.c ++++ b/ext/opcache/zend_shared_alloc.c +@@ -29,6 +29,7 @@ + #include + #include "ZendAccelerator.h" + #include "zend_shared_alloc.h" ++#include "zend_atomic.h" + #ifdef HAVE_UNISTD_H + # include + #endif +@@ -63,6 +64,14 @@ int lock_file = -1; + static char lockfile_name[MAXPATHLEN]; + #endif + ++#ifdef __wasi__ ++# ifdef ZTS ++static MUTEX_T zend_shared_alloc_wasi_mutex; ++# else ++static zend_atomic_bool zend_shared_alloc_wasi_lock; ++# endif ++#endif ++ + static const zend_shared_memory_handler_entry handler_table[] = { + #ifdef USE_MMAP + { "mmap", &zend_alloc_mmap_handlers }, +@@ -193,7 +202,15 @@ int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size) + ZSMMG(shared_free) = requested_size - reserved_size; /* goes to tmp_shared_globals.shared_free */ + + #ifndef ZEND_WIN32 ++#ifdef __wasi__ ++#ifdef ZTS ++ zend_shared_alloc_wasi_mutex = tsrm_mutex_alloc(); ++#else ++ ZEND_ATOMIC_BOOL_INIT(&zend_shared_alloc_wasi_lock, false); ++#endif ++#else + zend_shared_alloc_create_lock(ZCG(accel_directives).lockfile_path); ++#endif + #else + zend_shared_alloc_create_lock(); + #endif +@@ -337,10 +354,17 @@ void zend_shared_alloc_shutdown(void) + ZSMMG(shared_segments) = NULL; + g_shared_alloc_handler = NULL; + #ifndef ZEND_WIN32 +- close(lock_file); ++ if (lock_file >= 0) { ++ close(lock_file); ++ lock_file = -1; ++ } + + # ifdef ZTS ++# ifdef __wasi__ ++ tsrm_mutex_free(zend_shared_alloc_wasi_mutex); ++# else + tsrm_mutex_free(zts_lock); ++# endif + # endif + #endif + } +@@ -487,7 +511,16 @@ void zend_shared_alloc_lock(void) + { + ZEND_ASSERT(!ZCG(locked)); + +-#ifndef ZEND_WIN32 ++#ifdef ZEND_WIN32 ++ zend_shared_alloc_lock_win32(); ++#elif defined(__wasi__) ++#ifdef ZTS ++ tsrm_mutex_lock(zend_shared_alloc_wasi_mutex); ++#else ++ while (zend_atomic_bool_exchange_ex(&zend_shared_alloc_wasi_lock, true)) { ++ } ++#endif ++#else + struct flock mem_write_lock; + + mem_write_lock.l_type = F_WRLCK; +@@ -515,8 +548,6 @@ void zend_shared_alloc_lock(void) + } + break; + } +-#else +- zend_shared_alloc_lock_win32(); + #endif + + ZCG(locked) = 1; +@@ -526,7 +557,7 @@ void zend_shared_alloc_unlock(void) + { + ZEND_ASSERT(ZCG(locked)); + +-#ifndef ZEND_WIN32 ++#if !defined(ZEND_WIN32) && !defined(__wasi__) + struct flock mem_write_unlock; + + mem_write_unlock.l_type = F_UNLCK; +@@ -537,15 +568,21 @@ void zend_shared_alloc_unlock(void) + + ZCG(locked) = 0; + +-#ifndef ZEND_WIN32 ++#ifdef ZEND_WIN32 ++ zend_shared_alloc_unlock_win32(); ++#elif defined(__wasi__) ++#ifdef ZTS ++ tsrm_mutex_unlock(zend_shared_alloc_wasi_mutex); ++#else ++ zend_atomic_bool_store_ex(&zend_shared_alloc_wasi_lock, false); ++#endif ++#else + if (fcntl(lock_file, F_SETLK, &mem_write_unlock) == -1) { + zend_accel_error_noreturn(ACCEL_LOG_ERROR, "Cannot remove lock - %s (%d)", strerror(errno), errno); + } + #ifdef ZTS + tsrm_mutex_unlock(zts_lock); + #endif +-#else +- zend_shared_alloc_unlock_win32(); + #endif + } + + +diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c +index 904a9c2a..5a6f62bb 100644 +--- a/ext/opcache/ZendAccelerator.c ++++ b/ext/opcache/ZendAccelerator.c +@@ -3219,13 +3219,13 @@ static void accel_move_code_to_huge_pages(void) + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); + /* this should never happen? */ + ZEND_ASSERT(ret != MAP_FAILED); +-# ifdef MADV_HUGEPAGE ++# if defined(MADV_HUGEPAGE) && !defined(__wasi__) + if (-1 == madvise(start, size, MADV_HUGEPAGE)) { + memcpy(start, mem, real_size); + mprotect(start, size, PROT_READ | PROT_EXEC); + munmap(mem, size); + zend_error(E_WARNING, + ACCELERATOR_PRODUCT_NAME " huge_code_pages: madvise(HUGEPAGE) failed: %s (%d)", + strerror(errno), errno); + return FAILURE; + } diff --git a/pkgs/overlay/packages/php/patches/php85/0003-pgsql-env-overrides.patch b/pkgs/overlay/packages/php/patches/php85/0003-pgsql-env-overrides.patch new file mode 100644 index 00000000..a61cbe15 --- /dev/null +++ b/pkgs/overlay/packages/php/patches/php85/0003-pgsql-env-overrides.patch @@ -0,0 +1,22 @@ +diff --git a/build/php.m4 b/build/php.m4 +--- a/build/php.m4 ++++ b/build/php.m4 +@@ -1923,10 +1923,14 @@ AC_DEFUN([PHP_SETUP_PGSQL], [dnl + found_pgsql=no + dnl Set PostgreSQL installation directory if given from the configure argument. + AS_CASE([$4], [yes], [pgsql_dir=""], [pgsql_dir=$4]) +-AS_VAR_IF([pgsql_dir],, +- [PKG_CHECK_MODULES([PGSQL], [libpq >= 10.0], +- [found_pgsql=yes], +- [found_pgsql=no])]) ++AS_IF([test -n "$PGSQL_CFLAGS" && test -n "$PGSQL_LIBS"], [ ++ found_pgsql=yes ++], [ ++ AS_VAR_IF([pgsql_dir],, ++ [PKG_CHECK_MODULES([PGSQL], [libpq >= 10.0], ++ [found_pgsql=yes], ++ [found_pgsql=no])]) ++]) + + AS_VAR_IF([found_pgsql], [no], [dnl + AC_MSG_CHECKING([for pg_config]) diff --git a/pkgs/overlay/packages/php/patches/php85/0004-pgsql-libpq18-guards.patch b/pkgs/overlay/packages/php/patches/php85/0004-pgsql-libpq18-guards.patch new file mode 100644 index 00000000..08ca402e --- /dev/null +++ b/pkgs/overlay/packages/php/patches/php85/0004-pgsql-libpq18-guards.patch @@ -0,0 +1,39 @@ +diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c +--- a/ext/pgsql/pgsql.c ++++ b/ext/pgsql/pgsql.c +@@ -410,7 +410,7 @@ static bool php_pgsql_strtok_identifier_parse(const char *str, size_t str_len) + } + + #ifndef HAVE_PG_CHANGE_PASSWORD +-static PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd) ++static PGresult *php_PQchangePassword(PGconn *conn, const char *user, const char *passwd) + { + /** + * It is more appropriate to let the configured password encryption algorithm +@@ -451,7 +451,7 @@ static PGresult *PQchangePassword(PGconn *conn, const char *user, const char *pa + #endif + + #if !defined(HAVE_PG_SOCKET_POLL) +-static int PQsocketPoll(int socket, int read, int write, time_t timeout) ++static int php_PQsocketPoll(int socket, int read, int write, time_t timeout) + { + if (!read && !write) + return 0; +@@ -6335,7 +6335,7 @@ PHP_FUNCTION(pg_change_password) + RETURN_THROWS(); + } + +- pg_result = PQchangePassword(link->conn, ZSTR_VAL(user), ZSTR_VAL(passwd)); ++ pg_result = php_PQchangePassword(link->conn, ZSTR_VAL(user), ZSTR_VAL(passwd)); + RETVAL_BOOL(PQresultStatus(pg_result) == PGRES_COMMAND_OK); + PQclear(pg_result); + } +@@ -6404,7 +6404,7 @@ PHP_FUNCTION(pg_socket_poll) + RETURN_FALSE; + } + +- RETURN_LONG((zend_long)PQsocketPoll(socket, (int)read, (int)write, (int)ts)); ++ RETURN_LONG((zend_long)php_PQsocketPoll(socket, (int)read, (int)write, (int)ts)); + } + /* }}} */ + #endif diff --git a/pkgs/overlay/packages/php/patches/php85/0005-restore-php-smart-string-compat.patch b/pkgs/overlay/packages/php/patches/php85/0005-restore-php-smart-string-compat.patch new file mode 100644 index 00000000..8601ded6 --- /dev/null +++ b/pkgs/overlay/packages/php/patches/php85/0005-restore-php-smart-string-compat.patch @@ -0,0 +1,8 @@ +diff --git a/ext/standard/php_smart_string.h b/ext/standard/php_smart_string.h +new file mode 100644 +index 0000000..067e719 +--- /dev/null ++++ b/ext/standard/php_smart_string.h +@@ -0,0 +1,2 @@ ++/* Header moved to Zend. This file is retained for BC. */ ++#include "zend_smart_string.h" diff --git a/pkgs/overlay/packages/php/patches/php85/0006-zend-vm-tailcall-wasm32.patch b/pkgs/overlay/packages/php/patches/php85/0006-zend-vm-tailcall-wasm32.patch new file mode 100644 index 00000000..125d2903 --- /dev/null +++ b/pkgs/overlay/packages/php/patches/php85/0006-zend-vm-tailcall-wasm32.patch @@ -0,0 +1,26 @@ +diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php +index 38c20b24da2..9df053312d4 100755 +--- a/Zend/zend_vm_gen.php ++++ b/Zend/zend_vm_gen.php +@@ -2498,7 +2498,7 @@ function gen_vm_opcodes_header( + $str .= "# define ZEND_VM_KIND\t\tZEND_VM_KIND_HYBRID\n"; + } + if ($GLOBALS["vm_kind_name"][ZEND_VM_GEN_KIND] === "ZEND_VM_KIND_HYBRID" || $GLOBALS["vm_kind_name"][ZEND_VM_GEN_KIND] === "ZEND_VM_KIND_CALL") { +- $str .= "#elif defined(HAVE_MUSTTAIL) && defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(__aarch64__))\n"; ++ $str .= "#elif defined(HAVE_MUSTTAIL) && ((defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(__aarch64__))) || defined(__wasm32__))\n"; + $str .= "# define ZEND_VM_KIND\t\tZEND_VM_KIND_TAILCALL\n"; + $str .= "#else\n"; + $str .= "# define ZEND_VM_KIND\t\tZEND_VM_KIND_CALL\n"; +@@ -2515,8 +2515,12 @@ function gen_vm_opcodes_header( + $str .= "#endif\n"; + $str .= "\n"; + $str .= "#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n"; +- $str .= "# define ZEND_OPCODE_HANDLER_CCONV ZEND_PRESERVE_NONE\n"; ++ $str .= "# ifdef HAVE_PRESERVE_NONE\n"; ++ $str .= "# define ZEND_OPCODE_HANDLER_CCONV ZEND_PRESERVE_NONE\n"; ++ $str .= "# else\n"; ++ $str .= "# define ZEND_OPCODE_HANDLER_CCONV ZEND_FASTCALL\n"; ++ $str .= "# endif\n"; + $str .= "# define ZEND_OPCODE_HANDLER_CCONV_EX ZEND_FASTCALL\n"; + $str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL\n"; + $str .= "# define ZEND_OPCODE_HANDLER_CCONV ZEND_FASTCALL\n"; diff --git a/pkgs/overlay/packages/php/patches/php85/0007-zend-vm-opcodes-tailcall-wasm32.patch b/pkgs/overlay/packages/php/patches/php85/0007-zend-vm-opcodes-tailcall-wasm32.patch new file mode 100644 index 00000000..177030ba --- /dev/null +++ b/pkgs/overlay/packages/php/patches/php85/0007-zend-vm-opcodes-tailcall-wasm32.patch @@ -0,0 +1,13 @@ +diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h +--- a/Zend/zend_vm_opcodes.h ++++ b/Zend/zend_vm_opcodes.h +@@ -45 +45 @@ static const char *const zend_vm_kind_name[] = { +-#elif defined(HAVE_MUSTTAIL) && defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(__aarch64__)) ++#elif defined(HAVE_MUSTTAIL) && ((defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(__aarch64__))) || defined(__wasm32__)) +@@ -58 +58,5 @@ static const char *const zend_vm_kind_name[] = { +-# define ZEND_OPCODE_HANDLER_CCONV ZEND_PRESERVE_NONE ++# ifdef HAVE_PRESERVE_NONE ++# define ZEND_OPCODE_HANDLER_CCONV ZEND_PRESERVE_NONE ++# else ++# define ZEND_OPCODE_HANDLER_CCONV ZEND_FASTCALL ++# endif diff --git a/pkgs/overlay/packages/php/versions.nix b/pkgs/overlay/packages/php/versions.nix new file mode 100644 index 00000000..90df5b5d --- /dev/null +++ b/pkgs/overlay/packages/php/versions.nix @@ -0,0 +1,128 @@ +{ + lib, + fetchFromGitHub, +}: let + commonConfigureFlags = [ + "--enable-fd-setsize=8192" + "--enable-static" + "--disable-shared" + "--host=wasm32-wasi" + "--target=wasm32-wasi" + "--disable-opcache-jit" + "--disable-huge-code-pages" + "--disable-rpath" + "--disable-cgi" + "--with-zlib" + "--with-openssl" + "--enable-mbstring" + "--enable-mbregex" + "--disable-zend-signals" + "--with-valgrind=no" + "--with-pcre-jit=no" + "--with-iconv" + "--disable-phpdbg" + "--enable-bcmath" + "--enable-gd" + "--enable-exif" + "--with-jpeg" + "--with-freetype" + "--with-webp" + "--enable-fiber-asm" + "--with-curl" + "--with-mysqli=mysqlnd" + "--with-pdo-mysql=mysqlnd" + "--with-zip" + "--with-sodium" + "--enable-intl" + "--with-pdo-sqlite" + "--enable-ftp" + "--enable-igbinary" + "--with-imagick" + "--program-suffix=.wasm" + "--enable-zts" + "--enable-embed=static" + ]; + + commonBundledExtensions = { + igbinary = { + src = fetchFromGitHub { + owner = "igbinary"; + repo = "igbinary"; + rev = "8326f6a69ebb30dd6258dd536eb0914454fbf146"; + hash = "sha256-uBnM+zqwnaXzqt7XO6g87XEW3zp0clhuMgihlCV8apE="; + }; + }; + + imagick = { + src = fetchFromGitHub { + owner = "Imagick"; + repo = "imagick"; + rev = "70087bab33eab913e99ac77d64d04d1a2fd0b7b0"; + hash = "sha256-d1bRJKAnGyXbcc4Vv8WYtPpL7kPf2XfkXVta7HK+iLA="; + }; + }; + }; + + mkPhpZts = { + series, + upstreamVersion, + srcRev, + srcHash, + patches, + extraConfigureFlags ? [], + bundledExtensions ? commonBundledExtensions, + }: rec { + pname = "php${series}-zts"; + version = "${upstreamVersion}-wasix"; + + src = fetchFromGitHub { + owner = "php"; + repo = "php-src"; + rev = srcRev; + hash = srcHash; + }; + + inherit bundledExtensions patches; + + configureFlags = commonConfigureFlags ++ extraConfigureFlags; + + meta = { + description = "Static PHP ${upstreamVersion} WASIX ZTS libphp build"; + homepage = "https://github.com/php/php-src"; + license = lib.licenses.php301; + platforms = lib.platforms.linux; + }; + }; +in { + php83 = mkPhpZts { + series = "83"; + upstreamVersion = "8.3.21"; + srcRev = "2d2a21057fe357941652a2d1b5f296f527a0bee0"; + srcHash = "sha256-pLH+P1nBPXCmdy8OpcxhuDV4+ClZuv5XA5WujdorUCc="; + extraConfigureFlags = [ + "--enable-opcache" + ]; + patches = [ + ./patches/common/0001-wasix-core-support.patch + ./patches/common/0002-opcache-static-embed.patch + ./patches/common/0003-cli-server-instaboot.patch + ./patches/common/0004-openssl-no-sock.patch + ]; + }; + + php85 = mkPhpZts { + series = "85"; + upstreamVersion = "8.5.3"; + srcRev = "f665c20219d0861fcbdd1f663fc4ac061f245a3c"; + srcHash = "sha256-/chajkaMVtXTFdgAKEHaQA7FjLsYMyxLDYb+JXDLS4c="; + patches = [ + ./patches/php85/0001-wasix-core-support.patch + ./patches/php85/0002-opcache-static-embed.patch + ./patches/php85/0003-pgsql-env-overrides.patch + ./patches/php85/0005-restore-php-smart-string-compat.patch + ./patches/php85/0006-zend-vm-tailcall-wasm32.patch + ./patches/php85/0007-zend-vm-opcodes-tailcall-wasm32.patch + ./patches/common/0004-openssl-no-sock.patch + ]; + }; +} diff --git a/pkgs/overlay/packages/phpix/package.nix b/pkgs/overlay/packages/phpix/package.nix new file mode 100644 index 00000000..fc66f57d --- /dev/null +++ b/pkgs/overlay/packages/phpix/package.nix @@ -0,0 +1,108 @@ +# phpix — the PHP runtime/server for wasix (wasmerio/phpix): a cargo-wasix Rust program that embeds +# our static php85 libphp. Ported from the old pkgs/programs/phpix (mk-phpix-wasix + phpixPhp85). +# Built on the build host via cargo-wasix (targeting wasm32-wasmer-wasi), linking php's libphp.a + +# its phpExtraLibDirs/phpExtraLinkLibs. exnrefEh-only — must match php's profile/EH mode. +{ + final, + prev, + toolchain, + ... +}: let + lib = prev.lib; + php = final.php; + # build-platform rustPlatform — only for cargoSetupHook + importCargoLock (vendoring the lock); + # the actual compile goes through cargo-wasix. + rustPlatform = final.buildPackages.rustPlatform; +in + final.buildPackages.stdenvNoCC.mkDerivation { + pname = "phpix"; + version = "0.1.12803"; + + # phpix is a private repo, vendored as the vendor/phpix submodule. Build with + # `nix build '.?submodules=1#…'` so the flake tree includes it; the rev is pinned by the + # submodule gitlink (bump via `git submodule update --remote vendor/phpix`). + src = ../../../../vendor/phpix; + + cargoDeps = rustPlatform.importCargoLock { + lockFile = ./phpix.Cargo.lock; + allowBuiltinFetchGit = true; + # wasix-abi-rust bundles wasix-witx as a git submodule pinned to a rev that isn't on witx's + # main branch, so importCargoLock's builtin fetchGit can't resolve it. Route this one dep + # through fetchgit (submodule-aware + ref-agnostic) by pinning its hash here. + outputHashes = { + "wasix-0.13.1" = "sha256-HBCqkQivakAVUmnonThNj/D0HbRDtCummXQfvLpx1xY="; + }; + }; + + nativeBuildInputs = [ + rustPlatform.cargoSetupHook + toolchain.cargoWasix + toolchain.wasixcc + toolchain.wasixLlvm + # pkgsBuildBuild (fully native x86_64), NOT buildPackages — the latter is the build->host + # cross set, whose `gcc` is the unbuildable x86_64->wasm cross compiler. These are host-side + # build tooling: gcc links the x86_64 proc-macro/build-script artifacts, libclang runs bindgen. + final.pkgsBuildBuild.gcc + final.pkgsBuildBuild.llvmPackages.libclang + ]; + + prePatch = '' + cp ${./phpix.Cargo.lock} Cargo.lock + # report_memleaks: PHP 8.5 deprecates the INI route, but request shutdown still reads the flag + # to reclaim per-request memory; patch the Zend global directly for long-running workers. + patch -N -p1 --batch < ${./patches/report-memleaks.patch} || true + # build.rs's extra-libs const omits several transitive deps of the bundled extensions + # (libpgcommon/pgport, lcms2, openjpeg, libdeflate, zstd, brotli, webpmux/demux), leaving them + # as undefined wasm imports — add them so the module instantiates. + patch -p1 --batch < ${./patches/link-extra-libs.patch} + ''; + + buildPhase = '' + runHook preBuild + + export HOME="$PWD/.home" + export CARGO_HOME="$HOME/.cargo" + export RUSTUP_HOME="$HOME/.rustup" + mkdir -p "$HOME" "$CARGO_HOME" "$RUSTUP_HOME" + + SYSROOT_PATH="$(wasixccenv -sWASM_EXCEPTIONS=yes print-sysroot)" + compat_lib_dir="$PWD/.php-link-compat" + mkdir -p "$compat_lib_dir" + # PHP is built with LTO; some archived bitcode objects carry linker options for libraries + # provided by the sysroot/runtime surface rather than standalone Nix archives. Provide empty + # compat archives so wasm-ld accepts those names while libc/other archives resolve the symbols. + for lib in charset iconv icrt icutu; do + wasixar crs "$compat_lib_dir/lib''${lib}.a" + done + export WASIX_PHP_HOME="${php}" + export WASIX_PHP_EXTRA_LIB_DIR="$compat_lib_dir:${lib.concatStringsSep ":" php.phpExtraLibDirs}:$SYSROOT_PATH/lib/wasm32-wasi" + export WASIX_PHP_EXTRA_LIBS="${lib.concatStringsSep ":" php.phpExtraLinkLibs}" + export LIBCLANG_PATH="${final.pkgsBuildBuild.llvmPackages.libclang.lib}/lib" + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER="${final.pkgsBuildBuild.gcc}/bin/gcc" + + cargo-wasix wasix build --release --frozen --offline + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir -p "$out/bin" + cp target/wasm32-wasmer-wasi/release/phpix.wasm "$out/bin/phpix.wasm" + runHook postInstall + ''; + + passthru.wasix.supportedProfiles = ["exnrefEh"]; + passthru.wasix.shipped = true; + # The manifest entrypoint is what makes `wasmer run ` consult the + # command's detected wasm features (tail calls!) when picking its engine; + # without it the default engine rejects the module. + passthru.wasmer.entrypoint = "phpix"; + + meta = { + description = "PHPix — PHP runtime/server for wasix, embedding static php85 libphp"; + homepage = "https://github.com/wasmerio/phpix"; + license = lib.licenses.mit; + mainProgram = "phpix"; + }; + } diff --git a/pkgs/overlay/packages/phpix/patches/link-extra-libs.patch b/pkgs/overlay/packages/phpix/patches/link-extra-libs.patch new file mode 100644 index 00000000..25857c32 --- /dev/null +++ b/pkgs/overlay/packages/phpix/patches/link-extra-libs.patch @@ -0,0 +1,27 @@ +Link the bundled extensions' transitive deps. + +build.rs's extra-libs const only listed some of what the extensions pull in. ext/pgsql needs +libpgcommon/libpgport (pg_encoding_to_char etc.), and ImageMagick + libtiff + curl pull in lcms2, +openjpeg (opj_*), libdeflate, zstd, brotli, and the webpmux/webpdemux variants. Without these the +symbols are left as undefined wasm imports (--allow-undefined) and the module can't instantiate. + +diff --git a/build.rs b/build.rs +--- a/build.rs ++++ b/build.rs +@@ -22,6 +22,16 @@ const WASIX_PHP_EXTRA_LIBS: &[&str] = &[ + "onig", + "png", + "pq", ++ "pgcommon", ++ "pgport", ++ "lcms2", ++ "openjp2", ++ "brotlidec", ++ "brotlicommon", ++ "deflate", ++ "zstd", ++ "webpmux", ++ "webpdemux", + "sharpyuv", + "sodium", + "sqlite3", diff --git a/pkgs/overlay/packages/phpix/patches/report-memleaks.patch b/pkgs/overlay/packages/phpix/patches/report-memleaks.patch new file mode 100644 index 00000000..9ead0155 --- /dev/null +++ b/pkgs/overlay/packages/phpix/patches/report-memleaks.patch @@ -0,0 +1,77 @@ +diff --git a/src/php/mod.rs b/src/php/mod.rs +index abd4f10..44ddb14 100644 +--- a/src/php/mod.rs ++++ b/src/php/mod.rs +@@ -78,6 +78,22 @@ fn with_thread_mode(f: impl FnOnce(&RefCell>) -> R) -> + r + } + ++unsafe fn configure_core_globals_for_embedded_request() { ++ #[cfg(all(target_os = "wasi", target_vendor = "wasmer"))] ++ { ++ let pg = unsafe { phpix_pg() }; ++ if !pg.is_null() { ++ // PHP 8.5 deprecates setting report_memleaks=0 via INI, but request ++ // shutdown still uses this flag to decide whether tracked allocations ++ // are released immediately. Set the global directly so long-running ++ // workers reclaim request memory without invoking the deprecated INI handler. ++ unsafe { ++ (*pg).report_memleaks = false; ++ } ++ } ++ } ++} ++ + pub fn start_php( + num_threads: u32, + document_root: &Path, +@@ -129,24 +145,10 @@ pub fn start_php( + + sapi_startup(&raw mut sapi_mod); + +- #[cfg(all(target_os = "wasi", target_vendor = "wasmer"))] +- // WASI PHP currently uses a custom tracked allocator path in Zend. +- // PHP defaults report_memleaks to 1 (see php main/main.c ini defaults). +- // With report_memleaks=1, request shutdown keeps leaked allocations for +- // leak reporting and only clears tracking metadata, which causes memory +- // to ratchet upward across requests in long-running workers. +- // Disable leak reporting by default to force request-time reclamation. +- let runtime_ini_defaults = "report_memleaks=0\n"; +- #[cfg(not(all(target_os = "wasi", target_vendor = "wasmer")))] +- let runtime_ini_defaults = ""; +- + let ini_entries = if let Some(php_ini_path) = php_ini_path + && let Some(user_ini) = load_ini_entries(php_ini_path)? + { +- let combined = format!("{}{}", runtime_ini_defaults, user_ini.to_string_lossy()); +- Some(CString::new(combined)?) +- } else if !runtime_ini_defaults.is_empty() { +- Some(CString::new(runtime_ini_defaults)?) ++ Some(user_ini) + } else { + None + }; +diff --git a/src/php/script.rs b/src/php/script.rs +index 850d140..e575ee5 100644 +--- a/src/php/script.rs ++++ b/src/php/script.rs +@@ -181,6 +181,7 @@ pub fn execute_cli_script(script_path: &Path, script_args: Vec) -> Resul + // Set argc/argv in request_info so PHP core can populate $argc/$argv + sg.request_info.argc = argc; + sg.request_info.argv = argv_ptrs.as_ptr() as *mut *mut c_char; ++ configure_core_globals_for_embedded_request(); + + if php_request_startup() != 0 { + php_request_shutdown(ptr::null_mut()); +diff --git a/src/php/worker.rs b/src/php/worker.rs +index 87b0274..ab84828 100644 +--- a/src/php/worker.rs ++++ b/src/php/worker.rs +@@ -209,6 +209,7 @@ fn process_task(task: PhpTask) -> Result<()> { + sg.server_context = std::ptr::dangling_mut(); + sg.sapi_headers.http_response_code = 200; + update_server_globals(&mut sg.request_info); ++ configure_core_globals_for_embedded_request(); + + if php_request_startup() != 0 { + php_request_shutdown(ptr::null_mut()); diff --git a/pkgs/overlay/packages/phpix/phpix.Cargo.lock b/pkgs/overlay/packages/phpix/phpix.Cargo.lock new file mode 100644 index 00000000..523bb41b --- /dev/null +++ b/pkgs/overlay/packages/phpix/phpix.Cargo.lock @@ -0,0 +1,2196 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "arc-swap" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8" + +[[package]] +name = "async-compression" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1" +dependencies = [ + "compression-codecs", + "compression-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc 0.2.169", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.11.0", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "cc" +version = "1.2.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cidr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdf600c45bd958cf2945c445264471cca8b6c8e67bc87b71affd6d7e5682621" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc 0.2.169", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "compression-codecs" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7" +dependencies = [ + "compression-core", + "flate2", + "memchr", +] + +[[package]] +name = "compression-core" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc 0.2.169", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deadqueue" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ff1266be84e4e04a81e2d1cbb998cb271b374fb73ce780245ef96c037c50cd" +dependencies = [ + "crossbeam-queue", + "tokio", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc 0.2.169", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "filetime" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +dependencies = [ + "cfg-if", + "libc 0.2.169", + "libredox", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc 0.2.169", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "git+https://github.com/wasix-org/getrandom.git?branch=wasix-0.3.3#d7c0a8cd303836ec86c9559de0f15bf3b2761240" +dependencies = [ + "cfg-if", + "libc 0.2.169", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", + "wasix", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "htaccess" +version = "0.1.0" +dependencies = [ + "base64", + "cidr", + "getrandom 0.3.3", + "http", + "md5", + "notify", + "regex", + "tempfile", + "tokio", + "tracing", + "urlencoding", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "git+https://github.com/wasix-org/hyper.git?branch=wasix-1.6.0#7e0d5f82a73a2890ac06698cd6bf68470998a84b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-staticfile" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc4bce64c32578957926e75f832032f81ebb30bcee74f86c5848b13a69e547eb" +dependencies = [ + "futures-util", + "http", + "http-range", + "httpdate", + "hyper", + "mime_guess", + "percent-encoding", + "rand", + "tokio", + "url", + "winapi", +] + +[[package]] +name = "hyper-util" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc 0.2.169", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc 0.2.169", +] + +[[package]] +name = "io-uring" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd7bddefd0a8833b88a4b68f90dae22c7450d11b354198baee3874fd811b344" +dependencies = [ + "bitflags 2.11.0", + "cfg-if", + "libc 0.2.169", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "kqueue" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +dependencies = [ + "kqueue-sys", + "libc 0.2.169", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc 0.2.169", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.152" +source = "git+https://github.com/wasix-org/libc.git?branch=v0.2.152#4c7fa6d827b1ac54b6077295d0599fb6125a7bed" + +[[package]] +name = "libc" +version = "0.2.169" +source = "git+https://github.com/wasix-org/libc.git?branch=wasix-0.2.169#bde01aefba484da9e21c7f4a6b36d59f378ca4f7" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libredox" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +dependencies = [ + "bitflags 2.11.0", + "libc 0.2.169", + "plain", + "redox_syscall 0.7.3", +] + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "git+https://github.com/wasix-org/parking_lot.git?branch=v0.12.1#2ff4487ab9d48778e04f966bcd3a949dba9a8f32" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc 0.2.169", + "log", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "git+https://github.com/wasix-org/mio.git?branch=wasix-1.0.3#52c6243f3c0e3916a3320f25ca6d2bc66f952804" +dependencies = [ + "libc 0.2.169", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasix", + "windows-sys 0.52.0", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.11.0", + "filetime", + "inotify", + "kqueue", + "libc 0.2.169", + "log", + "mio 0.8.11", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "git+https://github.com/wasix-org/parking_lot.git?branch=v0.12.1#2ff4487ab9d48778e04f966bcd3a949dba9a8f32" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "git+https://github.com/wasix-org/parking_lot.git?branch=v0.12.1#2ff4487ab9d48778e04f966bcd3a949dba9a8f32" +dependencies = [ + "cfg-if", + "libc 0.2.169", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phpix" +version = "0.1.12803" +dependencies = [ + "anyhow", + "base64", + "bindgen", + "bytes", + "cc", + "clap", + "deadqueue", + "flate2", + "futures", + "getrandom 0.3.3", + "htaccess", + "http", + "http-body", + "http-body-util", + "httpdate", + "hyper", + "hyper-staticfile", + "hyper-util", + "libc 0.2.169", + "md5", + "percent-encoding", + "pin-project-lite", + "serde_json", + "sha1", + "tempfile", + "tokio", + "tower", + "tower-http", + "tracing", + "tracing-subscriber", + "ureq", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc 0.2.169", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc 0.2.169", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags 2.11.0", + "errno", + "libc 0.2.169", + "linux-raw-sys", + "windows-sys 0.60.2", +] + +[[package]] +name = "rustls" +version = "0.23.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.1.1" +source = "git+https://github.com/wasix-org/signal-hook.git?branch=registry-v1.1.1#c690fb4f3e2baa47252ded6338253e1af30087b1" +dependencies = [ + "arc-swap", + "libc 0.2.152", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.0" +source = "git+https://github.com/wasix-org/socket2.git?branch=wasix-0.6.0#a2c803821c921735386bea3762ff1ea86f128891" +dependencies = [ + "libc 0.2.169", + "windows-sys 0.59.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.47.0" +source = "git+https://github.com/wasix-org/tokio.git?branch=wasix-1.47.0#f8a71f57d148771498551c0590ca8e9906a60d05" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc 0.2.169", + "mio 1.0.3", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "slab", + "socket2", + "tokio-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "git+https://github.com/wasix-org/tokio.git?branch=wasix-1.47.0#f8a71f57d148771498551c0590ca8e9906a60d05" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "git+https://github.com/wasix-org/tower.git?branch=wasix-0.5.2#7994205c3d73a3744366eec3589445b7b8fe4d2b" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "async-compression", + "bitflags 2.11.0", + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "git+https://github.com/wasix-org/tower.git?branch=wasix-0.5.2#7994205c3d73a3744366eec3589445b7b8fe4d2b" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "git+https://github.com/wasix-org/tower.git?branch=wasix-0.5.2#7994205c3d73a3744366eec3589445b7b8fe4d2b" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +dependencies = [ + "base64", + "flate2", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "url", + "webpki-roots 0.26.11", +] + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasix" +version = "0.13.1" +source = "git+https://github.com/wasix-org/wasix-abi-rust.git#92534c00e865047b75e400c5bb0e159a0e7d096a" +dependencies = [ + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.6", +] + +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/pkgs/overlay/packages/phpix/tests/basic.nix b/pkgs/overlay/packages/phpix/tests/basic.nix new file mode 100644 index 00000000..9eefb37f --- /dev/null +++ b/pkgs/overlay/packages/phpix/tests/basic.nix @@ -0,0 +1,71 @@ +# e2e tests for phpix: run mode (script execution) and serve mode (a real +# HTTP round trip — phpix.wasm listening under wasmer --net, curl from host). +{ + pkgs, + wasmerPkgs, + testLib, + ... +}: { + version = testLib.mkWasixRun { + name = "phpix-version"; + wasixPkgs = [wasmerPkgs.phpix]; + script = "phpix --version"; + }; + + # `phpix run`: execute a script, exercising the embedded libphp (core, json, + # pcre) without networking. + run-script = testLib.mkWasixRun { + name = "phpix-run-script"; + wasixPkgs = [wasmerPkgs.phpix]; + script = '' + cat > hello.php <<'PHP' + array_sum([1, 2, 3])]) . "\n"; + preg_match('/w(as)ix/', 'wasix', $m); + echo $m[1] . "\n"; + PHP + out=$(phpix run hello.php) + echo "$out" + echo "$out" | grep -q '^hello from 8\.5' + echo "$out" | grep -q '^{"sum":6}$' + echo "$out" | grep -q '^as$' + ''; + }; + + # `phpix serve`: start the server in the guest, then drive it from the host + # with curl — GET with query-string dispatch and a POST body round trip. + serve-http = testLib.mkWasixRun { + name = "phpix-serve-http"; + nativePkgs = [pkgs.curl]; + wasixPkgs = [wasmerPkgs.phpix]; + wasmerArgs = ["--net"]; + script = '' + mkdir docroot + cat > docroot/index.php <<'PHP' + /dev/null && break + sleep 1 + done + + body=$(curl -fsS 'http://127.0.0.1:8123/index.php?msg=hello') + echo "$body" + [ "$body" = "echo:hello;post:" ] + + post=$(curl -fsS -d 'ping' 'http://127.0.0.1:8123/index.php') + echo "$post" + [ "$post" = "echo:none;post:ping" ] + + kill "$server_pid" 2>/dev/null || true + ''; + }; +}