github.com/tetratelabs/wazero@v1.7.1/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/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 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 memory size in bytes available. 563 // e.g. If the underlying memory has 1 page: 65536 564 // 565 // # Notes 566 // 567 // - This overflows (returns zero) if the memory has the maximum 65536 pages. 568 // As a workaround until wazero v2 to fix the return type, use Grow(0) to obtain the current pages and 569 // multiply by 65536. 570 // 571 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefsyntax-instr-memorymathsfmemorysize%E2%91%A0 572 Size() uint32 573 574 // Grow increases memory by the delta in pages (65536 bytes per page). 575 // The return val is the previous memory size in pages, or false if the 576 // delta was ignored as it exceeds MemoryDefinition.Max. 577 // 578 // # Notes 579 // 580 // - This is the same as the "memory.grow" instruction defined in the 581 // WebAssembly Core Specification, except returns false instead of -1. 582 // - When this returns true, any shared views via Read must be refreshed. 583 // 584 // See MemorySizer Read and https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#grow-mem 585 Grow(deltaPages uint32) (previousPages uint32, ok bool) 586 587 // ReadByte reads a single byte from the underlying buffer at the offset or returns false if out of range. 588 ReadByte(offset uint32) (byte, bool) 589 590 // ReadUint16Le reads a uint16 in little-endian encoding from the underlying buffer at the offset in or returns 591 // false if out of range. 592 ReadUint16Le(offset uint32) (uint16, bool) 593 594 // ReadUint32Le reads a uint32 in little-endian encoding from the underlying buffer at the offset in or returns 595 // false if out of range. 596 ReadUint32Le(offset uint32) (uint32, bool) 597 598 // ReadFloat32Le reads a float32 from 32 IEEE 754 little-endian encoded bits in the underlying buffer at the offset 599 // or returns false if out of range. 600 // See math.Float32bits 601 ReadFloat32Le(offset uint32) (float32, bool) 602 603 // ReadUint64Le reads a uint64 in little-endian encoding from the underlying buffer at the offset or returns false 604 // if out of range. 605 ReadUint64Le(offset uint32) (uint64, bool) 606 607 // ReadFloat64Le reads a float64 from 64 IEEE 754 little-endian encoded bits in the underlying buffer at the offset 608 // or returns false if out of range. 609 // 610 // See math.Float64bits 611 ReadFloat64Le(offset uint32) (float64, bool) 612 613 // Read reads byteCount bytes from the underlying buffer at the offset or 614 // returns false if out of range. 615 // 616 // For example, to search for a NUL-terminated string: 617 // buf, _ = memory.Read(offset, byteCount) 618 // n := bytes.IndexByte(buf, 0) 619 // if n < 0 { 620 // // Not found! 621 // } 622 // 623 // Write-through 624 // 625 // This returns a view of the underlying memory, not a copy. This means any 626 // writes to the slice returned are visible to Wasm, and any updates from 627 // Wasm are visible reading the returned slice. 628 // 629 // For example: 630 // buf, _ = memory.Read(offset, byteCount) 631 // buf[1] = 'a' // writes through to memory, meaning Wasm code see 'a'. 632 // 633 // If you don't intend-write through, make a copy of the returned slice. 634 // 635 // When to refresh Read 636 // 637 // The returned slice disconnects on any capacity change. For example, 638 // `buf = append(buf, 'a')` might result in a slice that is no longer 639 // shared. The same exists Wasm side. For example, if Wasm changes its 640 // memory capacity, ex via "memory.grow"), the host slice is no longer 641 // shared. Those who need a stable view must set Wasm memory min=max, or 642 // use wazero.RuntimeConfig WithMemoryCapacityPages to ensure max is always 643 // allocated. 644 Read(offset, byteCount uint32) ([]byte, bool) 645 646 // WriteByte writes a single byte to the underlying buffer at the offset in or returns false if out of range. 647 WriteByte(offset uint32, v byte) bool 648 649 // WriteUint16Le writes the value in little-endian encoding to the underlying buffer at the offset in or returns 650 // false if out of range. 651 WriteUint16Le(offset uint32, v uint16) bool 652 653 // WriteUint32Le writes the value in little-endian encoding to the underlying buffer at the offset in or returns 654 // false if out of range. 655 WriteUint32Le(offset, v uint32) bool 656 657 // WriteFloat32Le writes the value in 32 IEEE 754 little-endian encoded bits to the underlying buffer at the offset 658 // or returns false if out of range. 659 // 660 // See math.Float32bits 661 WriteFloat32Le(offset uint32, v float32) bool 662 663 // WriteUint64Le writes the value in little-endian encoding to the underlying buffer at the offset in or returns 664 // false if out of range. 665 WriteUint64Le(offset uint32, v uint64) bool 666 667 // WriteFloat64Le writes the value in 64 IEEE 754 little-endian encoded bits to the underlying buffer at the offset 668 // or returns false if out of range. 669 // 670 // See math.Float64bits 671 WriteFloat64Le(offset uint32, v float64) bool 672 673 // Write writes the slice to the underlying buffer at the offset or returns false if out of range. 674 Write(offset uint32, v []byte) bool 675 676 // WriteString writes the string to the underlying buffer at the offset or returns false if out of range. 677 WriteString(offset uint32, v string) bool 678 679 internalapi.WazeroOnly 680 } 681 682 // CustomSection contains the name and raw data of a custom section. 683 // 684 // # Notes 685 // 686 // - This is an interface for decoupling, not third-party implementations. 687 // All implementations are in wazero. 688 type CustomSection interface { 689 // Name is the name of the custom section 690 Name() string 691 // Data is the raw data of the custom section 692 Data() []byte 693 694 internalapi.WazeroOnly 695 } 696 697 // EncodeExternref encodes the input as a ValueTypeExternref. 698 // 699 // See DecodeExternref 700 func EncodeExternref(input uintptr) uint64 { 701 return uint64(input) 702 } 703 704 // DecodeExternref decodes the input as a ValueTypeExternref. 705 // 706 // See EncodeExternref 707 func DecodeExternref(input uint64) uintptr { 708 return uintptr(input) 709 } 710 711 // EncodeI32 encodes the input as a ValueTypeI32. 712 func EncodeI32(input int32) uint64 { 713 return uint64(uint32(input)) 714 } 715 716 // DecodeI32 decodes the input as a ValueTypeI32. 717 func DecodeI32(input uint64) int32 { 718 return int32(input) 719 } 720 721 // EncodeU32 encodes the input as a ValueTypeI32. 722 func EncodeU32(input uint32) uint64 { 723 return uint64(input) 724 } 725 726 // DecodeU32 decodes the input as a ValueTypeI32. 727 func DecodeU32(input uint64) uint32 { 728 return uint32(input) 729 } 730 731 // EncodeI64 encodes the input as a ValueTypeI64. 732 func EncodeI64(input int64) uint64 { 733 return uint64(input) 734 } 735 736 // EncodeF32 encodes the input as a ValueTypeF32. 737 // 738 // See DecodeF32 739 func EncodeF32(input float32) uint64 { 740 return uint64(math.Float32bits(input)) 741 } 742 743 // DecodeF32 decodes the input as a ValueTypeF32. 744 // 745 // See EncodeF32 746 func DecodeF32(input uint64) float32 { 747 return math.Float32frombits(uint32(input)) 748 } 749 750 // EncodeF64 encodes the input as a ValueTypeF64. 751 // 752 // See EncodeF32 753 func EncodeF64(input float64) uint64 { 754 return math.Float64bits(input) 755 } 756 757 // DecodeF64 decodes the input as a ValueTypeF64. 758 // 759 // See EncodeF64 760 func DecodeF64(input uint64) float64 { 761 return math.Float64frombits(input) 762 }