Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
submodules: true
- uses: ./.github/actions/prepare-playground
with:
node-version: 20
node-version: 22
- run: node --expose-gc node_modules/nx/bin/nx affected --target=${{ matrix.target }}
env:
MYSQL_DATABASE: test_db
Expand Down
3 changes: 2 additions & 1 deletion packages/php-wasm/cli/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@php-wasm/universal';
import type { SupportedPHPVersion } from '@php-wasm/universal';

import { FileLockManagerForNode } from '@php-wasm/node';
import { FileLockManagerForNode, SyscallsForNode } from '@php-wasm/node';
import { PHP } from '@php-wasm/universal';
import { loadNodeRuntime, useHostFilesystem } from '@php-wasm/node';
import { startBridge } from '@php-wasm/xdebug-bridge';
Expand Down Expand Up @@ -91,6 +91,7 @@ ${process.argv[0]} ${process.execArgv.join(' ')} ${process.argv[1]}
await loadNodeRuntime(phpVersion, {
emscriptenOptions: {
fileLockManager: new FileLockManagerForNode(),
syscalls: new SyscallsForNode(),
processId: 1,
ENV: {
...envVariables,
Expand Down
7 changes: 4 additions & 3 deletions packages/php-wasm/compile/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2234,6 +2234,7 @@ RUN mkdir /root/output
COPY ./php/phpwasm-emscripten-library.js /root/phpwasm-emscripten-library.js
COPY ./php/phpwasm-emscripten-library-dynamic-linking.js /root/phpwasm-emscripten-library-dynamic-linking.js
COPY ./php/phpwasm-emscripten-library-file-locking-for-node.js /root/phpwasm-emscripten-library-file-locking-for-node.js
COPY ./php/phpwasm-emscripten-library-dns-lookup-for-node.js /root/phpwasm-emscripten-library-dns-lookup-for-node.js
COPY ./php/phpwasm-emscripten-library-known-undefined-functions.js /root/phpwasm-emscripten-library-known-undefined-functions.js
ARG WITH_SOURCEMAPS
ARG WITH_DEBUG
Expand All @@ -2243,10 +2244,10 @@ RUN set -euxo pipefail; \
source /root/emsdk/emsdk_env.sh; \
if [ "$WITH_JSPI" = "yes" ]; then \
# Both imports and exports are required for inter-module communication with wrapped methods, e.g., wasm_recv.
export ASYNCIFY_FLAGS=" -s ASYNCIFY=2 -sSUPPORT_LONGJMP=wasm -fwasm-exceptions -sJSPI_IMPORTS=js_open_process,js_fd_read,js_waitpid,js_process_status,js_create_input_device,wasm_setsockopt,wasm_shutdown,wasm_close,wasm_recv,__syscall_fcntl64,js_flock,js_release_file_locks,js_waitpid -sJSPI_EXPORTS=php_wasm_init,wasm_sleep,wasm_read,emscripten_sleep,wasm_sapi_handle_request,wasm_sapi_request_shutdown,wasm_poll_socket,wrap_select,__wrap_select,select,php_pollfd_for,fflush,wasm_popen,wasm_read,wasm_php_exec,run_cli,wasm_recv,__wasm_call_ctors,__errno_location,__funcs_on_exit -s EXPORTED_RUNTIME_METHODS=HEAPU32,HEAPU8,ccall,PROXYFS,wasmExports "; \
export ASYNCIFY_FLAGS=" -s ASYNCIFY=2 -sSUPPORT_LONGJMP=wasm -fwasm-exceptions -sJSPI_IMPORTS=js_open_process,js_fd_read,js_waitpid,js_process_status,js_create_input_device,wasm_setsockopt,wasm_shutdown,wasm_close,wasm_recv,__syscall_fcntl64,__emscripten_lookup_name,js_flock,js_release_file_locks,js_waitpid -sJSPI_EXPORTS=php_wasm_init,wasm_sleep,wasm_read,emscripten_sleep,wasm_sapi_handle_request,wasm_sapi_request_shutdown,wasm_poll_socket,wrap_select,__wrap_select,select,php_pollfd_for,fflush,wasm_popen,wasm_read,wasm_php_exec,run_cli,wasm_recv,__wasm_call_ctors,__errno_location,__funcs_on_exit -s EXPORTED_RUNTIME_METHODS=HEAPU32,HEAPU8,ccall,PROXYFS,wasmExports,UTF8ToString,lengthBytesUTF8,stringToUTF8 "; \
echo '#define PLAYGROUND_JSPI 1' > /root/php_wasm_asyncify.h; \
else \
export ASYNCIFY_FLAGS=" -s ASYNCIFY=1 -s ASYNCIFY_IGNORE_INDIRECT=1 -s EXPORTED_RUNTIME_METHODS=HEAPU32,HEAPU8,ccall,PROXYFS,wasmExports $(cat /root/.emcc-php-asyncify-flags) "; \
export ASYNCIFY_FLAGS=" -s ASYNCIFY=1 -s ASYNCIFY_IGNORE_INDIRECT=1 -s EXPORTED_RUNTIME_METHODS=HEAPU32,HEAPU8,ccall,PROXYFS,wasmExports,UTF8ToString,lengthBytesUTF8,stringToUTF8 $(cat /root/.emcc-php-asyncify-flags) "; \
echo '' > /root/php_wasm_asyncify.h; \
fi; \
export EXPORTED_FUNCTIONS=$'["_exit", \n\
Expand Down Expand Up @@ -2287,7 +2288,7 @@ RUN set -euxo pipefail; \
ENVIRONMENT="$EMSCRIPTEN_ENVIRONMENT"; \
if [ "$EMSCRIPTEN_ENVIRONMENT" = "node" ]; then \
PLATFORM_SPECIFIC_ARGS="$PLATFORM_SPECIFIC_ARGS -DPHP_WASM_FILE_LOCKING_SUPPORT=1"; \
PLATFORM_SPECIFIC_ARGS="$PLATFORM_SPECIFIC_ARGS --js-library /root/phpwasm-emscripten-library-file-locking-for-node.js -Wl,--wrap=getpid"; \
PLATFORM_SPECIFIC_ARGS="$PLATFORM_SPECIFIC_ARGS --js-library /root/phpwasm-emscripten-library-file-locking-for-node.js --js-library /root/phpwasm-emscripten-library-dns-lookup-for-node.js -Wl,--wrap=getpid"; \
else \
# Prevents "document is not defined" errors in Web Workers when using MAIN_MODULE.
# By default, Emscripten assumes MAIN_MODULE runs only in a web environment,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Override Emscripten's _emscripten_lookup_name to resolve hostnames with
* Node.js DNS when running in the Node environment.
*
* JSPI vs Asyncify
* ----------------
* In JSPI builds (ASYNCIFY == 2) we can await the async dns.lookup() Promise.
* In classic Asyncify builds (ASYNCIFY == 1) we block the calling thread with
* Atomics.wait on a SharedArrayBuffer to synchronise the async callback into a
* synchronous return value without rewinding the stack.
*/
'use strict';

const LibraryForNodeDnsLookup = {
// $-prefixed deps pull the runtime helpers into scope.
__emscripten_lookup_name__deps: ['$DNS', '$inetPton4', '$UTF8ToString'],
__emscripten_lookup_name__sig: 'ip',
// Ensure our implementation is used even if the core library defines one.
__emscripten_lookup_name__postset:
'const original__emscripten_lookup_name = __emscripten_lookup_name; if (typeof __emscripten_lookup_name !== "undefined") { __emscripten_lookup_name = ___emscripten_lookup_name; }'
#if ASYNCIFY == 2
+ '___emscripten_lookup_name.isAsync = true;'
#endif
,
__emscripten_lookup_name: function __emscripten_lookup_name(namePtr) {
#if ASYNCIFY == 2
return Asyncify.handleAsync(async () => {
#endif
if ( ! ENVIRONMENT_IS_NODE ) {
return original__emscripten_lookup_name(namePtr);
}
if ( ! PHPLoader.syscalls ) {
return original__emscripten_lookup_name(namePtr);
}

const hostname = UTF8ToString(namePtr);

let ipString = '';
try {
ipString = (
#if ASYNCIFY == 2
await Promise.resolve(
#endif
PHPLoader.syscalls.gethostbyname(hostname)
#if ASYNCIFY == 2
)
#endif
);
} catch (e) {
// Fall through to the default synthetic mapping if native DNS fails.
}

return inetPton4(ipString);
#if ASYNCIFY == 2
});
#endif
},
};

mergeInto(LibraryManager.library, LibraryForNodeDnsLookup);
Loading