support classloading from jar files compiled into the executable

This commit is contained in:
Joel Dice
2007-10-25 16:06:05 -06:00
parent d4656e8a52
commit 20cc788fa4
10 changed files with 238 additions and 81 deletions

View File

@ -325,13 +325,13 @@ class JarIndex {
class JarElement: public Element {
public:
JarElement(System* s, const char* name):
s(s), name(name), region(0), index(0)
s(s), name(name), index(0)
{ }
void init() {
virtual void init() {
if (index == 0) {
System::Region* r;
if (s->success(s->map(&r, this->name))) {
if (s->success(s->map(&r, name))) {
region = r;
index = JarIndex::open(s, r);
}
@ -358,6 +358,8 @@ class JarElement: public Element {
s->free(name);
if (index) {
index->dispose();
}
if (region) {
region->dispose();
}
s->free(this);
@ -369,6 +371,35 @@ class JarElement: public Element {
JarIndex* index;
};
class BuiltinElement: public JarElement {
public:
BuiltinElement(System* s, const char* name):
JarElement(s, name)
{ }
virtual void init() {
if (index == 0) {
System::Library* library;
if (s->success(s->load(&library, 0, false, 0))) {
void* p = library->resolve(name);
if (p) {
uint8_t* (*function)(unsigned*);
memcpy(&function, &p, BytesPerWord);
unsigned size;
uint8_t* data = function(&size);
if (data) {
region = new (s->allocate(sizeof(PointerRegion)))
PointerRegion(s, data, size);
index = JarIndex::open(s, region);
}
}
library->dispose();
}
}
}
};
Element*
parsePath(System* s, const char* path)
{
@ -403,26 +434,34 @@ parsePath(System* s, const char* path)
Element* prev = 0;
for (Tokenizer t(path, s->pathSeparator()); t.hasMore();) {
Tokenizer::Token token(t.next());
char* name = static_cast<char*>(s->allocate(token.length + 1));
memcpy(name, token.s, token.length);
name[token.length] = 0;
Element* e;
switch (s->identify(name)) {
case System::File: {
e = new (s->allocate(sizeof(JarElement)))
JarElement(s, name);
} break;
if (*token.s == '[' and token.s[token.length - 1] == ']') {
char* name = static_cast<char*>(s->allocate(token.length - 1));
memcpy(name, token.s + 1, token.length - 1);
name[token.length - 2] = 0;
e = new (s->allocate(sizeof(BuiltinElement))) BuiltinElement(s, name);
} else {
char* name = static_cast<char*>(s->allocate(token.length + 1));
memcpy(name, token.s, token.length);
name[token.length] = 0;
case System::Directory: {
e = new (s->allocate(sizeof(DirectoryElement)))
DirectoryElement(s, name);
} break;
switch (s->identify(name)) {
case System::File: {
e = new (s->allocate(sizeof(JarElement))) JarElement(s, name);
} break;
default: {
s->free(name);
e = 0;
} break;
case System::Directory: {
e = new (s->allocate(sizeof(DirectoryElement)))
DirectoryElement(s, name);
} break;
default: {
s->free(name);
e = 0;
} break;
}
}
if (e) {