summaryrefslogtreecommitdiff
path: root/src/cmd/gc/pgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/pgen.c')
-rw-r--r--src/cmd/gc/pgen.c57
1 files changed, 51 insertions, 6 deletions
diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c
index 40620c3da..39028e3f8 100644
--- a/src/cmd/gc/pgen.c
+++ b/src/cmd/gc/pgen.c
@@ -11,9 +11,10 @@
#include "md5.h"
#include "gg.h"
#include "opt.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
static void allocauto(Prog* p);
+static void emitptrargsmap(void);
static Sym*
makefuncdatasym(char *namefmt, int64 funcdatakind)
@@ -173,9 +174,17 @@ compile(Node *fn)
lno = setlineno(fn);
+ curfn = fn;
+ dowidth(curfn->type);
+
if(fn->nbody == nil) {
- if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0)
+ if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0) {
yyerror("missing function body", fn);
+ goto ret;
+ }
+ if(debug['A'])
+ goto ret;
+ emitptrargsmap();
goto ret;
}
@@ -184,9 +193,6 @@ compile(Node *fn)
// set up domain for labels
clearlabels();
- curfn = fn;
- dowidth(curfn->type);
-
if(curfn->type->outnamed) {
// add clearing of the output parameters
t = structfirst(&save, getoutarg(curfn->type));
@@ -229,9 +235,11 @@ compile(Node *fn)
ptxt->TEXTFLAG |= WRAPPER;
if(fn->needctxt)
ptxt->TEXTFLAG |= NEEDCTXT;
+ if(fn->nosplit)
+ ptxt->TEXTFLAG |= NOSPLIT;
// Clumsy but important.
- // See test/recover.go for test cases and src/pkg/reflect/value.go
+ // See test/recover.go for test cases and src/reflect/value.go
// for the actual functions being considered.
if(myimportpath != nil && strcmp(myimportpath, "reflect") == 0) {
if(strcmp(curfn->nname->sym->name, "callReflect") == 0 || strcmp(curfn->nname->sym->name, "callMethod") == 0)
@@ -327,6 +335,43 @@ ret:
lineno = lno;
}
+static void
+emitptrargsmap(void)
+{
+ int nptr, nbitmap, j, off;
+ vlong xoffset;
+ Bvec *bv;
+ Sym *sym;
+
+ sym = lookup(smprint("%s.args_stackmap", curfn->nname->sym->name));
+
+ nptr = curfn->type->argwid / widthptr;
+ bv = bvalloc(nptr*2);
+ nbitmap = 1;
+ if(curfn->type->outtuple > 0)
+ nbitmap = 2;
+ off = duint32(sym, 0, nbitmap);
+ off = duint32(sym, off, bv->n);
+ if(curfn->type->thistuple > 0) {
+ xoffset = 0;
+ twobitwalktype1(getthisx(curfn->type), &xoffset, bv);
+ }
+ if(curfn->type->intuple > 0) {
+ xoffset = 0;
+ twobitwalktype1(getinargx(curfn->type), &xoffset, bv);
+ }
+ for(j = 0; j < bv->n; j += 32)
+ off = duint32(sym, off, bv->b[j/32]);
+ if(curfn->type->outtuple > 0) {
+ xoffset = 0;
+ twobitwalktype1(getoutargx(curfn->type), &xoffset, bv);
+ for(j = 0; j < bv->n; j += 32)
+ off = duint32(sym, off, bv->b[j/32]);
+ }
+ ggloblsym(sym, off, RODATA);
+ free(bv);
+}
+
// Sort the list of stack variables. Autos after anything else,
// within autos, unused after used, within used, things with
// pointers first, zeroed things first, and then decreasing size.