Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 11 additions & 28 deletions cl/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -859,24 +859,18 @@ func TestHandleExportDiffName(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save and restore global state
oldEnableExportRename := enableExportRename
defer func() {
EnableExportRename(oldEnableExportRename)
}()
EnableExportRename(tt.enableExportRename)

// Setup context
prog := llssa.NewProgram(nil)
pkg := prog.NewPackage("test", "test")
ctx := &context{
prog: prog,
pkg: pkg,
prog: prog,
pkg: pkg,
options: Options{ExportRename: tt.enableExportRename},
}

// Call initLinkname with closure that mimics initLinknameByDoc behavior
ret := ctx.initLinkname(tt.line, true, func(name string, isExport bool) (string, bool, bool) {
return tt.fullName, false, name == tt.inPkgName || (isExport && enableExportRename)
return tt.fullName, false, name == tt.inPkgName || (isExport && ctx.options.ExportRename)
})

// Verify result
Expand Down Expand Up @@ -944,7 +938,7 @@ func TestInitLinknameByDocExportDiffNames(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Without enableExportRename, export with different name will panic
// Without ExportRename, export with different names will panic.
if !tt.wantExported && !tt.enableExportRename {
defer func() {
if r := recover(); r == nil {
Expand All @@ -953,19 +947,13 @@ func TestInitLinknameByDocExportDiffNames(t *testing.T) {
}()
}

// Save and restore global state
oldEnableExportRename := enableExportRename
defer func() {
EnableExportRename(oldEnableExportRename)
}()
EnableExportRename(tt.enableExportRename)

// Setup context
prog := llssa.NewProgram(nil)
pkg := prog.NewPackage("test", "test")
ctx := &context{
prog: prog,
pkg: pkg,
prog: prog,
pkg: pkg,
options: Options{ExportRename: tt.enableExportRename},
}

// Call initLinknameByDoc
Expand Down Expand Up @@ -1018,17 +1006,12 @@ func TestInitLinkExportDiffNames(t *testing.T) {
}()
}

oldEnableExportRename := enableExportRename
defer func() {
EnableExportRename(oldEnableExportRename)
}()
EnableExportRename(tt.enableExportRename)

prog := llssa.NewProgram(nil)
pkg := prog.NewPackage("test", "test")
ctx := &context{
prog: prog,
pkg: pkg,
prog: prog,
pkg: pkg,
options: Options{ExportRename: tt.enableExportRename},
}

ctx.initLinkname(tt.line, true, func(inPkgName string, isExport bool) (fullName string, isVar, ok bool) {
Expand Down
15 changes: 9 additions & 6 deletions cl/caller_frame_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,6 @@ func TestRuntimeFrameNameNormalization(t *testing.T) {
}

func TestCompileRuntimeCallerFrameInstrumentation(t *testing.T) {
t.Setenv("LLGO_SHADOW_STACK", "1")
ssapkg, files := buildCallerFrameSSAPackage(t, "example.com/foo", `package foo
import "runtime/debug"

Expand All @@ -508,7 +507,9 @@ func f() {
}
`)
prog := newLLSSAProg(t)
pkg, err := NewPackage(prog, ssapkg, files)
pkg, _, err := NewPackageExWithEmbedMetaOptions(
prog, nil, nil, nil, ssapkg, files, nil, false, Options{ShadowStack: true},
)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -742,7 +743,6 @@ func top() {
}

func TestCompileRuntimeCallerFrameUsesGoNameForLinkname(t *testing.T) {
t.Setenv("LLGO_SHADOW_STACK", "1")
ssapkg, files := buildCallerFrameSSAPackage(t, "command-line-arguments", `package main
import "runtime"

Expand All @@ -753,7 +753,9 @@ func renamedPC() uintptr {
`)
prog := newLLSSAProg(t)
prog.SetLinkname("command-line-arguments.renamedPC", "main.renamedPCSymbol")
pkg, err := NewPackage(prog, ssapkg, files)
pkg, _, err := NewPackageExWithEmbedMetaOptions(
prog, nil, nil, nil, ssapkg, files, nil, false, Options{ShadowStack: true},
)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -821,7 +823,6 @@ func f() { _ = runtime.FuncForPC(0) }
}

func TestCompileRuntimeCallerLocationOnlyForRuntimePaths(t *testing.T) {
t.Setenv("LLGO_SHADOW_STACK", "1")
ssapkg, files := buildCallerFrameSSAPackage(t, "example.com/foo", `package foo
import "runtime"

Expand All @@ -833,7 +834,9 @@ func f() {
}
`)
prog := newLLSSAProg(t)
pkg, err := NewPackage(prog, ssapkg, files)
pkg, _, err := NewPackageExWithEmbedMetaOptions(
prog, nil, nil, nil, ssapkg, files, nil, false, Options{ShadowStack: true},
)
if err != nil {
t.Fatal(err)
}
Expand Down
33 changes: 33 additions & 0 deletions cl/caller_tracking_precompute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package cl

import (
"reflect"
"sync"
"testing"

Expand Down Expand Up @@ -72,6 +73,38 @@ func Logs() { dep.Where() }
wg.Wait()
}

func TestCallerTrackingPrecomputeMatchesLazyAnalysis(t *testing.T) {
dep, root := buildCallerFrameSSAProgram(t,
"example.com/dep", `package dep
import "runtime"
func Where() { runtime.Caller(0) }
func Quiet() {}
`,
"example.com/root", `package root
import "example.com/dep"
func Logs() { dep.Where() }
func Plain() { dep.Quiet() }
`)
pkgs := []*gossa.Package{root, dep}
lazy := NewCallerTracking()
for _, pkg := range pkgs {
runtimeCallerBaseSet(lazy, pkg)
}
for _, pkg := range pkgs {
runtimeCallerFuncSet(lazy, pkg)
}
precomputed := NewCallerTracking()
precomputed.Precompute(pkgs)
for _, pkg := range pkgs {
if got, want := precomputed.base[pkg], lazy.base[pkg]; !reflect.DeepEqual(got, want) {
t.Fatalf("precomputed base set for %s differs from lazy set", pkg.Pkg.Path())
}
if got, want := precomputed.extended[pkg], lazy.extended[pkg]; !reflect.DeepEqual(got, want) {
t.Fatalf("precomputed extended set for %s differs from lazy set", pkg.Pkg.Path())
}
}
}

func TestCallerTrackingPrecomputeRejectsLatePackages(t *testing.T) {
dep, root := buildCallerFrameSSAProgram(t,
"example.com/dep", `package dep
Expand Down
14 changes: 5 additions & 9 deletions cl/cltest/cltest.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,13 +760,6 @@ func filterRunOutput(in []byte) []byte {

func CompileIREx(t *testing.T, src any, fname string, dbg bool, configure func(llssa.Program)) string {
t.Helper()
// Build.Do configures cl debug globals for full-package builds. Keep the
// single-file compiler assertions independent from any prior build test.
cl.EnableDebug(dbg)
cl.EnableDbgSyms(dbg)
defer cl.EnableDebug(false)
defer cl.EnableDbgSyms(false)

fset := token.NewFileSet()
f, err := parser.ParseFile(fset, fname, src, parser.ParseComments)
if err != nil {
Expand All @@ -792,9 +785,12 @@ func CompileIREx(t *testing.T, src any, fname string, dbg bool, configure func(l
configure(prog)
}

ret, err := cl.NewPackage(prog, foo, files)
ret, _, err := cl.NewPackageExWithEmbedMetaOptions(
prog, nil, nil, nil, foo, files, nil, false,
cl.Options{Debug: dbg, DebugSymbols: dbg},
)
if err != nil {
t.Fatal("cl.NewPackage failed:", err)
t.Fatal("cl.NewPackageExWithEmbedMetaOptions failed:", err)
}
return ret.String()
}
Expand Down
83 changes: 14 additions & 69 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,12 @@ const (
)

var (
debugInstr bool
debugGoSSA bool

enableCallTracing bool
enableDbg bool
enableDbgSyms bool
disableInline bool

// enableExportRename enables //export to use different C symbol names than Go function names.
// This is for TinyGo compatibility when using -target flag for embedded targets.
// Currently, using -target implies TinyGo embedded target mode.
enableExportRename bool
debugInstr bool
debugGoSSA bool
disableInline bool
)

// Options contains frontend behavior for one package compilation. Drivers that
// may host multiple builds in one process should pass Options explicitly
// instead of changing the legacy package-level Enable* settings.
// Options contains frontend behavior for one package compilation.
type Options struct {
Debug bool
DebugSymbols bool
Expand All @@ -79,16 +68,6 @@ type Options struct {
PreloadedSyntax bool
}

func legacyOptions() Options {
return Options{
Debug: enableDbg,
DebugSymbols: enableDbgSyms,
Trace: enableCallTracing,
ExportRename: enableExportRename,
ShadowStack: os.Getenv("LLGO_SHADOW_STACK") == "1",
}
}

// SetDebug sets debug flags.
func SetDebug(dbgFlags dbgFlags) {
debugInstr = (dbgFlags & DbgFlagInstruction) != 0
Expand Down Expand Up @@ -139,31 +118,6 @@ func dbgGoSSAln(args ...any) {
}
}

// EnableDebug changes the legacy process-wide default.
// Deprecated: pass Options to NewPackageExWithEmbedMetaOptions.
func EnableDebug(b bool) {
enableDbg = b
}

// EnableDbgSyms changes the legacy process-wide default.
// Deprecated: pass Options to NewPackageExWithEmbedMetaOptions.
func EnableDbgSyms(b bool) {
enableDbgSyms = b
}

// EnableTrace changes the legacy process-wide default.
// Deprecated: pass Options to NewPackageExWithEmbedMetaOptions.
func EnableTrace(b bool) {
enableCallTracing = b
}

// EnableExportRename enables or disables //export with different C symbol names.
// This is enabled when using -target flag for TinyGo compatibility.
// Deprecated: pass Options to NewPackageExWithEmbedMetaOptions.
func EnableExportRename(b bool) {
enableExportRename = b
}

// -----------------------------------------------------------------------------

type instrOrValue interface {
Expand Down Expand Up @@ -213,7 +167,6 @@ type context struct {
runtimeCallerFuncs map[*ssa.Function]bool
pcLineSeq uint64
options Options
optionsSet bool
recoverSlots map[*ssa.Alloc]none

patches Patches
Expand Down Expand Up @@ -248,13 +201,6 @@ type context struct {
locality localityLowering
}

func (p *context) frontendOptions() Options {
if p != nil && p.optionsSet {
return p.options
}
return legacyOptions()
}

func (p *context) rewriteValue(name string) (string, bool) {
if p.rewrites == nil {
return "", false
Expand Down Expand Up @@ -699,8 +645,8 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
if f.Recover != nil { // set recover block
fn.SetRecover(fn.Block(f.Recover.Index))
}
dbgEnabled := p.frontendOptions().Debug
dbgSymsEnabled := p.frontendOptions().DebugSymbols && (f == nil || f.Origin() == nil)
dbgEnabled := p.options.Debug
dbgSymsEnabled := p.options.DebugSymbols && (f == nil || f.Origin() == nil)
p.inits = append(p.inits, func() {
oldFn, oldGoFn, oldMethodNilDerefChecks, oldCallerFrameMark := p.fn, p.goFn, p.methodNilDerefChecks, p.callerFrameMark
oldLocalityFunction := p.locality.function
Expand Down Expand Up @@ -958,11 +904,11 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
if block.Index == 0 && p.shouldTrackCallerFrames() {
p.pushCallerLocationFrame(b, block.Parent())
}
if block.Index == 0 && p.frontendOptions().Trace && !strings.HasPrefix(fn.Name(), "github.com/goplus/llgo/runtime/internal/runtime.Print") {
if block.Index == 0 && p.options.Trace && !strings.HasPrefix(fn.Name(), "github.com/goplus/llgo/runtime/internal/runtime.Print") {
b.Printf("call " + fn.Name() + "\n\x00")
}
// place here to avoid wrong current-block
if p.frontendOptions().DebugSymbols && block.Parent().Origin() == nil && block.Index == 0 {
if p.options.DebugSymbols && block.Parent().Origin() == nil && block.Index == 0 {
p.debugParams(b, block.Parent())
}

Expand Down Expand Up @@ -1800,7 +1746,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
if _, ok := p.staticInitInstrs[instr]; ok {
return
}
if p.frontendOptions().Debug && instr.Parent().Origin() == nil {
if p.options.Debug && instr.Parent().Origin() == nil {
if _, isDebugRef := instr.(*ssa.DebugRef); !isDebugRef {
scope := p.getDebugLocScope(instr.Parent(), instr.Pos())
if scope != nil {
Expand Down Expand Up @@ -1920,7 +1866,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
p.recordPanicLocation(b, v.Pos())
b.Send(ch, x)
case *ssa.DebugRef:
if p.frontendOptions().DebugSymbols && v.Parent().Origin() == nil {
if p.options.DebugSymbols && v.Parent().Origin() == nil {
p.debugRef(b, v)
}
default:
Expand Down Expand Up @@ -1983,7 +1929,7 @@ func (p *context) compileValue(b llssa.Builder, v ssa.Value) llssa.Expr {
if isCgoVar(varName) {
p.cgoSymbols = append(p.cgoSymbols, val.Name())
}
if p.frontendOptions().DebugSymbols && p.localityAllowsGlobalDebug(v) {
if p.options.DebugSymbols && p.localityAllowsGlobalDebug(v) {
pos := p.fset.Position(v.Pos())
b.DIGlobal(val, v.Name(), pos)
}
Expand Down Expand Up @@ -2242,7 +2188,7 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
// only affects string-typed globals defined in the current package.
// Deprecated: use NewPackageExWithEmbedMetaOptions with explicit Options.
func NewPackageEx(prog llssa.Program, patches Patches, rewrites map[string]string, pkg *ssa.Package, files []*ast.File) (ret llssa.Package, externs []string, err error) {
return newPackageEx(prog, nil, patches, rewrites, pkg, files, nil, false, legacyOptions())
return newPackageEx(prog, nil, patches, rewrites, pkg, files, nil, false, Options{})
}

// NewPackageExWithEmbed compiles a package using pre-loaded go:embed metadata.
Expand All @@ -2254,13 +2200,13 @@ func NewPackageEx(prog llssa.Program, patches Patches, rewrites map[string]strin
// instance is created for this call.
// Deprecated: use NewPackageExWithEmbedMetaOptions with explicit Options.
func NewPackageExWithEmbed(prog llssa.Program, ct *CallerTracking, patches Patches, rewrites map[string]string, pkg *ssa.Package, files []*ast.File, embedMap goembed.VarMap) (ret llssa.Package, externs []string, err error) {
return newPackageEx(prog, ct, patches, rewrites, pkg, files, &embedMap, false, legacyOptions())
return newPackageEx(prog, ct, patches, rewrites, pkg, files, &embedMap, false, Options{})
}

// NewPackageExWithEmbedMeta compiles a package and optionally collects metadata.
// Deprecated: use NewPackageExWithEmbedMetaOptions with explicit Options.
func NewPackageExWithEmbedMeta(prog llssa.Program, ct *CallerTracking, patches Patches, rewrites map[string]string, pkg *ssa.Package, files []*ast.File, embedMap goembed.VarMap, metaCollect bool) (ret llssa.Package, externs []string, err error) {
return newPackageEx(prog, ct, patches, rewrites, pkg, files, &embedMap, metaCollect, legacyOptions())
return newPackageEx(prog, ct, patches, rewrites, pkg, files, &embedMap, metaCollect, Options{})
}

// NewPackageExWithEmbedMetaOptions is NewPackageExWithEmbedMeta with explicit
Expand Down Expand Up @@ -2312,7 +2258,6 @@ func newPackageEx(prog llssa.Program, ct *CallerTracking, patches Patches, rewri
goPkg: pkg,
patches: patches,
options: options,
optionsSet: true,
skips: make(map[string]none),
vargs: make(map[*ssa.Alloc][]llssa.Expr),
funcs: make(map[*ssa.Function]llssa.Function),
Expand Down
Loading
Loading