Skip to content

PHP: Ensures that ExitStatus error thrown by Emscripten has a stack trace attached #470

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

Merged
merged 1 commit into from
May 30, 2023
Merged
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
11 changes: 6 additions & 5 deletions packages/php-wasm/compile/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,8 @@ RUN ls /root/output/
# fi

# Postprocess the build php.js module:
COPY ./build-assets/append-before-return.js /root/append-before-return.js
COPY ./build-assets/esm-prefix.js /root/esm-prefix.js
COPY ./build-assets/esm-suffix.js /root/esm-suffix.js
RUN \
# Figure out the target file names and URLs
# The .js and .wasm filenames should reflect the build configuration, e.g.:
Expand Down Expand Up @@ -1039,16 +1040,16 @@ RUN \
# Turn the php.js file into an ES module
# Manually turn the output into a esm module instead of relying on -s MODULARIZE=1.
# which pollutes the global namespace and does not play well with import() mechanics.
echo "export const dependenciesTotalSize = $FILE_SIZE; " >> /root/output/php-module.js && \
if [ "$EMSCRIPTEN_ENVIRONMENT" = "node" ]; then \
echo "const dependencyFilename = __dirname + '/$WASM_FILENAME'; " >> /root/output/php-module.js; \
else \
echo "import dependencyFilename from './$WASM_FILENAME'; " >> /root/output/php-module.js; \
fi; \
echo " export { dependencyFilename }; export function init(RuntimeName, PHPLoader) {" >> /root/output/php-module.js && \
echo " export { dependencyFilename }; " >> /root/output/php-module.js && \
echo "export const dependenciesTotalSize = $FILE_SIZE; " >> /root/output/php-module.js && \
cat /root/esm-prefix.js >> /root/output/php-module.js && \
cat /root/output/php.js >> /root/output/php-module.js && \
cat /root/append-before-return.js >> /root/output/php-module.js && \
echo " return PHPLoader; }" >> /root/output/php-module.js && \
cat /root/esm-suffix.js >> /root/output/php-module.js && \
\
# Remove the old php.js file
rm /root/output/php.js && \
Expand Down
37 changes: 37 additions & 0 deletions packages/php-wasm/compile/build-assets/esm-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export function init(RuntimeName, PHPLoader) {
/**
* Overrides Emscripten's default ExitStatus object which gets
* thrown on failure. Unfortunately, the default object is not
* a subclass of Error and does not provide any stack trace.
*
* This is a deliberate behavior on Emscripten's end to prevent
* memory leaks after the program exits. See:
*
* https://github.com/emscripten-core/emscripten/pull/9108
*
* In case of WordPress Playground, the worker in which the PHP
* runs will typically exit after the PHP program finishes, so
* we don't have to worry about memory leaks.
*
* As for assigning to a previously undeclared ExitStatus variable here,
* the Emscripten module declares `ExitStatus` as `function ExitStatus`
* which means it gets hoisted to the top of the scope and can be
* reassigned here – before the actual declaration is reached.
*
* If that sounds weird, try this example:
*
* ExitStatus = () => { console.log("reassigned"); }
* function ExitStatus() {}
* ExitStatus();
* // logs "reassigned"
*/
ExitStatus = class PHPExitStatus extends Error {
constructor(status) {
super(status);
this.name = "ExitStatus";
this.message = "Program terminated with exit(" + status + ")";
this.status = status;
}
}

// The rest of the code comes from the built php.js file and esm-suffix.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ if (PHPLoader.debug && typeof Asyncify !== "undefined") {
return originalHandleSleep(startAsync);
}
}

return PHPLoader;

// Close the opening bracket from esm-prefix.js:
}
49 changes: 45 additions & 4 deletions packages/php-wasm/node/public/php_5_6.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
export const dependenciesTotalSize = 10176855;
const dependencyFilename = __dirname + '/php_5_6.wasm';
export { dependencyFilename }; export function init(RuntimeName, PHPLoader) {
export { dependencyFilename };
export const dependenciesTotalSize = 10176855;
export function init(RuntimeName, PHPLoader) {
/**
* Overrides Emscripten's default ExitStatus object which gets
* thrown on failure. Unfortunately, the default object is not
* a subclass of Error and does not provide any stack trace.
*
* This is a deliberate behavior on Emscripten's end to prevent
* memory leaks after the program exits. See:
*
* https://github.com/emscripten-core/emscripten/pull/9108
*
* In case of WordPress Playground, the worker in which the PHP
* runs will typically exit after the PHP program finishes, so
* we don't have to worry about memory leaks.
*
* As for assigning to a previously undeclared ExitStatus variable here,
* the Emscripten module declares `ExitStatus` as `function ExitStatus`
* which means it gets hoisted to the top of the scope and can be
* reassigned here – before the actual declaration is reached.
*
* If that sounds weird, try this example:
*
* ExitStatus = () => { console.log("reassigned"); }
* function ExitStatus() {}
* ExitStatus();
* // logs "reassigned"
*/
ExitStatus = class PHPExitStatus extends Error {
constructor(status) {
super(status);
this.name = "ExitStatus";
this.message = "Program terminated with exit(" + status + ")";
this.status = status;
}
}

// The rest of the code comes from the built php.js file and esm-suffix.js
var Module = typeof PHPLoader != "undefined" ? PHPLoader : {};

var moduleOverrides = Object.assign({}, Module);
Expand Down Expand Up @@ -7041,7 +7078,7 @@ DNS.address_map.addrs.localhost = '127.0.0.1';
* so that it can be inspected later.
*/
PHPLoader.debug = 'debug' in PHPLoader ? PHPLoader.debug : true;
if (PHPLoader.debug) {
if (PHPLoader.debug && typeof Asyncify !== "undefined") {
const originalHandleSleep = Asyncify.handleSleep;
Asyncify.handleSleep = function (startAsync) {
if (!ABORT) {
Expand All @@ -7050,4 +7087,8 @@ if (PHPLoader.debug) {
return originalHandleSleep(startAsync);
}
}
return PHPLoader; }

return PHPLoader;

// Close the opening bracket from esm-prefix.js:
}
Binary file modified packages/php-wasm/node/public/php_5_6.wasm
Binary file not shown.
49 changes: 45 additions & 4 deletions packages/php-wasm/node/public/php_7_0.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
export const dependenciesTotalSize = 10390258;
const dependencyFilename = __dirname + '/php_7_0.wasm';
export { dependencyFilename }; export function init(RuntimeName, PHPLoader) {
export { dependencyFilename };
export const dependenciesTotalSize = 10390259;
export function init(RuntimeName, PHPLoader) {
/**
* Overrides Emscripten's default ExitStatus object which gets
* thrown on failure. Unfortunately, the default object is not
* a subclass of Error and does not provide any stack trace.
*
* This is a deliberate behavior on Emscripten's end to prevent
* memory leaks after the program exits. See:
*
* https://github.com/emscripten-core/emscripten/pull/9108
*
* In case of WordPress Playground, the worker in which the PHP
* runs will typically exit after the PHP program finishes, so
* we don't have to worry about memory leaks.
*
* As for assigning to a previously undeclared ExitStatus variable here,
* the Emscripten module declares `ExitStatus` as `function ExitStatus`
* which means it gets hoisted to the top of the scope and can be
* reassigned here – before the actual declaration is reached.
*
* If that sounds weird, try this example:
*
* ExitStatus = () => { console.log("reassigned"); }
* function ExitStatus() {}
* ExitStatus();
* // logs "reassigned"
*/
ExitStatus = class PHPExitStatus extends Error {
constructor(status) {
super(status);
this.name = "ExitStatus";
this.message = "Program terminated with exit(" + status + ")";
this.status = status;
}
}

// The rest of the code comes from the built php.js file and esm-suffix.js
var Module = typeof PHPLoader != "undefined" ? PHPLoader : {};

var moduleOverrides = Object.assign({}, Module);
Expand Down Expand Up @@ -7022,7 +7059,7 @@ DNS.address_map.addrs.localhost = '127.0.0.1';
* so that it can be inspected later.
*/
PHPLoader.debug = 'debug' in PHPLoader ? PHPLoader.debug : true;
if (PHPLoader.debug) {
if (PHPLoader.debug && typeof Asyncify !== "undefined") {
const originalHandleSleep = Asyncify.handleSleep;
Asyncify.handleSleep = function (startAsync) {
if (!ABORT) {
Expand All @@ -7031,4 +7068,8 @@ if (PHPLoader.debug) {
return originalHandleSleep(startAsync);
}
}
return PHPLoader; }

return PHPLoader;

// Close the opening bracket from esm-prefix.js:
}
Binary file modified packages/php-wasm/node/public/php_7_0.wasm
Binary file not shown.
49 changes: 45 additions & 4 deletions packages/php-wasm/node/public/php_7_1.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
export const dependenciesTotalSize = 10583885;
const dependencyFilename = __dirname + '/php_7_1.wasm';
export { dependencyFilename }; export function init(RuntimeName, PHPLoader) {
export { dependencyFilename };
export const dependenciesTotalSize = 10583885;
export function init(RuntimeName, PHPLoader) {
/**
* Overrides Emscripten's default ExitStatus object which gets
* thrown on failure. Unfortunately, the default object is not
* a subclass of Error and does not provide any stack trace.
*
* This is a deliberate behavior on Emscripten's end to prevent
* memory leaks after the program exits. See:
*
* https://github.com/emscripten-core/emscripten/pull/9108
*
* In case of WordPress Playground, the worker in which the PHP
* runs will typically exit after the PHP program finishes, so
* we don't have to worry about memory leaks.
*
* As for assigning to a previously undeclared ExitStatus variable here,
* the Emscripten module declares `ExitStatus` as `function ExitStatus`
* which means it gets hoisted to the top of the scope and can be
* reassigned here – before the actual declaration is reached.
*
* If that sounds weird, try this example:
*
* ExitStatus = () => { console.log("reassigned"); }
* function ExitStatus() {}
* ExitStatus();
* // logs "reassigned"
*/
ExitStatus = class PHPExitStatus extends Error {
constructor(status) {
super(status);
this.name = "ExitStatus";
this.message = "Program terminated with exit(" + status + ")";
this.status = status;
}
}

// The rest of the code comes from the built php.js file and esm-suffix.js
var Module = typeof PHPLoader != "undefined" ? PHPLoader : {};

var moduleOverrides = Object.assign({}, Module);
Expand Down Expand Up @@ -7007,7 +7044,7 @@ DNS.address_map.addrs.localhost = '127.0.0.1';
* so that it can be inspected later.
*/
PHPLoader.debug = 'debug' in PHPLoader ? PHPLoader.debug : true;
if (PHPLoader.debug) {
if (PHPLoader.debug && typeof Asyncify !== "undefined") {
const originalHandleSleep = Asyncify.handleSleep;
Asyncify.handleSleep = function (startAsync) {
if (!ABORT) {
Expand All @@ -7016,4 +7053,8 @@ if (PHPLoader.debug) {
return originalHandleSleep(startAsync);
}
}
return PHPLoader; }

return PHPLoader;

// Close the opening bracket from esm-prefix.js:
}
Binary file modified packages/php-wasm/node/public/php_7_1.wasm
Binary file not shown.
49 changes: 45 additions & 4 deletions packages/php-wasm/node/public/php_7_2.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
export const dependenciesTotalSize = 10993354;
const dependencyFilename = __dirname + '/php_7_2.wasm';
export { dependencyFilename }; export function init(RuntimeName, PHPLoader) {
export { dependencyFilename };
export const dependenciesTotalSize = 10993354;
export function init(RuntimeName, PHPLoader) {
/**
* Overrides Emscripten's default ExitStatus object which gets
* thrown on failure. Unfortunately, the default object is not
* a subclass of Error and does not provide any stack trace.
*
* This is a deliberate behavior on Emscripten's end to prevent
* memory leaks after the program exits. See:
*
* https://github.com/emscripten-core/emscripten/pull/9108
*
* In case of WordPress Playground, the worker in which the PHP
* runs will typically exit after the PHP program finishes, so
* we don't have to worry about memory leaks.
*
* As for assigning to a previously undeclared ExitStatus variable here,
* the Emscripten module declares `ExitStatus` as `function ExitStatus`
* which means it gets hoisted to the top of the scope and can be
* reassigned here – before the actual declaration is reached.
*
* If that sounds weird, try this example:
*
* ExitStatus = () => { console.log("reassigned"); }
* function ExitStatus() {}
* ExitStatus();
* // logs "reassigned"
*/
ExitStatus = class PHPExitStatus extends Error {
constructor(status) {
super(status);
this.name = "ExitStatus";
this.message = "Program terminated with exit(" + status + ")";
this.status = status;
}
}

// The rest of the code comes from the built php.js file and esm-suffix.js
var Module = typeof PHPLoader != "undefined" ? PHPLoader : {};

var moduleOverrides = Object.assign({}, Module);
Expand Down Expand Up @@ -7023,7 +7060,7 @@ DNS.address_map.addrs.localhost = '127.0.0.1';
* so that it can be inspected later.
*/
PHPLoader.debug = 'debug' in PHPLoader ? PHPLoader.debug : true;
if (PHPLoader.debug) {
if (PHPLoader.debug && typeof Asyncify !== "undefined") {
const originalHandleSleep = Asyncify.handleSleep;
Asyncify.handleSleep = function (startAsync) {
if (!ABORT) {
Expand All @@ -7032,4 +7069,8 @@ if (PHPLoader.debug) {
return originalHandleSleep(startAsync);
}
}
return PHPLoader; }

return PHPLoader;

// Close the opening bracket from esm-prefix.js:
}
Binary file modified packages/php-wasm/node/public/php_7_2.wasm
Binary file not shown.
Loading