diff options
author | Russ Cox <rsc@golang.org> | 2009-08-04 18:43:32 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-08-04 18:43:32 -0700 |
commit | 95ba3494d3e7b243be3f908ea37c211dd49f9933 (patch) | |
tree | b8c958456b0f74721798070ea60c0313ac427bce /src/cmd/gc/unsafe.c | |
parent | b4cfcef3334c0ff078a5e001191035a0d1275133 (diff) | |
download | golang-95ba3494d3e7b243be3f908ea37c211dd49f9933.tar.gz |
move various bits of code around
and delete some dead code.
no actual changes here.
R=ken
OCL=32764
CL=32764
Diffstat (limited to 'src/cmd/gc/unsafe.c')
-rw-r--r-- | src/cmd/gc/unsafe.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/cmd/gc/unsafe.c b/src/cmd/gc/unsafe.c new file mode 100644 index 000000000..9c1f9519a --- /dev/null +++ b/src/cmd/gc/unsafe.c @@ -0,0 +1,87 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "go.h" + +/* + * look for + * unsafe.Sizeof + * unsafe.Offsetof + * rewrite with a constant + */ +Node* +unsafenmagic(Node *fn, NodeList *args) +{ + Node *r, *n; + Sym *s; + Type *t, *tr; + long v; + Val val; + + if(fn == N || fn->op != ONAME || (s = fn->sym) == S) + goto no; + if(strcmp(s->package, "unsafe") != 0) + goto no; + + if(args == nil) { + yyerror("missing argument for %S", s); + goto no; + } + r = args->n; + + n = nod(OLITERAL, N, N); + if(strcmp(s->name, "Sizeof") == 0) { + typecheck(&r, Erv); + tr = r->type; + if(r->op == OLITERAL && r->val.ctype == CTSTR) + tr = types[TSTRING]; + if(tr == T) + goto no; + v = tr->width; + goto yes; + } + if(strcmp(s->name, "Offsetof") == 0) { + if(r->op != ODOT && r->op != ODOTPTR) + goto no; + typecheck(&r, Erv); + v = r->xoffset; + goto yes; + } + if(strcmp(s->name, "Alignof") == 0) { + typecheck(&r, Erv); + tr = r->type; + if(r->op == OLITERAL && r->val.ctype == CTSTR) + tr = types[TSTRING]; + if(tr == T) + goto no; + + // make struct { byte; T; } + t = typ(TSTRUCT); + t->type = typ(TFIELD); + t->type->type = types[TUINT8]; + t->type->down = typ(TFIELD); + t->type->down->type = tr; + // compute struct widths + dowidth(t); + + // the offset of T is its required alignment + v = t->type->down->width; + goto yes; + } + +no: + return N; + +yes: + if(args->next != nil) + yyerror("extra arguments for %S", s); + // any side effects disappear; ignore init + val.ctype = CTINT; + val.u.xval = mal(sizeof(*n->val.u.xval)); + mpmovecfix(val.u.xval, v); + n = nod(OLITERAL, N, N); + n->val = val; + n->type = types[TINT]; + return n; +} |