go/src/cmd/compile/internal/gc/abiutils_test.go

280 lines
8.8 KiB
Go
Raw Normal View History

// Copyright 2020 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 gc
import (
"bufio"
"cmd/compile/internal/base"
"cmd/compile/internal/reflectdata"
[dev.regabi] cmd/compile: split out package typecheck [generated] This commit splits the typechecking logic into its own package, the first of a sequence of CLs to break package gc into more manageable units. [git-generate] cd src/cmd/compile/internal/gc rf ' # The binary import/export has to be part of typechecking, # because we load inlined function bodies lazily, but "exporter" # should not be. Move that out of bexport.go. mv exporter exporter.markObject exporter.markType export.go # Use the typechecking helpers, so that the calls left behind # in package gc do not need access to ctxExpr etc. ex { import "cmd/compile/internal/ir" # TODO(rsc): Should not be necessary. avoid TypecheckExpr avoid TypecheckStmt avoid TypecheckExprs avoid TypecheckStmts avoid TypecheckAssignExpr avoid TypecheckCallee var n ir.Node var ns []ir.Node typecheck(n, ctxExpr) -> TypecheckExpr(n) typecheck(n, ctxStmt) -> TypecheckStmt(n) typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns) typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns) typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n) typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n) } # Move some typechecking API to typecheck. mv syslook LookupRuntime mv substArgTypes SubstArgTypes mv LookupRuntime SubstArgTypes syms.go mv conv Conv mv convnop ConvNop mv Conv ConvNop typecheck.go mv colasdefn AssignDefn mv colasname assignableName mv Target target.go mv initname autoexport exportsym dcl.go mv exportsym Export # Export API to be called from outside typecheck. # The ones with "Typecheck" prefixes will be renamed later to drop the prefix. mv adddot AddImplicitDots mv assignconv AssignConv mv expandmeth CalcMethods mv capturevarscomplete CaptureVarsComplete mv checkMapKeys CheckMapKeys mv checkreturn CheckReturn mv dclcontext DeclContext mv dclfunc DeclFunc mv declare Declare mv dotImportRefs DotImportRefs mv declImporter DeclImporter mv variter DeclVars mv defaultlit DefaultLit mv evalConst EvalConst mv expandInline ImportBody mv finishUniverse declareUniverse mv funcbody FinishFuncBody mv funchdr StartFuncBody mv indexconst IndexConst mv initTodo InitTodoFunc mv lookup Lookup mv resolve Resolve mv lookupN LookupNum mv nodAddr NodAddr mv nodAddrAt NodAddrAt mv nodnil NodNil mv origBoolConst OrigBool mv origConst OrigConst mv origIntConst OrigInt mv redeclare Redeclared mv tostruct NewStructType mv functype NewFuncType mv methodfunc NewMethodType mv structargs NewFuncParams mv temp Temp mv tempAt TempAt mv typecheckok TypecheckAllowed mv typecheck _typecheck # make room for typecheck pkg mv typecheckinl TypecheckImportedBody mv typecheckFunc TypecheckFunc mv iimport ReadImports mv iexport WriteExports mv sysfunc LookupRuntimeFunc mv sysvar LookupRuntimeVar # Move function constructors to typecheck. mv mkdotargslice MakeDotArgs mv fixVariadicCall FixVariadicCall mv closureType ClosureType mv partialCallType PartialCallType mv capturevars CaptureVars mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go mv autolabel AutoLabel mv AutoLabel syms.go mv Dlist dlist mv Symlink symlink mv \ AssignDefn assignableName \ AssignConv \ CaptureVarsComplete \ DeclContext \ DeclFunc \ DeclImporter \ DeclVars \ Declare \ DotImportRefs \ Export \ InitTodoFunc \ Lookup \ LookupNum \ LookupRuntimeFunc \ LookupRuntimeVar \ NewFuncParams \ NewName \ NodAddr \ NodAddrAt \ NodNil \ Redeclared \ StartFuncBody \ FinishFuncBody \ TypecheckImportedBody \ AddImplicitDots \ CalcMethods \ CheckFuncStack \ NewFuncType \ NewMethodType \ NewStructType \ TypecheckAllowed \ Temp \ TempAt \ adddot1 \ dotlist \ addmethod \ assignconvfn \ assignop \ autotmpname \ autoexport \ bexport.go \ checkdupfields \ checkembeddedtype \ closurename \ convertop \ declare_typegen \ decldepth \ dlist \ dotpath \ expand0 \ expand1 \ expandDecl \ fakeRecvField \ fnpkg \ funcStack \ funcStackEnt \ funcarg \ funcarg2 \ funcargs \ funcargs2 \ globClosgen \ ifacelookdot \ implements \ importalias \ importconst \ importfunc \ importobj \ importsym \ importtype \ importvar \ inimport \ initname \ isptrto \ loadsys \ lookdot0 \ lookdot1 \ makepartialcall \ okfor \ okforlen \ operandType \ slist \ symlink \ tointerface \ typeSet \ typeSet.add \ typeSetEntry \ typecheckExprSwitch \ typecheckTypeSwitch \ typecheckpartialcall \ typecheckrange \ typecheckrangeExpr \ typecheckselect \ typecheckswitch \ vargen \ builtin.go \ builtin_test.go \ const.go \ func.go \ iexport.go \ iimport.go \ mapfile_mmap.go \ syms.go \ target.go \ typecheck.go \ unsafe.go \ universe.go \ cmd/compile/internal/typecheck ' rm gen.go types.go types_acc.go sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go mv mapfile_read.go ../typecheck # not part of default build mv mkbuiltin.go ../typecheck # package main helper mv builtin ../typecheck cd ../typecheck mv dcl.go dcl1.go mv typecheck.go typecheck1.go mv universe.go universe1.go rf ' # Sweep some small files into larger ones. # "mv sym... file1.go file.go" (after the mv file1.go file.go above) # lets us insert sym... at the top of file.go. mv okfor okforeq universe1.go universe.go mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go mv inl.go closure.go func.go mv range.go select.go swt.go stmt.go mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go mv unsafe.go const.go mv TypecheckAssignExpr AssignExpr mv TypecheckExpr Expr mv TypecheckStmt Stmt mv TypecheckExprs Exprs mv TypecheckStmts Stmts mv TypecheckCall Call mv TypecheckCallee Callee mv _typecheck check mv TypecheckFunc Func mv TypecheckFuncBody FuncBody mv TypecheckImports AllImportedBodies mv TypecheckImportedBody ImportedBody mv TypecheckInit Init mv TypecheckPackage Package ' rm gen.go go.go init.go main.go reflect.go Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0 Reviewed-on: https://go-review.googlesource.com/c/go/+/279236 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/obj/x86"
"cmd/internal/src"
"os"
"testing"
)
// AMD64 registers available:
// - integer: RAX, RBX, RCX, RDI, RSI, R8, R9, r10, R11
// - floating point: X0 - X14
var configAMD64 = ABIConfig{
regAmounts: RegAmounts{
intRegs: 9,
floatRegs: 15,
},
}
func TestMain(m *testing.M) {
thearch.LinkArch = &x86.Linkamd64
thearch.REGSP = x86.REGSP
thearch.MAXWIDTH = 1 << 50
[dev.regabi] cmd/compile: move type size calculations into package types [generated] To break up package gc, we need to put these calculations somewhere lower in the import graph, either an existing or new package. Package types already needs this code and is using hacks to get it without an import cycle. We can remove the hacks and set up for the new package gc by moving the code into package types itself. [git-generate] cd src/cmd/compile/internal/gc rf ' # Remove old import cycle hacks in gc. rm TypecheckInit:/types.Widthptr =/-0,/types.Dowidth =/+0 \ ../ssa/export_test.go:/types.Dowidth =/-+ ex { import "cmd/compile/internal/types" types.Widthptr -> Widthptr types.Dowidth -> dowidth } # Disable CalcSize in tests instead of base.Fatalf sub dowidth:/base.Fatalf\("dowidth without betypeinit"\)/ \ // Assume this is a test. \ return # Move size calculation into cmd/compile/internal/types mv Widthptr PtrSize mv Widthreg RegSize mv slicePtrOffset SlicePtrOffset mv sliceLenOffset SliceLenOffset mv sliceCapOffset SliceCapOffset mv sizeofSlice SliceSize mv sizeofString StringSize mv skipDowidthForTracing SkipSizeForTracing mv dowidth CalcSize mv checkwidth CheckSize mv widstruct calcStructOffset mv sizeCalculationDisabled CalcSizeDisabled mv defercheckwidth DeferCheckSize mv resumecheckwidth ResumeCheckSize mv typeptrdata PtrDataSize mv \ PtrSize RegSize SlicePtrOffset SkipSizeForTracing typePos align.go PtrDataSize \ size.go mv size.go cmd/compile/internal/types ' : # Remove old import cycle hacks in types. cd ../types rf ' ex { Widthptr -> PtrSize Dowidth -> CalcSize } rm Widthptr Dowidth ' Change-Id: Ib96cdc6bda2617235480c29392ea5cfb20f60cd8 Reviewed-on: https://go-review.googlesource.com/c/go/+/279234 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:39:45 -05:00
types.MaxWidth = thearch.MAXWIDTH
base.Ctxt = obj.Linknew(thearch.LinkArch)
base.Ctxt.DiagFunc = base.Errorf
base.Ctxt.DiagFlush = base.FlushErrors
base.Ctxt.Bso = bufio.NewWriter(os.Stdout)
[dev.regabi] cmd/compile: move type size calculations into package types [generated] To break up package gc, we need to put these calculations somewhere lower in the import graph, either an existing or new package. Package types already needs this code and is using hacks to get it without an import cycle. We can remove the hacks and set up for the new package gc by moving the code into package types itself. [git-generate] cd src/cmd/compile/internal/gc rf ' # Remove old import cycle hacks in gc. rm TypecheckInit:/types.Widthptr =/-0,/types.Dowidth =/+0 \ ../ssa/export_test.go:/types.Dowidth =/-+ ex { import "cmd/compile/internal/types" types.Widthptr -> Widthptr types.Dowidth -> dowidth } # Disable CalcSize in tests instead of base.Fatalf sub dowidth:/base.Fatalf\("dowidth without betypeinit"\)/ \ // Assume this is a test. \ return # Move size calculation into cmd/compile/internal/types mv Widthptr PtrSize mv Widthreg RegSize mv slicePtrOffset SlicePtrOffset mv sliceLenOffset SliceLenOffset mv sliceCapOffset SliceCapOffset mv sizeofSlice SliceSize mv sizeofString StringSize mv skipDowidthForTracing SkipSizeForTracing mv dowidth CalcSize mv checkwidth CheckSize mv widstruct calcStructOffset mv sizeCalculationDisabled CalcSizeDisabled mv defercheckwidth DeferCheckSize mv resumecheckwidth ResumeCheckSize mv typeptrdata PtrDataSize mv \ PtrSize RegSize SlicePtrOffset SkipSizeForTracing typePos align.go PtrDataSize \ size.go mv size.go cmd/compile/internal/types ' : # Remove old import cycle hacks in types. cd ../types rf ' ex { Widthptr -> PtrSize Dowidth -> CalcSize } rm Widthptr Dowidth ' Change-Id: Ib96cdc6bda2617235480c29392ea5cfb20f60cd8 Reviewed-on: https://go-review.googlesource.com/c/go/+/279234 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:39:45 -05:00
types.PtrSize = thearch.LinkArch.PtrSize
types.RegSize = thearch.LinkArch.RegSize
types.TypeLinkSym = func(t *types.Type) *obj.LSym {
return reflectdata.TypeSym(t).Linksym()
}
types.TypeLinkSym = func(t *types.Type) *obj.LSym {
return reflectdata.TypeSym(t).Linksym()
}
[dev.regabi] cmd/compile: split out package typecheck [generated] This commit splits the typechecking logic into its own package, the first of a sequence of CLs to break package gc into more manageable units. [git-generate] cd src/cmd/compile/internal/gc rf ' # The binary import/export has to be part of typechecking, # because we load inlined function bodies lazily, but "exporter" # should not be. Move that out of bexport.go. mv exporter exporter.markObject exporter.markType export.go # Use the typechecking helpers, so that the calls left behind # in package gc do not need access to ctxExpr etc. ex { import "cmd/compile/internal/ir" # TODO(rsc): Should not be necessary. avoid TypecheckExpr avoid TypecheckStmt avoid TypecheckExprs avoid TypecheckStmts avoid TypecheckAssignExpr avoid TypecheckCallee var n ir.Node var ns []ir.Node typecheck(n, ctxExpr) -> TypecheckExpr(n) typecheck(n, ctxStmt) -> TypecheckStmt(n) typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns) typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns) typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n) typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n) } # Move some typechecking API to typecheck. mv syslook LookupRuntime mv substArgTypes SubstArgTypes mv LookupRuntime SubstArgTypes syms.go mv conv Conv mv convnop ConvNop mv Conv ConvNop typecheck.go mv colasdefn AssignDefn mv colasname assignableName mv Target target.go mv initname autoexport exportsym dcl.go mv exportsym Export # Export API to be called from outside typecheck. # The ones with "Typecheck" prefixes will be renamed later to drop the prefix. mv adddot AddImplicitDots mv assignconv AssignConv mv expandmeth CalcMethods mv capturevarscomplete CaptureVarsComplete mv checkMapKeys CheckMapKeys mv checkreturn CheckReturn mv dclcontext DeclContext mv dclfunc DeclFunc mv declare Declare mv dotImportRefs DotImportRefs mv declImporter DeclImporter mv variter DeclVars mv defaultlit DefaultLit mv evalConst EvalConst mv expandInline ImportBody mv finishUniverse declareUniverse mv funcbody FinishFuncBody mv funchdr StartFuncBody mv indexconst IndexConst mv initTodo InitTodoFunc mv lookup Lookup mv resolve Resolve mv lookupN LookupNum mv nodAddr NodAddr mv nodAddrAt NodAddrAt mv nodnil NodNil mv origBoolConst OrigBool mv origConst OrigConst mv origIntConst OrigInt mv redeclare Redeclared mv tostruct NewStructType mv functype NewFuncType mv methodfunc NewMethodType mv structargs NewFuncParams mv temp Temp mv tempAt TempAt mv typecheckok TypecheckAllowed mv typecheck _typecheck # make room for typecheck pkg mv typecheckinl TypecheckImportedBody mv typecheckFunc TypecheckFunc mv iimport ReadImports mv iexport WriteExports mv sysfunc LookupRuntimeFunc mv sysvar LookupRuntimeVar # Move function constructors to typecheck. mv mkdotargslice MakeDotArgs mv fixVariadicCall FixVariadicCall mv closureType ClosureType mv partialCallType PartialCallType mv capturevars CaptureVars mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go mv autolabel AutoLabel mv AutoLabel syms.go mv Dlist dlist mv Symlink symlink mv \ AssignDefn assignableName \ AssignConv \ CaptureVarsComplete \ DeclContext \ DeclFunc \ DeclImporter \ DeclVars \ Declare \ DotImportRefs \ Export \ InitTodoFunc \ Lookup \ LookupNum \ LookupRuntimeFunc \ LookupRuntimeVar \ NewFuncParams \ NewName \ NodAddr \ NodAddrAt \ NodNil \ Redeclared \ StartFuncBody \ FinishFuncBody \ TypecheckImportedBody \ AddImplicitDots \ CalcMethods \ CheckFuncStack \ NewFuncType \ NewMethodType \ NewStructType \ TypecheckAllowed \ Temp \ TempAt \ adddot1 \ dotlist \ addmethod \ assignconvfn \ assignop \ autotmpname \ autoexport \ bexport.go \ checkdupfields \ checkembeddedtype \ closurename \ convertop \ declare_typegen \ decldepth \ dlist \ dotpath \ expand0 \ expand1 \ expandDecl \ fakeRecvField \ fnpkg \ funcStack \ funcStackEnt \ funcarg \ funcarg2 \ funcargs \ funcargs2 \ globClosgen \ ifacelookdot \ implements \ importalias \ importconst \ importfunc \ importobj \ importsym \ importtype \ importvar \ inimport \ initname \ isptrto \ loadsys \ lookdot0 \ lookdot1 \ makepartialcall \ okfor \ okforlen \ operandType \ slist \ symlink \ tointerface \ typeSet \ typeSet.add \ typeSetEntry \ typecheckExprSwitch \ typecheckTypeSwitch \ typecheckpartialcall \ typecheckrange \ typecheckrangeExpr \ typecheckselect \ typecheckswitch \ vargen \ builtin.go \ builtin_test.go \ const.go \ func.go \ iexport.go \ iimport.go \ mapfile_mmap.go \ syms.go \ target.go \ typecheck.go \ unsafe.go \ universe.go \ cmd/compile/internal/typecheck ' rm gen.go types.go types_acc.go sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go mv mapfile_read.go ../typecheck # not part of default build mv mkbuiltin.go ../typecheck # package main helper mv builtin ../typecheck cd ../typecheck mv dcl.go dcl1.go mv typecheck.go typecheck1.go mv universe.go universe1.go rf ' # Sweep some small files into larger ones. # "mv sym... file1.go file.go" (after the mv file1.go file.go above) # lets us insert sym... at the top of file.go. mv okfor okforeq universe1.go universe.go mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go mv inl.go closure.go func.go mv range.go select.go swt.go stmt.go mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go mv unsafe.go const.go mv TypecheckAssignExpr AssignExpr mv TypecheckExpr Expr mv TypecheckStmt Stmt mv TypecheckExprs Exprs mv TypecheckStmts Stmts mv TypecheckCall Call mv TypecheckCallee Callee mv _typecheck check mv TypecheckFunc Func mv TypecheckFuncBody FuncBody mv TypecheckImports AllImportedBodies mv TypecheckImportedBody ImportedBody mv TypecheckInit Init mv TypecheckPackage Package ' rm gen.go go.go init.go main.go reflect.go Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0 Reviewed-on: https://go-review.googlesource.com/c/go/+/279236 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
typecheck.Init()
os.Exit(m.Run())
}
func TestABIUtilsBasic1(t *testing.T) {
// func(x int32) int32
i32 := types.Types[types.TINT32]
ft := mkFuncType(nil, []*types.Type{i32}, []*types.Type{i32})
// expected results
exp := makeExpectedDump(`
IN 0: R{ I0 } offset: -1 typ: int32
OUT 0: R{ I0 } offset: -1 typ: int32
intspill: 1 floatspill: 0 offsetToSpillArea: 0
`)
abitest(t, ft, exp)
}
func TestABIUtilsBasic2(t *testing.T) {
// func(x int32, y float64) (int32, float64, float64)
i8 := types.Types[types.TINT8]
i16 := types.Types[types.TINT16]
i32 := types.Types[types.TINT32]
i64 := types.Types[types.TINT64]
f32 := types.Types[types.TFLOAT32]
f64 := types.Types[types.TFLOAT64]
c64 := types.Types[types.TCOMPLEX64]
c128 := types.Types[types.TCOMPLEX128]
ft := mkFuncType(nil,
[]*types.Type{
i8, i16, i32, i64,
f32, f32, f64, f64,
i8, i16, i32, i64,
f32, f32, f64, f64,
c128, c128, c128, c128, c64,
i8, i16, i32, i64,
i8, i16, i32, i64},
[]*types.Type{i32, f64, f64})
exp := makeExpectedDump(`
IN 0: R{ I0 } offset: -1 typ: int8
IN 1: R{ I1 } offset: -1 typ: int16
IN 2: R{ I2 } offset: -1 typ: int32
IN 3: R{ I3 } offset: -1 typ: int64
IN 4: R{ F0 } offset: -1 typ: float32
IN 5: R{ F1 } offset: -1 typ: float32
IN 6: R{ F2 } offset: -1 typ: float64
IN 7: R{ F3 } offset: -1 typ: float64
IN 8: R{ I4 } offset: -1 typ: int8
IN 9: R{ I5 } offset: -1 typ: int16
IN 10: R{ I6 } offset: -1 typ: int32
IN 11: R{ I7 } offset: -1 typ: int64
IN 12: R{ F4 } offset: -1 typ: float32
IN 13: R{ F5 } offset: -1 typ: float32
IN 14: R{ F6 } offset: -1 typ: float64
IN 15: R{ F7 } offset: -1 typ: float64
IN 16: R{ F8 F9 } offset: -1 typ: complex128
IN 17: R{ F10 F11 } offset: -1 typ: complex128
IN 18: R{ F12 F13 } offset: -1 typ: complex128
IN 19: R{ } offset: 0 typ: complex128
IN 20: R{ F14 } offset: -1 typ: complex64
IN 21: R{ I8 } offset: -1 typ: int8
IN 22: R{ } offset: 16 typ: int16
IN 23: R{ } offset: 20 typ: int32
IN 24: R{ } offset: 24 typ: int64
IN 25: R{ } offset: 32 typ: int8
IN 26: R{ } offset: 34 typ: int16
IN 27: R{ } offset: 36 typ: int32
IN 28: R{ } offset: 40 typ: int64
OUT 0: R{ I0 } offset: -1 typ: int32
OUT 1: R{ F0 } offset: -1 typ: float64
OUT 2: R{ F1 } offset: -1 typ: float64
intspill: 9 floatspill: 15 offsetToSpillArea: 48
`)
abitest(t, ft, exp)
}
func TestABIUtilsArrays(t *testing.T) {
i32 := types.Types[types.TINT32]
ae := types.NewArray(i32, 0)
a1 := types.NewArray(i32, 1)
a2 := types.NewArray(i32, 2)
aa1 := types.NewArray(a1, 1)
ft := mkFuncType(nil, []*types.Type{a1, ae, aa1, a2},
[]*types.Type{a2, a1, ae, aa1})
exp := makeExpectedDump(`
IN 0: R{ I0 } offset: -1 typ: [1]int32
IN 1: R{ } offset: 0 typ: [0]int32
IN 2: R{ I1 } offset: -1 typ: [1][1]int32
IN 3: R{ } offset: 0 typ: [2]int32
OUT 0: R{ } offset: 8 typ: [2]int32
OUT 1: R{ I0 } offset: -1 typ: [1]int32
OUT 2: R{ } offset: 16 typ: [0]int32
OUT 3: R{ I1 } offset: -1 typ: [1][1]int32
intspill: 2 floatspill: 0 offsetToSpillArea: 16
`)
abitest(t, ft, exp)
}
func TestABIUtilsStruct1(t *testing.T) {
i8 := types.Types[types.TINT8]
i16 := types.Types[types.TINT16]
i32 := types.Types[types.TINT32]
i64 := types.Types[types.TINT64]
s := mkstruct([]*types.Type{i8, i8, mkstruct([]*types.Type{}), i8, i16})
ft := mkFuncType(nil, []*types.Type{i8, s, i64},
[]*types.Type{s, i8, i32})
exp := makeExpectedDump(`
IN 0: R{ I0 } offset: -1 typ: int8
IN 1: R{ I1 I2 I3 I4 } offset: -1 typ: struct { int8; int8; struct {}; int8; int16 }
IN 2: R{ I5 } offset: -1 typ: int64
OUT 0: R{ I0 I1 I2 I3 } offset: -1 typ: struct { int8; int8; struct {}; int8; int16 }
OUT 1: R{ I4 } offset: -1 typ: int8
OUT 2: R{ I5 } offset: -1 typ: int32
intspill: 6 floatspill: 0 offsetToSpillArea: 0
`)
abitest(t, ft, exp)
}
func TestABIUtilsStruct2(t *testing.T) {
f64 := types.Types[types.TFLOAT64]
i64 := types.Types[types.TINT64]
s := mkstruct([]*types.Type{i64, mkstruct([]*types.Type{})})
fs := mkstruct([]*types.Type{f64, s, mkstruct([]*types.Type{})})
ft := mkFuncType(nil, []*types.Type{s, s, fs},
[]*types.Type{fs, fs})
exp := makeExpectedDump(`
IN 0: R{ I0 } offset: -1 typ: struct { int64; struct {} }
IN 1: R{ I1 } offset: -1 typ: struct { int64; struct {} }
IN 2: R{ I2 F0 } offset: -1 typ: struct { float64; struct { int64; struct {} }; struct {} }
OUT 0: R{ I0 F0 } offset: -1 typ: struct { float64; struct { int64; struct {} }; struct {} }
OUT 1: R{ I1 F1 } offset: -1 typ: struct { float64; struct { int64; struct {} }; struct {} }
intspill: 3 floatspill: 1 offsetToSpillArea: 0
`)
abitest(t, ft, exp)
}
func TestABIUtilsSliceString(t *testing.T) {
i32 := types.Types[types.TINT32]
sli32 := types.NewSlice(i32)
str := types.New(types.TSTRING)
i8 := types.Types[types.TINT8]
i64 := types.Types[types.TINT64]
ft := mkFuncType(nil, []*types.Type{sli32, i8, sli32, i8, str, i8, i64, sli32},
[]*types.Type{str, i64, str, sli32})
exp := makeExpectedDump(`
IN 0: R{ I0 I1 I2 } offset: -1 typ: []int32
IN 1: R{ I3 } offset: -1 typ: int8
IN 2: R{ I4 I5 I6 } offset: -1 typ: []int32
IN 3: R{ I7 } offset: -1 typ: int8
IN 4: R{ } offset: 0 typ: string
IN 5: R{ I8 } offset: -1 typ: int8
IN 6: R{ } offset: 16 typ: int64
IN 7: R{ } offset: 24 typ: []int32
OUT 0: R{ I0 I1 } offset: -1 typ: string
OUT 1: R{ I2 } offset: -1 typ: int64
OUT 2: R{ I3 I4 } offset: -1 typ: string
OUT 3: R{ I5 I6 I7 } offset: -1 typ: []int32
intspill: 9 floatspill: 0 offsetToSpillArea: 48
`)
abitest(t, ft, exp)
}
func TestABIUtilsMethod(t *testing.T) {
i16 := types.Types[types.TINT16]
i64 := types.Types[types.TINT64]
f64 := types.Types[types.TFLOAT64]
s1 := mkstruct([]*types.Type{i16, i16, i16})
ps1 := types.NewPtr(s1)
a7 := types.NewArray(ps1, 7)
ft := mkFuncType(s1, []*types.Type{ps1, a7, f64, i16, i16, i16},
[]*types.Type{a7, f64, i64})
exp := makeExpectedDump(`
IN 0: R{ I0 I1 I2 } offset: -1 typ: struct { int16; int16; int16 }
IN 1: R{ I3 } offset: -1 typ: *struct { int16; int16; int16 }
IN 2: R{ } offset: 0 typ: [7]*struct { int16; int16; int16 }
IN 3: R{ F0 } offset: -1 typ: float64
IN 4: R{ I4 } offset: -1 typ: int16
IN 5: R{ I5 } offset: -1 typ: int16
IN 6: R{ I6 } offset: -1 typ: int16
OUT 0: R{ } offset: 56 typ: [7]*struct { int16; int16; int16 }
OUT 1: R{ F0 } offset: -1 typ: float64
OUT 2: R{ I0 } offset: -1 typ: int64
intspill: 7 floatspill: 1 offsetToSpillArea: 112
`)
abitest(t, ft, exp)
}
func TestABIUtilsInterfaces(t *testing.T) {
ei := types.Types[types.TINTER] // interface{}
pei := types.NewPtr(ei) // *interface{}
fldt := mkFuncType(types.FakeRecvType(), []*types.Type{},
[]*types.Type{types.UntypedString})
field := types.NewField(src.NoXPos, nil, fldt)
// interface{ ...() string }
nei := types.NewInterface(types.LocalPkg, []*types.Field{field})
i16 := types.Types[types.TINT16]
tb := types.Types[types.TBOOL]
s1 := mkstruct([]*types.Type{i16, i16, tb})
ft := mkFuncType(nil, []*types.Type{s1, ei, ei, nei, pei, nei, i16},
[]*types.Type{ei, nei, pei})
exp := makeExpectedDump(`
IN 0: R{ I0 I1 I2 } offset: -1 typ: struct { int16; int16; bool }
IN 1: R{ I3 I4 } offset: -1 typ: interface {}
IN 2: R{ I5 I6 } offset: -1 typ: interface {}
IN 3: R{ I7 I8 } offset: -1 typ: interface { () untyped string }
IN 4: R{ } offset: 0 typ: *interface {}
IN 5: R{ } offset: 8 typ: interface { () untyped string }
IN 6: R{ } offset: 24 typ: int16
OUT 0: R{ I0 I1 } offset: -1 typ: interface {}
OUT 1: R{ I2 I3 } offset: -1 typ: interface { () untyped string }
OUT 2: R{ I4 } offset: -1 typ: *interface {}
intspill: 9 floatspill: 0 offsetToSpillArea: 32
`)
abitest(t, ft, exp)
}