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