mirror of
https://github.com/golang/go
synced 2024-11-20 10:14:43 -07:00
first attempt at real FFI support.
in a .6 file, an export line //ffi T localfib remotefib remote.so means the dynamic linker should initialize localfib, always a pointer, to the address of remotefib, either text (T) or data (D) after loading remote.so. the C compiler will generate an export section when given the pragmas #pragma package fib #pragma ffi T localfib remotefib remote.so needing #pragma package is a bit of a kludge and hopefully could go away later. this is just the 6 tool chain support. other architectures will happen once 6 settles down. code using this to do FFI is in a later CL. R=r DELTA=161 (141 added, 14 deleted, 6 changed) OCL=33783 CL=33795
This commit is contained in:
parent
0262f8834d
commit
8c253bcae5
@ -232,6 +232,19 @@ outcode(void)
|
||||
Binit(&b, f, OWRITE);
|
||||
|
||||
Bprint(&b, "%s\n", thestring);
|
||||
if(nffi > 0) {
|
||||
int i;
|
||||
|
||||
if(package == nil) {
|
||||
yyerror("#pragma ffi without #pragma package");
|
||||
package = "_ffi_";
|
||||
}
|
||||
Bprint(&b, "\n$$ // ffi\n", thestring);
|
||||
Bprint(&b, "package %s\n", package);
|
||||
for(i=0; i<nffi; i++)
|
||||
Bprint(&b, "//ffi %c %s %s %s\n", ffi[i].type, ffi[i].local, ffi[i].remote, ffi[i].path);
|
||||
Bprint(&b, "$$\n\n$$\n\n");
|
||||
}
|
||||
Bprint(&b, "!\n");
|
||||
|
||||
outhist(&b);
|
||||
|
@ -1550,6 +1550,7 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp)
|
||||
|
||||
// skip white space
|
||||
p = *pp;
|
||||
again:
|
||||
while(p < ep && (*p == ' ' || *p == '\t'))
|
||||
p++;
|
||||
if(p == ep)
|
||||
@ -1569,7 +1570,13 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp)
|
||||
p += 5;
|
||||
else if(strncmp(p, "const ", 6) == 0)
|
||||
p += 6;
|
||||
else{
|
||||
else if(strncmp(p, "//", 2) == 0) {
|
||||
p = memchr(p, '\n', ep - p);
|
||||
if(p == nil)
|
||||
return 0;
|
||||
p++;
|
||||
goto again;
|
||||
} else {
|
||||
fprint(2, "ar: confused in pkg data near <<%.20s>>\n", p);
|
||||
errors++;
|
||||
return -1;
|
||||
|
@ -49,6 +49,7 @@ typedef struct Hist Hist;
|
||||
typedef struct Term Term;
|
||||
typedef struct Init Init;
|
||||
typedef struct Bits Bits;
|
||||
typedef struct Ffi Ffi;
|
||||
|
||||
#define NHUNK 50000L
|
||||
#define BUFSIZ 8192
|
||||
@ -436,6 +437,18 @@ struct Funct
|
||||
Sym* castfr[NTYPE];
|
||||
};
|
||||
|
||||
struct Ffi
|
||||
{
|
||||
char type;
|
||||
char* local;
|
||||
char* remote;
|
||||
char* path;
|
||||
};
|
||||
|
||||
EXTERN Ffi *ffi;
|
||||
EXTERN int nffi;
|
||||
EXTERN char* package;
|
||||
|
||||
EXTERN struct
|
||||
{
|
||||
Type* tenum; /* type of entire enum */
|
||||
@ -740,6 +753,8 @@ void pragpack(void);
|
||||
void pragfpround(void);
|
||||
void pragtextflag(void);
|
||||
void pragincomplete(void);
|
||||
void pragffi(void);
|
||||
void pragpackage(void);
|
||||
|
||||
/*
|
||||
* calls to machine depend part
|
||||
|
@ -200,13 +200,35 @@ arginit(void)
|
||||
flagbits['X'] = flagbits['o'];
|
||||
}
|
||||
|
||||
static char*
|
||||
getquoted(void)
|
||||
{
|
||||
int c;
|
||||
char *t;
|
||||
Rune r;
|
||||
|
||||
c = getnsc();
|
||||
if(c != '"')
|
||||
return nil;
|
||||
t = fmtbuf;
|
||||
for(;;) {
|
||||
r = getr();
|
||||
if(r == ' ' || r == '\n')
|
||||
return nil;
|
||||
if(r == '"')
|
||||
break;
|
||||
t += runetochar(t, &r);
|
||||
}
|
||||
*t = 0;
|
||||
return strdup(fmtbuf);
|
||||
}
|
||||
|
||||
void
|
||||
pragvararg(void)
|
||||
{
|
||||
Sym *s;
|
||||
int n, c;
|
||||
char *t;
|
||||
Rune r;
|
||||
Type *ty;
|
||||
|
||||
if(!debug['F'])
|
||||
@ -251,20 +273,9 @@ ckflag:
|
||||
|
||||
cktype:
|
||||
/*#pragma varargck type O int*/
|
||||
c = getnsc();
|
||||
if(c != '"')
|
||||
t = getquoted();
|
||||
if(t == nil)
|
||||
goto bad;
|
||||
t = fmtbuf;
|
||||
for(;;) {
|
||||
r = getr();
|
||||
if(r == ' ' || r == '\n')
|
||||
goto bad;
|
||||
if(r == '"')
|
||||
break;
|
||||
t += runetochar(t, &r);
|
||||
}
|
||||
*t = 0;
|
||||
t = strdup(fmtbuf);
|
||||
s = getsym();
|
||||
if(s == S)
|
||||
goto bad;
|
||||
@ -516,3 +527,64 @@ out:
|
||||
if(debug['f'])
|
||||
print("%s incomplete\n", s->name);
|
||||
}
|
||||
|
||||
void
|
||||
pragffi(void)
|
||||
{
|
||||
Sym *local, *remote, *type;
|
||||
char *path;
|
||||
Ffi *f;
|
||||
|
||||
type = getsym();
|
||||
if(type == nil)
|
||||
goto err;
|
||||
|
||||
local = getsym();
|
||||
if(local == nil)
|
||||
goto err;
|
||||
|
||||
remote = getsym();
|
||||
if(remote == nil)
|
||||
goto err;
|
||||
|
||||
path = getquoted();
|
||||
if(path == nil)
|
||||
goto err;
|
||||
|
||||
if(nffi%32 == 0)
|
||||
ffi = realloc(ffi, (nffi+32)*sizeof ffi[0]);
|
||||
f = &ffi[nffi++];
|
||||
f->type = type->name[0];
|
||||
f->local = local->name;
|
||||
f->remote = remote->name;
|
||||
f->path = path;
|
||||
goto out;
|
||||
|
||||
err:
|
||||
yyerror("usage: #pragma ffi typechar local remote \"path\"");
|
||||
|
||||
out:
|
||||
while(getnsc() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
pragpackage(void)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
s = getsym();
|
||||
if(s == nil)
|
||||
goto err;
|
||||
|
||||
package = s->name;
|
||||
goto out;
|
||||
|
||||
err:
|
||||
yyerror("malformed #pragma package");
|
||||
|
||||
out:
|
||||
while(getnsc() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,20 @@ pragvararg(void)
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
pragffi(void)
|
||||
{
|
||||
while(getnsc() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
pragpackage(void)
|
||||
{
|
||||
while(getnsc() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
pragfpround(void)
|
||||
{
|
||||
|
@ -283,7 +283,7 @@ macdef(void)
|
||||
continue;
|
||||
}
|
||||
if(ischr){
|
||||
if(c == '\\'){
|
||||
if(c == '\\'){
|
||||
base = allocn(base, len, 1);
|
||||
base[len++] = c;
|
||||
c = getc();
|
||||
@ -400,7 +400,7 @@ macexpand(Sym *s, char *b)
|
||||
print("#expand %s %s\n", s->name, ob);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
nargs = (char)(*s->macro & ~VARMAC) - 1;
|
||||
dots = *s->macro & VARMAC;
|
||||
|
||||
@ -737,6 +737,14 @@ macprag(void)
|
||||
pragincomplete();
|
||||
return;
|
||||
}
|
||||
if(s && strcmp(s->name, "ffi") == 0) {
|
||||
pragffi();
|
||||
return;
|
||||
}
|
||||
if(s && strcmp(s->name, "package") == 0) {
|
||||
pragpackage();
|
||||
return;
|
||||
}
|
||||
while(getnsc() != '\n')
|
||||
;
|
||||
return;
|
||||
@ -763,7 +771,7 @@ praglib:
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
* put pragma-line in as a funny history
|
||||
* put pragma-line in as a funny history
|
||||
*/
|
||||
c = strlen(symb) + 1;
|
||||
hp = alloc(c);
|
||||
|
@ -102,7 +102,7 @@ ldpkg(Biobuf *f, int64 len, char *filename)
|
||||
while(*p0 == ' ' || *p0 == '\t' || *p0 == '\n')
|
||||
p0++;
|
||||
if(strncmp(p0, "package ", 8) != 0) {
|
||||
fprint(2, "%s: bad package section in %s\n", argv0, filename);
|
||||
fprint(2, "%s: bad package section in %s - %s\n", argv0, filename, p0);
|
||||
return;
|
||||
}
|
||||
p0 += 8;
|
||||
@ -199,8 +199,6 @@ again:
|
||||
return 0;
|
||||
|
||||
// prefix: (var|type|func|const)
|
||||
prefix = p;
|
||||
|
||||
prefix = p;
|
||||
if(p + 6 > ep)
|
||||
return -1;
|
||||
@ -251,7 +249,7 @@ again:
|
||||
goto again;
|
||||
} else {
|
||||
err:
|
||||
fprint(2, "%s: confused in pkg data near <<%.20s>>\n", argv0, prefix);
|
||||
fprint(2, "%s: confused in pkg data near <<%.40s>>\n", argv0, prefix);
|
||||
nerrors++;
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user