diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml index 0544d0a697e..5a07b1861fd 100644 --- a/.github/workflows/commit.yaml +++ b/.github/workflows/commit.yaml @@ -26,36 +26,36 @@ concurrency: cancel-in-progress: true jobs: - check: - name: Pre-commit check - # wabt requires a later version of libc than what's installed on ubuntu-22.04. - runs-on: ubuntu-latest - steps: - - name: Install latest wast2json - run: | # Needed for build.spectest. wabt includes wast2json. - wabt_version=1.0.33 - wabt_url=https://github.com/WebAssembly/wabt/releases/download/${wabt_version}/wabt-${wabt_version}-ubuntu.tar.gz - curl -sSL ${wabt_url} | tar --strip-components 2 -C /usr/local/bin -xzf - wabt-${wabt_version}/bin/wast2json - - - uses: actions/checkout@v3 - - - uses: actions/setup-go@v4 - with: # not cache: true as we also need to cache golint - cache: false - go-version: ${{ env.GO_VERSION }} - - - uses: actions/cache@v3 - with: - path: | - ~/.cache/go-build - ~/.cache/golangci-lint - ~/go/pkg/mod - ~/go/bin - key: check-${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum', 'Makefile') }} - - - run: make build.spectest - - - run: make check + # check: + # name: Pre-commit check + # # wabt requires a later version of libc than what's installed on ubuntu-22.04. + # runs-on: ubuntu-latest + # steps: + # - name: Install latest wast2json + # run: | # Needed for build.spectest. wabt includes wast2json. + # wabt_version=1.0.33 + # wabt_url=https://github.com/WebAssembly/wabt/releases/download/${wabt_version}/wabt-${wabt_version}-ubuntu.tar.gz + # curl -sSL ${wabt_url} | tar --strip-components 2 -C /usr/local/bin -xzf - wabt-${wabt_version}/bin/wast2json + + # - uses: actions/checkout@v3 + + # - uses: actions/setup-go@v4 + # with: # not cache: true as we also need to cache golint + # cache: false + # go-version: ${{ env.GO_VERSION }} + + # - uses: actions/cache@v3 + # with: + # path: | + # ~/.cache/go-build + # ~/.cache/golangci-lint + # ~/go/pkg/mod + # ~/go/bin + # key: check-${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum', 'Makefile') }} + + # - run: make build.spectest + + # - run: make check test_amd64: name: amd64, ${{ matrix.os }}, Go-${{ matrix.go-version }} diff --git a/README.md b/README.md index f547d225779..be60da95416 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # wazero: the zero dependency WebAssembly runtime for Go developers -[![WebAssembly Core Specification Test](https://github.com/tetratelabs/wazero/actions/workflows/spectest.yaml/badge.svg)](https://github.com/tetratelabs/wazero/actions/workflows/spectest.yaml) [![Go Reference](https://pkg.go.dev/badge/github.com/tetratelabs/wazero.svg)](https://pkg.go.dev/github.com/tetratelabs/wazero) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![WebAssembly Core Specification Test](https://github.com/gaukas/wazero/actions/workflows/spectest.yaml/badge.svg)](https://github.com/gaukas/wazero/actions/workflows/spectest.yaml) [![Go Reference](https://pkg.go.dev/badge/github.com/gaukas/wazero.svg)](https://pkg.go.dev/github.com/gaukas/wazero) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) WebAssembly is a way to safely run code compiled in other languages. Runtimes execute WebAssembly Modules (Wasm), which are most often binaries with a `.wasm` diff --git a/api/w_wasm_ext.go b/api/w_wasm_ext.go new file mode 100644 index 00000000000..bdb4701bdae --- /dev/null +++ b/api/w_wasm_ext.go @@ -0,0 +1,16 @@ +// Copyright 2023 The WATER Authors. All rights reserved. +// Use of this source code is governed by Apache 2 license +// that can be found in the LICENSE file. + +package api + +import ( + "net" + "os" +) + +type WATERModuleExtension interface { + InsertTCPConn(*net.TCPConn) (key int32, ok bool) + InsertTCPListener(*net.TCPListener) (key int32, ok bool) + InsertOSFile(*os.File) (key int32, ok bool) +} diff --git a/api/wasm.go b/api/wasm.go index d6a0d796ab8..110b47ebf9c 100644 --- a/api/wasm.go +++ b/api/wasm.go @@ -210,6 +210,8 @@ type Module interface { IsClosed() bool internalapi.WazeroOnly + + WATERModuleExtension // [WATER] extended for WATER to support more features } // Closer closes a resource. diff --git a/config.go b/config.go index 00e223031db..e80746513cd 100644 --- a/config.go +++ b/config.go @@ -315,6 +315,14 @@ type CompiledModule interface { // Name returns the module name encoded into the binary or empty if not. Name() string + // AllImports returns name and type of all imported functions, tables, + // memories or globals required for instantiation, per module name. + AllImports() map[string]map[string]api.ExternType + + // AllExports returns name and type of all exported functions, tables, + // memories or globals from this module. + AllExports() map[string]api.ExternType + // ImportedFunctions returns all the imported functions // (api.FunctionDefinition) in this module or nil if there are none. // @@ -380,6 +388,35 @@ func (c *compiledModule) Close(context.Context) error { return nil } +// AllExports implements CompiledModule.AllExports +func (c *compiledModule) AllExports() map[string]api.ExternType { + var ret = make(map[string]api.ExternType) + for name, f := range c.module.Exports { + if f != nil { + ret[name] = f.Type + } + } + return ret +} + +// AllImports implements CompiledModule.AllImports +func (c *compiledModule) AllImports() map[string]map[string]api.ExternType { + var ret = make(map[string]map[string]api.ExternType) + for module, imports := range c.module.ImportPerModule { + if len(imports) == 0 { + continue + } + + if _, ok := ret[module]; !ok { + ret[module] = make(map[string]api.ExternType) + } + for _, f := range imports { + ret[module][f.Name] = f.Type + } + } + return ret +} + // ImportedFunctions implements CompiledModule.ImportedFunctions func (c *compiledModule) ImportedFunctions() []api.FunctionDefinition { return c.module.ImportedFunctions() diff --git a/experimental/wazerotest/w_wazerotest.go b/experimental/wazerotest/w_wazerotest.go new file mode 100644 index 00000000000..1edc0d3afbd --- /dev/null +++ b/experimental/wazerotest/w_wazerotest.go @@ -0,0 +1,24 @@ +// Copyright 2023 The WATER Authors. All rights reserved. +// Use of this source code is governed by Apache 2 license +// that can be found in the LICENSE file. + +package wazerotest + +import ( + "net" + "os" +) + +// TODO: implement the extended functions + +func (m *Module) InsertTCPConn(*net.TCPConn) (key int32, ok bool) { + return 0, false +} + +func (m *Module) InsertTCPListener(*net.TCPListener) (key int32, ok bool) { + return 0, false +} + +func (m *Module) InsertOSFile(*os.File) (key int32, ok bool) { + return 0, false +} diff --git a/imports/wasi_snapshot_preview1/poll.go b/imports/wasi_snapshot_preview1/poll.go index d09f30245b0..fdfcecd63fa 100644 --- a/imports/wasi_snapshot_preview1/poll.go +++ b/imports/wasi_snapshot_preview1/poll.go @@ -147,8 +147,12 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno if fd < 0 { return sys.EBADF } - if _, ok := fsc.LookupFile(fd); ok { - evt.errno = wasip1.ErrnoNotsup + // if _, ok := fsc.LookupFile(fd); ok { + // evt.errno = wasip1.ErrnoNotsup + if file, ok := fsc.LookupFile(fd); ok { + if !file.File.IsNonblock() { + evt.errno = wasip1.ErrnoNotsup + } } else { evt.errno = wasip1.ErrnoBadf } diff --git a/internal/sys/w_sys.go b/internal/sys/w_sys.go new file mode 100644 index 00000000000..2ddeead68fc --- /dev/null +++ b/internal/sys/w_sys.go @@ -0,0 +1,34 @@ +// Copyright 2023 The WATER Authors. All rights reserved. +// Use of this source code is governed by Apache 2 license +// that can be found in the LICENSE file. + +package sys + +import ( + "net" + "os" + + "github.com/tetratelabs/wazero/internal/fsapi" + "github.com/tetratelabs/wazero/internal/sysfs" +) + +func (c *Context) InsertTCPConn(conn *net.TCPConn) (key int32, ok bool) { + return c.fsc.openedFiles.Insert(&FileEntry{ + IsPreopen: true, + File: fsapi.Adapt(sysfs.NewTCPConnFile(conn)), + }) +} + +func (c *Context) InsertTCPListener(listener *net.TCPListener) (key int32, ok bool) { + return c.fsc.openedFiles.Insert(&FileEntry{ + IsPreopen: true, + File: fsapi.Adapt(sysfs.NewTCPListenerFile(listener)), + }) +} + +func (c *Context) InsertOSFile(file *os.File) (key int32, ok bool) { + return c.fsc.openedFiles.Insert(&FileEntry{ + IsPreopen: true, + File: sysfs.NewOSFile(file.Name(), 0, 0, file), // TODO: fix flag and perm + }) +} diff --git a/internal/sysfs/sock_unsupported.go b/internal/sysfs/sock_unsupported.go index 76a10a8b615..b17417e9fab 100644 --- a/internal/sysfs/sock_unsupported.go +++ b/internal/sysfs/sock_unsupported.go @@ -24,3 +24,15 @@ type unsupportedSockFile struct { func (f *unsupportedSockFile) Accept() (socketapi.TCPConn, sys.Errno) { return nil, sys.ENOSYS } + +func newTcpConn(tc *net.TCPConn) socketapi.TCPConn { + return &unsupportedSockFile{} +} + +func (*unsupportedSockFile) Recvfrom([]byte, int) (int, sys.Errno) { + return 0, sys.ENOSYS +} + +func (*unsupportedSockFile) Shutdown(int) sys.Errno { + return sys.ENOSYS +} diff --git a/internal/sysfs/w_osfile.go b/internal/sysfs/w_osfile.go new file mode 100644 index 00000000000..9beb83716c5 --- /dev/null +++ b/internal/sysfs/w_osfile.go @@ -0,0 +1,13 @@ +package sysfs + +import ( + "io/fs" + "os" + + experimentalsys "github.com/tetratelabs/wazero/experimental/sys" + "github.com/tetratelabs/wazero/internal/fsapi" +) + +func NewOSFile(path string, flag experimentalsys.Oflag, perm fs.FileMode, f *os.File) fsapi.File { + return newOsFile(path, flag, perm, f) +} diff --git a/internal/sysfs/w_sock.go b/internal/sysfs/w_sock.go new file mode 100644 index 00000000000..0ca7e7cf140 --- /dev/null +++ b/internal/sysfs/w_sock.go @@ -0,0 +1,12 @@ +package sysfs + +import ( + "net" + + socketapi "github.com/tetratelabs/wazero/internal/sock" +) + +// NewTCPConnFile creates a socketapi.TCPSock for a given *net.TCPConn. +func NewTCPConnFile(tc *net.TCPConn) socketapi.TCPConn { + return newTcpConn(tc) +} diff --git a/internal/wasm/w_module_instance.go b/internal/wasm/w_module_instance.go new file mode 100644 index 00000000000..933ac74fc2f --- /dev/null +++ b/internal/wasm/w_module_instance.go @@ -0,0 +1,22 @@ +// Copyright 2023 The WATER Authors. All rights reserved. +// Use of this source code is governed by Apache 2 license +// that can be found in the LICENSE file. + +package wasm + +import ( + "net" + "os" +) + +func (m *ModuleInstance) InsertTCPConn(conn *net.TCPConn) (key int32, ok bool) { + return m.Sys.InsertTCPConn(conn) +} + +func (m *ModuleInstance) InsertTCPListener(lis *net.TCPListener) (key int32, ok bool) { + return m.Sys.InsertTCPListener(lis) +} + +func (m *ModuleInstance) InsertOSFile(f *os.File) (key int32, ok bool) { + return m.Sys.InsertOSFile(f) +}