]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/noder/writer.go
all: implement wasmimport directive
[gostls13.git] / src / cmd / compile / internal / noder / writer.go
index da5c1e910d74094fed9b62e25e71f48186af40ef..5dd8d1de2df1b510490493943899e25fdec40d50 100644 (file)
@@ -6,6 +6,7 @@ package noder
 
 import (
        "fmt"
+       "internal/buildcfg"
        "internal/pkgbits"
 
        "cmd/compile/internal/base"
@@ -1003,11 +1004,15 @@ func (w *writer) funcExt(obj *types2.Func) {
        if pragma&ir.Systemstack != 0 && pragma&ir.Nosplit != 0 {
                w.p.errorf(decl, "go:nosplit and go:systemstack cannot be combined")
        }
+       wi := asWasmImport(decl.Pragma)
 
        if decl.Body != nil {
                if pragma&ir.Noescape != 0 {
                        w.p.errorf(decl, "can only use //go:noescape with external func implementations")
                }
+               if wi != nil {
+                       w.p.errorf(decl, "can only use //go:wasmimport with external func implementations")
+               }
                if (pragma&ir.UintptrKeepAlive != 0 && pragma&ir.UintptrEscapes == 0) && pragma&ir.Nosplit == 0 {
                        // Stack growth can't handle uintptr arguments that may
                        // be pointers (as we don't know which are pointers
@@ -1028,7 +1033,8 @@ func (w *writer) funcExt(obj *types2.Func) {
                if base.Flag.Complete || decl.Name.Value == "init" {
                        // Linknamed functions are allowed to have no body. Hopefully
                        // the linkname target has a body. See issue 23311.
-                       if _, ok := w.p.linknames[obj]; !ok {
+                       // Wasmimport functions are also allowed to have no body.
+                       if _, ok := w.p.linknames[obj]; !ok && wi == nil {
                                w.p.errorf(decl, "missing function body")
                        }
                }
@@ -1041,6 +1047,17 @@ func (w *writer) funcExt(obj *types2.Func) {
        w.Sync(pkgbits.SyncFuncExt)
        w.pragmaFlag(pragma)
        w.linkname(obj)
+
+       if buildcfg.GOARCH == "wasm" {
+               if wi != nil {
+                       w.String(wi.Module)
+                       w.String(wi.Name)
+               } else {
+                       w.String("")
+                       w.String("")
+               }
+       }
+
        w.Bool(false) // stub extension
        w.Reloc(pkgbits.RelocBody, body)
        w.Sync(pkgbits.SyncEOF)
@@ -2728,6 +2745,13 @@ func asPragmaFlag(p syntax.Pragma) ir.PragmaFlag {
        return p.(*pragmas).Flag
 }
 
+func asWasmImport(p syntax.Pragma) *WasmImport {
+       if p == nil {
+               return nil
+       }
+       return p.(*pragmas).WasmImport
+}
+
 // isPtrTo reports whether from is the type *to.
 func isPtrTo(from, to types2.Type) bool {
        ptr, ok := from.(*types2.Pointer)