mirror of
https://github.com/corda/corda.git
synced 2025-03-29 15:16:19 +00:00
it builds!
This commit is contained in:
parent
d4d155c834
commit
4e07acb26c
3
makefile
3
makefile
@ -47,7 +47,8 @@ interpreter-depends = \
|
||||
$(src)/vm.h
|
||||
interpreter-sources = \
|
||||
$(src)/vm.cpp \
|
||||
$(src)/heap.cpp
|
||||
$(src)/heap.cpp \
|
||||
$(src)/main.cpp
|
||||
interpreter-objects = $(call cpp-objects,$(interpreter-sources),$(src))
|
||||
interpreter-cflags = $(slow) $(cflags)
|
||||
|
||||
|
@ -7,9 +7,16 @@ namespace vm {
|
||||
|
||||
class ClassFinder {
|
||||
public:
|
||||
class Data {
|
||||
public:
|
||||
virtual ~Data() { }
|
||||
virtual const uint8_t* start() = 0;
|
||||
virtual size_t length() = 0;
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
||||
virtual ~ClassFinder() { }
|
||||
virtual const uint8_t* find(const char* className, unsigned* size) = 0;
|
||||
virtual void free(const uint8_t* class_) = 0;
|
||||
virtual Data* find(const char* className) = 0;
|
||||
};
|
||||
|
||||
} // namespace vm
|
||||
|
20
src/heap.cpp
20
src/heap.cpp
@ -238,12 +238,8 @@ class Segment {
|
||||
map(map)
|
||||
{
|
||||
if (capacity) {
|
||||
unsigned count = footprint(capacity) * BytesPerWord;
|
||||
data = static_cast<uintptr_t*>(system(context)->allocate(&count));
|
||||
|
||||
if (count != footprint(capacity) * BytesPerWord) {
|
||||
abort(context);
|
||||
}
|
||||
data = static_cast<uintptr_t*>
|
||||
(system(context)->allocate(footprint(capacity) * BytesPerWord));
|
||||
|
||||
if (map) {
|
||||
map->setSegment(this);
|
||||
@ -998,6 +994,8 @@ collect(Context* c)
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace vm {
|
||||
|
||||
Heap*
|
||||
makeHeap(System* system)
|
||||
{
|
||||
@ -1047,11 +1045,7 @@ makeHeap(System* system)
|
||||
Context c;
|
||||
};
|
||||
|
||||
unsigned count = sizeof(Heap);
|
||||
void* p = system->allocate(&count);
|
||||
if (count != sizeof(Heap)) {
|
||||
system->abort();
|
||||
}
|
||||
|
||||
return new (p) Heap(system);
|
||||
return new (system->allocate(sizeof(Heap))) Heap(system);
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef HEAP_H
|
||||
#define HEAP_H
|
||||
|
||||
#include "system.h"
|
||||
|
||||
namespace vm {
|
||||
|
||||
class Heap {
|
||||
@ -38,6 +40,8 @@ class Heap {
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
||||
Heap* makeHeap(System* system);
|
||||
|
||||
} // namespace vm
|
||||
|
||||
#endif//HEAP_H
|
||||
|
244
src/main.cpp
Normal file
244
src/main.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
#include "sys/mman.h"
|
||||
#include "sys/types.h"
|
||||
#include "sys/stat.h"
|
||||
#include "fcntl.h"
|
||||
#include "system.h"
|
||||
#include "heap.h"
|
||||
#include "vm.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
class System: public vm::System {
|
||||
public:
|
||||
System(unsigned limit): limit(limit), count(0) { }
|
||||
|
||||
virtual bool success(Status s) {
|
||||
return s == 0;
|
||||
}
|
||||
|
||||
virtual void* allocate(unsigned* size) {
|
||||
if (count + *size > limit) {
|
||||
*size = limit - count;
|
||||
}
|
||||
|
||||
uintptr_t* up = static_cast<uintptr_t*>(malloc(*size + sizeof(uintptr_t)));
|
||||
if (up == 0) abort();
|
||||
|
||||
*up = *size;
|
||||
return up + 1;
|
||||
}
|
||||
|
||||
virtual void free(const void* p) {
|
||||
if (p) {
|
||||
const uintptr_t* up = static_cast<const uintptr_t*>(p) - 1;
|
||||
count -= *up;
|
||||
::free(const_cast<uintptr_t*>(up));
|
||||
}
|
||||
}
|
||||
|
||||
virtual Status start(Thread*) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual Status make(Monitor**) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void abort() {
|
||||
::abort();
|
||||
}
|
||||
|
||||
unsigned limit;
|
||||
unsigned count;
|
||||
};
|
||||
|
||||
const char*
|
||||
append(vm::System* s, const char* a, const char* b, const char* c)
|
||||
{
|
||||
unsigned al = strlen(a);
|
||||
unsigned bl = strlen(b);
|
||||
unsigned cl = strlen(c);
|
||||
char* p = static_cast<char*>(s->allocate(al + bl + cl + 1));
|
||||
memcpy(p, a, al);
|
||||
memcpy(p + al, b, bl);
|
||||
memcpy(p + al + bl, c, cl + 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
class ClassFinder: public vm::ClassFinder {
|
||||
public:
|
||||
ClassFinder(vm::System* system, const char** path):
|
||||
system(system),
|
||||
path(path)
|
||||
{ }
|
||||
|
||||
class Data: public vm::ClassFinder::Data {
|
||||
public:
|
||||
Data(uint8_t* start, size_t length):
|
||||
start_(start),
|
||||
length_(length)
|
||||
{ }
|
||||
|
||||
virtual const uint8_t* start() {
|
||||
return start_;
|
||||
}
|
||||
|
||||
virtual size_t length() {
|
||||
return length_;
|
||||
}
|
||||
|
||||
virtual void dispose() {
|
||||
if (start_) {
|
||||
munmap(start_, length_);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* start_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
virtual Data* find(const char* className) {
|
||||
Data* d = new (system->allocate(sizeof(Data))) Data(0, 0);
|
||||
|
||||
for (const char** p = path; *p; ++p) {
|
||||
const char* file = append(system, *p, "/", className);
|
||||
int fd = open(file, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
struct stat s;
|
||||
int r = fstat(fd, &s);
|
||||
if (r != -1) {
|
||||
void* data = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (data) {
|
||||
d->start_ = static_cast<uint8_t*>(data);
|
||||
d->length_ = s.st_size;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
system->free(file);
|
||||
}
|
||||
|
||||
system->free(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
vm::System* system;
|
||||
const char** path;
|
||||
};
|
||||
|
||||
const char**
|
||||
parsePath(vm::System* s, const char* path)
|
||||
{
|
||||
class Tokenizer {
|
||||
public:
|
||||
class Token {
|
||||
public:
|
||||
Token(const char* s, unsigned length): s(s), length(length) { }
|
||||
|
||||
const char* s;
|
||||
unsigned length;
|
||||
};
|
||||
|
||||
Tokenizer(const char* s, char delimiter): s(s), delimiter(delimiter) { }
|
||||
|
||||
bool hasMore() {
|
||||
while (*s == delimiter) ++s;
|
||||
return *s;
|
||||
}
|
||||
|
||||
Token next() {
|
||||
const char* p = s;
|
||||
while (*s and *s != delimiter) ++s;
|
||||
return Token(p, s - p);
|
||||
}
|
||||
|
||||
const char* s;
|
||||
char delimiter;
|
||||
};
|
||||
|
||||
unsigned count = 0;
|
||||
for (Tokenizer t(path, ':'); t.hasMore();) ++ count;
|
||||
|
||||
const char** v = static_cast<const char**>
|
||||
(s->allocate((count + 1) * sizeof(const char*)));
|
||||
|
||||
unsigned i = 0;
|
||||
for (Tokenizer t(path, ':'); t.hasMore(); ++i) {
|
||||
Tokenizer::Token token(t.next());
|
||||
char* p = static_cast<char*>(s->allocate(token.length));
|
||||
memcpy(p, token.s, token.length);
|
||||
p[token.length] = 0;
|
||||
v[i] = p;
|
||||
}
|
||||
|
||||
v[i] = 0;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
run(unsigned heapSize, const char* path, const char* class_, int argc,
|
||||
const char** argv)
|
||||
{
|
||||
System s(heapSize);
|
||||
|
||||
const char** pathv = parsePath(&s, path);
|
||||
ClassFinder cf(&s, pathv);
|
||||
|
||||
Heap* heap = makeHeap(&s);
|
||||
|
||||
run(&s, heap, &cf, class_, argc, argv);
|
||||
|
||||
heap->dispose();
|
||||
|
||||
for (const char** p = pathv; *p; ++p) {
|
||||
s.free(*p);
|
||||
}
|
||||
|
||||
s.free(pathv);
|
||||
}
|
||||
|
||||
void
|
||||
usageAndExit(const char* name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-cp <classpath>] [-hs <maximum heap size>] "
|
||||
"<class name> [<argument> ...]", name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int
|
||||
main(int ac, const char** av)
|
||||
{
|
||||
unsigned heapSize = 4 * 1024 * 1024;
|
||||
const char* path = ".";
|
||||
const char* class_ = 0;
|
||||
int argc = 0;
|
||||
const char** argv = 0;
|
||||
|
||||
for (int i = 1; i < ac; ++i) {
|
||||
if (strcmp(av[i], "-cp") == 0) {
|
||||
path = av[++i];
|
||||
} else if (strcmp(av[i], "-hs") == 0) {
|
||||
heapSize = atoi(av[++i]);
|
||||
} else {
|
||||
class_ = av[i++];
|
||||
if (i < ac) {
|
||||
argc = ac - i;
|
||||
argv = av + i;
|
||||
i = ac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (class_ == 0) {
|
||||
usageAndExit(av[0]);
|
||||
}
|
||||
|
||||
run(heapSize, path, class_, argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
36
src/system.h
36
src/system.h
@ -27,39 +27,23 @@ class System {
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
||||
class File {
|
||||
public:
|
||||
virtual ~File() { }
|
||||
virtual Status read(uint8_t* data, unsigned* size) = 0;
|
||||
virtual Status write(const uint8_t* data, unsigned size) = 0;
|
||||
virtual Status close() = 0;
|
||||
};
|
||||
|
||||
static const int ReadOnly = 00;
|
||||
static const int WriteOnly = 01;
|
||||
static const int ReadWrite = 02;
|
||||
static const int Append = 02000;
|
||||
static const int Create = 0100;
|
||||
|
||||
static const int UserRead = 0400;
|
||||
static const int UserWrite = 0200;
|
||||
static const int UserExecute = 0100;
|
||||
static const int GroupRead = 040;
|
||||
static const int GroupWrite = 020;
|
||||
static const int GroupExecute = 010;
|
||||
static const int OtherRead = 04;
|
||||
static const int OtherWrite = 02;
|
||||
static const int OtherExecute = 01;
|
||||
|
||||
virtual ~System() { }
|
||||
|
||||
virtual bool success(Status) = 0;
|
||||
virtual void* allocate(unsigned* size) = 0;
|
||||
virtual void free(void*) = 0;
|
||||
virtual void free(const void*) = 0;
|
||||
virtual Status start(Thread*) = 0;
|
||||
virtual Status make(Monitor**) = 0;
|
||||
virtual Status open(File**, const char* path, int flags, int mode) = 0;
|
||||
virtual void abort() = 0;
|
||||
|
||||
void* allocate(unsigned size) {
|
||||
unsigned requested = size;
|
||||
void* p = allocate(&size);
|
||||
if (size != requested) {
|
||||
abort();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace vm
|
||||
|
10
src/vm.cpp
10
src/vm.cpp
@ -1429,15 +1429,13 @@ resolveClass(Thread* t, object spec)
|
||||
object class_ = hashMapFind
|
||||
(t, t->vm->classMap, spec, byteArrayHash, byteArrayEqual);
|
||||
if (class_ == 0) {
|
||||
unsigned size;
|
||||
const uint8_t* data = t->vm->classFinder->find
|
||||
(reinterpret_cast<const char*>(&byteArrayBody(t, spec, 0)), &size);
|
||||
ClassFinder::Data* data = t->vm->classFinder->find
|
||||
(reinterpret_cast<const char*>(&byteArrayBody(t, spec, 0)));
|
||||
|
||||
if (data) {
|
||||
// parse class file
|
||||
class_ = parseClass(t, data, size);
|
||||
|
||||
t->vm->classFinder->free(data);
|
||||
class_ = parseClass(t, data->start(), data->length());
|
||||
data->dispose();
|
||||
|
||||
PROTECT(t, class_);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user