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