mirror of
https://github.com/golang/go
synced 2024-11-20 01:24:43 -07:00
in preparation for changing 6g's behavior to
align the output args separately from the input args, change cgo2c to insert the necessary padding when the two arg lists are concatenated in the c translation. for example, there is a runtime func indexstring(s string, i int32) (b byte) right now in 6g those arguments are aligned in one struct with s at offset 0, i at 16, and b at 20. soon the b byte will be in its own struct and structs are 8 aligned, so it will be b at 24. right now cgo2c generates: void indexstring(string s, int32 i, byte b) this CL makes it generate, in --6g mode: void indexstring(string s, int32 i, uint32, byte b) this is valid 6c input, although not valid gcc input. (the code is being generated for 6c only anyway.) also, allow C code to be mixed in among the Go funcs. every instance of the token `func' is expected to start a new go func. R=iant DELTA=145 (118 added, 0 deleted, 27 changed) OCL=30949 CL=30963
This commit is contained in:
parent
b968943332
commit
88e7fd5410
@ -37,6 +37,51 @@ struct params {
|
||||
char *type;
|
||||
};
|
||||
|
||||
/* index into type_table */
|
||||
enum {
|
||||
Bool,
|
||||
Float,
|
||||
Int,
|
||||
Uint,
|
||||
Uintptr,
|
||||
String,
|
||||
Array,
|
||||
};
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
int size;
|
||||
} type_table[] = {
|
||||
/* variable sized first, for easy replacement */
|
||||
/* order matches enum above */
|
||||
/* default is 32-bit architecture sizes */
|
||||
"bool", 1,
|
||||
"float", 4,
|
||||
"int", 4,
|
||||
"uint", 4,
|
||||
"uintptr", 4,
|
||||
"String", 8,
|
||||
"Array", 12,
|
||||
|
||||
/* fixed size */
|
||||
"float32", 4,
|
||||
"float64", 8,
|
||||
"byte", 1,
|
||||
"int8", 1,
|
||||
"uint8", 1,
|
||||
"int16", 2,
|
||||
"uint16", 2,
|
||||
"int32", 4,
|
||||
"uint32", 4,
|
||||
"int64", 8,
|
||||
"uint64", 8,
|
||||
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Fixed structure alignment (non-gcc only) */
|
||||
int structround = 4;
|
||||
|
||||
/* Unexpected EOF. */
|
||||
static void
|
||||
bad_eof(void)
|
||||
@ -184,6 +229,8 @@ read_token(void)
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (isspace(c) || strchr(delims, c) != NULL) {
|
||||
if (c == '\n')
|
||||
lineno--;
|
||||
ungetc(c, stdin);
|
||||
break;
|
||||
}
|
||||
@ -231,7 +278,7 @@ read_preprocessor_lines(void)
|
||||
} while (isspace(c));
|
||||
if (c != '#') {
|
||||
ungetc(c, stdin);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
putchar(c);
|
||||
do {
|
||||
@ -272,24 +319,52 @@ read_type(void)
|
||||
return q;
|
||||
}
|
||||
|
||||
/* Return the size of the given type. */
|
||||
static int
|
||||
type_size(char *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(p[strlen(p)-1] == '*')
|
||||
return type_table[Uintptr].size;
|
||||
|
||||
for(i=0; type_table[i].name; i++)
|
||||
if(strcmp(type_table[i].name, p) == 0)
|
||||
return type_table[i].size;
|
||||
fprintf(stderr, "%s:%u: unknown type %s\n", file, lineno, p);
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read a list of parameters. Each parameter is a name and a type.
|
||||
The list ends with a ')'. We have already read the '('. */
|
||||
static struct params *
|
||||
read_params(void)
|
||||
read_params(int *poffset)
|
||||
{
|
||||
char *token;
|
||||
struct params *ret, **pp;
|
||||
struct params *ret, **pp, *p;
|
||||
int offset, size, rnd;
|
||||
|
||||
ret = NULL;
|
||||
pp = &ret;
|
||||
token = read_token_no_eof();
|
||||
offset = 0;
|
||||
if (strcmp(token, ")") != 0) {
|
||||
while (1) {
|
||||
*pp = xmalloc(sizeof(struct params));
|
||||
(*pp)->name = token;
|
||||
(*pp)->type = read_type();
|
||||
pp = &(*pp)->next;
|
||||
*pp = NULL;
|
||||
p = xmalloc(sizeof(struct params));
|
||||
p->name = token;
|
||||
p->type = read_type();
|
||||
p->next = NULL;
|
||||
*pp = p;
|
||||
pp = &p->next;
|
||||
|
||||
size = type_size(p->type);
|
||||
rnd = size;
|
||||
if(rnd > structround)
|
||||
rnd = structround;
|
||||
if(offset%rnd)
|
||||
offset += rnd - offset%rnd;
|
||||
offset += size;
|
||||
|
||||
token = read_token_no_eof();
|
||||
if (strcmp(token, ",") != 0)
|
||||
@ -302,24 +377,39 @@ read_params(void)
|
||||
file, lineno);
|
||||
exit(1);
|
||||
}
|
||||
if (poffset != NULL)
|
||||
*poffset = offset;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read a function header. This reads up to and including the initial
|
||||
'{' character. Returns 1 if it read a header, 0 at EOF. */
|
||||
static int
|
||||
read_func_header(char **name, struct params **params, struct params **rets)
|
||||
read_func_header(char **name, struct params **params, int *paramwid, struct params **rets)
|
||||
{
|
||||
int lastline;
|
||||
char *token;
|
||||
|
||||
token = read_token();
|
||||
if (token == NULL)
|
||||
return 0;
|
||||
if (strcmp(token, "func") != 0) {
|
||||
fprintf(stderr, "%s:%u: expected \"func\"\n",
|
||||
file, lineno);
|
||||
exit(1);
|
||||
lastline = -1;
|
||||
while (1) {
|
||||
token = read_token();
|
||||
if (token == NULL)
|
||||
return 0;
|
||||
if (strcmp(token, "func") == 0) {
|
||||
if(lastline != -1)
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
if (lastline != lineno) {
|
||||
if (lastline == lineno-1)
|
||||
printf("\n");
|
||||
else
|
||||
printf("\n#line %d \"%s\"\n", lineno, file);
|
||||
lastline = lineno;
|
||||
}
|
||||
printf("%s ", token);
|
||||
}
|
||||
|
||||
*name = read_token_no_eof();
|
||||
|
||||
token = read_token();
|
||||
@ -328,13 +418,13 @@ read_func_header(char **name, struct params **params, struct params **rets)
|
||||
file, lineno);
|
||||
exit(1);
|
||||
}
|
||||
*params = read_params();
|
||||
*params = read_params(paramwid);
|
||||
|
||||
token = read_token();
|
||||
if (token == NULL || strcmp(token, "(") != 0)
|
||||
*rets = NULL;
|
||||
else {
|
||||
*rets = read_params();
|
||||
*rets = read_params(NULL);
|
||||
token = read_token();
|
||||
}
|
||||
if (token == NULL || strcmp(token, "{") != 0) {
|
||||
@ -363,13 +453,25 @@ write_params(struct params *params, int *first)
|
||||
/* Write a 6g function header. */
|
||||
static void
|
||||
write_6g_func_header(char *package, char *name, struct params *params,
|
||||
struct params *rets)
|
||||
int paramwid, struct params *rets)
|
||||
{
|
||||
int first;
|
||||
int first, n;
|
||||
|
||||
printf("void\n%s·%s(", package, name);
|
||||
first = 1;
|
||||
write_params(params, &first);
|
||||
|
||||
/* insert padding to align output struct */
|
||||
if(rets != NULL && paramwid%structround != 0) {
|
||||
n = structround - paramwid%structround;
|
||||
if(n & 1)
|
||||
printf(", uint8");
|
||||
if(n & 2)
|
||||
printf(", uint16");
|
||||
if(n & 4)
|
||||
printf(", uint32");
|
||||
}
|
||||
|
||||
write_params(rets, &first);
|
||||
printf(")\n{\n");
|
||||
}
|
||||
@ -456,12 +558,13 @@ write_gcc_func_trailer(char *package, char *name, struct params *rets)
|
||||
/* Write out a function header. */
|
||||
static void
|
||||
write_func_header(char *package, char *name,
|
||||
struct params *params, struct params *rets)
|
||||
struct params *params, int paramwid,
|
||||
struct params *rets)
|
||||
{
|
||||
if (gcc)
|
||||
write_gcc_func_header(package, name, params, rets);
|
||||
else
|
||||
write_6g_func_header(package, name, params, rets);
|
||||
write_6g_func_header(package, name, params, paramwid, rets);
|
||||
printf("#line %d \"%s\"\n", lineno, file);
|
||||
}
|
||||
|
||||
@ -546,11 +649,12 @@ process_file(void)
|
||||
{
|
||||
char *package, *name;
|
||||
struct params *params, *rets;
|
||||
int paramwid;
|
||||
|
||||
package = read_package();
|
||||
read_preprocessor_lines();
|
||||
while (read_func_header(&name, ¶ms, &rets)) {
|
||||
write_func_header(package, name, params, rets);
|
||||
while (read_func_header(&name, ¶ms, ¶mwid, &rets)) {
|
||||
write_func_header(package, name, params, paramwid, rets);
|
||||
copy_body();
|
||||
write_func_trailer(package, name, rets);
|
||||
free(name);
|
||||
@ -570,6 +674,8 @@ usage(void)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *goarch;
|
||||
|
||||
while(argc > 1 && argv[1][0] == '-') {
|
||||
if(strcmp(argv[1], "-") == 0)
|
||||
break;
|
||||
@ -597,6 +703,18 @@ main(int argc, char **argv)
|
||||
fprintf(stderr, "open %s: %s\n", file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!gcc) {
|
||||
// 6g etc; update size table
|
||||
goarch = getenv("GOARCH");
|
||||
if(goarch != NULL && strcmp(goarch, "amd64") == 0) {
|
||||
type_table[Uintptr].size = 8;
|
||||
type_table[String].size = 16;
|
||||
type_table[Array].size = 8+4+4;
|
||||
structround = 8;
|
||||
}
|
||||
}
|
||||
|
||||
process_file();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user