mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 04:23:41 +00:00
87a8aafc4f
- add internal/wasm-tools/go.mod file to depend on wasm-tools-go
- copy package cm into src/internal/cm
- remove wasm-tools-go "vendor" submodule
internal/tools: fix typo
go.{mod,sum}, internal/tools: add wit-bindgen-go to tools
GNUmakefile: use go run for wit-bindgen-go
GNUmakefile: add tools target to go:generate tools binaries in internal/tools
GNUmakefile: add .PHONY for lint and spell
GNUmakefile, internal/cm: vendor package cm into internal/cm
go.{mod,sum}: update wasm-tools-go to v0.1.4
internal/wasi: use internal/cm package
remove submodule src/vendor/github.com/ydnar/wasm-tools-go
GNUmakefile: add comment documenting what wasi-cm target does
go.{mod,sum}: remove toolchain; go mod tidy
go.mod: revert to Go 1.19
go.mod: go 1.19
go.{mod,sum}, internal/{tools,wasm-tools}: revert root go.mod file to go1.19
Create a wasm-tools specific module that can require go1.22 for wasm-tools-go.
108 lines
3.1 KiB
Go
108 lines
3.1 KiB
Go
package cm
|
|
|
|
import "unsafe"
|
|
|
|
const (
|
|
// ResultOK represents the OK case of a result.
|
|
ResultOK = false
|
|
|
|
// ResultErr represents the error case of a result.
|
|
ResultErr = true
|
|
)
|
|
|
|
// BoolResult represents a result with no OK or error type.
|
|
// False represents the OK case and true represents the error case.
|
|
type BoolResult bool
|
|
|
|
// Result represents a result sized to hold the Shape type.
|
|
// The size of the Shape type must be greater than or equal to the size of OK and Err types.
|
|
// For results with two zero-length types, use [BoolResult].
|
|
type Result[Shape, OK, Err any] struct{ result[Shape, OK, Err] }
|
|
|
|
// result represents the internal representation of a Component Model result type.
|
|
type result[Shape, OK, Err any] struct {
|
|
isErr bool
|
|
_ [0]OK
|
|
_ [0]Err
|
|
data Shape // [unsafe.Sizeof(*(*Shape)(unsafe.Pointer(nil)))]byte
|
|
}
|
|
|
|
// IsOK returns true if r represents the OK case.
|
|
func (r *result[Shape, OK, Err]) IsOK() bool {
|
|
r.validate()
|
|
return !r.isErr
|
|
}
|
|
|
|
// IsErr returns true if r represents the error case.
|
|
func (r *result[Shape, OK, Err]) IsErr() bool {
|
|
r.validate()
|
|
return r.isErr
|
|
}
|
|
|
|
// OK returns a non-nil *OK pointer if r represents the OK case.
|
|
// If r represents an error, then it returns nil.
|
|
func (r *result[Shape, OK, Err]) OK() *OK {
|
|
r.validate()
|
|
if r.isErr {
|
|
return nil
|
|
}
|
|
return (*OK)(unsafe.Pointer(&r.data))
|
|
}
|
|
|
|
// Err returns a non-nil *Err pointer if r represents the error case.
|
|
// If r represents the OK case, then it returns nil.
|
|
func (r *result[Shape, OK, Err]) Err() *Err {
|
|
r.validate()
|
|
if !r.isErr {
|
|
return nil
|
|
}
|
|
return (*Err)(unsafe.Pointer(&r.data))
|
|
}
|
|
|
|
// This function is sized so it can be inlined and optimized away.
|
|
func (r *result[Shape, OK, Err]) validate() {
|
|
var shape Shape
|
|
var ok OK
|
|
var err Err
|
|
|
|
// Check if size of Shape is greater than both OK and Err
|
|
if unsafe.Sizeof(shape) > unsafe.Sizeof(ok) && unsafe.Sizeof(shape) > unsafe.Sizeof(err) {
|
|
panic("result: size of data type > OK and Err types")
|
|
}
|
|
|
|
// Check if size of OK is greater than Shape
|
|
if unsafe.Sizeof(ok) > unsafe.Sizeof(shape) {
|
|
panic("result: size of OK type > data type")
|
|
}
|
|
|
|
// Check if size of Err is greater than Shape
|
|
if unsafe.Sizeof(err) > unsafe.Sizeof(shape) {
|
|
panic("result: size of Err type > data type")
|
|
}
|
|
|
|
// Check if Shape is zero-sized, but size of result != 1
|
|
if unsafe.Sizeof(shape) == 0 && unsafe.Sizeof(*r) != 1 {
|
|
panic("result: size of data type == 0, but result size != 1")
|
|
}
|
|
}
|
|
|
|
// OK returns an OK result with shape Shape and type OK and Err.
|
|
// Pass Result[OK, OK, Err] or Result[Err, OK, Err] as the first type argument.
|
|
func OK[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](ok OK) R {
|
|
var r struct{ result[Shape, OK, Err] }
|
|
r.validate()
|
|
r.isErr = ResultOK
|
|
*((*OK)(unsafe.Pointer(&r.data))) = ok
|
|
return R(r)
|
|
}
|
|
|
|
// Err returns an error result with shape Shape and type OK and Err.
|
|
// Pass Result[OK, OK, Err] or Result[Err, OK, Err] as the first type argument.
|
|
func Err[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](err Err) R {
|
|
var r struct{ result[Shape, OK, Err] }
|
|
r.validate()
|
|
r.isErr = ResultErr
|
|
*((*Err)(unsafe.Pointer(&r.data))) = err
|
|
return R(r)
|
|
}
|