Skip to content

Commit

Permalink
Merge #38
Browse files Browse the repository at this point in the history
38: feat(module) Support import descriptors r=Hywan a=Hywan

Example:

```go
var module, _ = wasm.Compile(bytes)

assert.Equal(…, "log_message", module.Imports[0].Name)
assert.Equal(…, "env", module.Imports[0].Namespace)
```

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
  • Loading branch information
bors[bot] and Hywan committed Jun 7, 2019
2 parents efaf114 + b41eddb commit b212e98
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 27 deletions.
30 changes: 30 additions & 0 deletions wasmer/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type cWasmerExportDescriptorsT C.wasmer_export_descriptors_t
type cWasmerExportFuncT C.wasmer_export_func_t
type cWasmerExportT C.wasmer_export_t
type cWasmerExportsT C.wasmer_exports_t
type cWasmerImportDescriptorT C.wasmer_import_descriptor_t
type cWasmerImportDescriptorsT C.wasmer_import_descriptors_t
type cWasmerImportExportKind C.wasmer_import_export_kind
type cWasmerImportExportValue C.wasmer_import_export_value
type cWasmerImportFuncT C.wasmer_import_func_t
Expand Down Expand Up @@ -218,6 +220,34 @@ func cWasmerExportDescriptorName(exportDescriptor *cWasmerExportDescriptorT) cWa
return (cWasmerByteArray)(C.wasmer_export_descriptor_name((*C.wasmer_export_descriptor_t)(exportDescriptor)))
}

func cWasmerImportDescriptors(module *cWasmerModuleT, importDescriptors **cWasmerImportDescriptorsT) {
C.wasmer_import_descriptors((*C.wasmer_module_t)(module), (**C.wasmer_import_descriptors_t)(unsafe.Pointer(importDescriptors)))
}

func cWasmerImportDescriptorsDestroy(importDescriptors *cWasmerImportDescriptorsT) {
C.wasmer_import_descriptors_destroy((*C.wasmer_import_descriptors_t)(importDescriptors))
}

func cWasmerImportDescriptorsLen(importDescriptors *cWasmerImportDescriptorsT) cInt {
return (cInt)(C.wasmer_import_descriptors_len((*C.wasmer_import_descriptors_t)(importDescriptors)))
}

func cWasmerImportDescriptorsGet(importDescriptors *cWasmerImportDescriptorsT, index cInt) *cWasmerImportDescriptorT {
return (*cWasmerImportDescriptorT)(C.wasmer_import_descriptors_get((*C.wasmer_import_descriptors_t)(importDescriptors), (C.int)(index)))
}

func cWasmerImportDescriptorKind(importDescriptor *cWasmerImportDescriptorT) cWasmerImportExportKind {
return cWasmerImportExportKind(C.wasmer_import_descriptor_kind((*C.wasmer_import_descriptor_t)(importDescriptor)))
}

func cWasmerImportDescriptorName(importDescriptor *cWasmerImportDescriptorT) cWasmerByteArray {
return (cWasmerByteArray)(C.wasmer_import_descriptor_name((*C.wasmer_import_descriptor_t)(importDescriptor)))
}

func cWasmerImportDescriptorModuleName(importDescriptor *cWasmerImportDescriptorT) cWasmerByteArray {
return (cWasmerByteArray)(C.wasmer_import_descriptor_module_name((*C.wasmer_import_descriptor_t)(importDescriptor)))
}

func cGoString(string *cChar) string {
return C.GoString((*C.char)(string))
}
Expand Down
71 changes: 57 additions & 14 deletions wasmer/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,45 @@ type ExportDescriptor struct {
Name string

// The export kind/type.
Kind ExportKind
Kind ImportExportKind
}

// ExportKind represents an export descriptor kind/type.
type ExportKind int
// ImportExportKind represents an import/export descriptor kind/type.
type ImportExportKind int

const (
// ExportKindFunction represents an export descriptor of kind function.
ExportKindFunction = ExportKind(cWasmFunction)
// ImportExportKindFunction represents an import/export descriptor of kind function.
ImportExportKindFunction = ImportExportKind(cWasmFunction)

// ExportKindGlobal represents an export descriptor of kind global.
ExportKindGlobal = ExportKind(cWasmGlobal)
// ImportExportKindGlobal represents an import/export descriptor of kind global.
ImportExportKindGlobal = ImportExportKind(cWasmGlobal)

// ExportKindMemory represents an export descriptor of kind memory.
ExportKindMemory = ExportKind(cWasmMemory)
// ImportExportKindMemory represents an import/export descriptor of kind memory.
ImportExportKindMemory = ImportExportKind(cWasmMemory)

// ExportKindTable represents an export descriptor of kind table.
ExportKindTable = ExportKind(cWasmTable)
// ImportExportKindTable represents an import/export descriptor of kind table.
ImportExportKindTable = ImportExportKind(cWasmTable)
)

// ImportDescriptor represents an import descriptor of a WebAssembly
// module. It is different of an import of a WebAssembly instance. An
// import descriptor only has a name, a namespace, and a kind/type.
type ImportDescriptor struct {
// The import name.
Name string

// The import namespace.
Namespace string

// The import kind/type.
Kind ImportExportKind
}

// Module represents a WebAssembly module.
type Module struct {
module *cWasmerModuleT
Exports []ExportDescriptor
Imports []ImportDescriptor
}

// Compile compiles a WebAssembly module from bytes.
Expand All @@ -85,8 +100,9 @@ func Compile(bytes []byte) (Module, error) {
}

var exports = moduleExports(module)
var imports = moduleImports(module)

return Module{module, exports}, nil
return Module{module, exports, imports}, nil
}

func moduleExports(module *cWasmerModuleT) []ExportDescriptor {
Expand All @@ -105,13 +121,39 @@ func moduleExports(module *cWasmerModuleT) []ExportDescriptor {

exports[nth] = ExportDescriptor{
Name: exportName,
Kind: ExportKind(exportKind),
Kind: ImportExportKind(exportKind),
}
}

return exports
}

func moduleImports(module *cWasmerModuleT) []ImportDescriptor {
var importDescriptors *cWasmerImportDescriptorsT
cWasmerImportDescriptors(module, &importDescriptors)
defer cWasmerImportDescriptorsDestroy(importDescriptors)

var numberOfImportDescriptors = int(cWasmerImportDescriptorsLen(importDescriptors))
var imports = make([]ImportDescriptor, numberOfImportDescriptors)

for nth := 0; nth < numberOfImportDescriptors; nth++ {
var importDescriptor = cWasmerImportDescriptorsGet(importDescriptors, cInt(nth))
var importKind = cWasmerImportDescriptorKind(importDescriptor)
var wasmImportName = cWasmerImportDescriptorName(importDescriptor)
var importName = cGoStringN((*cChar)(unsafe.Pointer(wasmImportName.bytes)), (cInt)(wasmImportName.bytes_len))
var wasmImportNamespace = cWasmerImportDescriptorModuleName(importDescriptor)
var importNamespace = cGoStringN((*cChar)(unsafe.Pointer(wasmImportNamespace.bytes)), (cInt)(wasmImportNamespace.bytes_len))

imports[nth] = ImportDescriptor{
Name: importName,
Namespace: importNamespace,
Kind: ImportExportKind(importKind),
}
}

return imports
}

// Instantiate creates a new instance of the WebAssembly module.
func (module *Module) Instantiate() (Instance, error) {
return module.InstantiateWithImports(NewImports())
Expand Down Expand Up @@ -184,8 +226,9 @@ func DeserializeModule(serializedModuleBytes []byte) (Module, error) {
}

var exports = moduleExports(module)
var imports = moduleImports(module)

return Module{module, exports}, nil
return Module{module, exports, imports}, nil
}

// Close closes/frees a `Module`.
Expand Down
55 changes: 42 additions & 13 deletions wasmer/test/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,57 +104,86 @@ func TestModuleExports(t *testing.T) {
[]wasm.ExportDescriptor{
wasm.ExportDescriptor{
Name: "void",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "i32_i64_f32_f64_f64",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "sum",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "__heap_base",
Kind: wasm.ExportKindGlobal,
Kind: wasm.ImportExportKindGlobal,
},
wasm.ExportDescriptor{
Name: "arity_0",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "i32_i32",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "memory",
Kind: wasm.ExportKindMemory,
Kind: wasm.ImportExportKindMemory,
},
wasm.ExportDescriptor{
Name: "bool_casted_to_i32",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "__data_end",
Kind: wasm.ExportKindGlobal,
Kind: wasm.ImportExportKindGlobal,
},
wasm.ExportDescriptor{
Name: "f32_f32",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "f64_f64",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "string",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
wasm.ExportDescriptor{
Name: "i64_i64",
Kind: wasm.ExportKindFunction,
Kind: wasm.ImportExportKindFunction,
},
},
module.Exports,
)
}

func TestModuleImports(t *testing.T) {
_, filename, _, _ := runtime.Caller(0)
modulePath := path.Join(path.Dir(filename), "testdata", "log.wasm")

bytes, _ := wasm.ReadBytes(modulePath)

module, _ := wasm.Compile(bytes)
defer module.Close()

assert.Equal(
t,
[]wasm.ImportDescriptor{
wasm.ImportDescriptor{
Name: "log_message",
Namespace: "env",
Kind: wasm.ImportExportKindFunction,
},
},
module.Imports,
)
}

func TestModuleImportsNone(t *testing.T) {
module, _ := wasm.Compile(GetBytes())
defer module.Close()

assert.Equal(t, []wasm.ImportDescriptor{}, module.Imports)
}

0 comments on commit b212e98

Please sign in to comment.