Skip to content

Commit 4405353

Browse files
authored
[ php-wasm ] Add xdebug shared extension to @php-wasm/node ASYNCIFY (#2326)
## Motivation for the change This is a pull request to dynamically load Xdebug in `@php-wasm` Node ASYNCIFY. [Roadmap](#2315) ## Related issues and pull requests Relative to XDebug - #2248 - #314 - #2288 - #831 Relative to dynamic library - #89 - #2290 - #673 ## Implementation details Additional steps for asyncify are implemented : - new nx commands - new `WITH_JSPI` and `WITH_DEBUG` arguments in Xdebug Dockerfile - new `xdebug.so` files are compiled and dynamically loaded ## Zend extensions and PHP versions > [!IMPORTANT] > Each version of PHP requires its own version of Xdebug because each version of PHP has a specific Zend Engine API version. Consequently, each version of Xdebug is designed to be compatible with a particular Zend Engine API version. Example using PHP `8.2` with Xdebug `8.3` : ``` Xdebug requires Zend Engine API version 420230831. The Zend Engine API version 420220829 which is installed, is outdated. ``` ## Testing Instructions Two files are needed. A PHP file to test the step debugger. A JS file to run PHP 8.4 node ASYNCIFY. `php/xdebug.php` ```php <?php $test = 42; // Set a breakpoint on this line echo "Hello Xdebug World\n"; ``` `scripts/node.js` ```javascript import { PHP } from '@php-wasm/universal'; import { loadNodeRuntime } from '@php-wasm/node'; const php = new PHP( await loadNodeRuntime( '8.4', { withXdebug : true } ) ); await php.runStream( { scriptPath : `php/xdebug.php` } ); ``` To achieve the test, you first need to start debugging [ with F5 or Run > Start debugging in VSCode ], then run : ```bash node scripts/node.js ```
1 parent eee84fc commit 4405353

Some content is hidden

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

43 files changed

+507
-103
lines changed

packages/meta/src/node-es-module-loader/loader.mts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ export async function load(
171171
urlObj.search = '';
172172
return {
173173
format: 'module',
174-
source: `export default ${JSON.stringify(urlObj.href)};`,
175-
// TODO: Consider which is preferable and discuss with @adamziel.
176-
// He implemented the pathname version.
177-
//source: `export default ${JSON.stringify(urlObj.pathname)};`,
174+
source: `export default ${JSON.stringify(urlObj.pathname)};`,
175+
// As mentioned in
176+
// https://github.com/WordPress/wordpress-playground/pull/2318
177+
// using pathname is preferred over href.
178178
shortCircuit: true,
179179
};
180180
}

packages/php-wasm/compile/php/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,8 @@ RUN export ASYNCIFY_IMPORTS=$'[\n\
16441644
"zend_execute_script",\
16451645
"zend_execute_scripts",\
16461646
"zend_execute",\
1647+
"zend_extension_statement_handler",\
1648+
"ZEND_EXT_STMT_SPEC_HANDLER",\
16471649
"ZEND_FE_FETCH_R_SPEC_VAR_HANDLER",\
16481650
"zend_fe_reset_iterator",\
16491651
"ZEND_FE_RESET_R_SPEC_VAR_HANDLER",\
@@ -1724,6 +1726,8 @@ RUN export ASYNCIFY_IMPORTS=$'[\n\
17241726
"zend_objects_store_del_ref",\
17251727
"zend_objects_store_del",\
17261728
"zend_objects_store_free_object_storage",\
1729+
"zend_observer_fcall_begin_prechecked",\
1730+
"zend_observer_fcall_begin",\
17271731
"zend_observer_fcall_end",\
17281732
"zend_parse_arg_number_or_str_slow",\
17291733
"zend_parse_arg_str_weak",\

packages/php-wasm/compile/php/php7.3.patch

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,16 @@ diff --git a/php-src/main/streams/cast.c b/php-src/main/streams/cast.c
6868

6969

7070
diff --git a/php-src/Zend/zend_variables.c b/php-src/Zend/zend_variables.c
71-
index c2594274dd4..42fbacf8c6e 100644
71+
index c2594274dd4..2c3a01ece57 100644
7272
--- a/php-src/Zend/zend_variables.c
7373
+++ b/php-src/Zend/zend_variables.c
74-
@@ -44,6 +44,13 @@ static void ZEND_FASTCALL zend_ast_ref_destroy_wrapper(zend_ast_ref *ast);
74+
@@ -44,6 +44,16 @@ static void ZEND_FASTCALL zend_ast_ref_destroy_wrapper(zend_ast_ref *ast);
7575

7676
typedef void (ZEND_FASTCALL *zend_rc_dtor_func_t)(zend_refcounted *p);
7777

78+
+// Note: zend_list_free_wrapper function is required because active streams
79+
+// would otherwise cause a function signature mismatch. zend_list_free
80+
+// returns an int, while zend_rc_dtor_func_t expects a void return type.
7881
+static void zend_list_free_wrapper(zend_refcounted *p) {
7982
+ zend_resource *res = (zend_resource*)p;
8083
+ zval zv;
@@ -85,12 +88,12 @@ index c2594274dd4..42fbacf8c6e 100644
8588
static const zend_rc_dtor_func_t zend_rc_dtor_func[] = {
8689
/* IS_UNDEF */ (zend_rc_dtor_func_t)zend_empty_destroy,
8790
/* IS_NULL */ (zend_rc_dtor_func_t)zend_empty_destroy,
88-
@@ -54,7 +61,9 @@ static const zend_rc_dtor_func_t zend_rc_dtor_func[] = {
91+
@@ -54,7 +64,9 @@ static const zend_rc_dtor_func_t zend_rc_dtor_func[] = {
8992
/* IS_STRING */ (zend_rc_dtor_func_t)zend_string_destroy,
9093
/* IS_ARRAY */ (zend_rc_dtor_func_t)zend_array_destroy_wrapper,
9194
/* IS_OBJECT */ (zend_rc_dtor_func_t)zend_object_destroy_wrapper,
9295
- /* IS_RESOURCE */ (zend_rc_dtor_func_t)zend_resource_destroy_wrapper,
93-
+ // Info: zend_resource_destroy_wrapper is an alias for zend_list_free
96+
+ // Note: zend_resource_destroy_wrapper is an alias for zend_list_free
9497
+ // https://github.com/php/php-src/blob/PHP-7.3.33/Zend/zend_variables.c#L41
9598
+ /* IS_RESOURCE */ zend_list_free_wrapper,
9699
/* IS_REFERENCE */ (zend_rc_dtor_func_t)zend_reference_destroy,

packages/php-wasm/compile/php/php7.4.patch

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,24 +61,27 @@ diff --git a/php-src/ext/standard/file.c b/php-src/ext/standard/file.c
6161

6262

6363
diff --git a/php-src/Zend/zend_variables.c b/php-src/Zend/zend_variables.c
64-
index 810866a1be2..fdd1c80fea5 100644
64+
index 810866a1be2..0cc2a95dcf2 100644
6565
--- a/php-src/Zend/zend_variables.c
6666
+++ b/php-src/Zend/zend_variables.c
67-
@@ -36,6 +36,13 @@ static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref);
67+
@@ -36,6 +36,16 @@ static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref);
6868

6969
typedef void (ZEND_FASTCALL *zend_rc_dtor_func_t)(zend_refcounted *p);
7070

71+
+// Note: zend_list_free_wrapper function is required because active streams
72+
+// would otherwise cause a function signature mismatch. zend_list_free
73+
+// returns an int, while zend_rc_dtor_func_t expects a void return type.
7174
+static void zend_list_free_wrapper(zend_refcounted *p) {
72-
+ zend_resource *res = (zend_resource*)p;
73-
+ zval zv;
74-
+ ZVAL_RES(&zv, res);
75-
+ zend_list_free(&zv);
75+
+ zend_resource *res = (zend_resource*)p;
76+
+ zval zv;
77+
+ ZVAL_RES(&zv, res);
78+
+ zend_list_free(&zv);
7679
+}
7780
+
7881
static const zend_rc_dtor_func_t zend_rc_dtor_func[] = {
7982
/* IS_UNDEF */ (zend_rc_dtor_func_t)zend_empty_destroy,
8083
/* IS_NULL */ (zend_rc_dtor_func_t)zend_empty_destroy,
81-
@@ -46,7 +53,7 @@ static const zend_rc_dtor_func_t zend_rc_dtor_func[] = {
84+
@@ -46,7 +56,7 @@ static const zend_rc_dtor_func_t zend_rc_dtor_func[] = {
8285
/* IS_STRING */ (zend_rc_dtor_func_t)zend_string_destroy,
8386
/* IS_ARRAY */ (zend_rc_dtor_func_t)zend_array_destroy,
8487
/* IS_OBJECT */ (zend_rc_dtor_func_t)zend_objects_store_del,

0 commit comments

Comments
 (0)