From 595ea5d6b4975fa592438db3299caec5d4a8f5d4 Mon Sep 17 00:00:00 2001 From: "corda.ilaria@gmail.com" Date: Mon, 6 Apr 2026 01:08:30 +0200 Subject: [PATCH 1/6] upgrade go version and add more idiomatic Go --- example/countvowels/std_main.go | 9 ++++----- example/countvowels/tiny_main.go | 9 ++++----- example/http/std_main.go | 2 +- extism_pdk.go | 27 ++++++++++++++++++++------- go.mod | 4 +++- go.sum | 2 ++ go.work | 2 +- wasi-reactor/go.mod | 2 +- 8 files changed, 36 insertions(+), 21 deletions(-) diff --git a/example/countvowels/std_main.go b/example/countvowels/std_main.go index d41024f..cd1560e 100644 --- a/example/countvowels/std_main.go +++ b/example/countvowels/std_main.go @@ -26,7 +26,7 @@ type CountVowelsInput struct { } // CountVowelsOutput represents the JSON output sent to the host. -type CountVowelsOuptut struct { +type CountVowelsOutput struct { Count int `json:"count"` Total int `json:"total"` Vowels string `json:"vowels"` @@ -46,7 +46,7 @@ func countVowelsTyped() int32 { //export count_vowels_json_output func countVowelsJSONOutput() int32 { - output := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + output := CountVowelsOutput{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} err := pdk.OutputJSON(output) if err != nil { pdk.SetError(err) @@ -57,7 +57,7 @@ func countVowelsJSONOutput() int32 { //export count_vowels_roundtrip_json_mem func countVowelsJSONRoundtripMem() int32 { - a := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + a := CountVowelsOutput{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} mem, err := pdk.AllocateJSON(&a) if err != nil { pdk.SetError(err) @@ -65,7 +65,7 @@ func countVowelsJSONRoundtripMem() int32 { } // find the data in mem and ensure it's the same once decoded - var b CountVowelsOuptut + var b CountVowelsOutput err = pdk.JSONFrom(mem.Offset(), &b) if err != nil { pdk.SetError(err) @@ -89,7 +89,6 @@ func countVowels() int32 { switch a { case 'A', 'I', 'E', 'O', 'U', 'a', 'e', 'i', 'o', 'u': count++ - default: } } diff --git a/example/countvowels/tiny_main.go b/example/countvowels/tiny_main.go index 6b2046f..17f6458 100644 --- a/example/countvowels/tiny_main.go +++ b/example/countvowels/tiny_main.go @@ -15,7 +15,7 @@ type CountVowelsInput struct { } // CountVowelsOutput represents the JSON output sent to the host. -type CountVowelsOuptut struct { +type CountVowelsOutput struct { Count int `json:"count"` Total int `json:"total"` Vowels string `json:"vowels"` @@ -35,7 +35,7 @@ func countVowelsTyped() int32 { //export count_vowels_json_output func countVowelsJSONOutput() int32 { - output := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + output := CountVowelsOutput{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} err := pdk.OutputJSON(output) if err != nil { pdk.SetError(err) @@ -46,7 +46,7 @@ func countVowelsJSONOutput() int32 { //export count_vowels_roundtrip_json_mem func countVowelsJSONRoundtripMem() int32 { - a := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + a := CountVowelsOutput{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} mem, err := pdk.AllocateJSON(&a) if err != nil { pdk.SetError(err) @@ -54,7 +54,7 @@ func countVowelsJSONRoundtripMem() int32 { } // find the data in mem and ensure it's the same once decoded - var b CountVowelsOuptut + var b CountVowelsOutput err = pdk.JSONFrom(mem.Offset(), &b) if err != nil { pdk.SetError(err) @@ -79,7 +79,6 @@ func countVowels() int32 { switch a { case 'A', 'I', 'E', 'O', 'U', 'a', 'e', 'i', 'o', 'u': count++ - default: } } diff --git a/example/http/std_main.go b/example/http/std_main.go index d98e42e..ce73c04 100644 --- a/example/http/std_main.go +++ b/example/http/std_main.go @@ -15,7 +15,7 @@ func main() { } func httpGet() int32 { - // create an HTTP Request (withuot relying on WASI), set headers as needed + // create an HTTP Request (without relying on WASI), set headers as needed req := pdk.NewHTTPRequest(pdk.MethodGet, "https://jsonplaceholder.typicode.com/todos/1") req.SetHeader("some-name", "some-value") req.SetHeader("another", "again") diff --git a/extism_pdk.go b/extism_pdk.go index db01838..35dacd5 100644 --- a/extism_pdk.go +++ b/extism_pdk.go @@ -21,11 +21,27 @@ const ( LogError ) +// String returns the string representation of the LogLevel. +func (l LogLevel) String() string { + switch l { + case LogInfo: + return "info" + case LogDebug: + return "debug" + case LogWarn: + return "warn" + case LogError: + return "error" + default: + return "unknown" + } +} + func load(offset extismPointer, buf []byte) { length := len(buf) chunkCount := length >> 3 - for chunkIdx := 0; chunkIdx < chunkCount; chunkIdx++ { + for chunkIdx := range chunkCount { i := chunkIdx << 3 binary.LittleEndian.PutUint64(buf[i:i+8], extismLoadU64(offset+extismPointer(i))) } @@ -43,7 +59,7 @@ func loadInput() []byte { chunkCount := length >> 3 - for chunkIdx := 0; chunkIdx < chunkCount; chunkIdx++ { + for chunkIdx := range chunkCount { i := chunkIdx << 3 binary.LittleEndian.PutUint64(buf[i:i+8], extismInputLoadU64(extismPointer(i))) } @@ -61,7 +77,7 @@ func store(offset extismPointer, buf []byte) { length := len(buf) chunkCount := length >> 3 - for chunkIdx := 0; chunkIdx < chunkCount; chunkIdx++ { + for chunkIdx := range chunkCount { i := chunkIdx << 3 x := binary.LittleEndian.Uint64(buf[i : i+8]) extismStoreU64(offset+extismPointer(i), x) @@ -278,10 +294,7 @@ func SetVarInt(key string, value int) { // TODO: coordinate replacement of call to free based on SDK alignment // defer keyMem.Free() - bytes := make([]byte, 8) - binary.LittleEndian.PutUint64(bytes, uint64(value)) - - valMem := AllocateBytes(bytes) + valMem := AllocateBytes(binary.LittleEndian.AppendUint64(nil, uint64(value))) // TODO: coordinate replacement of call to free based on SDK alignment // defer valMem.Free() diff --git a/go.mod b/go.mod index 6584c24..e748c3f 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/extism/go-pdk -go 1.21.0 +go 1.26.1 + +require github.com/extism/go-pdk/wasi-reactor v0.0.0-20260122165646-35abd9e2ba55 diff --git a/go.sum b/go.sum index e69de29..291f3e5 100644 --- a/go.sum +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/extism/go-pdk/wasi-reactor v0.0.0-20260122165646-35abd9e2ba55 h1:4llAGnP7gEo6719wl4WUocxI4e1kU4G4QP0w25xhZ1Q= +github.com/extism/go-pdk/wasi-reactor v0.0.0-20260122165646-35abd9e2ba55/go.mod h1:WDu1fWWoFToXBPq+vRAnfFROFFdPayxGbiXf8ysq+no= diff --git a/go.work b/go.work index 99b21af..c1ed6d6 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.21.1 +go 1.26.1 use ( . diff --git a/wasi-reactor/go.mod b/wasi-reactor/go.mod index 797bced..4bb1f5c 100644 --- a/wasi-reactor/go.mod +++ b/wasi-reactor/go.mod @@ -1,3 +1,3 @@ module github.com/extism/go-pdk/wasi-reactor -go 1.21.1 +go 1.26.1 From 31dc4bc5cdbc9d5cf15f00e1dec6944b46e9f84c Mon Sep 17 00:00:00 2001 From: "corda.ilaria@gmail.com" Date: Mon, 6 Apr 2026 01:19:37 +0200 Subject: [PATCH 2/6] fix tiny.go compliance --- .github/actions/libextism/action.yml | 2 +- .github/workflows/ci.yml | 4 ++-- example/http/tiny_main.go | 2 +- go.mod | 4 +--- go.sum | 2 -- go.work | 2 +- wasi-reactor/go.mod | 2 +- 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/actions/libextism/action.yml b/.github/actions/libextism/action.yml index f04b74f..db5ec1a 100644 --- a/.github/actions/libextism/action.yml +++ b/.github/actions/libextism/action.yml @@ -17,4 +17,4 @@ runs: - uses: ./.extism-cli/.github/actions/extism-cli - name: Install shell: bash - run: sudo extism lib install --version git --github-token "${{ inputs.token }}" + run: sudo extism lib install --version v1.21.0 --github-token "${{ inputs.token }}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fb2337..5130f15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,10 +20,10 @@ jobs: - run: cp go-pdk/go.sum . # Needed to get setup-go to work - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: cache: true - go-version: '1.21.3' + go-version: '1.23.0' - name: Install TinyGo uses: acifani/setup-tinygo@v1.1.0 diff --git a/example/http/tiny_main.go b/example/http/tiny_main.go index f1e205f..0b05bb7 100644 --- a/example/http/tiny_main.go +++ b/example/http/tiny_main.go @@ -9,7 +9,7 @@ import ( //go:wasmexport http_get func httpGet() int32 { - // create an HTTP Request (withuot relying on WASI), set headers as needed + // create an HTTP Request (without relying on WASI), set headers as needed req := pdk.NewHTTPRequest(pdk.MethodGet, "https://jsonplaceholder.typicode.com/todos/1") req.SetHeader("some-name", "some-value") req.SetHeader("another", "again") diff --git a/go.mod b/go.mod index e748c3f..f212d68 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,3 @@ module github.com/extism/go-pdk -go 1.26.1 - -require github.com/extism/go-pdk/wasi-reactor v0.0.0-20260122165646-35abd9e2ba55 +go 1.23.0 diff --git a/go.sum b/go.sum index 291f3e5..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +0,0 @@ -github.com/extism/go-pdk/wasi-reactor v0.0.0-20260122165646-35abd9e2ba55 h1:4llAGnP7gEo6719wl4WUocxI4e1kU4G4QP0w25xhZ1Q= -github.com/extism/go-pdk/wasi-reactor v0.0.0-20260122165646-35abd9e2ba55/go.mod h1:WDu1fWWoFToXBPq+vRAnfFROFFdPayxGbiXf8ysq+no= diff --git a/go.work b/go.work index c1ed6d6..c37c14a 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.26.1 +go 1.23.0 use ( . diff --git a/wasi-reactor/go.mod b/wasi-reactor/go.mod index 4bb1f5c..84de416 100644 --- a/wasi-reactor/go.mod +++ b/wasi-reactor/go.mod @@ -1,3 +1,3 @@ module github.com/extism/go-pdk/wasi-reactor -go 1.26.1 +go 1.23.0 From 83d5c1a973fa4495a7ed752181a0e01bc908ceac Mon Sep 17 00:00:00 2001 From: "corda.ilaria@gmail.com" Date: Mon, 6 Apr 2026 01:49:27 +0200 Subject: [PATCH 3/6] fix more issues --- extism_pdk.go | 70 ++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/extism_pdk.go b/extism_pdk.go index 0fd6a03..e25572b 100644 --- a/extism_pdk.go +++ b/extism_pdk.go @@ -32,10 +32,12 @@ const ( // String returns the string representation of the LogLevel. func (l LogLevel) String() string { switch l { - case LogInfo: - return "info" + case LogTrace: + return "trace" case LogDebug: return "debug" + case LogInfo: + return "info" case LogWarn: return "warn" case LogError: @@ -44,6 +46,7 @@ func (l LogLevel) String() string { return "unknown" } } + func loadInput() []byte { length := int(extismInputLength()) buf := make([]byte, length) @@ -76,7 +79,7 @@ func JSONFrom(offset uint64, v any) error { return json.Unmarshal(mem.ReadBytes(), v) } -// InputJSON returns unmartialed JSON data from the host "input". +// InputJSON returns unmarshaled JSON data from the host "input". func InputJSON(v any) error { return json.Unmarshal(Input(), v) } @@ -131,10 +134,8 @@ func OutputMemory(mem Memory) { // Output sends the `data` slice of bytes to the host output. func Output(data []byte) { - clength := uint64(len(data)) m := memory.AllocateBytes(data) - - extismOutputSet(memory.ExtismPointer(m.Offset()), clength) + extismOutputSet(memory.ExtismPointer(m.Offset()), m.Length()) // TODO: coordinate replacement of call to free based on SDK alignment // extismFree(offset) } @@ -159,7 +160,7 @@ func SetErrorString(err string) { // GetConfig returns the config string associated with `key` (if any). func GetConfig(key string) (string, bool) { - mem := AllocateBytes([]byte(key)) + mem := AllocateString(key) defer mem.Free() offset := extismConfigGet(memory.ExtismPointer(mem.Offset())) @@ -205,7 +206,7 @@ func Log(level LogLevel, s string) { // GetVar returns the byte slice (if any) associated with `key`. func GetVar(key string) []byte { - mem := AllocateBytes([]byte(key)) + mem := AllocateString(key) defer mem.Free() offset := extismVarGet(memory.ExtismPointer(mem.Offset())) @@ -222,7 +223,7 @@ func GetVar(key string) []byte { // SetVar sets the host variable associated with `key` to the `value` byte slice. func SetVar(key string, value []byte) { - keyMem := AllocateBytes([]byte(key)) + keyMem := AllocateString(key) // TODO: coordinate replacement of call to free based on SDK alignment // defer keyMem.Free() @@ -238,7 +239,7 @@ func SetVar(key string, value []byte) { // GetVarInt returns the int associated with `key` (or 0 if none). func GetVarInt(key string) int { - mem := AllocateBytes([]byte(key)) + mem := AllocateString(key) defer mem.Free() offset := extismVarGet(memory.ExtismPointer(mem.Offset())) @@ -255,7 +256,7 @@ func GetVarInt(key string) int { // SetVarInt sets the host variable associated with `key` to the `value` int. func SetVarInt(key string, value int) { - keyMem := AllocateBytes([]byte(key)) + keyMem := AllocateString(key) // TODO: coordinate replacement of call to free based on SDK alignment // defer keyMem.Free() @@ -271,7 +272,7 @@ func SetVarInt(key string, value int) { // RemoveVar removes (and frees) the host variable associated with `key`. func RemoveVar(key string) { - mem := AllocateBytes([]byte(key)) + mem := AllocateString(key) // TODO: coordinate replacement of call to free based on SDK alignment // defer mem.Free() extismVarSet(memory.ExtismPointer(mem.Offset()), 0) @@ -298,12 +299,12 @@ type HTTPResponse struct { } // Memory returns the memory associated with the `HTTPResponse`. -func (r HTTPResponse) Memory() Memory { +func (r *HTTPResponse) Memory() Memory { return r.memory } // Body returns the body byte slice (if any) from the `HTTPResponse`. -func (r HTTPResponse) Body() []byte { +func (r *HTTPResponse) Body() []byte { if r.memory.Length() == 0 { return nil } @@ -314,7 +315,7 @@ func (r HTTPResponse) Body() []byte { } // Status returns the status code from the `HTTPResponse`. -func (r HTTPResponse) Status() uint16 { +func (r *HTTPResponse) Status() uint16 { return r.status } @@ -371,15 +372,11 @@ func NewHTTPRequest(method HTTPMethod, url string) *HTTPRequest { Headers: map[string]string{}, Method: method.String(), }, - body: nil, } } // SetHeader sets an HTTP header `key` to `value`. -func (r *HTTPRequest) SetHeader(key string, value string) *HTTPRequest { - if r.meta.Headers == nil { - r.meta.Headers = make(map[string]string) - } +func (r *HTTPRequest) SetHeader(key, value string) *HTTPRequest { r.meta.Headers[key] = value return r } @@ -391,8 +388,11 @@ func (r *HTTPRequest) SetBody(body []byte) *HTTPRequest { } // Send sends the `HTTPRequest` from the host and returns the `HTTPResponse`. -func (r *HTTPRequest) Send() HTTPResponse { - enc, _ := json.Marshal(r.meta) +func (r *HTTPRequest) Send() (HTTPResponse, error) { + enc, err := json.Marshal(r.meta) + if err != nil { + return HTTPResponse{}, err + } req := AllocateBytes(enc) defer req.Free() @@ -411,22 +411,24 @@ func (r *HTTPRequest) Send() HTTPResponse { status := uint16(http.ExtismHTTPStatusCode()) headersOffs := http.ExtismHTTPHeaders() - headers := map[string]string{} + headers := make(map[string]string) if headersOffs != 0 { - length := memory.ExtismLengthUnsafe(headersOffs) - mem := memory.NewMemory(headersOffs, length) - defer mem.Free() - json.Unmarshal(mem.ReadBytes(), &headers) + hdrLength := memory.ExtismLengthUnsafe(headersOffs) + hdrMem := memory.NewMemory(headersOffs, hdrLength) + defer hdrMem.Free() + if err := json.Unmarshal(hdrMem.ReadBytes(), &headers); err != nil { + return HTTPResponse{}, err + } } - memory := memory.NewMemory(offset, length) + mem := memory.NewMemory(offset, length) return HTTPResponse{ - memory, - status, - headers, - } + memory: mem, + status: status, + headers: headers, + }, nil } // FindMemory finds the host memory block at the given `offset`. @@ -473,12 +475,12 @@ func ResultString(s string) uint64 { // ResultU32 allocates a uint32 and returns the offset in Extism host memory. func ResultU32(d uint32) uint64 { - mem := AllocateBytes(binary.LittleEndian.AppendUint32([]byte{}, d)) + mem := AllocateBytes(binary.LittleEndian.AppendUint32(nil, d)) return mem.Offset() } // ResultU64 allocates a uint64 and returns the offset in Extism host memory. func ResultU64(d uint64) uint64 { - mem := AllocateBytes(binary.LittleEndian.AppendUint64([]byte{}, d)) + mem := AllocateBytes(binary.LittleEndian.AppendUint64(nil, d)) return mem.Offset() } From 697cf17230e0de727fd2633429c4420ce98db28d Mon Sep 17 00:00:00 2001 From: "corda.ilaria@gmail.com" Date: Mon, 6 Apr 2026 01:52:42 +0200 Subject: [PATCH 4/6] fix more issues --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5130f15..78898d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,13 +17,11 @@ jobs: - uses: ./go-pdk/.github/actions/libextism with: token: ${{ secrets.GITHUB_TOKEN }} - - run: cp go-pdk/go.sum . # Needed to get setup-go to work - - name: Install Go uses: actions/setup-go@v4 with: - cache: true go-version: '1.23.0' + cache-dependency-path: go-pdk/go.sum - name: Install TinyGo uses: acifani/setup-tinygo@v1.1.0 From 4be96570f105283fa6ad9f30f12da0a0a711a636 Mon Sep 17 00:00:00 2001 From: "corda.ilaria@gmail.com" Date: Mon, 6 Apr 2026 01:56:07 +0200 Subject: [PATCH 5/6] fix more issues --- example/http/tiny_main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/http/tiny_main.go b/example/http/tiny_main.go index 0b05bb7..12cb875 100644 --- a/example/http/tiny_main.go +++ b/example/http/tiny_main.go @@ -14,7 +14,7 @@ func httpGet() int32 { req.SetHeader("some-name", "some-value") req.SetHeader("another", "again") // send the request, get response back (can check status on response via res.Status()) - res := req.Send() + res, _ := req.Send() // zero-copy output to host pdk.OutputMemory(res.Memory()) From 8956492b9a5e71dc143bc7b2955995a2347b61fd Mon Sep 17 00:00:00 2001 From: "corda.ilaria@gmail.com" Date: Mon, 6 Apr 2026 01:59:35 +0200 Subject: [PATCH 6/6] fix more issues --- example/http/std_main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/http/std_main.go b/example/http/std_main.go index ce73c04..981ffbf 100644 --- a/example/http/std_main.go +++ b/example/http/std_main.go @@ -20,7 +20,7 @@ func httpGet() int32 { req.SetHeader("some-name", "some-value") req.SetHeader("another", "again") // send the request, get response back (can check status on response via res.Status()) - res := req.Send() + res, _ := req.Send() // zero-copy output to host pdk.OutputMemory(res.Memory())