Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/libextism/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"
8 changes: 3 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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@v3
uses: actions/setup-go@v4
with:
cache: true
go-version: '1.21.3'
go-version: '1.23.0'
cache-dependency-path: go-pdk/go.sum

- name: Install TinyGo
uses: acifani/setup-tinygo@v1.1.0
Expand Down
9 changes: 4 additions & 5 deletions example/countvowels/std_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -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)
Expand All @@ -57,15 +57,15 @@ 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)
return -1
}

// 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)
Expand All @@ -89,7 +89,6 @@ func countVowels() int32 {
switch a {
case 'A', 'I', 'E', 'O', 'U', 'a', 'e', 'i', 'o', 'u':
count++
default:
}
}

Expand Down
9 changes: 4 additions & 5 deletions example/countvowels/tiny_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -35,7 +35,7 @@ func countVowelsTyped() int32 {

//go:wasmexport 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)
Expand All @@ -46,15 +46,15 @@ func countVowelsJSONOutput() int32 {

//go:wasmexport 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)
return -1
}

// 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)
Expand All @@ -79,7 +79,6 @@ func countVowels() int32 {
switch a {
case 'A', 'I', 'E', 'O', 'U', 'a', 'e', 'i', 'o', 'u':
count++
default:
}
}

Expand Down
4 changes: 2 additions & 2 deletions example/http/std_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ 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")
// 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())
Expand Down
4 changes: 2 additions & 2 deletions example/http/tiny_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ 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")
// 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())
Expand Down
88 changes: 51 additions & 37 deletions extism_pdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,31 @@ const (
LogError
)

// String returns the string representation of the LogLevel.
func (l LogLevel) String() string {
switch l {
case LogTrace:
return "trace"
case LogDebug:
return "debug"
case LogInfo:
return "info"
case LogWarn:
return "warn"
case LogError:
return "error"
default:
return "unknown"
}
}

func loadInput() []byte {
length := int(extismInputLength())
buf := make([]byte, length)

chunkCount := length >> 3

for chunkIdx := 0; chunkIdx < chunkCount; chunkIdx++ {
for chunkIdx := range chunkCount {
i := chunkIdx << 3
binary.LittleEndian.PutUint64(buf[i:i+8], extismInputLoadU64(memory.ExtismPointer(i)))
}
Expand All @@ -61,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)
}
Expand Down Expand Up @@ -116,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)
}
Expand All @@ -144,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()))
Expand Down Expand Up @@ -190,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()))
Expand All @@ -207,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()

Expand All @@ -223,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()))
Expand All @@ -240,14 +256,11 @@ 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()

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()

Expand All @@ -259,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)
Expand All @@ -286,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
}
Expand All @@ -302,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
}

Expand Down Expand Up @@ -359,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
}
Expand All @@ -379,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()
Expand All @@ -399,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`.
Expand Down Expand Up @@ -461,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()
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/extism/go-pdk

go 1.21.0
go 1.23.0
2 changes: 1 addition & 1 deletion go.work
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
go 1.21.1
go 1.23.0

use (
.
Expand Down
2 changes: 1 addition & 1 deletion wasi-reactor/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/extism/go-pdk/wasi-reactor

go 1.21.1
go 1.23.0
Loading