ssa: map delete, map eql nil
This commit is contained in:
@@ -289,22 +289,14 @@ func (b Builder) abiChanOf(t *types.Chan) func() Expr {
|
||||
func (b Builder) abiMapOf(t *types.Map) func() Expr {
|
||||
key := b.abiTypeOf(t.Key())
|
||||
elem := b.abiTypeOf(t.Elem())
|
||||
bucket := b.abiTypeOf(b.bucketType(t))
|
||||
flags := abi.MapTypeFlags(t, (*goProgram)(b.Prog))
|
||||
sizes := (*goProgram)(b.Prog)
|
||||
bucket := b.abiTypeOf(abi.MapBucketType(t, sizes))
|
||||
flags := abi.MapTypeFlags(t, sizes)
|
||||
return func() Expr {
|
||||
return b.Call(b.Pkg.rtFunc("MapOf"), key(), elem(), bucket(), b.Prog.Val(flags))
|
||||
}
|
||||
}
|
||||
|
||||
func (b Builder) bucketType(t *types.Map) types.Type {
|
||||
if bucket, ok := b.Pkg.bucket[t]; ok {
|
||||
return bucket
|
||||
}
|
||||
bucket := abi.MapBucketType(t, (*goProgram)(b.Prog))
|
||||
b.Pkg.bucket[t] = bucket
|
||||
return bucket
|
||||
}
|
||||
|
||||
// func StructField(name string, typ *abi.Type, off uintptr, tag string, embedded bool)
|
||||
// func Struct(pkgPath string, size uintptr, fields []abi.StructField)
|
||||
func (b Builder) abiStructOf(t *types.Struct) func() Expr {
|
||||
|
||||
@@ -150,6 +150,9 @@ func (b Builder) MapLen(x Expr) Expr {
|
||||
log.Printf("MapLen %v\n", x.impl)
|
||||
}
|
||||
prog := b.Prog
|
||||
if x.impl.IsNull() {
|
||||
return prog.Val(0)
|
||||
}
|
||||
x.Type = prog.Pointer(prog.Int())
|
||||
return b.Load(x)
|
||||
}
|
||||
@@ -607,7 +610,6 @@ func (b Builder) Next(typ Type, iter Expr, isString bool) Expr {
|
||||
b.SetBlockEx(blks[2], AtEnd, false)
|
||||
b.blk.last = blks[2].last
|
||||
return phi.Expr
|
||||
|
||||
}
|
||||
|
||||
// The MakeChan instruction creates a new channel object and yields a
|
||||
|
||||
22
ssa/expr.go
22
ssa/expr.go
@@ -596,6 +596,13 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
|
||||
case token.NEQ:
|
||||
return Expr{b.impl.CreateICmp(llvm.IntNE, dx, dy, ""), tret}
|
||||
}
|
||||
case vkMap:
|
||||
switch op {
|
||||
case token.EQL:
|
||||
return b.Prog.BoolVal(x.impl.IsNull() == y.impl.IsNull())
|
||||
case token.NEQ:
|
||||
return b.Prog.BoolVal(x.impl.IsNull() != y.impl.IsNull())
|
||||
}
|
||||
case vkIface, vkEface:
|
||||
toEface := func(x Expr, emtpy bool) Expr {
|
||||
if emtpy {
|
||||
@@ -1082,6 +1089,21 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
return b.StringData(args[0]) // TODO(xsw): check return type
|
||||
case "SliceData":
|
||||
return b.SliceData(args[0]) // TODO(xsw): check return type
|
||||
case "delete":
|
||||
if len(args) == 2 && args[0].kind == vkMap {
|
||||
m := args[0]
|
||||
t := b.abiType(m.raw.Type)
|
||||
ptr := b.mapKeyPtr(args[1])
|
||||
b.Call(b.Pkg.rtFunc("MapDelete"), t, m, ptr)
|
||||
return
|
||||
}
|
||||
case "clear":
|
||||
if len(args) == 1 && args[0].kind == vkMap {
|
||||
m := args[0]
|
||||
t := b.abiType(m.raw.Type)
|
||||
b.Call(b.Pkg.rtFunc("MapClear"), t, m)
|
||||
return
|
||||
}
|
||||
}
|
||||
panic("todo: " + fn)
|
||||
}
|
||||
|
||||
@@ -326,13 +326,12 @@ func (p Program) NewPackage(name, pkgPath string) Package {
|
||||
pymods := make(map[string]Global)
|
||||
strs := make(map[string]llvm.Value)
|
||||
named := make(map[types.Type]Expr)
|
||||
bucket := make(map[*types.Map]types.Type)
|
||||
p.NeedRuntime = false
|
||||
// Don't need reset p.needPyInit here
|
||||
// p.needPyInit = false
|
||||
ret := &aPackage{
|
||||
mod: mod, vars: gbls, fns: fns, stubs: stubs,
|
||||
pyobjs: pyobjs, pymods: pymods, strs: strs, named: named, bucket: bucket, Prog: p}
|
||||
pyobjs: pyobjs, pymods: pymods, strs: strs, named: named, Prog: p}
|
||||
ret.abi.Init(pkgPath)
|
||||
return ret
|
||||
}
|
||||
@@ -577,7 +576,6 @@ type aPackage struct {
|
||||
pymods map[string]Global
|
||||
strs map[string]llvm.Value
|
||||
named map[types.Type]Expr
|
||||
bucket map[*types.Map]types.Type
|
||||
afterb unsafe.Pointer
|
||||
patch func(types.Type) types.Type
|
||||
|
||||
|
||||
Reference in New Issue
Block a user