Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,22 @@ PHP_FUNCTION(post_message_to_js)
char *data;
int data_len;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data, &data_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) {
return;
}

char *response;
size_t response_len = js_module_onMessage(data, &response);
if (response_len != -1) {
if (response_len != (size_t)-1) {
#if PHP_MAJOR_VERSION >= 7
zend_string *return_string = zend_string_init(response, response_len, 0);
free(response);
RETURN_NEW_STR(return_string);
#else
RETVAL_STRINGL(response, response_len, 1);
free(response);
return;
#endif
} else {
RETURN_NULL();
}
Expand Down
33 changes: 27 additions & 6 deletions packages/php-wasm/compile/php-wasm-dns-polyfill/dns_polyfill.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,21 +119,27 @@ PHP_FUNCTION(dns_check_record)
HEADER *hp;
querybuf answer = {0};
char *hostname;
#if PHP_MAJOR_VERSION >= 7
size_t hostname_len;
size_t rectype_len = 0;
zend_string *rectype = NULL;
#else
int hostname_len;
int rectype_len = 0;
char *rectype = NULL;
#endif
int type = DNS_T_MX, i;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &hostname, &hostname_len, &rectype, &rectype_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &hostname, &hostname_len, &rectype, &rectype_len) == FAILURE) {
return;
}

if (hostname_len == 0) {
php_error_docref(NULL, E_WARNING, "Host cannot be empty");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host cannot be empty");
RETURN_FALSE;
}

php_error_docref(NULL, E_WARNING, "dns_check_record() always returns false in PHP.wasm.");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "dns_check_record() always returns false in PHP.wasm.");

RETURN_FALSE;
}
Expand All @@ -143,8 +149,13 @@ PHP_FUNCTION(dns_check_record)
PHP_FUNCTION(dns_get_record)
{
char *hostname;
#if PHP_MAJOR_VERSION >= 7
size_t hostname_len;
zend_long type_param = PHP_DNS_ANY;
#else
int hostname_len;
long type_param = PHP_DNS_ANY;
#endif
zval *authns = NULL, *addtl = NULL;
int type_to_fetch;
int dns_errno;
Expand All @@ -155,7 +166,7 @@ PHP_FUNCTION(dns_get_record)
int type, first_query = 1, store_results = 1;
zend_bool raw = 0;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz!z!b",
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz!z!b",
&hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) {
return;
}
Expand All @@ -173,7 +184,7 @@ PHP_FUNCTION(dns_get_record)
}
}

php_error_docref(NULL, E_WARNING, "dns_get_record() always returns an empty array in PHP.wasm.");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "dns_get_record() always returns an empty array in PHP.wasm.");

/* Initialize the return array */
array_init(return_value);
Expand All @@ -186,7 +197,11 @@ PHP_FUNCTION(dns_get_record)
PHP_FUNCTION(dns_get_mx)
{
char *hostname;
#if PHP_MAJOR_VERSION >= 7
size_t hostname_len;
#else
int hostname_len;
#endif
zval *mx_list, *weight_list = NULL;
int count, qdc;
u_short type, weight;
Expand All @@ -196,12 +211,18 @@ PHP_FUNCTION(dns_get_mx)
uint8_t *cp, *end;
int i;

#if PHP_MAJOR_VERSION >= 7
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STRING(hostname, hostname_len)
Z_PARAM_ZVAL(mx_list)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(weight_list)
ZEND_PARSE_PARAMETERS_END();
#else
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) {
return;
}
#endif

array_init(mx_list);
if (!mx_list) {
Expand All @@ -215,7 +236,7 @@ PHP_FUNCTION(dns_get_mx)
}
}

php_error_docref(NULL, E_WARNING, "dns_get_mx() always returns an empty array in PHP.wasm.");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "dns_get_mx() always returns an empty array in PHP.wasm.");

RETURN_FALSE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "Zend/zend_alloc.h"
#include "php_wasm_memory_storage.h"

#if PHP_MAJOR_VERSION >= 7

/**
* Allocate a chunk of memory.
*
Expand Down Expand Up @@ -112,6 +114,22 @@ PHP_MSHUTDOWN_FUNCTION(wasm_memory_storage)
return SUCCESS;
}

#else /* PHP < 7 */

