@php-wasm/node 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/asyncify/7_2_34/php_7_2.wasm +0 -0
- package/asyncify/7_3_33/php_7_3.wasm +0 -0
- package/asyncify/7_4_33/php_7_4.wasm +0 -0
- package/asyncify/8_0_30/php_8_0.wasm +0 -0
- package/asyncify/8_1_23/php_8_1.wasm +0 -0
- package/asyncify/8_2_10/php_8_2.wasm +0 -0
- package/asyncify/8_3_0/php_8_3.wasm +0 -0
- package/asyncify/8_4_0/php_8_4.wasm +0 -0
- package/asyncify/php_7_2.js +179 -39
- package/asyncify/php_7_3.js +179 -39
- package/asyncify/php_7_4.js +179 -39
- package/asyncify/php_8_0.js +179 -39
- package/asyncify/php_8_1.js +179 -39
- package/asyncify/php_8_2.js +179 -39
- package/asyncify/php_8_3.js +179 -39
- package/asyncify/php_8_4.js +179 -39
- package/index.cjs +2710 -1213
- package/index.js +2710 -1213
- package/jspi/7_2_34/php_7_2.wasm +0 -0
- package/jspi/7_3_33/php_7_3.wasm +0 -0
- package/jspi/7_4_33/php_7_4.wasm +0 -0
- package/jspi/8_0_30/php_8_0.wasm +0 -0
- package/jspi/8_1_23/php_8_1.wasm +0 -0
- package/jspi/8_2_10/php_8_2.wasm +0 -0
- package/jspi/8_3_0/php_8_3.wasm +0 -0
- package/jspi/8_4_0/php_8_4.wasm +0 -0
- package/jspi/php_7_2.js +176 -36
- package/jspi/php_7_3.js +176 -36
- package/jspi/php_7_4.js +7703 -8484
- package/jspi/php_8_0.js +176 -36
- package/jspi/php_8_1.js +176 -36
- package/jspi/php_8_2.js +176 -36
- package/jspi/php_8_3.js +176 -36
- package/jspi/php_8_4.js +176 -36
- package/package.json +8 -8
package/asyncify/php_8_3.js
CHANGED
|
@@ -3,26 +3,12 @@
|
|
|
3
3
|
// this code in Node.js as an ES module.
|
|
4
4
|
import { createRequire } from 'module';
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* __filename and __dirname are not available in ES modules, so we need to
|
|
10
|
-
* polyfill them to ensure the debug command (npx nx debug playground-cli)
|
|
11
|
-
* works.
|
|
12
|
-
*
|
|
13
|
-
* @see https://nodejs.org/api/esm.html#no-__filename-or-__dirname
|
|
14
|
-
*/
|
|
6
|
+
// Note: The path module is currently needed by code injected by the php-wasm Dockerfile.
|
|
15
7
|
import path from 'path';
|
|
16
|
-
if (typeof __filename === 'undefined') {
|
|
17
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
18
|
-
}
|
|
19
|
-
if (typeof __dirname === 'undefined') {
|
|
20
|
-
var __dirname = path.dirname(__filename);
|
|
21
|
-
}
|
|
22
8
|
|
|
23
9
|
const dependencyFilename = path.join(__dirname, '8_3_0', 'php_8_3.wasm');
|
|
24
10
|
export { dependencyFilename };
|
|
25
|
-
export const dependenciesTotalSize =
|
|
11
|
+
export const dependenciesTotalSize = 18099540;
|
|
26
12
|
export function init(RuntimeName, PHPLoader) {
|
|
27
13
|
// The rest of the code comes from the built php.js file and esm-suffix.js
|
|
28
14
|
// include: shell.js
|
|
@@ -7046,6 +7032,44 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7046
7032
|
// The files from the preload directory are preloaded using the
|
|
7047
7033
|
// auto_prepend_file php.ini directive.
|
|
7048
7034
|
FS.mkdir('/internal/shared/preload');
|
|
7035
|
+
// Create stdout and stderr devices. We can't just use Emscripten's
|
|
7036
|
+
// default stdout and stderr devices because they stop processing data
|
|
7037
|
+
// on the first null byte. However, when dealing with binary data,
|
|
7038
|
+
// null bytes are valid and common.
|
|
7039
|
+
FS.registerDevice(FS.makedev(64, 0), {
|
|
7040
|
+
open: () => {},
|
|
7041
|
+
close: () => {},
|
|
7042
|
+
read: () => 0,
|
|
7043
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
7044
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
7045
|
+
PHPWASM.onStdout(chunk);
|
|
7046
|
+
return length;
|
|
7047
|
+
},
|
|
7048
|
+
});
|
|
7049
|
+
FS.mkdev('/internal/stdout', FS.makedev(64, 0));
|
|
7050
|
+
FS.registerDevice(FS.makedev(63, 0), {
|
|
7051
|
+
open: () => {},
|
|
7052
|
+
close: () => {},
|
|
7053
|
+
read: () => 0,
|
|
7054
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
7055
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
7056
|
+
PHPWASM.onStderr(chunk);
|
|
7057
|
+
return length;
|
|
7058
|
+
},
|
|
7059
|
+
});
|
|
7060
|
+
FS.mkdev('/internal/stderr', FS.makedev(63, 0));
|
|
7061
|
+
FS.registerDevice(FS.makedev(62, 0), {
|
|
7062
|
+
open: () => {},
|
|
7063
|
+
close: () => {},
|
|
7064
|
+
read: () => 0,
|
|
7065
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
7066
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
7067
|
+
PHPWASM.onHeaders(chunk);
|
|
7068
|
+
return length;
|
|
7069
|
+
},
|
|
7070
|
+
});
|
|
7071
|
+
FS.mkdev('/internal/headers', FS.makedev(62, 0));
|
|
7072
|
+
// Handle events.
|
|
7049
7073
|
PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
|
|
7050
7074
|
? require('events').EventEmitter
|
|
7051
7075
|
: class EventEmitter {
|
|
@@ -7086,9 +7110,71 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7086
7110
|
}
|
|
7087
7111
|
}
|
|
7088
7112
|
};
|
|
7113
|
+
// Clean up the fd -> childProcess mapping when the fd is closed:
|
|
7114
|
+
const originalClose = FS.close;
|
|
7115
|
+
FS.close = function (stream) {
|
|
7116
|
+
originalClose(stream);
|
|
7117
|
+
delete PHPWASM.child_proc_by_fd[stream.fd];
|
|
7118
|
+
};
|
|
7089
7119
|
PHPWASM.child_proc_by_fd = {};
|
|
7090
7120
|
PHPWASM.child_proc_by_pid = {};
|
|
7091
7121
|
PHPWASM.input_devices = {};
|
|
7122
|
+
const originalWrite = TTY.stream_ops.write;
|
|
7123
|
+
TTY.stream_ops.write = function (stream, ...rest) {
|
|
7124
|
+
const retval = originalWrite(stream, ...rest);
|
|
7125
|
+
// Implicit flush since PHP's fflush() doesn't seem to trigger the fsync event
|
|
7126
|
+
// @TODO: Fix this at the wasm level
|
|
7127
|
+
stream.tty.ops.fsync(stream.tty);
|
|
7128
|
+
return retval;
|
|
7129
|
+
};
|
|
7130
|
+
const originalPutChar = TTY.stream_ops.put_char;
|
|
7131
|
+
TTY.stream_ops.put_char = function (tty, val) {
|
|
7132
|
+
/**
|
|
7133
|
+
* Buffer newlines that Emscripten normally ignores.
|
|
7134
|
+
*
|
|
7135
|
+
* Emscripten doesn't do it by default because its default
|
|
7136
|
+
* print function is console.log that implicitly adds a newline. We are overwriting
|
|
7137
|
+
* it with an environment-specific function that outputs exaclty what it was given,
|
|
7138
|
+
* e.g. in Node.js it's process.stdout.write(). Therefore, we need to mak sure
|
|
7139
|
+
* all the newlines make it to the output buffer.
|
|
7140
|
+
*/ if (val === 10) tty.output.push(val);
|
|
7141
|
+
return originalPutChar(tty, val);
|
|
7142
|
+
};
|
|
7143
|
+
},
|
|
7144
|
+
onHeaders: function (chunk) {
|
|
7145
|
+
if (Module['onHeaders']) {
|
|
7146
|
+
Module['onHeaders'](chunk);
|
|
7147
|
+
return;
|
|
7148
|
+
}
|
|
7149
|
+
console.log('headers', {
|
|
7150
|
+
chunk,
|
|
7151
|
+
});
|
|
7152
|
+
},
|
|
7153
|
+
onStdout: function (chunk) {
|
|
7154
|
+
if (Module['onStdout']) {
|
|
7155
|
+
Module['onStdout'](chunk);
|
|
7156
|
+
return;
|
|
7157
|
+
}
|
|
7158
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7159
|
+
process.stdout.write(chunk);
|
|
7160
|
+
} else {
|
|
7161
|
+
console.log('stdout', {
|
|
7162
|
+
chunk,
|
|
7163
|
+
});
|
|
7164
|
+
}
|
|
7165
|
+
},
|
|
7166
|
+
onStderr: function (chunk) {
|
|
7167
|
+
if (Module['onStderr']) {
|
|
7168
|
+
Module['onStderr'](chunk);
|
|
7169
|
+
return;
|
|
7170
|
+
}
|
|
7171
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7172
|
+
process.stderr.write(chunk);
|
|
7173
|
+
} else {
|
|
7174
|
+
console.warn('stderr', {
|
|
7175
|
+
chunk,
|
|
7176
|
+
});
|
|
7177
|
+
}
|
|
7092
7178
|
},
|
|
7093
7179
|
getAllWebSockets: function (sock) {
|
|
7094
7180
|
const webSockets = new Set();
|
|
@@ -7270,7 +7356,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7270
7356
|
argsArray.push(UTF8ToString(HEAPU32[charPointer >> 2]));
|
|
7271
7357
|
}
|
|
7272
7358
|
}
|
|
7273
|
-
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) :
|
|
7359
|
+
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : FS.cwd();
|
|
7274
7360
|
let envObject = null;
|
|
7275
7361
|
if (envLength) {
|
|
7276
7362
|
envObject = {};
|
|
@@ -7343,6 +7429,15 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7343
7429
|
PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd] = ProcInfo;
|
|
7344
7430
|
PHPWASM.child_proc_by_pid[ProcInfo.pid] = ProcInfo;
|
|
7345
7431
|
cp.on('exit', function (code) {
|
|
7432
|
+
for (const fd of [
|
|
7433
|
+
// The child process exited. Let's clean up its output streams:
|
|
7434
|
+
ProcInfo.stdoutChildFd,
|
|
7435
|
+
ProcInfo.stderrChildFd,
|
|
7436
|
+
]) {
|
|
7437
|
+
if (FS.streams[fd] && !FS.isClosed(FS.streams[fd])) {
|
|
7438
|
+
FS.close(FS.streams[fd]);
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7346
7441
|
ProcInfo.exitCode = code;
|
|
7347
7442
|
ProcInfo.exited = true;
|
|
7348
7443
|
// Emit events for the wasm_poll_socket function.
|
|
@@ -7393,12 +7488,52 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7393
7488
|
* listen to the 'exit' event.
|
|
7394
7489
|
*/ try {
|
|
7395
7490
|
await new Promise((resolve, reject) => {
|
|
7396
|
-
|
|
7397
|
-
|
|
7491
|
+
/**
|
|
7492
|
+
* There was no `await` between the `spawnProcess` call
|
|
7493
|
+
* and the `await` below so the process haven't had a chance
|
|
7494
|
+
* to run any of the exit-related callbacks yet.
|
|
7495
|
+
*
|
|
7496
|
+
* Good.
|
|
7497
|
+
*
|
|
7498
|
+
* Let's listen to all the lifecycle events and resolve
|
|
7499
|
+
* the promise when the process starts or immediately crashes.
|
|
7500
|
+
*/ let resolved = false;
|
|
7501
|
+
cp.on('spawn', () => {
|
|
7502
|
+
if (resolved) return;
|
|
7503
|
+
resolved = true;
|
|
7504
|
+
resolve();
|
|
7505
|
+
});
|
|
7506
|
+
cp.on('error', (e) => {
|
|
7507
|
+
if (resolved) return;
|
|
7508
|
+
resolved = true;
|
|
7509
|
+
reject(e);
|
|
7510
|
+
});
|
|
7511
|
+
cp.on('exit', function (code) {
|
|
7512
|
+
if (resolved) return;
|
|
7513
|
+
resolved = true;
|
|
7514
|
+
if (code === 0) {
|
|
7515
|
+
resolve();
|
|
7516
|
+
} else {
|
|
7517
|
+
reject(
|
|
7518
|
+
new Error(`Process exited with code ${code}`)
|
|
7519
|
+
);
|
|
7520
|
+
}
|
|
7521
|
+
});
|
|
7522
|
+
/**
|
|
7523
|
+
* If the process haven't even started after 5 seconds, something
|
|
7524
|
+
* is wrong. Perhaps we're missing an event listener, or perhaps
|
|
7525
|
+
* the `spawnProcess` implementation failed to dispatch the relevant
|
|
7526
|
+
* event. Either way, let's crash to avoid blocking the proc_open()
|
|
7527
|
+
* call indefinitely.
|
|
7528
|
+
*/ setTimeout(() => {
|
|
7529
|
+
if (resolved) return;
|
|
7530
|
+
resolved = true;
|
|
7531
|
+
reject(new Error('Process timed out'));
|
|
7532
|
+
}, 5e3);
|
|
7398
7533
|
});
|
|
7399
7534
|
} catch (e) {
|
|
7400
7535
|
console.error(e);
|
|
7401
|
-
wakeUp(
|
|
7536
|
+
wakeUp(ProcInfo.pid);
|
|
7402
7537
|
return;
|
|
7403
7538
|
}
|
|
7404
7539
|
// Now we want to pass data from the STDIN source supplied by PHP
|
|
@@ -8291,14 +8426,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8291
8426
|
const POLLNVAL = 32;
|
|
8292
8427
|
return returnCallback((wakeUp) => {
|
|
8293
8428
|
const polls = [];
|
|
8294
|
-
if (socketd
|
|
8295
|
-
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8296
|
-
if (procInfo.exited) {
|
|
8297
|
-
wakeUp(0);
|
|
8298
|
-
return;
|
|
8299
|
-
}
|
|
8300
|
-
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8301
|
-
} else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8429
|
+
if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8302
8430
|
const sock = getSocketFromFD(socketd);
|
|
8303
8431
|
if (!sock) {
|
|
8304
8432
|
wakeUp(0);
|
|
@@ -8332,7 +8460,12 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8332
8460
|
polls.push(PHPWASM.awaitConnection(ws));
|
|
8333
8461
|
lookingFor.add('POLLOUT');
|
|
8334
8462
|
}
|
|
8335
|
-
if (
|
|
8463
|
+
if (
|
|
8464
|
+
events & POLLHUP ||
|
|
8465
|
+
events & POLLIN ||
|
|
8466
|
+
events & POLLOUT ||
|
|
8467
|
+
events & POLLERR
|
|
8468
|
+
) {
|
|
8336
8469
|
polls.push(PHPWASM.awaitClose(ws));
|
|
8337
8470
|
lookingFor.add('POLLHUP');
|
|
8338
8471
|
}
|
|
@@ -8341,6 +8474,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8341
8474
|
lookingFor.add('POLLERR');
|
|
8342
8475
|
}
|
|
8343
8476
|
}
|
|
8477
|
+
} else if (socketd in PHPWASM.child_proc_by_fd) {
|
|
8478
|
+
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8479
|
+
if (procInfo.exited) {
|
|
8480
|
+
wakeUp(0);
|
|
8481
|
+
return;
|
|
8482
|
+
}
|
|
8483
|
+
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8344
8484
|
} else {
|
|
8345
8485
|
setTimeout(function () {
|
|
8346
8486
|
wakeUp(1);
|
|
@@ -8653,21 +8793,21 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8653
8793
|
a4
|
|
8654
8794
|
));
|
|
8655
8795
|
|
|
8656
|
-
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8657
|
-
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['yb'])(
|
|
8658
|
-
a0
|
|
8659
|
-
));
|
|
8660
|
-
|
|
8661
|
-
var _run_cli = (Module['_run_cli'] = () =>
|
|
8662
|
-
(_run_cli = Module['_run_cli'] = wasmExports['zb'])());
|
|
8663
|
-
|
|
8664
8796
|
var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
|
|
8665
8797
|
(_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
|
|
8666
|
-
wasmExports['
|
|
8798
|
+
wasmExports['yb'])(a0));
|
|
8667
8799
|
|
|
8668
8800
|
var _wasm_set_phpini_path = (Module['_wasm_set_phpini_path'] = (a0) =>
|
|
8669
8801
|
(_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
|
|
8670
|
-
wasmExports['
|
|
8802
|
+
wasmExports['zb'])(a0));
|
|
8803
|
+
|
|
8804
|
+
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8805
|
+
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['Ab'])(
|
|
8806
|
+
a0
|
|
8807
|
+
));
|
|
8808
|
+
|
|
8809
|
+
var _run_cli = (Module['_run_cli'] = () =>
|
|
8810
|
+
(_run_cli = Module['_run_cli'] = wasmExports['Bb'])());
|
|
8671
8811
|
|
|
8672
8812
|
var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
|
|
8673
8813
|
(_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
|
package/asyncify/php_8_4.js
CHANGED
|
@@ -3,26 +3,12 @@
|
|
|
3
3
|
// this code in Node.js as an ES module.
|
|
4
4
|
import { createRequire } from 'module';
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* __filename and __dirname are not available in ES modules, so we need to
|
|
10
|
-
* polyfill them to ensure the debug command (npx nx debug playground-cli)
|
|
11
|
-
* works.
|
|
12
|
-
*
|
|
13
|
-
* @see https://nodejs.org/api/esm.html#no-__filename-or-__dirname
|
|
14
|
-
*/
|
|
6
|
+
// Note: The path module is currently needed by code injected by the php-wasm Dockerfile.
|
|
15
7
|
import path from 'path';
|
|
16
|
-
if (typeof __filename === 'undefined') {
|
|
17
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
18
|
-
}
|
|
19
|
-
if (typeof __dirname === 'undefined') {
|
|
20
|
-
var __dirname = path.dirname(__filename);
|
|
21
|
-
}
|
|
22
8
|
|
|
23
9
|
const dependencyFilename = path.join(__dirname, '8_4_0', 'php_8_4.wasm');
|
|
24
10
|
export { dependencyFilename };
|
|
25
|
-
export const dependenciesTotalSize =
|
|
11
|
+
export const dependenciesTotalSize = 21472349;
|
|
26
12
|
export function init(RuntimeName, PHPLoader) {
|
|
27
13
|
// The rest of the code comes from the built php.js file and esm-suffix.js
|
|
28
14
|
// include: shell.js
|
|
@@ -7046,6 +7032,44 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7046
7032
|
// The files from the preload directory are preloaded using the
|
|
7047
7033
|
// auto_prepend_file php.ini directive.
|
|
7048
7034
|
FS.mkdir('/internal/shared/preload');
|
|
7035
|
+
// Create stdout and stderr devices. We can't just use Emscripten's
|
|
7036
|
+
// default stdout and stderr devices because they stop processing data
|
|
7037
|
+
// on the first null byte. However, when dealing with binary data,
|
|
7038
|
+
// null bytes are valid and common.
|
|
7039
|
+
FS.registerDevice(FS.makedev(64, 0), {
|
|
7040
|
+
open: () => {},
|
|
7041
|
+
close: () => {},
|
|
7042
|
+
read: () => 0,
|
|
7043
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
7044
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
7045
|
+
PHPWASM.onStdout(chunk);
|
|
7046
|
+
return length;
|
|
7047
|
+
},
|
|
7048
|
+
});
|
|
7049
|
+
FS.mkdev('/internal/stdout', FS.makedev(64, 0));
|
|
7050
|
+
FS.registerDevice(FS.makedev(63, 0), {
|
|
7051
|
+
open: () => {},
|
|
7052
|
+
close: () => {},
|
|
7053
|
+
read: () => 0,
|
|
7054
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
7055
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
7056
|
+
PHPWASM.onStderr(chunk);
|
|
7057
|
+
return length;
|
|
7058
|
+
},
|
|
7059
|
+
});
|
|
7060
|
+
FS.mkdev('/internal/stderr', FS.makedev(63, 0));
|
|
7061
|
+
FS.registerDevice(FS.makedev(62, 0), {
|
|
7062
|
+
open: () => {},
|
|
7063
|
+
close: () => {},
|
|
7064
|
+
read: () => 0,
|
|
7065
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
7066
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
7067
|
+
PHPWASM.onHeaders(chunk);
|
|
7068
|
+
return length;
|
|
7069
|
+
},
|
|
7070
|
+
});
|
|
7071
|
+
FS.mkdev('/internal/headers', FS.makedev(62, 0));
|
|
7072
|
+
// Handle events.
|
|
7049
7073
|
PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
|
|
7050
7074
|
? require('events').EventEmitter
|
|
7051
7075
|
: class EventEmitter {
|
|
@@ -7086,9 +7110,71 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7086
7110
|
}
|
|
7087
7111
|
}
|
|
7088
7112
|
};
|
|
7113
|
+
// Clean up the fd -> childProcess mapping when the fd is closed:
|
|
7114
|
+
const originalClose = FS.close;
|
|
7115
|
+
FS.close = function (stream) {
|
|
7116
|
+
originalClose(stream);
|
|
7117
|
+
delete PHPWASM.child_proc_by_fd[stream.fd];
|
|
7118
|
+
};
|
|
7089
7119
|
PHPWASM.child_proc_by_fd = {};
|
|
7090
7120
|
PHPWASM.child_proc_by_pid = {};
|
|
7091
7121
|
PHPWASM.input_devices = {};
|
|
7122
|
+
const originalWrite = TTY.stream_ops.write;
|
|
7123
|
+
TTY.stream_ops.write = function (stream, ...rest) {
|
|
7124
|
+
const retval = originalWrite(stream, ...rest);
|
|
7125
|
+
// Implicit flush since PHP's fflush() doesn't seem to trigger the fsync event
|
|
7126
|
+
// @TODO: Fix this at the wasm level
|
|
7127
|
+
stream.tty.ops.fsync(stream.tty);
|
|
7128
|
+
return retval;
|
|
7129
|
+
};
|
|
7130
|
+
const originalPutChar = TTY.stream_ops.put_char;
|
|
7131
|
+
TTY.stream_ops.put_char = function (tty, val) {
|
|
7132
|
+
/**
|
|
7133
|
+
* Buffer newlines that Emscripten normally ignores.
|
|
7134
|
+
*
|
|
7135
|
+
* Emscripten doesn't do it by default because its default
|
|
7136
|
+
* print function is console.log that implicitly adds a newline. We are overwriting
|
|
7137
|
+
* it with an environment-specific function that outputs exaclty what it was given,
|
|
7138
|
+
* e.g. in Node.js it's process.stdout.write(). Therefore, we need to mak sure
|
|
7139
|
+
* all the newlines make it to the output buffer.
|
|
7140
|
+
*/ if (val === 10) tty.output.push(val);
|
|
7141
|
+
return originalPutChar(tty, val);
|
|
7142
|
+
};
|
|
7143
|
+
},
|
|
7144
|
+
onHeaders: function (chunk) {
|
|
7145
|
+
if (Module['onHeaders']) {
|
|
7146
|
+
Module['onHeaders'](chunk);
|
|
7147
|
+
return;
|
|
7148
|
+
}
|
|
7149
|
+
console.log('headers', {
|
|
7150
|
+
chunk,
|
|
7151
|
+
});
|
|
7152
|
+
},
|
|
7153
|
+
onStdout: function (chunk) {
|
|
7154
|
+
if (Module['onStdout']) {
|
|
7155
|
+
Module['onStdout'](chunk);
|
|
7156
|
+
return;
|
|
7157
|
+
}
|
|
7158
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7159
|
+
process.stdout.write(chunk);
|
|
7160
|
+
} else {
|
|
7161
|
+
console.log('stdout', {
|
|
7162
|
+
chunk,
|
|
7163
|
+
});
|
|
7164
|
+
}
|
|
7165
|
+
},
|
|
7166
|
+
onStderr: function (chunk) {
|
|
7167
|
+
if (Module['onStderr']) {
|
|
7168
|
+
Module['onStderr'](chunk);
|
|
7169
|
+
return;
|
|
7170
|
+
}
|
|
7171
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7172
|
+
process.stderr.write(chunk);
|
|
7173
|
+
} else {
|
|
7174
|
+
console.warn('stderr', {
|
|
7175
|
+
chunk,
|
|
7176
|
+
});
|
|
7177
|
+
}
|
|
7092
7178
|
},
|
|
7093
7179
|
getAllWebSockets: function (sock) {
|
|
7094
7180
|
const webSockets = new Set();
|
|
@@ -7270,7 +7356,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7270
7356
|
argsArray.push(UTF8ToString(HEAPU32[charPointer >> 2]));
|
|
7271
7357
|
}
|
|
7272
7358
|
}
|
|
7273
|
-
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) :
|
|
7359
|
+
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : FS.cwd();
|
|
7274
7360
|
let envObject = null;
|
|
7275
7361
|
if (envLength) {
|
|
7276
7362
|
envObject = {};
|
|
@@ -7343,6 +7429,15 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7343
7429
|
PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd] = ProcInfo;
|
|
7344
7430
|
PHPWASM.child_proc_by_pid[ProcInfo.pid] = ProcInfo;
|
|
7345
7431
|
cp.on('exit', function (code) {
|
|
7432
|
+
for (const fd of [
|
|
7433
|
+
// The child process exited. Let's clean up its output streams:
|
|
7434
|
+
ProcInfo.stdoutChildFd,
|
|
7435
|
+
ProcInfo.stderrChildFd,
|
|
7436
|
+
]) {
|
|
7437
|
+
if (FS.streams[fd] && !FS.isClosed(FS.streams[fd])) {
|
|
7438
|
+
FS.close(FS.streams[fd]);
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7346
7441
|
ProcInfo.exitCode = code;
|
|
7347
7442
|
ProcInfo.exited = true;
|
|
7348
7443
|
// Emit events for the wasm_poll_socket function.
|
|
@@ -7393,12 +7488,52 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7393
7488
|
* listen to the 'exit' event.
|
|
7394
7489
|
*/ try {
|
|
7395
7490
|
await new Promise((resolve, reject) => {
|
|
7396
|
-
|
|
7397
|
-
|
|
7491
|
+
/**
|
|
7492
|
+
* There was no `await` between the `spawnProcess` call
|
|
7493
|
+
* and the `await` below so the process haven't had a chance
|
|
7494
|
+
* to run any of the exit-related callbacks yet.
|
|
7495
|
+
*
|
|
7496
|
+
* Good.
|
|
7497
|
+
*
|
|
7498
|
+
* Let's listen to all the lifecycle events and resolve
|
|
7499
|
+
* the promise when the process starts or immediately crashes.
|
|
7500
|
+
*/ let resolved = false;
|
|
7501
|
+
cp.on('spawn', () => {
|
|
7502
|
+
if (resolved) return;
|
|
7503
|
+
resolved = true;
|
|
7504
|
+
resolve();
|
|
7505
|
+
});
|
|
7506
|
+
cp.on('error', (e) => {
|
|
7507
|
+
if (resolved) return;
|
|
7508
|
+
resolved = true;
|
|
7509
|
+
reject(e);
|
|
7510
|
+
});
|
|
7511
|
+
cp.on('exit', function (code) {
|
|
7512
|
+
if (resolved) return;
|
|
7513
|
+
resolved = true;
|
|
7514
|
+
if (code === 0) {
|
|
7515
|
+
resolve();
|
|
7516
|
+
} else {
|
|
7517
|
+
reject(
|
|
7518
|
+
new Error(`Process exited with code ${code}`)
|
|
7519
|
+
);
|
|
7520
|
+
}
|
|
7521
|
+
});
|
|
7522
|
+
/**
|
|
7523
|
+
* If the process haven't even started after 5 seconds, something
|
|
7524
|
+
* is wrong. Perhaps we're missing an event listener, or perhaps
|
|
7525
|
+
* the `spawnProcess` implementation failed to dispatch the relevant
|
|
7526
|
+
* event. Either way, let's crash to avoid blocking the proc_open()
|
|
7527
|
+
* call indefinitely.
|
|
7528
|
+
*/ setTimeout(() => {
|
|
7529
|
+
if (resolved) return;
|
|
7530
|
+
resolved = true;
|
|
7531
|
+
reject(new Error('Process timed out'));
|
|
7532
|
+
}, 5e3);
|
|
7398
7533
|
});
|
|
7399
7534
|
} catch (e) {
|
|
7400
7535
|
console.error(e);
|
|
7401
|
-
wakeUp(
|
|
7536
|
+
wakeUp(ProcInfo.pid);
|
|
7402
7537
|
return;
|
|
7403
7538
|
}
|
|
7404
7539
|
// Now we want to pass data from the STDIN source supplied by PHP
|
|
@@ -8291,14 +8426,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8291
8426
|
const POLLNVAL = 32;
|
|
8292
8427
|
return returnCallback((wakeUp) => {
|
|
8293
8428
|
const polls = [];
|
|
8294
|
-
if (socketd
|
|
8295
|
-
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8296
|
-
if (procInfo.exited) {
|
|
8297
|
-
wakeUp(0);
|
|
8298
|
-
return;
|
|
8299
|
-
}
|
|
8300
|
-
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8301
|
-
} else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8429
|
+
if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8302
8430
|
const sock = getSocketFromFD(socketd);
|
|
8303
8431
|
if (!sock) {
|
|
8304
8432
|
wakeUp(0);
|
|
@@ -8332,7 +8460,12 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8332
8460
|
polls.push(PHPWASM.awaitConnection(ws));
|
|
8333
8461
|
lookingFor.add('POLLOUT');
|
|
8334
8462
|
}
|
|
8335
|
-
if (
|
|
8463
|
+
if (
|
|
8464
|
+
events & POLLHUP ||
|
|
8465
|
+
events & POLLIN ||
|
|
8466
|
+
events & POLLOUT ||
|
|
8467
|
+
events & POLLERR
|
|
8468
|
+
) {
|
|
8336
8469
|
polls.push(PHPWASM.awaitClose(ws));
|
|
8337
8470
|
lookingFor.add('POLLHUP');
|
|
8338
8471
|
}
|
|
@@ -8341,6 +8474,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8341
8474
|
lookingFor.add('POLLERR');
|
|
8342
8475
|
}
|
|
8343
8476
|
}
|
|
8477
|
+
} else if (socketd in PHPWASM.child_proc_by_fd) {
|
|
8478
|
+
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8479
|
+
if (procInfo.exited) {
|
|
8480
|
+
wakeUp(0);
|
|
8481
|
+
return;
|
|
8482
|
+
}
|
|
8483
|
+
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8344
8484
|
} else {
|
|
8345
8485
|
setTimeout(function () {
|
|
8346
8486
|
wakeUp(1);
|
|
@@ -8652,21 +8792,21 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8652
8792
|
a4
|
|
8653
8793
|
));
|
|
8654
8794
|
|
|
8655
|
-
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8656
|
-
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['xb'])(
|
|
8657
|
-
a0
|
|
8658
|
-
));
|
|
8659
|
-
|
|
8660
|
-
var _run_cli = (Module['_run_cli'] = () =>
|
|
8661
|
-
(_run_cli = Module['_run_cli'] = wasmExports['yb'])());
|
|
8662
|
-
|
|
8663
8795
|
var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
|
|
8664
8796
|
(_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
|
|
8665
|
-
wasmExports['
|
|
8797
|
+
wasmExports['xb'])(a0));
|
|
8666
8798
|
|
|
8667
8799
|
var _wasm_set_phpini_path = (Module['_wasm_set_phpini_path'] = (a0) =>
|
|
8668
8800
|
(_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
|
|
8669
|
-
wasmExports['
|
|
8801
|
+
wasmExports['yb'])(a0));
|
|
8802
|
+
|
|
8803
|
+
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8804
|
+
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['zb'])(
|
|
8805
|
+
a0
|
|
8806
|
+
));
|
|
8807
|
+
|
|
8808
|
+
var _run_cli = (Module['_run_cli'] = () =>
|
|
8809
|
+
(_run_cli = Module['_run_cli'] = wasmExports['Ab'])());
|
|
8670
8810
|
|
|
8671
8811
|
var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
|
|
8672
8812
|
(_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
|