summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-05-27 15:46:15 +0000
committerLibravatar GitHub <noreply@github.com>2024-05-27 17:46:15 +0200
commit1e7b32490dfdccddd04f46d4b0416b48d749d51b (patch)
tree62a11365933a5a11e0800af64cbdf9172e5e6e7a /vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go
parent[chore] Small styling + link issues (#2933) (diff)
downloadgotosocial-1e7b32490dfdccddd04f46d4b0416b48d749d51b.tar.xz
[experiment] add alternative wasm sqlite3 implementation available via build-tag (#2863)
This allows for building GoToSocial with [SQLite transpiled to WASM](https://github.com/ncruces/go-sqlite3) and accessed through [Wazero](https://wazero.io/).
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go188
1 files changed, 188 insertions, 0 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go
new file mode 100644
index 000000000..c5f6e9121
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go
@@ -0,0 +1,188 @@
+package wasm
+
+import (
+ "github.com/tetratelabs/wazero/api"
+ "github.com/tetratelabs/wazero/internal/internalapi"
+ "github.com/tetratelabs/wazero/internal/wasmdebug"
+)
+
+// ImportedFunctions returns the definitions of each imported function.
+//
+// Note: Unlike ExportedFunctions, there is no unique constraint on imports.
+func (m *Module) ImportedFunctions() (ret []api.FunctionDefinition) {
+ for i := uint32(0); i < m.ImportFunctionCount; i++ {
+ ret = append(ret, m.FunctionDefinition(i))
+ }
+ return
+}
+
+// ExportedFunctions returns the definitions of each exported function.
+func (m *Module) ExportedFunctions() map[string]api.FunctionDefinition {
+ ret := map[string]api.FunctionDefinition{}
+ for i := range m.ExportSection {
+ exp := &m.ExportSection[i]
+ if exp.Type == ExternTypeFunc {
+ d := m.FunctionDefinition(exp.Index)
+ ret[exp.Name] = d
+ }
+ }
+ return ret
+}
+
+// FunctionDefinition returns the FunctionDefinition for the given `index`.
+func (m *Module) FunctionDefinition(index Index) *FunctionDefinition {
+ // TODO: function initialization is lazy, but bulk. Make it per function.
+ m.buildFunctionDefinitions()
+ return &m.FunctionDefinitionSection[index]
+}
+
+// buildFunctionDefinitions generates function metadata that can be parsed from
+// the module. This must be called after all validation.
+func (m *Module) buildFunctionDefinitions() {
+ m.functionDefinitionSectionInitOnce.Do(m.buildFunctionDefinitionsOnce)
+}
+
+func (m *Module) buildFunctionDefinitionsOnce() {
+ var moduleName string
+ var functionNames NameMap
+ var localNames, resultNames IndirectNameMap
+ if m.NameSection != nil {
+ moduleName = m.NameSection.ModuleName
+ functionNames = m.NameSection.FunctionNames
+ localNames = m.NameSection.LocalNames
+ resultNames = m.NameSection.ResultNames
+ }
+
+ importCount := m.ImportFunctionCount
+ m.FunctionDefinitionSection = make([]FunctionDefinition, importCount+uint32(len(m.FunctionSection)))
+
+ importFuncIdx := Index(0)
+ for i := range m.ImportSection {
+ imp := &m.ImportSection[i]
+ if imp.Type != ExternTypeFunc {
+ continue
+ }
+
+ def := &m.FunctionDefinitionSection[importFuncIdx]
+ def.importDesc = imp
+ def.index = importFuncIdx
+ def.Functype = &m.TypeSection[imp.DescFunc]
+ importFuncIdx++
+ }
+
+ for codeIndex, typeIndex := range m.FunctionSection {
+ code := &m.CodeSection[codeIndex]
+ idx := importFuncIdx + Index(codeIndex)
+ def := &m.FunctionDefinitionSection[idx]
+ def.index = idx
+ def.Functype = &m.TypeSection[typeIndex]
+ def.goFunc = code.GoFunc
+ }
+
+ n, nLen := 0, len(functionNames)
+ for i := range m.FunctionDefinitionSection {
+ d := &m.FunctionDefinitionSection[i]
+ // The function name section begins with imports, but can be sparse.
+ // This keeps track of how far in the name section we've searched.
+ funcIdx := d.index
+ var funcName string
+ for ; n < nLen; n++ {
+ next := &functionNames[n]
+ if next.Index > funcIdx {
+ break // we have function names, but starting at a later index.
+ } else if next.Index == funcIdx {
+ funcName = next.Name
+ break
+ }
+ }
+
+ d.moduleName = moduleName
+ d.name = funcName
+ d.Debugname = wasmdebug.FuncName(moduleName, funcName, funcIdx)
+ d.paramNames = paramNames(localNames, funcIdx, len(d.Functype.Params))
+ d.resultNames = paramNames(resultNames, funcIdx, len(d.Functype.Results))
+
+ for i := range m.ExportSection {
+ e := &m.ExportSection[i]
+ if e.Type == ExternTypeFunc && e.Index == funcIdx {
+ d.exportNames = append(d.exportNames, e.Name)
+ }
+ }
+ }
+}
+
+// FunctionDefinition implements api.FunctionDefinition
+type FunctionDefinition struct {
+ internalapi.WazeroOnlyType
+ moduleName string
+ index Index
+ name string
+ // Debugname is exported for testing purpose.
+ Debugname string
+ goFunc interface{}
+ // Functype is exported for testing purpose.
+ Functype *FunctionType
+ importDesc *Import
+ exportNames []string
+ paramNames []string
+ resultNames []string
+}
+
+// ModuleName implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) ModuleName() string {
+ return f.moduleName
+}
+
+// Index implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) Index() uint32 {
+ return f.index
+}
+
+// Name implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) Name() string {
+ return f.name
+}
+
+// DebugName implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) DebugName() string {
+ return f.Debugname
+}
+
+// Import implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) Import() (moduleName, name string, isImport bool) {
+ if f.importDesc != nil {
+ importDesc := f.importDesc
+ moduleName, name, isImport = importDesc.Module, importDesc.Name, true
+ }
+ return
+}
+
+// ExportNames implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) ExportNames() []string {
+ return f.exportNames
+}
+
+// GoFunction implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) GoFunction() interface{} {
+ return f.goFunc
+}
+
+// ParamTypes implements api.FunctionDefinition ParamTypes.
+func (f *FunctionDefinition) ParamTypes() []ValueType {
+ return f.Functype.Params
+}
+
+// ParamNames implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) ParamNames() []string {
+ return f.paramNames
+}
+
+// ResultTypes implements api.FunctionDefinition ResultTypes.
+func (f *FunctionDefinition) ResultTypes() []ValueType {
+ return f.Functype.Results
+}
+
+// ResultNames implements the same method as documented on api.FunctionDefinition.
+func (f *FunctionDefinition) ResultNames() []string {
+ return f.resultNames
+}