Skip to content
This repository has been archived by the owner on Nov 9, 2019. It is now read-only.

Reorganise to allow for different hosts #21

Merged
merged 5 commits into from
May 24, 2019
Merged

Reorganise to allow for different hosts #21

merged 5 commits into from
May 24, 2019

Conversation

kubkon
Copy link
Member

@kubkon kubkon commented May 20, 2019

This is a rather massive PR for which I apologise, but I couldn't find a better way of dealing with the problem at hand: reorganising to allow for Windows implementation of the crate. Having said that, this PR is by no means final, so if anything is amiss or should be shuffled around, I'll be more than happy to make any necessary changes.

In order to simplify traversing the PR, here's an extended summary of the most important changes:

  • wherever possible, I've tried to extract anything common between *nix and Windows in order to avoid duplicate code as much as possible
  • the actual host specific implementation is part of a specific submodule of the sys module -- this is entirely based on the implementation of Rust's libstd crate; so, for *nix, its implementation goes in sys/unix while for Windows, that would be sys/windows
  • the host specific implementation is resolved at compile time using cfg-if crate
  • WasiCtx remains common for all host implementations, however, FdEntry is now host specific since, on *nix, we deal with RawFd while on Windows with RawHandle
  • if a hostcall would feature any host specific implementation, I've decided to put it in sys/{os} submodule even if there could potentially be some overlap between implementations for different hosts; this one is not set in stone, however, it does make the overall implementation somewhat cleaner
  • alas, there does not seem to exist an equivalent of nix for Windows; the closest one will get is the winapi-rs which in terms of functionality and safety is much closer to libc than to nix
  • bearing in mind the previous point, I've ported from Rust nightly the IO vector struct, IoVec and IoVecMut, which is essentially a wrapper for Winapi's WSABUF; NB this will become obsolete when IoSlice/IoSliceMut land in libstd stable

A word of caution here that the implementation of hostcalls on Windows is barely begun, and while it compiles fine, and it's possible to run a simple "Hello world!" WASM binary via Wasmtime, it's still experimental and very much work-in-progress. I'll strive to add more hostcalls and stabilise the implementation over the course of the coming weeks though!

Finally, I've ported format-all.sh and test-all.sh to Windows (see format-all.bat and test-all.bat). This made it pretty simple to add Appveyor config for the crate (I've already tested it in my local fork: works as expected).

@kubkon kubkon requested a review from sunfishcode May 20, 2019 20:57
@kubkon kubkon changed the title Nix win reorg Reorganise to allow for different hosts May 20, 2019
@kubkon kubkon requested a review from jedisct1 May 20, 2019 21:25
@kubkon kubkon marked this pull request as ready for review May 20, 2019 21:32
Copy link
Member

@sunfishcode sunfishcode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like how this looks. Just one concern below:

.unwrap_or_else(|e| e)
}
})
hostcalls_impl::clock_res_get(memory, clock_id, resolution_ptr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These wrappers around hostcalls_impl:: are a fair amount of boilerplate. Would it be possible to have the clock_res_get etc. in unix/hostcalls/misc.rs and windows/hostcalls/misc.rs be the actual clock_res_get API entry point, instead of having a wrapper here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's an excellent point. Initially I've had this boilerplate generated with macro_rules! macro, but having the actual implementation an API entry point sounds even better. Let me see what I can do about that!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've reshuffled things a little, and now host specific implementation serves also as an API entry point. The common hostcalls reside now in src/hostcalls.rs, and also within that module, the host specific hostcalls are publicly re-exported using pub use crate::sys::hostcalls::* so that the lib's client code can access all hostcalls from the wasi_common::hostcalls module.

use crate::memory::*;
use crate::wasm32;

use cast::From as _0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please copy the comment here here so that it's clear what this is for.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! It's done now.

@@ -1,8 +1,10 @@
#![allow(non_camel_case_types)]
#![allow(unused_unsafe)]
use crate::sys::fdentry::{determine_type_rights, FdEntry};
use crate::sys::host as host_impl;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to rename sys/unix/host.rs and sys/windows/host.rs to .../host_impl.rs, so that we don't have to use an "as" here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It certainly would, thanks! I've done it now :-)

#![allow(dead_code)]
use crate::host;

pub fn errno_from_nix(errno: nix::errno::Errno) -> host::__wasi_errno_t {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems errno_from_nix changed from returning a wasm32::__wasi_errno_t to a host::__wasi_errno_t. However, I think the direction we're heading is that for most types, this distinction doesn't matter, and we should pull them out of "host" and "wasm32" anyway -- though that's a separate refactoring we can do. So I think we can leave this code as-is for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is the one I've had some problems in categorising. As you pointed out, on one hand, it was returning wasm32::__wasi_errno_t, but on the other, it takes nix::errno::Errno as an argument which to me belongs in host specific implementation. Hence why I decided to unify the two versions of the errno_from_nix functions. Also, as you rightly mentioned here, and as far as I remember also in bytecodealliance/lucet#176, we seem to be heading in the direction of unifying host and wasm32 anyway, so it seemed like a prudent thing to do here ;-)

@kubkon
Copy link
Member Author

kubkon commented May 22, 2019

Just some heads up about formatting and rustfmt in general. It turns out that there is a bug in rustfmt (rust-lang/rustfmt#3253) which prevents rustfmt from formatting modules inside a macro such as cfg-ig.

This seems pretty serious and difficult to solve, and I'm not sure how we should deal with it until a potential fix is found. For this PR, for example, I've commented out each conditional route one at a time in src/sys/mod.rs and then re-run cargo fmt. This works but obviously is less than ideal. The interesting thing is that even libc seems affected, and I'd imagine that also Rust's libstd was affected as well.

@sunfishcode
Copy link
Member

Cool, this looks in good shape!

@sunfishcode sunfishcode merged commit 0143ed5 into CraneStation:master May 24, 2019
@kubkon kubkon deleted the nix-win-reorg branch May 25, 2019 06:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants