From 55245ab8d85b03d8f1de8e42261771451d495076 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 7 Jun 2019 15:52:33 +0200 Subject: [PATCH 1/3] feat(module) Support import descriptors. This patch adds the `ImportDescriptor` structure, renames `ExportKind` to `ImportExportKind`, and adds the `Module.Imports` field, to represent import descriptors. --- wasmer/bridge.go | 30 +++++++++++++++++++++++ wasmer/module.go | 63 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/wasmer/bridge.go b/wasmer/bridge.go index 0c0bf44c..93959da5 100644 --- a/wasmer/bridge.go +++ b/wasmer/bridge.go @@ -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 @@ -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)) } diff --git a/wasmer/module.go b/wasmer/module.go index 51280bb6..8232b68d 100644 --- a/wasmer/module.go +++ b/wasmer/module.go @@ -42,30 +42,37 @@ 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) ) +type ImportDescriptor struct { + Name string + Namespace string + Kind ImportExportKind +} + // Module represents a WebAssembly module. type Module struct { module *cWasmerModuleT Exports []ExportDescriptor + Imports []ImportDescriptor } // Compile compiles a WebAssembly module from bytes. @@ -85,8 +92,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 { @@ -105,13 +113,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()) @@ -184,8 +218,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`. From da6eddf2b77a494ff18df399d17bc90ba76b7373 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 7 Jun 2019 15:53:33 +0200 Subject: [PATCH 2/3] test(module) Test `Module.Imports`. --- wasmer/test/module_test.go | 55 +++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/wasmer/test/module_test.go b/wasmer/test/module_test.go index dafb010b..a206cf00 100644 --- a/wasmer/test/module_test.go +++ b/wasmer/test/module_test.go @@ -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) +} From b41eddb2a5a1143f680a11a4b0fbb67e9530d211 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 7 Jun 2019 15:54:58 +0200 Subject: [PATCH 3/3] doc(module) Document `ImportDescriptor`. --- wasmer/module.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/wasmer/module.go b/wasmer/module.go index 8232b68d..f5ef97c1 100644 --- a/wasmer/module.go +++ b/wasmer/module.go @@ -62,10 +62,18 @@ const ( 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 { - Name string + // The import name. + Name string + + // The import namespace. Namespace string - Kind ImportExportKind + + // The import kind/type. + Kind ImportExportKind } // Module represents a WebAssembly module.