Skip to content

Commit

Permalink
Merge pull request #1735 from xushiwei/t
Browse files Browse the repository at this point in the history
mayBuiltin new/delete
  • Loading branch information
xushiwei authored Feb 13, 2024
2 parents 6c0687b + 459b5f1 commit 634aa46
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 19 deletions.
21 changes: 21 additions & 0 deletions cl/compile_gop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ import (
"testing"
)

func TestMayBuiltinDelete(t *testing.T) {
gopClTest(t, `
func Delete(a int) {}
func Foo(m map[string]int) {
delete(m, "a")
}
delete 10
`, `package main
func Delete(a int) {
}
func Foo(m map[string]int) {
delete(m, "a")
}
func main() {
Delete(10)
}
`)
}

func TestVargCommand(t *testing.T) {
gopClTest(t, `
type foo int
Expand Down
43 changes: 24 additions & 19 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ const (
clIdentGoto
clCallWithTwoValue
clCommandWithoutArgs
clMayBuiltinNew // maybe is builtin directive `new`
)

const (
Expand Down Expand Up @@ -562,13 +561,11 @@ func (p *fnType) initFuncs(base int, funcs []types.Object) {
}

func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
var flags gox.InstrFlags
var ifn *ast.Ident
switch fn := v.Fun.(type) {
case *ast.Ident:
if len(v.Args) == 1 && fn.Name == "new" { // maybe new(T)
flags = clMayBuiltinNew
}
compileIdent(ctx, fn, clIdentAllowBuiltin|inFlags)
ifn = fn
case *ast.SelectorExpr:
compileSelectorExpr(ctx, fn, 0)
case *ast.ErrWrapExpr:
Expand All @@ -585,9 +582,10 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
compileExpr(ctx, fn)
}
var fnt = ctx.cb.Get(-1).Type
var flags gox.InstrFlags
var ellipsis = v.Ellipsis != gotoken.NoPos
if ellipsis {
flags |= gox.InstrFlagEllipsis
flags = gox.InstrFlagEllipsis
}
if (inFlags & clCallWithTwoValue) != 0 {
flags |= gox.InstrFlagTwoValue
Expand All @@ -600,6 +598,9 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
break
}
if fn.next == nil {
if ifn != nil && mayBuiltin(ctx, ifn, v, flags) {
break
}
panic(err)
}
fn = fn.next
Expand All @@ -609,6 +610,23 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
}
}

// maybe builtin new/delete: see TestSpxNewObj, TestMayBuiltinDelete
func mayBuiltin(ctx *blockCtx, ifn *ast.Ident, v *ast.CallExpr, flags gox.InstrFlags) bool {
switch name := ifn.Name; name {
case "new", "delete":
cb := ctx.cb
cb.InternalStack().Pop()
o := ctx.pkg.Builtin().Ref(name)
cb.Val(o, ifn)
for _, arg := range v.Args {
compileExpr(ctx, arg)
}
cb.CallWith(len(v.Args), flags, v)
return true
}
return false
}

func compileCallArgs(fn *fnType, ctx *blockCtx, v *ast.CallExpr, ellipsis bool, flags gox.InstrFlags) (err error) {
cb := ctx.cb
stk := cb.InternalStack()
Expand Down Expand Up @@ -657,23 +675,10 @@ func compileCallArgs(fn *fnType, ctx *blockCtx, v *ast.CallExpr, ellipsis bool,
compileExpr(ctx, arg)
}
}
if (flags & clMayBuiltinNew) != 0 { // maybe new(T): see TestSpxNewObj
arg := stk.Get(-1)
if _, ok := arg.Type.(*gox.TypeType); ok && isNonInstr(stk.Get(-2).Type) {
stk.PopN(2)
cb.Val(ctx.pkg.Builtin().Ref("new"))
stk.Push(arg)
}
}
cb.CallWith(len(v.Args), flags, v)
return
}

func isNonInstr(t types.Type) bool {
_, ok := t.(*gox.TyInstruction)
return !ok
}

type clLambaFlag string

const (
Expand Down

0 comments on commit 634aa46

Please sign in to comment.