/* Custom memory storage is not available in PHP 5.x.
* Provide no-op MINIT/MSHUTDOWN. */
PHP_MINIT_FUNCTION(wasm_memory_storage)
{
return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(wasm_memory_storage)
{
return SUCCESS;
}

#endif /* PHP_MAJOR_VERSION >= 7 */

/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(wasm_memory_storage)
{
Expand Down
103 changes: 76 additions & 27 deletions packages/php-wasm/compile/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,11 @@ RUN if [ "$WITH_SOAP" = "yes" ]; \
RUN if [ "$WITH_SQLITE" = "yes" ]; \
then \
echo -n ' --with-sqlite3 --enable-pdo --with-pdo-sqlite=/root/lib ' >> /root/.php-configure-flags; \
echo -n ' /root/lib/lib/libsqlite3.a ' >> /root/.emcc-php-wasm-sources; \
# PHP 5.6 bundles its own sqlite3 in ext/sqlite3/libsqlite/, so linking the
# external libsqlite3.a would cause duplicate symbol errors.
if [ "${PHP_VERSION%%.*}" -ge "7" ]; then \
echo -n ' /root/lib/lib/libsqlite3.a ' >> /root/.emcc-php-wasm-sources; \
fi; \
else \
echo -n ' --without-sqlite3 --disable-pdo ' >> /root/.php-configure-flags; \
fi
Expand Down Expand Up @@ -257,6 +261,12 @@ RUN if [ "$WITH_CURL" = "yes" ]; \
then \
echo -n ' --with-curl=/root/lib ' >> /root/.php-configure-flags; \
echo -n ' /root/lib/lib/libcurl.a ' >> /root/.emcc-php-wasm-sources; \
# PHP 5.x uses curl-config to detect cURL instead of pkg-config.
# Provide a shim so configure can find the pre-built library.
if [ "${PHP_VERSION%%.*}" -le "5" ]; then \
printf '#!/bin/sh\ncase "$1" in\n--version) echo "7.80.0" ;;\n--cflags) echo "-I/root/lib/include" ;;\n--libs) echo "-L/root/lib/lib -lcurl" ;;\n--prefix) echo "/root/lib" ;;\nesac\n' > /usr/local/bin/curl-config && \
chmod +x /usr/local/bin/curl-config; \
fi; \
fi;

# Add mbstring if needed
Expand Down Expand Up @@ -290,14 +300,16 @@ RUN cd /root && \
git apply --no-index /root/php${PHP_VERSION:0:3}*.patch -v && \
chmod +x /root/apply-mysqlnd-patch.sh && \
/root/apply-mysqlnd-patch.sh && \
if [[ "${PHP_VERSION:0:3}" < '8.3' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-up-to-8.2.patch -v; \
elif [[ "${PHP_VERSION:0:3}" == '8.3' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-8.3.patch -v; \
elif [[ "${PHP_VERSION:0:3}" == '8.4' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-8.4.patch -v; \
elif [[ "${PHP_VERSION:0:3}" == '8.5' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-8.5.patch -v; \
if [[ "${PHP_VERSION:0:1}" -ge "7" ]]; then \
if [[ "${PHP_VERSION:0:3}" < '8.3' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-up-to-8.2.patch -v; \
elif [[ "${PHP_VERSION:0:3}" == '8.3' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-8.3.patch -v; \
elif [[ "${PHP_VERSION:0:3}" == '8.4' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-8.4.patch -v; \
elif [[ "${PHP_VERSION:0:3}" == '8.5' ]]; then \
git apply --no-index /root/php-chunk-alloc-zend-assert-8.5.patch -v; \
fi; \
fi && \
touch php-src/patched

Expand All @@ -309,7 +321,9 @@ RUN if [ "$WITH_MYSQL" = "yes" ]; then \

# Download and prepare imagick extension if needed (PHP 7.4+)
# Use version 3.7.0 for PHP 7.x, master for PHP 8.x
RUN if [ "${PHP_VERSION:0:1}" -eq "7" ]; then \
# Skip entirely for PHP 5.x (imagick 3.7+ requires PHP 7+)
RUN if [ "${PHP_VERSION:0:1}" -ge "7" ]; then \
if [ "${PHP_VERSION:0:1}" -eq "7" ]; then \
IMAGICK_BRANCH="3.7.0"; \
else \
IMAGICK_BRANCH="master"; \
Expand All @@ -331,13 +345,22 @@ RUN if [ "${PHP_VERSION:0:1}" -eq "7" ]; then \
./buildconf --force; \
fi && \
echo -n ' --with-imagick=/root/lib --with-imagick-config=/root/lib/bin/wasm32-unknown-emscripten-MagickWand-config ' >> /root/.php-configure-flags && \
echo -n ' /root/lib/lib/libMagickWand-7.Q16HDRI.a /root/lib/lib/libMagickCore-7.Q16HDRI.a ' >> /root/.emcc-php-wasm-sources
echo -n ' /root/lib/lib/libMagickWand-7.Q16HDRI.a /root/lib/lib/libMagickCore-7.Q16HDRI.a ' >> /root/.emcc-php-wasm-sources; \
fi

# Disable phar.php generation for all builds (WASM binaries can't execute during build)
# This must run after buildconf but before configure
RUN /root/replace.sh 's/pharcmd=pharcmd/pharcmd=/g' /root/php-src/configure && \
/root/replace.sh 's/pharcmd_install=install-pharcmd/pharcmd_install=/g' /root/php-src/configure

# Fibers are a PHP 8.1+ feature. They are compiled as a custom assembly
# implementation by default. However, that implementation does not work with
# emscripten. The line below disables it for PHP 8.1+.
# See https://github.com/WordPress/wordpress-playground/issues/92
RUN if [[ "${PHP_VERSION:0:1}" -gt "8" || ( "${PHP_VERSION:0:1}" -eq "8" && "${PHP_VERSION:2:1}" -ge "1" ) ]]; then \
echo -n ' --disable-fiber-asm ' >> /root/.php-configure-flags; \
fi

# Build the patched PHP
WORKDIR /root/php-src
RUN source /root/emsdk/emsdk_env.sh && \
Expand All @@ -356,16 +379,8 @@ RUN source /root/emsdk/emsdk_env.sh && \
PKG_CONFIG_PATH="/root/lib/lib/pkgconfig:${PKG_CONFIG_PATH}" \
emconfigure ./configure \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH \
# Fibers are a PHP 8.1+ feature. They are compiled as
# a custom assembly implementation by default. However,
# that implementation does not work with emscripten.
# --disable-fiber-asm is added via .php-configure-flags for PHP 8.1+ only
#
# The line below disables it, forcing PHP to use the
# C implementation instead.
#
# See https://github.com/WordPress/wordpress-playground/issues/92
# for more context.
--disable-fiber-asm \
--enable-phar \
# --enable-json for PHP < 8.0:
--enable-json \
Expand Down Expand Up @@ -397,6 +412,12 @@ RUN source /root/emsdk/emsdk_env.sh && \
# @TODO: Identify the root cause behind these errors and fix them properly
RUN echo '#define ZEND_MM_ERROR 0' >> /root/php-src/main/php_config.h;

# PHP 5.6's configure detects "old" readdir_r (2-arg) but Emscripten provides
# the modern 3-arg version. Undefine the old variant.
RUN if grep -q 'HAVE_OLD_READDIR_R' /root/php-src/main/php_config.h 2>/dev/null; then \
echo '#undef HAVE_OLD_READDIR_R' >> /root/php-src/main/php_config.h; \
fi

# Force GD JPEG/PNG/WebP/AVIF support for external GD builds (PHP 8.1+)
# Configure checks may fail during cross-compilation, so we explicitly enable them
# after verifying the external libgd was built with these features.
Expand Down Expand Up @@ -431,10 +452,31 @@ fi;
RUN echo '#undef HAVE_ASM_GOTO' >> /root/php-src/main/php_config.h;
RUN echo '#define HAVE_ASM_GOTO 0' >> /root/php-src/main/php_config.h;
# Disable asm arithmetic.
RUN /root/replace.sh 's/ZEND_USE_ASM_ARITHMETIC 1/ZEND_USE_ASM_ARITHMETIC 0/g' /root/php-src/Zend/zend_operators.h;
RUN /root/replace.sh 's/defined\(__GNUC__\)/0/g' /root/php-src/Zend/zend_multiply.h
RUN /root/replace.sh 's/defined\(__GNUC__\)/0/g' /root/php-src/Zend/zend_cpuinfo.c
RUN /root/replace.sh 's/defined\(__clang__\)/0/g' /root/php-src/Zend/zend_cpuinfo.c
# ZEND_USE_ASM_ARITHMETIC was introduced in PHP 7.x, zend_cpuinfo.c in PHP 7.1
RUN if [ -f /root/php-src/Zend/zend_operators.h ] && grep -q 'ZEND_USE_ASM_ARITHMETIC' /root/php-src/Zend/zend_operators.h; then \
/root/replace.sh 's/ZEND_USE_ASM_ARITHMETIC 1/ZEND_USE_ASM_ARITHMETIC 0/g' /root/php-src/Zend/zend_operators.h; \
fi
# PHP 5.x uses __GNUC__ && __x86_64__ guards for inline asm in zend_operators.h
# and zend_alloc.c instead of ZEND_USE_ASM_ARITHMETIC. Disable those too.
RUN if [ -f /root/php-src/Zend/zend_operators.h ] && ! grep -q 'ZEND_USE_ASM_ARITHMETIC' /root/php-src/Zend/zend_operators.h; then \
/root/replace.sh 's/defined\(__GNUC__\) && defined\(__x86_64__\)/0/g' /root/php-src/Zend/zend_operators.h; \
/root/replace.sh 's/defined\(__GNUC__\) && defined\(__i386__\)/0/g' /root/php-src/Zend/zend_operators.h || true; \
fi
RUN if [ -f /root/php-src/Zend/zend_alloc.c ] && ! grep -q 'ZEND_USE_ASM_ARITHMETIC' /root/php-src/Zend/zend_alloc.c; then \
/root/replace.sh 's/defined\(__GNUC__\) && defined\(__x86_64__\)/0/g' /root/php-src/Zend/zend_alloc.c; \
/root/replace.sh 's/defined\(__GNUC__\) && defined\(__i386__\)/0/g' /root/php-src/Zend/zend_alloc.c || true; \
fi
RUN if [ -f /root/php-src/Zend/zend_multiply.h ]; then \
/root/replace.sh 's/defined\(__GNUC__\)/0/g' /root/php-src/Zend/zend_multiply.h; \
fi
RUN if [ -f /root/php-src/Zend/zend_cpuinfo.c ]; then \
/root/replace.sh 's/defined\(__GNUC__\)/0/g' /root/php-src/Zend/zend_cpuinfo.c; \
/root/replace.sh 's/defined\(__clang__\)/0/g' /root/php-src/Zend/zend_cpuinfo.c; \
fi
# PHP 5.6 bundles PCRE with JIT hardcoded in config.h. Disable it for WASM.
RUN if [ -f /root/php-src/ext/pcre/pcrelib/config.h ] && grep -q '^#define SUPPORT_JIT' /root/php-src/ext/pcre/pcrelib/config.h; then \
/root/replace.sh 's/^#define SUPPORT_JIT/#undef SUPPORT_JIT/g' /root/php-src/ext/pcre/pcrelib/config.h; \
fi
# }}}

# With HAVE_UNISTD_H=1 PHP complains about the missing getdtablesize() function
Expand All @@ -461,8 +503,11 @@ RUN /root/replace.sh 's/#define VCWD_POPEN.+/#define VCWD_POPEN(command, type) w
RUN echo 'extern FILE *wasm_popen(const char *cmd, const char *mode);' >> /root/php-src/Zend/zend_virtual_cwd.h

# Provide a custom implementation of the shutdown() function.
RUN perl -pi.bak -e $'s/(\s+)shutdown\(/$1 wasm_shutdown(/g' /root/php-src/sapi/cli/php_cli_server.c
RUN perl -pi.bak -e $'s/(\s+)closesocket\(/$1 wasm_close(/g' /root/php-src/sapi/cli/php_cli_server.c
# php_cli_server.c exists in PHP 5.4+ (built-in server added in 5.4)
RUN if [ -f /root/php-src/sapi/cli/php_cli_server.c ]; then \
perl -pi.bak -e $'s/(\\s+)shutdown\\(/$1 wasm_shutdown(/g' /root/php-src/sapi/cli/php_cli_server.c; \
perl -pi.bak -e $'s/(\\s+)closesocket\\(/$1 wasm_close(/g' /root/php-src/sapi/cli/php_cli_server.c; \
fi

# Provide custom implementation fo the shutdown() function.
# This is used by intl ( which links C++ code ) and need C linkage.
Expand Down Expand Up @@ -504,8 +549,12 @@ RUN source /root/emsdk/emsdk_env.sh && \
# We're compiling PHP as emscripten's side module...
export JSPI_FLAGS=$(if [ "$WITH_JSPI" = "yes" ]; then echo "-sSUPPORT_LONGJMP=wasm -fwasm-exceptions"; else echo ""; fi) && \
export PHP_VERSION_ESCAPED="${PHP_VERSION//./_}" && \
# PHP 5.x has function pointer type mismatches, deprecated non-prototype
# function definitions, and implicit function declarations that are
# errors in modern clang/emcc
export PHP5_FLAGS=$(if [ "${PHP_VERSION:0:1}" -le "5" ]; then echo "-Wno-incompatible-function-pointer-types -Wno-deprecated-non-prototype -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -Wno-implicit-int"; else echo ""; fi) && \
EMCC_FLAGS=" -D__x86_64__ -sSIDE_MODULE -Dsetsockopt=wasm_setsockopt -Dphp_exec=wasm_php_exec \
$JSPI_FLAGS \
$JSPI_FLAGS $PHP5_FLAGS \
-fdebug-compilation-dir=${DEBUG_DWARF_COMPILATION_DIR}/ \
-fdebug-prefix-map=/root/php-src/=${OUTPUT_DIR_ON_HOST}/${PHP_VERSION_ESCAPED}/php-src/ " \
# ...which means we must skip all the libraries - they will be provided in the final linking step.
Expand Down
Loading
Loading