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

feat(wasi) Implement WASI #178

Merged
merged 17 commits into from
Feb 5, 2021
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
18 changes: 9 additions & 9 deletions wasmer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestConfig(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -31,7 +31,7 @@ func TestConfig_UseJITEngine(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -55,7 +55,7 @@ func TestConfig_UseNativeEngine(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -75,7 +75,7 @@ func TestConfig_UseCraneliftCompiler(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -99,7 +99,7 @@ func TestConfig_UseLLVMCompiler(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -120,7 +120,7 @@ func TestConfig_JITWithCranelift(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -145,7 +145,7 @@ func TestConfig_JITWithLLVM(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -166,7 +166,7 @@ func TestConfig_NativeWithCranelift(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand All @@ -191,7 +191,7 @@ func TestConfig_NativeWithLLVM(t *testing.T) {

engine := NewEngineWithConfig(config)
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand Down
2 changes: 1 addition & 1 deletion wasmer/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

func testEngine(t *testing.T, engine *Engine) {
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand Down
15 changes: 14 additions & 1 deletion wasmer/exports.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import (
type Exports struct {
_inner C.wasm_extern_vec_t
exports map[string]*Extern
instance *C.wasm_instance_t
}

func newExports(instance *C.wasm_instance_t, module *Module) *Exports {
self := &Exports{}
C.wasm_instance_exports(instance, &self._inner)

runtime.KeepAlive(instance)
runtime.SetFinalizer(self, func(exports *Exports) {
C.wasm_extern_vec_delete(exports.inner())
})
Expand All @@ -37,6 +39,7 @@ func newExports(instance *C.wasm_instance_t, module *Module) *Exports {
}

self.exports = exports
self.instance = instance

return self
}
Expand Down Expand Up @@ -98,7 +101,7 @@ func (self *Exports) GetRawFunction(name string) (*Function, error) {
// exportedFunc()
// }
//
func (self *Exports) GetFunction(name string) (func(...interface{}) (interface{}, error), error) {
func (self *Exports) GetFunction(name string) (NativeFunction, error) {
function, err := self.GetRawFunction(name)

if err != nil {
Expand Down Expand Up @@ -164,3 +167,13 @@ func (self *Exports) GetMemory(name string) (*Memory, error) {

return exports.IntoMemory(), nil
}

func (self *Exports) GetWasiStartFunction() (NativeFunction, error) {
start := C.wasi_get_start_function(self.instance)

if start == nil {
return nil, newErrorWith("WASI start function was not found")
}

return newFunction(start, nil, nil).Native(), nil
}
6 changes: 4 additions & 2 deletions wasmer/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import (
"unsafe"
)

type NativeFunction = func(...interface{}) (interface{}, error)

type Function struct {
_inner *C.wasm_func_t
_ownedBy interface{}
environment *FunctionEnvironment
lazyNative func(...interface{}) (interface{}, error)
lazyNative NativeFunction
}

func newFunction(pointer *C.wasm_func_t, environment *FunctionEnvironment, ownedBy interface{}) *Function {
Expand Down Expand Up @@ -181,7 +183,7 @@ func (self *Function) Call(parameters ...interface{}) (interface{}, error) {
// nativeFunction = function.Native()
// _ = nativeFunction(1, 2, 3)
//
func (self *Function) Native() func(...interface{}) (interface{}, error) {
func (self *Function) Native() NativeFunction {
if self.lazyNative != nil {
return self.lazyNative
}
Expand Down
22 changes: 2 additions & 20 deletions wasmer/import_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import (
)

type ImportObject struct {
externs map[string]map[string]IntoExtern
opaqueExterns []IntoExtern
externs map[string]map[string]IntoExtern
}

// NewImportObject instantiates a new empty ImportObject.
Expand All @@ -18,21 +17,13 @@ type ImportObject struct {
//
func NewImportObject() *ImportObject {
return &ImportObject{
externs: make(map[string]map[string]IntoExtern),
opaqueExterns: nil,
externs: make(map[string]map[string]IntoExtern),
}
}

func (self *ImportObject) intoInner(module *Module) (*C.wasm_extern_vec_t, error) {
cExterns := &C.wasm_extern_vec_t{}

/*
// TODO(ivan): review this
runtime.SetFinalizer(cExterns, func(cExterns *C.wasm_extern_vec_t) {
C.wasm_extern_vec_delete(cExterns)
})
*/

var externs []*C.wasm_extern_t
var numberOfExterns uint

Expand All @@ -50,11 +41,6 @@ func (self *ImportObject) intoInner(module *Module) (*C.wasm_extern_vec_t, error
numberOfExterns++
}

for _, extern := range self.opaqueExterns {
externs = append(externs, extern.IntoExtern().inner())
numberOfExterns++
}

if numberOfExterns > 0 {
C.wasm_extern_vec_new(cExterns, C.size_t(numberOfExterns), (**C.wasm_extern_t)(unsafe.Pointer(&externs[0])))
}
Expand Down Expand Up @@ -110,7 +96,3 @@ func (self *ImportObject) Register(namespaceName string, namespace map[string]In
}
}
}

func (self *ImportObject) addOpaqueExtern(extern *Extern) {
self.opaqueExterns = append(self.opaqueExterns, extern)
}
54 changes: 54 additions & 0 deletions wasmer/testdata/wasi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Compiled to Wasm as follows:
//
// ```sh
// $ rustc --target wasm32-wasi -O wasi.rs -o wasi.raw.wasm
// $ wasm-strip wasi.raw.wasm
// $ wasm-opt -O4 -Oz wasi.raw.wasm -o wasi.wasm
// ```

use std::{env, fs};

fn main() {
// Arguments
{
let mut arguments = env::args().collect::<Vec<String>>();

println!("Found program name: `{}`", arguments[0]);

arguments = arguments[1..].to_vec();
println!(
"Found {} arguments: {}",
arguments.len(),
arguments.join(", ")
);
}

// Environment variables
{
let mut environment_variables = env::vars()
.map(|(arg, val)| format!("{}={}", arg, val))
.collect::<Vec<String>>();
environment_variables.sort();

println!(
"Found {} environment variables: {}",
environment_variables.len(),
environment_variables.join(", ")
);
}

// Directories.
{
let root = fs::read_dir("/")
.unwrap()
.map(|e| e.map(|inner| format!("{:?}", inner)))
.collect::<Result<Vec<String>, _>>()
.unwrap();

println!(
"Found {} preopened directories: {}",
root.len(),
root.join(", ")
);
}
}
Binary file added wasmer/testdata/wasi.wasm
Binary file not shown.
6 changes: 3 additions & 3 deletions wasmer/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"testing"
)

func testGetBytes() []byte {
func testGetBytes(moduleFileName string) []byte {
_, filename, _, _ := runtime.Caller(0)
modulePath := path.Join(path.Dir(filename), "testdata", "tests.wasm")
modulePath := path.Join(path.Dir(filename), "testdata", moduleFileName)
bytes, _ := ioutil.ReadFile(modulePath)

return bytes
Expand All @@ -19,7 +19,7 @@ func testGetBytes() []byte {
func testGetInstance(t *testing.T) *Instance {
engine := NewEngine()
store := NewStore(engine)
module, err := NewModule(store, testGetBytes())
module, err := NewModule(store, testGetBytes("tests.wasm"))
assert.NoError(t, err)

instance, err := NewInstance(module, NewImportObject())
Expand Down
Loading