diff --git a/examples/helloworld/greeting/greet.pb.go b/examples/helloworld/greeting/greet.pb.go index abe93e5..6682544 100644 --- a/examples/helloworld/greeting/greet.pb.go +++ b/examples/helloworld/greeting/greet.pb.go @@ -63,5 +63,5 @@ func (x *GreetReply) GetMessage() string { // go:plugin type=plugin version=1 type Greeter interface { // Sends a greeting - Greet(context.Context, GreetRequest) (GreetReply, error) + Greet(context.Context, *GreetRequest) (*GreetReply, error) } diff --git a/examples/helloworld/greeting/greet_host.pb.go b/examples/helloworld/greeting/greet_host.pb.go index 9682e43..6a1de77 100644 --- a/examples/helloworld/greeting/greet_host.pb.go +++ b/examples/helloworld/greeting/greet_host.pb.go @@ -129,10 +129,10 @@ type greeterPlugin struct { greet api.Function } -func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (response GreetReply, err error) { +func (p *greeterPlugin) Greet(ctx context.Context, request *GreetRequest) (*GreetReply, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -141,7 +141,7 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -150,13 +150,13 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.greet.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -171,16 +171,17 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(GreetReply) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/examples/helloworld/greeting/greet_plugin.pb.go b/examples/helloworld/greeting/greet_plugin.pb.go index bfe4fb0..affd2cb 100644 --- a/examples/helloworld/greeting/greet_plugin.pb.go +++ b/examples/helloworld/greeting/greet_plugin.pb.go @@ -29,7 +29,7 @@ func RegisterGreeter(p Greeter) { //export greeter_greet func _greeter_greet(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req GreetRequest + req := new(GreetRequest) if err := req.UnmarshalVT(b); err != nil { return 0 } diff --git a/examples/helloworld/main.go b/examples/helloworld/main.go index 705f7d9..f2458ce 100644 --- a/examples/helloworld/main.go +++ b/examples/helloworld/main.go @@ -33,7 +33,7 @@ func run() error { } defer eveningPlugin.Close(ctx) - reply, err := morningPlugin.Greet(ctx, greeting.GreetRequest{ + reply, err := morningPlugin.Greet(ctx, &greeting.GreetRequest{ Name: "go-plugin", }) if err != nil { @@ -42,7 +42,7 @@ func run() error { fmt.Println(reply.GetMessage()) - reply, err = eveningPlugin.Greet(ctx, greeting.GreetRequest{ + reply, err = eveningPlugin.Greet(ctx, &greeting.GreetRequest{ Name: "go-plugin", }) if err != nil { diff --git a/examples/helloworld/plugin-evening/evening.go b/examples/helloworld/plugin-evening/evening.go index e3ac7c0..6fe12e1 100644 --- a/examples/helloworld/plugin-evening/evening.go +++ b/examples/helloworld/plugin-evening/evening.go @@ -18,8 +18,8 @@ type GoodEvening struct{} var _ greeting.Greeter = (*GoodEvening)(nil) -func (m GoodEvening) Greet(_ context.Context, request greeting.GreetRequest) (greeting.GreetReply, error) { - return greeting.GreetReply{ +func (m GoodEvening) Greet(_ context.Context, request *greeting.GreetRequest) (*greeting.GreetReply, error) { + return &greeting.GreetReply{ Message: fmt.Sprintf("Good evening, %s", request.GetName()), }, nil } diff --git a/examples/helloworld/plugin-morning/morning.go b/examples/helloworld/plugin-morning/morning.go index c053b18..872034f 100644 --- a/examples/helloworld/plugin-morning/morning.go +++ b/examples/helloworld/plugin-morning/morning.go @@ -17,8 +17,8 @@ type GoodMorning struct{} var _ greeting.Greeter = (*GoodMorning)(nil) -func (m GoodMorning) Greet(ctx context.Context, request greeting.GreetRequest) (greeting.GreetReply, error) { - return greeting.GreetReply{ +func (m GoodMorning) Greet(_ context.Context, request *greeting.GreetRequest) (*greeting.GreetReply, error) { + return &greeting.GreetReply{ Message: "Good morning, " + request.GetName(), }, nil } diff --git a/examples/host-functions/greeting/greet.pb.go b/examples/host-functions/greeting/greet.pb.go index 83a38c1..7faf961 100644 --- a/examples/host-functions/greeting/greet.pb.go +++ b/examples/host-functions/greeting/greet.pb.go @@ -121,14 +121,14 @@ func (x *LogRequest) GetMessage() string { // go:plugin type=plugin version=1 type Greeter interface { // Sends a greeting - Greet(context.Context, GreetRequest) (GreetReply, error) + Greet(context.Context, *GreetRequest) (*GreetReply, error) } // The host functions embedded into the plugin // go:plugin type=host type HostFunctions interface { // Sends a HTTP GET request - HttpGet(context.Context, HttpGetRequest) (HttpGetResponse, error) + HttpGet(context.Context, *HttpGetRequest) (*HttpGetResponse, error) // Shows a log message - Log(context.Context, LogRequest) (emptypb.Empty, error) + Log(context.Context, *LogRequest) (*emptypb.Empty, error) } diff --git a/examples/host-functions/greeting/greet_host.pb.go b/examples/host-functions/greeting/greet_host.pb.go index ebf3ebd..9d39346 100644 --- a/examples/host-functions/greeting/greet_host.pb.go +++ b/examples/host-functions/greeting/greet_host.pb.go @@ -54,7 +54,7 @@ func (h _hostFunctions) _HttpGet(ctx context.Context, m api.Module, stack []uint if err != nil { panic(err) } - var request HttpGetRequest + request := new(HttpGetRequest) err = request.UnmarshalVT(buf) if err != nil { panic(err) @@ -83,7 +83,7 @@ func (h _hostFunctions) _Log(ctx context.Context, m api.Module, stack []uint64) if err != nil { panic(err) } - var request LogRequest + request := new(LogRequest) err = request.UnmarshalVT(buf) if err != nil { panic(err) @@ -221,10 +221,10 @@ type greeterPlugin struct { greet api.Function } -func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (response GreetReply, err error) { +func (p *greeterPlugin) Greet(ctx context.Context, request *GreetRequest) (*GreetReply, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -233,7 +233,7 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -242,13 +242,13 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.greet.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -263,16 +263,17 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(GreetReply) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/examples/host-functions/greeting/greet_plugin.pb.go b/examples/host-functions/greeting/greet_plugin.pb.go index 67a05d7..dadb0c1 100644 --- a/examples/host-functions/greeting/greet_plugin.pb.go +++ b/examples/host-functions/greeting/greet_plugin.pb.go @@ -31,7 +31,7 @@ func RegisterGreeter(p Greeter) { //export greeter_greet func _greeter_greet(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req GreetRequest + req := new(GreetRequest) if err := req.UnmarshalVT(b); err != nil { return 0 } @@ -63,10 +63,10 @@ func NewHostFunctions() HostFunctions { //go:linkname _http_get func _http_get(ptr uint32, size uint32) uint64 -func (h hostFunctions) HttpGet(ctx context.Context, request HttpGetRequest) (response HttpGetResponse, err error) { +func (h hostFunctions) HttpGet(ctx context.Context, request *HttpGetRequest) (*HttpGetResponse, error) { buf, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } ptr, size := wasm.ByteToPtr(buf) ptrSize := _http_get(ptr, size) @@ -75,8 +75,9 @@ func (h hostFunctions) HttpGet(ctx context.Context, request HttpGetRequest) (res size = uint32(ptrSize) buf = wasm.PtrToByte(ptr, size) + response := new(HttpGetResponse) if err = response.UnmarshalVT(buf); err != nil { - return response, err + return nil, err } return response, nil } @@ -86,10 +87,10 @@ func (h hostFunctions) HttpGet(ctx context.Context, request HttpGetRequest) (res //go:linkname _log func _log(ptr uint32, size uint32) uint64 -func (h hostFunctions) Log(ctx context.Context, request LogRequest) (response emptypb.Empty, err error) { +func (h hostFunctions) Log(ctx context.Context, request *LogRequest) (*emptypb.Empty, error) { buf, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } ptr, size := wasm.ByteToPtr(buf) ptrSize := _log(ptr, size) @@ -98,8 +99,9 @@ func (h hostFunctions) Log(ctx context.Context, request LogRequest) (response em size = uint32(ptrSize) buf = wasm.PtrToByte(ptr, size) + response := new(emptypb.Empty) if err = response.UnmarshalVT(buf); err != nil { - return response, err + return nil, err } return response, nil } diff --git a/examples/host-functions/main.go b/examples/host-functions/main.go index e6dfda1..7aa555d 100644 --- a/examples/host-functions/main.go +++ b/examples/host-functions/main.go @@ -31,7 +31,7 @@ func run() error { } defer greetingPlugin.Close(ctx) - reply, err := greetingPlugin.Greet(ctx, greeting.GreetRequest{ + reply, err := greetingPlugin.Greet(ctx, &greeting.GreetRequest{ Name: "go-plugin", }) if err != nil { @@ -49,24 +49,24 @@ type myHostFunctions struct{} var _ greeting.HostFunctions = (*myHostFunctions)(nil) // HttpGet is embedded into the plugin and can be called by the plugin. -func (myHostFunctions) HttpGet(ctx context.Context, request greeting.HttpGetRequest) (greeting.HttpGetResponse, error) { +func (myHostFunctions) HttpGet(_ context.Context, request *greeting.HttpGetRequest) (*greeting.HttpGetResponse, error) { resp, err := http.Get(request.Url) if err != nil { - return greeting.HttpGetResponse{}, err + return nil, err } defer resp.Body.Close() buf, err := io.ReadAll(resp.Body) if err != nil { - return greeting.HttpGetResponse{}, err + return nil, err } - return greeting.HttpGetResponse{Response: buf}, nil + return &greeting.HttpGetResponse{Response: buf}, nil } // Log is embedded into the plugin and can be called by the plugin. -func (myHostFunctions) Log(ctx context.Context, request greeting.LogRequest) (emptypb.Empty, error) { +func (myHostFunctions) Log(_ context.Context, request *greeting.LogRequest) (*emptypb.Empty, error) { // Use the host logger log.Println(request.GetMessage()) - return emptypb.Empty{}, nil + return &emptypb.Empty{}, nil } diff --git a/examples/host-functions/plugin/plugin.go b/examples/host-functions/plugin/plugin.go index c963850..2b85423 100644 --- a/examples/host-functions/plugin/plugin.go +++ b/examples/host-functions/plugin/plugin.go @@ -17,21 +17,21 @@ type GreetingPlugin struct{} var _ greeting.Greeter = (*GreetingPlugin)(nil) -func (m GreetingPlugin) Greet(ctx context.Context, request greeting.GreetRequest) (greeting.GreetReply, error) { +func (m GreetingPlugin) Greet(ctx context.Context, request *greeting.GreetRequest) (*greeting.GreetReply, error) { hostFunctions := greeting.NewHostFunctions() // Logging via the host function - hostFunctions.Log(ctx, greeting.LogRequest{ + hostFunctions.Log(ctx, &greeting.LogRequest{ Message: "Sending a HTTP request...", }) // HTTP GET via the host function - resp, err := hostFunctions.HttpGet(ctx, greeting.HttpGetRequest{Url: "http://ifconfig.me"}) + resp, err := hostFunctions.HttpGet(ctx, &greeting.HttpGetRequest{Url: "http://ifconfig.me"}) if err != nil { - return greeting.GreetReply{}, err + return nil, err } - return greeting.GreetReply{ + return &greeting.GreetReply{ Message: "Hello, " + request.GetName() + " from " + string(resp.Response), }, nil } diff --git a/examples/known-types/known/known.pb.go b/examples/known-types/known/known.pb.go index e4d1cd5..fc70393 100644 --- a/examples/known-types/known/known.pb.go +++ b/examples/known-types/known/known.pb.go @@ -79,5 +79,5 @@ func (x *DiffReply) GetDuration() *durationpb.Duration { // The greeting service definition. // go:plugin type=plugin type WellKnown interface { - Diff(context.Context, DiffRequest) (DiffReply, error) + Diff(context.Context, *DiffRequest) (*DiffReply, error) } diff --git a/examples/known-types/known/known_host.pb.go b/examples/known-types/known/known_host.pb.go index 99f480d..ec730fc 100644 --- a/examples/known-types/known/known_host.pb.go +++ b/examples/known-types/known/known_host.pb.go @@ -129,10 +129,10 @@ type wellKnownPlugin struct { diff api.Function } -func (p *wellKnownPlugin) Diff(ctx context.Context, request DiffRequest) (response DiffReply, err error) { +func (p *wellKnownPlugin) Diff(ctx context.Context, request *DiffRequest) (*DiffReply, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -141,7 +141,7 @@ func (p *wellKnownPlugin) Diff(ctx context.Context, request DiffRequest) (respon if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -150,13 +150,13 @@ func (p *wellKnownPlugin) Diff(ctx context.Context, request DiffRequest) (respon // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.diff.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -171,16 +171,17 @@ func (p *wellKnownPlugin) Diff(ctx context.Context, request DiffRequest) (respon // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(DiffReply) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/examples/known-types/known/known_plugin.pb.go b/examples/known-types/known/known_plugin.pb.go index 27bc7b3..f13389b 100644 --- a/examples/known-types/known/known_plugin.pb.go +++ b/examples/known-types/known/known_plugin.pb.go @@ -29,7 +29,7 @@ func RegisterWellKnown(p WellKnown) { //export well_known_diff func _well_known_diff(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req DiffRequest + req := new(DiffRequest) if err := req.UnmarshalVT(b); err != nil { return 0 } diff --git a/examples/known-types/main.go b/examples/known-types/main.go index 9ebb546..0630605 100644 --- a/examples/known-types/main.go +++ b/examples/known-types/main.go @@ -44,7 +44,7 @@ func run() error { start := timestamppb.Now() end := timestamppb.New(start.AsTime().Add(1 * time.Hour)) - reply, err := plugin.Diff(ctx, known.DiffRequest{ + reply, err := plugin.Diff(ctx, &known.DiffRequest{ Value: value, Start: start, End: end, diff --git a/examples/known-types/plugin/plugin.go b/examples/known-types/plugin/plugin.go index 6bff63f..e02fc56 100644 --- a/examples/known-types/plugin/plugin.go +++ b/examples/known-types/plugin/plugin.go @@ -19,13 +19,13 @@ type WellKnownPlugin struct{} var _ known.WellKnown = (*WellKnownPlugin)(nil) -func (p WellKnownPlugin) Diff(_ context.Context, request known.DiffRequest) (known.DiffReply, error) { +func (p WellKnownPlugin) Diff(_ context.Context, request *known.DiffRequest) (*known.DiffReply, error) { value := request.GetValue().AsInterface() if m, ok := value.(map[string]interface{}); ok { fmt.Printf("I love %s\n", m["A"]) fmt.Printf("I love %s\n", m["B"]) } - return known.DiffReply{ + return &known.DiffReply{ Duration: durationpb.New(request.GetEnd().AsTime().Sub(request.GetStart().AsTime())), }, nil } diff --git a/examples/wasi/cat/cat.pb.go b/examples/wasi/cat/cat.pb.go index 768dbe9..4d87d80 100644 --- a/examples/wasi/cat/cat.pb.go +++ b/examples/wasi/cat/cat.pb.go @@ -59,5 +59,5 @@ func (x *FileCatReply) GetContent() string { // go:plugin type=plugin type FileCat interface { - Cat(context.Context, FileCatRequest) (FileCatReply, error) + Cat(context.Context, *FileCatRequest) (*FileCatReply, error) } diff --git a/examples/wasi/cat/cat_host.pb.go b/examples/wasi/cat/cat_host.pb.go index eb4ddc7..653e95c 100644 --- a/examples/wasi/cat/cat_host.pb.go +++ b/examples/wasi/cat/cat_host.pb.go @@ -129,10 +129,10 @@ type fileCatPlugin struct { cat api.Function } -func (p *fileCatPlugin) Cat(ctx context.Context, request FileCatRequest) (response FileCatReply, err error) { +func (p *fileCatPlugin) Cat(ctx context.Context, request *FileCatRequest) (*FileCatReply, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -141,7 +141,7 @@ func (p *fileCatPlugin) Cat(ctx context.Context, request FileCatRequest) (respon if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -150,13 +150,13 @@ func (p *fileCatPlugin) Cat(ctx context.Context, request FileCatRequest) (respon // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.cat.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -171,16 +171,17 @@ func (p *fileCatPlugin) Cat(ctx context.Context, request FileCatRequest) (respon // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(FileCatReply) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/examples/wasi/cat/cat_plugin.pb.go b/examples/wasi/cat/cat_plugin.pb.go index 0cc5852..804e058 100644 --- a/examples/wasi/cat/cat_plugin.pb.go +++ b/examples/wasi/cat/cat_plugin.pb.go @@ -29,7 +29,7 @@ func RegisterFileCat(p FileCat) { //export file_cat_cat func _file_cat_cat(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req FileCatRequest + req := new(FileCatRequest) if err := req.UnmarshalVT(b); err != nil { return 0 } diff --git a/examples/wasi/main.go b/examples/wasi/main.go index 9682eb1..3abaa7d 100644 --- a/examples/wasi/main.go +++ b/examples/wasi/main.go @@ -39,7 +39,7 @@ func run() error { } defer wasiPlugin.Close(ctx) - reply, err := wasiPlugin.Cat(ctx, cat.FileCatRequest{ + reply, err := wasiPlugin.Cat(ctx, &cat.FileCatRequest{ FilePath: "testdata/hello.txt", }) if err != nil { diff --git a/examples/wasi/plugin/plugin.go b/examples/wasi/plugin/plugin.go index 57f2fd4..875b219 100644 --- a/examples/wasi/plugin/plugin.go +++ b/examples/wasi/plugin/plugin.go @@ -19,14 +19,14 @@ type CatPlugin struct{} var _ cat.FileCat = (*CatPlugin)(nil) -func (CatPlugin) Cat(_ context.Context, request cat.FileCatRequest) (cat.FileCatReply, error) { +func (CatPlugin) Cat(_ context.Context, request *cat.FileCatRequest) (*cat.FileCatReply, error) { // The message is shown in stdout as os.Stdout is attached. fmt.Println("File loading...") b, err := os.ReadFile(request.GetFilePath()) if err != nil { - return cat.FileCatReply{}, err + return nil, err } - return cat.FileCatReply{ + return &cat.FileCatReply{ Content: string(b), }, nil } diff --git a/gen/host.go b/gen/host.go index 3fe04cb..8c71b20 100644 --- a/gen/host.go +++ b/gen/host.go @@ -83,7 +83,7 @@ func (gg *Generator) genHostFunctions(g *protogen.GeneratedFile, f *fileInfo) { g.P("buf, err := ", g.QualifiedGoIdent(pluginWasmPackage.Ident("ReadMemory")), "(m.Memory(), offset, size)") g.P(errorHandling) - g.P("var request ", g.QualifiedGoIdent(method.Input.GoIdent)) + g.P("request := new(", g.QualifiedGoIdent(method.Input.GoIdent), ")") g.P(`err = request.UnmarshalVT(buf)`) g.P(errorHandling) @@ -301,19 +301,19 @@ func genHost(g *protogen.GeneratedFile, f *fileInfo, service *serviceInfo) { func genPluginMethod(g *protogen.GeneratedFile, f *fileInfo, method *protogen.Method, structName string) { g.P("func (p *", structName, ")", method.GoName, "(ctx ", g.QualifiedGoIdent(contextPackage.Ident("Context")), - ", request ", g.QualifiedGoIdent(method.Input.GoIdent), ")", - "(response ", g.QualifiedGoIdent(method.Output.GoIdent), ", err error) {") + ", request *", g.QualifiedGoIdent(method.Input.GoIdent), ")", + "(*", g.QualifiedGoIdent(method.Output.GoIdent), ", error) {") - errorHandling := "if err != nil {return response , err}" + errorHandling := "if err != nil {return nil , err}" g.P("data, err := request.MarshalVT()") g.P(errorHandling) g.P("dataSize := uint64(len(data))") - g.P(` + g.P(fmt.Sprintf(` var dataPtr uint64 // If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin. if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) - if err != nil {return response , err} + %s dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. // So, we have to free it when finished @@ -321,10 +321,11 @@ func genPluginMethod(g *protogen.GeneratedFile, f *fileInfo, method *protogen.Me // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%%d, %%d) out of range of memory size %%d", dataPtr, dataSize, p.module.Memory().Size()) } } -`) +`, errorHandling)) + g.P("ptrSize, err := p.", strings.ToLower(method.GoName[:1]+method.GoName[1:]), ".Call(ctx, dataPtr, dataSize)") g.P(errorHandling) @@ -341,22 +342,24 @@ func genPluginMethod(g *protogen.GeneratedFile, f *fileInfo, method *protogen.Me // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%%d, %%d) out of range of memory size %%d", + return nil, fmt.Errorf("Memory.Read(%%d, %%d) out of range of memory size %%d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, %s(string(bytes)) + return nil, %s(string(bytes)) } + response := new(%s) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil`, ErrorMaskBit, ErrorMaskBit, - g.QualifiedGoIdent(errorsPackage.Ident("New"))), + g.QualifiedGoIdent(errorsPackage.Ident("New")), + g.QualifiedGoIdent(method.Output.GoIdent)), ) g.P("}") } diff --git a/gen/main.go b/gen/main.go index 4899cdb..66706ca 100644 --- a/gen/main.go +++ b/gen/main.go @@ -724,8 +724,8 @@ func genServiceInterface(g *protogen.GeneratedFile, f *fileInfo, s *serviceInfo) func genServiceInterfaceMethod(g *protogen.GeneratedFile, f *fileInfo, s *serviceInfo) { for _, method := range s.Methods { g.P(method.Comments.Leading, method.GoName, - "(", g.QualifiedGoIdent(contextPackage.Ident("Context")), ", ", g.QualifiedGoIdent(method.Input.GoIdent), ") ", - "(", g.QualifiedGoIdent(method.Output.GoIdent), ", error)") + "(", g.QualifiedGoIdent(contextPackage.Ident("Context")), ", *", g.QualifiedGoIdent(method.Input.GoIdent), ") ", + "(*", g.QualifiedGoIdent(method.Output.GoIdent), ", error)") } } diff --git a/gen/plugin.go b/gen/plugin.go index 012fb73..a7e0157 100644 --- a/gen/plugin.go +++ b/gen/plugin.go @@ -58,7 +58,7 @@ func genPlugin(g *protogen.GeneratedFile, f *fileInfo, service *serviceInfo) { g.P("func _", exportedName, "(ptr, size uint32) uint64 {") g.P("b := ", g.QualifiedGoIdent(pluginWasmPackage.Ident("PtrToByte")), "(ptr, size)") - g.P("var req ", g.QualifiedGoIdent(method.Input.GoIdent)) + g.P("req := new(", g.QualifiedGoIdent(method.Input.GoIdent), ")") g.P(`if err := req.UnmarshalVT(b); err != nil { return 0 }`) @@ -108,10 +108,10 @@ func genHostFunctions(g *protogen.GeneratedFile, f *fileInfo) { //go:linkname _%s func _%s(ptr uint32, size uint32) uint64 - func (h %s) %s(ctx %s, request %s) (response %s, err error) { + func (h %s) %s(ctx %s, request *%s) (*%s, error) { buf, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } ptr, size := %s(buf) ptrSize := _%s(ptr, size) @@ -120,8 +120,9 @@ func genHostFunctions(g *protogen.GeneratedFile, f *fileInfo) { size = uint32(ptrSize) buf = %s(ptr, size) + response := new(%s) if err = response.UnmarshalVT(buf); err != nil { - return response, err + return nil, err } return response, nil }`, @@ -132,6 +133,7 @@ func genHostFunctions(g *protogen.GeneratedFile, f *fileInfo) { g.QualifiedGoIdent(pluginWasmPackage.Ident("ByteToPtr")), importedName, g.QualifiedGoIdent(pluginWasmPackage.Ident("PtrToByte")), + g.QualifiedGoIdent(method.Output.GoIdent), )) } } diff --git a/tests/fields/fields_test.go b/tests/fields/fields_test.go index 844e766..23f16ef 100644 --- a/tests/fields/fields_test.go +++ b/tests/fields/fields_test.go @@ -20,11 +20,11 @@ func TestFields(t *testing.T) { require.NoError(t, err) defer plugin.Close(ctx) - res, err := plugin.TestEmptyInput(ctx, emptypb.Empty{}) + res, err := plugin.TestEmptyInput(ctx, &emptypb.Empty{}) require.NoError(t, err) require.True(t, res.GetOk()) - got, err := plugin.Test(ctx, proto.Request{ + got, err := plugin.Test(ctx, &proto.Request{ A: 1.2, B: 3.4, C: 5, @@ -50,7 +50,7 @@ func TestFields(t *testing.T) { S: proto.Enum_A, }) - want := proto.Response{ + want := &proto.Response{ A: 2.4, B: 6.8, C: 10, @@ -98,7 +98,7 @@ func TestErrorResponse(t *testing.T) { "error from plugin", }} { t.Run(tt.name, func(t *testing.T) { - _, err := plugin.TestError(ctx, proto.ErrorRequest{ErrText: tt.errMessage}) + _, err := plugin.TestError(ctx, &proto.ErrorRequest{ErrText: tt.errMessage}) require.Error(t, err) require.Equal(t, err.Error(), tt.errMessage) }) diff --git a/tests/fields/plugin/plugin.go b/tests/fields/plugin/plugin.go index 92cd877..a5ab0da 100644 --- a/tests/fields/plugin/plugin.go +++ b/tests/fields/plugin/plugin.go @@ -19,12 +19,12 @@ var _ proto.FieldTest = (*TestPlugin)(nil) type TestPlugin struct{} -func (p TestPlugin) TestEmptyInput(_ context.Context, _ emptypb.Empty) (proto.TestEmptyInputResponse, error) { - return proto.TestEmptyInputResponse{Ok: true}, nil +func (p TestPlugin) TestEmptyInput(_ context.Context, _ *emptypb.Empty) (*proto.TestEmptyInputResponse, error) { + return &proto.TestEmptyInputResponse{Ok: true}, nil } -func (p TestPlugin) Test(_ context.Context, request proto.Request) (proto.Response, error) { - return proto.Response{ +func (p TestPlugin) Test(_ context.Context, request *proto.Request) (*proto.Response, error) { + return &proto.Response{ A: request.GetA() * 2, B: request.GetB() * 2, C: request.GetC() * 2, @@ -59,6 +59,6 @@ func (p TestPlugin) Test(_ context.Context, request proto.Request) (proto.Respon }, nil } -func (p TestPlugin) TestError(_ context.Context, request proto.ErrorRequest) (proto.Response, error) { - return proto.Response{}, errors.New(request.ErrText) +func (p TestPlugin) TestError(_ context.Context, request *proto.ErrorRequest) (*proto.Response, error) { + return nil, errors.New(request.ErrText) } diff --git a/tests/fields/proto/fields.pb.go b/tests/fields/proto/fields.pb.go index 6b71132..d197944 100644 --- a/tests/fields/proto/fields.pb.go +++ b/tests/fields/proto/fields.pb.go @@ -471,7 +471,7 @@ func (x *Response_Nested) GetA() string { // go:plugin type=plugin version=1 type FieldTest interface { - Test(context.Context, Request) (Response, error) - TestEmptyInput(context.Context, emptypb.Empty) (TestEmptyInputResponse, error) - TestError(context.Context, ErrorRequest) (Response, error) + Test(context.Context, *Request) (*Response, error) + TestEmptyInput(context.Context, *emptypb.Empty) (*TestEmptyInputResponse, error) + TestError(context.Context, *ErrorRequest) (*Response, error) } diff --git a/tests/fields/proto/fields_host.pb.go b/tests/fields/proto/fields_host.pb.go index 055bc2f..4b3e0e4 100644 --- a/tests/fields/proto/fields_host.pb.go +++ b/tests/fields/proto/fields_host.pb.go @@ -142,10 +142,10 @@ type fieldTestPlugin struct { testerror api.Function } -func (p *fieldTestPlugin) Test(ctx context.Context, request Request) (response Response, err error) { +func (p *fieldTestPlugin) Test(ctx context.Context, request *Request) (*Response, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -154,7 +154,7 @@ func (p *fieldTestPlugin) Test(ctx context.Context, request Request) (response R if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -163,13 +163,13 @@ func (p *fieldTestPlugin) Test(ctx context.Context, request Request) (response R // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.test.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -184,24 +184,25 @@ func (p *fieldTestPlugin) Test(ctx context.Context, request Request) (response R // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(Response) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil } -func (p *fieldTestPlugin) TestEmptyInput(ctx context.Context, request emptypb.Empty) (response TestEmptyInputResponse, err error) { +func (p *fieldTestPlugin) TestEmptyInput(ctx context.Context, request *emptypb.Empty) (*TestEmptyInputResponse, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -210,7 +211,7 @@ func (p *fieldTestPlugin) TestEmptyInput(ctx context.Context, request emptypb.Em if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -219,13 +220,13 @@ func (p *fieldTestPlugin) TestEmptyInput(ctx context.Context, request emptypb.Em // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.testemptyinput.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -240,24 +241,25 @@ func (p *fieldTestPlugin) TestEmptyInput(ctx context.Context, request emptypb.Em // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(TestEmptyInputResponse) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil } -func (p *fieldTestPlugin) TestError(ctx context.Context, request ErrorRequest) (response Response, err error) { +func (p *fieldTestPlugin) TestError(ctx context.Context, request *ErrorRequest) (*Response, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -266,7 +268,7 @@ func (p *fieldTestPlugin) TestError(ctx context.Context, request ErrorRequest) ( if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -275,13 +277,13 @@ func (p *fieldTestPlugin) TestError(ctx context.Context, request ErrorRequest) ( // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.testerror.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -296,16 +298,17 @@ func (p *fieldTestPlugin) TestError(ctx context.Context, request ErrorRequest) ( // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(Response) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/tests/fields/proto/fields_plugin.pb.go b/tests/fields/proto/fields_plugin.pb.go index d141915..f03be7a 100644 --- a/tests/fields/proto/fields_plugin.pb.go +++ b/tests/fields/proto/fields_plugin.pb.go @@ -30,7 +30,7 @@ func RegisterFieldTest(p FieldTest) { //export field_test_test func _field_test_test(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req Request + req := new(Request) if err := req.UnmarshalVT(b); err != nil { return 0 } @@ -54,7 +54,7 @@ func _field_test_test(ptr, size uint32) uint64 { //export field_test_test_empty_input func _field_test_test_empty_input(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req emptypb.Empty + req := new(emptypb.Empty) if err := req.UnmarshalVT(b); err != nil { return 0 } @@ -78,7 +78,7 @@ func _field_test_test_empty_input(ptr, size uint32) uint64 { //export field_test_test_error func _field_test_test_error(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req ErrorRequest + req := new(ErrorRequest) if err := req.UnmarshalVT(b); err != nil { return 0 } diff --git a/tests/host-functions/host_functions_test.go b/tests/host-functions/host_functions_test.go index 5c99738..b5dd029 100644 --- a/tests/host-functions/host_functions_test.go +++ b/tests/host-functions/host_functions_test.go @@ -32,7 +32,7 @@ func TestHostFunctions(t *testing.T) { require.NoError(t, err) defer plugin.Close(ctx) - reply, err := plugin.Greet(ctx, proto.GreetRequest{ + reply, err := plugin.Greet(ctx, &proto.GreetRequest{ Name: "Sato", }) require.NoError(t, err) @@ -41,17 +41,41 @@ func TestHostFunctions(t *testing.T) { assert.Equal(t, want, reply.GetMessage()) } +func TestEmptyRequest(t *testing.T) { + ctx := context.Background() + p, err := proto.NewGreeterPlugin(ctx) + require.NoError(t, err) + + plugin, err := p.Load(ctx, "plugin-empty/plugin.wasm", myEmptyHostFunctions{}) + require.NoError(t, err) + defer plugin.Close(ctx) + + reply, err := plugin.Greet(ctx, nil) + require.NoError(t, err) + want := "Hello, empty request '' and empty '' host function request" + assert.Equal(t, want, reply.GetMessage()) +} + // myHostFunctions implements proto.HostFunctions type myHostFunctions struct{} var _ proto.HostFunctions = (*myHostFunctions)(nil) // ParseJson is embedded into the plugin and can be called by the plugin. -func (myHostFunctions) ParseJson(_ context.Context, request proto.ParseJsonRequest) (proto.ParseJsonResponse, error) { +func (myHostFunctions) ParseJson(_ context.Context, request *proto.ParseJsonRequest) (*proto.ParseJsonResponse, error) { var person proto.Person if err := json.Unmarshal(request.GetContent(), &person); err != nil { - return proto.ParseJsonResponse{}, err + return nil, err } - return proto.ParseJsonResponse{Response: &person}, nil + return &proto.ParseJsonResponse{Response: &person}, nil +} + +type myEmptyHostFunctions struct{} + +var _ proto.HostFunctions = (*myEmptyHostFunctions)(nil) + +// ParseJson is embedded into the plugin and can be called by the plugin. +func (myEmptyHostFunctions) ParseJson(_ context.Context, _ *proto.ParseJsonRequest) (*proto.ParseJsonResponse, error) { + return &proto.ParseJsonResponse{Response: &proto.Person{}}, nil } diff --git a/tests/host-functions/plugin-empty/plugin.go b/tests/host-functions/plugin-empty/plugin.go new file mode 100644 index 0000000..4dd7199 --- /dev/null +++ b/tests/host-functions/plugin-empty/plugin.go @@ -0,0 +1,33 @@ +//go:build tinygo.wasm + +package main + +import ( + "context" + "fmt" + + "github.com/knqyf263/go-plugin/tests/host-functions/proto" +) + +// main is required for TinyGo to compile to Wasm. +func main() { + proto.RegisterGreeter(TestPlugin{}) +} + +type TestPlugin struct{} + +var _ proto.Greeter = (*TestPlugin)(nil) + +func (p TestPlugin) Greet(ctx context.Context, request *proto.GreetRequest) (*proto.GreetReply, error) { + hostFunctions := proto.NewHostFunctions() + + // Call the host function with nil request + resp, err := hostFunctions.ParseJson(ctx, nil) + if err != nil { + return nil, err + } + + return &proto.GreetReply{ + Message: fmt.Sprintf("Hello, empty request '%s' and empty '%s' host function request", request.GetName(), resp.GetResponse().GetName()), + }, nil +} diff --git a/tests/host-functions/plugin/plugin.go b/tests/host-functions/plugin/plugin.go index 699c67f..e4ea6ff 100644 --- a/tests/host-functions/plugin/plugin.go +++ b/tests/host-functions/plugin/plugin.go @@ -18,18 +18,18 @@ type TestPlugin struct{} var _ proto.Greeter = (*TestPlugin)(nil) -func (p TestPlugin) Greet(ctx context.Context, request proto.GreetRequest) (proto.GreetReply, error) { +func (p TestPlugin) Greet(ctx context.Context, request *proto.GreetRequest) (*proto.GreetReply, error) { hostFunctions := proto.NewHostFunctions() // Call the host function to parse JSON - resp, err := hostFunctions.ParseJson(ctx, proto.ParseJsonRequest{ + resp, err := hostFunctions.ParseJson(ctx, &proto.ParseJsonRequest{ Content: []byte(`{"name": "Yamada", "age": 20}`), }) if err != nil { - return proto.GreetReply{}, err + return nil, err } - return proto.GreetReply{ + return &proto.GreetReply{ Message: fmt.Sprintf("Hello, %s. This is %s (age %d).", request.GetName(), resp.GetResponse().GetName(), resp.GetResponse().GetAge()), }, nil diff --git a/tests/host-functions/proto/host.pb.go b/tests/host-functions/proto/host.pb.go index 221d548..e141234 100644 --- a/tests/host-functions/proto/host.pb.go +++ b/tests/host-functions/proto/host.pb.go @@ -128,11 +128,11 @@ func (x *Person) GetAge() int64 { // go:plugin type=plugin version=1 type Greeter interface { // Sends a greeting - Greet(context.Context, GreetRequest) (GreetReply, error) + Greet(context.Context, *GreetRequest) (*GreetReply, error) } // The host functions embedded into the plugin // go:plugin type=host type HostFunctions interface { - ParseJson(context.Context, ParseJsonRequest) (ParseJsonResponse, error) + ParseJson(context.Context, *ParseJsonRequest) (*ParseJsonResponse, error) } diff --git a/tests/host-functions/proto/host_host.pb.go b/tests/host-functions/proto/host_host.pb.go index b777bac..cf18980 100644 --- a/tests/host-functions/proto/host_host.pb.go +++ b/tests/host-functions/proto/host_host.pb.go @@ -47,7 +47,7 @@ func (h _hostFunctions) _ParseJson(ctx context.Context, m api.Module, stack []ui if err != nil { panic(err) } - var request ParseJsonRequest + request := new(ParseJsonRequest) err = request.UnmarshalVT(buf) if err != nil { panic(err) @@ -185,10 +185,10 @@ type greeterPlugin struct { greet api.Function } -func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (response GreetReply, err error) { +func (p *greeterPlugin) Greet(ctx context.Context, request *GreetRequest) (*GreetReply, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -197,7 +197,7 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -206,13 +206,13 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.greet.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -227,16 +227,17 @@ func (p *greeterPlugin) Greet(ctx context.Context, request GreetRequest) (respon // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(GreetReply) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/tests/host-functions/proto/host_plugin.pb.go b/tests/host-functions/proto/host_plugin.pb.go index 7cc995a..fad0421 100644 --- a/tests/host-functions/proto/host_plugin.pb.go +++ b/tests/host-functions/proto/host_plugin.pb.go @@ -30,7 +30,7 @@ func RegisterGreeter(p Greeter) { //export greeter_greet func _greeter_greet(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req GreetRequest + req := new(GreetRequest) if err := req.UnmarshalVT(b); err != nil { return 0 } @@ -62,10 +62,10 @@ func NewHostFunctions() HostFunctions { //go:linkname _parse_json func _parse_json(ptr uint32, size uint32) uint64 -func (h hostFunctions) ParseJson(ctx context.Context, request ParseJsonRequest) (response ParseJsonResponse, err error) { +func (h hostFunctions) ParseJson(ctx context.Context, request *ParseJsonRequest) (*ParseJsonResponse, error) { buf, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } ptr, size := wasm.ByteToPtr(buf) ptrSize := _parse_json(ptr, size) @@ -74,8 +74,9 @@ func (h hostFunctions) ParseJson(ctx context.Context, request ParseJsonRequest) size = uint32(ptrSize) buf = wasm.PtrToByte(ptr, size) + response := new(ParseJsonResponse) if err = response.UnmarshalVT(buf); err != nil { - return response, err + return nil, err } return response, nil } diff --git a/tests/import/import_test.go b/tests/import/import_test.go index 0c63a09..2a726f8 100644 --- a/tests/import/import_test.go +++ b/tests/import/import_test.go @@ -20,11 +20,11 @@ func TestImport(t *testing.T) { require.NoError(t, err) defer plugin.Close(ctx) - got, err := plugin.Hello(ctx, foo.Request{ + got, err := plugin.Hello(ctx, &foo.Request{ A: "Hi", }) - want := bar.Reply{ + want := &bar.Reply{ A: "Hi, bar", } assert.Equal(t, want, got) diff --git a/tests/import/plugin/plugin.go b/tests/import/plugin/plugin.go index b9a7185..8412d35 100644 --- a/tests/import/plugin/plugin.go +++ b/tests/import/plugin/plugin.go @@ -18,8 +18,8 @@ type TestPlugin struct{} var _ foo.Foo = (*TestPlugin)(nil) -func (p TestPlugin) Hello(_ context.Context, request foo.Request) (bar.Reply, error) { - return bar.Reply{ +func (p TestPlugin) Hello(_ context.Context, request *foo.Request) (*bar.Reply, error) { + return &bar.Reply{ A: request.GetA() + ", bar", }, nil } diff --git a/tests/import/proto/bar/bar.pb.go b/tests/import/proto/bar/bar.pb.go index e71a4ec..7f589ca 100644 --- a/tests/import/proto/bar/bar.pb.go +++ b/tests/import/proto/bar/bar.pb.go @@ -59,5 +59,5 @@ func (x *Reply) GetA() string { // go:plugin type=plugin version=1 type Bar interface { - Hello(context.Context, Request) (Reply, error) + Hello(context.Context, *Request) (*Reply, error) } diff --git a/tests/import/proto/bar/bar_host.pb.go b/tests/import/proto/bar/bar_host.pb.go index 5b9fe23..bedf80d 100644 --- a/tests/import/proto/bar/bar_host.pb.go +++ b/tests/import/proto/bar/bar_host.pb.go @@ -129,10 +129,10 @@ type barPlugin struct { hello api.Function } -func (p *barPlugin) Hello(ctx context.Context, request Request) (response Reply, err error) { +func (p *barPlugin) Hello(ctx context.Context, request *Request) (*Reply, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -141,7 +141,7 @@ func (p *barPlugin) Hello(ctx context.Context, request Request) (response Reply, if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -150,13 +150,13 @@ func (p *barPlugin) Hello(ctx context.Context, request Request) (response Reply, // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.hello.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -171,16 +171,17 @@ func (p *barPlugin) Hello(ctx context.Context, request Request) (response Reply, // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(Reply) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/tests/import/proto/bar/bar_plugin.pb.go b/tests/import/proto/bar/bar_plugin.pb.go index 936b348..ad3e74b 100644 --- a/tests/import/proto/bar/bar_plugin.pb.go +++ b/tests/import/proto/bar/bar_plugin.pb.go @@ -29,7 +29,7 @@ func RegisterBar(p Bar) { //export bar_hello func _bar_hello(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req Request + req := new(Request) if err := req.UnmarshalVT(b); err != nil { return 0 } diff --git a/tests/import/proto/foo/foo.pb.go b/tests/import/proto/foo/foo.pb.go index 20c801b..1492daf 100644 --- a/tests/import/proto/foo/foo.pb.go +++ b/tests/import/proto/foo/foo.pb.go @@ -41,5 +41,5 @@ func (x *Request) GetA() string { // go:plugin type=plugin version=1 type Foo interface { - Hello(context.Context, Request) (bar.Reply, error) + Hello(context.Context, *Request) (*bar.Reply, error) } diff --git a/tests/import/proto/foo/foo_host.pb.go b/tests/import/proto/foo/foo_host.pb.go index f9c0d1f..c86c3af 100644 --- a/tests/import/proto/foo/foo_host.pb.go +++ b/tests/import/proto/foo/foo_host.pb.go @@ -130,10 +130,10 @@ type fooPlugin struct { hello api.Function } -func (p *fooPlugin) Hello(ctx context.Context, request Request) (response bar.Reply, err error) { +func (p *fooPlugin) Hello(ctx context.Context, request *Request) (*bar.Reply, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -142,7 +142,7 @@ func (p *fooPlugin) Hello(ctx context.Context, request Request) (response bar.Re if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -151,13 +151,13 @@ func (p *fooPlugin) Hello(ctx context.Context, request Request) (response bar.Re // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.hello.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -172,16 +172,17 @@ func (p *fooPlugin) Hello(ctx context.Context, request Request) (response bar.Re // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(bar.Reply) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/tests/import/proto/foo/foo_plugin.pb.go b/tests/import/proto/foo/foo_plugin.pb.go index da6623f..35872fc 100644 --- a/tests/import/proto/foo/foo_plugin.pb.go +++ b/tests/import/proto/foo/foo_plugin.pb.go @@ -29,7 +29,7 @@ func RegisterFoo(p Foo) { //export foo_hello func _foo_hello(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req Request + req := new(Request) if err := req.UnmarshalVT(b); err != nil { return 0 } diff --git a/tests/well-known/plugin/plugin.go b/tests/well-known/plugin/plugin.go index c739458..bb5e4b1 100644 --- a/tests/well-known/plugin/plugin.go +++ b/tests/well-known/plugin/plugin.go @@ -24,12 +24,12 @@ var _ proto.EmptyTest = (*TestPlugin)(nil) type TestPlugin struct{} -func (p TestPlugin) Test(_ context.Context, request proto.Request) (proto.Response, error) { +func (p TestPlugin) Test(_ context.Context, request *proto.Request) (*proto.Response, error) { c, err := p.GetC(request.GetC()) if err != nil { - return proto.Response{}, err + return nil, err } - return proto.Response{ + return &proto.Response{ A: durationpb.New(2 * time.Minute), B: timestamppb.New(request.GetB().AsTime().Add(request.GetA().AsDuration())), C: c, @@ -54,6 +54,6 @@ func (p TestPlugin) GetC(v *structpb.Value) (*structpb.Value, error) { return structpb.NewValue(c) } -func (p TestPlugin) DoNothing(_ context.Context, _ emptypb.Empty) (emptypb.Empty, error) { - return emptypb.Empty{}, nil +func (p TestPlugin) DoNothing(_ context.Context, _ *emptypb.Empty) (*emptypb.Empty, error) { + return nil, nil } diff --git a/tests/well-known/proto/known.pb.go b/tests/well-known/proto/known.pb.go index e1ec5d7..802c253 100644 --- a/tests/well-known/proto/known.pb.go +++ b/tests/well-known/proto/known.pb.go @@ -244,10 +244,10 @@ func (x *Response) GetL() *wrapperspb.UInt64Value { // go:plugin type=plugin version=1 type KnownTypesTest interface { - Test(context.Context, Request) (Response, error) + Test(context.Context, *Request) (*Response, error) } // go:plugin type=plugin version=1 type EmptyTest interface { - DoNothing(context.Context, emptypb.Empty) (emptypb.Empty, error) + DoNothing(context.Context, *emptypb.Empty) (*emptypb.Empty, error) } diff --git a/tests/well-known/proto/known_host.pb.go b/tests/well-known/proto/known_host.pb.go index 98baa26..38dd374 100644 --- a/tests/well-known/proto/known_host.pb.go +++ b/tests/well-known/proto/known_host.pb.go @@ -130,10 +130,10 @@ type knownTypesTestPlugin struct { test api.Function } -func (p *knownTypesTestPlugin) Test(ctx context.Context, request Request) (response Response, err error) { +func (p *knownTypesTestPlugin) Test(ctx context.Context, request *Request) (*Response, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -142,7 +142,7 @@ func (p *knownTypesTestPlugin) Test(ctx context.Context, request Request) (respo if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -151,13 +151,13 @@ func (p *knownTypesTestPlugin) Test(ctx context.Context, request Request) (respo // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.test.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -172,16 +172,17 @@ func (p *knownTypesTestPlugin) Test(ctx context.Context, request Request) (respo // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(Response) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil @@ -298,10 +299,10 @@ type emptyTestPlugin struct { donothing api.Function } -func (p *emptyTestPlugin) DoNothing(ctx context.Context, request emptypb.Empty) (response emptypb.Empty, err error) { +func (p *emptyTestPlugin) DoNothing(ctx context.Context, request *emptypb.Empty) (*emptypb.Empty, error) { data, err := request.MarshalVT() if err != nil { - return response, err + return nil, err } dataSize := uint64(len(data)) @@ -310,7 +311,7 @@ func (p *emptyTestPlugin) DoNothing(ctx context.Context, request emptypb.Empty) if dataSize != 0 { results, err := p.malloc.Call(ctx, dataSize) if err != nil { - return response, err + return nil, err } dataPtr = results[0] // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. @@ -319,13 +320,13 @@ func (p *emptyTestPlugin) DoNothing(ctx context.Context, request emptypb.Empty) // The pointer is a linear memory offset, which is where we write the name. if !p.module.Memory().Write(uint32(dataPtr), data) { - return response, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) + return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size()) } } ptrSize, err := p.donothing.Call(ctx, dataPtr, dataSize) if err != nil { - return response, err + return nil, err } // Note: This pointer is still owned by TinyGo, so don't try to free it! @@ -340,16 +341,17 @@ func (p *emptyTestPlugin) DoNothing(ctx context.Context, request emptypb.Empty) // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { - return response, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", resPtr, resSize, p.module.Memory().Size()) } if isErrResponse { - return response, errors.New(string(bytes)) + return nil, errors.New(string(bytes)) } + response := new(emptypb.Empty) if err = response.UnmarshalVT(bytes); err != nil { - return response, err + return nil, err } return response, nil diff --git a/tests/well-known/proto/known_plugin.pb.go b/tests/well-known/proto/known_plugin.pb.go index 666bf26..51e17c0 100644 --- a/tests/well-known/proto/known_plugin.pb.go +++ b/tests/well-known/proto/known_plugin.pb.go @@ -30,7 +30,7 @@ func RegisterKnownTypesTest(p KnownTypesTest) { //export known_types_test_test func _known_types_test_test(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req Request + req := new(Request) if err := req.UnmarshalVT(b); err != nil { return 0 } @@ -67,7 +67,7 @@ func RegisterEmptyTest(p EmptyTest) { //export empty_test_do_nothing func _empty_test_do_nothing(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) - var req emptypb.Empty + req := new(emptypb.Empty) if err := req.UnmarshalVT(b); err != nil { return 0 } diff --git a/tests/well-known/well_known_test.go b/tests/well-known/well_known_test.go index b3bd78b..75d31d2 100644 --- a/tests/well-known/well_known_test.go +++ b/tests/well-known/well_known_test.go @@ -43,7 +43,7 @@ func TestWellKnownTypes(t *testing.T) { }) require.NoError(t, err) - got, err := plugin.Test(ctx, proto.Request{ + got, err := plugin.Test(ctx, &proto.Request{ // duration A: durationpb.New(1 * time.Hour), @@ -83,7 +83,7 @@ func TestWellKnownTypes(t *testing.T) { }) require.NoError(t, err) - want := proto.Response{ + want := &proto.Response{ A: durationpb.New(2 * time.Minute), B: timestamppb.New(b.Add(1 * time.Hour)), C: c, @@ -109,7 +109,7 @@ func TestEmpty(t *testing.T) { require.NoError(t, err) defer plugin.Close(ctx) - got, err := plugin.DoNothing(ctx, emptypb.Empty{}) + got, err := plugin.DoNothing(ctx, &emptypb.Empty{}) require.NoError(t, err) - assert.Equal(t, emptypb.Empty{}, got) + assert.Equal(t, &emptypb.Empty{}, got) }