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