Skip to content
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

Plan9 compilation support #1578

Closed
SlashScreen opened this issue Jul 12, 2023 · 19 comments · Fixed by #1603
Closed

Plan9 compilation support #1578

SlashScreen opened this issue Jul 12, 2023 · 19 comments · Fixed by #1603
Assignees
Labels
enhancement New feature or request

Comments

@SlashScreen
Copy link

I am attempting to compile a program using Wazero to Plan9, since Go's compiler supports the target, however, pretty much everything related to Errno and Syscalls are broken, filled with Undefineds.
If it would be possible, I would like to have a mode where it can successfully compile to GOOS=plan9.
I am not adverse to implementing this change myself in a PR, however, I have no idea if this would be possible or not, nor where to start. I understand my use case is niche, but if I could get this working, it would potentially allow programs compiled to WASM to run on another OS, and I would be grateful.

@SlashScreen SlashScreen added the enhancement New feature or request label Jul 12, 2023
@codefromthecrypt
Copy link
Contributor

While we may not be able to support the raw syscall layer, we should at least gracefully build and default. So, this is a bug that the build breaks. You can look at what we do in make check to verify we don't break other things, even if we don't support raw syscalls everywhere.

@codefromthecrypt
Copy link
Contributor

So, I'm really happy you brought this up! I figured we wouldn't be lucky enough to expose syscall.X types in our
portable internal interface.

Here's what I think needs to be done. In internal/fsapi/constants.go add Errno which defaults to syscall.Errno, where possible. Then forward all the values we use to that type. e.g. EAGAIN = syscall.EAGAIN where syscall.Errno is around, and similar to how we treat O_DIRECTORY on windows, make fake values for plan9 that doesn't define them.

Then, change the interfaces in the fsapi package to return sys.Errno instead of syscall.Errno and I think we're ok.

cc @evacchi @achille-roussel for other input.

$ GOARCH=amd64 GOOS=plan9 go build ./...
# github.com/tetratelabs/wazero/internal/wasip1
internal/wasip1/errno.go:266:28: undefined: syscall.Errno
internal/wasip1/errno.go:272:15: undefined: syscall.EAGAIN
internal/wasip1/errno.go:274:15: undefined: syscall.EBADF
internal/wasip1/errno.go:278:15: undefined: syscall.EFAULT
internal/wasip1/errno.go:288:15: undefined: syscall.ELOOP
internal/wasip1/errno.go:294:15: undefined: syscall.ENOSYS
internal/wasip1/errno.go:298:15: undefined: syscall.ENOTEMPTY
internal/wasip1/errno.go:300:15: undefined: syscall.ENOTSOCK
internal/wasip1/errno.go:302:15: undefined: syscall.ENOTSUP
internal/wasip1/errno.go:306:15: undefined: syscall.EROFS
internal/wasip1/errno.go:306:15: too many errors
# github.com/tetratelabs/wazero/internal/fsapi
internal/fsapi/file.go:46:25: undefined: syscall.Errno
internal/fsapi/file.go:60:28: undefined: syscall.Errno
internal/fsapi/file.go:73:25: undefined: syscall.Errno
internal/fsapi/file.go:96:35: undefined: syscall.Errno
internal/fsapi/file.go:120:33: undefined: syscall.Errno
internal/fsapi/file.go:137:30: undefined: syscall.Errno
internal/fsapi/file.go:155:41: undefined: syscall.Errno
internal/fsapi/file.go:174:53: undefined: syscall.Errno
internal/fsapi/file.go:206:65: undefined: syscall.Errno
internal/fsapi/file.go:226:62: undefined: syscall.Errno
internal/fsapi/file.go:226:62: too many errors
# github.com/tetratelabs/wazero/internal/platform
internal/platform/errno.go:7:30: undefined: syscall.Errno
internal/platform/error.go:11:39: undefined: syscall.Errno
internal/platform/error.go:16:28: undefined: syscall.Errno
internal/platform/error.go:34:18: undefined: syscall.EBADF
# github.com/tetratelabs/wazero/internal/testing/require
internal/testing/require/require.go:135:46: undefined: syscall.Errno
internal/testing/require/require.go:140:28: undefined: syscall.Errno

@codefromthecrypt
Copy link
Contributor

ps I didn't mean to say the work will be only what I said.. I mean once everything compiles and also tests pass (which will find other things) we'll be ok ;)

@SlashScreen
Copy link
Author

I see, so I should open an issue in bug reports? Also, by "not support the syscall layer on all platforms" you mean that the interpreter would be the only option on Plan9?

@codefromthecrypt
Copy link
Contributor

I see, so I should open an issue in bug reports? Also

this issue is enough to track progress. Just mention this one on all related PRs. Also, if this is too much or if you don't feel comfortable on raising a PR, it is ok.

Also, by "not support the syscall layer on all platforms" you mean that the interpreter would be the only option on Plan9?

so, there are separate issues. First support is interpreter plus fs.FS for filesystem integration. Beyond that, like a compiler backend or raw syscall support, that would be enhancements. So, let's start with getting it to compile, which seems focused in the fsapi stuff (not related to compiler vs interpreter).

P.s. the compiler is being revisited right now in #1496, so it isn't likely a good time to start plan9. Compiler support is a very large task and would need more than one request to begin. In other words, yes interpreter only for now.

@codefromthecrypt
Copy link
Contributor

