wasmerio/wasmer-go

Access *wasmer.Instance from within host function

Closed this issue · 2 comments

Summary

I have a host function that needs to work with the guest's memory via the *wasmer.Instance. More specifically, I need the guest to call a host function and pass a pointer to a string allocated in the guest address space, and the host function needs to be able to access that memory to pull out the string.

I can deal with the memory negotiation, my question is how to get access to the *wasmer.Instance from within a host function.

function := wasmer.NewFunction(store,
	wasmer.NewFunctionType(
		wasmer.NewValueTypes(wasmer.I32),
		wasmer.NewValueTypes(wasmer.I32),
	), func(values []wasmer.Value) ([]wasmer.Value, error) {
		// I want to get access to the *wasmer.Instance here
		return []wasmer.Value{}, nil
	})

Additional details

I tried this but the memory object m is all zeros which made me wonder if I'm just going about this the wrong way.

engine := wasmer.NewEngine()
store := wasmer.NewStore(engine)
module, _ := wasmer.NewModule(store, wasm)
importObject := wasmer.NewImportObject()

type Environment struct {
	Instance *wasmer.Instance
}

env := Environment{}

function := wasmer.NewFunctionWithEnvironment(store,
	wasmer.NewFunctionType(
		wasmer.NewValueTypes(wasmer.I32),
		wasmer.NewValueTypes(wasmer.I32),
	),
	&env,
	func(env interface{}, values []wasmer.Value) ([]wasmer.Value, error) {
		pointer := values[0].I32()
		m, err := env.(*Environment).Instance.Exports.GetMemory("memory")
		if err != nil {
			return nil, err
		}
		region := m.Data()[pointer:]
		_ = region
		// get data out here
		return []wasmer.Value{}, nil
	})

importObject.Register("env", map[string]wasmer.IntoExtern{
	"example": function,
})
instance, err := wasmer.NewInstance(module, importObject)
if err != nil {
	panic(err)
}
env.Instance = instance

I just happened to come across #173 which looks like a duplicate. That being said, there was no confirmation in the issue that indicated that this was a working solution so it would be great to get a second pair of eyes to make sure I've reasoned about this correctly.

I believe it should work. (#173)

Well, sorry, everyone. It turned out to be a problem with my guest pointer logic. Problem resolved, this approach does work.