Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ os:
- osx
language: rust
rust:
- 1.32.0
- 1.34.0
- beta
- nightly
matrix:
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ wabt = "0.7"
libc = "0.2.50"
errno = "0.2.4"

[target.'cfg(unix)'.dependencies]
wasmtime-wasi-c = { path = "wasmtime-wasi-c" }

[target.'cfg(windows)'.dependencies]
winapi = "0.3"

[workspace]

[features]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ utility or as a library embedded in a larger application.
[![Travis Status](https://travis-ci.org/CraneStation/wasmtime.svg?branch=master)](https://travis-ci.org/CraneStation/wasmtime)
[![Appveyor Status](https://ci.appveyor.com/api/projects/status/vxvpt2plriy5s0mc?svg=true)](https://ci.appveyor.com/project/CraneStation/cranelift)
[![Gitter chat](https://badges.gitter.im/CraneStation/CraneStation.svg)](https://gitter.im/CraneStation/Lobby)
![Minimum rustc 1.32](https://img.shields.io/badge/rustc-1.32+-green.svg)
![Minimum rustc 1.34](https://img.shields.io/badge/rustc-1.34+-green.svg)

Wasmtime passes the WebAssembly spec testsuite, and supports a new system
API proposal called [WebAssembly System Interface], or WASI.
Expand Down
97 changes: 58 additions & 39 deletions src/wasmtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ use cranelift_codegen::settings;
use cranelift_codegen::settings::Configurable;
use cranelift_native;
use docopt::Docopt;
use errno::errno;
use file_per_thread_logger;
use pretty_env_logger;
use std::error::Error;
use std::ffi::{CString, OsStr};
use std::ffi::OsStr;
use std::fs::File;
use std::io;
use std::io::prelude::*;
Expand All @@ -53,6 +52,9 @@ use wasmtime_jit::{ActionOutcome, Context};
use wasmtime_wasi::instantiate_wasi;
use wasmtime_wast::instantiate_spectest;

#[cfg(unix)]
use wasmtime_wasi_c::instantiate_wasi_c;

static LOG_FILENAME_PREFIX: &str = "wasmtime.dbg.";

const USAGE: &str = "
Expand All @@ -63,15 +65,16 @@ including calling the start function if one is present. Additional functions
given with --invoke are then called.

Usage:
wasmtime [-odg] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] <file> [<arg>...]
wasmtime [-odg] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] --invoke=<fn> <file> [<arg>...]
wasmtime [-odg] [--wasi-common] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] <file> [<arg>...]
wasmtime [-odg] [--wasi-common] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] --invoke=<fn> <file> [<arg>...]
wasmtime --help | --version

Options:
--invoke=<fn> name of function to run
-o, --optimize runs optimization passes on the translated functions
-g generate debug information
-d, --debug enable debug output on stderr/stdout
--wasi-common enable the wasi-common implementation of WASI
--preload=<wasm> load an additional wasm module before loading the main module
--env=<env> pass an environment variable (\"key=value\") to the program
--dir=<dir> grant access to the given host directory
Expand All @@ -93,6 +96,7 @@ struct Args {
flag_env: Vec<String>,
flag_dir: Vec<String>,
flag_mapdir: Vec<String>,
flag_wasi_common: bool,
}

fn read_to_end(path: PathBuf) -> Result<Vec<u8>, io::Error> {
Expand All @@ -114,22 +118,42 @@ fn read_wasm(path: PathBuf) -> Result<Vec<u8>, String> {
})
}

fn compute_preopen_dirs(flag_dir: &[String], flag_mapdir: &[String]) -> Vec<(String, libc::c_int)> {
fn preopen_dir<P: AsRef<Path>>(path: P) -> io::Result<File> {
#[cfg(windows)]
{
use std::fs::OpenOptions;
use std::os::windows::fs::OpenOptionsExt;
use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS;

// To open a directory using CreateFile2, specify the
// FILE_FLAG_BACKUP_SEMANTICS flag as part of dwFileFlags...
// cf. https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfile2
OpenOptions::new()
.create(false)
.write(true)
.read(true)
.attributes(FILE_FLAG_BACKUP_SEMANTICS)
.open(path)
}
#[cfg(unix)]
{
File::open(path)
}
#[cfg(not(any(windows, unix)))]
{
unimplemented!("this OS is currently not supported by Wasmtime")
}
}

fn compute_preopen_dirs(flag_dir: &[String], flag_mapdir: &[String]) -> Vec<(String, File)> {
let mut preopen_dirs = Vec::new();

for dir in flag_dir {
let fd = unsafe {
libc::open(
CString::new(dir.as_bytes()).unwrap().as_ptr(),
libc::O_RDONLY | libc::O_DIRECTORY,
)
};
if fd < 0 {
println!("error while pre-opening directory {}: {}", dir, errno());
let preopen_dir = preopen_dir(dir).unwrap_or_else(|err| {
println!("error while pre-opening directory {}: {}", dir, err);
exit(1);
}

preopen_dirs.push((dir.clone(), fd));
});
preopen_dirs.push((dir.clone(), preopen_dir));
}

for mapdir in flag_mapdir {
Expand All @@ -139,18 +163,11 @@ fn compute_preopen_dirs(flag_dir: &[String], flag_mapdir: &[String]) -> Vec<(Str
exit(1);
}
let (key, value) = (parts[0], parts[1]);
let fd = unsafe {
libc::open(
CString::new(value.as_bytes()).unwrap().as_ptr(),
libc::O_RDONLY | libc::O_DIRECTORY,
)
};
if fd < 0 {
println!("error while pre-opening directory {}: {}", value, errno());
let preopen_dir = preopen_dir(value).unwrap_or_else(|err| {
println!("error while pre-opening directory {}: {}", value, err);
exit(1);
}

preopen_dirs.push((key.to_string(), fd));
});
preopen_dirs.push((key.to_string(), preopen_dir));
}

preopen_dirs
Expand Down Expand Up @@ -243,20 +260,22 @@ fn main() {
let preopen_dirs = compute_preopen_dirs(&args.flag_dir, &args.flag_mapdir);
let argv = compute_argv(&args.arg_file, &args.arg_arg);
let environ = compute_environ(&args.flag_env);
context.name_instance(
"wasi_unstable".to_owned(),

let wasi = if args.flag_wasi_common {
instantiate_wasi("", global_exports, &preopen_dirs, &argv, &environ)
.expect("instantiating wasi"),
);
} else {
#[cfg(unix)]
{
instantiate_wasi_c("", global_exports, &preopen_dirs, &argv, &environ)
}
#[cfg(not(unix))]
{
unimplemented!("wasmtime-wasi-c requires a *nix")
}
}
.expect("instantiating wasi");

// FIXME: Also recognize "env", for compatibility with clang/llvm 8.0. And use
// "__wasi_" prefixes for compatibility with prototype reference-sysroot.
let global_exports = context.get_global_exports();
context.name_instance(
"env".to_owned(),
instantiate_wasi("__wasi_", global_exports, &preopen_dirs, &argv, &environ)
.expect("instantiating wasi"),
);
context.name_instance("wasi_unstable".to_owned(), wasi);

// Enable/disable producing of debug info.
context.set_debug_info(args.flag_g);
Expand Down
30 changes: 30 additions & 0 deletions wasmtime-wasi-c/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "wasmtime-wasi-c"
version = "0.0.0"
authors = ["The Cranelift Project Developers"]
publish = false
description = "WASI API support for Wasmtime"
categories = ["wasm"]
repository = "https://github.com/CraneStation/wasmtime"
license = "Apache-2.0 WITH LLVM-exception"
readme = "README.md"

[dependencies]
wasmtime-runtime = { path = "../wasmtime-runtime" }
wasmtime-environ = { path = "../wasmtime-environ" }
wasmtime-jit = { path = "../wasmtime-jit" }
cranelift-codegen = "0.30.0"
cranelift-entity = "0.30.0"
cranelift-wasm = "0.30.0"
target-lexicon = "0.3.0"
cast = { version = "0.2.2", default-features = false }
log = { version = "0.4.6", default-features = false }
libc = "0.2.50"

[build-dependencies]
cmake = "0.1.35"
bindgen = "0.49.0"

[badges]
maintenance = { status = "experimental" }
travis-ci = { repository = "CraneStation/wasmtime" }
Loading