Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove unsafe.XXX from builtin #378

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ retry:

func toBasicType(pkg *Package, t *types.Basic) ast.Expr {
if t.Kind() == types.UnsafePointer {
return toObjectExpr(pkg, pkg.unsafe().Ref("Pointer"))
return toObjectExpr(pkg, unsafeRef("Pointer"))
}
if (t.Info() & types.IsUntyped) != 0 {
panic("unexpected: untyped type")
Expand Down
20 changes: 15 additions & 5 deletions builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func InitBuiltin(pkg *Package, builtin *types.Package, conf *Config) {
initBuiltinAssignOps(builtin)
initBuiltinFuncs(builtin)
initBuiltinTIs(pkg)
initUnsafeFuncs(pkg)
}

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -390,13 +391,18 @@ func initBuiltinFuncs(builtin *types.Package) {
// len & cap are special cases, because they may return a constant value.
gbl.Insert(NewInstruction(token.NoPos, builtin, "len", lenInstr{}))
gbl.Insert(NewInstruction(token.NoPos, builtin, "cap", capInstr{}))
}

func initUnsafeFuncs(pkg *Package) {
unsafe := types.NewPackage("unsafe", "unsafe")
gbl := unsafe.Scope()
// unsafe
gbl.Insert(NewInstruction(token.NoPos, types.Unsafe, "Sizeof", unsafeSizeofInstr{}))
gbl.Insert(NewInstruction(token.NoPos, types.Unsafe, "Alignof", unsafeAlignofInstr{}))
gbl.Insert(NewInstruction(token.NoPos, types.Unsafe, "Offsetof", unsafeOffsetofInstr{}))
gbl.Insert(NewInstruction(token.NoPos, types.Unsafe, "Add", unsafeAddInstr{}))
gbl.Insert(NewInstruction(token.NoPos, types.Unsafe, "Slice", unsafeSliceInstr{}))
pkg.unsafe_.Types = unsafe
}

func newBFunc(builtin *types.Package, name string, t typeBFunc) types.Object {
Expand Down Expand Up @@ -736,14 +742,18 @@ func init() {
}
}

func unsafeRef(name string) Ref {
return PkgRef{types.Unsafe}.Ref(name)
}

type unsafeSizeofInstr struct{}

// func unsafe.Sizeof(x ArbitraryType) uintptr
func (p unsafeSizeofInstr) Call(pkg *Package, args []*Element, flags InstrFlags, src ast.Node) (ret *Element, err error) {
checkArgsCount(pkg, "unsafe.Sizeof", 1, len(args), src)

typ := types.Default(realType(args[0].Type))
fn := toObjectExpr(pkg, pkg.unsafe().Ref("Sizeof"))
fn := toObjectExpr(pkg, unsafeRef("Sizeof"))
ret = &Element{
Val: &ast.CallExpr{Fun: fn, Args: []ast.Expr{args[0].Val}},
Type: types.Typ[types.Uintptr],
Expand All @@ -760,7 +770,7 @@ func (p unsafeAlignofInstr) Call(pkg *Package, args []*Element, flags InstrFlags
checkArgsCount(pkg, "unsafe.Alignof", 1, len(args), src)

typ := types.Default(realType(args[0].Type))
fn := toObjectExpr(pkg, pkg.unsafe().Ref("Alignof"))
fn := toObjectExpr(pkg, unsafeRef("Alignof"))
ret = &Element{
Val: &ast.CallExpr{Fun: fn, Args: []ast.Expr{args[0].Val}},
Type: types.Typ[types.Uintptr],
Expand Down Expand Up @@ -804,7 +814,7 @@ func (p unsafeOffsetofInstr) Call(pkg *Package, args []*Element, flags InstrFlag
pkg.cb.panicCodeErrorf(pos, "%v", err)
}
//var offset int64
fn := toObjectExpr(pkg, pkg.unsafe().Ref("Offsetof"))
fn := toObjectExpr(pkg, unsafeRef("Offsetof"))
ret = &Element{
Val: &ast.CallExpr{Fun: fn, Args: []ast.Expr{args[0].Val}},
Type: types.Typ[types.Uintptr],
Expand Down Expand Up @@ -890,7 +900,7 @@ func (p unsafeAddInstr) Call(pkg *Package, args []*Element, flags InstrFlags, sr
}
pkg.cb.panicCodeErrorf(pos, "cannot use %v (type %v) as type int", s, t)
}
fn := toObjectExpr(pkg, pkg.unsafe().Ref("Sizeof")).(*ast.SelectorExpr)
fn := toObjectExpr(pkg, unsafeRef("Sizeof")).(*ast.SelectorExpr)
fn.Sel.Name = "Add" // only in go v1.7+
ret = &Element{
Val: &ast.CallExpr{Fun: fn, Args: []ast.Expr{args[0].Val, args[1].Val}},
Expand Down Expand Up @@ -920,7 +930,7 @@ func (p unsafeSliceInstr) Call(pkg *Package, args []*Element, flags InstrFlags,
}
pkg.cb.panicCodeErrorf(pos, "non-integer len argument in unsafe.Slice - %v", t)
}
fn := toObjectExpr(pkg, pkg.unsafe().Ref("Sizeof")).(*ast.SelectorExpr)
fn := toObjectExpr(pkg, unsafeRef("Sizeof")).(*ast.SelectorExpr)
fn.Sel.Name = "Slice" // only in go v1.7+
ret = &Element{
Val: &ast.CallExpr{Fun: fn, Args: []ast.Expr{args[0].Val, args[1].Val}},
Expand Down
2 changes: 1 addition & 1 deletion builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ func TestBuiltinCall(t *testing.T) {

func TestUnsafe(t *testing.T) {
pkg := NewPackage("", "foo", gblConf)
sizeof := pkg.unsafe().Ref("Sizeof")
sizeof := unsafeRef("Sizeof")
expr := toObjectExpr(pkg, sizeof)
if v, ok := expr.(*ast.SelectorExpr); ok {
if id, ok := v.X.(*ast.Ident); !ok || id.Name != "unsafe" || v.Sel.Name != "Sizeof" {
Expand Down
18 changes: 9 additions & 9 deletions error_msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1133,7 +1133,7 @@ func TestErrUnsafe(t *testing.T) {
codeErrorTest(t,
`./foo.gop:6:15: missing argument to function call: unsafe.Sizeof()`,
func(pkg *gox.Package) {
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
Val(builtin.Ref("Sizeof")).CallWith(0, 0, source("unsafe.Sizeof()", 6, 2)).EndStmt().
EndStmt().
Expand All @@ -1142,7 +1142,7 @@ func TestErrUnsafe(t *testing.T) {
codeErrorTest(t,
`./foo.gop:6:15: too many arguments to function call: unsafe.Sizeof(1, 2)`,
func(pkg *gox.Package) {
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
Val(builtin.Ref("Sizeof")).Val(1).Val(2).CallWith(2, 0, source("unsafe.Sizeof(1, 2)", 6, 2)).EndStmt().
EndStmt().
Expand All @@ -1151,7 +1151,7 @@ func TestErrUnsafe(t *testing.T) {
codeErrorTest(t,
`./foo.gop:6:17: invalid expression unsafe.Offsetof(1)`,
func(pkg *gox.Package) {
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
Val(builtin.Ref("Offsetof")).Val(1).CallWith(1, 0, source("unsafe.Offsetof(1)", 6, 2)).EndStmt().
EndStmt().
Expand All @@ -1168,7 +1168,7 @@ func TestErrUnsafe(t *testing.T) {
foo := pkg.NewType("foo").InitType(pkg, typ)
recv := pkg.NewParam(token.NoPos, "a", foo)
pkg.NewFunc(recv, "Bar", nil, nil, false).BodyStart(pkg).End()
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
NewVar(foo, "a").
Val(builtin.Ref("Offsetof")).VarVal("a").MemberVal("Bar").CallWith(1, 0, source("unsafe.Offsetof(a.Bar)", 14, 2)).EndStmt().
Expand All @@ -1177,7 +1177,7 @@ func TestErrUnsafe(t *testing.T) {
})
codeErrorTest(t, `./foo.gop:17:26: invalid expression unsafe.Offsetof(t.M.m): selector implies indirection of embedded t.M`,
func(pkg *gox.Package) {
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
fieldsM := []*types.Var{
types.NewField(token.NoPos, pkg.Types, "m", types.Typ[types.Int], false),
types.NewField(token.NoPos, pkg.Types, "n", types.Typ[types.String], false),
Expand All @@ -1199,7 +1199,7 @@ func TestErrUnsafe(t *testing.T) {
`./foo.gop:7:12: cannot use a (type int) as type unsafe.Pointer in argument to unsafe.Add`,
func(pkg *gox.Package) {
tyInt := types.Typ[types.Int]
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
NewVar(tyInt, "a").
Val(builtin.Ref("Add")).Val(ctxRef(pkg, "a"), source("a", 7, 14)).Val(10).CallWith(2, 0, source("unsafe.Add(a, 10)", 7, 2)).EndStmt().
Expand All @@ -1209,7 +1209,7 @@ func TestErrUnsafe(t *testing.T) {
`./foo.gop:7:12: cannot use "hello" (type untyped string) as type int`,
func(pkg *gox.Package) {
tyUP := types.Typ[types.UnsafePointer]
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
NewVar(tyUP, "a").
Val(builtin.Ref("Add")).Val(ctxRef(pkg, "a"), source("a", 7, 14)).Val("hello", source(`"hello"`, 7, 16)).CallWith(2, 0, source("unsafe.Add(a, 10)", 7, 2)).EndStmt().
Expand All @@ -1219,7 +1219,7 @@ func TestErrUnsafe(t *testing.T) {
`./foo.gop:7:14: first argument to unsafe.Slice must be pointer; have int`,
func(pkg *gox.Package) {
tyInt := types.Typ[types.Int]
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
NewVar(tyInt, "a").
Val(builtin.Ref("Slice")).VarVal("a").Val(10).CallWith(2, 0, source(`unsafe.Slice(a, 10)`, 7, 2)).EndStmt().
Expand All @@ -1229,7 +1229,7 @@ func TestErrUnsafe(t *testing.T) {
`./foo.gop:7:14: non-integer len argument in unsafe.Slice - untyped string`,
func(pkg *gox.Package) {
tyInt := types.Typ[types.Int]
builtin := pkg.Builtin()
builtin := pkg.Unsafe()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
NewVarStart(nil, "ar").
Val(1).Val(2).Val(3).ArrayLit(types.NewArray(tyInt, 3), 3).EndInit(1).
Expand Down
4 changes: 0 additions & 4 deletions import.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,10 +549,6 @@ func (p *Package) big() PkgRef {
return p.pkgBig
}

func (p *Package) unsafe() PkgRef {
return PkgRef{types.Unsafe}
}

// ----------------------------------------------------------------------------

type null struct{}
Expand Down
6 changes: 6 additions & 0 deletions package.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ type Package struct {
files map[string]*File
file *File
conf *Config
unsafe_ PkgRef
builtin PkgRef
pkgBig PkgRef
utBigInt *types.Named
Expand Down Expand Up @@ -420,6 +421,11 @@ func (p *Package) Builtin() PkgRef {
return p.builtin
}

// Builtin returns the unsafe package.
func (p *Package) Unsafe() PkgRef {
return p.unsafe_
}

// CB returns the code builder.
func (p *Package) CB() *CodeBuilder {
return &p.cb
Expand Down
34 changes: 18 additions & 16 deletions package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1770,11 +1770,12 @@ func TestUnsafeFunc(t *testing.T) {
tyT := pkg.NewType("T").InitType(pkg, typ)
tyUintptr := types.Typ[types.Uintptr]
builtin := pkg.Builtin()
unsafe := pkg.Unsafe()
pkg.NewFunc(nil, "test", nil, nil, false).BodyStart(pkg).
NewVar(tyT, "a").NewVar(tyUintptr, "r").
VarRef(ctxRef(pkg, "r")).Val(builtin.Ref("Sizeof")).VarVal("a").Call(1).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r")).Val(builtin.Ref("Alignof")).VarVal("a").Call(1).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r")).Val(builtin.Ref("Offsetof")).VarVal("a").MemberVal("y").Call(1).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r")).Val(unsafe.Ref("Sizeof")).VarVal("a").Call(1).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r")).Val(unsafe.Ref("Alignof")).VarVal("a").Call(1).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r")).Val(unsafe.Ref("Offsetof")).VarVal("a").MemberVal("y").Call(1).Assign(1).EndStmt().
Val(builtin.Ref("println")).VarRef(ctxRef(pkg, "r")).Call(1).EndStmt().
End()
domTest(t, pkg, `package main
Expand All @@ -1800,15 +1801,16 @@ func test() {
func TestUnsafeFunc2(t *testing.T) {
pkg := newMainPackage()
builtin := pkg.Builtin()
unsafe := pkg.Unsafe()
tyUP := types.Typ[types.UnsafePointer]
tyInt := types.Typ[types.Int]
pkg.NewFunc(nil, "test17", nil, nil, false).BodyStart(pkg).
NewVar(tyUP, "a").NewVar(tyUP, "r").
NewVarStart(nil, "ar").
Val(1).Val(2).Val(3).ArrayLit(types.NewArray(tyInt, 3), 3).EndInit(1).
NewVar(types.NewSlice(tyInt), "r2").
VarRef(ctxRef(pkg, "r")).Val(builtin.Ref("Add")).VarVal("a").Val(10).Call(2).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r2")).Val(builtin.Ref("Slice")).Val(ctxRef(pkg, "ar")).Val(0).Index(1, false).UnaryOp(token.AND).Val(3).Call(2).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r")).Val(unsafe.Ref("Add")).VarVal("a").Val(10).Call(2).Assign(1).EndStmt().
VarRef(ctxRef(pkg, "r2")).Val(unsafe.Ref("Slice")).Val(ctxRef(pkg, "ar")).Val(0).Index(1, false).UnaryOp(token.AND).Val(3).Call(2).Assign(1).EndStmt().
Val(builtin.Ref("println")).VarRef(ctxRef(pkg, "r")).VarRef(ctxRef(pkg, "r2")).Call(2).EndStmt().
End()
domTest(t, pkg, `package main
Expand All @@ -1829,7 +1831,7 @@ func test17() {

func TestUnsafeConst(t *testing.T) {
pkg := newMainPackage()
builtin := pkg.Builtin()
unsafe_ := pkg.Unsafe()
fieldsM := []*types.Var{
types.NewField(token.NoPos, pkg.Types, "m", types.Typ[types.Int], false),
types.NewField(token.NoPos, pkg.Types, "n", types.Typ[types.String], false),
Expand All @@ -1845,17 +1847,17 @@ func TestUnsafeConst(t *testing.T) {
tyT := pkg.NewType("T").InitType(pkg, typT)
pkg.CB().NewVar(tyT, "t")
pkg.CB().NewConstStart(nil, "c1").
Val(builtin.Ref("Sizeof")).Val(100).Call(1).EndInit(1)
Val(unsafe_.Ref("Sizeof")).Val(100).Call(1).EndInit(1)
pkg.CB().NewConstStart(nil, "c2").
Val(builtin.Ref("Sizeof")).Val(ctxRef(pkg, "t")).Call(1).EndInit(1)
Val(unsafe_.Ref("Sizeof")).Val(ctxRef(pkg, "t")).Call(1).EndInit(1)
pkg.CB().NewConstStart(nil, "c3").
Val(builtin.Ref("Alignof")).Val("hello").Call(1).EndInit(1)
Val(unsafe_.Ref("Alignof")).Val("hello").Call(1).EndInit(1)
pkg.CB().NewConstStart(nil, "c4").
Val(builtin.Ref("Alignof")).Val(ctxRef(pkg, "t")).Call(1).EndInit(1)
Val(unsafe_.Ref("Alignof")).Val(ctxRef(pkg, "t")).Call(1).EndInit(1)
pkg.CB().NewConstStart(nil, "c5").
Val(builtin.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("y").Call(1).EndInit(1)
Val(unsafe_.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("y").Call(1).EndInit(1)
pkg.CB().NewConstStart(nil, "c6").
Val(builtin.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("n").Call(1).EndInit(1)
Val(unsafe_.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("n").Call(1).EndInit(1)

domTest(t, pkg, `package main

Expand All @@ -1880,19 +1882,19 @@ const c4 = unsafe.Alignof(t)
const c5 = unsafe.Offsetof(t.y)
const c6 = unsafe.Offsetof(t.n)
`)
c1 := pkg.CB().Val(builtin.Ref("Sizeof")).Val(ctxRef(pkg, "t")).Call(1).Get(-1)
c1 := pkg.CB().Val(unsafe_.Ref("Sizeof")).Val(ctxRef(pkg, "t")).Call(1).Get(-1)
if v, ok := constant.Int64Val(c1.CVal); !ok || uintptr(v) != (unsafe.Sizeof(int(0))*2+unsafe.Sizeof("")*2) {
t.Fatalf("unsafe.Sizeof(t) %v", c1.CVal)
}
c2 := pkg.CB().Val(builtin.Ref("Alignof")).Val(ctxRef(pkg, "t")).Call(1).Get(-1)
c2 := pkg.CB().Val(unsafe_.Ref("Alignof")).Val(ctxRef(pkg, "t")).Call(1).Get(-1)
if v, ok := constant.Int64Val(c2.CVal); !ok || uintptr(v) != unsafe.Alignof("") {
t.Fatalf("unsafe.Alignof(t) %v", c2.CVal)
}
c3 := pkg.CB().Val(builtin.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("y").Call(1).Get(-1)
c3 := pkg.CB().Val(unsafe_.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("y").Call(1).Get(-1)
if v, ok := constant.Int64Val(c3.CVal); !ok || uintptr(v) != unsafe.Sizeof(int(0)) {
t.Fatalf("unsafe.Offsetof(t.y) %v", c3.CVal)
}
c4 := pkg.CB().Val(builtin.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("n").Call(1).Get(-1)
c4 := pkg.CB().Val(unsafe_.Ref("Offsetof")).Val(ctxRef(pkg, "t")).MemberVal("n").Call(1).Get(-1)
if v, ok := constant.Int64Val(c4.CVal); !ok || uintptr(v) != (unsafe.Sizeof(int(0))*2+unsafe.Sizeof("")) {
t.Fatalf("unsafe.Offsetof(t.n) %v", c4.CVal)
}
Expand Down