make runtime compatible with wasm

This commit is contained in:
Li Jie
2025-04-08 16:50:47 +08:00
parent 7c81d9293b
commit be4737461a
183 changed files with 14122 additions and 647 deletions

View File

@@ -22,9 +22,6 @@ import (
"github.com/goplus/llgo/runtime/abi"
)
// llgo:skipall
type _abi struct{}
type InterfaceType = abi.InterfaceType
func NoEscape(p unsafe.Pointer) unsafe.Pointer {

View File

@@ -0,0 +1,185 @@
package chacha8rand
import (
"unsafe"
"github.com/goplus/llgo/runtime/internal/runtime/goarch"
)
func block(seed *[4]uint64, blocks *[32]uint64, counter uint32) {
block_generic(seed, blocks, counter)
}
// setup sets up 4 ChaCha8 blocks in b32 with the counter and seed.
// Note that b32 is [16][4]uint32 not [4][16]uint32: the blocks are interlaced
// the same way they would be in a 4-way SIMD implementations.
func setup(seed *[4]uint64, b32 *[16][4]uint32, counter uint32) {
// Convert to uint64 to do half as many stores to memory.
b := (*[16][2]uint64)(unsafe.Pointer(b32))
// Constants; same as in ChaCha20: "expand 32-byte k"
b[0][0] = 0x61707865_61707865
b[0][1] = 0x61707865_61707865
b[1][0] = 0x3320646e_3320646e
b[1][1] = 0x3320646e_3320646e
b[2][0] = 0x79622d32_79622d32
b[2][1] = 0x79622d32_79622d32
b[3][0] = 0x6b206574_6b206574
b[3][1] = 0x6b206574_6b206574
// Seed values.
var x64 uint64
var x uint32
x = uint32(seed[0])
x64 = uint64(x)<<32 | uint64(x)
b[4][0] = x64
b[4][1] = x64
x = uint32(seed[0] >> 32)
x64 = uint64(x)<<32 | uint64(x)
b[5][0] = x64
b[5][1] = x64
x = uint32(seed[1])
x64 = uint64(x)<<32 | uint64(x)
b[6][0] = x64
b[6][1] = x64
x = uint32(seed[1] >> 32)
x64 = uint64(x)<<32 | uint64(x)
b[7][0] = x64
b[7][1] = x64
x = uint32(seed[2])
x64 = uint64(x)<<32 | uint64(x)
b[8][0] = x64
b[8][1] = x64
x = uint32(seed[2] >> 32)
x64 = uint64(x)<<32 | uint64(x)
b[9][0] = x64
b[9][1] = x64
x = uint32(seed[3])
x64 = uint64(x)<<32 | uint64(x)
b[10][0] = x64
b[10][1] = x64
x = uint32(seed[3] >> 32)
x64 = uint64(x)<<32 | uint64(x)
b[11][0] = x64
b[11][1] = x64
// Counters.
if goarch.BigEndian {
b[12][0] = uint64(counter+0)<<32 | uint64(counter+1)
b[12][1] = uint64(counter+2)<<32 | uint64(counter+3)
} else {
b[12][0] = uint64(counter+0) | uint64(counter+1)<<32
b[12][1] = uint64(counter+2) | uint64(counter+3)<<32
}
// Zeros.
b[13][0] = 0
b[13][1] = 0
b[14][0] = 0
b[14][1] = 0
b[15][0] = 0
b[15][1] = 0
}
// block_generic is the non-assembly block implementation,
// for use on systems without special assembly.
// Even on such systems, it is quite fast: on GOOS=386,
// ChaCha8 using this code generates random values faster than PCG-DXSM.
func block_generic(seed *[4]uint64, buf *[32]uint64, counter uint32) {
b := (*[16][4]uint32)(unsafe.Pointer(buf))
setup(seed, b, counter)
for i := range b[0] {
// Load block i from b[*][i] into local variables.
b0 := b[0][i]
b1 := b[1][i]
b2 := b[2][i]
b3 := b[3][i]
b4 := b[4][i]
b5 := b[5][i]
b6 := b[6][i]
b7 := b[7][i]
b8 := b[8][i]
b9 := b[9][i]
b10 := b[10][i]
b11 := b[11][i]
b12 := b[12][i]
b13 := b[13][i]
b14 := b[14][i]
b15 := b[15][i]
// 4 iterations of eight quarter-rounds each is 8 rounds
for round := 0; round < 4; round++ {
b0, b4, b8, b12 = qr(b0, b4, b8, b12)
b1, b5, b9, b13 = qr(b1, b5, b9, b13)
b2, b6, b10, b14 = qr(b2, b6, b10, b14)
b3, b7, b11, b15 = qr(b3, b7, b11, b15)
b0, b5, b10, b15 = qr(b0, b5, b10, b15)
b1, b6, b11, b12 = qr(b1, b6, b11, b12)
b2, b7, b8, b13 = qr(b2, b7, b8, b13)
b3, b4, b9, b14 = qr(b3, b4, b9, b14)
}
// Store block i back into b[*][i].
// Add b4..b11 back to the original key material,
// like in ChaCha20, to avoid trivial invertibility.
// There is no entropy in b0..b3 and b12..b15
// so we can skip the additions and save some time.
b[0][i] = b0
b[1][i] = b1
b[2][i] = b2
b[3][i] = b3
b[4][i] += b4
b[5][i] += b5
b[6][i] += b6
b[7][i] += b7
b[8][i] += b8
b[9][i] += b9
b[10][i] += b10
b[11][i] += b11
b[12][i] = b12
b[13][i] = b13
b[14][i] = b14
b[15][i] = b15
}
if goarch.BigEndian {
// On a big-endian system, reading the uint32 pairs as uint64s
// will word-swap them compared to little-endian, so we word-swap
// them here first to make the next swap get the right answer.
for i, x := range buf {
buf[i] = x>>32 | x<<32
}
}
}
// qr is the (inlinable) ChaCha8 quarter round.
func qr(a, b, c, d uint32) (_a, _b, _c, _d uint32) {
a += b
d ^= a
d = d<<16 | d>>16
c += d
b ^= c
b = b<<12 | b>>20
a += b
d ^= a
d = d<<8 | d>>24
c += d
b ^= c
b = b<<7 | b>>25
return a, b, c, d
}

View File

@@ -0,0 +1,21 @@
#if defined(__GNUC__) || defined(__clang__)
void llgo_getcpuid(unsigned int eax, unsigned int ecx,
unsigned int *a, unsigned int *b,
unsigned int *c, unsigned int *d)
{
#if defined(__i386__) || defined(__x86_64__)
__asm__ __volatile__(
"pushq %%rbp\n\t"
"movq %%rsp, %%rbp\n\t"
"andq $-16, %%rsp\n\t" // 16-byte align stack
"cpuid\n\t"
"movq %%rbp, %%rsp\n\t"
"popq %%rbp\n\t"
: "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d)
: "a"(eax), "c"(ecx)
: "memory");
#endif
}
#else
#error This code requires GCC or Clang
#endif

View File

@@ -2,39 +2,28 @@
package cpu
/*
#if defined(__GNUC__) || defined(__clang__)
static void getcpuid(unsigned int eax, unsigned int ecx,
unsigned int *a, unsigned int *b,
unsigned int *c, unsigned int *d) {
#if defined(__i386__) || defined(__x86_64__)
__asm__ __volatile__(
"pushq %%rbp\n\t"
"movq %%rsp, %%rbp\n\t"
"andq $-16, %%rsp\n\t" // 16-byte align stack
"cpuid\n\t"
"movq %%rbp, %%rsp\n\t"
"popq %%rbp\n\t"
: "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d)
: "a"(eax), "c"(ecx)
: "memory"
);
#endif
}
#else
#error This code requires GCC or Clang
#endif
*/
import "C"
import (
_ "unsafe"
c "github.com/goplus/llgo/runtime/internal/clite"
)
const (
LLGoPackage = "link"
LLGoFiles = "_wrap/cpu_x86.c"
)
//go:linkname c_getcpuid C.llgo_getcpuid
func c_getcpuid(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *c.Uint)
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
C.getcpuid(
C.uint(eaxArg),
C.uint(ecxArg),
(*C.uint)(&eax),
(*C.uint)(&ebx),
(*C.uint)(&ecx),
(*C.uint)(&edx),
c_getcpuid(
c.Uint(eaxArg),
c.Uint(ecxArg),
(*c.Uint)(&eax),
(*c.Uint)(&ebx),
(*c.Uint)(&ecx),
(*c.Uint)(&edx),
)
return
}

View File

@@ -0,0 +1,60 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build ignore
package main
import (
"bytes"
"fmt"
"log"
"os"
"strings"
)
var goarches []string
func main() {
data, err := os.ReadFile("../../internal/syslist/syslist.go")
if err != nil {
log.Fatal(err)
}
const goarchPrefix = `var KnownArch = map[string]bool{`
inGOARCH := false
for _, line := range strings.Split(string(data), "\n") {
if strings.HasPrefix(line, goarchPrefix) {
inGOARCH = true
} else if inGOARCH && strings.HasPrefix(line, "}") {
break
} else if inGOARCH {
goarch := strings.Fields(line)[0]
goarch = strings.TrimPrefix(goarch, `"`)
goarch = strings.TrimSuffix(goarch, `":`)
goarches = append(goarches, goarch)
}
}
for _, target := range goarches {
if target == "amd64p32" {
continue
}
var buf bytes.Buffer
fmt.Fprintf(&buf, "// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.\n\n")
fmt.Fprintf(&buf, "//go:build %s\n\n", target) // must explicitly include target for bootstrapping purposes
fmt.Fprintf(&buf, "package goarch\n\n")
fmt.Fprintf(&buf, "const GOARCH = `%s`\n\n", target)
for _, goarch := range goarches {
value := 0
if goarch == target {
value = 1
}
fmt.Fprintf(&buf, "const Is%s = %d\n", strings.Title(goarch), value)
}
err := os.WriteFile("zgoarch_"+target+".go", buf.Bytes(), 0666)
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -0,0 +1,60 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// package goarch contains GOARCH-specific constants.
package goarch
// The next line makes 'go generate' write the zgoarch*.go files with
// per-arch information, including constants named $GOARCH for every
// GOARCH. The constant is 1 on the current system, 0 otherwise; multiplying
// by them is useful for defining GOARCH-specific constants.
//
//go:generate go run gengoarch.go
type ArchFamilyType int
const (
AMD64 ArchFamilyType = iota
ARM
ARM64
I386
LOONG64
MIPS
MIPS64
PPC64
RISCV64
S390X
WASM
)
// PtrSize is the size of a pointer in bytes - unsafe.Sizeof(uintptr(0)) but as an ideal constant.
// It is also the size of the machine's native word size (that is, 4 on 32-bit systems, 8 on 64-bit).
const PtrSize = 4 << (^uintptr(0) >> 63)
// ArchFamily is the architecture family (AMD64, ARM, ...)
const ArchFamily ArchFamilyType = _ArchFamily
// BigEndian reports whether the architecture is big-endian.
const BigEndian = IsArmbe|IsArm64be|IsMips|IsMips64|IsPpc|IsPpc64|IsS390|IsS390x|IsSparc|IsSparc64 == 1
// DefaultPhysPageSize is the default physical page size.
const DefaultPhysPageSize = _DefaultPhysPageSize
// PCQuantum is the minimal unit for a program counter (1 on x86, 4 on most other systems).
// The various PC tables record PC deltas pre-divided by PCQuantum.
const PCQuantum = _PCQuantum
// Int64Align is the required alignment for a 64-bit integer (4 on 32-bit systems, 8 on 64-bit).
const Int64Align = PtrSize
// MinFrameSize is the size of the system-reserved words at the bottom
// of a frame (just above the architectural stack pointer).
// It is zero on x86 and PtrSize on most non-x86 (LR-based) systems.
// On PowerPC it is larger, to cover three more reserved words:
// the compiler word, the link editor word, and the TOC save word.
const MinFrameSize = _MinFrameSize
// StackAlign is the required alignment of the SP register.
// The stack must be at least word aligned, but some architectures require more.
const StackAlign = _StackAlign

View File

@@ -0,0 +1,13 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = I386
_DefaultPhysPageSize = 4096
_PCQuantum = 1
_MinFrameSize = 0
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = AMD64
_DefaultPhysPageSize = 4096
_PCQuantum = 1
_MinFrameSize = 0
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = ARM
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 4
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = ARM64
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = 16
)

View File

@@ -0,0 +1,15 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build loong64
package goarch
const (
_ArchFamily = LOONG64
_DefaultPhysPageSize = 16384
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = MIPS
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 4
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = MIPS64
_DefaultPhysPageSize = 16384
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = MIPS64
_DefaultPhysPageSize = 16384
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = MIPS
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 4
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = PPC64
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 32
_StackAlign = 16
)

View File

@@ -0,0 +1,13 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = PPC64
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 32
_StackAlign = 16
)

View File

@@ -0,0 +1,13 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = RISCV64
_DefaultPhysPageSize = 4096
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = S390X
_DefaultPhysPageSize = 4096
_PCQuantum = 2
_MinFrameSize = 8
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,13 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goarch
const (
_ArchFamily = WASM
_DefaultPhysPageSize = 65536
_PCQuantum = 1
_MinFrameSize = 0
_StackAlign = PtrSize
)

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build 386
package goarch
const GOARCH = `386`
const Is386 = 1
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build amd64
package goarch
const GOARCH = `amd64`
const Is386 = 0
const IsAmd64 = 1
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build arm
package goarch
const GOARCH = `arm`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 1
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build arm64
package goarch
const GOARCH = `arm64`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 1
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build arm64be
package goarch
const GOARCH = `arm64be`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 1
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build armbe
package goarch
const GOARCH = `armbe`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 1
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build loong64
package goarch
const GOARCH = `loong64`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 1
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build mips
package goarch
const GOARCH = `mips`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 1
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build mips64
package goarch
const GOARCH = `mips64`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 1
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build mips64le
package goarch
const GOARCH = `mips64le`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 1
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build mips64p32
package goarch
const GOARCH = `mips64p32`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 1
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build mips64p32le
package goarch
const GOARCH = `mips64p32le`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 1
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build mipsle
package goarch
const GOARCH = `mipsle`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 1
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build ppc
package goarch
const GOARCH = `ppc`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 1
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build ppc64
package goarch
const GOARCH = `ppc64`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 1
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build ppc64le
package goarch
const GOARCH = `ppc64le`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 1
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build riscv
package goarch
const GOARCH = `riscv`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 1
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build riscv64
package goarch
const GOARCH = `riscv64`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 1
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build s390
package goarch
const GOARCH = `s390`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 1
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build s390x
package goarch
const GOARCH = `s390x`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 1
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build sparc
package goarch
const GOARCH = `sparc`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 1
const IsSparc64 = 0
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build sparc64
package goarch
const GOARCH = `sparc64`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 1
const IsWasm = 0

View File

@@ -0,0 +1,32 @@
// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.
//go:build wasm
package goarch
const GOARCH = `wasm`
const Is386 = 0
const IsAmd64 = 0
const IsAmd64p32 = 0
const IsArm = 0
const IsArmbe = 0
const IsArm64 = 0
const IsArm64be = 0
const IsLoong64 = 0
const IsMips = 0
const IsMipsle = 0
const IsMips64 = 0
const IsMips64le = 0
const IsMips64p32 = 0
const IsMips64p32le = 0
const IsPpc = 0
const IsPpc64 = 0
const IsPpc64le = 0
const IsRiscv = 0
const IsRiscv64 = 0
const IsS390 = 0
const IsS390x = 0
const IsSparc = 0
const IsSparc64 = 0
const IsWasm = 1

View File

@@ -7,15 +7,17 @@
// These types are defined here to permit the syscall package to reference them.
package oserror
import "errors"
import (
"github.com/goplus/llgo/runtime/internal/clite/syscall"
)
// llgo:skipall
type _oserror struct{}
var (
ErrInvalid = errors.New("invalid argument")
ErrPermission = errors.New("permission denied")
ErrExist = errors.New("file already exists")
ErrNotExist = errors.New("file does not exist")
ErrClosed = errors.New("file already closed")
ErrInvalid = syscall.ErrInvalid
ErrPermission = syscall.ErrPermission
ErrExist = syscall.ErrExist
ErrNotExist = syscall.ErrNotExist
ErrClosed = syscall.ErrClosed
)

View File

@@ -0,0 +1,19 @@
package atomic
import (
"unsafe"
"github.com/goplus/llgo/runtime/internal/lib/sync/atomic"
)
func casPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
return atomic.CompareAndSwapPointer(ptr, old, new)
}
func storePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
atomic.StorePointer(ptr, new)
}
func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer) {
atomic.StorePointer((*unsafe.Pointer)(ptr), val)
}

