Skip to content

Commit e31e6b8

Browse files
ereslibreassambar
andcommitted
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 <alexandrov@vmware.com>
1 parent cd0c6bc commit e31e6b8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+847
-95
lines changed

Zend/Optimizer/zend_func_infos.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -658,11 +658,19 @@ static const func_info_t func_infos[] = {
658658
FN("stream_context_set_default", MAY_BE_RESOURCE),
659659
FN("stream_filter_prepend", MAY_BE_RESOURCE|MAY_BE_FALSE),
660660
FN("stream_filter_append", MAY_BE_RESOURCE|MAY_BE_FALSE),
661+
#if !defined(__wasi__)
661662
F1("stream_socket_client", MAY_BE_RESOURCE|MAY_BE_FALSE),
663+
#endif
664+
#if !defined(__wasi__)
662665
F1("stream_socket_server", MAY_BE_RESOURCE|MAY_BE_FALSE),
666+
#endif
667+
#if !defined(__wasi__)
663668
F1("stream_socket_accept", MAY_BE_RESOURCE|MAY_BE_FALSE),
669+
#endif
670+
#if !defined(__wasi__)
664671
F1("stream_socket_recvfrom", MAY_BE_STRING|MAY_BE_FALSE),
665-
#if defined(HAVE_SOCKETPAIR)
672+
#endif
673+
#if !defined(__wasi__) && defined(HAVE_SOCKETPAIR)
666674
F1("stream_socket_pair", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_FALSE),
667675
#endif
668676
F1("stream_get_contents", MAY_BE_STRING|MAY_BE_FALSE),

Zend/zend.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,9 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
784784
#endif
785785
executor_globals->saved_fpu_cw_ptr = NULL;
786786
executor_globals->active = 0;
787+
#ifndef __wasi__
787788
executor_globals->bailout = NULL;
789+
#endif // __wasi__
788790
executor_globals->error_handling = EH_NORMAL;
789791
executor_globals->exception_class = NULL;
790792
executor_globals->exception = NULL;
@@ -1175,9 +1177,9 @@ ZEND_COLD void zenderror(const char *error) /* {{{ */
11751177
}
11761178
/* }}} */
11771179

1180+
#ifndef __wasi__
11781181
ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */
11791182
{
1180-
11811183
if (!EG(bailout)) {
11821184
zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
11831185
exit(-1);
@@ -1190,6 +1192,7 @@ ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32
11901192
LONGJMP(*EG(bailout), FAILURE);
11911193
}
11921194
/* }}} */
1195+
#endif // __wasi__
11931196

11941197
ZEND_API size_t zend_get_page_size(void)
11951198
{

Zend/zend.h

+14
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length);
258258

259259
#define zend_bailout() _zend_bailout(__FILE__, __LINE__)
260260

261+
#ifndef __wasi__
261262
#define zend_try \
262263
{ \
263264
JMP_BUF *__orig_bailout = EG(bailout); \
@@ -274,6 +275,19 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length);
274275
}
275276
#define zend_first_try EG(bailout)=NULL; zend_try
276277

278+
#else // __wasi__
279+
#define zend_try \
280+
{ \
281+
if (1) {
282+
#define zend_catch \
283+
} else {
284+
#define zend_end_try() \
285+
} \
286+
}
287+
#define zend_first_try zend_try
288+
#endif // __wasi__
289+
290+
277291
BEGIN_EXTERN_C()
278292
void zend_startup(zend_utility_functions *utility_functions);
279293
void zend_shutdown(void);

Zend/zend_alloc.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
#include <fcntl.h>
8181
#include <errno.h>
8282

83-
#ifndef _WIN32
83+
#if !defined(_WIN32) && defined(HAVE_MMAP)
8484
# include <sys/mman.h>
8585
# ifndef MAP_ANON
8686
# ifdef MAP_ANONYMOUS
@@ -444,6 +444,8 @@ static void zend_mm_munmap(void *addr, size_t size)
444444
#endif
445445
}
446446
}
447+
#elif !defined(_WIN32) && !defined(HAVE_MMAP)
448+
free(addr);
447449
#else
448450
if (munmap(addr, size) != 0) {
449451
#if ZEND_MM_ERROR
@@ -471,6 +473,8 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size)
471473
}
472474
ZEND_ASSERT(ptr == addr);
473475
return ptr;
476+
#elif !defined(HAVE_MMAP)
477+
return NULL;
474478
#else
475479
int flags = MAP_PRIVATE | MAP_ANON;
476480
#if defined(MAP_EXCL)
@@ -507,6 +511,10 @@ static void *zend_mm_mmap(size_t size)
507511
return NULL;
508512
}
509513
return ptr;
514+
#elif !defined(HAVE_MMAP)
515+
void* ptr = malloc(size);
516+
memset(ptr, 0, size);
517+
return ptr;
510518
#else
511519
void *ptr;
512520

@@ -716,6 +724,11 @@ static zend_always_inline void zend_mm_hugepage(void* ptr, size_t size)
716724

717725
static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
718726
{
727+
#if !defined(_WIN32) && !defined(HAVE_MMAP)
728+
void* ptr = aligned_alloc(alignment, size);
729+
memset(ptr, 0, size);
730+
return ptr;
731+
#else
719732
void *ptr = zend_mm_mmap(size);
720733

721734
if (ptr == NULL) {
@@ -766,6 +779,7 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
766779
#endif
767780
return ptr;
768781
}
782+
#endif
769783
}
770784

771785
static void *zend_mm_chunk_alloc(zend_mm_heap *heap, size_t size, size_t alignment)
@@ -2931,7 +2945,7 @@ ZEND_API void start_memory_manager(void)
29312945
#else
29322946
alloc_globals_ctor(&alloc_globals);
29332947
#endif
2934-
#ifndef _WIN32
2948+
#if !defined(_WIN32) && defined(HAVE_MMAP)
29352949
# if defined(_SC_PAGESIZE)
29362950
REAL_PAGE_SIZE = sysconf(_SC_PAGESIZE);
29372951
# elif defined(_SC_PAGE_SIZE)

Zend/zend_fibers.c

+17-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
# include <ucontext.h>
4040
#endif
4141

42-
#ifndef ZEND_WIN32
42+
#if !defined(ZEND_WIN32) && defined(HAVE_MMAP)
4343
# include <unistd.h>
4444
# include <sys/mman.h>
4545
# include <limits.h>
@@ -108,7 +108,9 @@ typedef struct _zend_fiber_vm_state {
108108
zend_execute_data *current_execute_data;
109109
int error_reporting;
110110
uint32_t jit_trace_num;
111+
#ifndef __wasi__
111112
JMP_BUF *bailout;
113+
#endif // __wasi__
112114
zend_fiber *active_fiber;
113115
#ifdef ZEND_CHECK_STACK_LIMIT
114116
void *stack_base;
@@ -125,7 +127,9 @@ static zend_always_inline void zend_fiber_capture_vm_state(zend_fiber_vm_state *
125127
state->current_execute_data = EG(current_execute_data);
126128
state->error_reporting = EG(error_reporting);
127129
state->jit_trace_num = EG(jit_trace_num);
130+
#ifndef __wasi__
128131
state->bailout = EG(bailout);
132+
#endif // __wasi__
129133
state->active_fiber = EG(active_fiber);
130134
#ifdef ZEND_CHECK_STACK_LIMIT
131135
state->stack_base = EG(stack_base);
@@ -142,7 +146,9 @@ static zend_always_inline void zend_fiber_restore_vm_state(zend_fiber_vm_state *
142146
EG(current_execute_data) = state->current_execute_data;
143147
EG(error_reporting) = state->error_reporting;
144148
EG(jit_trace_num) = state->jit_trace_num;
149+
#ifndef __wasi__
145150
EG(bailout) = state->bailout;
151+
#endif // __wasi__
146152
EG(active_fiber) = state->active_fiber;
147153
#ifdef ZEND_CHECK_STACK_LIMIT
148154
EG(stack_base) = state->stack_base;
@@ -236,6 +242,8 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size)
236242
return NULL;
237243
}
238244
# endif
245+
#elif defined(__wasi__)
246+
pointer = malloc(alloc_size);
239247
#else
240248
pointer = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
241249

@@ -302,6 +310,8 @@ static void zend_fiber_stack_free(zend_fiber_stack *stack)
302310

303311
#ifdef ZEND_WIN32
304312
VirtualFree(pointer, 0, MEM_RELEASE);
313+
#elif defined(__wasi__)
314+
free(pointer);
305315
#else
306316
munmap(pointer, stack->size + ZEND_FIBER_GUARD_PAGES * page_size);
307317
#endif
@@ -394,6 +404,7 @@ ZEND_API bool zend_fiber_switch_blocked(void)
394404
return zend_fiber_switch_blocking;
395405
}
396406

407+
#ifndef __wasi__
397408
ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size)
398409
{
399410
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 *
440451

441452
return SUCCESS;
442453
}
454+
#endif // __wasi__
443455

444456
ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context)
445457
{
@@ -502,16 +514,18 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer)
502514

503515
/* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */
504516
*transfer = *transfer_data;
505-
#else
517+
#elif !defined(__wasi__)
506518
boost_context_data data = jump_fcontext(to->handle, transfer);
507519

508520
/* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */
509521
*transfer = *data.transfer;
522+
#else
523+
return;
510524
#endif
511525

512526
to = transfer->context;
513527

514-
#ifndef ZEND_FIBER_UCONTEXT
528+
#if !defined(ZEND_FIBER_UCONTEXT) && !defined(__wasi__)
515529
/* Get the context that resumed us and update its handle to allow for symmetric coroutines. */
516530
to->handle = data.handle;
517531
#endif

Zend/zend_globals.h

+5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
#define ZEND_GLOBALS_H
2222

2323

24+
#ifndef __wasi__
2425
#include <setjmp.h>
26+
#endif
27+
2528
#include <stdint.h>
2629
#include <sys/types.h>
2730

@@ -174,7 +177,9 @@ struct _zend_executor_globals {
174177

175178
HashTable included_files; /* files already included */
176179

180+
#ifndef __wasi__
177181
JMP_BUF *bailout;
182+
#endif
178183

179184
int error_reporting;
180185
int exit_status;

Zend/zend_types.h

-1
Original file line numberDiff line numberDiff line change
@@ -1283,5 +1283,4 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
12831283
#define ZVAL_COPY_OR_DUP_PROP(z, v) \
12841284
do { ZVAL_COPY_OR_DUP(z, v); Z_PROP_FLAG_P(z) = Z_PROP_FLAG_P(v); } while (0)
12851285

1286-
12871286
#endif /* ZEND_TYPES_H */

Zend/zend_virtual_cwd.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf) /* {{{ */
13751375
/* }}} */
13761376
#endif
13771377

1378+
#ifndef __wasi__
13781379
CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */
13791380
{
13801381
cwd_state new_state;
@@ -1408,8 +1409,9 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */
14081409
return ret;
14091410
}
14101411
/* }}} */
1412+
#endif
14111413

1412-
#if !defined(ZEND_WIN32)
1414+
#if !defined(ZEND_WIN32) && !defined(__wasi__)
14131415
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link) /* {{{ */
14141416
{
14151417
cwd_state new_state;
@@ -1656,7 +1658,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */
16561658
return popen_ex(command, type, CWDG(cwd).cwd, NULL);
16571659
}
16581660
/* }}} */
1659-
#else /* Unix */
1661+
#elif !defined(__wasi__) /* Unix */
16601662
CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */
16611663
{
16621664
size_t command_length;

build/ax_check_define.m4

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# ===========================================================================
2+
# https://www.gnu.org/software/autoconf-archive/ax_check_define.html
3+
# ===========================================================================
4+
#
5+
# SYNOPSIS
6+
#
7+
# AC_CHECK_DEFINE([symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT])
8+
# AX_CHECK_DEFINE([includes],[symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT])
9+
#
10+
# DESCRIPTION
11+
#
12+
# Complements AC_CHECK_FUNC but it does not check for a function but for a
13+
# define to exist. Consider a usage like:
14+
#
15+
# AC_CHECK_DEFINE(__STRICT_ANSI__, CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500")
16+
#
17+
# LICENSE
18+
#
19+
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
20+
#
21+
# Copying and distribution of this file, with or without modification, are
22+
# permitted in any medium without royalty provided the copyright notice
23+
# and this notice are preserved. This file is offered as-is, without any
24+
# warranty.
25+
26+
#serial 11
27+
28+
AU_ALIAS([AC_CHECK_DEFINED], [AC_CHECK_DEFINE])
29+
AC_DEFUN([AC_CHECK_DEFINE],[
30+
AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl
31+
AC_CACHE_CHECK([for $1 defined], ac_var,
32+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
33+
#ifdef $1
34+
int ok;
35+
(void)ok;
36+
#else
37+
choke me
38+
#endif
39+
]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)]))
40+
AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl
41+
AS_VAR_POPDEF([ac_var])dnl
42+
])
43+
44+
AU_ALIAS([AX_CHECK_DEFINED], [AX_CHECK_DEFINE])
45+
AC_DEFUN([AX_CHECK_DEFINE],[
46+
AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2_$1])dnl
47+
AC_CACHE_CHECK([for $2 defined in $1], ac_var,
48+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <$1>]], [[
49+
#ifdef $2
50+
int ok;
51+
(void)ok;
52+
#else
53+
choke me
54+
#endif
55+
]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)]))
56+
AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl
57+
AS_VAR_POPDEF([ac_var])dnl
58+
])
59+
60+
AC_DEFUN([AX_CHECK_FUNC],
61+
[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl
62+
AC_CACHE_CHECK([for $2], ac_var,
63+
dnl AC_LANG_FUNC_LINK_TRY
64+
[AC_LINK_IFELSE([AC_LANG_PROGRAM([$1
65+
#undef $2
66+
char $2 ();],[
67+
char (*f) () = $2;
68+
return f != $2; ])],
69+
[AS_VAR_SET(ac_var, yes)],
70+
[AS_VAR_SET(ac_var, no)])])
71+
AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl
72+
AS_VAR_POPDEF([ac_var])dnl
73+
])# AC_CHECK_FUNC

0 commit comments

Comments
 (0)