Sorry, I misstated. It is rare there is any real compiler work for an operating system, mostly it is mmap (assuming you are using arm64 or amd64). The main issue for plan9 may be around mmap or other utilities needed in the platform package. It is worth pursuing compiler, as we did for freebsd, but separate from the fs stuff. Also, we may not be able to test it on PR, depending on how difficult running plan9 in CI is.

@evacchi
Copy link
Contributor

evacchi commented Jul 12, 2023

this is related to #1526 (x-compilation for GOARCH=wasm) in that what breaks #1526 is that we are using some syscalls straight from the syscall package and they are missing in wasm; this is similar, but for plan 9, and the solution is likely common

@evacchi evacchi self-assigned this Jul 12, 2023
@SlashScreen
Copy link
Author

This focuses on fsapi, but what of wasip1 and platform?

@codefromthecrypt
Copy link
Contributor

This focuses on fsapi, but what of wasip1 and platform?

wasip1 consumes changes of fsapi and not platform, so a change to fsapi means a change to wasip1 (and gojs too, maybe other imports)

platform is independent of fsapi and can be a separate PR, probably a smaller one

@SlashScreen
Copy link
Author

Here's what I think needs to be done. In internal/fsapi/constants.go add Errno which defaults to syscall.Errno, where possible. Then forward all the values we use to that type. e.g. EAGAIN = syscall.EAGAIN where syscall.Errno is around, and similar to how we treat O_DIRECTORY on windows, make fake values for plan9 that doesn't define them.

What exactly does this mean? Add a new Constant?

codefromthecrypt pushed a commit that referenced this issue Jul 14, 2023
This cherry-picks errors we use in our wasip1 implementation as
`fsapi.Errno`. This is to start progress towards compiling on all GOOS
values (such as plan9), to make future changes a lot easier.

See #1578

Signed-off-by: Adrian Cole <[email protected]>
@codefromthecrypt
Copy link
Contributor

@SlashScreen I meant #1582 which I messed up windows a bit and can't work more on it today, but will circle back on

codefromthecrypt pushed a commit that referenced this issue Jul 15, 2023
This cherry-picks errors we use in our wasip1 implementation as
`fsapi.Errno`. This is to start progress towards compiling on all GOOS
values (such as plan9), to make future changes a lot easier.

See #1578

Signed-off-by: Adrian Cole <[email protected]>
codefromthecrypt pushed a commit that referenced this issue Jul 15, 2023
This cherry-picks errors we use in our wasip1 implementation as
`fsapi.Errno`. This is to start progress towards compiling on all GOOS
values (such as plan9), to make future changes a lot easier.

See #1578

Signed-off-by: Adrian Cole <[email protected]>
codefromthecrypt pushed a commit that referenced this issue Jul 15, 2023
This cherry-picks errors we use in our wasip1 implementation as
`fsapi.Errno`. This is to start progress towards compiling on all GOOS
values (such as plan9), to make future changes a lot easier.

See #1578

Signed-off-by: Adrian Cole <[email protected]>
codefromthecrypt pushed a commit that referenced this issue Jul 16, 2023
This cherry-picks errors we use in our wasip1 implementation as
`fsapi.Errno`. This is to start progress towards compiling on all GOOS
values (such as plan9), to make future changes a lot easier.

See #1578

Signed-off-by: Adrian Cole <[email protected]>
@codefromthecrypt
Copy link
Contributor

This one is ready for review and I'll do some similar work to decouple the rest of the syscall package from the fsapi later. Then, it should be a lot easier to progress this issue, at least changes will be contained to certain GOOS values instead of wide scale refactoring #1582

@codefromthecrypt
Copy link
Contributor

more progress on decoupling #1586

@codefromthecrypt
Copy link
Contributor

more #1587

@codefromthecrypt
Copy link
Contributor

codefromthecrypt commented Jul 29, 2023

one last thing to fix is utimes. Before, we weren't doing this correctly as we unconditionally used the real host clock instead of what was provided via ModuleConfig. This leaves only the OMIT use case which while not supported directly via Go, is implementable on some platforms. We can do this to remove the last syscall types, swapping syscall.Timespec array for two numbers and a special case marker value. I'll raise a PR tomorrow.

	// Utimens set file access and modification times of this file, at
	// nanosecond precision.
	//
	// # Parameters
	//
	// The `atim` and `mtim` parameters refer to access and modification time
	// stamps as defined in sys.Stat_t. To retain one or the other, substitute
	// it with the pseudo-timestamp UTIME_OMIT.
	//
	// # Errors
	//
	// A zero sys.Errno is success. The below are expected otherwise:
	//   - sys.ENOSYS: the implementation does not support this function.
	//   - sys.EBADF: the file or directory was closed.
	//
	// # Notes
	//
	//   - This is like syscall.UtimesNano and `futimens` in POSIX. See
	//     https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
	//   - Windows requires files to be open with fsapi.O_RDWR, which means you
	//     cannot use this to update timestamps on a directory (EPERM).
	Utimens(atim, mtim int64) experimentalsys.Errno

@codefromthecrypt
Copy link
Contributor

I have a partially implemented draft of the above locally. I'll try to push to a shared branch today even if I may not have time to personally complete it.

@codefromthecrypt
Copy link
Contributor

once this is merged, it should be easy to compile plan9. Basically update Makefile check target and there should only be minor issues left #1602

@codefromthecrypt codefromthecrypt self-assigned this Jul 30, 2023
@codefromthecrypt
Copy link
Contributor

I'll try to spike the last of this now

@SlashScreen
Copy link
Author

Awesome! Thank you for spending time to allow for this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants