add optional LZMA support for compressing embedded JARs, boot images, and shared objects

This commit is contained in:
Joel Dice
2012-06-02 09:06:22 -06:00
parent bd7ef24734
commit 5d9f7b2bc3
15 changed files with 764 additions and 30 deletions

View File

@ -12,6 +12,7 @@
#include "system.h"
#include "tokenizer.h"
#include "finder.h"
#include "lzma.h"
using namespace vm;
@ -173,11 +174,12 @@ class DirectoryElement: public Element {
class PointerRegion: public System::Region {
public:
PointerRegion(System* s, Allocator* allocator, const uint8_t* start,
size_t length):
size_t length, bool freePointer = false):
s(s),
allocator(allocator),
start_(start),
length_(length)
length_(length),
freePointer(freePointer)
{ }
virtual const uint8_t* start() {
@ -189,6 +191,9 @@ class PointerRegion: public System::Region {
}
virtual void dispose() {
if (freePointer) {
allocator->free(start_, length_);
}
allocator->free(this, sizeof(*this));
}
@ -196,6 +201,7 @@ class PointerRegion: public System::Region {
Allocator* allocator;
const uint8_t* start_;
size_t length_;
bool freePointer;
};
class DataRegion: public System::Region {
@ -556,7 +562,10 @@ class BuiltinElement: public JarElement {
virtual void init() {
if (index == 0) {
if (s->success(s->load(&library, libraryName))) {
void* p = library->resolve(name);
bool lzma = strncmp("lzma:", name, 5) == 0;
const char* symbolName = lzma ? name + 5 : name;
void* p = library->resolve(symbolName);
if (p) {
uint8_t* (*function)(unsigned*);
memcpy(&function, &p, BytesPerWord);
@ -564,10 +573,29 @@ class BuiltinElement: public JarElement {
unsigned size;
uint8_t* data = function(&size);
if (data) {
bool freePointer;
if (lzma) {
#ifdef AVIAN_USE_LZMA
unsigned outSize;
data = decodeLZMA(s, allocator, data, size, &outSize);
size = outSize;
freePointer = true;
#else
abort(s);
#endif
} else {
freePointer = false;
}
region = new (allocator->allocate(sizeof(PointerRegion)))
PointerRegion(s, allocator, data, size);
PointerRegion(s, allocator, data, size, freePointer);
index = JarIndex::open(s, allocator, region);
} else if (DebugFind) {
fprintf(stderr, "%s in %s returned null\n", symbolName,
libraryName);
}
} else if (DebugFind) {
fprintf(stderr, "unable to find %s in %s\n", symbolName,
libraryName);
}
}
}