Skip to content

Commit

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

Example:

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

assert.Equal(…, "sum", module.Exports[7].Name)
```

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
  • Loading branch information
bors[bot] and Hywan committed Jun 7, 2019
2 parents 49d1374 + 2172de5 commit efaf114
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 3 deletions.
28 changes: 28 additions & 0 deletions wasmer/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type cUint C.uint
type cUint32T C.uint32_t
type cUint8T C.uint8_t
type cWasmerByteArray C.wasmer_byte_array
type cWasmerExportDescriptorT C.wasmer_export_descriptor_t
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
Expand All @@ -33,9 +35,11 @@ type cWasmerValueTag C.wasmer_value_tag
const cWasmF32 = C.WASM_F32
const cWasmF64 = C.WASM_F64
const cWasmFunction = C.WASM_FUNCTION
const cWasmGlobal = C.WASM_GLOBAL
const cWasmI32 = C.WASM_I32
const cWasmI64 = C.WASM_I64
const cWasmMemory = C.WASM_MEMORY
const cWasmTable = C.WASM_TABLE
const cWasmerOk = C.WASMER_OK

func cWasmerLastErrorLength() cInt {
Expand Down Expand Up @@ -190,6 +194,30 @@ func cWasmerSerializedModuleDestroy(serializedModule *cWasmerSerializedModuleT)
C.wasmer_serialized_module_destroy((*C.wasmer_serialized_module_t)(serializedModule))
}

func cWasmerExportDescriptors(module *cWasmerModuleT, exportDescriptors **cWasmerExportDescriptorsT) {
C.wasmer_export_descriptors((*C.wasmer_module_t)(module), (**C.wasmer_export_descriptors_t)(unsafe.Pointer(exportDescriptors)))
}

func cWasmerExportDescriptorsDestroy(exportDescriptors *cWasmerExportDescriptorsT) {
C.wasmer_export_descriptors_destroy((*C.wasmer_export_descriptors_t)(exportDescriptors))
}

func cWasmerExportDescriptorsLen(exportDescriptors *cWasmerExportDescriptorsT) cInt {
return (cInt)(C.wasmer_export_descriptors_len((*C.wasmer_export_descriptors_t)(exportDescriptors)))
}

func cWasmerExportDescriptorsGet(exportDescriptors *cWasmerExportDescriptorsT, index cInt) *cWasmerExportDescriptorT {
return (*cWasmerExportDescriptorT)(C.wasmer_export_descriptors_get((*C.wasmer_export_descriptors_t)(exportDescriptors), (C.int)(index)))
}

func cWasmerExportDescriptorKind(exportDescriptor *cWasmerExportDescriptorT) cWasmerImportExportKind {
return cWasmerImportExportKind(C.wasmer_export_descriptor_kind((*C.wasmer_export_descriptor_t)(exportDescriptor)))
}

func cWasmerExportDescriptorName(exportDescriptor *cWasmerExportDescriptorT) cWasmerByteArray {
return (cWasmerByteArray)(C.wasmer_export_descriptor_name((*C.wasmer_export_descriptor_t)(exportDescriptor)))
}

func cGoString(string *cChar) string {
return C.GoString((*C.char)(string))
}
Expand Down
62 changes: 59 additions & 3 deletions wasmer/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,38 @@ func (error *ModuleError) Error() string {
return error.message
}

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

// The export kind/type.
Kind ExportKind
}

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

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

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

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

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

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

// Compile compiles a WebAssembly module from bytes.
Expand All @@ -55,7 +84,32 @@ func Compile(bytes []byte) (Module, error) {
return emptyModule, NewModuleError("Failed to compile the module.")
}

return Module{module}, nil
var exports = moduleExports(module)

return Module{module, exports}, nil
}

func moduleExports(module *cWasmerModuleT) []ExportDescriptor {
var exportDescriptors *cWasmerExportDescriptorsT
cWasmerExportDescriptors(module, &exportDescriptors)
defer cWasmerExportDescriptorsDestroy(exportDescriptors)

var numberOfExportDescriptors = int(cWasmerExportDescriptorsLen(exportDescriptors))
var exports = make([]ExportDescriptor, numberOfExportDescriptors)

for nth := 0; nth < numberOfExportDescriptors; nth++ {
var exportDescriptor = cWasmerExportDescriptorsGet(exportDescriptors, cInt(nth))
var exportKind = cWasmerExportDescriptorKind(exportDescriptor)
var wasmExportName = cWasmerExportDescriptorName(exportDescriptor)
var exportName = cGoStringN((*cChar)(unsafe.Pointer(wasmExportName.bytes)), (cInt)(wasmExportName.bytes_len))

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

return exports
}

// Instantiate creates a new instance of the WebAssembly module.
Expand Down Expand Up @@ -129,7 +183,9 @@ func DeserializeModule(serializedModuleBytes []byte) (Module, error) {
return emptyModule, NewModuleError("Failed to deserialize the module.")
}

return Module{module}, nil
var exports = moduleExports(module)

return Module{module, exports}, nil
}

// Close closes/frees a `Module`.
Expand Down
64 changes: 64 additions & 0 deletions wasmer/test/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,67 @@ func TestModuleDeserializeModuleWithRandomBytes(t *testing.T) {

assert.EqualError(t, err, "Failed to deserialize the module.")
}

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

assert.Equal(
t,
[]wasm.ExportDescriptor{
wasm.ExportDescriptor{
Name: "void",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "i32_i64_f32_f64_f64",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "sum",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "__heap_base",
Kind: wasm.ExportKindGlobal,
},
wasm.ExportDescriptor{
Name: "arity_0",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "i32_i32",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "memory",
Kind: wasm.ExportKindMemory,
},
wasm.ExportDescriptor{
Name: "bool_casted_to_i32",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "__data_end",
Kind: wasm.ExportKindGlobal,
},
wasm.ExportDescriptor{
Name: "f32_f32",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "f64_f64",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "string",
Kind: wasm.ExportKindFunction,
},
wasm.ExportDescriptor{
Name: "i64_i64",
Kind: wasm.ExportKindFunction,
},
},
module.Exports,
)
}

0 comments on commit efaf114

Please sign in to comment.