@tybys/wasm-util 0.10.0 → 0.10.2

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.
@@ -306,6 +306,141 @@ function asyncifyLoadSync(asyncify, buffer, imports) {
306
306
 
307
307
  const CHAR_DOT = 46; /* . */
308
308
  const CHAR_FORWARD_SLASH = 47; /* / */
309
+ const CHAR_BACKWARD_SLASH = 92; /* \ */
310
+ const CHAR_COLON = 58; /* : */
311
+ const CHAR_UPPERCASE_A = 65; /* A */
312
+ const CHAR_UPPERCASE_Z = 90; /* Z */
313
+ const CHAR_LOWERCASE_A = 97; /* a */
314
+ const CHAR_LOWERCASE_Z = 122; /* z */
315
+ function isPathSeparatorWin(code) {
316
+ return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
317
+ }
318
+ function isWindowsDeviceRoot(code) {
319
+ return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||
320
+ (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z);
321
+ }
322
+ const _isWin32 = typeof process !== 'undefined' && process.platform === 'win32';
323
+ /**
324
+ * Windows variant of `resolve()`. Mirrors Node's `path.win32.resolve`
325
+ * semantics enough for the WASI shim's needs (drive-letter absolutes
326
+ * + UNC paths + per-drive cwd lookups via `process.env`/`process.cwd`).
327
+ *
328
+ * Why this is needed: on Windows, `FileDescriptor.realPath` is the
329
+ * host realpath returned by `fs.realpathSync(realPath, 'utf8')` — the
330
+ * backslash form `D:\…`. The POSIX-only `resolveImpl` below only
331
+ * treats `/` as a separator, reads `D` as non-`/`, decides realPath
332
+ * is "relative", and produces a garbage joined path. Downstream
333
+ * `fs.openSync(garbage)` then returns `EINVAL` and the WASI caller
334
+ * sees a permanent failure. This function gives us the correct
335
+ * Windows-style resolution without taking a Node-only `path` import
336
+ * (which would break browser bundles of this package).
337
+ *
338
+ * Cribbed from Node's `lib/path.js` `win32.resolve()` (MIT-licensed),
339
+ * trimmed to what WASI realpath resolution actually exercises.
340
+ */
341
+ function resolveWin32(args) {
342
+ let resolvedDevice = '';
343
+ let resolvedTail = '';
344
+ let resolvedAbsolute = false;
345
+ for (let i = args.length - 1; i >= -1; i--) {
346
+ let path;
347
+ if (i >= 0) {
348
+ path = args[i];
349
+ validateString(path, 'path');
350
+ if (path.length === 0)
351
+ continue;
352
+ }
353
+ else if (resolvedDevice.length === 0) {
354
+ path = (typeof process !== 'undefined' && typeof process.cwd === 'function')
355
+ ? process.cwd()
356
+ : '';
357
+ }
358
+ else {
359
+ // Look up per-drive cwd via the `=X:` env var convention; fall back
360
+ // to the global cwd if absent.
361
+ const envKey = `=${resolvedDevice}`;
362
+ const env = (typeof process !== 'undefined') ? process.env : undefined;
363
+ path = (env && typeof env[envKey] === 'string')
364
+ ? env[envKey]
365
+ : (typeof process !== 'undefined' && typeof process.cwd === 'function')
366
+ ? process.cwd()
367
+ : '';
368
+ if (path === undefined ||
369
+ (path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() &&
370
+ path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) {
371
+ path = `${resolvedDevice}\\`;
372
+ }
373
+ }
374
+ const len = path.length;
375
+ let rootEnd = 0;
376
+ let device = '';
377
+ let isAbsolute = false;
378
+ const code = path.charCodeAt(0);
379
+ if (len === 1) {
380
+ if (isPathSeparatorWin(code)) {
381
+ rootEnd = 1;
382
+ isAbsolute = true;
383
+ }
384
+ }
385
+ else if (isPathSeparatorWin(code)) {
386
+ isAbsolute = true;
387
+ if (isPathSeparatorWin(path.charCodeAt(1))) {
388
+ // UNC path: `\\server\share\…`
389
+ let j = 2;
390
+ let last = j;
391
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
392
+ j++;
393
+ if (j < len && j !== last) {
394
+ const firstPart = path.slice(last, j);
395
+ last = j;
396
+ while (j < len && isPathSeparatorWin(path.charCodeAt(j)))
397
+ j++;
398
+ if (j < len && j !== last) {
399
+ last = j;
400
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
401
+ j++;
402
+ if (j === len || j !== last) {
403
+ device = `\\\\${firstPart}\\${path.slice(last, j)}`;
404
+ rootEnd = j;
405
+ }
406
+ }
407
+ }
408
+ }
409
+ else {
410
+ rootEnd = 1;
411
+ }
412
+ }
413
+ else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
414
+ device = path.slice(0, 2);
415
+ rootEnd = 2;
416
+ if (len > 2 && isPathSeparatorWin(path.charCodeAt(2))) {
417
+ isAbsolute = true;
418
+ rootEnd = 3;
419
+ }
420
+ }
421
+ if (device.length > 0) {
422
+ if (resolvedDevice.length > 0) {
423
+ if (device.toLowerCase() !== resolvedDevice.toLowerCase())
424
+ continue;
425
+ }
426
+ else {
427
+ resolvedDevice = device;
428
+ }
429
+ }
430
+ if (resolvedAbsolute) {
431
+ if (resolvedDevice.length > 0)
432
+ break;
433
+ }
434
+ else {
435
+ resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
436
+ resolvedAbsolute = isAbsolute;
437
+ if (isAbsolute && resolvedDevice.length > 0)
438
+ break;
439
+ }
440
+ }
441
+ resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\', isPathSeparatorWin);
442
+ return resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail || '.';
443
+ }
309
444
  function isPosixPathSeparator(code) {
310
445
  return code === CHAR_FORWARD_SLASH;
311
446
  }
@@ -381,6 +516,13 @@ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
381
516
  return res;
382
517
  }
