Skip to content

Commit ff1c4f6

Browse files
authored
Merge pull request #52 from extism/tinygo-readme
fix: readme/tinygo examples use go:wasmexport/wasmimport, -buildmode=c-shared
2 parents 1502218 + dc2e875 commit ff1c4f6

File tree

5 files changed

+53
-36
lines changed

5 files changed

+53
-36
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
.PHONY: example
22
example:
3-
tinygo build -o example/tiny_countvowels.wasm -target wasi -buildmode c-shared ./example/countvowels
4-
tinygo build -o example/tiny_http.wasm -target wasi -buildmode c-shared ./example/http
5-
tinygo build -o example/tiny_reactor.wasm -target wasi -buildmode c-shared ./example/reactor
3+
tinygo build -o example/tiny_countvowels.wasm -target wasip1 -buildmode c-shared ./example/countvowels
4+
tinygo build -o example/tiny_http.wasm -target wasip1 -buildmode c-shared ./example/http
5+
tinygo build -o example/tiny_reactor.wasm -target wasip1 -buildmode c-shared ./example/reactor
66

77
GOOS=wasip1 GOARCH=wasm go build -tags std -o example/std_countvowels.wasm ./example/countvowels
88
GOOS=wasip1 GOARCH=wasm go build -tags std -o example/std_http.wasm ./example/http

README.md

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,25 @@ import (
3232
"github.com/extism/go-pdk"
3333
)
3434