View File

@@ -0,0 +1,50 @@
package maps
import (
"unsafe"
"github.com/goplus/llgo/runtime/abi"
)
func rand() uint64 {
panic("not implemented")
}
func fatal(s string) {
panic("fatal: " + s)
}
type Type = abi.Type
type SwissMapType struct {
Type
Key *Type
Elem *Type
Group *Type // internal type representing a slot group
// function for hashing keys (ptr to key, seed) -> hash
Hasher func(unsafe.Pointer, uintptr) uintptr
GroupSize uintptr // == Group.Size_
SlotSize uintptr // size of key/elem slot
ElemOff uintptr // offset of elem in key/elem slot
Flags uint32
}
func mapKeyError(typ *SwissMapType, p unsafe.Pointer) error {
return nil
}
func typedmemmove(typ *abi.Type, dst, src unsafe.Pointer) {
panic("not implemented")
}
func typedmemclr(typ *abi.Type, ptr unsafe.Pointer) {
panic("not implemented")
}
func newobject(typ *abi.Type) unsafe.Pointer {
panic("not implemented")
}
func newarray(typ *abi.Type, n int) unsafe.Pointer {
panic("not implemented")
}

View File

@@ -0,0 +1,5 @@
package sys
func GetCallerPC() uintptr {
panic("not implemented")
}