383
518
  function resolve(...args) {
519
+ // On Windows, host paths are `D:\…` style. The POSIX-only resolver
520
+ // below treats `D` as a non-`/` character and produces garbage; route
521
+ // to the Windows-aware variant. POSIX hosts (Linux/macOS/browser)
522
+ // run the original code path unchanged — `_isWin32` is constant-folded
523
+ // away on those targets.
524
+ if (_isWin32)
525
+ return resolveWin32(args);
384
526
  let resolvedPath = '';
385
527
  let resolvedAbsolute = false;
386
528
  for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
@@ -1017,6 +1159,26 @@ function wrapExports(exports, needWrap) {
1017
1159
  });
1018
1160
  }
1019
1161
 
1162
+ // Linux fcntl flag bits ↔ Windows libuv flag bits. `pathOpen()` builds
1163
+ // `flagsRes` using Linux constants (O_CREAT=0x40, O_EXCL=0x80,
1164
+ // O_APPEND=0x400). Windows libuv expects different bits (O_CREAT=0x100,
1165
+ // O_EXCL=0x400, O_APPEND=0x8). Without translation,
1166
+ // `fs.openSync(path, 0x241 /* L:WRONLY|CREAT|TRUNC */)` is rejected
1167
+ // with EINVAL because Linux's 0x40 happens to mean O_TEMPORARY on
1168
+ // Windows — and O_TEMPORARY without O_CREAT is invalid.
1169
+ const _isWin32Flags = typeof process !== 'undefined' && process.platform === 'win32';
1170
+ function _toWinOpenFlags(f) {
1171
+ let r = f & 3; // RDONLY/WRONLY/RDWR — same on both
1172
+ if ((f & 0x40) !== 0)
1173
+ r |= 0x100; // O_CREAT: Linux 0x40 -> Windows 0x100
1174
+ if ((f & 0x80) !== 0)
1175
+ r |= 0x400; // O_EXCL: Linux 0x80 -> Windows 0x400
1176
+ if ((f & 0x200) !== 0)
1177
+ r |= 0x200; // O_TRUNC: same value on both
1178
+ if ((f & 0x400) !== 0)
1179
+ r |= 0x8; // O_APPEND: Linux 0x400 -> Windows 0x8
1180
+ return r;
1181
+ }
1020
1182
  function copyMemory(targets, src) {
1021
1183
  if (targets.length === 0 || src.length === 0)
1022
1184
  return 0;
@@ -1075,26 +1237,43 @@ function defineName(name, f) {
1075
1237
  Object.defineProperty(f, 'name', { value: name });
1076
1238
  return f;
1077
1239
  }
1240
+ function tryCall(f, wasi, args) {
1241
+ let r;
1242
+ try {
1243
+ r = f.apply(wasi, args);
1244
+ }
1245
+ catch (err) {
1246
+ return handleError(err);
1247
+ }
1248
+ if (isPromiseLike(r)) {
1249
+ return r.then(_ => _, handleError);
1250
+ }
1251
+ return r;
1252
+ }
1078
1253
  function syscallWrap(self, name, f) {
1079
- return defineName(name, function () {
1080
- if (process.env.NODE_DEBUG_NATIVE === 'wasi') {
1254
+ let debug = false;
1255
+ const NODE_DEBUG_NATIVE = (() => {
1256
+ try {
1257
+ return process.env.NODE_DEBUG_NATIVE;
1258
+ }
1259
+ catch (_) {
1260
+ return undefined;
1261
+ }
1262
+ })();
1263
+ if (typeof NODE_DEBUG_NATIVE === 'string' && NODE_DEBUG_NATIVE.split(',').includes('wasi')) {
1264
+ debug = true;
1265
+ }
1266
+ return debug
1267
+ ? defineName(name, function () {
1081
1268
  const args = Array.prototype.slice.call(arguments);
1082
1269
  let debugArgs = [`${name}(${Array.from({ length: arguments.length }).map(() => '%d').join(', ')})`];
1083
1270
  debugArgs = debugArgs.concat(args);
1084
1271
  console.debug.apply(console, debugArgs);
1085
- }
1086
- let r;
1087
- try {
1088
- r = f.apply(self, arguments);
1089
- }
1090
- catch (err) {
1091
- return handleError(err);
1092
- }
1093
- if (isPromiseLike(r)) {
1094
- return r.then(_ => _, handleError);
1095
- }
1096
- return r;
1097
- });
1272
+ return tryCall(f, self, args);
1273
+ })
1274
+ : defineName(name, function () {
1275
+ return tryCall(f, self, arguments);
1276
+ });
1098
1277
  }
1099
1278
  function resolvePathSync(fs, fileDescriptor, path, flags) {
1100
1279
  let resolvedPath = resolve(fileDescriptor.realPath, path);
@@ -2256,7 +2435,7 @@ class WASI$1 {
2256
2435
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2257
2436
  const fs = getFs(this);
2258
2437
  const resolved_path = resolvePathSync(fs, fileDescriptor, pathString, dirflags);
2259
- const r = fs.openSync(resolved_path, flagsRes, 0o666);
2438
+ const r = fs.openSync(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2260
2439
  const filetype = wasi.fds.getFileTypeByFd(r);
2261
2440
  if ((filetype !== 3 /* WasiFileType.DIRECTORY */) &&
2262
2441
  ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 ||
@@ -2292,7 +2471,7 @@ class WASI$1 {
2292
2471
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2293
2472
  const fs = getFs(this);
2294
2473
  const resolved_path = await resolvePathAsync(fs, fileDescriptor, pathString, dirflags);
2295
- const r = await fs.promises.open(resolved_path, flagsRes, 0o666);
2474
+ const r = await fs.promises.open(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2296
2475
  const filetype = await wasi.fds.getFileTypeByFd(r);
2297
2476
  if ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 && filetype !== 3 /* WasiFileType.DIRECTORY */) {
2298
2477
  return 54 /* WasiErrno.ENOTDIR */;
@@ -306,6 +306,141 @@ function asyncifyLoadSync(asyncify, buffer, imports) {
306
306
 
307
307
  const CHAR_DOT = 46; /* . */
308
308
  const CHAR_FORWARD_SLASH = 47; /* / */
309
+ const CHAR_BACKWARD_SLASH = 92; /* \ */
310
+ const CHAR_COLON = 58; /* : */
311
+ const CHAR_UPPERCASE_A = 65; /* A */
312
+ const CHAR_UPPERCASE_Z = 90; /* Z */
313
+ const CHAR_LOWERCASE_A = 97; /* a */
314
+ const CHAR_LOWERCASE_Z = 122; /* z */
315
+ function isPathSeparatorWin(code) {
316
+ return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
317
+ }
318
+ function isWindowsDeviceRoot(code) {
319
+ return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||
320
+ (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z);
321
+ }
322
+ const _isWin32 = typeof process !== 'undefined' && process.platform === 'win32';
323
+ /**
324
+ * Windows variant of `resolve()`. Mirrors Node's `path.win32.resolve`
325
+ * semantics enough for the WASI shim's needs (drive-letter absolutes
326
+ * + UNC paths + per-drive cwd lookups via `process.env`/`process.cwd`).
327
+ *
328
+ * Why this is needed: on Windows, `FileDescriptor.realPath` is the
329
+ * host realpath returned by `fs.realpathSync(realPath, 'utf8')` — the
330
+ * backslash form `D:\…`. The POSIX-only `resolveImpl` below only
331
+ * treats `/` as a separator, reads `D` as non-`/`, decides realPath
332
+ * is "relative", and produces a garbage joined path. Downstream
333
+ * `fs.openSync(garbage)` then returns `EINVAL` and the WASI caller
334
+ * sees a permanent failure. This function gives us the correct
335
+ * Windows-style resolution without taking a Node-only `path` import
336
+ * (which would break browser bundles of this package).
337
+ *
338
+ * Cribbed from Node's `lib/path.js` `win32.resolve()` (MIT-licensed),
339
+ * trimmed to what WASI realpath resolution actually exercises.
340
+ */
341
+ function resolveWin32(args) {
342
+ let resolvedDevice = '';
343
+ let resolvedTail = '';
344
+ let resolvedAbsolute = false;
345
+ for (let i = args.length - 1; i >= -1; i--) {
346
+ let path;
347
+ if (i >= 0) {
348
+ path = args[i];
349
+ validateString(path, 'path');
350
+ if (path.length === 0)
351
+ continue;
352
+ }
353
+ else if (resolvedDevice.length === 0) {
354
+ path = (typeof process !== 'undefined' && typeof process.cwd === 'function')
355
+ ? process.cwd()
356
+ : '';
357
+ }
358
+ else {
359
+ // Look up per-drive cwd via the `=X:` env var convention; fall back
360
+ // to the global cwd if absent.
361
+ const envKey = `=${resolvedDevice}`;
362
+ const env = (typeof process !== 'undefined') ? process.env : undefined;
363
+ path = (env && typeof env[envKey] === 'string')
364
+ ? env[envKey]
365
+ : (typeof process !== 'undefined' && typeof process.cwd === 'function')
366
+ ? process.cwd()
367
+ : '';
368
+ if (path === undefined ||
369
+ (path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() &&
370
+ path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) {
371
+ path = `${resolvedDevice}\\`;
372
+ }
373
+ }
374
+ const len = path.length;
375
+ let rootEnd = 0;
376
+ let device = '';
377
+ let isAbsolute = false;
378
+ const code = path.charCodeAt(0);
379
+ if (len === 1) {
380
+ if (isPathSeparatorWin(code)) {
381
+ rootEnd = 1;
382
+ isAbsolute = true;
383
+ }
384
+ }
385
+ else if (isPathSeparatorWin(code)) {
386
+ isAbsolute = true;
387
+ if (isPathSeparatorWin(path.charCodeAt(1))) {
388
+ // UNC path: `\\server\share\…`
389
+ let j = 2;
390
+ let last = j;
391
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
392
+ j++;
393
+ if (j < len && j !== last) {
394
+ const firstPart = path.slice(last, j);
395
+ last = j;
396
+ while (j < len && isPathSeparatorWin(path.charCodeAt(j)))
397
+ j++;
398
+ if (j < len && j !== last) {
399
+ last = j;
400
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
401
+ j++;
402
+ if (j === len || j !== last) {
403
+ device = `\\\\${firstPart}\\${path.slice(last, j)}`;
404
+ rootEnd = j;
405
+ }
406
+ }
407
+ }
408
+ }
409
+ else {
410
+ rootEnd = 1;
411
+ }
412
+ }
413
+ else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
414
+ device = path.slice(0, 2);
415
+ rootEnd = 2;
416
+ if (len > 2 && isPathSeparatorWin(path.charCodeAt(2))) {
417
+ isAbsolute = true;
418
+ rootEnd = 3;
419
+ }
420
+ }
421
+ if (device.length > 0) {
422
+ if (resolvedDevice.length > 0) {
423
+ if (device.toLowerCase() !== resolvedDevice.toLowerCase())
424
+ continue;
425
+ }
426
+ else {
427
+ resolvedDevice = device;
428
+ }
429
+ }
430
+ if (resolvedAbsolute) {
431
+ if (resolvedDevice.length > 0)
432
+ break;
433
+ }
434
+ else {
435
+ resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
436
+ resolvedAbsolute = isAbsolute;
437
+ if (isAbsolute && resolvedDevice.length > 0)
438
+ break;
439
+ }
440
+ }
441
+ resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\', isPathSeparatorWin);
442
+ return resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail || '.';
443
+ }
309
444
  function isPosixPathSeparator(code) {
310
445
  return code === CHAR_FORWARD_SLASH;
311
446
  }
@@ -381,6 +516,13 @@ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
381
516
  return res;
382
517
  }
383
518
  function resolve(...args) {
519
+ // On Windows, host paths are `D:\…` style. The POSIX-only resolver
520
+ // below treats `D` as a non-`/` character and produces garbage; route
521
+ // to the Windows-aware variant. POSIX hosts (Linux/macOS/browser)
522
+ // run the original code path unchanged — `_isWin32` is constant-folded
523
+ // away on those targets.
524
+ if (_isWin32)
525
+ return resolveWin32(args);
384
526
  let resolvedPath = '';
385
527
  let resolvedAbsolute = false;
386
528
  for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
@@ -1017,6 +1159,26 @@ function wrapExports(exports, needWrap) {
1017
1159
  });
1018
1160
  }
1019
1161
 
1162
+ // Linux fcntl flag bits ↔ Windows libuv flag bits. `pathOpen()` builds
1163
+ // `flagsRes` using Linux constants (O_CREAT=0x40, O_EXCL=0x80,
1164
+ // O_APPEND=0x400). Windows libuv expects different bits (O_CREAT=0x100,
1165
+ // O_EXCL=0x400, O_APPEND=0x8). Without translation,
1166
+ // `fs.openSync(path, 0x241 /* L:WRONLY|CREAT|TRUNC */)` is rejected
1167
+ // with EINVAL because Linux's 0x40 happens to mean O_TEMPORARY on
1168
+ // Windows — and O_TEMPORARY without O_CREAT is invalid.
1169
+ const _isWin32Flags = typeof process !== 'undefined' && process.platform === 'win32';
1170
+ function _toWinOpenFlags(f) {
1171
+ let r = f & 3; // RDONLY/WRONLY/RDWR — same on both
1172
+ if ((f & 0x40) !== 0)
1173
+ r |= 0x100; // O_CREAT: Linux 0x40 -> Windows 0x100
1174
+ if ((f & 0x80) !== 0)
1175
+ r |= 0x400; // O_EXCL: Linux 0x80 -> Windows 0x400
1176
+ if ((f & 0x200) !== 0)
1177
+ r |= 0x200; // O_TRUNC: same value on both
1178
+ if ((f & 0x400) !== 0)
1179
+ r |= 0x8; // O_APPEND: Linux 0x400 -> Windows 0x8
1180
+ return r;
1181
+ }
1020
1182
  function copyMemory(targets, src) {
1021
1183
  if (targets.length === 0 || src.length === 0)
1022
1184
  return 0;
@@ -1075,26 +1237,43 @@ function defineName(name, f) {
1075
1237
  Object.defineProperty(f, 'name', { value: name });
1076
1238
  return f;
1077
1239
  }
1240
+ function tryCall(f, wasi, args) {
1241
+ let r;
1242
+ try {
1243
+ r = f.apply(wasi, args);
1244
+ }
1245
+ catch (err) {
1246
+ return handleError(err);
1247
+ }
1248
+ if (isPromiseLike(r)) {
1249
+ return r.then(_ => _, handleError);
1250
+ }
1251
+ return r;
1252
+ }
1078
1253
  function syscallWrap(self, name, f) {
1079
- return defineName(name, function () {
1080
- {
1254
+ let debug = false;
1255
+ const NODE_DEBUG_NATIVE = (() => {
1256
+ try {
1257
+ return "wasi";
1258
+ }
1259
+ catch (_) {
1260
+ return undefined;
1261
+ }
1262
+ })();
1263
+ if (typeof NODE_DEBUG_NATIVE === 'string' && NODE_DEBUG_NATIVE.split(',').includes('wasi')) {
1264
+ debug = true;
1265
+ }
1266
+ return debug
1267
+ ? defineName(name, function () {
1081
1268
  const args = Array.prototype.slice.call(arguments);
1082
1269
  let debugArgs = [`${name}(${Array.from({ length: arguments.length }).map(() => '%d').join(', ')})`];
1083
1270
  debugArgs = debugArgs.concat(args);
1084
1271
  console.debug.apply(console, debugArgs);
1085
- }
1086
- let r;
1087
- try {
1088
- r = f.apply(self, arguments);
1089
- }
1090
- catch (err) {
1091
- return handleError(err);
1092
- }
1093
- if (isPromiseLike(r)) {
1094
- return r.then(_ => _, handleError);
1095
- }
1096
- return r;
1097
- });
1272
+ return tryCall(f, self, args);
1273
+ })
1274
+ : defineName(name, function () {
1275
+ return tryCall(f, self, arguments);
1276
+ });
1098
1277
  }
1099
1278
  function resolvePathSync(fs, fileDescriptor, path, flags) {
1100
1279
  let resolvedPath = resolve(fileDescriptor.realPath, path);
@@ -2256,7 +2435,7 @@ class WASI$1 {
2256
2435
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2257
2436
  const fs = getFs(this);
2258
2437
  const resolved_path = resolvePathSync(fs, fileDescriptor, pathString, dirflags);
2259
- const r = fs.openSync(resolved_path, flagsRes, 0o666);
2438
+ const r = fs.openSync(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2260
2439
  const filetype = wasi.fds.getFileTypeByFd(r);
2261
2440
  if ((filetype !== 3 /* WasiFileType.DIRECTORY */) &&
2262
2441
  ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 ||
@@ -2292,7 +2471,7 @@ class WASI$1 {
2292
2471
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2293
2472
  const fs = getFs(this);
2294
2473
  const resolved_path = await resolvePathAsync(fs, fileDescriptor, pathString, dirflags);
2295
- const r = await fs.promises.open(resolved_path, flagsRes, 0o666);
2474
+ const r = await fs.promises.open(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2296
2475
  const filetype = await wasi.fds.getFileTypeByFd(r);
2297
2476
  if ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 && filetype !== 3 /* WasiFileType.DIRECTORY */) {
2298
2477
  return 54 /* WasiErrno.ENOTDIR */;