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
89 changes: 1 addition & 88 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,12 +484,6 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
p.debugParams(b, block.Parent())
}

// Handle init$hasPatch: split dependency init calls into separate function
if doModInit && p.state == pkgHasPatch {
baseName := strings.TrimSuffix(p.fn.Name(), "$hasPatch")
instrs = p.createInitDepsFunction(pkg, baseName, instrs)
}

if doModInit {
if pyModInit = p.pyMod != ""; pyModInit {
last = len(instrs) - 1
Expand All @@ -508,15 +502,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
isCgoCmacro := isCgoCmacro(fnName)
for i, instr := range instrs {
if i == 1 && doModInit && p.state == pkgInPatch { // in patch package but no pkgFNoOldInit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: The comment mentions pkgFNoOldInit but the condition doesn't check for it. Consider clarifying what the comment is documenting:

Suggested change
if i == 1 && doModInit && p.state == pkgInPatch { // in patch package but no pkgFNoOldInit
for i, instr := range instrs {
if i == 1 && doModInit && p.state == pkgInPatch { // in patch package: call original init$hasPatch

This would make it clearer that the comment describes the action being taken, not what's being checked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: The comment mentions pkgFNoOldInit but the condition doesn't check for it. Consider clarifying what the comment is documenting:

Suggested change
if i == 1 && doModInit && p.state == pkgInPatch { // in patch package but no pkgFNoOldInit
for i, instr := range instrs {
if i == 1 && doModInit && p.state == pkgInPatch { // in patch package: call original init$hasPatch

This would make it clearer that the comment describes the action being taken, not what's being checked.

name := p.fn.Name()
initFnNameOld := initFnNameOfHasPatch(name)
initPatchDepsFnName := initDepsFnNameOfHasPatch(name)

// Call deps function first
fnDeps := pkg.NewFunc(initPatchDepsFnName, llssa.NoArgsNoRet, llssa.InC)
b.Call(fnDeps.Expr)

// Then call hasPatch (global vars)
initFnNameOld := initFnNameOfHasPatch(p.fn.Name())
fnOld := pkg.NewFunc(initFnNameOld, llssa.NoArgsNoRet, llssa.InC)
b.Call(fnOld.Expr)
}
Expand Down Expand Up @@ -1174,79 +1160,6 @@ func initFnNameOfHasPatch(name string) string {
return name + "$hasPatch"
}

func initDepsFnNameOfHasPatch(name string) string {
return name + "$patchDeps"
}

// findFirstNonInitInstruction finds the index of the first non-init instruction
// in the given instructions. Returns -1 if all instructions are init calls.
// Skips non-call instructions (like store for guard).
func findFirstNonInitInstruction(instrs []ssa.Instruction) int {
for i, instr := range instrs {
call, ok := instr.(*ssa.Call)
if !ok {
// Skip non-call instructions (like guard store)
continue
}
fn, ok := call.Call.Value.(*ssa.Function)
if !ok {
// Not a direct function call
return i
}
if fn.Name() == "init" && fn.Signature.Recv() == nil {
// This is an init call, continue looking
continue
}
// Found a non-init call
return i
}
return -1
}

// createInitDepsFunction creates and fills the init$patchDeps function
// for the given init function, extracting dependency init calls from instrs.
// Returns the remaining instructions after removing dependency inits.
func (p *context) createInitDepsFunction(pkg llssa.Package, baseName string, instrs []ssa.Instruction) []ssa.Instruction {
// Create deps function
depsName := initDepsFnNameOfHasPatch(baseName)
depsFn := pkg.NewFunc(depsName, llssa.NoArgsNoRet, llssa.InC)
depsFn.MakeBlocks(1)
depsBuilder := depsFn.NewBuilder()
depsBuilder.SetBlock(depsFn.Block(0))

// Find and split dependency init calls
firstNonInit := findFirstNonInitInstruction(instrs)
var depsInstrs []ssa.Instruction
if firstNonInit > 0 {
depsInstrs = instrs[:firstNonInit]
instrs = instrs[firstNonInit:]

// Fill deps function body with dependency init calls
for _, instr := range depsInstrs {
if call, ok := instr.(*ssa.Call); ok {
if fn, ok := call.Call.Value.(*ssa.Function); ok {
if fn.Name() == "init" && fn.Signature.Recv() == nil {
// Skip packages that don't need init (like unsafe)
if p.pkgNoInit(fn.Pkg.Pkg) {
continue
}
// This is a dependency init call
// Use funcName to get the correct function name (handles patches, linkname, etc.)
_, depInitName, ftype := p.funcName(fn)
if ftype == goFunc {
depInitFn := pkg.NewFunc(depInitName, llssa.NoArgsNoRet, llssa.InC)
depsBuilder.Call(depInitFn.Expr)
}
}
}
}
}
}
depsBuilder.Return()

return instrs
}

func processPkg(ctx *context, ret llssa.Package, pkg *ssa.Package) {
type namedMember struct {
name string
Expand Down
4 changes: 2 additions & 2 deletions ssa/stmt_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ func notInit(instr llvm.Value) bool {
if n := instr.OperandsCount(); n == 1 {
fn := instr.Operand(0)
name := fn.Name()
// Skip .init and .init$patchDeps calls
return !strings.HasSuffix(name, ".init") && !strings.HasSuffix(name, ".init$patchDeps")
// Skip .init calls
return !strings.HasSuffix(name, ".init")
}
}
return true
Expand Down
Loading