Skip to content

Commit

Permalink
wasip1: add //go:wasmexport support
Browse files Browse the repository at this point in the history
This adds support for the `//go:wasmexport` pragma as proposed here:
golang/go#65199

It is currently implemented only for wasip1, but it is certainly
possible to extend it to other targets like GOOS=js, wasm-unknown, or
wasip2. It is also currently limited to -buildmode=c-shared, this is a
limitation that could easily be lifted in the future.
  • Loading branch information
aykevl committed Sep 1, 2024
1 parent d144b11 commit 829f62e
Show file tree
Hide file tree
Showing 14 changed files with 451 additions and 52 deletions.
8 changes: 8 additions & 0 deletions builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
ABI: config.ABI(),
GOOS: config.GOOS(),
GOARCH: config.GOARCH(),
BuildMode: config.BuildMode(),
CodeModel: config.CodeModel(),
RelocationModel: config.RelocationModel(),
SizeLevel: sizeLevel,
Expand Down Expand Up @@ -649,6 +650,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
result.Binary = result.Executable // final file
ldflags := append(config.LDFlags(), "-o", result.Executable)

if config.Options.BuildMode == "c-shared" {
if config.GOOS() != "wasip1" {
return result, fmt.Errorf("buildmode c-shared is only supported on wasip1 at the moment")
}
ldflags = append(ldflags, "--no-entry")
}

// Add compiler-rt dependency if needed. Usually this is a simple load from
// a cache.
if config.Target.RTLib == "compiler-rt" {
Expand Down
14 changes: 14 additions & 0 deletions compileopts/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ func (c *Config) CPU() string {
return c.Target.CPU
}

// The current build mode (like the `-buildmode` command line flag).
func (c *Config) BuildMode() string {
if c.Options.BuildMode != "" {
return c.Options.BuildMode
}
return "default"
}

// Features returns a list of features this CPU supports. For example, for a
// RISC-V processor, that could be "+a,+c,+m". For many targets, an empty list
// will be returned.
Expand Down Expand Up @@ -91,6 +99,12 @@ func (c *Config) BuildTags() []string {
for i := 1; i <= c.GoMinorVersion; i++ {
tags = append(tags, fmt.Sprintf("go1.%d", i))
}
if c.BuildMode() == "c-shared" && strings.HasPrefix(c.Triple(), "wasm") {
// Use reactor mode, which means the application is initialized in
// _initialize and main.main is not called by default. See for example:
// https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md
tags = append(tags, "tinygo_wasm_reactor")
}
tags = append(tags, c.Options.Tags...)
return tags
}
Expand Down
10 changes: 10 additions & 0 deletions compileopts/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
)

var (
validBuildModeOptions = []string{"default", "c-shared"}
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
validSchedulerOptions = []string{"none", "tasks", "asyncify"}
validSerialOptions = []string{"none", "uart", "usb", "rtt"}
Expand All @@ -26,6 +27,7 @@ type Options struct {
GOMIPS string // environment variable (only used with GOARCH=mips and GOARCH=mipsle)
Directory string // working dir, leave it unset to use the current working dir
Target string
BuildMode string // -buildmode flag
Opt string
GC string
PanicStrategy string
Expand Down Expand Up @@ -60,6 +62,14 @@ type Options struct {

// Verify performs a validation on the given options, raising an error if options are not valid.
func (o *Options) Verify() error {
if o.BuildMode != "" {
valid := isInArray(validBuildModeOptions, o.BuildMode)
if !valid {
return fmt.Errorf(`invalid buildmode option '%s': valid values are %s`,
o.BuildMode,
strings.Join(validBuildModeOptions, ", "))
}
}
if o.GC != "" {
valid := isInArray(validGCOptions, o.GC)
if !valid {
Expand Down
6 changes: 6 additions & 0 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Config struct {
ABI string
GOOS string
GOARCH string
BuildMode string
CodeModel string
RelocationModel string
SizeLevel int
Expand Down Expand Up @@ -1384,6 +1385,11 @@ func (b *builder) createFunction() {
b.llvmFn.SetLinkage(llvm.InternalLinkage)
b.createFunction()
}

// Create wrapper function that can be called externally.
if b.info.wasmExport != "" {
b.createWasmExport()
}
}

// posser is an interface that's implemented by both ssa.Value and
Expand Down
Loading

0 comments on commit 829f62e

Please sign in to comment.