35-
//export greet
35+
//go:wasmexport greet
3636
func greet() int32 {
3737
input := pdk.Input()
3838
greeting := `Hello, ` + string(input) + `!`
3939
pdk.OutputString(greeting)
4040
return 0
4141
}
42-
43-
func main() {}
4442
```
4543

4644
Some things to note about this code:
4745

48-
1. The `//export greet` comment is required. This marks the greet function as an
46+
1. The `//go:wasmexport greet` comment is required. This marks the greet function as an
4947
export with the name `greet` that can be called by the host.
50-
2. We need a `main` but it is unused.
51-
3. Exports in the Go PDK are coded to the raw ABI. You get parameters from the
48+
2. Exports in the Go PDK are coded to the raw ABI. You get parameters from the
5249
host by calling
5350
[pdk.Input* functions](https://pkg.go.dev/github.com/extism/go-pdk#Input) and
5451
you send returns back with the
5552
[pdk.Output* functions](https://pkg.go.dev/github.com/extism/go-pdk#Output).
56-
4. An Extism export expects an i32 return code. `0` is success and `1` is a
53+
3. An Extism export expects an i32 return code. `0` is success and `1` is a
5754
failure.
5855

5956
Install the `tinygo` compiler:
@@ -68,7 +65,7 @@ platform.
6865
Compile this with the command:
6966

7067
```bash
71-
tinygo build -o plugin.wasm -target wasi main.go
68+
tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared main.go
7269
```
7370

7471
We can now test `plugin.wasm` using the
@@ -79,7 +76,7 @@ extism call plugin.wasm greet --input "Benjamin" --wasi
7976
# => Hello, Benjamin!
8077
```
8178

82-
> **Note**: Currently `wasi` must be provided for all Go plug-ins even if they
79+
> **Note**: Currently `wasip1` must be provided for all Go plug-ins even if they
8380
> don't need system access, however this will eventually be optional.
8481
8582
> **Note**: We also have a web-based, plug-in tester called the
@@ -92,7 +89,7 @@ use [pdk.SetError](https://pkg.go.dev/github.com/extism/go-pdk#SetError) or
9289
[pdk.SetErrorString](https://pkg.go.dev/github.com/extism/go-pdk#SetErrorString):
9390

9491
```go
95-
//export greet
92+
//go:wasmexport greet
9693
func greet() int32 {
9794
name := string(pdk.Input())
9895
if name == "Benjamin" {
@@ -110,6 +107,7 @@ Now when we try again:
110107
```bash
111108
extism call plugin.wasm greet --input="Benjamin" --wasi
112109
# => Error: Sorry, we don't greet Benjamins!
110+
# => returned non-zero exit code: 1
113111
echo $? # print last status code
114112
# => 1
115113
extism call plugin.wasm greet --input="Zach" --wasi
@@ -134,7 +132,7 @@ type Sum struct {
134132
Sum int `json:"sum"`
135133
}
136134

137-
//export add
135+
//go:wasmexport add
138136
func add() int32 {
139137
params := Add{}
140138
// use json input helper, which automatically unmarshals the plugin input into your struct
@@ -145,7 +143,7 @@ func add() int32 {
145143
}
146144
sum := Sum{Sum: params.A + params.B}
147145
// use json output helper, which automatically marshals your struct to the plugin output
148-
output, err := pdk.OutputJSON(sum)
146+
_, err := pdk.OutputJSON(sum)
149147
if err != nil {
150148
pdk.SetError(err)
151149
return 1
@@ -167,7 +165,7 @@ that exists across every function call. Here is a trivial example using
167165
[pdk.GetConfig](https://pkg.go.dev/github.com/extism/go-pdk#GetConfig):
168166

169167
```go
170-
//export greet
168+
//go:wasmexport greet
171169
func greet() int32 {
172170
user, ok := pdk.GetConfig("user")
173171
if !ok {
@@ -195,7 +193,7 @@ will persist across function calls. These variables will persist as long as the
195193
host has loaded and not freed the plug-in.
196194

197195
```go
198-
//export count
196+
//go:wasmexport count
199197
func count() int32 {
200198
count := pdk.GetVarInt("count")
201199
count = count + 1
@@ -220,7 +218,7 @@ you to use the host application to log without having to give the plug-in
220218
permission to make syscalls.
221219

222220
```go
223-
//export log_stuff
221+
//go:wasmexport log_stuff
224222
func logStuff() int32 {
225223
pdk.Log(pdk.LogInfo, "An info log!")
226224
pdk.Log(pdk.LogDebug, "A debug log!")
@@ -252,7 +250,7 @@ Sometimes it is useful to let a plug-in
252250
[See this example](example/http/tiny_main.go)
253251

254252
```go
255-
//export http_get
253+
//go:wasmexport http_get
256254
func httpGet() int32 {
257255
// create an HTTP Request (withuot relying on WASI), set headers as needed
258256
req := pdk.NewHTTPRequest(pdk.MethodGet, "https://jsonplaceholder.typicode.com/todos/1")
@@ -304,7 +302,7 @@ We should be able to call this function as a normal Go function. Note that we
304302
need to manually handle the pointer casting:
305303

306304
```go
307-
//export hello_from_python
305+
//go:wasmexport hello_from_python
308306
func helloFromPython() int32 {
309307
msg := "An argument to send to Python"
310308
mem := pdk.AllocateString(msg)
@@ -356,11 +354,29 @@ python3 app.py
356354

357355
## Reactor modules
358356

359-
Since TinyGo doesn't support
360-
[Reactor modules](https://dylibso.com/blog/wasi-command-reactor/) yet, If you
361-
want to use WASI inside your Reactor module functions (exported functions other
362-
than `main`), you'll need to import `wasi-reactor` module which makes sure libc
363-
and go runtime are properly initialized:
357+
Since TinyGo version 0.34.0, the compiler has native support for
358+
[Reactor modules](https://dylibso.com/blog/wasi-command-reactor/).
359+
360+
Make sure you invoke the compiler with the `-buildmode=c-shared` flag
361+
so that libc and the Go runtime are properly initialized:
362+
363+
```bash
364+
cd example/reactor
365+
tinygo build -target wasip1 -buildmode=c-shared -o reactor.wasm ./tiny_main.go
366+
extism call ./reactor.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info
367+
# => Hello World!
368+
```
369+
370+
### Note on TinyGo 0.33.0 and earlier
371+
372+
TinyGo versions below 0.34.0 do not support
373+
[Reactor modules](https://dylibso.com/blog/wasi-command-reactor/).
374+
If you want to use WASI inside your Reactor module functions (exported functions other
375+
than `main`). You can however import the `wasi-reactor` module to ensure that libc
376+
and go runtime are initialized as expected:
377+
378+
Moreover, older versions may not provide the special `//go:wasmexport`
379+
directive, and instead use `//export`.
364380

365381
```go
366382
package main
@@ -389,7 +405,7 @@ func main() {}
389405
```
390406

391407
```bash
392-
tinygo build -target wasi -o reactor.wasm .\tiny_main.go
408+
tinygo build -target wasip1 -o reactor.wasm ./tiny_main.go
393409
extism call ./reactor.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info
394410
# => Hello World!
395411
```

example/countvowels/tiny_main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type CountVowelsOuptut struct {
2121
Vowels string `json:"vowels"`
2222
}
2323

24-
//export count_vowels_typed
24+
//go:wasmexport count_vowels_typed
2525
func countVowelsTyped() int32 {
2626
var input CountVowelsInput
2727
if err := pdk.InputJSON(&input); err != nil {
@@ -33,7 +33,7 @@ func countVowelsTyped() int32 {
3333
return 0
3434
}
3535

36-
//export count_vowels_json_output
36+
//go:wasmexport count_vowels_json_output
3737
func countVowelsJSONOutput() int32 {
3838
output := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"}
3939
err := pdk.OutputJSON(output)
@@ -44,7 +44,7 @@ func countVowelsJSONOutput() int32 {
4444
return 0
4545
}
4646

47-
//export count_vowels_roundtrip_json_mem
47+
//go:wasmexport count_vowels_roundtrip_json_mem
4848
func countVowelsJSONRoundtripMem() int32 {
4949
a := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"}
5050
mem, err := pdk.AllocateJSON(&a)

example/http/tiny_main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/extism/go-pdk"
88
)
99

10-
//export http_get
10+
//go:wasmexport http_get
1111
func httpGet() int32 {
1212
// create an HTTP Request (withuot relying on WASI), set headers as needed
1313
req := pdk.NewHTTPRequest(pdk.MethodGet, "https://jsonplaceholder.typicode.com/todos/1")
@@ -21,4 +21,3 @@ func httpGet() int32 {
2121

2222
return 0
2323
}
24-

example/reactor/README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
## Reactor module example
2-
By including this package, you'll turn your plugin into a [Reactor](https://dylibso.com/blog/wasi-command-reactor/) module. This makes sure that you can use WASI (e.g. File Access) in your exported functions.
2+
By including this package, you'll turn your plugin into a [Reactor](https://dylibso.com/blog/wasi-command-reactor/) module.
3+
This makes sure that you can use WASI (e.g. File Access) in your exported functions.
34

4-
To test this example, run:
5+
This is only required for TinyGo versions below 0.34.0 where native support for reactort-style modules
6+
was missing.To test this example, run:
57

68
```bash
7-
tinygo build -target wasi -o reactor.wasm .\tiny_main.go
9+
tinygo build -target wasi -o reactor.wasm ./tiny_main.go
810
extism call ./reactor.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info
911
# => Hello World!
1012
```
1113

1214
If you don't include the pacakge, you'll see this output:
1315
```bash
14-
extism call .\c.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info
16+
extism call ./c.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info
1517
# => 2024/01/18 20:48:48 open ./test.txt: errno 76
16-
```
18+
```

0 commit comments

Comments
 (0)