@php-wasm/node-8-2 3.0.53 → 3.1.0

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/jspi/php_8_2.js CHANGED
@@ -15,7 +15,7 @@ const currentDirPath =
15
15
  : path.dirname(fileURLToPath(import.meta.url));
16
16
  const dependencyFilename = path.join(currentDirPath, '8_2_30', 'php_8_2.wasm');
17
17
  export { dependencyFilename };
18
- export const dependenciesTotalSize = 26936455;
18
+ export const dependenciesTotalSize = 26936408;
19
19
  const phpVersionString = '8.2.30';
20
20
  export function init(RuntimeName, PHPLoader) {
21
21
  // The rest of the code comes from the built php.js file and esm-suffix.js
@@ -6396,7 +6396,81 @@ export function init(RuntimeName, PHPLoader) {
6396
6396
  O_NONBLOCK: 2048,
6397
6397
  POLLHUP: 16,
6398
6398
  SETFL_MASK: 3072,
6399
- init: function (phpWasmInitOptions) {
6399
+ init: function () {
6400
+ // TODO: Move this to a library function that is made an onInit callback by the `__postset` suffix.
6401
+ if (PHPLoader.bindUserSpace) {
6402
+ /**
6403
+ * We need to add an onInit callback to bind the user-space API
6404
+ * because some dependencies like wasmImports and wasmExports
6405
+ * are not yet assigned.
6406
+ */
6407
+ addOnInit(() => {
6408
+ Module['userSpace'] = PHPLoader.bindUserSpace({
6409
+ // TODO: Require PID instead of defaulting to 42.
6410
+ pid: PHPLoader.processId ?? 42,
6411
+ // TODO: When receiving this context, validate that all these fields exist.
6412
+ constants: {
6413
+ F_GETFL: Number('3'),
6414
+ O_ACCMODE: Number('2097155'),
6415
+ O_RDONLY: Number('0'),
6416
+ O_WRONLY: Number('1'),
6417
+ O_APPEND: Number('1024'),
6418
+ O_NONBLOCK: Number('2048'),
6419
+ F_SETFL: Number('4'),
6420
+ F_GETLK: Number('12'),
6421
+ F_SETLK: Number('13'),
6422
+ F_SETLKW: Number('14'),
6423
+ SEEK_SET: Number('0'),
6424
+ SEEK_CUR: Number('1'),
6425
+ SEEK_END: Number('2'),
6426
+ F_GETFL: Number('3'),
6427
+ O_ACCMODE: Number('2097155'),
6428
+ O_RDONLY: Number('0'),
6429
+ O_WRONLY: Number('1'),
6430
+ O_APPEND: Number('1024'),
6431
+ O_NONBLOCK: Number('2048'),
6432
+ F_SETFL: Number('4'),
6433
+ F_GETLK: Number('12'),
6434
+ F_SETLK: Number('13'),
6435
+ F_SETLKW: Number('14'),
6436
+ SEEK_SET: Number('0'),
6437
+ SEEK_CUR: Number('1'),
6438
+ SEEK_END: Number('2'),
6439
+ // From:
6440
+ // https://github.com/emscripten-core/emscripten/blob/66d2137b0381ac35f7e2346b2d6a90abd0f1211a/system/lib/libc/musl/include/fcntl.h#L58-L60
6441
+ F_RDLCK: 0,
6442
+ F_WRLCK: 1,
6443
+ F_UNLCK: 2,
6444
+ // From:
6445
+ // https://github.com/emscripten-core/emscripten/blob/81bbaa42a7827d88a71bd89701245052c622428c/system/lib/libc/musl/include/sys/file.h#L7-L10
6446
+ LOCK_SH: 1,
6447
+ LOCK_EX: 2,
6448
+ LOCK_NB: 4, // Non-blocking lock
6449
+ LOCK_UN: 8, // Unlock
6450
+ },
6451
+ errnoCodes: ERRNO_CODES,
6452
+ memory: {
6453
+ HEAP8,
6454
+ HEAPU8,
6455
+ HEAP16,
6456
+ HEAPU16,
6457
+ HEAP32,
6458
+ HEAPU32,
6459
+ HEAPF32,
6460
+ HEAP64,
6461
+ HEAPU64,
6462
+ HEAPF64,
6463
+ },
6464
+ wasmImports,
6465
+ wasmExports,
6466
+ syscalls: SYSCALLS,
6467
+ FS,
6468
+ PROXYFS,
6469
+ NODEFS,
6470
+ });
6471
+ });
6472
+ }
6473
+
6400
6474
  Module['ENV'] = Module['ENV'] || {};
6401
6475
  // Ensure a platform-level bin directory for a fallback `php` binary.
6402
6476
  Module['ENV']['PATH'] = [
@@ -6415,10 +6489,10 @@ export function init(RuntimeName, PHPLoader) {
6415
6489
  // and contains the php.ini, constants definitions, etc.
6416
6490
  FS.mkdir('/internal');
6417
6491
 
6418
- if (phpWasmInitOptions?.nativeInternalDirPath) {
6492
+ if (PHPLoader.nativeInternalDirPath) {
6419
6493
  FS.mount(
6420
6494
  FS.filesystems.NODEFS,
6421
- { root: phpWasmInitOptions.nativeInternalDirPath },
6495
+ { root: PHPLoader.nativeInternalDirPath },
6422
6496
  '/internal'
6423
6497
  );
6424
6498
  }
@@ -6728,19 +6802,32 @@ export function init(RuntimeName, PHPLoader) {
6728
6802
  },
6729
6803
  };
6730
6804
 
6731
- var _wasm_connect = function (sockfd, addr, addrlen) {
6805
+ function _wasm_connect(sockfd, addr, addrlen) {
6806
+ /**
6807
+ * Use a synchronous connect() call when Asyncify is used.
6808
+ *
6809
+ * The async version was originally introduced to support the Memcached and Redis extensions,
6810
+ * and both are only available with JSPI. Asyncify is too difficult to maintain and
6811
+ * it's not getting that upgrade.
6812
+ */
6813
+ if (!('Suspending' in WebAssembly)) {
6814
+ var sock = getSocketFromFD(sockfd);
6815
+ var info = getSocketAddress(addr, addrlen);
6816
+ sock.sock_ops.connect(sock, info.addr, info.port);
6817
+ return 0;
6818
+ }
6732
6819
  return Asyncify.handleSleep((wakeUp) => {
6733
6820
  // Get the socket
6734
6821
  let sock;
6735
6822
  try {
6736
6823
  sock = getSocketFromFD(sockfd);
6737
6824
  } catch (e) {
6738
- wakeUp(-ERRNO_CODES.EBADF); // EBADF
6825
+ wakeUp(-ERRNO_CODES.EBADF);
6739
6826
  return;
6740
6827
  }
6741
6828
 
6742
6829
  if (!sock) {
6743
- wakeUp(-ERRNO_CODES.EBADF); // EBADF
6830
+ wakeUp(-ERRNO_CODES.EBADF);
6744
6831
  return;
6745
6832
  }
6746
6833
 
@@ -6750,7 +6837,7 @@ export function init(RuntimeName, PHPLoader) {
6750
6837
  info = getSocketAddress(addr, addrlen);
6751
6838
  } catch (e) {
6752
6839
  if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) {
6753
- wakeUp(-ERRNO_CODES.EFAULT); // EFAULT
6840
+ wakeUp(-ERRNO_CODES.EFAULT);
6754
6841
  return;
6755
6842
  }
6756
6843
  wakeUp(-e.errno);
@@ -6836,7 +6923,7 @@ export function init(RuntimeName, PHPLoader) {
6836
6923
  ws.addEventListener('error', handleError);
6837
6924
  ws.addEventListener('close', handleClose);
6838
6925
  });
6839
- };
6926
+ }
6840
6927
 
6841
6928
  function ___syscall_connect(sockfd, addr, addrlen, d1, d2, d3) {
6842
6929
  return _wasm_connect(sockfd, addr, addrlen);
@@ -7007,55 +7094,12 @@ export function init(RuntimeName, PHPLoader) {
7007
7094
  };
7008
7095
  var syscallGetVarargP = syscallGetVarargI;
7009
7096
 
7010
- var _fd_close = function fd_close(fd) {
7011
- return Asyncify.handleAsync(async () => {
7012
- // We have to get the VFS path from the file descriptor
7013
- // before closing it.
7014
- const [vfsPath, vfsPathResolutionErrno] =
7015
- locking.get_vfs_path_from_fd(fd);
7016
-
7017
- const fdCloseResult = _builtin_fd_close(fd);
7018
- if (fdCloseResult !== 0 || !locking.maybeLockedFds.has(fd)) {
7019
- _js_wasm_trace('fd_close(%d) result %d', fd, fdCloseResult);
7020
- return fdCloseResult;
7021
- }
7022
-
7023
- if (vfsPathResolutionErrno !== 0) {
7024
- _js_wasm_trace(
7025
- 'fd_close(%d) get_vfs_path_from_fd error %d',
7026
- fd,
7027
- vfsPathResolutionErrno
7028
- );
7029
- /*
7030
- * It looks like the file may have had an associated lock,
7031
- * but since we cannot look up the path,
7032
- * there is nothing more for us to do.
7033
- *
7034
- * NOTE: This seems possible for files that are locked and
7035
- * then unlinked before close. It is an opportunity for a
7036
- * lock to be orphaned in the lock manager.
7037
- * @TODO: Explore how to ensure cleanup in this case.
7038
- */
7039
- return fdCloseResult;
7040
- }
7041
-
7042
- try {
7043
- const nativeFilePath =
7044
- locking.get_native_path_from_vfs_path(vfsPath);
7045
- await PHPLoader.fileLockManager.releaseLocksForProcessFd(
7046
- PHPLoader.processId,
7047
- fd,
7048
- nativeFilePath
7049
- );
7050
- _js_wasm_trace('fd_close(%d) release locks success', fd);
7051
- } catch (e) {
7052
- _js_wasm_trace("fd_close(%d) error '%s'", fd, e);
7053
- } finally {
7054
- locking.maybeLockedFds.delete(fd);
7055
- }
7056
- return fdCloseResult;
7057
- });
7058
- };
7097
+ function _fd_close(fd) {
7098
+ if (typeof Module['userSpace'] === 'undefined') {
7099
+ return _builtin_fd_close(fd);
7100
+ }
7101
+ return Module['userSpace'].fd_close(fd);
7102
+ }
7059
7103
  _fd_close.sig = 'ii';
7060
7104
  function _builtin_fd_close(fd) {
7061
7105
  try {
@@ -7117,663 +7161,11 @@ export function init(RuntimeName, PHPLoader) {
7117
7161
  }
7118
7162
  }
7119
7163
 
7120
- var locking = {
7121
- maybeLockedFds: new Set(),
7122
- F_RDLCK: 0,
7123
- F_WRLCK: 1,
7124
- F_UNLCK: 2,
7125
- lockStateToFcntl: {
7126
- shared: 0,
7127
- exclusive: 1,
7128
- unlocked: 2,
7129
- },
7130
- fcntlToLockState: {
7131
- 0: 'shared',
7132
- 1: 'exclusive',
7133
- 2: 'unlocked',
7134
- },
7135
- is_path_to_shared_fs(path) {
7136
- _js_wasm_trace('is_path_to_shared_fs(%s)', path);
7137
- const { node } = FS.lookupPath(path, { noent_okay: true });
7138
- if (!node) {
7139
- return false;
7140
- }
7141
- if (node.mount.type !== PROXYFS) {
7142
- return !!node.isSharedFS;
7143
- }
7144
-
7145
- // This looks like a PROXYFS node. Let's try a lookup.
7146
- const nodePath = PROXYFS.realPath(node);
7147
- const backingFs = node?.mount?.opts?.fs;
7148
- if (backingFs) {
7149
- // Tolerate ENOENT because looking up a MEMFS node by path always fails.
7150
- const { node: backingNode } = backingFs.lookupPath(nodePath, {
7151
- noent_okay: true,
7152
- });
7153
- return !!backingNode?.isSharedFS;
7154
- }
7155
-
7156
- return false;
7157
- },
7158
- get_fd_access_mode(fd) {
7159
- const emscripten_F_GETFL = Number('3');
7160
- const emscripten_O_ACCMODE = Number('2097155');
7161
-
7162
- return (
7163
- _builtin_fcntl64(fd, emscripten_F_GETFL) & emscripten_O_ACCMODE
7164
- );
7165
- },
7166
- get_vfs_path_from_fd(fd) {
7167
- try {
7168
- return [FS.readlink(`/proc/self/fd/${fd}`), 0];
7169
- } catch (error) {
7170
- return [null, ERRNO_CODES.EBADF];
7171
- }
7172
- },
7173
- get_native_path_from_vfs_path(vfsPath) {
7174
- const { node } = FS.lookupPath(vfsPath, {
7175
- noent_okay: true,
7176
- });
7177
- if (!node) {
7178
- throw new Error(`No node found for VFS path ${vfsPath}`);
7179
- }
7180
- if (node.mount.type === NODEFS) {
7181
- return NODEFS.realPath(node);
7182
- } else if (node.mount.type === PROXYFS) {
7183
- // TODO: Tolerate ENOENT here?
7184
- const { node: backingNode, path: backingPath } =
7185
- node.mount.opts.fs.lookupPath(vfsPath);
7186
- _js_wasm_trace(
7187
- 'backingNode for %s: %s',
7188
- vfsPath,
7189
- backingPath,
7190
- backingNode
7191
- );
7192
- return backingNode.mount.type.realPath(backingNode);
7193
- } else {
7194
- throw new Error(
7195
- `Unsupported filesystem type for path ${vfsPath}`
7196
- );
7197
- }
7198
- },
7199
- check_lock_params(fd, l_type) {
7200
- const emscripten_O_RDONLY = Number('0');
7201
- const emscripten_O_WRONLY = Number('1');
7202
-
7203
- const accessMode = locking.get_fd_access_mode(fd);
7204
- if (
7205
- (l_type === locking.F_WRLCK &&
7206
- accessMode === emscripten_O_RDONLY) ||
7207
- (l_type === locking.F_RDLCK &&
7208
- accessMode === emscripten_O_WRONLY)
7209
- ) {
7210
- return ERRNO_CODES.EBADF;
7211
- }
7212
-
7213
- return 0;
7214
- },
7215
- };
7216
-
7217
7164
  function ___syscall_fcntl64(fd, cmd, varargs) {
7218
- if (!PHPLoader.fileLockManager) {
7165
+ if (typeof Module['userSpace'] === 'undefined') {
7219
7166
  return _builtin_fcntl64(fd, cmd, varargs);
7220
7167
  }
7221
- return Asyncify.handleAsync(async () => {
7222
- // Necessary to use varargs accessor
7223
- SYSCALLS.varargs = varargs;
7224
-
7225
- // These constants are replaced by Emscripten during the build process
7226
- const emscripten_F_SETFL = Number('4');
7227
- const emscripten_F_GETLK = Number('12');
7228
- const emscripten_F_SETLK = Number('13');
7229
- const emscripten_F_SETLKW = Number('14');
7230
- const emscripten_SEEK_SET = Number('0');
7231
-
7232
- // NOTE: With the exception of l_type, these offsets are not exposed to
7233
- // JS by Emscripten, so we hardcode them here.
7234
- const emscripten_flock_l_type_offset = 0;
7235
- const emscripten_flock_l_whence_offset = 2;
7236
- const emscripten_flock_l_start_offset = 8;
7237
- const emscripten_flock_l_len_offset = 16;
7238
- const emscripten_flock_l_pid_offset = 24;
7239
-
7240
- /**
7241
- * Read the flock struct at the given address.
7242
- *
7243
- * @param {bigint} flockStructAddress - the address of the flock struct
7244
- * @returns the flock struct
7245
- */
7246
- function read_flock_struct(flockStructAddress) {
7247
- /*
7248
- * NOTE: Since we are using HEAP<WORD_SIZE> vars like HEAP16 and HEAP64,
7249
- * we need to adjust offsets to address the word size of each HEAP.
7250
- *
7251
- * For example, an offset of 64 bytes is the following for each HEAP:
7252
- * - HEAP8: 64 (the 64th byte)
7253
- * - HEAP16: 32 (the 32nd 16-bit word)
7254
- * - HEAP32: 16 (the 16th 32-bit word)
7255
- * - HEAP64: 8 (the 8th 64-bit word)
7256
- *
7257
- * We get a word offset by dividing the byte offset by the word size.
7258
- */
7259
- return {
7260
- l_type: HEAP16[
7261
- // Shift right by 1 to divide by 2^1.
7262
- (flockStructAddress + emscripten_flock_l_type_offset) >>
7263
- 1
7264
- ],
7265
- l_whence:
7266
- HEAP16[
7267
- // Shift right by 1 to divide by 2^1.
7268
- (flockStructAddress +
7269
- emscripten_flock_l_whence_offset) >>
7270
- 1
7271
- ],
7272
- l_start:
7273
- HEAP64[
7274
- // Shift right by 3 to divide by 2^3.
7275
- (flockStructAddress +
7276
- emscripten_flock_l_start_offset) >>
7277
- 3
7278
- ],
7279
- l_len: HEAP64[
7280
- // Shift right by 3 to divide by 2^3.
7281
- (flockStructAddress + emscripten_flock_l_len_offset) >>
7282
- 3
7283
- ],
7284
- l_pid: HEAP32[
7285
- // Shift right by 2 to divide by 2^2.
7286
- (flockStructAddress + emscripten_flock_l_pid_offset) >>
7287
- 2
7288
- ],
7289
- };
7290
- }
7291
-
7292
- /**
7293
- * Update the flock struct at the given address with the given fields.
7294
- *
7295
- * @param {bigint} flockStructAddress - the address of the flock struct
7296
- * @param {object} fields - the fields to update
7297
- */
7298
- function update_flock_struct(flockStructAddress, fields) {
7299
- /*
7300
- * NOTE: Since we are using HEAP<WORD_SIZE> vars like HEAP16 and HEAP64,
7301
- * we need to adjust offsets to address the word size of each HEAP.
7302
- *
7303
- * For example, an offset of 64 bytes is the following for each HEAP:
7304
- * - HEAP8: 64 (the 64th byte)
7305
- * - HEAP16: 32 (the 32nd 16-bit word)
7306
- * - HEAP32: 16 (the 16th 32-bit word)
7307
- * - HEAP64: 8 (the 8th 64-bit word)
7308
- *
7309
- * We get a word offset by dividing the byte offset by the word size.
7310
- */
7311
- if (fields.l_type !== undefined) {
7312
- HEAP16[
7313
- // Shift right by 1 to divide by 2^1.
7314
- (flockStructAddress + emscripten_flock_l_type_offset) >>
7315
- 1
7316
- ] = fields.l_type;
7317
- }
7318
- if (fields.l_whence !== undefined) {
7319
- HEAP16[
7320
- // Shift right by 1 to divide by 2^1.
7321
- (flockStructAddress +
7322
- emscripten_flock_l_whence_offset) >>
7323
- 1
7324
- ] = fields.l_whence;
7325
- }
7326
- if (fields.l_start !== undefined) {
7327
- HEAP64[
7328
- // Shift right by 3 to divide by 2^3.
7329
- (flockStructAddress +
7330
- emscripten_flock_l_start_offset) >>
7331
- 3
7332
- ] = fields.l_start;
7333
- }
7334
- if (fields.l_len !== undefined) {
7335
- HEAP64[
7336
- // Shift right by 3 to divide by 2^3.
7337
- (flockStructAddress + emscripten_flock_l_len_offset) >>
7338
- 3
7339
- ] = fields.l_len;
7340
- }
7341
- if (fields.l_pid !== undefined) {
7342
- HEAP32[
7343
- // Shift right by 2 to divide by 2^2.
7344
- (flockStructAddress + emscripten_flock_l_pid_offset) >>
7345
- 2
7346
- ] = fields.l_pid;
7347
- }
7348
- }
7349
-
7350
- /**
7351
- * Resolve the base address of the range depending on the whence and start offset.
7352
- *
7353
- * @param {number} fd - the file descriptor
7354
- * @param {number} whence - what the start offset is relative to
7355
- * @param {bigint} startOffset - the offset from the whence
7356
- * @returns The resolved offset and the errno. If there is an error,
7357
- * the resolved offset is null, and the errno is non-zero.
7358
- */
7359
- function get_base_address(fd, whence, startOffset) {
7360
- let baseAddress;
7361
- switch (whence) {
7362
- case emscripten_SEEK_SET:
7363
- baseAddress = 0n;
7364
- break;
7365
- case emscripten_SEEK_CUR:
7366
- baseAddress = FS.lseek(fd, 0, whence);
7367
- break;
7368
- case emscripten_SEEK_END:
7369
- baseAddress = _wasm_get_end_offset(fd);
7370
- break;
7371
- default:
7372
- return [null, ERRNO_CODES.EINVAL];
7373
- }
7374
-
7375
- if (baseAddress == -1) {
7376
- // We cannot resolve the offset within the file.
7377
- // Let's treat this as a problem with the file descriptor.
7378
- return [null, ERRNO_CODES.EBADF];
7379
- }
7380
-
7381
- const resolvedOffset = baseAddress + startOffset;
7382
- if (resolvedOffset < 0) {
7383
- // This is not a valid offset. Report args as invalid.
7384
- return [null, ERRNO_CODES.EINVAL];
7385
- }
7386
-
7387
- return [resolvedOffset, 0];
7388
- }
7389
-
7390
- const pid = PHPLoader.processId;
7391
- switch (cmd) {
7392
- case emscripten_F_GETLK: {
7393
- _js_wasm_trace('fcntl(%d, F_GETLK)', fd);
7394
- let vfsPath;
7395
- let errno;
7396
-
7397
- [vfsPath, errno] = locking.get_vfs_path_from_fd(fd);
7398
- if (errno !== 0) {
7399
- _js_wasm_trace(
7400
- 'fcntl(%d, F_GETLK) %s get_vfs_path_from_fd errno %d',
7401
- fd,
7402
- vfsPath,
7403
- errno
7404
- );
7405
- return -ERRNO_CODES.EBADF;
7406
- }
7407
-
7408
- const flockStructAddr = syscallGetVarargP();
7409
-
7410
- if (!locking.is_path_to_shared_fs(vfsPath)) {
7411
- _js_wasm_trace(
7412
- "fcntl(%d, F_GETLK) locking is not implemented for non-NodeFS path '%s'",
7413
- fd,
7414
- vfsPath
7415
- );
7416
-
7417
- // If not a NodeFS path, we can't lock it.
7418
- // Default to succeeding as Emscripten does.
7419
- update_flock_struct(flockStructAddr, {
7420
- l_type: F_UNLCK,
7421
- });
7422
- return 0;
7423
- }
7424
-
7425
- const flockStruct = read_flock_struct(flockStructAddr);
7426
-
7427
- if (!(flockStruct.l_type in locking.fcntlToLockState)) {
7428
- return -ERRNO_CODES.EINVAL;
7429
- }
7430
-
7431
- errno = locking.check_lock_params(fd, flockStruct.l_type);
7432
- if (errno !== 0) {
7433
- _js_wasm_trace(
7434
- 'fcntl(%d, F_GETLK) %s check_lock_params errno %d',
7435
- fd,
7436
- vfsPath,
7437
- errno
7438
- );
7439
- return -ERRNO_CODES.EINVAL;
7440
- }
7441
-
7442
- const requestedLockType =
7443
- locking.fcntlToLockState[flockStruct.l_type];
7444
- let absoluteStartOffset;
7445
- [absoluteStartOffset, errno] = get_base_address(
7446
- fd,
7447
- flockStruct.l_whence,
7448
- flockStruct.l_start
7449
- );
7450
- if (errno !== 0) {
7451
- _js_wasm_trace(
7452
- 'fcntl(%d, F_GETLK) %s get_base_address errno %d',
7453
- fd,
7454
- vfsPath,
7455
- errno
7456
- );
7457
- return -ERRNO_CODES.EINVAL;
7458
- }
7459
-
7460
- try {
7461
- const nativeFilePath =
7462
- locking.get_native_path_from_vfs_path(vfsPath);
7463
- const conflictingLock = await Promise.resolve(
7464
- PHPLoader.fileLockManager.findFirstConflictingByteRangeLock(
7465
- nativeFilePath,
7466
- {
7467
- type: requestedLockType,
7468
- start: absoluteStartOffset,
7469
- end:
7470
- absoluteStartOffset + flockStruct.l_len,
7471
- pid,
7472
- }
7473
- )
7474
- );
7475
- if (conflictingLock === undefined) {
7476
- _js_wasm_trace(
7477
- 'fcntl(%d, F_GETLK) %s findFirstConflictingByteRangeLock type=unlocked start=0x%x end=0x%x',
7478
- fd,
7479
- vfsPath,
7480
- absoluteStartOffset,
7481
- absoluteStartOffset + flockStruct.l_len
7482
- );
7483
-
7484
- update_flock_struct(flockStructAddr, {
7485
- l_type: F_UNLCK,
7486
- });
7487
- return 0;
7488
- }
7489
-
7490
- _js_wasm_trace(
7491
- 'fcntl(%d, F_GETLK) %s findFirstConflictingByteRangeLock type=%s start=0x%x end=0x%x conflictingLock %d',
7492
- fd,
7493
- vfsPath,
7494
- conflictingLock.type,
7495
- conflictingLock.start,
7496
- conflictingLock.end,
7497
- conflictingLock.pid
7498
- );
7499
-
7500
- const fcntlLockState =
7501
- locking.lockStateToFcntl[conflictingLock.type];
7502
- update_flock_struct(flockStructAddr, {
7503
- l_type: fcntlLockState,
7504
- l_whence: emscripten_SEEK_SET,
7505
- l_start: conflictingLock.start,
7506
- l_len: conflictingLock.end - conflictingLock.start,
7507
- l_pid: conflictingLock.pid,
7508
- });
7509
- return 0;
7510
- } catch (e) {
7511
- _js_wasm_trace(
7512
- 'fcntl(%d, F_GETLK) %s findFirstConflictingByteRangeLock error %s',
7513
- fd,
7514
- vfsPath,
7515
- e
7516
- );
7517
- return -ERRNO_CODES.EINVAL;
7518
- }
7519
- }
7520
- case emscripten_F_SETLK: {
7521
- _js_wasm_trace('fcntl(%d, F_SETLK)', fd);
7522
- let vfsPath;
7523
- let errno;
7524
- [vfsPath, errno] = locking.get_vfs_path_from_fd(fd);
7525
- if (errno !== 0) {
7526
- _js_wasm_trace(
7527
- 'fcntl(%d, F_SETLK) %s get_vfs_path_from_fd errno %d',
7528
- fd,
7529
- vfsPath,
7530
- errno
7531
- );
7532
- return -errno;
7533
- }
7534
-
7535
- if (!locking.is_path_to_shared_fs(vfsPath)) {
7536
- _js_wasm_trace(
7537
- 'fcntl(%d, F_SETLK) locking is not implemented for non-NodeFS path %s',
7538
- fd,
7539
- vfsPath
7540
- );
7541
-
7542
- // If not a NodeFS path, we can't lock it.
7543
- // Default to succeeding as Emscripten does.
7544
- return 0;
7545
- }
7546
-
7547
- var flockStructAddr = syscallGetVarargP();
7548
- const flockStruct = read_flock_struct(flockStructAddr);
7549
-
7550
- let absoluteStartOffset;
7551
- [absoluteStartOffset, errno] = get_base_address(
7552
- fd,
7553
- flockStruct.l_whence,
7554
- flockStruct.l_start
7555
- );
7556
- if (errno !== 0) {
7557
- _js_wasm_trace(
7558
- 'fcntl(%d, F_SETLK) %s get_base_address errno %d',
7559
- fd,
7560
- vfsPath,
7561
- errno
7562
- );
7563
- return -errno;
7564
- }
7565
-
7566
- if (!(flockStruct.l_type in locking.fcntlToLockState)) {
7567
- _js_wasm_trace(
7568
- 'fcntl(%d, F_SETLK) %s invalid lock type %d',
7569
- fd,
7570
- vfsPath,
7571
- flockStruct.l_type
7572
- );
7573
- return -ERRNO_CODES.EINVAL;
7574
- }
7575
-
7576
- errno = locking.check_lock_params(fd, flockStruct.l_type);
7577
- if (errno !== 0) {
7578
- _js_wasm_trace(
7579
- 'fcntl(%d, F_SETLK) %s check_lock_params errno %d',
7580
- fd,
7581
- vfsPath,
7582
- errno
7583
- );
7584
- return -errno;
7585
- }
7586
-
7587
- locking.maybeLockedFds.add(fd);
7588
-
7589
- const requestedLockType =
7590
- locking.fcntlToLockState[flockStruct.l_type];
7591
- const rangeLock = {
7592
- type: requestedLockType,
7593
- start: absoluteStartOffset,
7594
- end: absoluteStartOffset + flockStruct.l_len,
7595
- pid,
7596
- };
7597
-
7598
- try {
7599
- const nativeFilePath =
7600
- locking.get_native_path_from_vfs_path(vfsPath);
7601
- _js_wasm_trace(
7602
- 'fcntl(%d, F_SETLK) %s calling lockFileByteRange for range lock %s',
7603
- fd,
7604
- vfsPath,
7605
- rangeLock
7606
- );
7607
-
7608
- const succeeded = await Promise.resolve(
7609
- PHPLoader.fileLockManager.lockFileByteRange(
7610
- nativeFilePath,
7611
- rangeLock
7612
- )
7613
- );
7614
-
7615
- _js_wasm_trace(
7616
- 'fcntl(%d, F_SETLK) %s lockFileByteRange returned %d for range lock %s',
7617
- fd,
7618
- vfsPath,
7619
- succeeded,
7620
- rangeLock
7621
- );
7622
- return succeeded ? 0 : -ERRNO_CODES.EAGAIN;
7623
- } catch (e) {
7624
- _js_wasm_trace(
7625
- 'fcntl(%d, F_SETLK) %s lockFileByteRange error %s for range lock %s',
7626
- fd,
7627
- vfsPath,
7628
- e,
7629
- rangeLock
7630
- );
7631
- return -ERRNO_CODES.EINVAL;
7632
- }
7633
- }
7634
- // @TODO: Implement a blocking version of F_SETLKW instead of
7635
- // treating it the same as F_SETLK.
7636
- case emscripten_F_SETLKW: {
7637
- // F_SETLKW is the blocking version of F_SETLK.
7638
- // For now, we treat it the same as F_SETLK (non-blocking).
7639
- // In a true blocking implementation, this would wait for the lock to become available.
7640
- _js_wasm_trace('fcntl(%d, F_SETLKW)', fd);
7641
- let vfsPath;
7642
- let errno;
7643
- [vfsPath, errno] = locking.get_vfs_path_from_fd(fd);
7644
- if (errno !== 0) {
7645
- _js_wasm_trace(
7646
- 'fcntl(%d, F_SETLKW) %s get_vfs_path_from_fd errno %d',
7647
- fd,
7648
- vfsPath,
7649
- errno
7650
- );
7651
- return -errno;
7652
- }
7653
-
7654
- if (!locking.is_path_to_shared_fs(vfsPath)) {
7655
- _js_wasm_trace(
7656
- 'fcntl(%d, F_SETLKW) locking is not implemented for non-NodeFS path %s',
7657
- fd,
7658
- vfsPath
7659
- );
7660
-
7661
- // If not a NodeFS path, we can't lock it.
7662
- // Default to succeeding as Emscripten does.
7663
- return 0;
7664
- }
7665
-
7666
- var flockStructAddr = syscallGetVarargP();
7667
- const flockStruct = read_flock_struct(flockStructAddr);
7668
-
7669
- let absoluteStartOffset;
7670
- [absoluteStartOffset, errno] = get_base_address(
7671
- fd,
7672
- flockStruct.l_whence,
7673
- flockStruct.l_start
7674
- );
7675
- if (errno !== 0) {
7676
- _js_wasm_trace(
7677
- 'fcntl(%d, F_SETLKW) %s get_base_address errno %d',
7678
- fd,
7679
- vfsPath,
7680
- errno
7681
- );
7682
- return -errno;
7683
- }
7684
-
7685
- if (!(flockStruct.l_type in locking.fcntlToLockState)) {
7686
- _js_wasm_trace(
7687
- 'fcntl(%d, F_SETLKW) %s invalid lock type %d',
7688
- fd,
7689
- vfsPath,
7690
- flockStruct.l_type
7691
- );
7692
- return -ERRNO_CODES.EINVAL;
7693
- }
7694
-
7695
- errno = locking.check_lock_params(fd, flockStruct.l_type);
7696
- if (errno !== 0) {
7697
- _js_wasm_trace(
7698
- 'fcntl(%d, F_SETLKW) %s check_lock_params errno %d',
7699
- fd,
7700
- vfsPath,
7701
- errno
7702
- );
7703
- return -errno;
7704
- }
7705
-
7706
- locking.maybeLockedFds.add(fd);
7707
-
7708
- const requestedLockType =
7709
- locking.fcntlToLockState[flockStruct.l_type];
7710
- const rangeLock = {
7711
- type: requestedLockType,
7712
- start: absoluteStartOffset,
7713
- end: absoluteStartOffset + flockStruct.l_len,
7714
- pid,
7715
- };
7716
-
7717
- try {
7718
- const nativeFilePath =
7719
- locking.get_native_path_from_vfs_path(vfsPath);
7720
- _js_wasm_trace(
7721
- 'fcntl(%d, F_SETLKW) %s calling lockFileByteRange for range lock %s',
7722
- fd,
7723
- vfsPath,
7724
- rangeLock
7725
- );
7726
-
7727
- const succeeded = await Promise.resolve(
7728
- PHPLoader.fileLockManager.lockFileByteRange(
7729
- nativeFilePath,
7730
- rangeLock
7731
- )
7732
- );
7733
-
7734
- _js_wasm_trace(
7735
- 'fcntl(%d, F_SETLKW) %s lockFileByteRange returned %d for range lock %s',
7736
- fd,
7737
- vfsPath,
7738
- succeeded,
7739
- rangeLock
7740
- );
7741
- return succeeded ? 0 : -ERRNO_CODES.EAGAIN;
7742
- } catch (e) {
7743
- _js_wasm_trace(
7744
- 'fcntl(%d, F_SETLKW) %s lockFileByteRange error %s for range lock %s',
7745
- fd,
7746
- vfsPath,
7747
- e,
7748
- rangeLock
7749
- );
7750
- return -ERRNO_CODES.EINVAL;
7751
- }
7752
- }
7753
- case emscripten_F_SETFL: {
7754
- /**
7755
- * Overrides the core Emscripten implementation to reflect what
7756
- * fcntl does in linux kernel. This implementation is still missing
7757
- * a bunch of nuance, but, unlike the core Emscripten implementation,
7758
- * it overrides the stream flags while preserving non-stream flags.
7759
- *
7760
- * @see fcntl.c:
7761
- * https://github.com/torvalds/linux/blob/a79a588fc1761dc12a3064fc2f648ae66cea3c5a/fs/fcntl.c#L39
7762
- */
7763
- const arg = varargs ? syscallGetVarargI() : 0;
7764
- const stream = SYSCALLS.getStreamFromFD(fd);
7765
-
7766
- // Update the stream flags
7767
- stream.flags =
7768
- (arg & PHPWASM.SETFL_MASK) |
7769
- (stream.flags & ~PHPWASM.SETFL_MASK);
7770
-
7771
- return 0;
7772
- }
7773
- default:
7774
- return _builtin_fcntl64(fd, cmd, varargs);
7775
- }
7776
- });
7168
+ return Module['userSpace'].fcntl64(fd, cmd, varargs);
7777
7169
  }
7778
7170
  ___syscall_fcntl64.sig = 'iiip';
7779
7171
 
@@ -17160,122 +16552,14 @@ export function init(RuntimeName, PHPLoader) {
17160
16552
  };
17161
16553
  _getprotobynumber.sig = 'pi';
17162
16554
 
17163
- var _js_flock = function js_flock(fd, op) {
17164
- return Asyncify.handleAsync(async () => {
17165
- _js_wasm_trace('js_flock(%d, %d)', fd, op);
17166
- // Emscripten does not expose these constants to JS, so we hardcode them here.
17167
- // Based on
17168
- // https://github.com/emscripten-core/emscripten/blob/76860cc47cef67f5712a7a03a247bc1baabf7ba4/system/lib/libc/musl/include/sys/file.h#L7-L10
17169
- const emscripten_LOCK_SH = 1;
17170
- const emscripten_LOCK_EX = 2;
17171
- const emscripten_LOCK_NB = 4;
17172
- const emscripten_LOCK_UN = 8;
17173
-
17174
- const flockToLockOpType = {
17175
- [emscripten_LOCK_SH]: 'shared',
17176
- [emscripten_LOCK_EX]: 'exclusive',
17177
- [emscripten_LOCK_UN]: 'unlocked',
17178
- };
17179
-
17180
- let vfsPath;
17181
- let errno;
17182
-
17183
- [vfsPath, errno] = locking.get_vfs_path_from_fd(fd);
17184
- if (errno !== 0) {
17185
- _js_wasm_trace(
17186
- 'js_flock(%d, %d) get_vfs_path_from_fd errno %d',
17187
- fd,
17188
- op,
17189
- vfsPath,
17190
- errno
17191
- );
17192
- return -errno;
17193
- }
17194
-
17195
- if (!locking.is_path_to_shared_fs(vfsPath)) {
17196
- _js_wasm_trace(
17197
- 'flock(%d, %d) locking is not implemented for non-NodeFS path %s',
17198
- fd,
17199
- op,
17200
- vfsPath
17201
- );
17202
- // If not a NodeFS path, we can't lock it.
17203
- // Default to succeeding as Emscripten does.
17204
- return 0;
17205
- }
17206
-
17207
- errno = locking.check_lock_params(fd, op);
17208
- if (errno !== 0) {
17209
- _js_wasm_trace(
17210
- 'js_flock(%d, %d) check_lock_params errno %d',
17211
- fd,
17212
- op,
17213
- errno
17214
- );
17215
- return -errno;
17216
- }
17217
-
17218
- // @TODO: Consider supporting blocking mode of flock()
17219
- if (op & (emscripten_LOCK_NB === 0)) {
17220
- _js_wasm_trace(
17221
- 'js_flock(%d, %d) blocking mode of flock() is not implemented',
17222
- fd,
17223
- op
17224
- );
17225
- // We do not yet support the blocking form of flock().
17226
- // We respond with EINVAL to indicate failure
17227
- // because it is a known errno for a failed blocking flock().
17228
- return -ERRNO_CODES.EINVAL;
17229
- }
17230
-
17231
- const maskedOp =
17232
- op &
17233
- (emscripten_LOCK_SH | emscripten_LOCK_EX | emscripten_LOCK_UN);
17234
-
17235
- const lockOpType = flockToLockOpType[maskedOp];
17236
- if (lockOpType === undefined) {
17237
- _js_wasm_trace(
17238
- 'js_flock(%d, %d) invalid flock() operation',
17239
- fd,
17240
- op
17241
- );
17242
- return -ERRNO_CODES.EINVAL;
17243
- }
17244
-
17245
- try {
17246
- const nativeFilePath =
17247
- locking.get_native_path_from_vfs_path(vfsPath);
17248
- const obtainedLock = await Promise.resolve(
17249
- PHPLoader.fileLockManager.lockWholeFile(nativeFilePath, {
17250
- type: lockOpType,
17251
- pid: PHPLoader.processId,
17252
- fd,
17253
- })
17254
- );
17255
- _js_wasm_trace(
17256
- 'js_flock(%d, %d) lockWholeFile %s returned %d',
17257
- fd,
17258
- op,
17259
- vfsPath,
17260
- obtainedLock
17261
- );
17262
- if (obtainedLock) {
17263
- locking.maybeLockedFds.add(fd);
17264
- return 0;
17265
- } else {
17266
- return -ERRNO_CODES.EWOULDBLOCK;
17267
- }
17268
- } catch (e) {
17269
- _js_wasm_trace(
17270
- 'js_flock(%d, %d) lockWholeFile error %s',
17271
- fd,
17272
- op,
17273
- e
17274
- );
17275
- return -ERRNO_CODES.EINVAL;
17276
- }
17277
- });
17278
- };
16555
+ function _js_flock(fd, op) {
16556
+ if (typeof Module['userSpace'] === 'undefined') {
16557
+ // In the absence of a real locking facility,
16558
+ // return success by default as Emscripten does.
16559
+ return 0;
16560
+ }
16561
+ return Module['userSpace'].flock(fd, op);
16562
+ }
17279
16563
 
17280
16564
  function _js_open_process(
17281
16565
  command,
@@ -17626,27 +16910,12 @@ export function init(RuntimeName, PHPLoader) {
17626
16910
  return 0;
17627
16911
  }
17628
16912
 
17629
- var _js_release_file_locks = function js_release_file_locks() {
17630
- return Asyncify.handleAsync(async () => {
17631
- _js_wasm_trace('js_release_file_locks()');
17632
- const pid = PHPLoader.processId;
17633
- if (!pid || !PHPLoader.fileLockManager) {
17634
- _js_wasm_trace(
17635
- 'js_release_file_locks no pid or file lock manager'
17636
- );
17637
- return 0;
17638
- }
17639
-
17640
- try {
17641
- await Promise.resolve(
17642
- PHPLoader.fileLockManager.releaseLocksForProcess(pid)
17643
- );
17644
- _js_wasm_trace('js_release_file_locks succeeded');
17645
- } catch (e) {
17646
- _js_wasm_trace('js_release_file_locks error %s', e);
17647
- }
17648
- });
17649
- };
16913
+ function _js_release_file_locks() {
16914
+ if (typeof Module['userSpace'] === 'undefined') {
16915
+ return;
16916
+ }
16917
+ return Module['userSpace'].js_release_file_locks();
16918
+ }
17650
16919
 
17651
16920
  function _js_waitpid(pid, exitCodePtr) {
17652
16921
  if (!PHPWASM.processTable[pid]) {
@@ -30662,6 +29931,31 @@ export function init(RuntimeName, PHPLoader) {
30662
29931
  );
30663
29932
  }
30664
29933
 
29934
+ var ___emscripten_lookup_name = function __emscripten_lookup_name(namePtr) {
29935
+ return Asyncify.handleAsync(async () => {
29936
+ if (!ENVIRONMENT_IS_NODE) {
29937
+ return original__emscripten_lookup_name(namePtr);
29938
+ }
29939
+ if (!PHPLoader.syscalls) {
29940
+ return original__emscripten_lookup_name(namePtr);
29941
+ }
29942
+
29943
+ const hostname = UTF8ToString(namePtr);
29944
+
29945
+ let ipString = '';
29946
+ try {
29947
+ ipString = await Promise.resolve(
29948
+ PHPLoader.syscalls.gethostbyname(hostname)
29949
+ );
29950
+ } catch (e) {
29951
+ // Fall through to the default synthetic mapping if native DNS fails.
29952
+ }
29953
+
29954
+ return inetPton4(ipString);
29955
+ });
29956
+ };
29957
+ ___emscripten_lookup_name.sig = 'ip';
29958
+
30665
29959
  var webSockets = new HandleAllocator();
30666
29960
 
30667
29961
  var WS = {
@@ -30995,7 +30289,7 @@ export function init(RuntimeName, PHPLoader) {
30995
30289
  if (ENVIRONMENT_IS_NODE) {
30996
30290
  NODEFS.staticInit();
30997
30291
  }
30998
- PHPWASM.init(PHPLoader?.phpWasmInitOptions);
30292
+ PHPWASM.init();
30999
30293
 
31000
30294
  Module['requestAnimationFrame'] = MainLoop.requestAnimationFrame;
31001
30295
  Module['pauseMainLoop'] = MainLoop.pause;
@@ -31053,6 +30347,11 @@ export function init(RuntimeName, PHPLoader) {
31053
30347
  // invocation, so that we will immediately be able to queue the newest
31054
30348
  // produced audio samples.
31055
30349
  registerPostMainLoop(() => SDL.audio?.queueNewAudioData?.());
30350
+ const original__emscripten_lookup_name = __emscripten_lookup_name;
30351
+ if (typeof __emscripten_lookup_name !== 'undefined') {
30352
+ __emscripten_lookup_name = ___emscripten_lookup_name;
30353
+ }
30354
+ ___emscripten_lookup_name.isAsync = true;
31056
30355
  // End JS library code
31057
30356
 
31058
30357
  // include: postlibrary.js
@@ -31116,13 +30415,13 @@ export function init(RuntimeName, PHPLoader) {
31116
30415
  // end include: postlibrary.js
31117
30416
 
31118
30417
  var ASM_CONSTS = {
31119
- 13131858: ($0) => {
30418
+ 13131602: ($0) => {
31120
30419
  if (!$0) {
31121
30420
  AL.alcErr = 0xa004;
31122
30421
  return 1;
31123
30422
  }
31124
30423
  },
31125
- 13131906: ($0) => {
30424
+ 13131650: ($0) => {
31126
30425
  if (!AL.currentCtx) {
31127
30426
  err('alGetProcAddress() called without a valid context');
31128
30427
  return 1;
@@ -31610,7 +30909,7 @@ export function init(RuntimeName, PHPLoader) {
31610
30909
  ___cpp_exception = wasmExports['__cpp_exception'];
31611
30910
  }
31612
30911
 
31613
- var ___heap_base = 14718688;
30912
+ var ___heap_base = 14718432;
31614
30913
 
31615
30914
  var wasmImports = {
31616
30915
  /** @export */
@@ -32050,6 +31349,8 @@ export function init(RuntimeName, PHPLoader) {
32050
31349
  /** @export */
32051
31350
  __call_sighandler: ___call_sighandler,
32052
31351
  /** @export */
31352
+ __emscripten_lookup_name: ___emscripten_lookup_name,
31353
+ /** @export */
32053
31354
  __syscall__newselect: ___syscall__newselect,
32054
31355
  /** @export */
32055
31356
  __syscall_accept4: ___syscall_accept4,