mirror of https://github.com/tinygo-org/tinygo.git
Ayke van Laethem
2 years ago
committed by
Ron Evans
33 changed files with 249 additions and 628 deletions
@ -1,18 +0,0 @@ |
|||
//go:build go1.18
|
|||
// +build go1.18
|
|||
|
|||
package compiler |
|||
|
|||
// Workaround for Go 1.17 support. Should be removed once we drop Go 1.17
|
|||
// support.
|
|||
|
|||
import "go/types" |
|||
|
|||
func init() { |
|||
typeParamUnderlyingType = func(t types.Type) types.Type { |
|||
if t, ok := t.(*types.TypeParam); ok { |
|||
return t.Underlying() |
|||
} |
|||
return t |
|||
} |
|||
} |
@ -1,41 +0,0 @@ |
|||
package main |
|||
|
|||
// Test changes to the language introduced in Go 1.17.
|
|||
// For details, see: https://tip.golang.org/doc/go1.17#language
|
|||
// These tests should be merged into the regular slice tests once Go 1.17 is the
|
|||
// minimun Go version for TinyGo.
|
|||
|
|||
import "unsafe" |
|||
|
|||
func Add32(p unsafe.Pointer, len int) unsafe.Pointer { |
|||
return unsafe.Add(p, len) |
|||
} |
|||
|
|||
func Add64(p unsafe.Pointer, len int64) unsafe.Pointer { |
|||
return unsafe.Add(p, len) |
|||
} |
|||
|
|||
func SliceToArray(s []int) *[4]int { |
|||
return (*[4]int)(s) |
|||
} |
|||
|
|||
func SliceToArrayConst() *[4]int { |
|||
s := make([]int, 6) |
|||
return (*[4]int)(s) |
|||
} |
|||
|
|||
func SliceInt(ptr *int, len int) []int { |
|||
return unsafe.Slice(ptr, len) |
|||
} |
|||
|
|||
func SliceUint16(ptr *byte, len uint16) []byte { |
|||
return unsafe.Slice(ptr, len) |
|||
} |
|||
|
|||
func SliceUint64(ptr *int, len uint64) []int { |
|||
return unsafe.Slice(ptr, len) |
|||
} |
|||
|
|||
func SliceInt64(ptr *int, len int64) []int { |
|||
return unsafe.Slice(ptr, len) |
|||
} |
@ -1,161 +0,0 @@ |
|||
; ModuleID = 'go1.17.go' |
|||
source_filename = "go1.17.go" |
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" |
|||
target triple = "wasm32-unknown-wasi" |
|||
|
|||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 |
|||
|
|||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden void @main.init(i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
ret void |
|||
} |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%0 = getelementptr i8, i8* %p, i32 %len |
|||
call void @runtime.trackPointer(i8* %0, i8* undef) #2 |
|||
ret i8* %0 |
|||
} |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%0 = trunc i64 %len to i32 |
|||
%1 = getelementptr i8, i8* %p, i32 %0 |
|||
call void @runtime.trackPointer(i8* %1, i8* undef) #2 |
|||
ret i8* %1 |
|||
} |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden [4 x i32]* @main.SliceToArray(i32* %s.data, i32 %s.len, i32 %s.cap, i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%0 = icmp ult i32 %s.len, 4 |
|||
br i1 %0, label %slicetoarray.throw, label %slicetoarray.next |
|||
|
|||
slicetoarray.next: ; preds = %entry |
|||
%1 = bitcast i32* %s.data to [4 x i32]* |
|||
ret [4 x i32]* %1 |
|||
|
|||
slicetoarray.throw: ; preds = %entry |
|||
call void @runtime.sliceToArrayPointerPanic(i8* undef) #2 |
|||
unreachable |
|||
} |
|||
|
|||
declare void @runtime.sliceToArrayPointerPanic(i8*) #0 |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%makeslice = call i8* @runtime.alloc(i32 24, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 |
|||
call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef) #2 |
|||
br i1 false, label %slicetoarray.throw, label %slicetoarray.next |
|||
|
|||
slicetoarray.next: ; preds = %entry |
|||
%0 = bitcast i8* %makeslice to [4 x i32]* |
|||
ret [4 x i32]* %0 |
|||
|
|||
slicetoarray.throw: ; preds = %entry |
|||
unreachable |
|||
} |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden { i32*, i32, i32 } @main.SliceInt(i32* dereferenceable_or_null(4) %ptr, i32 %len, i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%0 = icmp ugt i32 %len, 1073741823 |
|||
%1 = icmp eq i32* %ptr, null |
|||
%2 = icmp ne i32 %len, 0 |
|||
%3 = and i1 %1, %2 |
|||
%4 = or i1 %3, %0 |
|||
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next |
|||
|
|||
unsafe.Slice.next: ; preds = %entry |
|||
%5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 |
|||
%6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1 |
|||
%7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2 |
|||
%8 = bitcast i32* %ptr to i8* |
|||
call void @runtime.trackPointer(i8* %8, i8* undef) #2 |
|||
ret { i32*, i32, i32 } %7 |
|||
|
|||
unsafe.Slice.throw: ; preds = %entry |
|||
call void @runtime.unsafeSlicePanic(i8* undef) #2 |
|||
unreachable |
|||
} |
|||
|
|||
declare void @runtime.unsafeSlicePanic(i8*) #0 |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden { i8*, i32, i32 } @main.SliceUint16(i8* dereferenceable_or_null(1) %ptr, i16 %len, i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%0 = icmp eq i8* %ptr, null |
|||
%1 = icmp ne i16 %len, 0 |
|||
%2 = and i1 %0, %1 |
|||
br i1 %2, label %unsafe.Slice.throw, label %unsafe.Slice.next |
|||
|
|||
unsafe.Slice.next: ; preds = %entry |
|||
%3 = zext i16 %len to i32 |
|||
%4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0 |
|||
%5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1 |
|||
%6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2 |
|||
call void @runtime.trackPointer(i8* %ptr, i8* undef) #2 |
|||
ret { i8*, i32, i32 } %6 |
|||
|
|||
unsafe.Slice.throw: ; preds = %entry |
|||
call void @runtime.unsafeSlicePanic(i8* undef) #2 |
|||
unreachable |
|||
} |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden { i32*, i32, i32 } @main.SliceUint64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%0 = icmp ugt i64 %len, 1073741823 |
|||
%1 = icmp eq i32* %ptr, null |
|||
%2 = icmp ne i64 %len, 0 |
|||
%3 = and i1 %1, %2 |
|||
%4 = or i1 %3, %0 |
|||
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next |
|||
|
|||
unsafe.Slice.next: ; preds = %entry |
|||
%5 = trunc i64 %len to i32 |
|||
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 |
|||
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 |
|||
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 |
|||
%9 = bitcast i32* %ptr to i8* |
|||
call void @runtime.trackPointer(i8* %9, i8* undef) #2 |
|||
ret { i32*, i32, i32 } %8 |
|||
|
|||
unsafe.Slice.throw: ; preds = %entry |
|||
call void @runtime.unsafeSlicePanic(i8* undef) #2 |
|||
unreachable |
|||
} |
|||
|
|||
; Function Attrs: nounwind |
|||
define hidden { i32*, i32, i32 } @main.SliceInt64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 { |
|||
entry: |
|||
%0 = icmp ugt i64 %len, 1073741823 |
|||
%1 = icmp eq i32* %ptr, null |
|||
%2 = icmp ne i64 %len, 0 |
|||
%3 = and i1 %1, %2 |
|||
%4 = or i1 %3, %0 |
|||
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next |
|||
|
|||
unsafe.Slice.next: ; preds = %entry |
|||
%5 = trunc i64 %len to i32 |
|||
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 |
|||
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 |
|||
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 |
|||
%9 = bitcast i32* %ptr to i8* |
|||
call void @runtime.trackPointer(i8* %9, i8* undef) #2 |
|||
ret { i32*, i32, i32 } %8 |
|||
|
|||
unsafe.Slice.throw: ; preds = %entry |
|||
call void @runtime.unsafeSlicePanic(i8* undef) #2 |
|||
unreachable |
|||
} |
|||
|
|||
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } |
|||
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } |
|||
attributes #2 = { nounwind } |
@ -1,18 +0,0 @@ |
|||
//go:build go1.18
|
|||
// +build go1.18
|
|||
|
|||
package loader |
|||
|
|||
// Workaround for Go 1.17 support. Should be removed once we drop Go 1.17
|
|||
// support.
|
|||
|
|||
import ( |
|||
"go/ast" |
|||
"go/types" |
|||
) |
|||
|
|||
func init() { |
|||
addInstances = func(info *types.Info) { |
|||
info.Instances = make(map[*ast.Ident]types.Instance) |
|||
} |
|||
} |
@ -1,2 +0,0 @@ |
|||
internal/itoa is new to go as of 1.17. |
|||
This directory should be removed when tinygo drops support for go 1.16. |
@ -1,33 +0,0 @@ |
|||
// 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.
|
|||
|
|||
// Simple conversions to avoid depending on strconv.
|
|||
|
|||
package itoa |
|||
|
|||
// Itoa converts val to a decimal string.
|
|||
func Itoa(val int) string { |
|||
if val < 0 { |
|||
return "-" + Uitoa(uint(-val)) |
|||
} |
|||
return Uitoa(uint(val)) |
|||
} |
|||
|
|||
// Uitoa converts val to a decimal string.
|
|||
func Uitoa(val uint) string { |
|||
if val == 0 { // avoid string allocation
|
|||
return "0" |
|||
} |
|||
var buf [20]byte // big enough for 64bit value base 10
|
|||
i := len(buf) - 1 |
|||
for val >= 10 { |
|||
q := val / 10 |
|||
buf[i] = byte('0' + val - q*10) |
|||
i-- |
|||
val = q |
|||
} |
|||
// val < 10
|
|||
buf[i] = byte('0' + val) |
|||
return string(buf[i:]) |
|||
} |
@ -1,40 +0,0 @@ |
|||
// 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 itoa_test |
|||
|
|||
import ( |
|||
"fmt" |
|||
"internal/itoa" |
|||
"math" |
|||
"testing" |
|||
) |
|||
|
|||
var ( |
|||
minInt64 int64 = math.MinInt64 |
|||
maxInt64 int64 = math.MaxInt64 |
|||
maxUint64 uint64 = math.MaxUint64 |
|||
) |
|||
|
|||
func TestItoa(t *testing.T) { |
|||
tests := []int{int(minInt64), math.MinInt32, -999, -100, -1, 0, 1, 100, 999, math.MaxInt32, int(maxInt64)} |
|||
for _, tt := range tests { |
|||
got := itoa.Itoa(tt) |
|||
want := fmt.Sprint(tt) |
|||
if want != got { |
|||
t.Fatalf("Itoa(%d) = %s, want %s", tt, got, want) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func TestUitoa(t *testing.T) { |
|||
tests := []uint{0, 1, 100, 999, math.MaxUint32, uint(maxUint64)} |
|||
for _, tt := range tests { |
|||
got := itoa.Uitoa(tt) |
|||
want := fmt.Sprint(tt) |
|||
if want != got { |
|||
t.Fatalf("Uitoa(%d) = %s, want %s", tt, got, want) |
|||
} |
|||
} |
|||
} |
@ -1,6 +1,3 @@ |
|||
//go:build go1.18
|
|||
// +build go1.18
|
|||
|
|||
// Portions copyright 2009 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.
|
@ -1,36 +0,0 @@ |
|||
//go:build !go1.18
|
|||
// +build !go1.18
|
|||
|
|||
// Portions copyright 2009 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 runtime |
|||
|
|||
type puintptr uintptr |
|||
|
|||
// Package time knows the layout of this structure.
|
|||
// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
|
|||
type timer struct { |
|||
// If this timer is on a heap, which P's heap it is on.
|
|||
// puintptr rather than *p to match uintptr in the versions
|
|||
// of this struct defined in other packages.
|
|||
pp puintptr |
|||
|
|||
// Timer wakes up at when, and then at when+period, ... (period > 0 only)
|
|||
// each time calling f(arg, now) in the timer goroutine, so f must be
|
|||
// a well-behaved function and not block.
|
|||
//
|
|||
// when must be positive on an active timer.
|
|||
when int64 |
|||
period int64 |
|||
f func(interface{}, uintptr) |
|||
arg interface{} |
|||
seq uintptr |
|||
|
|||
// What to set the when field to in timerModifiedXX status.
|
|||
nextwhen int64 |
|||
|
|||
// The status field holds one of the values below.
|
|||
status uint32 |
|||
} |
@ -1,16 +0,0 @@ |
|||
//go:build go1.18
|
|||
// +build go1.18
|
|||
|
|||
package testing |
|||
|
|||
// MainStart is meant for use by tests generated by 'go test'.
|
|||
// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
|
|||
// It may change signature from release to release.
|
|||
func MainStart(deps interface{}, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M { |
|||
Init() |
|||
return &M{ |
|||
Tests: tests, |
|||
Benchmarks: benchmarks, |
|||
deps: deps.(testDeps), |
|||
} |
|||
} |
@ -1,16 +0,0 @@ |
|||
//go:build !go1.18
|
|||
// +build !go1.18
|
|||
|
|||
package testing |
|||
|
|||
// MainStart is meant for use by tests generated by 'go test'.
|
|||
// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
|
|||
// It may change signature from release to release.
|
|||
func MainStart(deps interface{}, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M { |
|||
Init() |
|||
return &M{ |
|||
Tests: tests, |
|||
Benchmarks: benchmarks, |
|||
deps: deps.(testDeps), |
|||
} |
|||
} |
@ -1,34 +0,0 @@ |
|||
package main |
|||
|
|||
// Test new language features introduced in Go 1.17:
|
|||
// https://tip.golang.org/doc/go1.17#language
|
|||
// Once this becomes the minimum Go version of TinyGo, these tests should be
|
|||
// merged with the regular slice tests.
|
|||
|
|||
import "unsafe" |
|||
|
|||
func main() { |
|||
// Test conversion from array to slice.
|
|||
slice1 := []int{1, 2, 3, 4} |
|||
arr1 := (*[4]int)(slice1) |
|||
arr1[1] = -2 |
|||
arr1[2] = 20 |
|||
println("slice to array pointer:", arr1[0], arr1[1], arr1[2], arr1[3]) |
|||
|
|||
// Test unsafe.Add.
|
|||
arr2 := [...]int{1, 2, 3, 4} |
|||
*(*int)(unsafe.Add(unsafe.Pointer(&arr2[0]), unsafe.Sizeof(int(1))*1)) = 5 |
|||
*addInt(&arr2[0], 2) = 8 |
|||
println("unsafe.Add array:", arr2[0], arr2[1], arr2[2], arr2[3]) |
|||
|
|||
// Test unsafe.Slice.
|
|||
arr3 := [...]int{1, 2, 3, 4} |
|||
slice3 := unsafe.Slice(&arr3[1], 3) |
|||
slice3[0] = 9 |
|||
slice3[1] = 15 |
|||
println("unsafe.Slice array:", len(slice3), cap(slice3), slice3[0], slice3[1], slice3[2]) |
|||
} |
|||
|
|||
func addInt(ptr *int, index uintptr) *int { |
|||
return (*int)(unsafe.Add(unsafe.Pointer(ptr), unsafe.Sizeof(int(1))*index)) |
|||
} |
@ -1,3 +0,0 @@ |
|||
slice to array pointer: 1 -2 20 4 |
|||
unsafe.Add array: 1 5 8 4 |
|||
unsafe.Slice array: 3 3 9 15 4 |
@ -1,100 +0,0 @@ |
|||
package main |
|||
|
|||
// TODO: also test the verbose version.
|
|||
|
|||
import ( |
|||
"errors" |
|||
"flag" |
|||
"io" |
|||
"strings" |
|||
"testing" |
|||
) |
|||
|
|||
func TestFoo(t *testing.T) { |
|||
t.Log("log Foo.a") |
|||
t.Log("log Foo.b") |
|||
} |
|||
|
|||
func TestBar(t *testing.T) { |
|||
t.Log("log Bar") |
|||
t.Log("log g\nh\ni\n") |
|||
t.Run("Bar1", func(t *testing.T) {}) |
|||
t.Run("Bar2", func(t *testing.T) { |
|||
t.Log("log Bar2\na\nb\nc") |
|||
t.Error("failed") |
|||
t.Log("after failed") |
|||
}) |
|||
t.Run("Bar3", func(t *testing.T) {}) |
|||
t.Log("log Bar end") |
|||
} |
|||
|
|||
func TestAllLowercase(t *testing.T) { |
|||
names := []string { |
|||
"alpha", |
|||
"BETA", |
|||
"gamma", |
|||
"BELTA", |
|||
} |
|||
|
|||
for _, name := range names { |
|||
t.Run(name, func(t *testing.T) { |
|||
if 'a' <= name[0] && name[0] <= 'a' { |
|||
t.Logf("expected lowercase name, and got one, so I'm happy") |
|||
} else { |
|||
t.Errorf("expected lowercase name, got %s", name) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
var tests = []testing.InternalTest{ |
|||
{"TestFoo", TestFoo}, |
|||
{"TestBar", TestBar}, |
|||
{"TestAllLowercase", TestAllLowercase}, |
|||
} |
|||
|
|||
var benchmarks = []testing.InternalBenchmark{} |
|||
|
|||
var fuzzes = []testing.InternalFuzzTarget{} |
|||
|
|||
var examples = []testing.InternalExample{} |
|||
|
|||
// A fake regexp matcher.
|
|||
// Inflexible, but saves 50KB of flash and 50KB of RAM per -size full,
|
|||
// and lets tests pass on cortex-m.
|
|||
// Must match the one in src/testing/match.go that is substituted on bare-metal platforms,
|
|||
// or "make test" will fail there.
|
|||
func fakeMatchString(pat, str string) (bool, error) { |
|||
if pat == ".*" { |
|||
return true, nil |
|||
} |
|||
matched := strings.Contains(str, pat) |
|||
return matched, nil |
|||
} |
|||
|
|||
func main() { |
|||
testing.Init() |
|||
flag.Set("test.run", ".*/B") |
|||
m := testing.MainStart(matchStringOnly(fakeMatchString /*regexp.MatchString*/), tests, benchmarks, fuzzes, examples) |
|||
|
|||
exitcode := m.Run() |
|||
if exitcode != 0 { |
|||
println("exitcode:", exitcode) |
|||
} |
|||
} |
|||
|
|||
var errMain = errors.New("testing: unexpected use of func Main") |
|||
|
|||
// matchStringOnly is part of upstream, and is used below to provide a dummy deps to pass to MainStart
|
|||
// so it can be run with go (tested with go 1.16) to provide a baseline for the regression test.
|
|||
// See c56cc9b3b57276. Unfortunately, testdeps is internal, so we can't just use &testdeps.TestDeps{}.
|
|||
type matchStringOnly func(pat, str string) (bool, error) |
|||
|
|||
func (f matchStringOnly) MatchString(pat, str string) (bool, error) { return f(pat, str) } |
|||
func (f matchStringOnly) StartCPUProfile(w io.Writer) error { return errMain } |
|||
func (f matchStringOnly) StopCPUProfile() {} |
|||
func (f matchStringOnly) WriteProfileTo(string, io.Writer, int) error { return errMain } |
|||
func (f matchStringOnly) ImportPath() string { return "" } |
|||
func (f matchStringOnly) StartTestLog(io.Writer) {} |
|||
func (f matchStringOnly) StopTestLog() error { return errMain } |
|||
func (f matchStringOnly) SetPanicOnExit0(bool) {} |
@ -1,21 +0,0 @@ |
|||
--- FAIL: TestBar (0.00s) |
|||
log Bar |
|||
log g |
|||
h |
|||
i |
|||
|
|||
--- FAIL: TestBar/Bar2 (0.00s) |
|||
log Bar2 |
|||
a |
|||
b |
|||
c |
|||
failed |
|||
after failed |
|||
log Bar end |
|||
--- FAIL: TestAllLowercase (0.00s) |
|||
--- FAIL: TestAllLowercase/BETA (0.00s) |
|||
expected lowercase name, got BETA |
|||
--- FAIL: TestAllLowercase/BELTA (0.00s) |
|||
expected lowercase name, got BELTA |
|||
FAIL |
|||
exitcode: 1 |
Loading…
Reference in new issue