Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is go-wasmer can handle C codes? #77

Closed
AchalaSB opened this issue Oct 14, 2019 · 11 comments · Fixed by #92
Closed

Is go-wasmer can handle C codes? #77

AchalaSB opened this issue Oct 14, 2019 · 11 comments · Fixed by #92
Assignees
Labels
❓ question Further information is requested

Comments

@AchalaSB
Copy link

Using go-wasmer we were able to handle Rust code by calling extern function.

can we do same for C codes?
is it compatible now?

If yes. How can we call C code as an extern function?

@AchalaSB AchalaSB added the ❓ question Further information is requested label Oct 14, 2019
@Hywan
Copy link
Contributor

Hywan commented Oct 14, 2019

If your C code is compiled to WebAssembly, yes, it will work!

@Hywan Hywan self-assigned this Oct 14, 2019
@AchalaSB
Copy link
Author

Yea, we can compile C code to wasm.
So again wasmer requires the C code as extern function only?

Is there any examples, go-wasmer handles C code?

@Hywan
Copy link
Contributor

Hywan commented Oct 18, 2019

So far, a useful tool is https://emscripten.org/. More to come in few days :-).

@AchalaSB
Copy link
Author

Using emscripten we can compile. but that can't be use in go-wasmer.
We can compile using WASI if that supports in go-wasmer its good to go. (even for Rust)

I see go-wasmer is working on WASI. Waiting for WASI support

@Hywan
Copy link
Contributor

Hywan commented Oct 23, 2019

Few days later

We've released wasienv, check it out https://medium.com/wasmer/wasienv-wasi-development-workflow-for-humans-1811d9a50345 :-)

@AchalaSB
Copy link
Author

This looks good to me. But my feature request is to handle wasm bytecode(from C/C++ code) in go module.

This wasienv is usable in only in wasmer if I'm not wrong

@Hywan
Copy link
Contributor

Hywan commented Oct 23, 2019

wasienv helps to compile a C/C++ program to Wasm (with WASI support), and then you can use this Wasm module anywhere, incl. this project.

@AchalaSB
Copy link
Author

Thanks will try with go module.
Is there any specific way to write code in C/C++ like in Rust for this project?
If so can I get any simple example.

@Hywan
Copy link
Contributor

Hywan commented Dec 4, 2019

Nothing I'm aware of. What do you want to know?

@AchalaSB
Copy link
Author

AchalaSB commented Dec 5, 2019

i'm trying to run C code in go-wasmer. C code compiled in wasm using WASI
main.c

#include<stdio.h>
int main(int argc, char **argv)
{
  if (argc < 4) {
    printf("Hello, WASI!\n");
  } else {
    printf("Hello, %s!\n", argv[1]);
  }
}

main.go

package main

/*
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
  if (argc < 4) {
    printf("Hello, WASI!\n");
  } else {
    printf("Hello, %s!\n", argv[1]);
  }
}
*/
import "C"
import (
	"fmt"
	wasm "github.com/wasmerio/go-ext-wasm/wasmer"
)
func test(x int32) int32{
	return x
}

func main() {
	// Reads the WebAssembly module as bytes.
         bytes, _ := wasm.ReadBytes("/home/achala/codes/wasm-play/src/new.wasm")
	imports, _ := wasm.NewImports().Append("test", test, C.test)
	instance, err := wasm.NewInstanceWithImports(bytes, imports)
	if err != nil {
		panic(err)
	  }
	defer instance.Close()
	res := instance.Exports["main"]
	result, _ := res(2)
	fmt.Println(result) 
}

This is endup error

# command-line-arguments
./Ctest.go:29:55: could not determine kind of name for C.test

If I remove test function and imports just doing in normal export way. got this error

# command-line-arguments
/tmp/go-build871956597/b001/_x002.o: In function `main':
./Ctest.go:8: multiple definition of `main'
/tmp/go-build871956597/b001/_cgo_main.o:/tmp/go-build/_cgo_main.c:1: first defined here
collect2: error: ld returned 1 exit status

How can I call C/C++ code in go-wasmer ?

@Hywan
Copy link
Contributor

Hywan commented Dec 6, 2019

Considering #92 is merged (it still a draft, it's blocked by wasmerio/wasmer#1028 and wasmerio/wasmer#1030, they are all landing very soon).

Let's consider the following C++ program:

#include <stdio.h>

extern "C" {
  int32_t sum(int32_t, int32_t) __attribute__((used));
  int32_t sum(int32_t x, int32_t y) {
    return x + y;
  }
}

int main(int argc, char **argv) {
  if (argc < 2) {
    printf("Hello, WASI!\n");
  } else {
    printf("Hello, %s!\n", argv[1]);
  }
}

You can compile it with:

$ wasicc wasi_c.cpp -o wasi_c

Then from Go:

module, err := wasm.Compile(getBytes("wasi_c.wasm"))
assert.NoError(t, err)

wasiVersion := wasm.WasiGetVersion(module)
assert.Equal(t, wasiVersion, wasm.Snapshot0)

importObject := wasm.NewDefaultWasiImportObjectForVersion(wasiVersion)

instance, err := module.InstantiateWithImportObject(importObject)
assert.NoError(t, err)

defer instance.Close()

// `_starts` calls the `main` function. It prints `Hello, WASI!`.
start, exists := instance.Exports["_start"]
assert.Equal(t, true, exists)

_, err = start()
assert.NoError(t, err)

// `sum` is a regular exported function.
sum, exists := instance.Exports["sum"]
assert.Equal(t, true, exists)

output, err := sum(1, 2)
assert.NoError(t, err)
assert.Equal(t, wasm.I32(3), output)

As soon as the PR mentionned above are merged, we have to wait for a new Wasmer release, and we will good to go!

Hope it helps.

bors bot added a commit that referenced this issue Jan 7, 2020
92: feat(wasi) Support `WasiGetVersion` & other `*ForVersion` WASI API r=Hywan a=Hywan

Fix #90.
Fix #77.

⚠️ Depends on wasmerio/wasmer#1028, wasmerio/wasmer#1029, and wasmerio/wasmer#1030. They must be merged before merging this PR! Marking this PR as a draft to be sure (the shared libraries must be updated too).

This patch updates `bridge.go` and `wasmer.h` to support the new `wasmer_wasi_generate_import_object_for_version` and `wasmer_wasi_get_version` functions.

After that, this patch updates `wasi.go` to implement the new `NewDefaultWasiImportObjectForVersion`, `NewWasiImportObjectForVersion` and the `WasiGetVersion` functions. In addition to that, we create a new `WasiVersion` type.

Finally, this patch updates the tests to test this new API. And it works like a charm 👌.

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
bors bot added a commit that referenced this issue Jan 8, 2020
92: feat(wasi) Support `WasiGetVersion` & other `*ForVersion` WASI API r=Hywan a=Hywan

Fix #90.
Fix #77.

⚠️ Depends on wasmerio/wasmer#1028, wasmerio/wasmer#1029, and wasmerio/wasmer#1030. They must be merged before merging this PR! Marking this PR as a draft to be sure (the shared libraries must be updated too).

This patch updates `bridge.go` and `wasmer.h` to support the new `wasmer_wasi_generate_import_object_for_version` and `wasmer_wasi_get_version` functions.

After that, this patch updates `wasi.go` to implement the new `NewDefaultWasiImportObjectForVersion`, `NewWasiImportObjectForVersion` and the `WasiGetVersion` functions. In addition to that, we create a new `WasiVersion` type.

Finally, this patch updates the tests to test this new API. And it works like a charm 👌.

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
@bors bors bot closed this as completed in 978d876 Jan 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❓ question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants