wa-lang.org/wazero@v1.0.2/api/wasm.go (about)

     1  // Package api includes constants and interfaces used by both end-users and internal implementations.
     2  package api
     3  
     4  import (
     5  	"context"
     6  	"fmt"
     7  	"math"
     8  )
     9  
    10  // ExternType classifies imports and exports with their respective types.
    11  //
    12  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#external-types%E2%91%A0
    13  type ExternType = byte
    14  
    15  const (
    16  	ExternTypeFunc   ExternType = 0x00
    17  	ExternTypeTable  ExternType = 0x01
    18  	ExternTypeMemory ExternType = 0x02
    19  	ExternTypeGlobal ExternType = 0x03
    20  )
    21  
    22  // The below are exported to consolidate parsing behavior for external types.
    23  const (
    24  	// ExternTypeFuncName is the name of the WebAssembly 1.0 (20191205) Text Format field for ExternTypeFunc.
    25  	ExternTypeFuncName = "func"
    26  	// ExternTypeTableName is the name of the WebAssembly 1.0 (20191205) Text Format field for ExternTypeTable.
    27  	ExternTypeTableName = "table"
    28  	// ExternTypeMemoryName is the name of the WebAssembly 1.0 (20191205) Text Format field for ExternTypeMemory.
    29  	ExternTypeMemoryName = "memory"
    30  	// ExternTypeGlobalName is the name of the WebAssembly 1.0 (20191205) Text Format field for ExternTypeGlobal.
    31  	ExternTypeGlobalName = "global"
    32  )
    33  
    34  // ExternTypeName returns the name of the WebAssembly 1.0 (20191205) Text Format field of the given type.
    35  //
    36  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#exports%E2%91%A4
    37  func ExternTypeName(et ExternType) string {
    38  	switch et {
    39  	case ExternTypeFunc:
    40  		return ExternTypeFuncName
    41  	case ExternTypeTable:
    42  		return ExternTypeTableName
    43  	case ExternTypeMemory:
    44  		return ExternTypeMemoryName
    45  	case ExternTypeGlobal:
    46  		return ExternTypeGlobalName
    47  	}
    48  	return fmt.Sprintf("%#x", et)
    49  }
    50  
    51  // ValueType describes a parameter or result type mapped to a WebAssembly
    52  // function signature.
    53  //
    54  // The following describes how to convert between Wasm and Golang types:
    55  //
    56  //   - ValueTypeI32 - EncodeU32 DecodeU32 for uint32 / EncodeI32 DecodeI32 for int32
    57  //   - ValueTypeI64 - uint64(int64)
    58  //   - ValueTypeF32 - EncodeF32 DecodeF32 from float32
    59  //   - ValueTypeF64 - EncodeF64 DecodeF64 from float64
    60  //   - ValueTypeExternref - unintptr(unsafe.Pointer(p)) where p is any pointer
    61  //     type in Go (e.g. *string)
    62  //
    63  // e.g. Given a Text Format type use (param i64) (result i64), no conversion is
    64  // necessary.
    65  //
    66  //	results, _ := fn(ctx, input)
    67  //	result := result[0]
    68  //
    69  // e.g. Given a Text Format type use (param f64) (result f64), conversion is
    70  // necessary.
    71  //
    72  //	results, _ := fn(ctx, api.EncodeF64(input))
    73  //	result := api.DecodeF64(result[0])
    74  //
    75  // Note: This is a type alias as it is easier to encode and decode in the
    76  // binary format.
    77  //
    78  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-valtype
    79  type ValueType = byte
    80  
    81  const (
    82  	// ValueTypeI32 is a 32-bit integer.
    83  	ValueTypeI32 ValueType = 0x7f
    84  	// ValueTypeI64 is a 64-bit integer.
    85  	ValueTypeI64 ValueType = 0x7e
    86  	// ValueTypeF32 is a 32-bit floating point number.
    87  	ValueTypeF32 ValueType = 0x7d
    88  	// ValueTypeF64 is a 64-bit floating point number.
    89  	ValueTypeF64 ValueType = 0x7c
    90  
    91  	// ValueTypeExternref is a externref type.
    92  	//
    93  	// Note: in wazero, externref type value are opaque raw 64-bit pointers,
    94  	// and the ValueTypeExternref type in the signature will be translated as
    95  	// uintptr in wazero's API level.
    96  	//
    97  	// For example, given the import function:
    98  	//	(func (import "env" "f") (param externref) (result externref))
    99  	//
   100  	// This can be defined in Go as:
   101  	//  r.NewHostModuleBuilder("env").
   102  	//		NewFunctionBuilder().
   103  	//		WithFunc(func(context.Context, _ uintptr) (_ uintptr) { return }).
   104  	//		Export("f")
   105  	//
   106  	// Note: The usage of this type is toggled with api.CoreFeatureBulkMemoryOperations.
   107  	ValueTypeExternref ValueType = 0x6f
   108  )
   109  
   110  // ValueTypeName returns the type name of the given ValueType as a string.
   111  // These type names match the names used in the WebAssembly text format.
   112  //
   113  // Note: This returns "unknown", if an undefined ValueType value is passed.
   114  func ValueTypeName(t ValueType) string {
   115  	switch t {
   116  	case ValueTypeI32:
   117  		return "i32"
   118  	case ValueTypeI64:
   119  		return "i64"
   120  	case ValueTypeF32:
   121  		return "f32"
   122  	case ValueTypeF64:
   123  		return "f64"
   124  	case ValueTypeExternref:
   125  		return "externref"
   126  	}
   127  	return "unknown"
   128  }
   129  
   130  // Module return functions exported in a module, post-instantiation.
   131  //
   132  // # Notes
   133  //
   134  //   - Closing the wazero.Runtime closes any Module it instantiated.
   135  //   - This is an interface for decoupling, not third-party implementations. All implementations are in wazero.
   136  //
   137  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#external-types%E2%91%A0
   138  type Module interface {
   139  	fmt.Stringer
   140  
   141  	// Name is the name this module was instantiated with. Exported functions can be imported with this name.
   142  	Name() string
   143  
   144  	// Memory returns a memory defined in this module or nil if there are none wasn't.
   145  	Memory() Memory
   146  
   147  	// ExportedFunction returns a function exported from this module or nil if it wasn't.
   148  	ExportedFunction(name string) Function
   149  
   150  	// TODO: Table
   151  
   152  	// ExportedMemory returns a memory exported from this module or nil if it wasn't.
   153  	//
   154  	// WASI modules require exporting a Memory named "memory". This means that a module successfully initialized
   155  	// as a WASI Command or Reactor will never return nil for this name.
   156  	//
   157  	// See https://github.com/WebAssembly/WASI/blob/snapshot-01/design/application-abi.md#current-unstable-abi
   158  	ExportedMemory(name string) Memory
   159  
   160  	// ExportedGlobal a global exported from this module or nil if it wasn't.
   161  	ExportedGlobal(name string) Global
   162  
   163  	// CloseWithExitCode releases resources allocated for this Module. Use a non-zero exitCode parameter to indicate a
   164  	// failure to ExportedFunction callers.
   165  	//
   166  	// The error returned here, if present, is about resource de-allocation (such as I/O errors). Only the last error is
   167  	// returned, so a non-nil return means at least one error happened. Regardless of error, this module instance will
   168  	// be removed, making its name available again.
   169  	//
   170  	// Calling this inside a host function is safe, and may cause ExportedFunction callers to receive a sys.ExitError
   171  	// with the exitCode.
   172  	CloseWithExitCode(ctx context.Context, exitCode uint32) error
   173  
   174  	// Closer closes this module by delegating to CloseWithExitCode with an exit code of zero.
   175  	Closer
   176  }
   177  
   178  // Closer closes a resource.
   179  //
   180  // Note: This is an interface for decoupling, not third-party implementations. All implementations are in wazero.
   181  type Closer interface {
   182  	// Close closes the resource.
   183  	Close(context.Context) error
   184  }
   185  
   186  // ExportDefinition is a WebAssembly type exported in a module
   187  // (wazero.CompiledModule).
   188  //
   189  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#exports%E2%91%A0
   190  type ExportDefinition interface {
   191  	// ModuleName is the possibly empty name of the module defining this
   192  	// export.
   193  	//
   194  	// Note: This may be different from Module.Name, because a compiled module
   195  	// can be instantiated multiple times as different names.
   196  	ModuleName() string
   197  
   198  	// Index is the position in the module's index namespace, imports first.
   199  	Index() uint32
   200  
   201  	// Import returns true with the module and name when this was imported.
   202  	// Otherwise, it returns false.
   203  	//
   204  	// Note: Empty string is valid for both names in the WebAssembly Core
   205  	// Specification, so "" "" is possible.
   206  	Import() (moduleName, name string, isImport bool)
   207  
   208  	// ExportNames include all exported names.
   209  	//
   210  	// Note: The empty name is allowed in the WebAssembly Core Specification,
   211  	// so "" is possible.
   212  	ExportNames() []string
   213  }
   214  
   215  // MemoryDefinition is a WebAssembly memory exported in a module
   216  // (wazero.CompiledModule). Units are in pages (64KB).
   217  //
   218  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#exports%E2%91%A0
   219  type MemoryDefinition interface {
   220  	ExportDefinition
   221  
   222  	// Min returns the possibly zero initial count of 64KB pages.
   223  	Min() uint32
   224  
   225  	// Max returns the possibly zero max count of 64KB pages, or false if
   226  	// unbounded.
   227  	Max() (uint32, bool)
   228  }
   229  
   230  // FunctionDefinition is a WebAssembly function exported in a module
   231  // (wazero.CompiledModule).
   232  //
   233  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#exports%E2%91%A0
   234  type FunctionDefinition interface {
   235  	ExportDefinition
   236  
   237  	// Name is the module-defined name of the function, which is not necessarily
   238  	// the same as its export name.
   239  	Name() string
   240  
   241  	// DebugName identifies this function based on its Index or Name in the
   242  	// module. This is used for errors and stack traces. e.g. "env.abort".
   243  	//
   244  	// When the function name is empty, a substitute name is generated by
   245  	// prefixing '$' to its position in the index namespace. Ex ".$0" is the
   246  	// first function (possibly imported) in an unnamed module.
   247  	//
   248  	// The format is dot-delimited module and function name, but there are no
   249  	// restrictions on the module and function name. This means either can be
   250  	// empty or include dots. e.g. "x.x.x" could mean module "x" and name "x.x",
   251  	// or it could mean module "x.x" and name "x".
   252  	//
   253  	// Note: This name is stable regardless of import or export. For example,
   254  	// if Import returns true, the value is still based on the Name or Index
   255  	// and not the imported function name.
   256  	DebugName() string
   257  
   258  	// GoFunction is non-nil when implemented by the embedder instead of a wasm
   259  	// binary, e.g. via wazero.HostModuleBuilder
   260  	//
   261  	// The expected results are nil, GoFunction or GoModuleFunction.
   262  	GoFunction() interface{}
   263  
   264  	// ParamTypes are the possibly empty sequence of value types accepted by a
   265  	// function with this signature.
   266  	//
   267  	// See ValueType documentation for encoding rules.
   268  	ParamTypes() []ValueType
   269  
   270  	// ParamNames are index-correlated with ParamTypes or nil if not available
   271  	// for one or more parameters.
   272  	ParamNames() []string
   273  
   274  	// ResultTypes are the results of the function.
   275  	//
   276  	// When WebAssembly 1.0 (20191205), there can be at most one result.
   277  	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#result-types%E2%91%A0
   278  	//
   279  	// See ValueType documentation for encoding rules.
   280  	ResultTypes() []ValueType
   281  }
   282  
   283  // Function is a WebAssembly function exported from an instantiated module
   284  // (wazero.Runtime InstantiateModule).
   285  //
   286  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-func
   287  type Function interface {
   288  	// Definition is metadata about this function from its defining module.
   289  	Definition() FunctionDefinition
   290  
   291  	// Call invokes the function with the given parameters and returns any
   292  	// results or an error for any failure looking up or invoking the function.
   293  	//
   294  	// Encoding is described in Definition, and supplying an incorrect count of
   295  	// parameters vs FunctionDefinition.ParamTypes is an error.
   296  	//
   297  	// If the exporting Module was closed during this call, the error returned
   298  	// may be a sys.ExitError. See Module.CloseWithExitCode for details.
   299  	//
   300  	// Call is not goroutine-safe, therefore it is recommended to create
   301  	// another Function if you want to invoke the same function concurrently.
   302  	// On the other hand, sequential invocations of Call is allowed.
   303  	//
   304  	// To safely encode/decode params/results expressed as uint64, users are encouraged to
   305  	// use api.EncodeXXX or DecodeXXX functions. See the docs on api.ValueType.
   306  	Call(ctx context.Context, params ...uint64) ([]uint64, error)
   307  }
   308  
   309  // GoModuleFunction is a Function implemented in Go instead of a wasm binary.
   310  // The Module parameter is the calling module, used to access memory or
   311  // exported functions. See GoModuleFunc for an example.
   312  //
   313  // The stack is includes any parameters encoded according to their ValueType.
   314  // Its length is the max of parameter or result length. When there are results,
   315  // write them in order beginning at index zero. Do not use the stack after the
   316  // function returns.
   317  //
   318  // Here's a typical way to read three parameters and write back one.
   319  //
   320  //	// read parameters off the stack in index order
   321  //	argv, argvBuf := api.DecodeU32(stack[0]), api.DecodeU32(stack[1])
   322  //
   323  //	// write results back to the stack in index order
   324  //	stack[0] = api.EncodeU32(ErrnoSuccess)
   325  //
   326  // This function can be non-deterministic or cause side effects. It also
   327  // has special properties not defined in the WebAssembly Core specification.
   328  // Notably, this uses the caller's memory (via Module.Memory). See
   329  // https://www.w3.org/TR/wasm-core-1/#host-functions%E2%91%A0
   330  //
   331  // Most end users will not define functions directly with this, as they will
   332  // use reflection or code generators instead. These approaches are more
   333  // idiomatic as they can map go types to ValueType. This type is exposed for
   334  // those willing to trade usability and safety for performance.
   335  //
   336  // To safely decode/encode values from/to the uint64 stack, users are encouraged to use
   337  // api.EncodeXXX or api.DecodeXXX functions. See the docs on api.ValueType.
   338  type GoModuleFunction interface {
   339  	Call(ctx context.Context, mod Module, stack []uint64)
   340  }
   341  
   342  // GoModuleFunc is a convenience for defining an inlined function.
   343  //
   344  // For example, the following returns an uint32 value read from parameter zero:
   345  //
   346  //	api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
   347  //		offset := api.DecodeU32(params[0]) // read the parameter from the stack
   348  //
   349  //		ret, ok := mod.Memory().ReadUint32Le(ctx, offset)
   350  //		if !ok {
   351  //			panic("out of memory")
   352  //		}
   353  //
   354  //		results[0] = api.EncodeU32(ret) // add the result back to the stack.
   355  //	})
   356  type GoModuleFunc func(ctx context.Context, mod Module, stack []uint64)
   357  
   358  // Call implements GoModuleFunction.Call.
   359  func (f GoModuleFunc) Call(ctx context.Context, mod Module, stack []uint64) {
   360  	f(ctx, mod, stack)
   361  }
   362  
   363  // GoFunction is an optimized form of GoModuleFunction which doesn't require
   364  // the Module parameter. See GoFunc for an example.
   365  //
   366  // For example, this function does not need to use the importing module's
   367  // memory or exported functions.
   368  type GoFunction interface {
   369  	Call(ctx context.Context, stack []uint64)
   370  }
   371  
   372  // GoFunc is a convenience for defining an inlined function.
   373  //
   374  // For example, the following returns the sum of two uint32 parameters:
   375  //
   376  //	api.GoFunc(func(ctx context.Context, stack []uint64) {
   377  //		x, y := api.DecodeU32(params[0]), api.DecodeU32(params[1])
   378  //		results[0] = api.EncodeU32(x + y)
   379  //	})
   380  type GoFunc func(ctx context.Context, stack []uint64)
   381  
   382  // Call implements GoFunction.Call.
   383  func (f GoFunc) Call(ctx context.Context, stack []uint64) {
   384  	f(ctx, stack)
   385  }
   386  
   387  // Global is a WebAssembly 1.0 (20191205) global exported from an instantiated module (wazero.Runtime InstantiateModule).
   388  //
   389  // For example, if the value is not mutable, you can read it once:
   390  //
   391  //	offset := module.ExportedGlobal("memory.offset").Get()
   392  //
   393  // Globals are allowed by specification to be mutable. However, this can be disabled by configuration. When in doubt,
   394  // safe cast to find out if the value can change. Here's an example:
   395  //
   396  //	offset := module.ExportedGlobal("memory.offset")
   397  //	if _, ok := offset.(api.MutableGlobal); ok {
   398  //		// value can change
   399  //	} else {
   400  //		// value is constant
   401  //	}
   402  //
   403  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#globals%E2%91%A0
   404  type Global interface {
   405  	fmt.Stringer
   406  
   407  	// Type describes the numeric type of the global.
   408  	Type() ValueType
   409  
   410  	// Get returns the last known value of this global.
   411  	//
   412  	// See Type for how to encode this value from a Go type.
   413  	Get(context.Context) uint64
   414  }
   415  
   416  // MutableGlobal is a Global whose value can be updated at runtime (variable).
   417  type MutableGlobal interface {
   418  	Global
   419  
   420  	// Set updates the value of this global.
   421  	//
   422  	// See Global.Type for how to decode this value to a Go type.
   423  	Set(ctx context.Context, v uint64)
   424  }
   425  
   426  // Memory allows restricted access to a module's memory. Notably, this does not allow growing.
   427  //
   428  // # Notes
   429  //
   430  //   - This is an interface for decoupling, not third-party implementations. All implementations are in wazero.
   431  //   - This includes all value types available in WebAssembly 1.0 (20191205) and all are encoded little-endian.
   432  //
   433  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#storage%E2%91%A0
   434  type Memory interface {
   435  	// Definition is metadata about this memory from its defining module.
   436  	Definition() MemoryDefinition
   437  
   438  	// Size returns the size in bytes available. e.g. If the underlying memory
   439  	// has 1 page: 65536
   440  	//
   441  	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefsyntax-instr-memorymathsfmemorysize%E2%91%A0
   442  	Size(context.Context) uint32
   443  
   444  	// Grow increases memory by the delta in pages (65536 bytes per page).
   445  	// The return val is the previous memory size in pages, or false if the
   446  	// delta was ignored as it exceeds MemoryDefinition.Max.
   447  	//
   448  	// # Notes
   449  	//
   450  	//   - This is the same as the "memory.grow" instruction defined in the
   451  	//	  WebAssembly Core Specification, except returns false instead of -1.
   452  	//   - When this returns true, any shared views via Read must be refreshed.
   453  	//
   454  	// See MemorySizer Read and https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#grow-mem
   455  	Grow(ctx context.Context, deltaPages uint32) (previousPages uint32, ok bool)
   456  
   457  	// ReadByte reads a single byte from the underlying buffer at the offset or returns false if out of range.
   458  	ReadByte(ctx context.Context, offset uint32) (byte, bool)
   459  
   460  	// ReadUint16Le reads a uint16 in little-endian encoding from the underlying buffer at the offset in or returns
   461  	// false if out of range.
   462  	ReadUint16Le(ctx context.Context, offset uint32) (uint16, bool)
   463  
   464  	// ReadUint32Le reads a uint32 in little-endian encoding from the underlying buffer at the offset in or returns
   465  	// false if out of range.
   466  	ReadUint32Le(ctx context.Context, offset uint32) (uint32, bool)
   467  
   468  	// ReadFloat32Le reads a float32 from 32 IEEE 754 little-endian encoded bits in the underlying buffer at the offset
   469  	// or returns false if out of range.
   470  	// See math.Float32bits
   471  	ReadFloat32Le(ctx context.Context, offset uint32) (float32, bool)
   472  
   473  	// ReadUint64Le reads a uint64 in little-endian encoding from the underlying buffer at the offset or returns false
   474  	// if out of range.
   475  	ReadUint64Le(ctx context.Context, offset uint32) (uint64, bool)
   476  
   477  	// ReadFloat64Le reads a float64 from 64 IEEE 754 little-endian encoded bits in the underlying buffer at the offset
   478  	// or returns false if out of range.
   479  	//
   480  	// See math.Float64bits
   481  	ReadFloat64Le(ctx context.Context, offset uint32) (float64, bool)
   482  
   483  	// Read reads byteCount bytes from the underlying buffer at the offset or
   484  	// returns false if out of range.
   485  	//
   486  	// For example, to search for a NUL-terminated string:
   487  	//	buf, _ = memory.Read(ctx, offset, byteCount)
   488  	//	n := bytes.IndexByte(buf, 0)
   489  	//	if n < 0 {
   490  	//		// Not found!
   491  	//	}
   492  	//
   493  	// Write-through
   494  	//
   495  	// This returns a view of the underlying memory, not a copy. This means any
   496  	// writes to the slice returned are visible to Wasm, and any updates from
   497  	// Wasm are visible reading the returned slice.
   498  	//
   499  	// For example:
   500  	//	buf, _ = memory.Read(ctx, offset, byteCount)
   501  	//	buf[1] = 'a' // writes through to memory, meaning Wasm code see 'a'.
   502  	//
   503  	// If you don't intend-write through, make a copy of the returned slice.
   504  	//
   505  	// When to refresh Read
   506  	//
   507  	// The returned slice disconnects on any capacity change. For example,
   508  	// `buf = append(buf, 'a')` might result in a slice that is no longer
   509  	// shared. The same exists Wasm side. For example, if Wasm changes its
   510  	// memory capacity, ex via "memory.grow"), the host slice is no longer
   511  	// shared. Those who need a stable view must set Wasm memory min=max, or
   512  	// use wazero.RuntimeConfig WithMemoryCapacityPages to ensure max is always
   513  	// allocated.
   514  	Read(ctx context.Context, offset, byteCount uint32) ([]byte, bool)
   515  
   516  	// WriteByte writes a single byte to the underlying buffer at the offset in or returns false if out of range.
   517  	WriteByte(ctx context.Context, offset uint32, v byte) bool
   518  
   519  	// WriteUint16Le writes the value in little-endian encoding to the underlying buffer at the offset in or returns
   520  	// false if out of range.
   521  	WriteUint16Le(ctx context.Context, offset uint32, v uint16) bool
   522  
   523  	// WriteUint32Le writes the value in little-endian encoding to the underlying buffer at the offset in or returns
   524  	// false if out of range.
   525  	WriteUint32Le(ctx context.Context, offset, v uint32) bool
   526  
   527  	// WriteFloat32Le writes the value in 32 IEEE 754 little-endian encoded bits to the underlying buffer at the offset
   528  	// or returns false if out of range.
   529  	//
   530  	// See math.Float32bits
   531  	WriteFloat32Le(ctx context.Context, offset uint32, v float32) bool
   532  
   533  	// WriteUint64Le writes the value in little-endian encoding to the underlying buffer at the offset in or returns
   534  	// false if out of range.
   535  	WriteUint64Le(ctx context.Context, offset uint32, v uint64) bool
   536  
   537  	// WriteFloat64Le writes the value in 64 IEEE 754 little-endian encoded bits to the underlying buffer at the offset
   538  	// or returns false if out of range.
   539  	//
   540  	// See math.Float64bits
   541  	WriteFloat64Le(ctx context.Context, offset uint32, v float64) bool
   542  
   543  	// Write writes the slice to the underlying buffer at the offset or returns false if out of range.
   544  	Write(ctx context.Context, offset uint32, v []byte) bool
   545  
   546  	// WriteString writes the string to the underlying buffer at the offset or returns false if out of range.
   547  	WriteString(ctx context.Context, offset uint32, v string) bool
   548  }
   549  
   550  // EncodeExternref encodes the input as a ValueTypeExternref.
   551  //
   552  // See DecodeExternref
   553  func EncodeExternref(input uintptr) uint64 {
   554  	return uint64(input)
   555  }
   556  
   557  // DecodeExternref decodes the input as a ValueTypeExternref.
   558  //
   559  // See EncodeExternref
   560  func DecodeExternref(input uint64) uintptr {
   561  	return uintptr(input)
   562  }
   563  
   564  // EncodeI32 encodes the input as a ValueTypeI32.
   565  func EncodeI32(input int32) uint64 {
   566  	return uint64(uint32(input))
   567  }
   568  
   569  // DecodeI32 decodes the input as a ValueTypeI32.
   570  func DecodeI32(input uint64) int32 {
   571  	return int32(input)
   572  }
   573  
   574  // EncodeU32 encodes the input as a ValueTypeI32.
   575  func EncodeU32(input uint32) uint64 {
   576  	return uint64(input)
   577  }
   578  
   579  // DecodeU32 decodes the input as a ValueTypeI32.
   580  func DecodeU32(input uint64) uint32 {
   581  	return uint32(input)
   582  }
   583  
   584  // EncodeI64 encodes the input as a ValueTypeI64.
   585  func EncodeI64(input int64) uint64 {
   586  	return uint64(input)
   587  }
   588  
   589  // EncodeF32 encodes the input as a ValueTypeF32.
   590  //
   591  // See DecodeF32
   592  func EncodeF32(input float32) uint64 {
   593  	return uint64(math.Float32bits(input))
   594  }
   595  
   596  // DecodeF32 decodes the input as a ValueTypeF32.
   597  //
   598  // See EncodeF32
   599  func DecodeF32(input uint64) float32 {
   600  	return math.Float32frombits(uint32(input))
   601  }
   602  
   603  // EncodeF64 encodes the input as a ValueTypeF64.
   604  //
   605  // See EncodeF32
   606  func EncodeF64(input float64) uint64 {
   607  	return math.Float64bits(input)
   608  }
   609  
   610  // DecodeF64 decodes the input as a ValueTypeF64.
   611  //
   612  // See EncodeF64
   613  func DecodeF64(input uint64) float64 {
   614  	return math.Float64frombits(input)
   615  }