[Go] Use a unique name for the wrapper functions, since they are
publicly visible. This permits linking together different SWIG wrappers in the same program if they wrap the same function. The unique name is generated by hashing the .swig file.
This commit is contained in:
parent
96134c65a8
commit
2752d78ce6
1 changed files with 127 additions and 1 deletions
|
|
@ -11,6 +11,103 @@
|
|||
#include "cparse.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* siphash()
|
||||
*
|
||||
* 64-bit SipHash-2-4 to generate unique id for each module
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
// An unsigned 64-bit integer that works on a 32-bit host.
|
||||
typedef struct {
|
||||
// Assume unsigned long is at least 32 bits.
|
||||
unsigned long hi;
|
||||
unsigned long lo;
|
||||
} swig_uint64;
|
||||
|
||||
// Rotate v left by bits, which must be <= 32.
|
||||
static inline void _rotl(swig_uint64 *v, int bits) {
|
||||
assert(bits <= 32);
|
||||
unsigned long tmp = v->hi;
|
||||
if (bits == 32) {
|
||||
v->hi = v->lo;
|
||||
v->lo = tmp;
|
||||
} else {
|
||||
v->hi = (tmp << bits) | ((0xfffffffful & v->lo) >> (32 - bits));
|
||||
v->lo = (v->lo << bits) | ((0xfffffffful & tmp) >> (32 - bits));
|
||||
}
|
||||
}
|
||||
|
||||
// dst ^= src
|
||||
static inline void _xor(swig_uint64 *dst, swig_uint64 *src) {
|
||||
dst->lo ^= src->lo;
|
||||
dst->hi ^= src->hi;
|
||||
}
|
||||
|
||||
// dst += src
|
||||
static inline void _add(swig_uint64 *dst, swig_uint64 *src) {
|
||||
dst->lo += src->lo;
|
||||
dst->hi += src->hi + ((dst->lo & 0xfffffffful) < (src->lo&0xfffffffful) ? 1 : 0);
|
||||
}
|
||||
#define SIPROUND \
|
||||
do { \
|
||||
_add(&v0, &v1); _rotl(&v1, 13); _xor(&v1, &v0); _rotl(&v0, 32); \
|
||||
_add(&v2, &v3); _rotl(&v3, 16); _xor(&v3, &v2); \
|
||||
_add(&v0, &v3); _rotl(&v3, 21); _xor(&v3, &v0); \
|
||||
_add(&v2, &v1); _rotl(&v1, 17); _xor(&v1, &v2); _rotl(&v2, 32); \
|
||||
} while(0)
|
||||
|
||||
// Set out to the hash of inc/inlen.
|
||||
static void siphash(swig_uint64 *out, const char *inc, unsigned long inlen) {
|
||||
/* "somepseudorandomlygeneratedbytes" */
|
||||
swig_uint64 v0 = {0x736f6d65UL, 0x70736575UL};
|
||||
swig_uint64 v1 = {0x646f7261UL, 0x6e646f6dUL};
|
||||
swig_uint64 v2 = {0x6c796765UL, 0x6e657261UL};
|
||||
swig_uint64 v3 = {0x74656462UL, 0x79746573UL};
|
||||
swig_uint64 b;
|
||||
/* hard-coded k. */
|
||||
swig_uint64 k0 = {0x07060504UL, 0x03020100UL};
|
||||
swig_uint64 k1 = {0x0F0E0D0CUL, 0x0B0A0908UL};
|
||||
int i;
|
||||
const int cROUNDS = 2, dROUNDS = 4;
|
||||
const unsigned char *in = (const unsigned char *)inc;
|
||||
const unsigned char *end = in + inlen - (inlen % 8);
|
||||
int left = inlen & 7;
|
||||
_xor(&v3, &k1); _xor(&v2, &k0); _xor(&v1, &k1); _xor(&v0, &k0);
|
||||
for (; in != end; in += 8) {
|
||||
b.hi = 0; b.lo = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
b.lo |= ((unsigned long)in[i]) << (8*i);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
b.hi |= ((unsigned long)in[i+4]) << (8*i);
|
||||
}
|
||||
_xor(&v3, &b);
|
||||
for (i = 0; i < cROUNDS; i++) {
|
||||
SIPROUND;
|
||||
}
|
||||
_xor(&v0, &b);
|
||||
}
|
||||
b.hi = (inlen & 0xff)<<24; b.lo = 0;
|
||||
for (; left; left--) {
|
||||
if (left > 4) {
|
||||
b.hi |= ((unsigned long)in[left-1]) << (8*left-8-32);
|
||||
} else {
|
||||
b.lo |= ((unsigned long)in[left-1]) << (8*left-8);
|
||||
}
|
||||
}
|
||||
_xor(&v3, &b);
|
||||
for(i=0; i<cROUNDS; i++) {
|
||||
SIPROUND;
|
||||
}
|
||||
_xor(&v0, &b); v2.lo ^= 0xff;
|
||||
for(i=0; i<dROUNDS; i++) {
|
||||
SIPROUND;
|
||||
}
|
||||
out->lo = 0; out->hi = 0;
|
||||
_xor(out, &v0); _xor(out, &v1); _xor(out, &v2); _xor(out, &v3);
|
||||
}
|
||||
#undef SIPROUND
|
||||
|
||||
class GO:public Language {
|
||||
static const char *const usage;
|
||||
|
||||
|
|
@ -91,6 +188,8 @@ class GO:public Language {
|
|||
// A hash table of all the go_imports already imported. The index is a full
|
||||
// import name e.g. '"runtime"' or '_ "runtime/cgo"' or 'sc "syscall"'.
|
||||
Hash *go_imports;
|
||||
// A unique ID used to make public symbols unique.
|
||||
String *unique_id;
|
||||
|
||||
public:
|
||||
GO():package(NULL),
|
||||
|
|
@ -333,6 +432,20 @@ private:
|
|||
Printf(gc_filename, "%s%s_gc.c", SWIG_output_directory(), module);
|
||||
}
|
||||
|
||||
// Generate a unique ID based on a hash of the SWIG input.
|
||||
swig_uint64 hash = {0, 0};
|
||||
FILE *swig_input = Swig_open(swig_filename);
|
||||
if (swig_input == NULL) {
|
||||
FileErrorDisplay(swig_filename);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
String *swig_input_content = Swig_read_file(swig_input);
|
||||
siphash(&hash, Char(swig_input_content), Len(swig_input_content));
|
||||
Delete(swig_input_content);
|
||||
fclose(swig_input);
|
||||
unique_id = NewString("");
|
||||
Printf(unique_id, "_%s_%08x%08x", package, hash.hi, hash.lo);
|
||||
|
||||
// Open files.
|
||||
|
||||
f_c_begin = NewFile(c_filename, "w", SWIG_output_files());
|
||||
|
|
@ -744,6 +857,7 @@ private:
|
|||
if (overname) {
|
||||
Append(wname, overname);
|
||||
}
|
||||
Append(wname, unique_id);
|
||||
Setattr(n, "wrap:name", wname);
|
||||
|
||||
ParmList *parms = Getattr(n, "parms");
|
||||
|
|
@ -2044,6 +2158,7 @@ private:
|
|||
Append(go_name, sname);
|
||||
|
||||
String *wname = Swig_name_wrapper(sname);
|
||||
Append(wname, unique_id);
|
||||
Setattr(n, "wrap:name", wname);
|
||||
|
||||
int r = makeWrappers(n, sname, go_name, NULL, wname, NULL, NULL, type, true);
|
||||
|
|
@ -2332,6 +2447,7 @@ private:
|
|||
if (overname) {
|
||||
Append(wname, overname);
|
||||
}
|
||||
Append(wname, unique_id);
|
||||
|
||||
String *result = NewString(Getattr(method, "type"));
|
||||
SwigType_push(result, Getattr(method, "decl"));
|
||||
|
|
@ -2419,6 +2535,7 @@ private:
|
|||
Swig_MembersetToFunction(var, class_name, flags);
|
||||
|
||||
String *wname = Swig_name_wrapper(mname_set);
|
||||
Append(wname, unique_id);
|
||||
ParmList *parms = NewParm(vt, var_name, var);
|
||||
String *result = NewString("void");
|
||||
int r = makeWrappers(var, mname_set, go_name, NULL, wname, bases, parms, result, false);
|
||||
|
|
@ -2448,6 +2565,7 @@ private:
|
|||
Append(go_name, var_name);
|
||||
|
||||
String *wname = Swig_name_wrapper(mname_get);
|
||||
Append(wname, unique_id);
|
||||
|
||||
int r = makeWrappers(var, mname_get, go_name, NULL, wname, bases, NULL, vt, false);
|
||||
if (r != SWIG_OK) {
|
||||
|
|
@ -2559,6 +2677,7 @@ private:
|
|||
Delete(c1);
|
||||
|
||||
String *wname = Swig_name_wrapper(name);
|
||||
Append(wname, unique_id);
|
||||
Setattr(n, "wrap:name", wname);
|
||||
|
||||
SwigType *result = Copy(Getattr(b.item, "classtypeobj"));
|
||||
|
|
@ -2772,6 +2891,7 @@ private:
|
|||
if (overname) {
|
||||
Append(wname, overname);
|
||||
}
|
||||
Append(wname, unique_id);
|
||||
Setattr(n, "wrap:name", wname);
|
||||
|
||||
bool is_static = isStatic(n);
|
||||
|
|
@ -2885,7 +3005,9 @@ private:
|
|||
|
||||
Swig_save("classDirectorConstructor", n, "wrap:name", "wrap:action", NULL);
|
||||
|
||||
Setattr(n, "wrap:name", Swig_name_wrapper(name));
|
||||
String *dwname = Swig_name_wrapper(name);
|
||||
Append(dwname, unique_id);
|
||||
Setattr(n, "wrap:name", dwname);
|
||||
|
||||
String *action = NewString("");
|
||||
Printv(action, Swig_cresult_name(), " = new SwigDirector_", class_name, "(", NULL);
|
||||
|
|
@ -2999,6 +3121,7 @@ private:
|
|||
Delete(c1);
|
||||
|
||||
String *wname = Swig_name_wrapper(fnname);
|
||||
Append(wname, unique_id);
|
||||
|
||||
Setattr(n, "wrap:name", fnname);
|
||||
|
||||
|
|
@ -3134,6 +3257,7 @@ private:
|
|||
// set.
|
||||
String *wn = Swig_name_wrapper(Getattr(on, "sym:name"));
|
||||
Append(wn, Getattr(on, "sym:overname"));
|
||||
Append(wn, unique_id);
|
||||
Setattr(on, "wrap:name", wn);
|
||||
Delete(wn);
|
||||
Setattr(on, "wrap:parms", Getattr(on, "parms"));
|
||||
|
|
@ -3252,6 +3376,7 @@ private:
|
|||
}
|
||||
|
||||
String *callback_wname = Swig_name_wrapper(callback_name);
|
||||
Append(callback_wname, unique_id);
|
||||
|
||||
String *upcall_name = Copy(director_struct_name);
|
||||
Append(upcall_name, "_upcall_");
|
||||
|
|
@ -3261,6 +3386,7 @@ private:
|
|||
if (overname) {
|
||||
Append(upcall_wname, overname);
|
||||
}
|
||||
Append(upcall_wname, unique_id);
|
||||
|
||||
String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue