Skip to content

Conversation

@nbaertsch
Copy link
Contributor

Added WASI P1:

  • fd_tell
  • fd_readdir
  • environ_get
  • environ_sizes_get

This is enough for a cpython "Hello World" running in zware.

Disclaimer: LLM assisted code. Tested on Linux only. Includes the fixes for zig 0.15.2.

Noah Baertsch added 8 commits December 29, 2025 17:18
- ArrayHashMap.put() now requires allocator as first parameter
- ArrayList.append() now requires allocator as first parameter

These changes are required for Zig 0.15.2 which changed the API for
managed data structures to take the allocator explicitly.
- fd_tell: Get current file offset using cross-platform posix.lseek_CUR_get
- fd_readdir: Read directory entries with WASI dirent format

Platform support for fd_readdir:
- Linux: Implemented using getdents64 syscall (no libc required)
- macOS/iOS/tvOS/watchOS/visionOS: Implemented using getdirentries via libc
- FreeBSD/OpenBSD/NetBSD/DragonFly: Implemented using getdents via libc
- Windows: Compile-time error (TODO: implement with NtQueryDirectoryFile)
- Other platforms: Compile-time error

These are required for running CPython 3.13 WASM builds.
Changes:
- Use @sizeof(wasi.dirent_t) instead of hardcoded 24 for WASI dirent header size
- Add toWasiFiletype() helper to convert native DT_* values to wasi.filetype_t enum
- Add writeWasiDirent() helper for spec-compliant WASI dirent structure writes
- Implement Windows fd_readdir using NtQueryDirectoryFile API:
  - Uses FILE_BOTH_DIR_INFORMATION for directory enumeration
  - Converts UTF-16 filenames to UTF-8
  - Maps FILE_ATTRIBUTE_* to wasi.filetype_t
  - Uses FileIndex as pseudo-inode (Windows has no true inodes)
- Update doc comments to reference std.os.wasi type definitions

Platform support:
- Linux: getdents64 syscall (no libc)
- macOS/iOS/tvOS/watchOS/visionOS: getdirentries via std.c
- FreeBSD/OpenBSD/NetBSD/DragonFly: getdents via std.c
- Windows: NtQueryDirectoryFile via std.os.windows
- Other platforms: @CompileError
Add error mappings for:
- Unseekable -> ESPIPE (illegal seek on pipes/sockets)
- NotOpenForReading -> EBADF (bad file descriptor)
- InvalidArgument -> EINVAL
- PermissionDenied -> EPERM

Note: The Windows fd_readdir implementation from the previous commit
is untested - zware itself lacks Windows support in other areas
(fd_t type handling, stat.inode types, posix.O flags, etc.)
WASI spec does not mandate filtering these entries, and major runtimes
like wasmtime and wasmer include them. Removing the filter ensures
compatibility with applications that may depend on seeing these entries.
- Remove verbose doc comments (code is self-documenting)
- Remove Windows implementation (to be added in separate branch)
- Simplify variable names and reduce code duplication
- Keep Linux, macOS, and BSD implementations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant