The Go Programming Language

Text file src/cmd/gc/unsafe.c

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	#include "go.h"
     6	
     7	/*
     8	 * look for
     9	 *	unsafe.Sizeof
    10	 *	unsafe.Offsetof
    11	 * rewrite with a constant
    12	 */
    13	Node*
    14	unsafenmagic(Node *nn)
    15	{
    16		Node *r, *n;
    17		Sym *s;
    18		Type *t, *tr;
    19		long v;
    20		Val val;
    21		Node *fn;
    22		NodeList *args;
    23		
    24		fn = nn->left;
    25		args = nn->list;
    26	
    27		if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
    28			goto no;
    29		if(s->pkg != unsafepkg)
    30			goto no;
    31	
    32		if(args == nil) {
    33			yyerror("missing argument for %S", s);
    34			goto no;
    35		}
    36		r = args->n;
    37	
    38		if(strcmp(s->name, "Sizeof") == 0) {
    39			typecheck(&r, Erv);
    40			defaultlit(&r, T);
    41			tr = r->type;
    42			if(tr == T)
    43				goto bad;
    44			dowidth(tr);
    45			v = tr->width;
    46			goto yes;
    47		}
    48		if(strcmp(s->name, "Offsetof") == 0) {
    49			typecheck(&r, Erv);
    50			if(r->op != ODOT && r->op != ODOTPTR)
    51				goto bad;
    52			typecheck(&r, Erv);
    53			v = r->xoffset;
    54			goto yes;
    55		}
    56		if(strcmp(s->name, "Alignof") == 0) {
    57			typecheck(&r, Erv);
    58			defaultlit(&r, T);
    59			tr = r->type;
    60			if(tr == T)
    61				goto bad;
    62	
    63			// make struct { byte; T; }
    64			t = typ(TSTRUCT);
    65			t->type = typ(TFIELD);
    66			t->type->type = types[TUINT8];
    67			t->type->down = typ(TFIELD);
    68			t->type->down->type = tr;
    69			// compute struct widths
    70			dowidth(t);
    71	
    72			// the offset of T is its required alignment
    73			v = t->type->down->width;
    74			goto yes;
    75		}
    76	
    77	no:
    78		return N;
    79	
    80	bad:
    81		yyerror("invalid expression %#N", nn);
    82		v = 0;
    83		goto ret;
    84		
    85	yes:
    86		if(args->next != nil)
    87			yyerror("extra arguments for %S", s);
    88	ret:
    89		// any side effects disappear; ignore init
    90		val.ctype = CTINT;
    91		val.u.xval = mal(sizeof(*n->val.u.xval));
    92		mpmovecfix(val.u.xval, v);
    93		n = nod(OLITERAL, N, N);
    94		n->val = val;
    95		n->type = types[TUINTPTR];
    96		return n;
    97	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.