@@ -1,7 +1,6 @@
|
|||||||
; ModuleID = 'main'
|
; ModuleID = 'main'
|
||||||
source_filename = "main"
|
source_filename = "main"
|
||||||
|
|
||||||
@main._Cgo_always_false = global ptr null
|
|
||||||
@main.format = global ptr null
|
@main.format = global ptr null
|
||||||
@"main.init$guard" = 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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func ignoreFunc(name string, fn *ssa.Function) bool {
|
func ignoreName(name string) bool {
|
||||||
/* TODO(xsw): confirm this is not needed more
|
/* TODO(xsw): confirm this is not needed more
|
||||||
if name == "unsafe.init" {
|
if name == "unsafe.init" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
fnName := fn.Name()
|
if strings.HasPrefix(name, "internal/") || strings.HasPrefix(name, "crypto/") ||
|
||||||
if strings.HasPrefix(fnName, "_Cgo_") {
|
strings.HasPrefix(name, "arena.") || strings.HasPrefix(name, "maps.") ||
|
||||||
return true
|
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"
|
return inPkg(name, "runtime") || inPkg(name, "sync")
|
||||||
if strings.HasPrefix(name, runtime) {
|
}
|
||||||
left := name[len(runtime):]
|
|
||||||
return strings.HasPrefix(left, ".cgo") || strings.HasPrefix(left, "/cgo")
|
func inPkg(name, pkg string) bool {
|
||||||
|
if len(name) > len(pkg) && strings.HasPrefix(name, pkg) {
|
||||||
|
c := name[len(pkg)]
|
||||||
|
return c == '.' || c == '/'
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -131,8 +137,12 @@ type context struct {
|
|||||||
|
|
||||||
func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
|
func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
|
||||||
tn := t.Object().(*types.TypeName)
|
tn := t.Object().(*types.TypeName)
|
||||||
|
tnName := tn.Name()
|
||||||
typ := tn.Type()
|
typ := tn.Type()
|
||||||
name := fullName(tn.Pkg(), tn.Name())
|
name := fullName(tn.Pkg(), tnName)
|
||||||
|
if ignoreName(name) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Println("==> NewType", name, typ)
|
log.Println("==> NewType", name, typ)
|
||||||
}
|
}
|
||||||
@@ -145,8 +155,9 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
|
|||||||
mthds := prog.MethodSets.MethodSet(typ)
|
mthds := prog.MethodSets.MethodSet(typ)
|
||||||
for i, n := 0, mthds.Len(); i < n; i++ {
|
for i, n := 0, mthds.Len(); i < n; i++ {
|
||||||
mthd := mthds.At(i)
|
mthd := mthds.At(i)
|
||||||
ssaMthd := prog.MethodValue(mthd)
|
if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil {
|
||||||
p.compileFunc(pkg, mthd.Obj().Pkg(), ssaMthd)
|
p.compileFunc(pkg, mthd.Obj().Pkg(), ssaMthd)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +165,9 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
|
|||||||
func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
|
func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
|
||||||
typ := gbl.Type()
|
typ := gbl.Type()
|
||||||
name := fullName(gbl.Pkg.Pkg, gbl.Name())
|
name := fullName(gbl.Pkg.Pkg, gbl.Name())
|
||||||
|
if ignoreName(name) || checkCgo(gbl.Name()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Println("==> NewVar", name, typ)
|
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) {
|
func (p *context) compileFunc(pkg llssa.Package, pkgTypes *types.Package, f *ssa.Function) {
|
||||||
sig := f.Signature
|
sig := f.Signature
|
||||||
name := p.funcName(pkgTypes, f)
|
name, ok := p.funcName(pkgTypes, f, true)
|
||||||
if debugInstr {
|
if !ok { // ignored
|
||||||
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig)
|
|
||||||
}
|
|
||||||
if ignoreFunc(name, f) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if debugInstr {
|
||||||
|
log.Println("==> NewFunc", f.Name(), name, "type:", sig.Recv(), sig)
|
||||||
|
}
|
||||||
fn := pkg.NewFunc(name, sig)
|
fn := pkg.NewFunc(name, sig)
|
||||||
p.inits = append(p.inits, func() {
|
p.inits = append(p.inits, func() {
|
||||||
p.fn = fn
|
p.fn = fn
|
||||||
|
|||||||
19
cl/import.go
19
cl/import.go
@@ -137,18 +137,27 @@ func funcName(pkg *types.Package, fn *ssa.Function) string {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) funcName(pkg *types.Package, fn *ssa.Function) string {
|
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"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *context) funcName(pkg *types.Package, fn *ssa.Function, ignore bool) (string, bool) {
|
||||||
name := funcName(pkg, fn)
|
name := funcName(pkg, fn)
|
||||||
if v, ok := p.link[name]; ok {
|
if ignore && ignoreName(name) || checkCgo(fn.Name()) {
|
||||||
return v
|
return name, false
|
||||||
}
|
}
|
||||||
return name
|
if v, ok := p.link[name]; ok {
|
||||||
|
return v, true
|
||||||
|
}
|
||||||
|
return name, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) funcOf(fn *ssa.Function) llssa.Function {
|
func (p *context) funcOf(fn *ssa.Function) llssa.Function {
|
||||||
pkgTypes := p.ensureLoaded(fn.Pkg.Pkg)
|
pkgTypes := p.ensureLoaded(fn.Pkg.Pkg)
|
||||||
pkg := p.pkg
|
pkg := p.pkg
|
||||||
name := p.funcName(pkgTypes, fn)
|
name, _ := p.funcName(pkgTypes, fn, false)
|
||||||
if ret := pkg.FuncOf(name); ret != nil {
|
if ret := pkg.FuncOf(name); ret != nil {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user