Skip to content

Commit

Permalink
fix: sockets virtualization
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Sep 1, 2023
1 parent bb44033 commit d9dde90
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 2 deletions.
Binary file modified lib/virtual_adapter.wasm
Binary file not shown.
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ use wasm_opt::{Feature, OptimizationOptions};
use wit_component::{metadata, ComponentEncoder, StringEncoding};

mod data;
mod stub_preview1;
mod virt_deny;
mod virt_env;
mod virt_io;
mod walrus_ops;

pub use stub_preview1::stub_preview1;
pub use virt_env::{HostEnv, VirtEnv};
pub use virt_io::{FsEntry, StdioCfg, VirtFs, VirtualFiles};

Expand Down
89 changes: 89 additions & 0 deletions src/stub_preview1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use anyhow::{bail, Result};

use walrus::{
Function, FunctionBuilder, FunctionKind, ImportKind, ImportedFunction, InstrSeqBuilder,
LocalId, Module, ValType,
};

fn stub_import<StubFn>(module: &mut Module, import: &str, name: &str, stub: StubFn) -> Result<()>
where
StubFn: Fn(&mut InstrSeqBuilder) -> Result<Vec<LocalId>>,
{
let Some(iid) = module.imports.find(import, name) else {
bail!("Cannot find '{import}#{name}' to stub.");
};

let ImportKind::Function(fid) = module.imports.get(iid).kind else {
bail!("'{import}#{name}' is not a function.")
};

let Function {
kind: FunctionKind::Import(ImportedFunction { ty, .. }),
..
} = module.funcs.get(fid)
else {
bail!("Can't find type of '{import}#{name}'")
};

let ty = module.types.get(*ty);
let (params, results) = (ty.params().to_vec(), ty.results().to_vec());

let mut builder =
FunctionBuilder::new(&mut module.types, params.as_slice(), results.as_slice());
let args = stub(&mut builder.func_body())?;
let local_func = builder.local_func(args);

module.funcs.get_mut(fid).kind = FunctionKind::Local(local_func);

module.imports.delete(iid);
Ok(())
}

fn unreachable_stub(body: &mut InstrSeqBuilder) -> Result<Vec<LocalId>> {
body.unreachable();
Ok(vec![])
}

const WASI: &str = "wasi_snapshot_preview1";

pub fn stub_preview1(wasm: Vec<u8>, stdout: bool) -> Result<Vec<u8>> {
let mut module = Module::from_buffer(wasm.as_slice())?;

stub_import(&mut module, WASI, "clock_res_get", unreachable_stub)?;
stub_import(&mut module, WASI, "environ_get", unreachable_stub)?;
stub_import(&mut module, WASI, "environ_sizes_get", unreachable_stub)?;
stub_import(&mut module, WASI, "fd_close", unreachable_stub)?;
stub_import(&mut module, WASI, "fd_fdstat_set_flags", unreachable_stub)?;
stub_import(&mut module, WASI, "fd_prestat_get", unreachable_stub)?;
stub_import(&mut module, WASI, "fd_prestat_dir_name", unreachable_stub)?;
stub_import(&mut module, WASI, "fd_read", unreachable_stub)?;
stub_import(&mut module, WASI, "fd_seek", unreachable_stub)?;
stub_import(&mut module, WASI, "path_open", unreachable_stub)?;
stub_import(&mut module, WASI, "path_remove_directory", unreachable_stub)?;
stub_import(&mut module, WASI, "path_unlink_file", unreachable_stub)?;
stub_import(&mut module, WASI, "proc_exit", unreachable_stub)?;
stub_import(&mut module, WASI, "random_get", unreachable_stub)?;

// (func (param i32 i32 i32 i32) (result i32)))
stub_import(&mut module, WASI, "clock_time_get", |body| {
body.i32_const(0);
Ok(vec![])
})?;

// (func (param i32 i32) (result i32)))
stub_import(&mut module, WASI, "fd_fdstat_get", |body| {
body.i32_const(0);
Ok(vec![])
})?;

// (func (param i32 i32 i32 i32) (result i32)))
let len_local = module.locals.add(ValType::I32);
if !stdout {
stub_import(&mut module, WASI, "fd_write", |body| {
body.local_get(len_local);
Ok(vec![len_local])
})?;
}

Ok(module.emit_wasm())
}
6 changes: 6 additions & 0 deletions src/virt_deny.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@ pub(crate) fn deny_exit_virt(module: &mut Module) -> Result<()> {

pub(crate) fn deny_sockets_virt(module: &mut Module) -> Result<()> {
stub_sockets_virt(module)?;
add_stub_exported_func(
module,
"wasi:sockets/network#drop-network",
vec![ValType::I32],
vec![],
)?;
add_stub_exported_func(
module,
"wasi:sockets/instance-network#instance-network",
Expand Down
1 change: 0 additions & 1 deletion update-wasi.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
git clone https://github.com/bytecodealliance/wasmtime --depth 1
cd wasmtime
git checkout 134dddc
git submodule init
git submodule update
cargo build -p wasi-preview1-component-adapter --target wasm32-unknown-unknown --release
Expand Down
3 changes: 2 additions & 1 deletion virtual-adapter/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use crate::wasi::clocks::monotonic_clock;
use crate::wasi::http::types as http_types;
use crate::wasi::poll::poll;
use crate::wasi::sockets::ip_name_lookup;
use crate::wasi::sockets::network;
use crate::wasi::sockets::tcp;
use crate::wasi::sockets::udp;

Expand Down Expand Up @@ -1517,7 +1518,7 @@ impl IpNameLookup for VirtAdapter {
name: String,
address_family: Option<IpAddressFamily>,
include_unavailable: bool,
) -> Result<ip_name_lookup::ResolveAddressStream, NetworkErrorCode> {
) -> Result<ip_name_lookup::ResolveAddressStream, network::ErrorCode> {
ip_name_lookup::resolve_addresses(network, &name, address_family, include_unavailable)
}
fn resolve_next_address(
Expand Down
2 changes: 2 additions & 0 deletions wit/virt.wit
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ world virtual-sockets {
export wasi:sockets/instance-network
export wasi:sockets/tcp-create-socket
export wasi:sockets/udp-create-socket
import wasi:sockets/network
export wasi:sockets/network
}

world virtual-http {
Expand Down

0 comments on commit d9dde90

Please sign in to comment.