blob: 218af22c1769fd8824c6bd85f1933f8d36fd7382 [file] [log] [blame]
#include "j3/j3mangler.h"
#include "j3/j3class.h"
#include "j3/j3classloader.h"
#include "j3/j3method.h"
#include "j3/j3utf16.h"
#include "j3/j3thread.h"
#include "j3/j3.h"
using namespace j3;
const char* J3Mangler::j3Id = "j3_";
const char* J3Mangler::javaId = "Java_";
J3Mangler::J3Mangler(J3Class* _from) {
from = _from;
cur = buf;
}
J3Mangler* J3Mangler::mangle(J3Signature* signature) {
const vmkit::Name* name = signature->name();
if(name->cStr()[1] == J3Cst::ID_Right)
return this;
check(2);
cur[0] = '_';
cur[1] = '_';
cur = next;
J3Utf16Encoder encoder(name);
encoder.nextUtf16();
uint16_t c;
while(!encoder.isEof() && ((c = encoder.nextUtf16()) != J3Cst::ID_Right)) {
mangle(c);
}
*cur = 0;
return this;
}
J3Mangler* J3Mangler::mangle(const vmkit::Name* clName, const vmkit::Name* name) {
mangle(clName);
check(1);
*cur = '_';
cur = next;
mangle(name);
return this;
}
J3Mangler* J3Mangler::mangle(const char* prefix) {
return mangle(prefix, strlen(prefix));
}
J3Mangler* J3Mangler::mangle(const char* prefix, size_t length) {
check(length);
memcpy(cur, prefix, length);
*next = 0;
cur = next;
return this;
}
J3Mangler* J3Mangler::mangle(const vmkit::Name* name) {
J3Utf16Encoder encoder(name);
while(!encoder.isEof()) {
mangle(encoder.nextUtf16());
}
*cur = 0;
return this;
}
J3Mangler* J3Mangler::mangle(uint16_t c) {
switch(c) {
case '<':
case '>':
break; /* do not encode at all */
case '(':
case ')':
J3Thread::get()->vm()->internalError("should not try to encode a special character such as %c", (char)c);
case '_':
check(2);
*cur++ = '_';
*cur++ = '1';
break;
case ';':
check(2);
*cur++ = '_';
*cur++ = '2';
break;
case '[':
check(2);
*cur++ = '_';
*cur++ = '3';
break;
case '.':
case '/':
c = '_';
default:
if((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
(c == '_')) {
check(1);
*cur++ = c;
} else {
check(6);
*cur++ = '_';
*cur++ = '0';
*cur++ = hex(c >> 12);
*cur++ = hex(c >> 8);
*cur++ = hex(c >> 4);
*cur++ = hex(c >> 0);
}
}
cur = next;
return this;
}
char J3Mangler::hex(uint32_t n) {
n = n & 0xf;
return n < 10 ? (n + '0') : (n + 'a' - 10);
}
void J3Mangler::check(size_t n) {
next = cur + n;
if((next+1) >= (buf + max))
J3::internalError("unable to mangle: not enough space");
}