llgo/ssa: StringData/StringLen
This commit is contained in:
@@ -299,7 +299,7 @@ func (p Package) NewPyFunc(name string, sig *types.Signature, doInit bool) PyFun
|
||||
return v
|
||||
}
|
||||
prog := p.Prog
|
||||
prog.needPyInit = true
|
||||
prog.NeedPyInit = true
|
||||
obj := p.NewVar(name, prog.PyObjectPtrPtr().RawType(), InC)
|
||||
if doInit {
|
||||
obj.Init(prog.Null(obj.Type))
|
||||
|
||||
29
ssa/expr.go
29
ssa/expr.go
@@ -598,6 +598,26 @@ func (b Builder) getField(x Expr, idx int) Expr {
|
||||
return Expr{fld, tfld}
|
||||
}
|
||||
|
||||
// StringData returns the data pointer of a string.
|
||||
func (b Builder) StringData(x Expr) Expr {
|
||||
if debugInstr {
|
||||
log.Printf("StringData %v\n", x.impl)
|
||||
}
|
||||
prog := b.Prog
|
||||
ptr := llvm.CreateExtractValue(b.impl, x.impl, 0)
|
||||
return Expr{ptr, prog.CStr()}
|
||||
}
|
||||
|
||||
// StringLen returns the length of a string.
|
||||
func (b Builder) StringLen(x Expr) Expr {
|
||||
if debugInstr {
|
||||
log.Printf("StringLen %v\n", x.impl)
|
||||
}
|
||||
prog := b.Prog
|
||||
ptr := llvm.CreateExtractValue(b.impl, x.impl, 1)
|
||||
return Expr{ptr, prog.Int()}
|
||||
}
|
||||
|
||||
// The IndexAddr instruction yields the address of the element at
|
||||
// index `idx` of collection `x`. `idx` is an integer expression.
|
||||
//
|
||||
@@ -649,8 +669,7 @@ func (b Builder) Index(x, idx Expr, addr func(Expr) Expr) Expr {
|
||||
panic(fmt.Errorf("invalid operation: cannot index %v", t))
|
||||
}
|
||||
telem = prog.rawType(types.Typ[types.Byte])
|
||||
pkg := b.Func.Pkg
|
||||
ptr = b.InlineCall(pkg.rtFunc("StringData"), x)
|
||||
ptr = b.StringData(x)
|
||||
case *types.Array:
|
||||
telem = prog.Index(x.Type)
|
||||
if addr != nil {
|
||||
@@ -717,7 +736,7 @@ func (b Builder) Slice(x, low, high, max Expr) (ret Expr) {
|
||||
panic(fmt.Errorf("invalid operation: cannot slice %v", t))
|
||||
}
|
||||
if high.IsNil() {
|
||||
high = b.InlineCall(pkg.rtFunc("StringLen"), x)
|
||||
high = b.StringLen(x)
|
||||
}
|
||||
ret.Type = x.Type
|
||||
ret.impl = b.InlineCall(pkg.rtFunc("NewStringSlice"), x, low, high).impl
|
||||
@@ -871,7 +890,7 @@ func (b Builder) AllocaCStr(gostr Expr) (ret Expr) {
|
||||
log.Printf("AllocaCStr %v\n", gostr.impl)
|
||||
}
|
||||
pkg := b.Func.Pkg
|
||||
n := b.InlineCall(pkg.rtFunc("StringLen"), gostr)
|
||||
n := b.StringLen(gostr)
|
||||
n1 := b.BinOp(token.ADD, n, b.Prog.Val(1))
|
||||
cstr := b.Alloca(n1)
|
||||
return b.InlineCall(pkg.rtFunc("CStrCopy"), cstr, gostr)
|
||||
@@ -1250,7 +1269,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
return b.InlineCall(b.Func.Pkg.rtFunc("SliceLen"), arg)
|
||||
case *types.Basic:
|
||||
if t.Kind() == types.String {
|
||||
return b.InlineCall(b.Func.Pkg.rtFunc("StringLen"), arg)
|
||||
return b.StringLen(arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,8 +140,8 @@ type aProgram struct {
|
||||
callNoArgs *types.Signature
|
||||
callOneArg *types.Signature
|
||||
|
||||
needRuntime bool
|
||||
needPyInit bool
|
||||
NeedRuntime bool
|
||||
NeedPyInit bool
|
||||
}
|
||||
|
||||
// A Program presents a program.
|
||||
@@ -189,21 +189,11 @@ func (p Program) SetRuntime(runtime any) {
|
||||
}
|
||||
}
|
||||
|
||||
// NeedRuntime returns if the current package needs runtime.
|
||||
func (p Program) NeedRuntime() bool {
|
||||
return p.needRuntime
|
||||
}
|
||||
|
||||
// NeedPyInit returns if the current package needs Python initialization.
|
||||
func (p Program) NeedPyInit() bool {
|
||||
return p.needPyInit
|
||||
}
|
||||
|
||||
func (p Program) runtime() *types.Package {
|
||||
if p.rt == nil {
|
||||
p.rt = p.rtget()
|
||||
}
|
||||
p.needRuntime = true
|
||||
p.NeedRuntime = true
|
||||
return p.rt
|
||||
}
|
||||
|
||||
@@ -268,7 +258,7 @@ func (p Program) NewPackage(name, pkgPath string) Package {
|
||||
stubs := make(map[string]Function)
|
||||
pyfns := make(map[string]PyFunction)
|
||||
pymods := make(map[string]Global)
|
||||
p.needRuntime = false
|
||||
p.NeedRuntime = false
|
||||
// Don't need reset p.needPyInit here
|
||||
// p.needPyInit = false
|
||||
return &aPackage{mod, gbls, fns, stubs, pyfns, pymods, p}
|
||||
@@ -397,7 +387,7 @@ func (p Package) rtFunc(fnName string) Expr {
|
||||
}
|
||||
|
||||
func (p Package) pyFunc(fullName string, sig *types.Signature) Expr {
|
||||
p.Prog.needPyInit = true
|
||||
p.Prog.NeedPyInit = true
|
||||
return p.NewFunc(fullName, sig, InC).Expr
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ source_filename = "foo/bar"
|
||||
|
||||
@a = external global {}
|
||||
`)
|
||||
if prog.NeedRuntime() {
|
||||
if prog.NeedRuntime {
|
||||
t.Fatal("NeedRuntime?")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user