Adds support for FreeBSD (#671)

FreeBSD was disabled due to lack of testing. This works around the
compilation problems. Note: We can't currently test arm64 automatically!

Notes:

* GitHub Actions doesn’t support FreeBSD, and may never.
* We could use Travis to run FreeBSD, but it would split our CI config.
* Using Vagrant directly is easier to debug than vmactions/freebsd-vm.
* GitHub Actions only supports virtualization on MacOS.
* GitHub Actions removed vagrant from the image starting with macos-11.
* Since VirtualBox doesn't work on arm64, freebsd/arm64 is untestabl

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Co-authored-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
Crypt Keeper
2022-07-01 18:59:19 +08:00
committed by GitHub
parent 63f6b22311
commit 891761ac1e
11 changed files with 147 additions and 14 deletions

View File

@@ -61,7 +61,7 @@ jobs:
strategy: strategy:
fail-fast: false # don't fail fast as sometimes failures are arch/OS specific fail-fast: false # don't fail fast as sometimes failures are arch/OS specific
matrix: # use latest available versions and be consistent on all workflows! matrix: # use latest available versions and be consistent on all workflows!
os: [ubuntu-20.04, macos-11, windows-2022] os: [ubuntu-20.04, macos-12, windows-2022]
go-version: go-version:
- "1.17" # == ${{ env.GO_VERSION }} because matrix cannot expand env variables - "1.17" # == ${{ env.GO_VERSION }} because matrix cannot expand env variables
- "1.18" - "1.18"
@@ -92,6 +92,38 @@ jobs:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: bash <(curl -s https://codecov.io/bash) run: bash <(curl -s https://codecov.io/bash)
test_freebsd: # See /Vagrantfile for notes
name: amd64, FreeBSD, Go-${{ matrix.go-version }}
runs-on: macos-12
strategy:
fail-fast: false # don't fail fast as sometimes failures are arch/OS specific
matrix:
go-version:
- "1.17" # == ${{ env.GO_VERSION }} because matrix cannot expand env variables
- "1.18"
steps:
- uses: actions/setup-go@v3
with: # Note: This isn't really used, it is just to match versions.
go-version: ${{ matrix.go-version }}
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: ~/.vagrant.d/boxes
key: spectest-${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum','Vagrantfile') }}-${{ matrix.spec-version }}
- name: Install Vagrant
run: brew install --cask vagrant
- name: Configure Vagrant
run: | # This ensures the same version of Go is used inside Vagrant.
GOVERSION=$(go env GOVERSION) GOARCH=$(go env GOARCH) vagrant up
- name: make test
run: vagrant ssh -c "cd wazero && make test"
test_scratch: test_scratch:
name: ${{ matrix.arch }}, Linux (scratch), Go-${{ matrix.go-version }} name: ${{ matrix.arch }}, Linux (scratch), Go-${{ matrix.go-version }}
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04

View File

@@ -19,7 +19,7 @@ defaults:
jobs: jobs:
test_amd64: test_amd64:
name: ${{ matrix.spec-version }} / amd64, Go-${{ matrix.go-version }} name: ${{ matrix.spec-version }} - linux/amd64, Go-${{ matrix.go-version }}
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
strategy: strategy:
fail-fast: false # don't fail fast as sometimes failures are arch/OS specific fail-fast: false # don't fail fast as sometimes failures are arch/OS specific
@@ -47,6 +47,41 @@ jobs:
- run: make spectest.${{ matrix.spec-version }} - run: make spectest.${{ matrix.spec-version }}
test_freebsd: # See /Vagrantfile for notes
name: ${{ matrix.spec-version }} - freebsd/amd64, Go-${{ matrix.go-version }}
runs-on: macos-12
strategy:
fail-fast: false # don't fail fast as sometimes failures are arch/OS specific
matrix:
go-version:
- "1.17"
- "1.18"
spec-version:
- "v1"
- "v2"
steps:
- uses: actions/setup-go@v3
with: # Note: This isn't really used, it is just to match versions.
go-version: ${{ matrix.go-version }}
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: ~/.vagrant.d/boxes
key: spectest-${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum','Vagrantfile') }}-${{ matrix.spec-version }}
- name: Install Vagrant
run: brew install --cask vagrant
- name: Configure Vagrant
run: | # This ensures the same version of Go is used inside Vagrant.
GOVERSION=$(go env GOVERSION) GOARCH=$(go env GOARCH) vagrant up
- name: make spectest.${{ matrix.spec-version }}
run: vagrant ssh -c "cd wazero && make spectest.${{ matrix.spec-version }}"
test_scratch: test_scratch:
name: ${{ matrix.spec-version }} / ${{ matrix.arch }}, Go-${{ matrix.go-version }} name: ${{ matrix.spec-version }} / ${{ matrix.arch }}, Go-${{ matrix.go-version }}
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04

2
.gitignore vendored
View File

@@ -29,3 +29,5 @@ package-lock.json
# codecov.io # codecov.io
/coverage.txt /coverage.txt
.vagrant

View File

@@ -168,14 +168,14 @@ systems are ones we test, but that doesn't necessarily mean other operating
system versions won't work. system versions won't work.
We currently test Linux (Ubuntu and scratch), MacOS and Windows as packaged by We currently test Linux (Ubuntu and scratch), MacOS and Windows as packaged by
[GitHub Actions][11]. [GitHub Actions][11], as well FreeBSD via Vagrant/VirtualBox.
* Interpreter * Interpreter
* Linux is tested on amd64 (native) as well arm64 and riscv64 via emulation. * Linux is tested on amd64 (native) as well arm64 and riscv64 via emulation.
* MacOS and Windows are only tested on amd64. * FreeBSD, MacOS and Windows are only tested on amd64.
* Compiler * Compiler
* Linux is tested on amd64 (native) as well arm64 via emulation. * Linux is tested on amd64 (native) as well arm64 via emulation.
* MacOS and Windows are only tested on amd64. * FreeBSD, MacOS and Windows are only tested on amd64.
wazero has no dependencies and doesn't require CGO. This means it can also be wazero has no dependencies and doesn't require CGO. This means it can also be
embedded in an application that doesn't use an operating system. This is a main embedded in an application that doesn't use an operating system. This is a main

44
Vagrantfile vendored Normal file
View File

@@ -0,0 +1,44 @@
# Vagrant file for FreeBSD
#
# Ex.
# GOVERSION=$(go env GOVERSION) GOARCH=$(go env GOARCH) vagrant up
# vagrant rsync
# vagrant ssh -c "cd wazero; go test ./..."
#
# Notes on FreeBSD:
# * GitHub Actions doesnt support FreeBSD, and may never.
# * We could use Travis to run FreeBSD, but it would split our CI config.
# * Using Vagrant directly is easier to debug than vmactions/freebsd-vm.
# * GitHub Actions only supports virtualization on MacOS.
# * GitHub Actions removed vagrant from the image starting with macos-11.
# * Since VirtualBox doesn't work on arm64, freebsd/arm64 is untestable.
Vagrant.configure("2") do |config|
config.vm.box = "generic/freebsd13"
config.vm.synced_folder ".", "/home/vagrant/wazero",
type: "rsync",
rsync__exclude: ".git/"
config.vm.provider "virtualbox" do |v|
v.memory = 1024
v.cpus = 1
end
# Ex. `GOVERSION=$(go env GOVERSION) GOARCH=$(go env GOARCH) vagrant provision`
config.vm.provision "install-golang", type: "shell", run: "once" do |sh|
sh.env = {
'GOVERSION': ENV['GOVERSION'],
'GOARCH': ENV['GOARCH'],
}
sh.inline = <<~GOINSTALL
set -eux -o pipefail
curl -fsSL "https://dl.google.com/go/${GOVERSION}.freebsd-${GOARCH}.tar.gz" | tar Cxz /usr/local
cat >> /usr/local/etc/profile <<EOF
export GOROOT=/usr/local/go
export PATH=/usr/local/go/bin:$PATH
EOF
GOINSTALL
end
end

View File

@@ -5,7 +5,7 @@
// //
// Meanwhile, users who know their runtime.GOOS can operate with the compiler // Meanwhile, users who know their runtime.GOOS can operate with the compiler
// may choose to use NewRuntimeConfigCompiler explicitly. // may choose to use NewRuntimeConfigCompiler explicitly.
//go:build (amd64 || arm64) && (darwin || linux || windows) //go:build (amd64 || arm64) && (darwin || linux || freebsd || windows)
package wazero package wazero

View File

@@ -1,5 +1,5 @@
// This is the opposite constraint of config_supported.go // This is the opposite constraint of config_supported.go
//go:build !(amd64 || arm64) || !(darwin || linux || windows) //go:build !(amd64 || arm64) || !(darwin || linux || freebsd || windows)
package wazero package wazero

View File

@@ -1166,7 +1166,7 @@ func (c *amd64Compiler) compileClz(o *wazeroir.OperationClz) error {
return err return err
} }
if runtime.GOOS != "darwin" { if runtime.GOOS != "darwin" && runtime.GOOS != "freebsd" {
if o.Type == wazeroir.UnsignedInt32 { if o.Type == wazeroir.UnsignedInt32 {
c.assembler.CompileRegisterToRegister(amd64.LZCNTL, target.register, target.register) c.assembler.CompileRegisterToRegister(amd64.LZCNTL, target.register, target.register)
} else { } else {
@@ -1229,7 +1229,7 @@ func (c *amd64Compiler) compileCtz(o *wazeroir.OperationCtz) error {
return err return err
} }
if runtime.GOOS != "darwin" { if runtime.GOOS != "darwin" && runtime.GOOS != "freebsd" {
if o.Type == wazeroir.UnsignedInt32 { if o.Type == wazeroir.UnsignedInt32 {
c.assembler.CompileRegisterToRegister(amd64.TZCNTL, target.register, target.register) c.assembler.CompileRegisterToRegister(amd64.TZCNTL, target.register, target.register)
} else { } else {

View File

@@ -1,9 +1,12 @@
// This uses syscall.Mprotect. Go's SDK only supports this on darwin and linux. // This uses syscall.Mprotect. Go's SDK only supports this on darwin and linux.
//go:build darwin || linux //go:build darwin || linux || freebsd
package platform package platform
import "syscall" import (
"syscall"
"unsafe"
)
func munmapCodeSegment(code []byte) error { func munmapCodeSegment(code []byte) error {
return syscall.Munmap(code) return syscall.Munmap(code)
@@ -51,6 +54,23 @@ func mmapCodeSegmentARM64(code []byte) ([]byte, error) {
copy(mmapFunc, code) copy(mmapFunc, code)
// Then we're done with writing code, change the permission to RX. // Then we're done with writing code, change the permission to RX.
err = syscall.Mprotect(mmapFunc, syscall.PROT_READ|syscall.PROT_EXEC) err = mprotect(mmapFunc, syscall.PROT_READ|syscall.PROT_EXEC)
return mmapFunc, err return mmapFunc, err
} }
var _zero uintptr
// mprotect is like syscall.Mprotect, defined locally so that freebsd compiles.
func mprotect(b []byte, prot int) (err error) {
var _p0 unsafe.Pointer
if len(b) > 0 {
_p0 = unsafe.Pointer(&b[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
_, _, e1 := syscall.Syscall(syscall.SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
if e1 != 0 {
err = syscall.Errno(e1)
}
return
}

View File

@@ -1,4 +1,4 @@
//go:build !(darwin || linux || windows) //go:build !(darwin || linux || freebsd || windows)
package platform package platform

View File

@@ -12,7 +12,7 @@ import (
// CompilerSupported is exported for tests and includes constraints here and also the assembler. // CompilerSupported is exported for tests and includes constraints here and also the assembler.
func CompilerSupported() bool { func CompilerSupported() bool {
switch runtime.GOOS { switch runtime.GOOS {
case "darwin", "windows", "linux": case "darwin", "windows", "linux", "freebsd":
default: default:
return false return false
} }