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