Commits

Anonymous committed eedaa59

Name mangling, what the heck!

Comments (0)

Files changed (1)

    XXX other JAR tricks?
 */
 
+#ifndef NO_PRIVATE_NAME_MANGLING
+#define PRIVATE_NAME_MANGLING
+#endif
+
 #include "allobjects.h"
 
 #include "node.h"
 	int c_nblocks;		/* current block stack level */
 	char *c_filename;	/* filename of current node */
 	char *c_name;		/* name of object (e.g. function) */
+#ifdef PRIVATE_NAME_MANGLING
+	char *c_private;	/* for private name mangling */
+#endif
 };
 
 
 static void com_list PROTO((struct compiling *, node *, int));
 static int com_argdefs PROTO((struct compiling *, node *));
 static int com_newlocal PROTO((struct compiling *, char *));
+static codeobject *icompile PROTO((struct _node *, struct compiling *));
+static codeobject *jcompile PROTO((struct _node *, char *, struct compiling *));
 
 static int
 com_init(c, filename)
 	return com_add(c, c->c_names, v);
 }
 
+#ifdef PRIVATE_NAME_MANGLING
+static int
+com_mangle(c, name, buffer, maxlen)
+	struct compiling *c;
+	char *name;
+	char *buffer;
+	int maxlen;
+{
+	/* Name mangling: __private becomes _classname_private.
+	   This is independent from how the name is used. */
+	char *p;
+	int nlen, plen;
+	nlen = strlen(name);
+	if (nlen+1 >= maxlen)
+		return 0; /* Don't mangle __extremely_long_names */
+	if (name[nlen-1] == '_' && name[nlen-2] == '_')
+		return 0; /* Don't mangle __whatever__ */
+	p = c->c_private;
+	/* Strip leading underscores from class name */
+	while (*p == '_')
+		p++;
+	if (*p == '\0')
+		return 0; /* Don't mangle if class is just underscores */
+	plen = strlen(p);
+	if (plen + nlen >= maxlen)
+		plen = maxlen-nlen-1; /* Truncate class name if too long */
+	/* buffer = "_" + p[:plen] + name[1:] # i.e. plen+nlen bytes */
+	buffer[0] = '_';
+	strncpy(buffer+1, p, plen);
+	strcpy(buffer+plen+1, name+1);
+	/* fprintf(stderr, "mangle %s -> %s\n", name, buffer); */
+	return 1;
+}
+#endif
+
 static void
 com_addopnamestr(c, op, name)
 	struct compiling *c;
 {
 	object *v;
 	int i;
+#ifdef PRIVATE_NAME_MANGLING
+	char buffer[256];
+	if (name != NULL && name[0] == '_' && name[1] == '_' &&
+	    c->c_private != NULL &&
+	    com_mangle(c, name, buffer, (int)sizeof(buffer)))
+		name = buffer;
+#endif
 	if (name == NULL || (v = newstringobject(name)) == NULL) {
 		c->c_errors++;
 		i = 255;
 		object *v;
 		int i;
 		int ndefs = com_argdefs(c, CHILD(n, 0));
-		v = (object *) compile(CHILD(n, 0), c->c_filename);
+		v = (object *) icompile(CHILD(n, 0), c);
 		if (v == NULL) {
 			c->c_errors++;
 			i = 255;
 {
 	object *v;
 	REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
-	v = (object *)compile(n, c->c_filename);
+	v = (object *)icompile(n, c);
 	if (v == NULL)
 		c->c_errors++;
 	else {
 		com_addoparg(c, BUILD_TUPLE, 0);
 	else
 		com_bases(c, CHILD(n, 3));
-	v = (object *)compile(n, c->c_filename);
+	v = (object *)icompile(n, c);
 	if (v == NULL)
 		c->c_errors++;
 	else {
 	REQ(n, classdef);
 	/* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
 	c->c_name = STR(CHILD(n, 1));
+#ifdef PRIVATE_NAME_MANGLING
+	c->c_private = c->c_name;
+#endif
 	ch = CHILD(n, NCH(n)-1); /* The suite */
 	doc = get_docstring(ch);
 	if (doc != NULL) {
 	node *n;
 	char *filename;
 {
+	return jcompile(n, filename, NULL);
+}
+
+static codeobject *
+icompile(n, base)
+	node *n;
+	struct compiling *base;
+{
+	return jcompile(n, base->c_filename, base);
+}
+
+static codeobject *
+jcompile(n, filename, base)
+	node *n;
+	char *filename;
+	struct compiling *base;
+{
 	struct compiling sc;
 	codeobject *co;
 	if (!com_init(&sc, filename))
 		return NULL;
+#ifdef PRIVATE_NAME_MANGLING
+	if (base)
+		sc.c_private = base->c_private;
+	else
+		sc.c_private = NULL;
+#endif
 	compile_node(&sc, n);
 	com_done(&sc);
 	if ((TYPE(n) == funcdef || TYPE(n) == lambdef) && sc.c_errors == 0) {