summaryrefslogtreecommitdiff
path: root/src/cmd/cc
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-08-24 16:15:21 -0700
committerRuss Cox <rsc@golang.org>2009-08-24 16:15:21 -0700
commit848e9261c030e32aec6f3f8b13d6aa1a458f2f18 (patch)
treea65fa19b965ad5b4c2a0bacc21bb06f03a8bdd95 /src/cmd/cc
parenta04e55452a8b999d380bdfb3ea72603d42fd076e (diff)
downloadgolang-848e9261c030e32aec6f3f8b13d6aa1a458f2f18.tar.gz
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
Diffstat (limited to 'src/cmd/cc')
-rw-r--r--src/cmd/cc/cc.h15
-rw-r--r--src/cmd/cc/dpchk.c100
-rw-r--r--src/cmd/cc/lexbody14
-rw-r--r--src/cmd/cc/macbody14
4 files changed, 126 insertions, 17 deletions
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index 2ebea6f5f..9964681f1 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -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
diff --git a/src/cmd/cc/dpchk.c b/src/cmd/cc/dpchk.c
index 9d22e621e..b1e988b87 100644
--- a/src/cmd/cc/dpchk.c
+++ b/src/cmd/cc/dpchk.c
@@ -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')
+ ;
+}
+
diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody
index 33734c722..1c979a0f1 100644
--- a/src/cmd/cc/lexbody
+++ b/src/cmd/cc/lexbody
@@ -47,6 +47,20 @@ pragvararg(void)
}
void
+pragffi(void)
+{
+ while(getnsc() != '\n')
+ ;
+}
+
+void
+pragpackage(void)
+{
+ while(getnsc() != '\n')
+ ;
+}
+
+void
pragfpround(void)
{
while(getnsc() != '\n')
diff --git a/src/cmd/cc/macbody b/src/cmd/cc/macbody
index 64f04129f..09ecccf5d 100644
--- a/src/cmd/cc/macbody
+++ b/src/cmd/cc/macbody
@@ -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);