OLD | NEW |
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 #undef EXTERN | 5 #undef EXTERN |
6 #define EXTERN | 6 #define EXTERN |
7 #include <u.h> | 7 #include <u.h> |
8 #include <libc.h> | 8 #include <libc.h> |
9 #include "gg.h" | 9 #include "gg.h" |
10 #include "opt.h" | 10 #include "opt.h" |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 * call f | 172 * call f |
173 * proc=-1 normal call but no return | 173 * proc=-1 normal call but no return |
174 * proc=0 normal call | 174 * proc=0 normal call |
175 * proc=1 goroutine run in new proc | 175 * proc=1 goroutine run in new proc |
176 * proc=2 defer call save away stack | 176 * proc=2 defer call save away stack |
177 * proc=3 normal call to C pointer (not Go func value) | 177 * proc=3 normal call to C pointer (not Go func value) |
178 */ | 178 */ |
179 void | 179 void |
180 ginscall(Node *f, int proc) | 180 ginscall(Node *f, int proc) |
181 { | 181 { |
182 int32 arg; | |
183 Prog *p; | 182 Prog *p; |
184 Node n1, r, r1, con; | 183 Node n1, r, r1, con; |
185 | 184 |
186 if(f->type != T) | 185 if(f->type != T) |
187 setmaxarg(f->type); | 186 setmaxarg(f->type); |
188 | 187 |
189 arg = -1; | |
190 // Most functions have a fixed-size argument block, so traceback uses th
at during unwind. | |
191 // Not all, though: there are some variadic functions in package runtime
, | |
192 // and for those we emit call-specific metadata recorded by caller. | |
193 // Reflect generates functions with variable argsize (see reflect.method
ValueCall/makeFuncStub), | |
194 // so we do this for all indirect calls as well. | |
195 if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtim
epkg) || proc == 1 || proc == 2)) { | |
196 arg = f->type->argwid; | |
197 if(proc == 1 || proc == 2) | |
198 arg += 3*widthptr; | |
199 } | |
200 | |
201 if(arg != -1) | |
202 gargsize(arg); | |
203 | |
204 switch(proc) { | 188 switch(proc) { |
205 default: | 189 default: |
206 fatal("ginscall: bad proc %d", proc); | 190 fatal("ginscall: bad proc %d", proc); |
207 break; | 191 break; |
208 | 192 |
209 case 0: // normal call | 193 case 0: // normal call |
210 case -1: // normal call but no return | 194 case -1: // normal call but no return |
211 if(f->op == ONAME && f->class == PFUNC) { | 195 if(f->op == ONAME && f->class == PFUNC) { |
212 if(f == deferreturn) { | 196 if(f == deferreturn) { |
213 // Deferred calls will appear to be returning to | 197 // Deferred calls will appear to be returning to |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 if(proc == 2) { | 274 if(proc == 2) { |
291 nodconst(&con, types[TINT32], 0); | 275 nodconst(&con, types[TINT32], 0); |
292 p = gins(ACMP, &con, N); | 276 p = gins(ACMP, &con, N); |
293 p->reg = 0; | 277 p->reg = 0; |
294 p = gbranch(ABEQ, T, +1); | 278 p = gbranch(ABEQ, T, +1); |
295 cgen_ret(N); | 279 cgen_ret(N); |
296 patch(p, pc); | 280 patch(p, pc); |
297 } | 281 } |
298 break; | 282 break; |
299 } | 283 } |
300 ········ | |
301 if(arg != -1) | |
302 gargsize(-1); | |
303 } | 284 } |
304 | 285 |
305 /* | 286 /* |
306 * n is call to interface method. | 287 * n is call to interface method. |
307 * generate res = n. | 288 * generate res = n. |
308 */ | 289 */ |
309 void | 290 void |
310 cgen_callinter(Node *n, Node *res, int proc) | 291 cgen_callinter(Node *n, Node *res, int proc) |
311 { | 292 { |
312 int r; | 293 int r; |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 p1->to.reg = reg; | 947 p1->to.reg = reg; |
967 p1->to.offset = 0; | 948 p1->to.offset = 0; |
968 p1->scond = C_SCOND_EQ; | 949 p1->scond = C_SCOND_EQ; |
969 p->as = ACMP; | 950 p->as = ACMP; |
970 p->from.type = D_CONST; | 951 p->from.type = D_CONST; |
971 p->from.reg = NREG; | 952 p->from.reg = NREG; |
972 p->from.offset = 0; | 953 p->from.offset = 0; |
973 p->reg = reg; | 954 p->reg = reg; |
974 } | 955 } |
975 } | 956 } |
OLD | NEW |