View File

@@ -0,0 +1,29 @@
package sync
func runtime_canSpin(i int) bool {
panic("not implemented")
}
func runtime_doSpin() {
panic("not implemented")
}
func throw(string) {
panic("not implemented")
}
func fatal(string) {
panic("not implemented")
}
func runtime_nanotime() int64 {
panic("not implemented")
}
func runtime_SemacquireMutex(s *uint32, lifo bool, skipframes int) {
panic("not implemented")
}
func runtime_Semrelease(s *uint32, handoff bool, skipframes int) {
panic("not implemented")
}

View File

@@ -0,0 +1,21 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix
package unix
import "syscall"
func IsNonblock(fd int) (nonblocking bool, err error) {
flag, e1 := Fcntl(fd, syscall.F_GETFL, 0)
if e1 != nil {
return false, e1
}
return flag&syscall.O_NONBLOCK != 0, nil
}
func HasNonblockFlag(flag int) bool {
return flag&syscall.O_NONBLOCK != 0
}

View File

@@ -0,0 +1,17 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package unix
import (
_ "unsafe" // for go:linkname
)
func IsNonblock(fd int) (nonblocking bool, err error) {
panic("not implemented")
}
func HasNonblockFlag(flag int) bool {
panic("not implemented")
}

View File

@@ -17,10 +17,8 @@
package unix
import (
"syscall"
_ "unsafe"
)
func HasNonblockFlag(flag int) bool {
return flag&syscall.O_NONBLOCK != 0
}
// llgo:skip path_filestat_get path_create_directory path_readlink path_unlink_file path_remove_directory Fstatat Mkdirat Readlinkat Unlinkat
type _unix struct{}

View File

@@ -0,0 +1,42 @@
package fs
import (
"io"
"io/fs"
)
func ReadFile(fsys fs.FS, name string) ([]byte, error) {
if fsys, ok := fsys.(fs.ReadFileFS); ok {
return fsys.ReadFile(name)
}
file, err := fsys.Open(name)
if err != nil {
return nil, err
}
var size int
if info, err := file.Stat(); err == nil {
size64 := info.Size()
if int64(int(size64)) == size64 {
size = int(size64)
}
}
data := make([]byte, 0, size+1)
for {
if len(data) >= cap(data) {
d := append(data[:cap(data)], 0)
data = d[:len(data)]
}
n, err := file.Read(data[len(data):cap(data)])
data = data[:len(data)+n]
if err != nil {
if err == io.EOF {
err = nil
}
file.Close()
return data, err
}
}
}

View File

@@ -22,7 +22,7 @@ import (
"sync/atomic"
_ "unsafe" // for go:linkname
"github.com/goplus/llgo/runtime/internal/clite"
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/math/rand"
"github.com/goplus/llgo/runtime/internal/clite/time"
)
@@ -348,7 +348,7 @@ func fastrand64() uint64 {
}
func init() {
rand.Srandom(clite.Uint(time.Time(nil)))
rand.Srandom(c.Uint(time.Time(nil)))
}
// fastSource is an implementation of Source64 that uses the runtime

View File

@@ -8,8 +8,8 @@ import (
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/os"
"github.com/goplus/llgo/runtime/internal/clite/syscall"
"github.com/goplus/llgo/runtime/internal/lib/internal/bytealg"
"github.com/goplus/llgo/runtime/internal/lib/syscall"
)
type readdirMode int
@@ -39,7 +39,7 @@ func (f *File) Readdirnames(n int) (names []string, err error) {
}
func open(path string, flag int, perm uint32) (int, error) {
fd, err := syscall.Open(path, flag, perm)
fd, err := origSyscall.Open(path, flag, perm)
return fd, err
}
@@ -100,10 +100,29 @@ func closedir(dir uintptr) error {
}
//go:linkname c_readdir C.readdir
func c_readdir(dir uintptr) ([]syscall.Dirent, error)
func c_readdir(dir uintptr) *syscall.Dirent
func readdir(dir uintptr) ([]syscall.Dirent, error) {
return c_readdir(dir)
var entries []syscall.Dirent
for {
dirent := c_readdir(dir)
if dirent == nil {
break
}
entries = append(entries, *dirent)
}
return entries, nil
}
func direntNamePtr(name any) *byte {
switch name := name.(type) {
case *byte:
return name
case []byte:
return &name[0]
default:
panic("invalid type")
}
}
func (f *File) ReadDir(n int) (dirents []DirEntry, err error) {
@@ -133,26 +152,26 @@ func (f *File) ReadDir(n int) (dirents []DirEntry, err error) {
for _, entry := range entries {
// Convert syscall.Dirent to fs.DirEntry
name := bytesToString((*[1024]byte)(unsafe.Pointer(&entry.Name[0]))[:])
name := bytesToString((*[1024]byte)(unsafe.Pointer(direntNamePtr(entry.Name)))[:])
if name == "." || name == ".." {
continue
}
typ := fs.FileMode(0)
switch entry.Type {
case origSyscall.DT_REG:
case syscall.DT_REG:
typ = 0
case origSyscall.DT_DIR:
case syscall.DT_DIR:
typ = fs.ModeDir
case origSyscall.DT_LNK:
case syscall.DT_LNK:
typ = fs.ModeSymlink
case origSyscall.DT_SOCK:
case syscall.DT_SOCK:
typ = fs.ModeSocket
case origSyscall.DT_FIFO:
case syscall.DT_FIFO:
typ = fs.ModeNamedPipe
case origSyscall.DT_CHR:
case syscall.DT_CHR:
typ = fs.ModeCharDevice
case origSyscall.DT_BLK:
case syscall.DT_BLK:
typ = fs.ModeDevice
}

View File

@@ -208,15 +208,6 @@ func (f *File) WriteString(s string) (n int, err error) {
panic("todo: os.(*File).WriteString")
}
// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
func setStickyBit(name string) error {
fi, err := Stat(name)
if err != nil {
return err
}
return Chmod(name, fi.Mode()|ModeSticky)
}
// Open opens the named file for reading. If successful, methods on
// the returned file can be used for reading; the associated file
// descriptor has mode O_RDONLY.
@@ -476,7 +467,6 @@ func ReadFile(name string) ([]byte, error) {
if err != nil {
return nil, err
}
defer f.Close()
var size int
if info, err := f.Stat(); err == nil {
@@ -507,6 +497,7 @@ func ReadFile(name string) ([]byte, error) {
if err == io.EOF {
err = nil
}
f.Close()
return data, err
}
}

View File

@@ -80,44 +80,6 @@ func Chdir(dir string) error {
}
*/
func Chmod(name string, mode FileMode) error {
ret := os.Chmod(c.AllocaCStr(name), os.ModeT(syscallMode(mode)))
if ret == 0 {
return nil
}
return toPathErr("chmod", name, ret)
}
/* TODO(xsw):
// Chmod changes the mode of the named file to mode.
// If the file is a symbolic link, it changes the mode of the link's target.
// If there is an error, it will be of type *PathError.
//
// A different subset of the mode bits are used, depending on the
// operating system.
//
// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
// ModeSticky are used.
//
// On Windows, only the 0200 bit (owner writable) of mode is used; it
// controls whether the file's read-only attribute is set or cleared.
// The other bits are currently unused. For compatibility with Go 1.12
// and earlier, use a non-zero mode. Use mode 0400 for a read-only
// file and 0600 for a readable+writable file.
//
// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
// and ModeTemporary are used.
func Chmod(name string, mode FileMode) error { return chmod(name, mode) }
*/
func Chown(name string, uid, gid int) error {
ret := os.Chown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
if ret == 0 {
return nil
}
return toPathErr("chown", name, ret)
}
/* TODO(xsw):
// Chown changes the numeric uid and gid of the named file.
// If the file is a symbolic link, it changes the uid and gid of the link's target.
@@ -152,34 +114,6 @@ func Clearenv()
// func Expand(s string, mapping func(string) string) string
// func ExpandEnv(s string) string
func Getegid() int {
return int(os.Getegid())
}
func Geteuid() int {
return int(os.Geteuid())
}
func Getgid() int {
return int(os.Getgid())
}
// TODO(xsw):
// func Getgroups() ([]int, error)
// func Getpagesize() int
func Getpid() int {
return int(os.Getpid())
}
func Getppid() int {
return int(os.Getppid())
}
func Getuid() int {
return int(os.Getuid())
}
func Getwd() (dir string, err error) {
wd := os.Getcwd(c.Alloca(os.PATH_MAX), os.PATH_MAX)
if wd != nil {
@@ -195,32 +129,6 @@ func Getwd() (dir string, err error) {
// func IsPermission(err error) bool
// func IsTimeout(err error) bool
func Lchown(name string, uid, gid int) error {
ret := os.Lchown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
if ret == 0 {
return nil
}
return toPathErr("lchown", name, ret)
}
/* TODO(xsw):
// Lchown changes the numeric uid and gid of the named file.
// If the file is a symbolic link, it changes the uid and gid of the link itself.
// If there is an error, it will be of type *PathError.
//
// On Windows, it always returns the syscall.EWINDOWS error, wrapped
// in *PathError.
func Lchown(name string, uid, gid int) error {
e := ignoringEINTR(func() error {
return syscall.Lchown(name, uid, gid)
})
if e != nil {
return &PathError{Op: "lchown", Path: name, Err: e}
}
return nil
}
*/
func Link(oldname, newname string) error {
ret := os.Link(c.AllocaCStr(oldname), c.AllocaCStr(newname))
if ret == 0 {

View File

@@ -0,0 +1,109 @@
//go:build !wasm
package os
import (
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/os"
)
// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
func setStickyBit(name string) error {
fi, err := Stat(name)
if err != nil {
return err
}
return Chmod(name, fi.Mode()|ModeSticky)
}
func Chmod(name string, mode FileMode) error {
ret := os.Chmod(c.AllocaCStr(name), os.ModeT(syscallMode(mode)))
if ret == 0 {
return nil
}
return toPathErr("chmod", name, ret)
}
/* TODO(xsw):
// Chmod changes the mode of the named file to mode.
// If the file is a symbolic link, it changes the mode of the link's target.
// If there is an error, it will be of type *PathError.
//
// A different subset of the mode bits are used, depending on the
// operating system.
//
// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
// ModeSticky are used.
//
// On Windows, only the 0200 bit (owner writable) of mode is used; it
// controls whether the file's read-only attribute is set or cleared.
// The other bits are currently unused. For compatibility with Go 1.12
// and earlier, use a non-zero mode. Use mode 0400 for a read-only
// file and 0600 for a readable+writable file.
//
// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
// and ModeTemporary are used.
func Chmod(name string, mode FileMode) error { return chmod(name, mode) }
*/
func Chown(name string, uid, gid int) error {
ret := os.Chown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
if ret == 0 {
return nil
}
return toPathErr("chown", name, ret)
}
func Getegid() int {
return int(os.Getegid())
}
func Geteuid() int {
return int(os.Geteuid())
}
func Getgid() int {
return int(os.Getgid())
}
// TODO(xsw):
// func Getgroups() ([]int, error)
// func Getpagesize() int
func Getpid() int {
return int(os.Getpid())
}
func Getppid() int {
return int(os.Getppid())
}
func Getuid() int {
return int(os.Getuid())
}
func Lchown(name string, uid, gid int) error {
ret := os.Lchown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
if ret == 0 {
return nil
}
return toPathErr("lchown", name, ret)
}
/* TODO(xsw):
// Lchown changes the numeric uid and gid of the named file.
// If the file is a symbolic link, it changes the uid and gid of the link itself.
// If there is an error, it will be of type *PathError.
//
// On Windows, it always returns the syscall.EWINDOWS error, wrapped
// in *PathError.
func Lchown(name string, uid, gid int) error {
e := ignoringEINTR(func() error {
return syscall.Lchown(name, uid, gid)
})
if e != nil {
return &PathError{Op: "lchown", Path: name, Err: e}
}
return nil
}
*/

View File

@@ -0,0 +1,10 @@
package os
// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
func setStickyBit(name string) error {
return nil
}
func Chmod(name string, mode FileMode) error {
return nil
}

View File

@@ -57,3 +57,14 @@ func MkdirAll(path string, perm FileMode) error {
func RemoveAll(path string) error {
return removeAll(path)
}
// endsWithDot reports whether the final component of path is ".".
func endsWithDot(path string) bool {
if path == "." {
return true
}
if len(path) >= 2 && path[len(path)-1] == '.' && IsPathSeparator(path[len(path)-2]) {
return true
}
return false
}

View File

@@ -209,14 +209,3 @@ func openDirAt(dirfd int, name string) (*File, error) {
// We use kindNoPoll because we know that this is a directory.
return newFile(r, name, kindNoPoll), nil
}
// endsWithDot reports whether the final component of path is ".".
func endsWithDot(path string) bool {
if path == "." {
return true
}
if len(path) >= 2 && path[len(path)-1] == '.' && IsPathSeparator(path[len(path)-2]) {
return true
}
return false
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix || (js && wasm) || wasip1
//go:build unix || wasm
package os
@@ -23,7 +23,6 @@ func (f *File) Stat() (FileInfo, error) {
if err != 0 {
return nil, &PathError{Op: "stat", Path: f.name, Err: syscall.Errno(err)}
}
fillFileStatFromSys(&fs, f.name)
return &fs, nil
}
@@ -36,7 +35,6 @@ func statNolog(name string) (FileInfo, error) {
if err != nil {
return nil, &PathError{Op: "stat", Path: name, Err: err}
}
fillFileStatFromSys(&fs, name)
return &fs, nil
}
@@ -49,6 +47,5 @@ func lstatNolog(name string) (FileInfo, error) {
if err != nil {
return nil, &PathError{Op: "lstat", Path: name, Err: err}
}
fillFileStatFromSys(&fs, name)
return &fs, nil
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build js && wasm
//go:build js && !wasm
package os

View File

@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build wasip1
package os
// supportsCloseOnExec reports whether the platform supports the

View File

@@ -707,10 +707,10 @@ func (v Value) Float() float64 {
} else {
switch k {
case Float32:
return float64(bitcast.ToFloat32(uintptr(v.ptr)))
return float64(bitcast.ToFloat32(int32(uintptr(v.ptr))))
case Float64:
if is64bit {
return bitcast.ToFloat64(uintptr(v.ptr))
return bitcast.ToFloat64(int64(uintptr(v.ptr)))
} else {
return *(*float64)(v.ptr)
}
@@ -2845,10 +2845,10 @@ func makeFloat(f flag, v float64, t Type) Value {
var ptr unsafe.Pointer
switch typ.Size() {
case 4:
ptr = unsafe.Pointer(bitcast.FromFloat32(float32(v)))
ptr = unsafe.Pointer(uintptr(bitcast.FromFloat32(float32(v))))
case 8:
if is64bit {
ptr = unsafe.Pointer(bitcast.FromFloat64(v))
ptr = unsafe.Pointer(uintptr(bitcast.FromFloat64(v)))
} else {
ptr = unsafe_New(typ)
*(*float64)(ptr) = v

View File

@@ -0,0 +1,10 @@
#include <unistd.h>
int llgo_maxprocs()
{
#ifdef _SC_NPROCESSORS_ONLN
return (int)sysconf(_SC_NPROCESSORS_ONLN);
#else
return 1;
#endif
}

View File

@@ -0,0 +1,5 @@
package runtime
// const (
// heapAddrBits = (_64bit*(1-goarch.IsWasm)*(1-goos.IsIos*goarch.IsArm64))*48 + (1-_64bit+goarch.IsWasm)*(32-(goarch.IsMips+goarch.IsMipsle)) + 40*goos.IsIos*goarch.IsArm64
// )

View File

@@ -16,27 +16,21 @@
package runtime
/*
#include <unistd.h>
int llgo_maxprocs() {
#ifdef _SC_NPROCESSORS_ONLN
return (int)sysconf(_SC_NPROCESSORS_ONLN);
#else
return 1;
#endif
}
*/
import "C"
import (
"unsafe"
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/runtime"
)
// llgo:skipall
type _runtime struct{}
const (
LLGoPackage = "link"
LLGoFiles = "_wrap/runtime.c"
)
// GOROOT returns the root of the Go tree. It uses the
// GOROOT environment variable, if set at process start,
// or else the root used during the Go build.
@@ -58,6 +52,11 @@ func Goexit() {
func KeepAlive(x any) {
}
//go:linkname c_write C.write
func c_write(fd c.Int, p unsafe.Pointer, n c.SizeT) int32
func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
return int32(C.write(C.int(fd), p, C.size_t(n)))
return int32(c_write(c.Int(fd), p, c.SizeT(n)))
}
const heapArenaBytes = 1024 * 1024

View File

@@ -4,9 +4,7 @@
package runtime
import (
"runtime"
)
import "runtime"
// Layout of in-memory per-function information prepared by linker
// See https://golang.org/s/go12symtab.

View File

@@ -101,3 +101,37 @@ func OrInt64(addr *int64, mask int64) (old int64) {
func OrUint64(addr *uint64, mask uint64) (old uint64) {
panic("implement by llgo instruction")
}
// ----------------------------------------------------------------------------
// llgo:link AndInt32 llgo.atomicAnd
func AndInt32(addr *int32, mask int32) (old int32) {
panic("implement by llgo instruction")
}
// llgo:link AndUint32 llgo.atomicAnd
func AndUint32(addr *uint32, mask uint32) (old uint32) {
panic("implement by llgo instruction")
}
// llgo:link OrInt32 llgo.atomicOr
func OrInt32(addr *int32, mask int32) (old int32) {
panic("implement by llgo instruction")
}
// llgo:link OrUint32 llgo.atomicOr
func OrUint32(addr *uint32, mask uint32) (old uint32) {
panic("implement by llgo instruction")
}
// ----------------------------------------------------------------------------
// llgo:link AndUintptr llgo.atomicAnd
func AndUintptr(addr *uintptr, mask uintptr) (old uintptr) {
panic("implement by llgo instruction")
}
// llgo:link OrUintptr llgo.atomicOr
func OrUintptr(addr *uintptr, mask uintptr) (old uintptr) {
panic("implement by llgo instruction")
}

View File

@@ -19,7 +19,9 @@ package sync
import (
"runtime"
gosync "sync"
_ "unsafe"
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/pthread/sync"
"github.com/goplus/llgo/runtime/internal/lib/sync/atomic"
)
@@ -62,8 +64,12 @@ func (m *Mutex) TryLock() bool {
return (*sync.Mutex)(&m.Mutex).TryLock() == 0
}
// llgo:link (*Mutex).Unlock C.pthread_mutex_unlock
func (m *Mutex) Unlock() {}
//go:linkname c_pthread_mutex_unlock C.pthread_mutex_unlock
func c_pthread_mutex_unlock(m *Mutex) c.Int
func (m *Mutex) Unlock() {
c_pthread_mutex_unlock(m)
}
// -----------------------------------------------------------------------------
@@ -94,8 +100,12 @@ func (rw *RWMutex) TryRLock() bool {
return (*sync.RWLock)(&rw.RWLock).TryRLock() == 0
}
// llgo:link (*RWMutex).RUnlock C.pthread_rwlock_unlock
func (rw *RWMutex) RUnlock() {}
//go:linkname c_pthread_rwlock_unlock C.pthread_rwlock_unlock
func c_pthread_rwlock_unlock(rw *RWMutex) c.Int
func (rw *RWMutex) RUnlock() {
c_pthread_rwlock_unlock(rw)
}
func (rw *RWMutex) Lock() {
rw.ensureInit()
@@ -107,8 +117,9 @@ func (rw *RWMutex) TryLock() bool {
return (*sync.RWLock)(&rw.RWLock).TryLock() == 0
}
// llgo:link (*RWMutex).Unlock C.pthread_rwlock_unlock
func (rw *RWMutex) Unlock() {}
func (rw *RWMutex) Unlock() {
c_pthread_rwlock_unlock(rw)
}
// -----------------------------------------------------------------------------
@@ -144,11 +155,19 @@ func NewCond(l gosync.Locker) *Cond {
return ret
}
// llgo:link (*Cond).Signal C.pthread_cond_signal
func (c *Cond) Signal() {}
//go:linkname c_pthread_cond_signal C.pthread_cond_signal
func c_pthread_cond_signal(c *Cond) c.Int
// llgo:link (*Cond).Broadcast C.pthread_cond_broadcast
func (c *Cond) Broadcast() {}
//go:linkname c_pthread_cond_broadcast C.pthread_cond_broadcast
func c_pthread_cond_broadcast(c *Cond) c.Int
func (c *Cond) Signal() {
c_pthread_cond_signal(c)
}
func (c *Cond) Broadcast() {
c_pthread_cond_broadcast(c)
}
func (c *Cond) Wait() {
c.cond.Wait(c.m)

View File

@@ -724,7 +724,7 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
childerror:
// send error code on pipe
os.Write(c.Int(pipe), unsafe.Pointer(&err1), unsafe.Sizeof(err1))
os.Write(c.Int(pipe), unsafe.Pointer(&err1), c.SizeT(unsafe.Sizeof(err1)))
for {
os.Exit(253)
}

View File

@@ -0,0 +1,325 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build wasip1
package syscall
import (
"structs"
)
func init() {
// Try to set stdio to non-blocking mode before the os package
// calls NewFile for each fd. NewFile queries the non-blocking flag
// but doesn't change it, even if the runtime supports non-blocking
// stdio. Since WebAssembly modules are single-threaded, blocking
// system calls temporarily halt execution of the module. If the
// runtime supports non-blocking stdio, the Go runtime is able to
// use the WASI net poller to poll for read/write readiness and is
// able to schedule goroutines while waiting.
SetNonblock(0, true)
SetNonblock(1, true)
SetNonblock(2, true)
}
type uintptr32 = uint32
type size = uint32
type fdflags = uint32
type filesize = uint64
type filetype = uint8
type lookupflags = uint32
type oflags = uint32
type rights = uint64
type timestamp = uint64
type dircookie = uint64
type filedelta = int64
type fstflags = uint32
type iovec struct {
_ structs.HostLayout
buf uintptr32
bufLen size
}
const (
LOOKUP_SYMLINK_FOLLOW = 0x00000001
)
const (
OFLAG_CREATE = 0x0001
OFLAG_DIRECTORY = 0x0002
OFLAG_EXCL = 0x0004
OFLAG_TRUNC = 0x0008
)
const (
FDFLAG_APPEND = 0x0001
FDFLAG_DSYNC = 0x0002
FDFLAG_NONBLOCK = 0x0004
FDFLAG_RSYNC = 0x0008
FDFLAG_SYNC = 0x0010
)
const (
RIGHT_FD_DATASYNC = 1 << iota
RIGHT_FD_READ
RIGHT_FD_SEEK
RIGHT_FDSTAT_SET_FLAGS
RIGHT_FD_SYNC
RIGHT_FD_TELL
RIGHT_FD_WRITE
RIGHT_FD_ADVISE
RIGHT_FD_ALLOCATE
RIGHT_PATH_CREATE_DIRECTORY
RIGHT_PATH_CREATE_FILE
RIGHT_PATH_LINK_SOURCE
RIGHT_PATH_LINK_TARGET
RIGHT_PATH_OPEN
RIGHT_FD_READDIR
RIGHT_PATH_READLINK
RIGHT_PATH_RENAME_SOURCE
RIGHT_PATH_RENAME_TARGET
RIGHT_PATH_FILESTAT_GET
RIGHT_PATH_FILESTAT_SET_SIZE
RIGHT_PATH_FILESTAT_SET_TIMES
RIGHT_FD_FILESTAT_GET
RIGHT_FD_FILESTAT_SET_SIZE
RIGHT_FD_FILESTAT_SET_TIMES
RIGHT_PATH_SYMLINK
RIGHT_PATH_REMOVE_DIRECTORY
RIGHT_PATH_UNLINK_FILE
RIGHT_POLL_FD_READWRITE
RIGHT_SOCK_SHUTDOWN
RIGHT_SOCK_ACCEPT
)
const (
WHENCE_SET = 0
WHENCE_CUR = 1
WHENCE_END = 2
)
const (
FILESTAT_SET_ATIM = 0x0001
FILESTAT_SET_ATIM_NOW = 0x0002
FILESTAT_SET_MTIM = 0x0004
FILESTAT_SET_MTIM_NOW = 0x0008
)
const (
// Despite the rights being defined as a 64 bits integer in the spec,
// wasmtime crashes the program if we set any of the upper 32 bits.
fullRights = rights(^uint32(0))
readRights = rights(RIGHT_FD_READ | RIGHT_FD_READDIR)
writeRights = rights(RIGHT_FD_DATASYNC | RIGHT_FD_WRITE | RIGHT_FD_ALLOCATE | RIGHT_PATH_FILESTAT_SET_SIZE)
// Some runtimes have very strict expectations when it comes to which
// rights can be enabled on files opened by path_open. The fileRights
// constant is used as a mask to retain only bits for operations that
// are supported on files.
fileRights rights = RIGHT_FD_DATASYNC |
RIGHT_FD_READ |
RIGHT_FD_SEEK |
RIGHT_FDSTAT_SET_FLAGS |
RIGHT_FD_SYNC |
RIGHT_FD_TELL |
RIGHT_FD_WRITE |
RIGHT_FD_ADVISE |
RIGHT_FD_ALLOCATE |
RIGHT_PATH_CREATE_DIRECTORY |
RIGHT_PATH_CREATE_FILE |
RIGHT_PATH_LINK_SOURCE |
RIGHT_PATH_LINK_TARGET |
RIGHT_PATH_OPEN |
RIGHT_FD_READDIR |
RIGHT_PATH_READLINK |
RIGHT_PATH_RENAME_SOURCE |
RIGHT_PATH_RENAME_TARGET |
RIGHT_PATH_FILESTAT_GET |
RIGHT_PATH_FILESTAT_SET_SIZE |
RIGHT_PATH_FILESTAT_SET_TIMES |
RIGHT_FD_FILESTAT_GET |
RIGHT_FD_FILESTAT_SET_SIZE |
RIGHT_FD_FILESTAT_SET_TIMES |
RIGHT_PATH_SYMLINK |
RIGHT_PATH_REMOVE_DIRECTORY |
RIGHT_PATH_UNLINK_FILE |
RIGHT_POLL_FD_READWRITE
// Runtimes like wasmtime and wasmedge will refuse to open directories
// if the rights requested by the application exceed the operations that
// can be performed on a directory.
dirRights rights = RIGHT_FD_SEEK |
RIGHT_FDSTAT_SET_FLAGS |
RIGHT_FD_SYNC |
RIGHT_PATH_CREATE_DIRECTORY |
RIGHT_PATH_CREATE_FILE |
RIGHT_PATH_LINK_SOURCE |
RIGHT_PATH_LINK_TARGET |
RIGHT_PATH_OPEN |
RIGHT_FD_READDIR |
RIGHT_PATH_READLINK |
RIGHT_PATH_RENAME_SOURCE |
RIGHT_PATH_RENAME_TARGET |
RIGHT_PATH_FILESTAT_GET |
RIGHT_PATH_FILESTAT_SET_SIZE |
RIGHT_PATH_FILESTAT_SET_TIMES |
RIGHT_FD_FILESTAT_GET |
RIGHT_FD_FILESTAT_SET_TIMES |
RIGHT_PATH_SYMLINK |
RIGHT_PATH_REMOVE_DIRECTORY |
RIGHT_PATH_UNLINK_FILE
)
type preopentype = uint8
const (
preopentypeDir preopentype = iota
)
type prestatDir struct {
_ structs.HostLayout
prNameLen size
}
type prestat struct {
_ structs.HostLayout
typ preopentype
dir prestatDir
}
//go:wasmimport wasi_snapshot_preview1 fd_prestat_get
//go:noescape
func fd_prestat_get(fd int32, prestat *prestat) Errno
//go:wasmimport wasi_snapshot_preview1 fd_prestat_dir_name
//go:noescape
func fd_prestat_dir_name(fd int32, path *byte, pathLen size) Errno
type opendir struct {
fd int32
name string
}
// List of preopen directories that were exposed by the runtime. The first one
// is assumed to the be root directory of the file system, and others are seen
// as mount points at sub paths of the root.
var preopens []opendir
// Current working directory. We maintain this as a string and resolve paths in
// the code because wasmtime does not allow relative path lookups outside of the
// scope of a directory; a previous approach we tried consisted in maintaining
// open a file descriptor to the current directory so we could perform relative
// path lookups from that location, but it resulted in breaking path resolution
// from the current directory to its parent.
var cwd string
func Openat(dirFd int, path string, openmode int, perm uint32) (int, error) {
panic("not implemented")
}
func CloseOnExec(fd int) {
// nothing to do - no exec
}
func Mkdir(path string, perm uint32) error {
panic("not implemented")
}
func ReadDir(fd int, buf []byte, cookie dircookie) (int, error) {
panic("not implemented")
}
func Fstat(fd int, st *Stat_t) error {
panic("not implemented")
}
func Unlink(path string) error {
panic("not implemented")
}
func Rmdir(path string) error {
panic("not implemented")
}
func Chmod(path string, mode uint32) error {
var stat Stat_t
return Stat(path, &stat)
}
func Fchmod(fd int, mode uint32) error {
var stat Stat_t
return Fstat(fd, &stat)
}
func Chown(path string, uid, gid int) error {
panic("not implemented")
}
func Fchown(fd int, uid, gid int) error {
panic("not implemented")
}
func Lchown(path string, uid, gid int) error {
panic("not implemented")
}
func UtimesNano(path string, ts []Timespec) error {
panic("not implemented")
}
func Rename(from, to string) error {
panic("not implemented")
}
func Truncate(path string, length int64) error {
panic("not implemented")
}
func Ftruncate(fd int, length int64) error {
panic("not implemented")
}
const ImplementsGetwd = true
func Chdir(path string) error {
panic("not implemented")
}
func Readlink(path string, buf []byte) (n int, err error) {
panic("not implemented")
}
func Link(path, link string) error {
panic("not implemented")
}
func Symlink(path, link string) error {
panic("not implemented")
}
func Fsync(fd int) error {
panic("not implemented")
}
func Write(fd int, b []byte) (int, error) {
panic("not implemented")
}
func Pread(fd int, b []byte, offset int64) (int, error) {
panic("not implemented")
}
func Pwrite(fd int, b []byte, offset int64) (int, error) {
panic("not implemented")
}
func Dup(fd int) (int, error) {
panic("not implemented")
}
func Dup2(fd, newfd int) error {
panic("not implemented")
}

View File

@@ -0,0 +1,81 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build wasip1
package syscall
import "syscall"
const (
SHUT_RD = 0x1
SHUT_WR = 0x2
SHUT_RDWR = SHUT_RD | SHUT_WR
)
type sdflags = uint32
//go:wasmimport wasi_snapshot_preview1 sock_accept
//go:noescape
func sock_accept(fd int32, flags fdflags, newfd *int32) Errno
//go:wasmimport wasi_snapshot_preview1 sock_shutdown
//go:noescape
func sock_shutdown(fd int32, flags sdflags) Errno
func Socket(proto, sotype, unused int) (fd int, err error) {
panic("not implemented")
}
func Bind(fd int, sa syscall.Sockaddr) error {
panic("not implemented")
}
func StopIO(fd int) error {
panic("not implemented")
}
func Listen(fd int, backlog int) error {
panic("not implemented")
}
func Connect(fd int, sa syscall.Sockaddr) error {
panic("not implemented")
}
func Recvfrom(fd int, p []byte, flags int) (n int, from syscall.Sockaddr, err error) {
panic("not implemented")
}
func Sendto(fd int, p []byte, flags int, to syscall.Sockaddr) error {
panic("not implemented")
}
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from syscall.Sockaddr, err error) {
panic("not implemented")
}
func SendmsgN(fd int, p, oob []byte, to syscall.Sockaddr, flags int) (n int, err error) {
panic("not implemented")
}
func GetsockoptInt(fd, level, opt int) (value int, err error) {
panic("not implemented")
}
func SetsockoptInt(fd, level, opt int, value int) error {
panic("not implemented")
}
func SetReadDeadline(fd int, t int64) error {
panic("not implemented")
}
func SetWriteDeadline(fd int, t int64) error {
panic("not implemented")
}
func Shutdown(fd int, how int) error {
panic("not implemented")
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix
//go:build unix && !wasm
package syscall

View File

@@ -83,30 +83,6 @@ func Getpid() (pid int) {
return int(os.Getpid())
}
func Kill(pid int, signum Signal) (err error) {
ret := os.Kill(os.PidT(pid), c.Int(signum))
if ret == 0 {
return nil
}
return Errno(ret)
}
func fork() (uintptr, Errno) {
ret := os.Fork()
if ret >= 0 {
return uintptr(ret), Errno(0)
}
return 0, Errno(os.Errno())
}
func wait4(pid int, wstatus *c.Int, options int, rusage *syscall.Rusage) (wpid int, err error) {
ret := os.Wait4(os.PidT(pid), wstatus, c.Int(options), rusage)
if ret >= 0 {
return int(ret), nil
}
return 0, Errno(os.Errno())
}
func Open(path string, mode int, perm uint32) (fd int, err error) {
ret := os.Open(c.AllocaCStr(path), c.Int(mode), os.ModeT(perm))
if ret >= 0 {
@@ -165,38 +141,6 @@ func Stat(path string, stat *Stat_t) (err error) {
return Errno(os.Errno())
}
func Pipe(p []int) (err error) {
if len(p) != 2 {
return Errno(syscall.EINVAL)
}
var q [2]c.Int
ret := os.Pipe(&q)
if ret == 0 {
p[0] = int(q[0])
p[1] = int(q[1])
return nil
}
return Errno(ret)
}
type Rlimit syscall.Rlimit
func Getrlimit(which int, lim *Rlimit) (err error) {
ret := os.Getrlimit(c.Int(which), (*syscall.Rlimit)(lim))
if ret == 0 {
return nil
}
return Errno(ret)
}
func setrlimit(which int, lim *Rlimit) (err error) {
ret := os.Setrlimit(c.Int(which), (*syscall.Rlimit)(lim))
if ret == 0 {
return nil
}
return Errno(ret)
}
func BytePtrFromString(s string) (*byte, error) {
a, err := ByteSliceFromString(s)
if err != nil {
@@ -217,3 +161,7 @@ func ByteSliceFromString(s string) ([]byte, error) {
func Accept(fd int) (nfd int, sa origSyscall.Sockaddr, err error) {
panic("todo: syscall.Accept")
}
func Kill(pid int, signum Signal) error {
return syscall.Kill(pid, syscall.Signal(signum))
}

View File

@@ -0,0 +1,57 @@
//go:build !wasm
package syscall
import (
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/os"
"github.com/goplus/llgo/runtime/internal/clite/syscall"
)
type Rlimit syscall.Rlimit
func Getrlimit(which int, lim *Rlimit) (err error) {
ret := os.Getrlimit(c.Int(which), (*syscall.Rlimit)(lim))
if ret == 0 {
return nil
}
return Errno(ret)
}
func setrlimit(which int, lim *Rlimit) (err error) {
ret := os.Setrlimit(c.Int(which), (*syscall.Rlimit)(lim))
if ret == 0 {
return nil
}
return Errno(ret)
}
func wait4(pid int, wstatus *c.Int, options int, rusage *syscall.Rusage) (wpid int, err error) {
ret := os.Wait4(os.PidT(pid), wstatus, c.Int(options), rusage)
if ret >= 0 {
return int(ret), nil
}
return 0, Errno(os.Errno())
}
func fork() (uintptr, Errno) {
ret := os.Fork()
if ret >= 0 {
return uintptr(ret), Errno(0)
}
return 0, Errno(os.Errno())
}
func Pipe(p []int) (err error) {
if len(p) != 2 {
return Errno(syscall.EINVAL)
}
var q [2]c.Int
ret := os.Pipe(&q)
if ret == 0 {
p[0] = int(q[0])
p[1] = int(q[1])
return nil
}
return Errno(ret)
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix
//go:build unix && !wasm
package syscall

View File

@@ -0,0 +1,366 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build wasip1
package syscall
import (
"strconv"
"github.com/goplus/llgo/runtime/internal/clite/syscall"
)
const (
DT_UNKNOWN = 0
DT_FIFO = 1
DT_CHR = 2
DT_DIR = 4
DT_BLK = 6
DT_REG = 8
DT_LNK = 10
DT_SOCK = 12
DT_WHT = 14
)
type Dircookie = uint64
type Filetype = uint8
const (
FILETYPE_UNKNOWN Filetype = iota
FILETYPE_BLOCK_DEVICE
FILETYPE_CHARACTER_DEVICE
FILETYPE_DIRECTORY
FILETYPE_REGULAR_FILE
FILETYPE_SOCKET_DGRAM
FILETYPE_SOCKET_STREAM
FILETYPE_SYMBOLIC_LINK
)
type Dirent struct {
// The offset of the next directory entry stored in this directory.
Next Dircookie
// The serial number of the file referred to by this directory entry.
Ino uint64
// The length of the name of the directory entry.
Namlen uint32
// The type of the file referred to by this directory entry.
Type Filetype
// Name of the directory entry.
Name *byte
}
// An Errno is an unsigned number describing an error condition.
// It implements the error interface. The zero Errno is by convention
// a non-error, so code to convert from Errno to error should use:
//
// var err = nil
// if errno != 0 {
// err = errno
// }
type Errno syscall.Errno
func (e Errno) Error() string {
return syscall.Errno(e).Error()
}
func (e Errno) Is(target error) bool {
return syscall.Errno(e).Is(target)
}
// A Signal is a number describing a process signal.
// It implements the [os.Signal] interface.
type Signal uint8
const (
SIGNONE Signal = iota
SIGHUP
SIGINT
SIGQUIT
SIGILL
SIGTRAP
SIGABRT
SIGBUS
SIGFPE
SIGKILL
SIGUSR1
SIGSEGV
SIGUSR2
SIGPIPE
SIGALRM
SIGTERM
SIGCHLD
SIGCONT
SIGSTOP
SIGTSTP
SIGTTIN
SIGTTOU
SIGURG
SIGXCPU
SIGXFSZ
SIGVTARLM
SIGPROF
SIGWINCH
SIGPOLL
SIGPWR
SIGSYS
)
func (s Signal) Signal() {}
func (s Signal) String() string {
switch s {
case SIGNONE:
return "no signal"
case SIGHUP:
return "hangup"
case SIGINT:
return "interrupt"
case SIGQUIT:
return "quit"
case SIGILL:
return "illegal instruction"
case SIGTRAP:
return "trace/breakpoint trap"
case SIGABRT:
return "abort"
case SIGBUS:
return "bus error"
case SIGFPE:
return "floating point exception"
case SIGKILL:
return "killed"
case SIGUSR1:
return "user defined signal 1"
case SIGSEGV:
return "segmentation fault"
case SIGUSR2:
return "user defined signal 2"
case SIGPIPE:
return "broken pipe"
case SIGALRM:
return "alarm clock"
case SIGTERM:
return "terminated"
case SIGCHLD:
return "child exited"
case SIGCONT:
return "continued"
case SIGSTOP:
return "stopped (signal)"
case SIGTSTP:
return "stopped"
case SIGTTIN:
return "stopped (tty input)"
case SIGTTOU:
return "stopped (tty output)"
case SIGURG:
return "urgent I/O condition"
case SIGXCPU:
return "CPU time limit exceeded"
case SIGXFSZ:
return "file size limit exceeded"
case SIGVTARLM:
return "virtual timer expired"
case SIGPROF:
return "profiling timer expired"
case SIGWINCH:
return "window changed"
case SIGPOLL:
return "I/O possible"
case SIGPWR:
return "power failure"
case SIGSYS:
return "bad system call"
default:
return "signal " + strconv.Itoa(int(s))
}
}
const (
Stdin = 0
Stdout = 1
Stderr = 2
)
const (
O_RDONLY = 0
O_WRONLY = 1
O_RDWR = 2
O_CREAT = 0100
O_CREATE = O_CREAT
O_TRUNC = 01000
O_APPEND = 02000
O_EXCL = 0200
O_SYNC = 010000
O_DIRECTORY = 020000
O_NOFOLLOW = 0400
O_CLOEXEC = 0
)
const (
F_DUPFD = 0
F_GETFD = 1
F_SETFD = 2
F_GETFL = 3
F_SETFL = 4
F_GETOWN = 5
F_SETOWN = 6
F_GETLK = 7
F_SETLK = 8
F_SETLKW = 9
F_RGETLK = 10
F_RSETLK = 11
F_CNVT = 12
F_RSETLKW = 13
F_RDLCK = 1
F_WRLCK = 2
F_UNLCK = 3
F_UNLKSYS = 4
)
const (
S_IFMT = 0000370000
S_IFSHM_SYSV = 0000300000
S_IFSEMA = 0000270000
S_IFCOND = 0000260000
S_IFMUTEX = 0000250000
S_IFSHM = 0000240000
S_IFBOUNDSOCK = 0000230000
S_IFSOCKADDR = 0000220000
S_IFDSOCK = 0000210000
S_IFSOCK = 0000140000
S_IFLNK = 0000120000
S_IFREG = 0000100000
S_IFBLK = 0000060000
S_IFDIR = 0000040000
S_IFCHR = 0000020000
S_IFIFO = 0000010000
S_UNSUP = 0000370000
S_ISUID = 0004000
S_ISGID = 0002000
S_ISVTX = 0001000
S_IREAD = 0400
S_IWRITE = 0200
S_IEXEC = 0100
S_IRWXU = 0700
S_IRUSR = 0400
S_IWUSR = 0200
S_IXUSR = 0100
S_IRWXG = 070
S_IRGRP = 040
S_IWGRP = 020
S_IXGRP = 010
S_IRWXO = 07
S_IROTH = 04
S_IWOTH = 02
S_IXOTH = 01
)
type WaitStatus uint32
func (w WaitStatus) Exited() bool { return false }
func (w WaitStatus) ExitStatus() int { return 0 }
func (w WaitStatus) Signaled() bool { return false }
func (w WaitStatus) Signal() Signal { return 0 }
func (w WaitStatus) CoreDump() bool { return false }
func (w WaitStatus) Stopped() bool { return false }
func (w WaitStatus) Continued() bool { return false }
func (w WaitStatus) StopSignal() Signal { return 0 }
func (w WaitStatus) TrapCause() int { return 0 }
// Rusage is a placeholder to allow compilation of the [os/exec] package
// because we need Go programs to be portable across platforms. WASI does
// not have a mechanism to spawn processes so there is no reason for an
// application to take a dependency on this type.
type Rusage struct {
Utime Timeval
Stime Timeval
}
// ProcAttr is a placeholder to allow compilation of the [os/exec] package
// because we need Go programs to be portable across platforms. WASI does
// not have a mechanism to spawn processes so there is no reason for an
// application to take a dependency on this type.
type ProcAttr struct {
Dir string
Env []string
Files []uintptr
Sys *SysProcAttr
}
type SysProcAttr struct {
}
func Getuid() int {
return 1
}
func Getgid() int {
return 1
}
func Geteuid() int {
return 1
}
func Getegid() int {
return 1
}
func Getgroups() ([]int, error) {
return []int{1}, nil
}
func Getppid() int {
return 2
}
func Umask(mask int) int {
return 0
}
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
type clockid = uint32
const (
clockRealtime clockid = iota
clockMonotonic
clockProcessCPUTimeID
clockThreadCPUTimeID
)
func SetNonblock(fd int, nonblocking bool) error {
panic("todo: syscall.SetNonblock")
}
const (
RLIMIT_NOFILE = iota
)
func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
panic("not implemented")
}
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
panic("not implemented")
}

View File

@@ -6,10 +6,8 @@ package time
import (
"sync"
"unsafe"
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/libuv"
)
// Sleep pauses the current goroutine for at least the duration d.
@@ -21,7 +19,7 @@ func Sleep(d Duration) {
// Interface to timers implemented in package runtime.
// Must be in sync with ../runtime/time.go:/^type timer
type runtimeTimer struct {
libuv.Timer
// libuv.Timer
when int64
f func(any, uintptr)
arg any
@@ -178,62 +176,65 @@ func goFunc(arg any, seq uintptr) {
}
var (
timerLoop *libuv.Loop
// timerLoop *libuv.Loop
timerOnce sync.Once
)
func init() {
timerOnce.Do(func() {
timerLoop = libuv.LoopNew()
})
go func() {
timerLoop.Run(libuv.RUN_DEFAULT)
}()
}
// func init() {
// timerOnce.Do(func() {
// timerLoop = libuv.LoopNew()
// })
// go func() {
// timerLoop.Run(libuv.RUN_DEFAULT)
// }()
// }
// cross thread
func timerEvent(async *libuv.Async) {
a := (*asyncTimerEvent)(unsafe.Pointer(async))
a.cb()
a.Close(nil)
}
// func timerEvent(async *libuv.Async) {
// a := (*asyncTimerEvent)(unsafe.Pointer(async))
// a.cb()
// a.Close(nil)
// }
type asyncTimerEvent struct {
libuv.Async
// libuv.Async
cb func()
}
func timerCallback(t *libuv.Timer) {
}
// func timerCallback(t *libuv.Timer) {
// }
func startTimer(r *runtimeTimer) {
asyncTimer := &asyncTimerEvent{
cb: func() {
libuv.InitTimer(timerLoop, &r.Timer)
r.Start(timerCallback, uint64(r.when), 0)
},
}
timerLoop.Async(&asyncTimer.Async, timerEvent)
asyncTimer.Send()
panic("not implemented")
// asyncTimer := &asyncTimerEvent{
// cb: func() {
// libuv.InitTimer(timerLoop, &r.Timer)
// r.Start(timerCallback, uint64(r.when), 0)
// },
// }
// timerLoop.Async(&asyncTimer.Async, timerEvent)
// asyncTimer.Send()
}
func stopTimer(r *runtimeTimer) bool {
asyncTimer := &asyncTimerEvent{
cb: func() {
r.Stop()
},
}
timerLoop.Async(&asyncTimer.Async, timerEvent)
return asyncTimer.Send() == 0
panic("not implemented")
// asyncTimer := &asyncTimerEvent{
// cb: func() {
// r.Stop()
// },
// }
// timerLoop.Async(&asyncTimer.Async, timerEvent)
// return asyncTimer.Send() == 0
}
func resetTimer(r *runtimeTimer, when int64) bool {
asyncTimer := &asyncTimerEvent{
cb: func() {
r.Stop()
r.Start(timerCallback, uint64(when), 0)
},
}
timerLoop.Async(&asyncTimer.Async, timerEvent)
return asyncTimer.Send() == 0
panic("not implemented")
// asyncTimer := &asyncTimerEvent{
// cb: func() {
// r.Stop()
// r.Start(timerCallback, uint64(when), 0)
// },
// }
// timerLoop.Async(&asyncTimer.Async, timerEvent)
// return asyncTimer.Send() == 0
}

View File

@@ -0,0 +1,12 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package time
// in wasip1 zoneinfo is managed by the runtime.
var platformZoneSources = []string{}
func initLocal() {
localLoc.name = "Local"
}