llgo run: strlen
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
; ModuleID = 'main'
|
||||
source_filename = "main"
|
||||
|
||||
@main._Cgo_always_false = global ptr null
|
||||
@main.format = global ptr null
|
||||
@"main.init$guard" = global ptr null
|
||||
|
||||
|
||||
27
cl/builtin_test.go
Normal file
27
cl/builtin_test.go
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIgnoreName(t *testing.T) {
|
||||
if !ignoreName("runtime.foo") || !ignoreName("runtime/foo") || !ignoreName("internal/abi") {
|
||||
t.Fatal("ignoreName failed")
|
||||
}
|
||||
}
|
||||
@@ -87,20 +87,26 @@ func ignorePkgInit(pkgPath string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ignoreFunc(name string, fn *ssa.Function) bool {
|
||||
func ignoreName(name string) bool {
|
||||
/* TODO(xsw): confirm this is not needed more
|
||||
if name == "unsafe.init" {
|
||||
return true
|
||||
}
|
||||
*/
|
||||
fnName := fn.Name()
|
||||
if strings.HasPrefix(fnName, "_Cgo_") {
|
||||
return true
|
||||
if strings.HasPrefix(name, "internal/") || strings.HasPrefix(name, "crypto/") ||
|
||||
strings.HasPrefix(name, "arena.") || strings.HasPrefix(name, "maps.") ||
|
||||
strings.HasPrefix(name, "time.") || strings.HasPrefix(name, "syscall.") ||
|
||||
strings.HasPrefix(name, "os.") || strings.HasPrefix(name, "plugin.") ||
|
||||
strings.HasPrefix(name, "reflect.") || strings.HasPrefix(name, "errors.") {
|
||||
return true // TODO(xsw)
|
||||
}
|
||||
const runtime = "runtime"
|
||||
if strings.HasPrefix(name, runtime) {
|
||||
left := name[len(runtime):]
|
||||
return strings.HasPrefix(left, ".cgo") || strings.HasPrefix(left, "/cgo")
|
||||
return inPkg(name, "runtime") || inPkg(name, "sync")
|
||||
}
|
||||
|
||||
func inPkg(name, pkg string) bool {
|
||||
if len(name) > len(pkg) && strings.HasPrefix(name, pkg) {
|
||||
c := name[len(pkg)]
|
||||
return c == '.' || c == '/'
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -131,8 +137,12 @@ type context struct {
|
||||
|
||||
func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
|
||||
tn := t.Object().(*types.TypeName)
|
||||
tnName := tn.Name()
|
||||
typ := tn.Type()
|
||||
name := fullName(tn.Pkg(), tn.Name())
|
||||
name := fullName(tn.Pkg(), tnName)
|
||||
if ignoreName(name) {
|
||||
return
|
||||
}
|
||||
if debugInstr {
|
||||
log.Println("==> NewType", name, typ)
|
||||
}
|
||||
@@ -145,15 +155,19 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
|
||||
mthds := prog.MethodSets.MethodSet(typ)
|
||||
for i, n := 0, mthds.Len(); i < n; i++ {
|
||||
mthd := mthds.At(i)
|
||||
ssaMthd := prog.MethodValue(mthd)
|
||||
if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil {
|
||||
p.compileFunc(pkg, mthd.Obj().Pkg(), ssaMthd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global variable.
|
||||
func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
|
||||
typ := gbl.Type()
|
||||
name := fullName(gbl.Pkg.Pkg, gbl.Name())
|
||||
if ignoreName(name) || checkCgo(gbl.Name()) {
|
||||
return
|
||||
}
|
||||
if debugInstr {
|
||||
log.Println("==> NewVar", name, typ)
|
||||
}
|
||||
@@ -163,13 +177,13 @@ func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
|
||||
|
||||
func (p *context) compileFunc(pkg llssa.Package, pkgTypes *types.Package, f *ssa.Function) {
|
||||
sig := f.Signature
|
||||
name := p.funcName(pkgTypes, f)
|
||||
if debugInstr {
|
||||
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig)
|
||||
}
|
||||
if ignoreFunc(name, f) {
|
||||
name, ok := p.funcName(pkgTypes, f, true)
|
||||
if !ok { // ignored
|
||||
return
|
||||
}
|
||||
if debugInstr {
|
||||
log.Println("==> NewFunc", f.Name(), name, "type:", sig.Recv(), sig)
|
||||
}
|
||||
fn := pkg.NewFunc(name, sig)
|
||||
p.inits = append(p.inits, func() {
|
||||
p.fn = fn
|
||||
|
||||
21
cl/import.go
21
cl/import.go
@@ -137,18 +137,27 @@ func funcName(pkg *types.Package, fn *ssa.Function) string {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *context) funcName(pkg *types.Package, fn *ssa.Function) string {
|
||||
name := funcName(pkg, fn)
|
||||
if v, ok := p.link[name]; ok {
|
||||
return v
|
||||
func checkCgo(fnName string) bool {
|
||||
return len(fnName) > 4 && fnName[0] == '_' && fnName[2] == 'g' && fnName[3] == 'o' &&
|
||||
(fnName[1] == 'C' || fnName[1] == 'c') &&
|
||||
(fnName[4] == '_' || strings.HasPrefix(fnName[4:], "Check"))
|
||||
}
|
||||
return name
|
||||
|
||||
func (p *context) funcName(pkg *types.Package, fn *ssa.Function, ignore bool) (string, bool) {
|
||||
name := funcName(pkg, fn)
|
||||
if ignore && ignoreName(name) || checkCgo(fn.Name()) {
|
||||
return name, false
|
||||
}
|
||||
if v, ok := p.link[name]; ok {
|
||||
return v, true
|
||||
}
|
||||
return name, true
|
||||
}
|
||||
|
||||
func (p *context) funcOf(fn *ssa.Function) llssa.Function {
|
||||
pkgTypes := p.ensureLoaded(fn.Pkg.Pkg)
|
||||
pkg := p.pkg
|
||||
name := p.funcName(pkgTypes, fn)
|
||||
name, _ := p.funcName(pkgTypes, fn, false)
|
||||
if ret := pkg.FuncOf(name); ret != nil {
|
||||
return ret
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user