From 0e4ef52966402c19a3294458ea55de894bccc2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Fern=C3=A1ndez=20L=C3=B3pez?= Date: Wed, 25 Jan 2023 14:38:28 +0100 Subject: [PATCH 1/2] Add support for building to the wasm32-wasi target This change performs initial adaptations allowing the PHP interpreter to be compiled for the wasm32-wasi target. Co-Authored-By: Asen Alexandrov --- Zend/Optimizer/zend_func_infos.h | 10 ++- Zend/zend.c | 4 + Zend/zend.h | 19 ++++ Zend/zend_alloc.c | 20 ++++- Zend/zend_fibers.c | 20 ++++- Zend/zend_fibers_wasi.c | 24 +++++ Zend/zend_globals.h | 5 ++ Zend/zend_virtual_cwd.c | 6 +- Zend/zend_virtual_cwd_wasi.c | 34 +++++++ Zend/zend_wasi.c | 26 ++++++ build/ax_check_define.m4 | 73 +++++++++++++++ configure.ac | 41 +++++++-- ext/standard/basic_functions.c | 14 ++- ext/standard/basic_functions.stub.php | 6 ++ ext/standard/basic_functions_arginfo.h | 118 ++++++++++++++++++------- ext/standard/basic_functions_wasi.c | 19 ++++ ext/standard/config.m4 | 18 ++-- ext/standard/exec.c | 26 +++++- ext/standard/exec_wasi.c | 27 ++++++ ext/standard/file.c | 40 +++++++-- ext/standard/file_wasi.c | 27 ++++++ ext/standard/filestat.c | 47 ++++++++-- ext/standard/filestat_wasi.c | 33 +++++++ ext/standard/flock_wasi.c | 22 +++++ ext/standard/mail.c | 4 + ext/standard/mail_wasi.c | 22 +++++ ext/standard/microtime.c | 4 +- ext/standard/net.c | 6 +- ext/standard/pageinfo.c | 3 + ext/standard/php_fopen_wrapper.c | 4 +- main/fastcgi_wasi.c | 81 +++++++++++++++++ main/fopen_wrappers.c | 2 + main/main.c | 6 +- main/network_wasi.c | 34 +++++++ main/php.h | 4 + main/php_open_temporary_file.c | 6 ++ main/php_open_temporary_file_wasi.c | 25 ++++++ main/php_syslog.h | 2 + main/streams/plain_wrapper.c | 17 ++-- main/streams/streams.c | 4 + main/unistd_wasi.c | 21 +++++ sapi/cgi/cgi_main.c | 10 +-- sapi/cgi/config9.m4 | 3 + sapi/cli/config.m4 | 9 +- sapi/cli/php_cli.c | 6 +- wasi/syslog.h | 27 ++++++ 46 files changed, 886 insertions(+), 93 deletions(-) create mode 100644 Zend/zend_fibers_wasi.c create mode 100644 Zend/zend_virtual_cwd_wasi.c create mode 100644 Zend/zend_wasi.c create mode 100644 build/ax_check_define.m4 create mode 100644 ext/standard/basic_functions_wasi.c create mode 100644 ext/standard/exec_wasi.c create mode 100644 ext/standard/file_wasi.c create mode 100644 ext/standard/filestat_wasi.c create mode 100644 ext/standard/flock_wasi.c create mode 100644 ext/standard/mail_wasi.c create mode 100644 main/fastcgi_wasi.c create mode 100644 main/network_wasi.c create mode 100644 main/php_open_temporary_file_wasi.c create mode 100644 main/unistd_wasi.c create mode 100644 wasi/syslog.h diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index a77ec0a49f7bb..7c785a9902f4d 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -512,13 +512,19 @@ static const func_info_t func_infos[] = { #if defined(HAVE_STRPTIME) F1("strptime", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE), #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) F1("gethostname", MAY_BE_STRING|MAY_BE_FALSE), #endif +#if !defined(PHP_WASI) F1("gethostbyaddr", MAY_BE_STRING|MAY_BE_FALSE), +#endif +#if !defined(PHP_WASI) F1("gethostbyname", MAY_BE_STRING), +#endif +#if !defined(PHP_WASI) F1("gethostbynamel", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE), -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#endif +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) F1("dns_get_record", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE), #endif F1("md5", MAY_BE_STRING), diff --git a/Zend/zend.c b/Zend/zend.c index ee3f5272c9640..b8259623a35d5 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -788,7 +788,9 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{ #endif executor_globals->saved_fpu_cw_ptr = NULL; executor_globals->active = 0; +#ifndef PHP_WASI executor_globals->bailout = NULL; +#endif // PHP_WASI executor_globals->error_handling = EH_NORMAL; executor_globals->exception_class = NULL; executor_globals->exception = NULL; @@ -1179,6 +1181,7 @@ ZEND_COLD void zenderror(const char *error) /* {{{ */ } /* }}} */ +#ifndef PHP_WASI ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */ { @@ -1195,6 +1198,7 @@ ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32 LONGJMP(*EG(bailout), FAILURE); } /* }}} */ +#endif // PHP_WASI ZEND_API size_t zend_get_page_size(void) { diff --git a/Zend/zend.h b/Zend/zend.h index 94440530f3b36..12c33e3d76ebf 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -76,6 +76,11 @@ TSRMLS_MAIN_CACHE_EXTERN() ZEND_TSRMLS_CACHE_EXTERN() #endif +#undef PHP_WASI +#ifdef __wasi__ +#define PHP_WASI __wasi__ +#endif + struct _zend_serialize_data; struct _zend_unserialize_data; @@ -257,6 +262,7 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length); #define zend_bailout() _zend_bailout(__FILE__, __LINE__) +#ifndef PHP_WASI #define zend_try \ { \ JMP_BUF *__orig_bailout = EG(bailout); \ @@ -273,6 +279,19 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length); } #define zend_first_try EG(bailout)=NULL; zend_try +#else // PHP_WASI +#define zend_try \ + { \ + if (1) { +#define zend_catch \ + } else { +#define zend_end_try() \ + } \ + } +#define zend_first_try zend_try +#endif // PHP_WASI + + BEGIN_EXTERN_C() void zend_startup(zend_utility_functions *utility_functions); void zend_shutdown(void); diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 7335baf849d5e..118897c90708a 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -80,7 +80,7 @@ #include #include -#ifndef _WIN32 +#if !defined(_WIN32) && defined(HAVE_MMAP) # include # ifndef MAP_ANON # ifdef MAP_ANONYMOUS @@ -444,6 +444,8 @@ static void zend_mm_munmap(void *addr, size_t size) #endif } } +#elif !defined(_WIN32) && !defined(HAVE_MMAP) + free(addr); #else if (munmap(addr, size) != 0) { #if ZEND_MM_ERROR @@ -471,7 +473,7 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size) } ZEND_ASSERT(ptr == addr); return ptr; -#else +#elif defined(HAVE_MMAP) int flags = MAP_PRIVATE | MAP_ANON; #if defined(MAP_EXCL) flags |= MAP_FIXED | MAP_EXCL; @@ -491,6 +493,8 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size) return NULL; } return ptr; +#else + return NULL; #endif } #endif @@ -507,6 +511,10 @@ static void *zend_mm_mmap(size_t size) return NULL; } return ptr; +#elif !defined(HAVE_MMAP) + void* ptr = malloc(size); + memset(ptr, 0, size); + return ptr; #else void *ptr; @@ -716,6 +724,7 @@ static zend_always_inline void zend_mm_hugepage(void* ptr, size_t size) static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) { +#if defined(_WIN32) || defined(HAVE_MMAP) // defined(_WIN32) || defined(HAVE_MMAP) void *ptr = zend_mm_mmap(size); if (ptr == NULL) { @@ -766,6 +775,11 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) #endif return ptr; } +#else // defined(_WIN32) || defined(HAVE_MMAP) + void* ptr = aligned_alloc(alignment, size); + memset(ptr, 0, size); + return ptr; +#endif // defined(_WIN32) || defined(HAVE_MMAP) } static void *zend_mm_chunk_alloc(zend_mm_heap *heap, size_t size, size_t alignment) @@ -2934,7 +2948,7 @@ ZEND_API void start_memory_manager(void) #else alloc_globals_ctor(&alloc_globals); #endif -#ifndef _WIN32 +#if !defined(_WIN32) && defined(HAVE_MMAP) # if defined(_SC_PAGESIZE) REAL_PAGE_SIZE = sysconf(_SC_PAGESIZE); # elif defined(_SC_PAGE_SIZE) diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index a43ed60dcd9b8..5d9602cd49c0b 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -39,7 +39,7 @@ # include #endif -#ifndef ZEND_WIN32 +#if !defined(ZEND_WIN32) && defined(HAVE_MMAP) # include # include # include @@ -108,7 +108,9 @@ typedef struct _zend_fiber_vm_state { zend_execute_data *current_execute_data; int error_reporting; uint32_t jit_trace_num; +#ifndef PHP_WASI JMP_BUF *bailout; +#endif // PHP_WASI zend_fiber *active_fiber; #ifdef ZEND_CHECK_STACK_LIMIT void *stack_base; @@ -125,7 +127,9 @@ static zend_always_inline void zend_fiber_capture_vm_state(zend_fiber_vm_state * state->current_execute_data = EG(current_execute_data); state->error_reporting = EG(error_reporting); state->jit_trace_num = EG(jit_trace_num); +#ifndef PHP_WASI state->bailout = EG(bailout); +#endif // PHP_WASI state->active_fiber = EG(active_fiber); #ifdef ZEND_CHECK_STACK_LIMIT state->stack_base = EG(stack_base); @@ -142,7 +146,9 @@ static zend_always_inline void zend_fiber_restore_vm_state(zend_fiber_vm_state * EG(current_execute_data) = state->current_execute_data; EG(error_reporting) = state->error_reporting; EG(jit_trace_num) = state->jit_trace_num; +#ifndef PHP_WASI EG(bailout) = state->bailout; +#endif // PHP_WASI EG(active_fiber) = state->active_fiber; #ifdef ZEND_CHECK_STACK_LIMIT EG(stack_base) = state->stack_base; @@ -236,6 +242,8 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size) return NULL; } # endif +#elif defined(PHP_WASI) + pointer = malloc(alloc_size); #else pointer = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); @@ -302,6 +310,8 @@ static void zend_fiber_stack_free(zend_fiber_stack *stack) #ifdef ZEND_WIN32 VirtualFree(pointer, 0, MEM_RELEASE); +#elif defined(PHP_WASI) + free(pointer); #else munmap(pointer, stack->size + ZEND_FIBER_GUARD_PAGES * page_size); #endif @@ -394,6 +404,7 @@ ZEND_API bool zend_fiber_switch_blocked(void) return zend_fiber_switch_blocking; } +#ifndef PHP_WASI ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size) { context->stack = zend_fiber_stack_allocate(stack_size); @@ -440,6 +451,7 @@ ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void * return SUCCESS; } +#endif // PHP_WASI ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context) { @@ -502,16 +514,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(PHP_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(PHP_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_fibers_wasi.c b/Zend/zend_fibers_wasi.c new file mode 100644 index 0000000000000..30942633aac70 --- /dev/null +++ b/Zend/zend_fibers_wasi.c @@ -0,0 +1,24 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_fibers.h" + +ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size) +{ + zend_throw_exception(NULL, "Fibers are not supported yet on this platform (wasm32-wasi)", 0); + return FAILURE; +} diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 8900a5f416f53..69a7397c2a14f 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -21,7 +21,10 @@ #define ZEND_GLOBALS_H +#ifndef PHP_WASI #include +#endif + #include #include @@ -174,7 +177,9 @@ struct _zend_executor_globals { HashTable included_files; /* files already included */ +#ifndef PHP_WASI JMP_BUF *bailout; +#endif int error_reporting; int exit_status; diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 6bff2ad984d02..e152e8527d0db 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -1378,6 +1378,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf) /* {{{ */ /* }}} */ #endif +#ifndef PHP_WASI CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */ { cwd_state new_state; @@ -1411,8 +1412,9 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */ return ret; } /* }}} */ +#endif -#if !defined(ZEND_WIN32) +#if !defined(ZEND_WIN32) && !defined(PHP_WASI) CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link) /* {{{ */ { cwd_state new_state; @@ -1659,7 +1661,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ return popen_ex(command, type, CWDG(cwd).cwd, NULL); } /* }}} */ -#else /* Unix */ +#elif !defined(PHP_WASI) /* Unix */ CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ { size_t command_length; diff --git a/Zend/zend_virtual_cwd_wasi.c b/Zend/zend_virtual_cwd_wasi.c new file mode 100644 index 0000000000000..576b9aadf5698 --- /dev/null +++ b/Zend/zend_virtual_cwd_wasi.c @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_virtual_cwd.h" + +CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */ +{ + return -1; +} +/* }}} */ + +CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link) /* {{{ */ +{ + return -1; +} +/* }}} */ + +CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ +{ + return NULL; +} +/* }}} */ diff --git a/Zend/zend_wasi.c b/Zend/zend_wasi.c new file mode 100644 index 0000000000000..ec5c6f901bc5a --- /dev/null +++ b/Zend/zend_wasi.c @@ -0,0 +1,26 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" + +ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, + uint32_t lineno) /* {{{ */ +{ + // Not implemented yet, as WebAssembly has no stack switching + // feature implementation at this point. + zend_throw_exception(NULL, "Exception bailout is not supported yet on this platform (wasm32-wasi)", 0); +} +/* }}} */ diff --git a/build/ax_check_define.m4 b/build/ax_check_define.m4 new file mode 100644 index 0000000000000..c10d1137aee49 --- /dev/null +++ b/build/ax_check_define.m4 @@ -0,0 +1,73 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_define.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_CHECK_DEFINE([symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# AX_CHECK_DEFINE([includes],[symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# +# DESCRIPTION +# +# Complements AC_CHECK_FUNC but it does not check for a function but for a +# define to exist. Consider a usage like: +# +# AC_CHECK_DEFINE(__STRICT_ANSI__, CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500") +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +AU_ALIAS([AC_CHECK_DEFINED], [AC_CHECK_DEFINE]) +AC_DEFUN([AC_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl +AC_CACHE_CHECK([for $1 defined], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + #ifdef $1 + int ok; + (void)ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AU_ALIAS([AX_CHECK_DEFINED], [AX_CHECK_DEFINE]) +AC_DEFUN([AX_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2_$1])dnl +AC_CACHE_CHECK([for $2 defined in $1], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <$1>]], [[ + #ifdef $2 + int ok; + (void)ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AC_DEFUN([AX_CHECK_FUNC], +[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl +AC_CACHE_CHECK([for $2], ac_var, +dnl AC_LANG_FUNC_LINK_TRY +[AC_LINK_IFELSE([AC_LANG_PROGRAM([$1 + #undef $2 + char $2 ();],[ + char (*f) () = $2; + return f != $2; ])], + [AS_VAR_SET(ac_var, yes)], + [AS_VAR_SET(ac_var, no)])]) +AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +])# AC_CHECK_FUNC diff --git a/configure.ac b/configure.ac index 7445f930d6023..1c4e1b412c24e 100644 --- a/configure.ac +++ b/configure.ac @@ -4,6 +4,7 @@ dnl Include external macro definitions before the AC_INIT to also remove dnl comments starting with # and empty newlines from the included files. dnl ---------------------------------------------------------------------------- m4_include([build/ax_check_compile_flag.m4]) +m4_include([build/ax_check_define.m4]) m4_include([build/ax_func_which_gethostbyname_r.m4]) m4_include([build/ax_gcc_func_attribute.m4]) m4_include([build/libtool.m4]) @@ -274,6 +275,11 @@ if test "$ac_cv_safe_to_define___extensions__" = yes ; then AC_MSG_RESULT(yes) fi +dnl wasm32-wasi builds with a specific execution model named "command" +if test "$WASI" = "yes"; then + CPPFLAGS="$CPPFLAGS -mexec-model=command -Wl,--gc-sections" +fi + dnl Include Zend configurations. dnl ---------------------------------------------------------------------------- @@ -477,6 +483,8 @@ PHP_MISSING_TIME_R_DECL PHP_MISSING_FCLOSE_DECL PHP_STRUCT_FLOCK +AC_CHECK_DEFINE([__wasi__], [WASI="yes"], []) + AC_CHECK_TYPES(socklen_t, [], [], [ #ifdef HAVE_SYS_TYPES_H # include @@ -1351,11 +1359,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 "$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 @@ -1707,15 +1717,24 @@ PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c \ php_ini_builder.c \ php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_odbc_utils.c safe_bcmp.c \ - output.c getopt.c php_syslog.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) + php_open_temporary_file.c php_odbc_utils.c safe_bcmp.c \ + output.c getopt.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) -PHP_ADD_SOURCES_X(main, fastcgi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_FASTCGI_OBJS, no) +if test "$WASI" = "yes"; then + PHP_ADD_SOURCES(main, fastcgi_wasi.c network_wasi.c php_open_temporary_file_wasi.c unistd_wasi.c,) +else + PHP_ADD_SOURCES(main, php_syslog.c network.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) + PHP_ADD_SOURCES_X(main, fastcgi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_FASTCGI_OBJS, no) +fi PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ - plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c \ + plain_wrapper.c userspace.c transports.c mmap.c \ glob_wrapper.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +if test "$WASI" != "yes"; then + PHP_ADD_SOURCES(main/streams, xp_socket.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +fi + PHP_ADD_SOURCES(/main, internal_functions.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, sapi) PHP_ADD_SOURCES_X(/main, internal_functions_cli.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_BINARY_OBJS) @@ -1757,6 +1776,10 @@ PHP_ADD_SOURCES(Zend, \ Optimizer/zend_dump.c \ , -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +if test "$WASI" = "yes"; then + PHP_ADD_SOURCES(Zend, zend_wasi.c zend_fibers_wasi.c zend_virtual_cwd_wasi.c,) +fi + PHP_ADD_BUILD_DIR(main main/streams) PHP_ADD_BUILD_DIR(TSRM) PHP_ADD_BUILD_DIR(Zend Zend/asm Zend/Optimizer) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 1c84ddcc98947..97b0ee87eeaa4 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -66,9 +66,9 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #include #endif -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) # include -#else +#elif defined(PHP_WIN32) #include "win32/inet.h" #endif @@ -349,8 +349,10 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ php_register_url_stream_wrapper("glob", &php_glob_stream_wrapper); #endif php_register_url_stream_wrapper("data", &php_stream_rfc2397_wrapper); +#ifndef PHP_WASI php_register_url_stream_wrapper("http", &php_stream_http_wrapper); php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper); +#endif // PHP_WASI BASIC_MINIT_SUBMODULE(hrtime) @@ -1427,7 +1429,11 @@ PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_le break; default: +#ifdef HAVE_SYSLOG_H php_log_err_with_severity(message, LOG_NOTICE); +#else + php_log_err_with_severity(message, 5); +#endif break; } return SUCCESS; @@ -2382,7 +2388,7 @@ PHP_FUNCTION(move_uploaded_file) size_t path_len, new_path_len; bool successful = 0; -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) int oldmask; int ret; #endif @@ -2405,7 +2411,7 @@ PHP_FUNCTION(move_uploaded_file) if (VCWD_RENAME(path, new_path) == 0) { successful = 1; -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) oldmask = umask(077); umask(oldmask); diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 9ce2224a78292..3497aa8261921 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -739,6 +739,7 @@ /* error levels */ +#ifndef PHP_WASI /** * system unusable * @var int @@ -933,6 +934,7 @@ */ const LOG_PERROR = UNKNOWN; #endif +#endif /* string.c */ @@ -2103,6 +2105,8 @@ function strptime(string $timestamp, string $format): array|false {} /* dns.c */ +#ifndef PHP_WASI + #ifdef HAVE_GETHOSTNAME /** @refcount 1 */ function gethostname(): string|false {} @@ -2148,6 +2152,8 @@ function dns_get_mx(string $hostname, &$hosts, &$weights = null): bool {} function getmxrr(string $hostname, &$hosts, &$weights = null): bool {} #endif +#endif + /* net.c */ #if (defined(PHP_WIN32) || HAVE_GETIFADDRS || defined(__PASE__)) diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 1fb54cd02d8ef..6aed40956b39d 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b0767630614e040866bd7ffdaf50dd31298a64f3 */ + * Stub hash: 3ac35fd4af803d1fd3796c2c36ea61f2bff040ae */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -610,35 +610,41 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strptime, 0, 2, MAY_BE_ARRAY|MAY ZEND_END_ARG_INFO() #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gethostname, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) ZEND_END_ARG_INFO() #endif +#if !defined(PHP_WASI) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gethostbyaddr, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, ip, IS_STRING, 0) ZEND_END_ARG_INFO() +#endif +#if !defined(PHP_WASI) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gethostbyname, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_END_ARG_INFO() +#endif +#if !defined(PHP_WASI) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gethostbynamel, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_END_ARG_INFO() +#endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dns_check_record, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 0, "\"MX\"") ZEND_END_ARG_INFO() #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) #define arginfo_checkdnsrr arginfo_dns_check_record #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_dns_get_record, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_LONG, 0, "DNS_ANY") @@ -648,7 +654,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_dns_get_record, 0, 1, MAY_BE_ARR ZEND_END_ARG_INFO() #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dns_get_mx, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_ARG_INFO(1, hosts) @@ -656,7 +662,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dns_get_mx, 0, 2, _IS_BOOL, 0) ZEND_END_ARG_INFO() #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) #define arginfo_getmxrr arginfo_dns_get_mx #endif @@ -2369,19 +2375,25 @@ ZEND_FUNCTION(crypt); #if defined(HAVE_STRPTIME) ZEND_FUNCTION(strptime); #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) ZEND_FUNCTION(gethostname); #endif +#if !defined(PHP_WASI) ZEND_FUNCTION(gethostbyaddr); +#endif +#if !defined(PHP_WASI) ZEND_FUNCTION(gethostbyname); +#endif +#if !defined(PHP_WASI) ZEND_FUNCTION(gethostbynamel); -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#endif +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FUNCTION(dns_check_record); #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FUNCTION(dns_get_record); #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FUNCTION(dns_get_mx); #endif #if (defined(PHP_WIN32) || HAVE_GETIFADDRS || defined(__PASE__)) @@ -2995,25 +3007,31 @@ static const zend_function_entry ext_functions[] = { #if defined(HAVE_STRPTIME) ZEND_DEP_FE(strptime, arginfo_strptime) #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) ZEND_FE(gethostname, arginfo_gethostname) #endif +#if !defined(PHP_WASI) ZEND_FE(gethostbyaddr, arginfo_gethostbyaddr) +#endif +#if !defined(PHP_WASI) ZEND_FE(gethostbyname, arginfo_gethostbyname) +#endif +#if !defined(PHP_WASI) ZEND_FE(gethostbynamel, arginfo_gethostbynamel) -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#endif +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FE(dns_check_record, arginfo_dns_check_record) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FALIAS(checkdnsrr, dns_check_record, arginfo_checkdnsrr) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FE(dns_get_record, arginfo_dns_get_record) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FE(dns_get_mx, arginfo_dns_get_mx) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FALIAS(getmxrr, dns_get_mx, arginfo_getmxrr) #endif #if (defined(PHP_WIN32) || HAVE_GETIFADDRS || defined(__PASE__)) @@ -3669,65 +3687,103 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("CREDITS_FULLPAGE", PHP_CREDITS_FULLPAGE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CREDITS_QA", PHP_CREDITS_QA, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CREDITS_ALL", PHP_CREDITS_ALL, CONST_PERSISTENT); +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_PERSISTENT); -#if defined(LOG_NEWS) +#endif +#if !defined(PHP_WASI) && defined(LOG_NEWS) REGISTER_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_PERSISTENT); #endif -#if defined(LOG_UUCP) +#if !defined(PHP_WASI) && defined(LOG_UUCP) REGISTER_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_PERSISTENT); #endif -#if defined(LOG_CRON) +#if !defined(PHP_WASI) && defined(LOG_CRON) REGISTER_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_PERSISTENT); #endif -#if defined(LOG_AUTHPRIV) +#if !defined(PHP_WASI) && defined(LOG_AUTHPRIV) REGISTER_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_PERSISTENT); #endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_PERSISTENT); -#if defined(LOG_NOWAIT) +#endif +#if !defined(PHP_WASI) && defined(LOG_NOWAIT) REGISTER_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_PERSISTENT); #endif -#if defined(LOG_PERROR) +#if !defined(PHP_WASI) && defined(LOG_PERROR) REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_PERSISTENT); #endif REGISTER_LONG_CONSTANT("STR_PAD_LEFT", PHP_STR_PAD_LEFT, CONST_PERSISTENT); diff --git a/ext/standard/basic_functions_wasi.c b/ext/standard/basic_functions_wasi.c new file mode 100644 index 0000000000000..e8bf65232996e --- /dev/null +++ b/ext/standard/basic_functions_wasi.c @@ -0,0 +1,19 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include + +mode_t umask(mode_t mask) { + return 0; +} diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index 984dfcd8a256e..637cab9b665cd 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -445,20 +445,26 @@ dnl dnl Setup extension sources dnl PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32.c crypt.c \ - datetime.c dir.c dl.c dns.c exec.c file.c filestat.c \ - flock_compat.c formatted_print.c fsock.c head.c html.c image.c \ + datetime.c dir.c dl.c exec.c file.c filestat.c \ + formatted_print.c fsock.c head.c html.c image.c \ info.c iptc.c link.c mail.c math.c md5.c metaphone.c \ microtime.c pack.c pageinfo.c quot_print.c \ soundex.c string.c scanf.c syslog.c type.c uniqid.c url.c \ var.c versioning.c assert.c strnatcmp.c levenshtein.c \ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ + incomplete_class.c url_scanner_ex.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ - filters.c proc_open.c streamsfuncs.c http.c password.c \ - net.c hrtime.c crc32_x86.c libavifinfo/avifinfo.c,,, + filters.c php_fopen_wrapper.c proc_open.c streamsfuncs.c http.c \ + password.c net.c hrtime.c crc32_x86.c libavifinfo/avifinfo.c \ + $stdlib_extra_sources,,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_ADD_BUILD_DIR($ext_builddir/libavifinfo) +if test "$WASI" = "yes"; then + PHP_ADD_SOURCES(ext/standard, basic_functions_wasi.c exec_wasi.c file_wasi.c filestat_wasi.c flock_wasi.c mail_wasi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +else + PHP_ADD_SOURCES(ext/standard, dns.c flock_compat.c ftp_fopen_wrapper.c http_fopen_wrapper.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +fi + PHP_ADD_MAKEFILE_FRAGMENT PHP_INSTALL_HEADERS([ext/standard/]) diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 1b1b0ab9e9ce1..d4a7552fb7039 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -104,6 +104,8 @@ static size_t handle_line(int type, zval *array, char *buf, size_t bufl) { return bufl; } +#ifndef PHP_WASI + /* {{{ php_exec * If type==0, only last line of output is returned (exec) * If type==1, all lines will be printed and last lined returned (system) @@ -203,6 +205,12 @@ PHPAPI int php_exec(int type, const char *cmd, zval *array, zval *return_value) } /* }}} */ +#else + +int php_exec(int type, const char *cmd, zval *array, zval *return_value); + +#endif // PHP_WASI + static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ { char *cmd; @@ -509,8 +517,9 @@ PHP_FUNCTION(escapeshellarg) } /* }}} */ -/* {{{ Execute command via shell and return complete output as string */ -PHP_FUNCTION(shell_exec) +#ifndef PHP_WASI + +static void php_shell_exec_ex(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { FILE *in; char *command; @@ -547,6 +556,19 @@ PHP_FUNCTION(shell_exec) if (ret && ZSTR_LEN(ret) > 0) { RETVAL_STR(ret); } + } +/* }}} */ + +#else + +void php_shell_exec_ex(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Execute command via shell and return complete output as string */ +PHP_FUNCTION(shell_exec) /* {{{ */ +{ + php_shell_exec_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ diff --git a/ext/standard/exec_wasi.c b/ext/standard/exec_wasi.c new file mode 100644 index 0000000000000..ac3c0a5cf0ad9 --- /dev/null +++ b/ext/standard/exec_wasi.c @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI int php_exec(int type, const char *cmd, zval *array, zval *return_value) /* {{{ */ +{ + return -1; +} +/* }}} */ + +PHPAPI void php_shell_exec_ex(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ diff --git a/ext/standard/file.c b/ext/standard/file.c index f6076438f69d6..bdc39ab869a05 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -55,7 +55,9 @@ # endif # include # include -# include +# ifndef PHP_WASI +# include +# endif // PHP_WASI # if HAVE_ARPA_INET_H # include # endif @@ -790,8 +792,9 @@ PHPAPI PHP_FUNCTION(fclose) } /* }}} */ -/* {{{ Execute a command and open either a read or a write pipe to it */ -PHP_FUNCTION(popen) +#ifndef PHP_WASI + +static void php_popen(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { char *command, *mode; size_t command_len, mode_len; @@ -845,6 +848,19 @@ PHP_FUNCTION(popen) } /* }}} */ +#else + +void php_popen(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Execute a command and open either a read or a write pipe to it */ +PHP_FUNCTION(popen) /* {{{ */ +{ + php_popen(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + /* {{{ Close a file pointer opened by popen() */ PHP_FUNCTION(pclose) { @@ -1220,8 +1236,9 @@ PHP_FUNCTION(readfile) } /* }}} */ -/* {{{ Return or change the umask */ -PHP_FUNCTION(umask) +#ifndef PHP_WASI + +static void php_umask(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { zend_long mask = 0; bool mask_is_null = 1; @@ -1248,6 +1265,19 @@ PHP_FUNCTION(umask) } /* }}} */ +#else + +void php_umask(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Return or change the umask */ +PHP_FUNCTION(umask) /* {{{ */ +{ + php_umask(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + /* {{{ Output all remaining data from a file pointer */ PHPAPI PHP_FUNCTION(fpassthru) { diff --git a/ext/standard/file_wasi.c b/ext/standard/file_wasi.c new file mode 100644 index 0000000000000..961d47e77e789 --- /dev/null +++ b/ext/standard/file_wasi.c @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" + +PHPAPI void php_popen(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ + +PHPAPI void php_umask(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_LONG(0); +} +/* }}} */ diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 131011715be78..20e203b2b151a 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -271,7 +271,7 @@ PHP_FUNCTION(disk_free_space) } /* }}} */ -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) PHPAPI zend_result php_get_gid_by_name(const char *name, gid_t *gid) { #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX) @@ -303,6 +303,7 @@ PHPAPI zend_result php_get_gid_by_name(const char *name, gid_t *gid) } #endif +#ifndef PHP_WASI static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ { char *filename; @@ -380,6 +381,11 @@ static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ #endif } /* }}} */ +#else + +void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp); + +#endif // PHP_WASI /* {{{ Change file group */ PHP_FUNCTION(chgrp) @@ -397,8 +403,14 @@ PHP_FUNCTION(lchgrp) #endif /* }}} */ -#ifndef PHP_WIN32 -PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) +#ifdef PHP_WASI +PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) /* {{{ */ +{ + return FAILURE; +} +/* }}} */ +#elif !defined(PHP_WIN32) +PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) /* {{{ */ { #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R) struct passwd pw; @@ -427,8 +439,10 @@ PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) #endif return SUCCESS; } -#endif +/* }}} */ +#endif // PHP_WASI +#ifndef PHP_WASI static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */ { char *filename; @@ -508,6 +522,11 @@ static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */ } /* }}} */ +#else + +void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown); + +#endif // PHP_WASI /* {{{ Change file owner */ PHP_FUNCTION(chown) @@ -526,8 +545,8 @@ PHP_FUNCTION(lchown) #endif /* }}} */ -/* {{{ Change file mode */ -PHP_FUNCTION(chmod) +#ifndef PHP_WASI +static void php_do_chmod(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { char *filename; size_t filename_len; @@ -569,6 +588,17 @@ PHP_FUNCTION(chmod) } RETURN_TRUE; } +#else + +void php_do_chmod(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Change file mode */ +PHP_FUNCTION(chmod) +{ + php_do_chmod(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} /* }}} */ #ifdef HAVE_UTIME @@ -819,6 +849,8 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) } } while (0); + +#ifndef PHP_WASI if (type >= FS_IS_W && type <= FS_IS_X) { if(stat_sb->st_uid==getuid()) { rmask=S_IRUSR; @@ -859,6 +891,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) } } } +#endif // PHP_WASI switch (type) { case FS_PERMS: @@ -883,7 +916,9 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) RETURN_STRING("link"); } switch(stat_sb->st_mode & S_IFMT) { +#ifndef PHP_WASI case S_IFIFO: RETURN_STRING("fifo"); +#endif // PHP_WASI case S_IFCHR: RETURN_STRING("char"); case S_IFDIR: RETURN_STRING("dir"); case S_IFBLK: RETURN_STRING("block"); diff --git a/ext/standard/filestat_wasi.c b/ext/standard/filestat_wasi.c new file mode 100644 index 0000000000000..6dda57781999e --- /dev/null +++ b/ext/standard/filestat_wasi.c @@ -0,0 +1,33 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ + +PHPAPI void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ + +PHPAPI void php_do_chmod(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ diff --git a/ext/standard/flock_wasi.c b/ext/standard/flock_wasi.c new file mode 100644 index 0000000000000..49df6d222cb51 --- /dev/null +++ b/ext/standard/flock_wasi.c @@ -0,0 +1,22 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sascha Schumann | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" + +PHPAPI int flock(int fd, int operation) +{ + return -1; +} diff --git a/ext/standard/mail.c b/ext/standard/mail.c index b1e0f14b8d5e2..90197925df4b6 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -371,6 +371,8 @@ static int php_mail_detect_multiple_crlf(const char *hdr) { } +#ifndef PHP_WASI + /* {{{ php_mail */ PHPAPI int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) { @@ -558,6 +560,8 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co } /* }}} */ +#endif // PHP_WASI + /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(mail) { diff --git a/ext/standard/mail_wasi.c b/ext/standard/mail_wasi.c new file mode 100644 index 0000000000000..1da5d64afbac5 --- /dev/null +++ b/ext/standard/mail_wasi.c @@ -0,0 +1,22 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sascha Schumann | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" + +PHPAPI int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) +{ + return 0; +} diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c index ca8643eb5196f..fad841aa78b54 100644 --- a/ext/standard/microtime.c +++ b/ext/standard/microtime.c @@ -125,7 +125,7 @@ PHP_FUNCTION(getrusage) #ifdef PHP_WIN32 /* Windows only implements a limited amount of fields from the rusage struct */ PHP_RUSAGE_PARA(ru_majflt); PHP_RUSAGE_PARA(ru_maxrss); -#elif !defined(_OSD_POSIX) && !defined(__HAIKU__) +#elif !defined(_OSD_POSIX) && !defined(__HAIKU__) && !defined(PHP_WASI) PHP_RUSAGE_PARA(ru_oublock); PHP_RUSAGE_PARA(ru_inblock); PHP_RUSAGE_PARA(ru_msgsnd); @@ -139,7 +139,7 @@ PHP_FUNCTION(getrusage) PHP_RUSAGE_PARA(ru_nvcsw); PHP_RUSAGE_PARA(ru_nivcsw); PHP_RUSAGE_PARA(ru_nswap); -#endif /*_OSD_POSIX*/ +#endif /* !defined(_OSD_POSIX) && !defined(__HAIKU__) && !defined(PHP_WASI) */ PHP_RUSAGE_PARA(ru_utime.tv_usec); PHP_RUSAGE_PARA(ru_utime.tv_sec); PHP_RUSAGE_PARA(ru_stime.tv_usec); diff --git a/ext/standard/net.c b/ext/standard/net.c index b22f304c8eb33..aeec02004aa34 100644 --- a/ext/standard/net.c +++ b/ext/standard/net.c @@ -43,10 +43,11 @@ # include # include # include -#else +#elif !defined(PHP_WASI) # include #endif +#ifndef PHP_WASI PHPAPI zend_string* php_inet_ntop(const struct sockaddr *addr) { socklen_t addrlen = sizeof(struct sockaddr_in); @@ -101,6 +102,7 @@ PHPAPI zend_string* php_inet_ntop(const struct sockaddr *addr) { return NULL; } +#endif // PHP_WASI #if defined(PHP_WIN32) || defined(HAVE_GETIFADDRS) || defined(__PASE__) static void iface_append_unicast(zval *unicast, zend_long flags, @@ -151,6 +153,7 @@ array( ), // etc... ) */ +#ifndef PHP_WASI PHP_FUNCTION(net_get_interfaces) { #ifdef PHP_WIN32 # define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) @@ -311,3 +314,4 @@ PHP_FUNCTION(net_get_interfaces) { } #endif /* }}} */ +#endif // PHP_WASI diff --git a/ext/standard/pageinfo.c b/ext/standard/pageinfo.c index f24659a95e048..a9ebf4a3d244e 100644 --- a/ext/standard/pageinfo.c +++ b/ext/standard/pageinfo.c @@ -35,6 +35,9 @@ #define getgroups(a, b) 0 #define getgid() 1 #define getuid() 1 +#elif defined(PHP_WASI) +#define getgid() 1 +#define getuid() 1 #endif #ifdef HAVE_UNISTD_H #include diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 8926485025a3b..5c424fa9a83fe 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(PHP_WASI) dtablesize = getdtablesize(); #else dtablesize = INT_MAX; @@ -390,7 +390,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa return NULL; } -#if defined(S_IFSOCK) && !defined(PHP_WIN32) +#if defined(S_IFSOCK) && !defined(PHP_WIN32) && !defined(PHP_WASI) do { zend_stat_t st = {0}; memset(&st, 0, sizeof(st)); diff --git a/main/fastcgi_wasi.c b/main/fastcgi_wasi.c new file mode 100644 index 0000000000000..0e350db30f911 --- /dev/null +++ b/main/fastcgi_wasi.c @@ -0,0 +1,81 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +int fcgi_is_fastcgi(void) { + return 0; +} + +struct _fcgi_request {}; +typedef struct _fcgi_request fcgi_request; + +enum _fcgi_request_type { FCGI_NONE = 1 }; +typedef enum _fcgi_request_type fcgi_request_type; + +typedef void (*fcgi_apply_func)(const char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg); + +void fcgi_terminate(void) {} + +void fcgi_loadenv(fcgi_request *req, fcgi_apply_func func, zval *array) {} + +int fcgi_listen(const char *path, int backlog) { + return -1; +} + +fcgi_request *fcgi_init_request(int listen_socket, void(*on_accept)(void), void(*on_read)(void), void(*on_close)(void)) { + return NULL; +} + +void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len) {} + +void fcgi_destroy_request(fcgi_request *req) {} + +void fcgi_shutdown(void) {} + +int fcgi_accept_request(fcgi_request *req) { + return 0; +} + +int fcgi_has_env(fcgi_request *req) { + return 0; +} + +char* fcgi_quick_getenv(fcgi_request *req, const char* var, int var_len, unsigned int hash_value) { + return NULL; +} + +char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val) { + return NULL; +} + +int fcgi_finish_request(fcgi_request *req, int force_close) { + return 0; +} + +char* fcgi_getenv(fcgi_request *req, const char* var, int var_len) { + return NULL; +} + +int fcgi_read(fcgi_request *req, char *str, int len) { + return 0; +} + +int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len) { + return 0; +} + +int fcgi_flush(fcgi_request *req, int end) { + return 0; +} diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index ead11a958b32a..e97712754b340 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -52,7 +52,9 @@ #include #else #include +#ifndef PHP_WASI #include +#endif // PHP_WASI #if HAVE_ARPA_INET_H #include #endif diff --git a/main/main.c b/main/main.c index d918e0b73ae78..d85ca959b1a3e 100644 --- a/main/main.c +++ b/main/main.c @@ -1191,7 +1191,7 @@ static void clear_last_error(void) { } } -#if ZEND_DEBUG +#if ZEND_DEBUG && !defined(PHP_WASI) /* {{{ report_zend_debug_error_notify_cb */ static void report_zend_debug_error_notify_cb(int type, zend_string *error_filename, uint32_t error_lineno, zend_string *message) { @@ -1461,11 +1461,14 @@ PHPAPI char *php_get_current_user(void) return ""; } pwd = &_pw; +#elif defined(PHP_WASI) + return ""; #else if ((pwd=getpwuid(pstat->st_uid))==NULL) { return ""; } #endif +#ifndef PHP_WASI SG(request_info).current_user_length = strlen(pwd->pw_name); SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length); #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX) @@ -1473,6 +1476,7 @@ PHPAPI char *php_get_current_user(void) #endif return SG(request_info).current_user; #endif +#endif // PHP_WASI } } /* }}} */ diff --git a/main/network_wasi.c b/main/network_wasi.c new file mode 100644 index 0000000000000..4fc6a45bc68d6 --- /dev/null +++ b/main/network_wasi.c @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI int php_network_parse_network_address_with_port(const char *addr, zend_long addrlen, struct sockaddr *sa, socklen_t *sl) +{ + return FAILURE; +} + +PHPAPI int php_set_sock_blocking(int socketd, int block) +{ + return FAILURE; +} + +PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) +{ + return NULL; +} + +PHPAPI void _php_emit_fd_setsize_warning(int max_fd) +{ +} diff --git a/main/php.h b/main/php.h index 3385fb799927e..9fc31ae020479 100644 --- a/main/php.h +++ b/main/php.h @@ -51,6 +51,10 @@ # define PHP_OS_FAMILY "Unknown" #endif +#ifdef __wasi__ +#define PHP_WASI __wasi__ +#endif + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ #undef PHP_DEBUG #define PHP_DEBUG ZEND_DEBUG diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index dcea78358486d..3b73f414891e4 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -30,7 +30,9 @@ #include #include #include +#ifndef PHP_WASI #include +#endif // PHP_WASI #if HAVE_ARPA_INET_H #include #endif @@ -84,6 +86,7 @@ * SUCH DAMAGE. */ +#ifndef PHP_WASI static int php_do_open_temporary_file(const char *path, const char *pfx, zend_string **opened_path_p) { #ifdef PHP_WIN32 @@ -196,11 +199,13 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st efree(new_state.cwd); return fd; } +#endif // PHP_WASI /* }}} */ /* * Determine where to place temporary files. */ +#ifndef PHP_WASI PHPAPI const char* php_get_temporary_directory(void) { /* Did we determine the temporary directory already? */ @@ -275,6 +280,7 @@ PHPAPI const char* php_get_temporary_directory(void) return PG(php_sys_temp_dir); #endif } +#endif // PHP_WASI /* {{{ php_open_temporary_file * diff --git a/main/php_open_temporary_file_wasi.c b/main/php_open_temporary_file_wasi.c new file mode 100644 index 0000000000000..793c254401a5b --- /dev/null +++ b/main/php_open_temporary_file_wasi.c @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI const char* php_get_temporary_directory(void) +{ + return NULL; +} + +PHPAPI int php_do_open_temporary_file(const char *path, const char *pfx, zend_string **opened_path_p) +{ + return -1; +} diff --git a/main/php_syslog.h b/main/php_syslog.h index f2682d74f2382..2563786e2c215 100644 --- a/main/php_syslog.h +++ b/main/php_syslog.h @@ -21,6 +21,8 @@ #ifdef PHP_WIN32 #include "win32/syslog.h" +#elif defined(PHP_WASI) +#include "wasi/syslog.h" #else #include #ifdef HAVE_SYSLOG_H diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 86c517132482e..b9f76b53b7c1f 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -47,7 +47,7 @@ #define php_stream_fopen_from_file_int(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_CC) #define php_stream_fopen_from_file_int_rel(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_REL_CC) -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) extern int php_get_uid_by_name(const char *name, uid_t *uid); extern int php_get_gid_by_name(const char *name, gid_t *gid); #endif @@ -491,6 +491,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle) if (close_handle) { if (data->file) { +#ifndef PHP_WASI if (data->is_process_pipe) { errno = 0; ret = pclose(data->file); @@ -504,6 +505,10 @@ static int php_stdiop_close(php_stream *stream, int close_handle) ret = fclose(data->file); data->file = NULL; } +#else // PHP_WASI + ret = fclose(data->file); + data->file = NULL; +#endif // PHP_WASI } else if (data->fd != -1) { ret = close(data->fd); data->fd = -1; @@ -1307,7 +1312,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f # ifdef EXDEV if (errno == EXDEV) { zend_stat_t sb; -# if !defined(ZTS) && !defined(TSRM_WIN32) +# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(PHP_WASI) /* not sure what to do in ZTS case, umask is not thread-safe */ int oldmask = umask(077); # endif @@ -1315,7 +1320,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f if (php_copy_file(url_from, url_to) == SUCCESS) { if (VCWD_STAT(url_from, &sb) == 0) { success = 1; -# ifndef TSRM_WIN32 +# if !defined(TSRM_WIN32) && !defined(PHP_WASI) /* * Try to set user and permission info on the target. * If we're not root, then some of these may fail. @@ -1348,7 +1353,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f } else { php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); } -# if !defined(ZTS) && !defined(TSRM_WIN32) +# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(PHP_WASI) umask(oldmask); # endif return success; @@ -1529,7 +1534,7 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url ret = VCWD_UTIME(url, newtime); break; -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) case PHP_STREAM_META_OWNER_NAME: case PHP_STREAM_META_OWNER: if(option == PHP_STREAM_META_OWNER_NAME) { @@ -1555,10 +1560,12 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url ret = VCWD_CHOWN(url, -1, gid); break; #endif +#ifndef PHP_WASI case PHP_STREAM_META_ACCESS: mode = (mode_t)*(zend_long *)value; ret = VCWD_CHMOD(url, mode); break; +#endif default: zend_value_error("Unknown option %d for stream_metadata", option); return 0; diff --git a/main/streams/streams.c b/main/streams/streams.c index 06589e649c2ec..bad8df2940af6 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1839,6 +1839,9 @@ int php_init_stream_wrappers(int module_number) zend_hash_init(php_get_stream_filters_hash_global(), 8, NULL, NULL, 1); zend_hash_init(php_stream_xport_get_hash(), 8, NULL, NULL, 1); +#ifdef PHP_WASI + return SUCCESS; +#else return (php_stream_xport_register("tcp", php_stream_generic_socket_factory) == SUCCESS && php_stream_xport_register("udp", php_stream_generic_socket_factory) == SUCCESS @@ -1849,6 +1852,7 @@ int php_init_stream_wrappers(int module_number) php_stream_xport_register("udg", php_stream_generic_socket_factory) == SUCCESS #endif ) ? SUCCESS : FAILURE; +#endif // PHP_WASI } void php_shutdown_stream_wrappers(int module_number) diff --git a/main/unistd_wasi.c b/main/unistd_wasi.c new file mode 100644 index 0000000000000..dab39c0beee4f --- /dev/null +++ b/main/unistd_wasi.c @@ -0,0 +1,21 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include + +int dup(int fildes) +{ + errno = ENOTSUP; + return -1; +} diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 156599f6f9d4d..af1c477303ca9 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -95,7 +95,7 @@ int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS; # include "valgrind/callgrind.h" #endif -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) /* XXX this will need to change later when threaded fastcgi is implemented. shane */ struct sigaction act, old_term, old_quit, old_int; #endif @@ -1450,7 +1450,7 @@ static void init_request_info(fcgi_request *request) } /* }}} */ -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) /** * Clean up child processes upon exit */ @@ -1471,7 +1471,7 @@ void fastcgi_cleanup(int signal) exit(0); } } -#else +#elif defined(PHP_WIN32) BOOL WINAPI fastcgi_cleanup(DWORD sig) { int i = kids; @@ -1982,7 +1982,7 @@ consult the installation file that came with this distribution, or visit \n\ fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, "1", sizeof("1")-1); } -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) if (children) { int running = 0; pid_t pid; @@ -2070,7 +2070,7 @@ consult the installation file that came with this distribution, or visit \n\ zend_signal_init(); } -#else +#elif defined(PHP_WIN32) if (children) { wchar_t *cmd_line_tmp, cmd_line[PHP_WIN32_IOUTIL_MAXPATHLEN]; size_t cmd_line_len; diff --git a/sapi/cgi/config9.m4 b/sapi/cgi/config9.m4 index 04bd70b269ee6..6aa31ea39a8c4 100644 --- a/sapi/cgi/config9.m4 +++ b/sapi/cgi/config9.m4 @@ -54,6 +54,9 @@ if test "$PHP_CGI" != "no"; then *darwin*) BUILD_CGI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" ;; + *wasi*) + BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + ;; *) BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" ;; diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4 index d17d531683605..9b3518332ca91 100644 --- a/sapi/cli/config.m4 +++ b/sapi/cli/config.m4 @@ -4,6 +4,7 @@ PHP_ARG_ENABLE([cli],, [yes], [no]) +AC_CHECK_DEFINE([__wasi__], [WASI="yes"], []) AC_CHECK_FUNCS(setproctitle) AC_CHECK_HEADERS([sys/pstat.h]) @@ -28,7 +29,10 @@ if test "$PHP_CLI" != "no"; then SAPI_CLI_PATH=sapi/cli/php dnl Select SAPI. - PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c php_cli_server.c ps_title.c php_cli_process_title.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, '$(SAPI_CLI_PATH)') + if test "$WASI" != "yes"; then + cli_extra_sources="php_cli_server.c" + fi + PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c ps_title.c php_cli_process_title.c $cli_extra_sources, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, '$(SAPI_CLI_PATH)') case $host_alias in *aix*) @@ -41,6 +45,9 @@ if test "$PHP_CLI" != "no"; then *darwin*) BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" ;; + *wasi*) + BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ;; *) BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" ;; diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 546c4ba997dc3..2db2959c40cb4 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1259,7 +1259,7 @@ int main(int argc, char *argv[]) /* define ini entries on command line */ php_ini_builder_define(&ini_builder, php_optarg); break; -#ifndef PHP_CLI_WIN32_NO_CONSOLE +#if !defined(PHP_CLI_WIN32_NO_CONSOLE) && !defined(PHP_WASI) case 'S': sapi_module = &cli_server_sapi_module; cli_server_sapi_module.additional_functions = server_additional_functions; @@ -1331,11 +1331,11 @@ int main(int argc, char *argv[]) } zend_first_try { -#ifndef PHP_CLI_WIN32_NO_CONSOLE +#if !defined(PHP_CLI_WIN32_NO_CONSOLE) && !defined(PHP_WASI) if (sapi_module == &cli_sapi_module) { #endif exit_status = do_cli(argc, argv); -#ifndef PHP_CLI_WIN32_NO_CONSOLE +#if !defined(PHP_CLI_WIN32_NO_CONSOLE) && !defined(PHP_WASI) } else { exit_status = do_cli_server(argc, argv); } diff --git a/wasi/syslog.h b/wasi/syslog.h new file mode 100644 index 0000000000000..39768a093b7e8 --- /dev/null +++ b/wasi/syslog.h @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef SYSLOG_H +#define SYSLOG_H + +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ + +#endif // SYSLOG_H From 908a7a7292615381744bafb0ee0299f2a02011e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Fern=C3=A1ndez=20L=C3=B3pez?= Date: Wed, 1 Feb 2023 17:42:41 +0100 Subject: [PATCH 2/2] Implement WebAssembly + WASI GH actions WebAssembly + WASI GH actions have specific tasks for the following steps: - apt: an existing PHP installation will be used as the test runner, as opposed to the binary being built. It also installs other dependencies used by later stages, such as Wasmtime (WebAssembly runtime), and Binaryen (contains `wasm-opt`, to be used on the optimization phase.) - configure-wasi: specific configure values. - optimize-wasi (new action): performs binaryen optimization passes on the resulting binary. - test-wasi: requires a wrapper that will use `wasmtime` to run the `php` CLI compiled to WebAssembly. --- .github/actions/apt-wasi/action.yml | 48 +++++++++++++++++++++++ .github/actions/configure-wasi/action.yml | 48 +++++++++++++++++++++++ .github/actions/optimize-wasi/action.yml | 14 +++++++ .github/actions/test-wasi/action.yml | 46 ++++++++++++++++++++++ .github/workflows/push.yml | 34 ++++++++++++++++ 5 files changed, 190 insertions(+) create mode 100644 .github/actions/apt-wasi/action.yml create mode 100644 .github/actions/configure-wasi/action.yml create mode 100644 .github/actions/optimize-wasi/action.yml create mode 100644 .github/actions/test-wasi/action.yml diff --git a/.github/actions/apt-wasi/action.yml b/.github/actions/apt-wasi/action.yml new file mode 100644 index 0000000000000..1e664d6cfd53e --- /dev/null +++ b/.github/actions/apt-wasi/action.yml @@ -0,0 +1,48 @@ +name: apt +inputs: + wasi_sdk_version: + default: 19 + wasmtime_version: + default: 5.0.0 + binaryen_version: + default: 111 +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + sudo apt-get update + sudo apt-get install \ + php \ + libtool-bin \ + bison \ + re2c \ + tcl + - shell: bash + run: | + set -x + + wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{ inputs.wasi_sdk_version }}/wasi-sdk_${{ inputs.wasi_sdk_version }}.0_amd64.deb + sudo dpkg -i wasi-sdk_${{ inputs.wasi_sdk_version }}.0_amd64.deb + - shell: bash + run: | + echo /opt/wasi-sdk/bin >> $GITHUB_PATH + - shell: bash + run: | + set -x + + mkdir -p /opt/bin + + wget https://github.com/bytecodealliance/wasmtime/releases/download/v${{ inputs.wasmtime_version }}/wasmtime-v${{ inputs.wasmtime_version }}-x86_64-linux.tar.xz + tar -xvf wasmtime-v${{ inputs.wasmtime_version }}-x86_64-linux.tar.xz + mv wasmtime-v${{ inputs.wasmtime_version }}-x86_64-linux/wasmtime /opt/bin/ + - shell: bash + run: | + set -x + + mkdir -p /opt/bin + + wget https://github.com/WebAssembly/binaryen/releases/download/version_${{ inputs.binaryen_version }}/binaryen-version_${{ inputs.binaryen_version }}-x86_64-linux.tar.gz + tar -xvf binaryen-version_${{ inputs.binaryen_version }}-x86_64-linux.tar.gz --strip-components=2 -C /opt/bin binaryen-version_${{ inputs.binaryen_version }}/bin/wasm-opt diff --git a/.github/actions/configure-wasi/action.yml b/.github/actions/configure-wasi/action.yml new file mode 100644 index 0000000000000..8b450f4b5f34c --- /dev/null +++ b/.github/actions/configure-wasi/action.yml @@ -0,0 +1,48 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + ./buildconf --force + ./configure \ + --host=wasm32-wasi host_alias=wasm32-musl-wasi \ + --target=wasm32-wasi target_alias=wasm32-musl-wasi \ + --disable-all \ + --disable-ctype \ + --disable-dom \ + --disable-fiber-asm \ + --disable-fileinfo \ + --disable-filter \ + --disable-flatfile \ + --disable-huge-code-pages \ + --disable-inifile \ + --disable-mbregex \ + --disable-mysqlnd-compression-support \ + --disable-opcache \ + --disable-opcache-jit \ + --disable-pdo \ + --disable-phar \ + --disable-posix \ + --disable-session \ + --disable-simplexml \ + --disable-tokenizer \ + --disable-xml \ + --disable-xmlreader \ + --disable-xmlwriter \ + --disable-zend-signals \ + --without-cdb \ + --without-libxml \ + --without-openssl \ + --without-pcre-jit \ + --without-pear \ + --without-sqlite3 \ + CFLAGS="-D_WASI_EMULATED_GETPID -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_PROCESS_CLOCKS" \ + LDFLAGS="-lwasi-emulated-getpid -lwasi-emulated-signal -lwasi-emulated-process-clocks" \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/optimize-wasi/action.yml b/.github/actions/optimize-wasi/action.yml new file mode 100644 index 0000000000000..30e7ad2ac2bd0 --- /dev/null +++ b/.github/actions/optimize-wasi/action.yml @@ -0,0 +1,14 @@ +name: Optimize +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + /opt/bin/wasm-opt -O sapi/cli/php -o sapi/cli/php.optimized + - shell: bash + run: | + set -x + + /opt/bin/wasm-opt -O sapi/cgi/php-cgi -o sapi/cgi/php-cgi.optimized diff --git a/.github/actions/test-wasi/action.yml b/.github/actions/test-wasi/action.yml new file mode 100644 index 0000000000000..7882fecceaa99 --- /dev/null +++ b/.github/actions/test-wasi/action.yml @@ -0,0 +1,46 @@ +name: Test +inputs: + testArtifacts: + default: null + required: false + runTestsParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + cat <<-'EOF' > /opt/bin/wasmtime-run-cli.sh + #!/bin/bash + WASMTIME_BACKTRACE_DETAILS=1 /opt/bin/wasmtime run --mapdir /::/ "$PWD/sapi/cli/php.optimized" 2> /dev/null -- "$@" + EOF + chmod +x /opt/bin/wasmtime-run-cli.sh + cat <<-'EOF' > /opt/bin/wasmtime-run-cgi.sh + #!/bin/bash + WASMTIME_BACKTRACE_DETAILS=1 /opt/bin/wasmtime run --mapdir /::/ "$PWD/sapi/cgi/php-cgi.optimized" 2> /dev/null -- "$@" + EOF + chmod +x /opt/bin/wasmtime-run-cgi.sh + - shell: bash + run: | + set -x + export SKIP_IO_CAPTURE_TESTS=1 + export TEST_PHP_JUNIT=junit.out.xml + export STACK_LIMIT_DEFAULTS_CHECK=1 + export TEST_PHP_EXECUTABLE=/opt/bin/wasmtime-run-cli.sh + export TEST_PHP_CGI_EXECUTABLE=/opt/bin/wasmtime-run-cgi.sh + export TEST_PHPDBG_EXECUTABLE="" + php run-tests.php -q ${{ inputs.runTestsParameters }} \ + -j$(/usr/bin/nproc) \ + -g FAIL,BORK,LEAK,XLEAK \ + --no-progress \ + --offline \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 + - uses: actions/upload-artifact@v3 + if: always() && inputs.testArtifacts != null + with: + name: ${{ github.job }}_${{ inputs.testArtifacts }} + path: ${{ github.workspace }}/junit.out.xml + retention-days: 5 diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 35519428a166e..d8134d1b27140 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -312,3 +312,37 @@ jobs: ${{ github.sha }} \ $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \ > $GITHUB_STEP_SUMMARY + WASM32_WASI: + name: "WASM32_WASI_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: ubuntu-20.04 + env: + CC: clang + CXX: clang++ + LD: wasm-ld + AR: llvm-ar + RANLIB: llvm-ranlib + steps: + - name: git checkout + uses: actions/checkout@v3 + - name: apt + uses: ./.github/actions/apt-wasi + - name: ./configure + uses: ./.github/actions/configure-wasi + with: + configurationParameters: >- + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + - name: make + env: + CFLAGS: "-D_WASI_EMULATED_GETPID -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_PROCESS_CLOCKS" + LDFLAGS: "-lwasi-emulated-getpid -lwasi-emulated-signal -lwasi-emulated-process-clocks" + run: make -j$(/usr/bin/nproc) cgi cli + - name: Optimize + uses: ./.github/actions/optimize-wasi + # To be defined how to approach test coverage on this platform. + # - name: Test + # uses: ./.github/actions/test-wasi + # with: + # testArtifacts: ${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }} + # - name: Verify generated files are up to date + # uses: ./.github/actions/verify-generated-files