Commit 8c253bca authored by Russ Cox's avatar Russ Cox

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
parent 0262f883
...@@ -232,6 +232,19 @@ outcode(void) ...@@ -232,6 +232,19 @@ outcode(void)
Binit(&b, f, OWRITE); Binit(&b, f, OWRITE);
Bprint(&b, "%s\n", thestring); 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"); Bprint(&b, "!\n");
outhist(&b); outhist(&b);
......
...@@ -1550,6 +1550,7 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp) ...@@ -1550,6 +1550,7 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp)
// skip white space // skip white space
p = *pp; p = *pp;
again:
while(p < ep && (*p == ' ' || *p == '\t')) while(p < ep && (*p == ' ' || *p == '\t'))
p++; p++;
if(p == ep) if(p == ep)
...@@ -1569,7 +1570,13 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp) ...@@ -1569,7 +1570,13 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp)
p += 5; p += 5;
else if(strncmp(p, "const ", 6) == 0) else if(strncmp(p, "const ", 6) == 0)
p += 6; 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); fprint(2, "ar: confused in pkg data near <<%.20s>>\n", p);
errors++; errors++;
return -1; return -1;
......
...@@ -49,6 +49,7 @@ typedef struct Hist Hist; ...@@ -49,6 +49,7 @@ typedef struct Hist Hist;
typedef struct Term Term; typedef struct Term Term;
typedef struct Init Init; typedef struct Init Init;
typedef struct Bits Bits; typedef struct Bits Bits;
typedef struct Ffi Ffi;
#define NHUNK 50000L #define NHUNK 50000L
#define BUFSIZ 8192 #define BUFSIZ 8192
...@@ -436,6 +437,18 @@ struct Funct ...@@ -436,6 +437,18 @@ struct Funct
Sym* castfr[NTYPE]; Sym* castfr[NTYPE];
}; };
struct Ffi
{
char type;
char* local;
char* remote;
char* path;
};
EXTERN Ffi *ffi;
EXTERN int nffi;
EXTERN char* package;
EXTERN struct EXTERN struct
{ {
Type* tenum; /* type of entire enum */ Type* tenum; /* type of entire enum */
...@@ -740,6 +753,8 @@ void pragpack(void); ...@@ -740,6 +753,8 @@ void pragpack(void);
void pragfpround(void); void pragfpround(void);
void pragtextflag(void); void pragtextflag(void);
void pragincomplete(void); void pragincomplete(void);
void pragffi(void);
void pragpackage(void);
/* /*
* calls to machine depend part * calls to machine depend part
......
...@@ -200,13 +200,35 @@ arginit(void) ...@@ -200,13 +200,35 @@ arginit(void)
flagbits['X'] = flagbits['o']; 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 void
pragvararg(void) pragvararg(void)
{ {
Sym *s; Sym *s;
int n, c; int n, c;
char *t; char *t;
Rune r;
Type *ty; Type *ty;
if(!debug['F']) if(!debug['F'])
...@@ -251,20 +273,9 @@ ckflag: ...@@ -251,20 +273,9 @@ ckflag:
cktype: cktype:
/*#pragma varargck type O int*/ /*#pragma varargck type O int*/
c = getnsc(); t = getquoted();
if(c != '"') if(t == nil)
goto bad; 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(); s = getsym();
if(s == S) if(s == S)
goto bad; goto bad;
...@@ -516,3 +527,64 @@ out: ...@@ -516,3 +527,64 @@ out:
if(debug['f']) if(debug['f'])
print("%s incomplete\n", s->name); 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) ...@@ -46,6 +46,20 @@ pragvararg(void)
; ;
} }
void
pragffi(void)
{
while(getnsc() != '\n')
;
}
void
pragpackage(void)
{
while(getnsc() != '\n')
;
}
void void
pragfpround(void) pragfpround(void)
{ {
......
...@@ -283,7 +283,7 @@ macdef(void) ...@@ -283,7 +283,7 @@ macdef(void)
continue; continue;
} }
if(ischr){ if(ischr){
if(c == '\\'){ if(c == '\\'){
base = allocn(base, len, 1); base = allocn(base, len, 1);
base[len++] = c; base[len++] = c;
c = getc(); c = getc();
...@@ -400,7 +400,7 @@ macexpand(Sym *s, char *b) ...@@ -400,7 +400,7 @@ macexpand(Sym *s, char *b)
print("#expand %s %s\n", s->name, ob); print("#expand %s %s\n", s->name, ob);
return; return;
} }
nargs = (char)(*s->macro & ~VARMAC) - 1; nargs = (char)(*s->macro & ~VARMAC) - 1;
dots = *s->macro & VARMAC; dots = *s->macro & VARMAC;
...@@ -737,6 +737,14 @@ macprag(void) ...@@ -737,6 +737,14 @@ macprag(void)
pragincomplete(); pragincomplete();
return; return;
} }
if(s && strcmp(s->name, "ffi") == 0) {
pragffi();
return;
}
if(s && strcmp(s->name, "package") == 0) {
pragpackage();
return;
}
while(getnsc() != '\n') while(getnsc() != '\n')
; ;
return; return;
...@@ -763,7 +771,7 @@ praglib: ...@@ -763,7 +771,7 @@ praglib:
goto bad; goto bad;
/* /*
* put pragma-line in as a funny history * put pragma-line in as a funny history
*/ */
c = strlen(symb) + 1; c = strlen(symb) + 1;
hp = alloc(c); hp = alloc(c);
......
...@@ -102,7 +102,7 @@ ldpkg(Biobuf *f, int64 len, char *filename) ...@@ -102,7 +102,7 @@ ldpkg(Biobuf *f, int64 len, char *filename)
while(*p0 == ' ' || *p0 == '\t' || *p0 == '\n') while(*p0 == ' ' || *p0 == '\t' || *p0 == '\n')
p0++; p0++;
if(strncmp(p0, "package ", 8) != 0) { 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; return;
} }
p0 += 8; p0 += 8;
...@@ -199,8 +199,6 @@ again: ...@@ -199,8 +199,6 @@ again:
return 0; return 0;
// prefix: (var|type|func|const) // prefix: (var|type|func|const)
prefix = p;
prefix = p; prefix = p;
if(p + 6 > ep) if(p + 6 > ep)
return -1; return -1;
...@@ -251,7 +249,7 @@ again: ...@@ -251,7 +249,7 @@ again:
goto again; goto again;
} else { } else {
err: 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++; nerrors++;
return -1; return -1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment