LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "cgocall.h" | 6 #include "cgocall.h" |
7 | 7 |
8 void *initcgo; /* filled in by dynamic linker when Cgo is available */ | 8 void *initcgo; /* filled in by dynamic linker when Cgo is available */ |
9 int64 ncgocall; | 9 int64 ncgocall; |
10 void ·entersyscall(void); | 10 void ·entersyscall(void); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 return; | 45 return; |
46 } | 46 } |
47 | 47 |
48 // When a C function calls back into Go, the wrapper function will | 48 // When a C function calls back into Go, the wrapper function will |
49 // call this. This switches to a Go stack, copies the arguments | 49 // call this. This switches to a Go stack, copies the arguments |
50 // (arg/argsize) on to the stack, calls the function, copies the | 50 // (arg/argsize) on to the stack, calls the function, copies the |
51 // arguments back where they came from, and finally returns to the old | 51 // arguments back where they came from, and finally returns to the old |
52 // stack. | 52 // stack. |
53 void | 53 void |
54 cgocallback(void (*fn)(), void *arg, int32 argsize) | 54 cgocallback(void (*fn)(void), void *arg, int32 argsize) |
55 { | 55 { |
56 Gobuf oldsched; | 56 Gobuf oldsched; |
| 57 G *g1; |
57 void *sp; | 58 void *sp; |
58 | 59 |
59 » if(g == m->g0 || g != m->curg) | 60 » if(g != m->g0) |
60 » » throw("bad m->curg in cgocallback"); | 61 » » throw("bad g in cgocallback"); |
61 | 62 |
62 oldsched = m->sched; | 63 oldsched = m->sched; |
63 | 64 |
64 » startcgocallback(); | 65 » g1 = m->curg; |
65 | 66 |
66 » sp = g->sched.sp - argsize; | 67 » startcgocallback(g1); |
| 68 |
| 69 » sp = g1->sched.sp - argsize; |
| 70 » if(sp < g1->stackguard) |
| 71 » » throw("g stack overflow in cgocallback"); |
67 mcpy(sp, arg, argsize); | 72 mcpy(sp, arg, argsize); |
68 | 73 |
69 » runcgocallback(sp, fn); | 74 » runcgocallback(g1, sp, fn); |
70 | 75 |
71 mcpy(arg, sp, argsize); | 76 mcpy(arg, sp, argsize); |
72 | 77 |
73 » endcgocallback(); | 78 » endcgocallback(g1); |
74 | 79 |
75 m->sched = oldsched; | 80 m->sched = oldsched; |
76 } | 81 } |
77 | 82 |
78 void | 83 void |
79 ·Cgocalls(int64 ret) | 84 ·Cgocalls(int64 ret) |
80 { | 85 { |
81 ret = ncgocall; | 86 ret = ncgocall; |
82 FLUSH(&ret); | 87 FLUSH(&ret); |
83 } | 88 } |
(...skipping 14 matching lines...) Expand all Loading... |
98 cgocall(_cgo_malloc, &a); | 103 cgocall(_cgo_malloc, &a); |
99 return a.ret; | 104 return a.ret; |
100 } | 105 } |
101 | 106 |
102 void | 107 void |
103 cfree(void *p) | 108 cfree(void *p) |
104 { | 109 { |
105 cgocall(_cgo_free, p); | 110 cgocall(_cgo_free, p); |
106 } | 111 } |
107 | 112 |
LEFT | RIGHT |