mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
support building Avian as a self-contained dynamic library
This commit is contained in:
parent
91494d9081
commit
357bd29460
71
makefile
71
makefile
@ -56,7 +56,8 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self
|
|||||||
|
|
||||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
||||||
-I$(JAVA_HOME)/include -idirafter $(src) -I$(native-build) \
|
-I$(JAVA_HOME)/include -idirafter $(src) -I$(native-build) \
|
||||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\"
|
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||||
|
-DBOOT_CLASSPATH=\"[classpathJar]\"
|
||||||
|
|
||||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||||
-I$(JAVA_HOME)/include/linux -I$(src) -pthread
|
-I$(JAVA_HOME)/include/linux -I$(src) -pthread
|
||||||
@ -65,7 +66,7 @@ cflags = $(build-cflags)
|
|||||||
|
|
||||||
common-lflags = -lm -lz
|
common-lflags = -lm -lz
|
||||||
|
|
||||||
lflags = $(common-lflags) -lpthread -ldl -rdynamic
|
lflags = $(common-lflags) -lpthread -ldl
|
||||||
|
|
||||||
system = posix
|
system = posix
|
||||||
asm = x86
|
asm = x86
|
||||||
@ -74,6 +75,11 @@ object-arch = i386:x86-64
|
|||||||
object-format = elf64-x86-64
|
object-format = elf64-x86-64
|
||||||
pointer-size = 8
|
pointer-size = 8
|
||||||
|
|
||||||
|
so-prefix = lib
|
||||||
|
so-suffix = .so
|
||||||
|
|
||||||
|
shared = -shared
|
||||||
|
|
||||||
ifeq ($(arch),i386)
|
ifeq ($(arch),i386)
|
||||||
object-arch = i386
|
object-arch = i386
|
||||||
object-format = elf32-i386
|
object-format = elf32-i386
|
||||||
@ -86,6 +92,8 @@ ifeq ($(platform),darwin)
|
|||||||
lflags = $(common-lflags) -ldl -framework CoreFoundation
|
lflags = $(common-lflags) -ldl -framework CoreFoundation
|
||||||
strip-all = -S -x
|
strip-all = -S -x
|
||||||
binaryToMacho = $(native-build)/binaryToMacho
|
binaryToMacho = $(native-build)/binaryToMacho
|
||||||
|
so-suffix = .jnilib
|
||||||
|
shared = -dynamiclib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
@ -95,6 +103,9 @@ ifeq ($(platform),windows)
|
|||||||
system = windows
|
system = windows
|
||||||
object-format = pe-i386
|
object-format = pe-i386
|
||||||
|
|
||||||
|
so-prefix =
|
||||||
|
so-suffix = .dll
|
||||||
|
|
||||||
cxx = i586-mingw32msvc-g++
|
cxx = i586-mingw32msvc-g++
|
||||||
cc = i586-mingw32msvc-gcc
|
cc = i586-mingw32msvc-gcc
|
||||||
dlltool = i586-mingw32msvc-dlltool
|
dlltool = i586-mingw32msvc-dlltool
|
||||||
@ -181,9 +192,12 @@ vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(native-build))
|
|||||||
vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(native-build))
|
vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(native-build))
|
||||||
vm-objects = $(vm-cpp-objects) $(vm-asm-objects)
|
vm-objects = $(vm-cpp-objects) $(vm-asm-objects)
|
||||||
|
|
||||||
driver-sources = $(src)/main.cpp
|
driver-source = $(src)/main.cpp
|
||||||
|
driver-object = $(native-build)/main.o
|
||||||
|
driver-dynamic-object = $(native-build)/main-dynamic.o
|
||||||
|
|
||||||
driver-object = $(call cpp-objects,$(driver-sources),$(src),$(native-build))
|
boot-source = $(src)/boot.cpp
|
||||||
|
boot-object = $(native-build)/boot.o
|
||||||
|
|
||||||
generator-headers = $(src)/constants.h
|
generator-headers = $(src)/constants.h
|
||||||
generator-sources = $(src)/type-generator.cpp
|
generator-sources = $(src)/type-generator.cpp
|
||||||
@ -191,8 +205,10 @@ generator-objects = \
|
|||||||
$(call cpp-objects,$(generator-sources),$(src),$(native-build))
|
$(call cpp-objects,$(generator-sources),$(src),$(native-build))
|
||||||
generator = $(native-build)/generator
|
generator = $(native-build)/generator
|
||||||
|
|
||||||
libvm = $(native-build)/lib$(name).a
|
static-library = $(native-build)/lib$(name).a
|
||||||
vm = $(native-build)/$(name)
|
executable = $(native-build)/$(name)
|
||||||
|
dynamic-library = $(native-build)/$(so-prefix)$(name)$(so-suffix)
|
||||||
|
executable-dynamic = $(native-build)/$(name)-dynamic
|
||||||
|
|
||||||
classpath-sources = $(shell find $(classpath) -name '*.java')
|
classpath-sources = $(shell find $(classpath) -name '*.java')
|
||||||
classpath-classes = \
|
classpath-classes = \
|
||||||
@ -212,26 +228,27 @@ flags = -cp $(test-build)
|
|||||||
args = $(flags) $(input)
|
args = $(flags) $(input)
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: $(vm) $(libvm) $(classpath-dep) $(test-dep)
|
build: $(static-library) $(executable) $(dynamic-library) \
|
||||||
|
$(executable-dynamic) $(classpath-dep) $(test-dep)
|
||||||
|
|
||||||
$(test-classes): $(classpath-dep)
|
$(test-classes): $(classpath-dep)
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: build
|
run: build
|
||||||
$(vm) $(args)
|
$(executable) $(args)
|
||||||
|
|
||||||
.PHONY: debug
|
.PHONY: debug
|
||||||
debug: build
|
debug: build
|
||||||
gdb --args $(vm) $(args)
|
gdb --args $(executable) $(args)
|
||||||
|
|
||||||
.PHONY: vg
|
.PHONY: vg
|
||||||
vg: build
|
vg: build
|
||||||
$(vg) $(vm) $(args)
|
$(vg) $(executable) $(args)
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: build
|
test: build
|
||||||
/bin/bash $(test)/test.sh 2>/dev/null \
|
/bin/bash $(test)/test.sh 2>/dev/null \
|
||||||
$(vm) $(mode) "$(flags)" \
|
$(executable) $(mode) "$(flags)" \
|
||||||
$(call class-names,$(test-build),$(test-classes))
|
$(call class-names,$(test-build),$(test-classes))
|
||||||
|
|
||||||
.PHONY: javadoc
|
.PHONY: javadoc
|
||||||
@ -293,7 +310,15 @@ $(vm-cpp-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
|||||||
$(vm-asm-objects): $(native-build)/%-asm.o: $(src)/%.S
|
$(vm-asm-objects): $(native-build)/%-asm.o: $(src)/%.S
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
$(driver-object): $(native-build)/%.o: $(src)/%.cpp
|
$(driver-object): $(driver-source)
|
||||||
|
$(compile-object)
|
||||||
|
|
||||||
|
$(driver-dynamic-object): $(driver-source)
|
||||||
|
@echo "compiling $(@)"
|
||||||
|
@mkdir -p $(dir $(@))
|
||||||
|
$(cxx) $(cflags) -DBOOT_LIBRARY=\"$(name)\" -c $(<) -o $(@)
|
||||||
|
|
||||||
|
$(boot-object): $(boot-source)
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
$(build)/classpath.jar: $(classpath-dep)
|
$(build)/classpath.jar: $(classpath-dep)
|
||||||
@ -307,7 +332,7 @@ $(binaryToMacho): $(src)/binaryToMacho.cpp
|
|||||||
$(classpath-object): $(build)/classpath.jar $(binaryToMacho)
|
$(classpath-object): $(build)/classpath.jar $(binaryToMacho)
|
||||||
ifeq ($(platform),darwin)
|
ifeq ($(platform),darwin)
|
||||||
$(binaryToMacho) $(build)/classpath.jar \
|
$(binaryToMacho) $(build)/classpath.jar \
|
||||||
__binary_classpath_jar_start __binary_classpath_jar_size > $(@)
|
__binary_classpath_jar_start __binary_classpath_jar_end > $(@)
|
||||||
else
|
else
|
||||||
(wd=$$(pwd); \
|
(wd=$$(pwd); \
|
||||||
cd $(build); \
|
cd $(build); \
|
||||||
@ -324,23 +349,37 @@ $(generator-objects): $(native-build)/%.o: $(src)/%.cpp
|
|||||||
$(jni-objects): $(native-build)/%.o: $(classpath)/%.cpp
|
$(jni-objects): $(native-build)/%.o: $(classpath)/%.cpp
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
$(libvm): $(vm-objects) $(jni-objects)
|
$(static-library): $(vm-objects) $(jni-objects)
|
||||||
@echo "creating $(@)"
|
@echo "creating $(@)"
|
||||||
rm -rf $(@)
|
rm -rf $(@)
|
||||||
$(ar) cru $(@) $(^)
|
$(ar) cru $(@) $(^)
|
||||||
$(ranlib) $(@)
|
$(ranlib) $(@)
|
||||||
|
|
||||||
$(vm): $(vm-objects) $(classpath-object) $(jni-objects) $(driver-object)
|
$(executable): \
|
||||||
|
$(vm-objects) $(classpath-object) $(jni-objects) $(driver-object) \
|
||||||
|
$(boot-object)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
$(dlltool) -z $(@).def $(^)
|
$(dlltool) -z $(@).def $(^)
|
||||||
$(dlltool) -k -d $(@).def -e $(@).exp
|
$(dlltool) -k -d $(@).def -e $(@).exp
|
||||||
$(cc) $(@).exp $(^) $(lflags) -o $(@)
|
$(cc) $(@).exp $(^) $(lflags) -o $(@)
|
||||||
else
|
else
|
||||||
$(cc) $(^) $(lflags) -o $(@)
|
$(cc) $(^) $(rdynamic) $(lflags) -o $(@)
|
||||||
endif
|
endif
|
||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
|
$(dynamic-library): \
|
||||||
|
$(vm-objects) $(classpath-object) $(dynamic-object) $(jni-objects) \
|
||||||
|
$(boot-object)
|
||||||
|
@echo "linking $(@)"
|
||||||
|
$(cc) $(^) $(shared) $(lflags) -o $(@)
|
||||||
|
$(strip) $(@)
|
||||||
|
|
||||||
|
$(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
|
||||||
|
@echo "linking $(@)"
|
||||||
|
$(cc) $(^) $(lflags) -o $(@)
|
||||||
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
$(generator): $(generator-objects)
|
$(generator): $(generator-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
$(build-cc) $(^) -o $(@)
|
$(build-cc) $(^) -o $(@)
|
||||||
|
@ -165,12 +165,12 @@ setting the classpath to "[bootJar]".
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
extern const uint8_t SYMBOL(start)[];
|
extern const uint8_t SYMBOL(start)[];
|
||||||
extern const uint8_t SYMBOL(size)[];
|
extern const uint8_t SYMBOL(end)[];
|
||||||
|
|
||||||
EXPORT const uint8_t*
|
EXPORT const uint8_t*
|
||||||
bootJar(unsigned* size)
|
bootJar(unsigned* size)
|
||||||
{
|
{
|
||||||
*size = reinterpret_cast<uintptr_t>(SYMBOL(size));
|
*size = SYMBOL(end) - SYMBOL(start);
|
||||||
return SYMBOL(start);
|
return SYMBOL(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,10 +30,10 @@ pad(unsigned n)
|
|||||||
|
|
||||||
void
|
void
|
||||||
writeObject(FILE* out, const uint8_t* data, unsigned size,
|
writeObject(FILE* out, const uint8_t* data, unsigned size,
|
||||||
const char* dataName, const char* sizeName)
|
const char* startName, const char* endName)
|
||||||
{
|
{
|
||||||
unsigned dataNameLength = strlen(dataName) + 1;
|
unsigned startNameLength = strlen(startName) + 1;
|
||||||
unsigned sizeNameLength = strlen(sizeName) + 1;
|
unsigned endNameLength = strlen(endName) + 1;
|
||||||
|
|
||||||
mach_header header = {
|
mach_header header = {
|
||||||
MH_MAGIC, // magic
|
MH_MAGIC, // magic
|
||||||
@ -42,7 +42,7 @@ writeObject(FILE* out, const uint8_t* data, unsigned size,
|
|||||||
MH_OBJECT, // filetype,
|
MH_OBJECT, // filetype,
|
||||||
2, // ncmds
|
2, // ncmds
|
||||||
sizeof(segment_command)
|
sizeof(segment_command)
|
||||||
+ sizeof(section)
|
+ (sizeof(section) * 2)
|
||||||
+ sizeof(symtab_command), // sizeofcmds
|
+ sizeof(symtab_command), // sizeofcmds
|
||||||
0 // flags
|
0 // flags
|
||||||
};
|
};
|
||||||
@ -55,23 +55,23 @@ writeObject(FILE* out, const uint8_t* data, unsigned size,
|
|||||||
pad(size), // vmsize
|
pad(size), // vmsize
|
||||||
sizeof(mach_header)
|
sizeof(mach_header)
|
||||||
+ sizeof(segment_command)
|
+ sizeof(segment_command)
|
||||||
+ sizeof(section)
|
+ (sizeof(section) * 2)
|
||||||
+ sizeof(symtab_command), // fileoff
|
+ sizeof(symtab_command), // fileoff
|
||||||
pad(size), // filesize
|
pad(size), // filesize
|
||||||
7, // maxprot
|
7, // maxprot
|
||||||
7, // initprot
|
7, // initprot
|
||||||
1, // nsects
|
2, // nsects
|
||||||
0 // flags
|
0 // flags
|
||||||
};
|
};
|
||||||
|
|
||||||
section sect = {
|
section sect1 = {
|
||||||
"__const", // sectname
|
"__const", // sectname
|
||||||
"__TEXT", // segname
|
"__TEXT", // segname
|
||||||
0, // addr
|
0, // addr
|
||||||
pad(size), // size
|
pad(size), // size
|
||||||
sizeof(mach_header)
|
sizeof(mach_header)
|
||||||
+ sizeof(segment_command)
|
+ sizeof(segment_command)
|
||||||
+ sizeof(section)
|
+ (sizeof(section) * 2)
|
||||||
+ sizeof(symtab_command), // offset
|
+ sizeof(symtab_command), // offset
|
||||||
0, // align
|
0, // align
|
||||||
0, // reloff
|
0, // reloff
|
||||||
@ -81,12 +81,30 @@ writeObject(FILE* out, const uint8_t* data, unsigned size,
|
|||||||
0, // reserved2
|
0, // reserved2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
section sect2 = {
|
||||||
|
"__const", // sectname
|
||||||
|
"__TEXT", // segname
|
||||||
|
0, // addr
|
||||||
|
0, // size
|
||||||
|
sizeof(mach_header)
|
||||||
|
+ sizeof(segment_command)
|
||||||
|
+ (sizeof(section) * 2)
|
||||||
|
+ sizeof(symtab_command)
|
||||||
|
+ size, // offset
|
||||||
|
0, // align
|
||||||
|
0, // reloff
|
||||||
|
0, // nreloc
|
||||||
|
S_REGULAR, // flags
|
||||||
|
0, // reserved1
|
||||||
|
0, // reserved2
|
||||||
|
};
|
||||||
|
|
||||||
symtab_command symbolTable = {
|
symtab_command symbolTable = {
|
||||||
LC_SYMTAB, // cmd
|
LC_SYMTAB, // cmd
|
||||||
sizeof(symtab_command), // cmdsize
|
sizeof(symtab_command), // cmdsize
|
||||||
sizeof(mach_header)
|
sizeof(mach_header)
|
||||||
+ sizeof(segment_command)
|
+ sizeof(segment_command)
|
||||||
+ sizeof(section)
|
+ (sizeof(section) * 2)
|
||||||
+ sizeof(symtab_command)
|
+ sizeof(symtab_command)
|
||||||
+ pad(size), // symoff
|
+ pad(size), // symoff
|
||||||
2, // nsyms
|
2, // nsyms
|
||||||
@ -96,7 +114,7 @@ writeObject(FILE* out, const uint8_t* data, unsigned size,
|
|||||||
+ sizeof(symtab_command)
|
+ sizeof(symtab_command)
|
||||||
+ pad(size)
|
+ pad(size)
|
||||||
+ (sizeof(struct nlist) * 2), // stroff
|
+ (sizeof(struct nlist) * 2), // stroff
|
||||||
1 + dataNameLength + sizeNameLength, // strsize
|
1 + startNameLength + endNameLength, // strsize
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nlist symbolList[] = {
|
struct nlist symbolList[] = {
|
||||||
@ -108,17 +126,18 @@ writeObject(FILE* out, const uint8_t* data, unsigned size,
|
|||||||
0 // n_value
|
0 // n_value
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
reinterpret_cast<char*>(1 + dataNameLength), // n_un
|
reinterpret_cast<char*>(1 + startNameLength), // n_un
|
||||||
N_ABS | N_EXT, // n_type
|
N_SECT | N_EXT, // n_type
|
||||||
NO_SECT, // n_sect
|
2, // n_sect
|
||||||
0, // n_desc
|
0, // n_desc
|
||||||
size // n_value
|
0 // n_value
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fwrite(&header, 1, sizeof(header), out);
|
fwrite(&header, 1, sizeof(header), out);
|
||||||
fwrite(&segment, 1, sizeof(segment), out);
|
fwrite(&segment, 1, sizeof(segment), out);
|
||||||
fwrite(§, 1, sizeof(sect), out);
|
fwrite(§1, 1, sizeof(sect1), out);
|
||||||
|
fwrite(§2, 1, sizeof(sect2), out);
|
||||||
fwrite(&symbolTable, 1, sizeof(symbolTable), out);
|
fwrite(&symbolTable, 1, sizeof(symbolTable), out);
|
||||||
|
|
||||||
fwrite(data, 1, size, out);
|
fwrite(data, 1, size, out);
|
||||||
@ -127,8 +146,8 @@ writeObject(FILE* out, const uint8_t* data, unsigned size,
|
|||||||
fwrite(&symbolList, 1, sizeof(symbolList), out);
|
fwrite(&symbolList, 1, sizeof(symbolList), out);
|
||||||
|
|
||||||
fputc(0, out);
|
fputc(0, out);
|
||||||
fwrite(dataName, 1, dataNameLength, out);
|
fwrite(startName, 1, startNameLength, out);
|
||||||
fwrite(sizeName, 1, sizeNameLength, out);
|
fwrite(endName, 1, endNameLength, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -138,7 +157,7 @@ main(int argc, const char** argv)
|
|||||||
{
|
{
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s <input file> <data symbol name> <size symbol name>\n",
|
"usage: %s <input file> <start symbol name> <end symbol name>\n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
29
src/boot.cpp
Normal file
29
src/boot.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "stdint.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
// since we don't link against libstdc++, we must implement some dummy
|
||||||
|
// functions:
|
||||||
|
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
||||||
|
void operator delete(void*) { abort(); }
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
# define EXPORT __declspec(dllexport)
|
||||||
|
# define SYMBOL(x) binary_classpath_jar_##x
|
||||||
|
#else
|
||||||
|
# define EXPORT __attribute__ ((visibility("default")))
|
||||||
|
# define SYMBOL(x) _binary_classpath_jar_##x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
extern const uint8_t SYMBOL(start)[];
|
||||||
|
extern const uint8_t SYMBOL(end)[];
|
||||||
|
|
||||||
|
EXPORT const uint8_t*
|
||||||
|
classpathJar(unsigned* size)
|
||||||
|
{
|
||||||
|
*size = SYMBOL(end) - SYMBOL(start);
|
||||||
|
return SYMBOL(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -440,14 +440,15 @@ class JarElement: public Element {
|
|||||||
|
|
||||||
class BuiltinElement: public JarElement {
|
class BuiltinElement: public JarElement {
|
||||||
public:
|
public:
|
||||||
BuiltinElement(System* s, const char* name, unsigned nameLength):
|
BuiltinElement(System* s, const char* name, unsigned nameLength,
|
||||||
JarElement(s, name, nameLength)
|
const char* libraryName):
|
||||||
|
JarElement(s, name, nameLength),
|
||||||
|
libraryName(libraryName)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
System::Library* library;
|
if (s->success(s->load(&library, libraryName, true))) {
|
||||||
if (s->success(s->load(&library, 0, false))) {
|
|
||||||
void* p = library->resolve(name);
|
void* p = library->resolve(name);
|
||||||
if (p) {
|
if (p) {
|
||||||
uint8_t* (*function)(unsigned*);
|
uint8_t* (*function)(unsigned*);
|
||||||
@ -461,14 +462,21 @@ class BuiltinElement: public JarElement {
|
|||||||
index = JarIndex::open(s, region);
|
index = JarIndex::open(s, region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void dispose() {
|
||||||
|
JarElement::dispose();
|
||||||
library->disposeAll();
|
library->disposeAll();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
System::Library* library;
|
||||||
|
const char* libraryName;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element*
|
Element*
|
||||||
parsePath(System* s, const char* path)
|
parsePath(System* s, const char* path, const char* bootLibrary)
|
||||||
{
|
{
|
||||||
class Tokenizer {
|
class Tokenizer {
|
||||||
public:
|
public:
|
||||||
@ -509,7 +517,7 @@ parsePath(System* s, const char* path)
|
|||||||
name[token.length - 2] = 0;
|
name[token.length - 2] = 0;
|
||||||
|
|
||||||
e = new (allocate(s, sizeof(BuiltinElement)))
|
e = new (allocate(s, sizeof(BuiltinElement)))
|
||||||
BuiltinElement(s, name, token.length - 2);
|
BuiltinElement(s, name, token.length - 2, bootLibrary);
|
||||||
} else {
|
} else {
|
||||||
char* name = static_cast<char*>(allocate(s, token.length + 1));
|
char* name = static_cast<char*>(allocate(s, token.length + 1));
|
||||||
memcpy(name, token.s, token.length);
|
memcpy(name, token.s, token.length);
|
||||||
@ -548,9 +556,9 @@ parsePath(System* s, const char* path)
|
|||||||
|
|
||||||
class MyFinder: public Finder {
|
class MyFinder: public Finder {
|
||||||
public:
|
public:
|
||||||
MyFinder(System* system, const char* path):
|
MyFinder(System* system, const char* path, const char* bootLibrary):
|
||||||
system(system),
|
system(system),
|
||||||
path_(parsePath(system, path)),
|
path_(parsePath(system, path, bootLibrary)),
|
||||||
pathString(copy(system, &pathStringLength, path))
|
pathString(copy(system, &pathStringLength, path))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -600,9 +608,9 @@ class MyFinder: public Finder {
|
|||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
Finder*
|
Finder*
|
||||||
makeFinder(System* s, const char* path)
|
makeFinder(System* s, const char* path, const char* bootLibrary)
|
||||||
{
|
{
|
||||||
return new (allocate(s, sizeof(MyFinder))) MyFinder(s, path);
|
return new (allocate(s, sizeof(MyFinder))) MyFinder(s, path, bootLibrary);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -27,7 +27,7 @@ class Finder {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Finder*
|
Finder*
|
||||||
makeFinder(System* s, const char* path);
|
makeFinder(System* s, const char* path, const char* bootLibrary);
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
|
||||||
|
@ -1986,28 +1986,38 @@ JNI_GetDefaultJavaVMInitArgs(void* args)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BUILTINS_PROPERTY "vm.builtins"
|
#define BUILTINS_PROPERTY "avian.builtins"
|
||||||
|
#define BOOTSTRAP_PROPERTY "avian.bootstrap"
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
||||||
{
|
{
|
||||||
JDK1_1InitArgs* a = static_cast<JDK1_1InitArgs*>(args);
|
JDK1_1InitArgs* a = static_cast<JDK1_1InitArgs*>(args);
|
||||||
|
|
||||||
System* s = makeSystem();
|
const char* builtins = 0;
|
||||||
Heap* h = makeHeap(s, a->maxHeapSize);
|
const char* bootLibrary = 0;
|
||||||
Finder* f = makeFinder(s, a->classpath);
|
|
||||||
Processor* p = makeProcessor(s, h);
|
|
||||||
|
|
||||||
*m = new (h->allocate(sizeof(Machine), false)) Machine(s, h, f, p);
|
|
||||||
|
|
||||||
if (a->properties) {
|
if (a->properties) {
|
||||||
for (const char** p = a->properties; *p; ++p) {
|
for (const char** p = a->properties; *p; ++p) {
|
||||||
if (strncmp(*p, BUILTINS_PROPERTY "=", sizeof(BUILTINS_PROPERTY)) == 0) {
|
if (strncmp(*p, BUILTINS_PROPERTY "=",
|
||||||
(*m)->builtins = (*p) + sizeof(BUILTINS_PROPERTY);
|
sizeof(BUILTINS_PROPERTY)) == 0)
|
||||||
|
{
|
||||||
|
builtins = (*p) + sizeof(BUILTINS_PROPERTY);
|
||||||
|
} else if (strncmp(*p, BOOTSTRAP_PROPERTY "=",
|
||||||
|
sizeof(BOOTSTRAP_PROPERTY)) == 0)
|
||||||
|
{
|
||||||
|
bootLibrary = (*p) + sizeof(BOOTSTRAP_PROPERTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System* s = makeSystem();
|
||||||
|
Heap* h = makeHeap(s, a->maxHeapSize);
|
||||||
|
Finder* f = makeFinder(s, a->classpath, bootLibrary);
|
||||||
|
Processor* p = makeProcessor(s, h);
|
||||||
|
|
||||||
|
*m = new (h->allocate(sizeof(Machine), false))
|
||||||
|
Machine(s, h, f, p, bootLibrary, builtins);
|
||||||
|
|
||||||
*t = p->makeThread(*m, 0, 0);
|
*t = p->makeThread(*m, 0, 0);
|
||||||
|
|
||||||
enter(*t, Thread::ActiveState);
|
enter(*t, Thread::ActiveState);
|
||||||
|
@ -1644,7 +1644,8 @@ class HeapClient: public Heap::Client {
|
|||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
Machine::Machine(System* system, Heap* heap, Finder* finder,
|
Machine::Machine(System* system, Heap* heap, Finder* finder,
|
||||||
Processor* processor):
|
Processor* processor, const char* bootLibrary,
|
||||||
|
const char* builtins):
|
||||||
vtable(&javaVMVTable),
|
vtable(&javaVMVTable),
|
||||||
system(system),
|
system(system),
|
||||||
heapClient(new (heap->allocate(sizeof(HeapClient), false))
|
heapClient(new (heap->allocate(sizeof(HeapClient), false))
|
||||||
@ -1655,7 +1656,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
|
|||||||
rootThread(0),
|
rootThread(0),
|
||||||
exclusive(0),
|
exclusive(0),
|
||||||
jniReferences(0),
|
jniReferences(0),
|
||||||
builtins(0),
|
builtins(builtins),
|
||||||
activeCount(0),
|
activeCount(0),
|
||||||
liveCount(0),
|
liveCount(0),
|
||||||
fixedFootprint(0),
|
fixedFootprint(0),
|
||||||
@ -1688,7 +1689,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
|
|||||||
not system->success(system->make(&heapLock)) or
|
not system->success(system->make(&heapLock)) or
|
||||||
not system->success(system->make(&classLock)) or
|
not system->success(system->make(&classLock)) or
|
||||||
not system->success(system->make(&referenceLock)) or
|
not system->success(system->make(&referenceLock)) or
|
||||||
not system->success(system->load(&libraries, 0, false)))
|
not system->success(system->load(&libraries, bootLibrary, true)))
|
||||||
{
|
{
|
||||||
system->abort();
|
system->abort();
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1121,8 @@ class Machine {
|
|||||||
ImmortalAllocation
|
ImmortalAllocation
|
||||||
};
|
};
|
||||||
|
|
||||||
Machine(System* system, Heap* heap, Finder* finder, Processor* processor);
|
Machine(System* system, Heap* heap, Finder* finder, Processor* processor,
|
||||||
|
const char* bootLibrary, const char* builtins);
|
||||||
|
|
||||||
~Machine() {
|
~Machine() {
|
||||||
dispose();
|
dispose();
|
||||||
|
40
src/main.cpp
40
src/main.cpp
@ -14,37 +14,12 @@
|
|||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
// since we don't link against libstdc++, we must implement some dummy
|
|
||||||
// functions:
|
|
||||||
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
|
||||||
void operator delete(void*) { abort(); }
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
# define PATH_SEPARATOR ';'
|
# define PATH_SEPARATOR ';'
|
||||||
# define EXPORT __declspec(dllexport)
|
|
||||||
# define SYMBOL(x) binary_classpath_jar_##x
|
|
||||||
#else
|
#else
|
||||||
# define PATH_SEPARATOR ':'
|
# define PATH_SEPARATOR ':'
|
||||||
# define EXPORT __attribute__ ((visibility("default")))
|
|
||||||
# define SYMBOL(x) _binary_classpath_jar_##x
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BOOT_CLASSPATH "[classpathJar]"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
extern const uint8_t SYMBOL(start)[];
|
|
||||||
extern const uint8_t SYMBOL(size)[];
|
|
||||||
|
|
||||||
EXPORT const uint8_t*
|
|
||||||
classpathJar(unsigned* size)
|
|
||||||
{
|
|
||||||
*size = reinterpret_cast<uintptr_t>(SYMBOL(size));
|
|
||||||
return SYMBOL(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef JNI_VERSION_1_6
|
#ifdef JNI_VERSION_1_6
|
||||||
// todo: use JavaVMInitArgs instead
|
// todo: use JavaVMInitArgs instead
|
||||||
typedef struct JDK1_1InitArgs {
|
typedef struct JDK1_1InitArgs {
|
||||||
@ -121,14 +96,25 @@ main(int ac, const char** av)
|
|||||||
vmArgs.classpath = classpath;
|
vmArgs.classpath = classpath;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* properties[propertyCount + 1];
|
#ifdef BOOT_LIBRARY
|
||||||
properties[propertyCount] = 0;
|
const int BootPropertyCount = 1;
|
||||||
|
#else
|
||||||
|
const int BootPropertyCount = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* properties[propertyCount + BootPropertyCount + 1];
|
||||||
|
properties[propertyCount + BootPropertyCount] = 0;
|
||||||
for (int i = 1; i < ac; ++i) {
|
for (int i = 1; i < ac; ++i) {
|
||||||
if (strncmp(av[i], "-D", 2) == 0) {
|
if (strncmp(av[i], "-D", 2) == 0) {
|
||||||
properties[--propertyCount] = av[i] + 2;
|
properties[--propertyCount] = av[i] + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOT_LIBRARY
|
||||||
|
properties[propertyCount + BootPropertyCount - 1]
|
||||||
|
= "avian.bootstrap=" BOOT_LIBRARY;
|
||||||
|
#endif
|
||||||
|
|
||||||
vmArgs.properties = const_cast<char**>(properties);
|
vmArgs.properties = const_cast<char**>(properties);
|
||||||
|
|
||||||
if (class_ == 0) {
|
if (class_ == 0) {
|
||||||
|
@ -687,18 +687,18 @@ class MySystem: public System {
|
|||||||
bool alreadyAllocated = false;
|
bool alreadyAllocated = false;
|
||||||
bool isMain = false;
|
bool isMain = false;
|
||||||
unsigned nameLength = (name ? strlen(name) : 0);
|
unsigned nameLength = (name ? strlen(name) : 0);
|
||||||
if (mapName) {
|
if (mapName and name) {
|
||||||
unsigned size = nameLength + 3 + sizeof(SO_SUFFIX);
|
unsigned size = nameLength + 3 + sizeof(SO_SUFFIX);
|
||||||
char buffer[size];
|
char buffer[size];
|
||||||
snprintf(buffer, size, "lib%s" SO_SUFFIX, name);
|
snprintf(buffer, size, "lib%s" SO_SUFFIX, name);
|
||||||
p = dlopen(buffer, RTLD_LAZY);
|
p = dlopen(buffer, RTLD_LAZY | RTLD_LOCAL);
|
||||||
} else {
|
} else {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
pathOfExecutable(this, &name, &nameLength);
|
pathOfExecutable(this, &name, &nameLength);
|
||||||
alreadyAllocated = true;
|
alreadyAllocated = true;
|
||||||
isMain = true;
|
isMain = true;
|
||||||
}
|
}
|
||||||
p = dlopen(name, RTLD_LAZY);
|
p = dlopen(name, RTLD_LAZY | RTLD_LOCAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
|
@ -623,7 +623,7 @@ class MySystem: public System {
|
|||||||
{
|
{
|
||||||
HMODULE handle;
|
HMODULE handle;
|
||||||
unsigned nameLength = (name ? strlen(name) : 0);
|
unsigned nameLength = (name ? strlen(name) : 0);
|
||||||
if (mapName) {
|
if (mapName and name) {
|
||||||
unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX);
|
unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX);
|
||||||
char buffer[size];
|
char buffer[size];
|
||||||
snprintf(buffer, size, SO_PREFIX "%s" SO_SUFFIX, name);
|
snprintf(buffer, size, SO_PREFIX "%s" SO_SUFFIX, name);
|
||||||
|
Loading…
Reference in New Issue
Block a user