Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Add support for building to the wasm32-wasi target #10457

Closed
wants to merge 2 commits into from
Closed
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
48 changes: 48 additions & 0 deletions .github/actions/apt-wasi/action.yml
Original file line number Diff line number Diff line change
@@ -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
48 changes: 48 additions & 0 deletions .github/actions/configure-wasi/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: ./configure
inputs:
configurationParameters:
default: ''
required: false
runs:
using: composite
steps:
- shell: bash
run: |
set -x

./buildconf --force
./configure \
ereslibre marked this conversation as resolved.
Show resolved Hide resolved
--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 }}
14 changes: 14 additions & 0 deletions .github/actions/optimize-wasi/action.yml
Original file line number Diff line number Diff line change
@@ -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
46 changes: 46 additions & 0 deletions .github/actions/test-wasi/action.yml
Original file line number Diff line number Diff line change
@@ -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
34 changes: 34 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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' }}"
Comment on lines +315 to +316
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
WASM32_WASI:
name: "WASM32_WASI_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}"
WASI:
name: "WASI_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}"

just to make the CI job name shorter/nicer...

Copy link
Author

@ereslibre ereslibre Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep WASM32_WASI if that's fine, given that WASM64 be added eventually

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All core tests (tests that does not require any unsupported extension) must pass or they must be exluded if they are expected to fail ATM.

setjmp/longjmp emulation

Fibers are core part of the PHP language since PHP 8.0 release. Can the support be added from the day zero?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All core tests (tests that does not require any unsupported extension) must pass or they must be exluded if they are expected to fail ATM.

Will exclude tests that don't apply on this platform in a next pass.

Fibers are core part of the PHP language since PHP 8.0 release. Can the support be added from the day zero?

We should look into that. If it's a prerequisite for this patch to land, then yes. If it's fine to iterate I'd prefer so, to not block the whole patch on smaller specifics, given the patch is already somewhat big.

# - 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
10 changes: 8 additions & 2 deletions Zend/Optimizer/zend_func_infos.h
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) /* {{{ */
{

Expand All @@ -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)
{
Expand Down
19 changes: 19 additions & 0 deletions Zend/zend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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); \
Expand All @@ -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);
Expand Down
20 changes: 17 additions & 3 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
#include <fcntl.h>
#include <errno.h>

#ifndef _WIN32
#if !defined(_WIN32) && defined(HAVE_MMAP)
# include <sys/mman.h>
# ifndef MAP_ANON
# ifdef MAP_ANONYMOUS
Expand Down Expand Up @@ -444,6 +444,8 @@ static void zend_mm_munmap(void *addr, size_t size)
#endif
}
}
#elif !defined(_WIN32) && !defined(HAVE_MMAP)
ereslibre marked this conversation as resolved.
Show resolved Hide resolved
free(addr);
#else
if (munmap(addr, size) != 0) {
#if ZEND_MM_ERROR
Expand Down Expand Up @@ -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;
Expand All @@ -491,6 +493,8 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size)
return NULL;
}
return ptr;
#else
return NULL;
#endif
}
#endif
Expand All @@ -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;

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Loading