@@ -471,23 +471,9 @@ func (cg *CodeGen) emitInteropWrappers(stmts []ast.Node) error {
471471// passes. The user's contract is "this function is callable from C";
472472// linker DCE breaks that contract.
473473func (cg * CodeGen ) pinInteropWrappers (wrappers []* ir.Func ) {
474- if len ( wrappers ) == 0 {
475- return
474+ for _ , f := range wrappers {
475+ cg . registerLlvmUsedFunc ( cg . mod , f )
476476 }
477-
478- i8Ptr := irtypes .I8Ptr
479-
480- entries := make ([]constant.Constant , len (wrappers ))
481- for i , f := range wrappers {
482- entries [i ] = constant .NewBitCast (f , i8Ptr )
483- }
484-
485- arrTy := irtypes .NewArray (uint64 (len (wrappers )), i8Ptr )
486- init := constant .NewArray (arrTy , entries ... )
487-
488- used := cg .mod .NewGlobalDef ("llvm.used" , init )
489- used .Linkage = enum .LinkageAppending
490- used .Section = "llvm.metadata"
491477}
492478
493479// emitInteropWrapperFor emits a single wrapper. Assumes the validation
@@ -521,6 +507,16 @@ func (cg *CodeGen) emitInteropWrapperWithName(fn *ast.FuncDecl, wrapperName stri
521507 return cg .nodeErr (fn , "fn %s: #interop entry resolved to non-function value" , fn .Name )
522508 }
523509
510+ // Override the pclntab display name so stacktrace() reports the
511+ // C-visible symbol (__tin_interop_<name>) rather than the Tin source
512+ // name. The heuristic would already return the IR name unchanged
513+ // (it starts with __tin_), but recordFnDisplayName stored the Tin
514+ // source name earlier; override it here.
515+ if cg .fnDisplayNames == nil {
516+ cg .fnDisplayNames = map [string ]string {}
517+ }
518+ cg .fnDisplayNames [internalFn .Name ()] = internalFn .Name ()
519+
524520 // When the active emit target is a sibling module (CTFE shimMod),
525521 // internalFn lives in cg.mod and is unreachable from the wrapper's
526522 // blocks. Mirror it as a `declare` in the active module so calls
@@ -706,6 +702,7 @@ func (cg *CodeGen) emitInteropWrapperWithName(fn *ast.FuncDecl, wrapperName stri
706702 }
707703
708704 wrapper := cg .activeModule ().NewFunc (wrapperName , retType , wrapperParams ... )
705+ wrapper .FuncAttrs = append (wrapper .FuncAttrs , ir .AttrString ("noinline" ))
709706 block := wrapper .NewBlock ("entry" )
710707 // Skip the tin_runtime_init bootstrap when emitting into the CTFE
711708 // shim module: the dispatcher (Tin compiler) doesn't link the runtime
0 commit comments