@@ -321,6 +321,9 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
321
321
Type : gtype ,
322
322
}
323
323
324
+ // Builtins defined in the C prolog.
325
+ inProlog := name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes"
326
+
324
327
if * gccgo {
325
328
// Gccgo style hooks.
326
329
fmt .Fprint (fgo2 , "\n " )
@@ -334,8 +337,10 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
334
337
335
338
conf .Fprint (fgo2 , fset , d )
336
339
fmt .Fprint (fgo2 , " {\n " )
337
- fmt .Fprint (fgo2 , "\t defer syscall.CgocallDone()\n " )
338
- fmt .Fprint (fgo2 , "\t syscall.Cgocall()\n " )
340
+ if ! inProlog {
341
+ fmt .Fprint (fgo2 , "\t defer syscall.CgocallDone()\n " )
342
+ fmt .Fprint (fgo2 , "\t syscall.Cgocall()\n " )
343
+ }
339
344
if n .AddError {
340
345
fmt .Fprint (fgo2 , "\t syscall.SetErrno(0)\n " )
341
346
}
@@ -366,7 +371,11 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
366
371
fmt .Fprint (fgo2 , "}\n " )
367
372
368
373
// declare the C function.
369
- fmt .Fprintf (fgo2 , "//extern %s\n " , n .C )
374
+ if inProlog {
375
+ fmt .Fprintf (fgo2 , "//extern %s\n " , n .C )
376
+ } else {
377
+ fmt .Fprintf (fgo2 , "//extern _cgo%s%s\n " , cPrefix , n .Mangle )
378
+ }
370
379
d .Name = ast .NewIdent (cname )
371
380
if n .AddError {
372
381
l := d .Type .Results .List
@@ -380,8 +389,7 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
380
389
conf .Fprint (fgo2 , fset , d )
381
390
fmt .Fprint (fgo2 , "\n " )
382
391
383
- if name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes" {
384
- // The builtins are already defined in the C prolog.
392
+ if inProlog {
385
393
return
386
394
}
387
395
@@ -469,7 +477,7 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
469
477
p .Written [name ] = true
470
478
471
479
if * gccgo {
472
- // we don't use wrappers with gccgo.
480
+ p . writeGccgoOutputFunc ( fgcc , n )
473
481
return
474
482
}
475
483
@@ -526,6 +534,54 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
526
534
fmt .Fprintf (fgcc , "\n " )
527
535
}
528
536
537
+ // Write out a wrapper for a function when using gccgo. This is a
538
+ // simple wrapper that just calls the real function. We only need a
539
+ // wrapper to support static functions in the prologue--without a
540
+ // wrapper, we can't refer to the function, since the reference is in
541
+ // a different file.
542
+ func (p * Package ) writeGccgoOutputFunc (fgcc * os.File , n * Name ) {
543
+ if t := n .FuncType .Result ; t != nil {
544
+ fmt .Fprintf (fgcc , "%s\n " , t .C .String ())
545
+ } else {
546
+ fmt .Fprintf (fgcc , "void\n " )
547
+ }
548
+ fmt .Fprintf (fgcc , "_cgo%s%s(" , cPrefix , n .Mangle )
549
+ for i , t := range n .FuncType .Params {
550
+ if i > 0 {
551
+ fmt .Fprintf (fgcc , ", " )
552
+ }
553
+ c := t .Typedef
554
+ if c == "" {
555
+ c = t .C .String ()
556
+ }
557
+ fmt .Fprintf (fgcc , "%s p%d" , c , i )
558
+ }
559
+ fmt .Fprintf (fgcc , ")\n " )
560
+ fmt .Fprintf (fgcc , "{\n " )
561
+ fmt .Fprintf (fgcc , "\t " )
562
+ if t := n .FuncType .Result ; t != nil {
563
+ fmt .Fprintf (fgcc , "return " )
564
+ // Cast to void* to avoid warnings due to omitted qualifiers.
565
+ if c := t .C .String (); c [len (c )- 1 ] == '*' {
566
+ fmt .Fprintf (fgcc , "(void*)" )
567
+ }
568
+ }
569
+ fmt .Fprintf (fgcc , "%s(" , n .C )
570
+ for i , t := range n .FuncType .Params {
571
+ if i > 0 {
572
+ fmt .Fprintf (fgcc , ", " )
573
+ }
574
+ // Cast to void* to avoid warnings due to omitted qualifiers.
575
+ if c := t .C .String (); c [len (c )- 1 ] == '*' {
576
+ fmt .Fprintf (fgcc , "(void*)" )
577
+ }
578
+ fmt .Fprintf (fgcc , "p%d" , i )
579
+ }
580
+ fmt .Fprintf (fgcc , ");\n " )
581
+ fmt .Fprintf (fgcc , "}\n " )
582
+ fmt .Fprintf (fgcc , "\n " )
583
+ }
584
+
529
585
// Write out the various stubs we need to support functions exported
530
586
// from Go so that they are callable from C.
531
587
func (p * Package ) writeExports (fgo2 , fc , fm * os.File ) {
0 commit comments