mirror of
https://github.com/corda/corda.git
synced 2025-01-01 02:36:44 +00:00
rework OpenJDK build to derive classpath and library path from environment
We now consult the JAVA_HOME environment variable to determine where to find the system library JARs and SOs. Ultimately, we'll want to support self-contained build, but this allows Avian to behave like a conventional libjvm.so.
This commit is contained in:
parent
88942a9672
commit
17f495eb27
86
makefile
86
makefile
@ -40,26 +40,20 @@ ifeq ($(continuations),true)
|
||||
options := $(options)-continuations
|
||||
endif
|
||||
|
||||
root := $(shell (cd .. && pwd))
|
||||
build = build/$(platform)-$(arch)$(options)
|
||||
classpath-build = $(build)/classpath
|
||||
test-build = $(build)/test
|
||||
src = src
|
||||
classpath-src = classpath
|
||||
test = test
|
||||
|
||||
classpath = avian
|
||||
|
||||
test-library-path = .
|
||||
test-executable = $(executable)
|
||||
generator-classpath = $(classpath-build)
|
||||
boot-classpath = $(classpath-build)
|
||||
|
||||
ifdef gnu
|
||||
classpath = gnu
|
||||
options := $(options)-gnu
|
||||
classapth-jar = $(gnu)/share/classpath/glibj.zip
|
||||
classpath-libraries = \
|
||||
$(gnu)/lib/classpath/libjavaio.a \
|
||||
$(gnu)/lib/classpath/libjavalang.a \
|
||||
$(gnu)/lib/classpath/libjavalangreflect.a \
|
||||
$(gnu)/lib/classpath/libjavamath.a \
|
||||
$(gnu)/lib/classpath/libjavanet.a \
|
||||
$(gnu)/lib/classpath/libjavanio.a \
|
||||
$(gnu)/lib/classpath/libjavautil.a
|
||||
classpath-cflags = -DBOOT_BUILTINS=\"javaio,javalang,javalangreflect,javamath,javanet,javanio,javautil\" -DAVIAN_GNU
|
||||
classpath-lflags = -lgmp
|
||||
endif
|
||||
ifdef openjdk
|
||||
classpath = openjdk
|
||||
options := $(options)-openjdk
|
||||
@ -68,19 +62,12 @@ ifdef openjdk
|
||||
else
|
||||
openjdk-lib-dir = $(openjdk)/jre/lib
|
||||
endif
|
||||
classpath-jar = $(openjdk)/jre/lib/rt.jar
|
||||
test-library-path = $(openjdk-lib-dir):$(build)
|
||||
classpath-cflags = -DAVIAN_OPENJDK_JAVA_HOME=\"$(openjdk)\"
|
||||
test-executable = $(executable-dynamic)
|
||||
generator-classpath := $(generator-classpath):$(openjdk)/jre/lib/rt.jar
|
||||
boot-classpath := $(boot-classpath):$(openjdk)/jre/lib/rt.jar
|
||||
endif
|
||||
|
||||
root := $(shell (cd .. && pwd))
|
||||
build = build/$(platform)-$(arch)$(options)
|
||||
classpath-build = $(build)/classpath
|
||||
test-build = $(build)/test
|
||||
src = src
|
||||
classpath-src = classpath
|
||||
test = test
|
||||
|
||||
ifneq ($(classpath),avian)
|
||||
classpath-object-dep = $(build)/classpath-object.dep
|
||||
classpath-objects = $(shell find $(build)/classpath-objects -name "*.o")
|
||||
@ -138,7 +125,7 @@ cflags = $(build-cflags)
|
||||
|
||||
common-lflags = -lm -lz $(classpath-lflags)
|
||||
|
||||
build-lflags =
|
||||
build-lflags = -lz -lpthread -ldl
|
||||
|
||||
lflags = $(common-lflags) -lpthread -ldl
|
||||
|
||||
@ -401,10 +388,15 @@ driver-dynamic-object = $(build)/main-dynamic.o
|
||||
boot-source = $(src)/boot.cpp
|
||||
boot-object = $(build)/boot.o
|
||||
|
||||
generator-headers = $(src)/constants.h
|
||||
generator-sources = $(src)/type-generator.cpp
|
||||
generator-depends := $(wildcard $(src)/*.h)
|
||||
generator-sources = \
|
||||
$(src)/type-generator.cpp \
|
||||
$(src)/$(system).cpp \
|
||||
$(src)/finder.cpp
|
||||
generator-cpp-objects = \
|
||||
$(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x)))
|
||||
generator-objects = \
|
||||
$(call cpp-objects,$(generator-sources),$(src),$(build))
|
||||
$(call generator-cpp-objects,$(generator-sources),$(src),$(build))
|
||||
generator = $(build)/generator
|
||||
|
||||
converter-objects = \
|
||||
@ -467,9 +459,9 @@ test-extra-dep = $(test-build)-extra.dep
|
||||
class-name = $(patsubst $(1)/%.class,%,$(2))
|
||||
class-names = $(foreach x,$(2),$(call class-name,$(1),$(x)))
|
||||
|
||||
flags = -cp $(test-build)
|
||||
test-flags = -cp $(build)/test
|
||||
|
||||
args = $(flags) $(input)
|
||||
test-args = $(test-flags) $(input)
|
||||
|
||||
.PHONY: build
|
||||
build: $(static-library) $(executable) $(dynamic-library) \
|
||||
@ -481,20 +473,20 @@ $(test-extra-dep): $(classpath-dep)
|
||||
|
||||
.PHONY: run
|
||||
run: build
|
||||
$(executable) $(args)
|
||||
LD_LIBRARY_PATH=$(build) $(test-executable) $(test-args)
|
||||
|
||||
.PHONY: debug
|
||||
debug: build
|
||||
gdb --args $(executable) $(args)
|
||||
LD_LIBRARY_PATH=$(build) gdb --args $(test-executable) $(test-args)
|
||||
|
||||
.PHONY: vg
|
||||
vg: build
|
||||
$(vg) $(executable) $(args)
|
||||
LD_LIBRARY_PATH=$(build) $(vg) $(test-executable) $(test-args)
|
||||
|
||||
.PHONY: test
|
||||
test: build
|
||||
/bin/sh $(test)/test.sh 2>/dev/null \
|
||||
$(test-library-path) $(test-executable) $(mode) "$(flags)" \
|
||||
$(build) $(test-executable) $(mode) "$(test-flags)" \
|
||||
$(call class-names,$(test-build),$(test-classes))
|
||||
|
||||
.PHONY: tarball
|
||||
@ -523,24 +515,15 @@ gen-arg = $(shell echo $(1) | sed -e 's:$(build)/type-\(.*\)\.cpp:\1:')
|
||||
$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
|
||||
@echo "generating $(@)"
|
||||
@mkdir -p $(dir $(@))
|
||||
$(generator) $(classpath-build) $(call gen-arg,$(@)) < $(<) > $(@)
|
||||
|
||||
$(build)/type-generator.o: \
|
||||
$(generator-headers)
|
||||
$(generator) $(generator-classpath) $(<) $(@) $(call gen-arg,$(@))
|
||||
|
||||
$(classpath-build)/%.class: $(classpath-src)/%.java
|
||||
@echo $(<)
|
||||
|
||||
$(classpath-dep): $(classpath-sources) $(classpath-jar)
|
||||
$(classpath-dep): $(classpath-sources)
|
||||
@echo "compiling classpath classes"
|
||||
@mkdir -p $(classpath-build)
|
||||
ifneq ($(classpath),avian)
|
||||
(wd=$$(pwd) && \
|
||||
cd $(classpath-build) && \
|
||||
$(jar) xf $(classpath-jar))
|
||||
endif
|
||||
$(javac) -d $(classpath-build) \
|
||||
-bootclasspath $(classpath-build) \
|
||||
$(javac) -d $(classpath-build) -bootclasspath $(boot-classpath) \
|
||||
$(shell $(MAKE) -s --no-print-directory build=$(build) \
|
||||
$(classpath-classes))
|
||||
@touch $(@)
|
||||
@ -553,7 +536,7 @@ $(test-dep): $(test-sources)
|
||||
@mkdir -p $(test-build)
|
||||
files="$(shell $(MAKE) -s --no-print-directory build=$(build) $(test-classes))"; \
|
||||
if test -n "$${files}"; then \
|
||||
$(javac) -d $(test-build) -bootclasspath $(classpath-build) $${files}; \
|
||||
$(javac) -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \
|
||||
fi
|
||||
$(javac) -source 1.2 -target 1.1 -XDjsrlimit=0 -d $(test-build) \
|
||||
test/Subroutine.java
|
||||
@ -564,7 +547,7 @@ $(test-extra-dep): $(test-extra-sources)
|
||||
@mkdir -p $(test-build)
|
||||
files="$(shell $(MAKE) -s --no-print-directory build=$(build) $(test-extra-classes))"; \
|
||||
if test -n "$${files}"; then \
|
||||
$(javac) -d $(test-build) -bootclasspath $(classpath-build) $${files}; \
|
||||
$(javac) -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \
|
||||
fi
|
||||
@touch $(@)
|
||||
|
||||
@ -635,7 +618,8 @@ $(classpath-object): $(build)/classpath.jar $(converter)
|
||||
$(converter) $(<) $(@) _binary_classpath_jar_start \
|
||||
_binary_classpath_jar_end $(platform) $(arch)
|
||||
|
||||
$(generator-objects): $(build)/%.o: $(src)/%.cpp
|
||||
$(generator-objects): $(generator-depends)
|
||||
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
|
||||
@echo "compiling $(@)"
|
||||
@mkdir -p $(dir $(@))
|
||||
$(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \
|
||||
|
@ -92,6 +92,12 @@ class MyClasspath : public Classpath {
|
||||
// ignore
|
||||
}
|
||||
|
||||
virtual const char*
|
||||
bootClasspath()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
virtual void
|
||||
dispose()
|
||||
{
|
||||
@ -473,7 +479,7 @@ Avian_java_lang_Runtime_load
|
||||
RUNTIME_ARRAY(char, n, length + 1);
|
||||
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
||||
|
||||
loadLibrary(t, RUNTIME_ARRAY_BODY(n), mapName, true);
|
||||
loadLibrary(t, "", RUNTIME_ARRAY_BODY(n), mapName, true);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
@ -11,9 +11,11 @@
|
||||
#ifndef CLASSPATH_COMMON_H
|
||||
#define CLASSPATH_COMMON_H
|
||||
|
||||
#include "tokenizer.h"
|
||||
|
||||
namespace vm {
|
||||
|
||||
inline object
|
||||
object
|
||||
getCaller(Thread* t, unsigned target)
|
||||
{
|
||||
class Visitor: public Processor::StackVisitor {
|
||||
@ -43,7 +45,7 @@ getCaller(Thread* t, unsigned target)
|
||||
return v.method;
|
||||
}
|
||||
|
||||
inline object
|
||||
object
|
||||
getTrace(Thread* t, unsigned skipCount)
|
||||
{
|
||||
class Visitor: public Processor::StackVisitor {
|
||||
@ -84,7 +86,7 @@ getTrace(Thread* t, unsigned skipCount)
|
||||
return v.trace;
|
||||
}
|
||||
|
||||
inline bool
|
||||
bool
|
||||
compatibleArrayTypes(Thread* t, object a, object b)
|
||||
{
|
||||
return classArrayElementSize(t, a)
|
||||
@ -94,7 +96,7 @@ compatibleArrayTypes(Thread* t, object a, object b)
|
||||
or (classVmFlags(t, b) & PrimitiveFlag))));
|
||||
}
|
||||
|
||||
inline void
|
||||
void
|
||||
arrayCopy(Thread* t, object src, int32_t srcOffset, object dst,
|
||||
int32_t dstOffset, int32_t length)
|
||||
{
|
||||
@ -160,37 +162,13 @@ runOnLoadIfFound(Thread* t, System::Library* library)
|
||||
}
|
||||
|
||||
System::Library*
|
||||
loadLibrary(Thread* t, const char* name, bool mapName, bool runOnLoad)
|
||||
loadLibrary(Thread* t, const char* name)
|
||||
{
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
const char* builtins = findProperty(t, "avian.builtins");
|
||||
if (mapName and builtins) {
|
||||
const char* s = builtins;
|
||||
while (*s) {
|
||||
unsigned length = strlen(name);
|
||||
if (::strncmp(s, name, length) == 0
|
||||
and (s[length] == ',' or s[length] == 0))
|
||||
{
|
||||
// library is built in to this executable
|
||||
if (runOnLoad and not t->m->triedBuiltinOnLoad) {
|
||||
t->m->triedBuiltinOnLoad = true;
|
||||
runOnLoadIfFound(t, t->m->libraries);
|
||||
}
|
||||
return t->m->libraries;
|
||||
} else {
|
||||
while (*s and *s != ',') ++ s;
|
||||
if (*s) ++ s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System::Library* last = t->m->libraries;
|
||||
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
|
||||
if (lib->name()
|
||||
and ::strcmp(lib->name(), name) == 0
|
||||
and lib->mapName() == mapName)
|
||||
{
|
||||
if (lib->name() and ::strcmp(lib->name(), name) == 0) {
|
||||
// already loaded
|
||||
return lib;
|
||||
}
|
||||
@ -198,18 +176,91 @@ loadLibrary(Thread* t, const char* name, bool mapName, bool runOnLoad)
|
||||
}
|
||||
|
||||
System::Library* lib;
|
||||
if (LIKELY(t->m->system->success(t->m->system->load(&lib, name, mapName)))) {
|
||||
if (LIKELY(t->m->system->success(t->m->system->load(&lib, name)))) {
|
||||
last->setNext(lib);
|
||||
return lib;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
System::Library*
|
||||
loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
|
||||
bool runOnLoad)
|
||||
{
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
unsigned nameLength = strlen(name);
|
||||
if (mapName) {
|
||||
const char* builtins = findProperty(t, "avian.builtins");
|
||||
if (builtins) {
|
||||
const char* s = builtins;
|
||||
while (*s) {
|
||||
if (::strncmp(s, name, nameLength) == 0
|
||||
and (s[nameLength] == ',' or s[nameLength] == 0))
|
||||
{
|
||||
// library is built in to this executable
|
||||
if (runOnLoad and not t->m->triedBuiltinOnLoad) {
|
||||
t->m->triedBuiltinOnLoad = true;
|
||||
runOnLoadIfFound(t, t->m->libraries);
|
||||
}
|
||||
return t->m->libraries;
|
||||
} else {
|
||||
while (*s and *s != ',') ++ s;
|
||||
if (*s) ++ s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* prefix = t->m->system->libraryPrefix();
|
||||
const char* suffix = t->m->system->librarySuffix();
|
||||
unsigned mappedNameLength = nameLength + strlen(prefix) + strlen(suffix);
|
||||
|
||||
char* mappedName = static_cast<char*>
|
||||
(t->m->heap->allocate(mappedNameLength + 1));
|
||||
|
||||
snprintf(mappedName, mappedNameLength + 1, "%s%s%s", prefix, name, suffix);
|
||||
|
||||
name = mappedName;
|
||||
nameLength = mappedNameLength;
|
||||
}
|
||||
|
||||
System::Library* lib = 0;
|
||||
for (Tokenizer tokenizer(path, t->m->system->pathSeparator());
|
||||
tokenizer.hasMore();)
|
||||
{
|
||||
Tokenizer::Token token(tokenizer.next());
|
||||
|
||||
unsigned fullNameLength = token.length + 1 + nameLength;
|
||||
RUNTIME_ARRAY(char, fullName, fullNameLength + 1);
|
||||
|
||||
snprintf(RUNTIME_ARRAY_BODY(fullName), fullNameLength + 1,
|
||||
"%*s%c%s", token.length, token.s, t->m->system->fileSeparator(),
|
||||
name);
|
||||
|
||||
lib = loadLibrary(t, RUNTIME_ARRAY_BODY(fullName));
|
||||
if (lib) break;
|
||||
}
|
||||
|
||||
if (lib == 0) {
|
||||
lib = loadLibrary(t, name);
|
||||
}
|
||||
|
||||
if (lib) {
|
||||
if (runOnLoad) {
|
||||
runOnLoadIfFound(t, lib);
|
||||
}
|
||||
return lib;
|
||||
} else {
|
||||
} else {
|
||||
object message = makeString(t, "library not found: %s", name);
|
||||
t->exception = t->m->classpath->makeThrowable
|
||||
(t, Machine::UnsatisfiedLinkErrorType, message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mapName) {
|
||||
t->m->heap->free(name, nameLength + 1);
|
||||
}
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
||||
object
|
||||
|
@ -139,9 +139,73 @@ makeClassNameString(Thread* t, object name)
|
||||
|
||||
class MyClasspath : public Classpath {
|
||||
public:
|
||||
MyClasspath(Allocator* allocator):
|
||||
static const unsigned BufferSize = 256;
|
||||
|
||||
MyClasspath(System* s, Allocator* allocator):
|
||||
allocator(allocator)
|
||||
{ }
|
||||
{
|
||||
const char* javaHome = getenv("JAVA_HOME");
|
||||
if (javaHome == 0) {
|
||||
javaHome = AVIAN_OPENJDK_JAVA_HOME;
|
||||
}
|
||||
|
||||
class StringBuilder {
|
||||
public:
|
||||
StringBuilder(System* s, char* pointer, unsigned remaining):
|
||||
s(s), pointer(pointer), remaining(remaining)
|
||||
{ }
|
||||
|
||||
void append(const char* append) {
|
||||
unsigned length = strlen(append);
|
||||
assert(s, remaining > length);
|
||||
|
||||
strncpy(pointer, append, remaining);
|
||||
|
||||
remaining -= length;
|
||||
pointer += length;
|
||||
}
|
||||
|
||||
void append(char c) {
|
||||
assert(s, remaining > 1);
|
||||
|
||||
pointer[0] = c;
|
||||
pointer[1] = 0;
|
||||
|
||||
-- remaining;
|
||||
++ pointer;
|
||||
}
|
||||
|
||||
System* s;
|
||||
char* pointer;
|
||||
unsigned remaining;
|
||||
} sb(s, buffer, BufferSize);
|
||||
|
||||
this->javaHome = sb.pointer;
|
||||
sb.append(javaHome);
|
||||
sb.append('\0');
|
||||
|
||||
this->classpath = sb.pointer;
|
||||
sb.append(javaHome);
|
||||
sb.append("/jre/lib/rt.jar");
|
||||
sb.append(s->pathSeparator());
|
||||
sb.append(javaHome);
|
||||
sb.append("/jre/lib/jsse.jar");
|
||||
sb.append(s->pathSeparator());
|
||||
sb.append(javaHome);
|
||||
sb.append("/jre/lib/jce.jar");
|
||||
sb.append(s->pathSeparator());
|
||||
sb.append(javaHome);
|
||||
sb.append("/jre/lib/resources.jar");
|
||||
sb.append('\0');
|
||||
|
||||
this->libraryPath = sb.pointer;
|
||||
sb.append(javaHome);
|
||||
#ifdef ARCH_x86_64
|
||||
sb.append("/jre/lib/amd64");
|
||||
#else
|
||||
sb.append("/jre/lib");
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual object
|
||||
makeJclass(Thread* t, object class_)
|
||||
@ -232,7 +296,7 @@ class MyClasspath : public Classpath {
|
||||
{
|
||||
globalMachine = t->m;
|
||||
|
||||
if (loadLibrary(t, "java", true, true) == 0) {
|
||||
if (loadLibrary(t, libraryPath, "java", true, true) == 0) {
|
||||
abort(t);
|
||||
}
|
||||
|
||||
@ -271,6 +335,12 @@ class MyClasspath : public Classpath {
|
||||
fieldOffset(t, sclSet)) = true;
|
||||
}
|
||||
|
||||
virtual const char*
|
||||
bootClasspath()
|
||||
{
|
||||
return classpath;
|
||||
}
|
||||
|
||||
virtual void
|
||||
dispose()
|
||||
{
|
||||
@ -278,6 +348,10 @@ class MyClasspath : public Classpath {
|
||||
}
|
||||
|
||||
Allocator* allocator;
|
||||
const char* javaHome;
|
||||
const char* classpath;
|
||||
const char* libraryPath;
|
||||
char buffer[BufferSize];
|
||||
};
|
||||
|
||||
struct JVM_ExceptionTableEntryType{
|
||||
@ -560,10 +634,10 @@ interruptLock(Thread* t, object thread)
|
||||
namespace vm {
|
||||
|
||||
Classpath*
|
||||
makeClasspath(System*, Allocator* allocator)
|
||||
makeClasspath(System* s, Allocator* allocator)
|
||||
{
|
||||
return new (allocator->allocate(sizeof(local::MyClasspath)))
|
||||
local::MyClasspath(allocator);
|
||||
local::MyClasspath(s, allocator);
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
@ -1028,18 +1102,20 @@ JVM_InitProperties(Thread* t, jobject properties)
|
||||
local::setProperty(t, method, *properties, "os.name", "Linux");
|
||||
# endif
|
||||
local::setProperty(t, method, *properties, "java.io.tmpdir", "/tmp");
|
||||
local::setProperty(t, method, *properties, "java.home", "/tmp");
|
||||
local::setProperty(t, method, *properties, "user.home", getenv("HOME"));
|
||||
local::setProperty(t, method, *properties, "user.dir", getenv("PWD"));
|
||||
|
||||
// todo: set this to something sane:
|
||||
local::setProperty(t, method, *properties, "sun.boot.library.path",
|
||||
getenv("LD_LIBRARY_PATH"));
|
||||
|
||||
local::setProperty(t, method, *properties, "java.protocol.handler.pkgs",
|
||||
"avian");
|
||||
|
||||
#endif
|
||||
local::setProperty
|
||||
(t, method, *properties, "java.home",
|
||||
static_cast<local::MyClasspath*>(t->m->classpath)->javaHome);
|
||||
|
||||
local::setProperty
|
||||
(t, method, *properties, "sun.boot.library.path",
|
||||
static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath);
|
||||
|
||||
local::setProperty(t, method, *properties, "file.encoding", "ASCII");
|
||||
#ifdef ARCH_x86_32
|
||||
local::setProperty(t, method, *properties, "os.arch", "x86");
|
||||
@ -1132,7 +1208,9 @@ JVM_LoadLibrary(const char* name)
|
||||
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return loadLibrary(t, name, false, false);
|
||||
return loadLibrary
|
||||
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath, name,
|
||||
false, false);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "zlib-custom.h"
|
||||
#include "system.h"
|
||||
#include "tokenizer.h"
|
||||
#include "finder.h"
|
||||
|
||||
using namespace vm;
|
||||
@ -19,8 +20,7 @@ namespace {
|
||||
const bool DebugFind = false;
|
||||
|
||||
const char*
|
||||
append(System* s, const char* a, const char* b,
|
||||
const char* c)
|
||||
append(System* s, const char* a, const char* b, const char* c)
|
||||
{
|
||||
unsigned al = strlen(a);
|
||||
unsigned bl = strlen(b);
|
||||
@ -148,6 +148,9 @@ class DirectoryElement: public Element {
|
||||
}
|
||||
return region;
|
||||
} else {
|
||||
if (DebugFind) {
|
||||
fprintf(stderr, "%s not found in %s\n", name, this->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -493,8 +496,12 @@ class JarElement: public Element {
|
||||
while (*name == '/') name++;
|
||||
|
||||
System::Region* r = (index ? index->find(name, region->start()) : 0);
|
||||
if (DebugFind and r) {
|
||||
fprintf(stderr, "found %s in %s\n", name, this->name);
|
||||
if (DebugFind) {
|
||||
if (r) {
|
||||
fprintf(stderr, "found %s in %s\n", name, this->name);
|
||||
} else {
|
||||
fprintf(stderr, "%s not found in %s\n", name, this->name);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -533,7 +540,7 @@ class BuiltinElement: public JarElement {
|
||||
|
||||
virtual void init() {
|
||||
if (index == 0) {
|
||||
if (s->success(s->load(&library, libraryName, false))) {
|
||||
if (s->success(s->load(&library, libraryName))) {
|
||||
void* p = library->resolve(name);
|
||||
if (p) {
|
||||
uint8_t* (*function)(unsigned*);
|
||||
@ -564,33 +571,6 @@ class BuiltinElement: public JarElement {
|
||||
Element*
|
||||
parsePath(System* s, const char* path, const char* bootLibrary)
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
Element* first = 0;
|
||||
Element* prev = 0;
|
||||
for (Tokenizer t(path, s->pathSeparator()); t.hasMore();) {
|
||||
|
@ -2306,26 +2306,31 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
||||
|
||||
if (classpath == 0) classpath = ".";
|
||||
|
||||
System* s = makeSystem(crashDumpDirectory);
|
||||
Heap* h = makeHeap(s, heapLimit);
|
||||
Classpath* c = makeClasspath(s, h);
|
||||
const char* classpathBootClasspath = c->bootClasspath();
|
||||
|
||||
unsigned bcppl = strlen(bootClasspathPrepend);
|
||||
unsigned bcpl = strlen(bootClasspath);
|
||||
unsigned cbcpl = strlen(classpathBootClasspath);
|
||||
unsigned bcpal = strlen(bootClasspathAppend);
|
||||
|
||||
unsigned bootClasspathBufferSize = bcppl + bcpl + bcpal + 3;
|
||||
unsigned bootClasspathBufferSize = bcppl + bcpl + cbcpl + bcpal + 3;
|
||||
RUNTIME_ARRAY(char, bootClasspathBuffer, bootClasspathBufferSize);
|
||||
char* bootClasspathPointer = RUNTIME_ARRAY_BODY(bootClasspathBuffer);
|
||||
local::append
|
||||
(&bootClasspathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR);
|
||||
local::append(&bootClasspathPointer, bootClasspathPrepend, bcppl,
|
||||
bcpl + cbcpl + bcpal ? PATH_SEPARATOR : 0);
|
||||
local::append(&bootClasspathPointer, bootClasspath, bcpl,
|
||||
cbcpl + bcpal ? PATH_SEPARATOR : 0);
|
||||
local::append(&bootClasspathPointer, classpathBootClasspath, cbcpl,
|
||||
bcpal ? PATH_SEPARATOR : 0);
|
||||
local::append(&bootClasspathPointer, bootClasspathAppend, bcpal, 0);
|
||||
|
||||
System* s = makeSystem(crashDumpDirectory);
|
||||
Heap* h = makeHeap(s, heapLimit);
|
||||
Finder* bf = makeFinder
|
||||
(s, RUNTIME_ARRAY_BODY(bootClasspathBuffer), bootLibrary);
|
||||
Finder* af = makeFinder(s, classpath, bootLibrary);
|
||||
Processor* p = makeProcessor(s, h, true);
|
||||
Classpath* c = makeClasspath(s, h);
|
||||
|
||||
const char** properties = static_cast<const char**>
|
||||
(h->allocate(sizeof(const char*) * propertyCount));
|
||||
|
@ -2166,7 +2166,7 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
|
||||
not system->success(system->make(&referenceLock)) or
|
||||
not system->success(system->make(&shutdownLock)) or
|
||||
not system->success
|
||||
(system->load(&libraries, findProperty(this, "avian.bootstrap"), false)))
|
||||
(system->load(&libraries, findProperty(this, "avian.bootstrap"))))
|
||||
{
|
||||
system->abort();
|
||||
}
|
||||
|
@ -1432,6 +1432,9 @@ class Classpath {
|
||||
virtual void
|
||||
boot(Thread* t) = 0;
|
||||
|
||||
virtual const char*
|
||||
bootClasspath() = 0;
|
||||
|
||||
virtual void
|
||||
dispose() = 0;
|
||||
};
|
||||
|
@ -469,13 +469,12 @@ class MySystem: public System {
|
||||
class Library: public System::Library {
|
||||
public:
|
||||
Library(System* s, void* p, const char* name, unsigned nameLength,
|
||||
bool mapName, bool isMain):
|
||||
bool isMain):
|
||||
s(s),
|
||||
p(p),
|
||||
mainExecutable(isMain),
|
||||
name_(name),
|
||||
nameLength(nameLength),
|
||||
mapName_(mapName),
|
||||
next_(0)
|
||||
{ }
|
||||
|
||||
@ -487,10 +486,6 @@ class MySystem: public System {
|
||||
return name_;
|
||||
}
|
||||
|
||||
virtual bool mapName() {
|
||||
return mapName_;
|
||||
}
|
||||
|
||||
virtual System::Library* next() {
|
||||
return next_;
|
||||
}
|
||||
@ -504,7 +499,7 @@ class MySystem: public System {
|
||||
fprintf(stderr, "close %p\n", p);
|
||||
}
|
||||
|
||||
if (!mainExecutable) dlclose(p);
|
||||
if (not mainExecutable) dlclose(p);
|
||||
|
||||
if (next_) {
|
||||
next_->disposeAll();
|
||||
@ -522,7 +517,6 @@ class MySystem: public System {
|
||||
bool mainExecutable;
|
||||
const char* name_;
|
||||
unsigned nameLength;
|
||||
bool mapName_;
|
||||
System::Library* next_;
|
||||
};
|
||||
|
||||
@ -716,27 +710,23 @@ class MySystem: public System {
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char* libraryPrefix() {
|
||||
return "lib";
|
||||
}
|
||||
|
||||
virtual const char* librarySuffix() {
|
||||
return SO_SUFFIX;
|
||||
}
|
||||
|
||||
virtual Status load(System::Library** lib,
|
||||
const char* name,
|
||||
bool mapName)
|
||||
const char* name)
|
||||
{
|
||||
void* p;
|
||||
bool alreadyAllocated = false;
|
||||
bool isMain = false;
|
||||
unsigned nameLength = (name ? strlen(name) : 0);
|
||||
if (mapName and name) {
|
||||
unsigned size = nameLength + 3 + sizeof(SO_SUFFIX);
|
||||
char buffer[size];
|
||||
vm::snprintf(buffer, size, "lib%s" SO_SUFFIX, name);
|
||||
p = dlopen(buffer, RTLD_LAZY | RTLD_LOCAL);
|
||||
} else {
|
||||
if (!name) {
|
||||
pathOfExecutable(this, &name, &nameLength);
|
||||
alreadyAllocated = true;
|
||||
isMain = true;
|
||||
}
|
||||
p = dlopen(name, RTLD_LAZY | RTLD_LOCAL);
|
||||
bool isMain = name == 0;
|
||||
if (isMain) {
|
||||
pathOfExecutable(this, &name, &nameLength);
|
||||
}
|
||||
void* p = dlopen(name, RTLD_LAZY | RTLD_LOCAL);
|
||||
|
||||
if (p) {
|
||||
if (Verbose) {
|
||||
@ -747,7 +737,7 @@ class MySystem: public System {
|
||||
if (name) {
|
||||
n = static_cast<char*>(allocate(this, nameLength + 1));
|
||||
memcpy(n, name, nameLength + 1);
|
||||
if (alreadyAllocated) {
|
||||
if (isMain) {
|
||||
free(name);
|
||||
}
|
||||
} else {
|
||||
@ -755,11 +745,13 @@ class MySystem: public System {
|
||||
}
|
||||
|
||||
*lib = new (allocate(this, sizeof(Library)))
|
||||
Library(this, p, n, nameLength, mapName, isMain);
|
||||
Library(this, p, n, nameLength, isMain);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "dlerror: %s\n", dlerror());
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "dlerror: %s\n", dlerror());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -768,6 +760,10 @@ class MySystem: public System {
|
||||
return ':';
|
||||
}
|
||||
|
||||
virtual char fileSeparator() {
|
||||
return '/';
|
||||
}
|
||||
|
||||
virtual int64_t now() {
|
||||
timeval tv = { 0, 0 };
|
||||
gettimeofday(&tv, 0);
|
||||
|
@ -89,7 +89,6 @@ class System {
|
||||
public:
|
||||
virtual void* resolve(const char* symbol) = 0;
|
||||
virtual const char* name() = 0;
|
||||
virtual bool mapName() = 0;
|
||||
virtual Library* next() = 0;
|
||||
virtual void setNext(Library* lib) = 0;
|
||||
virtual void disposeAll() = 0;
|
||||
@ -135,8 +134,11 @@ class System {
|
||||
virtual Status map(Region**, const char* name) = 0;
|
||||
virtual FileType identify(const char* name) = 0;
|
||||
virtual Status open(Directory**, const char* name) = 0;
|
||||
virtual Status load(Library**, const char* name, bool mapName) = 0;
|
||||
virtual const char* libraryPrefix() = 0;
|
||||
virtual const char* librarySuffix() = 0;
|
||||
virtual Status load(Library**, const char* name) = 0;
|
||||
virtual char pathSeparator() = 0;
|
||||
virtual char fileSeparator() = 0;
|
||||
virtual int64_t now() = 0;
|
||||
virtual void exit(int code) = 0;
|
||||
virtual void abort() = 0;
|
||||
|
45
src/tokenizer.h
Normal file
45
src/tokenizer.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright (c) 2010, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
#ifndef TOKENIZER_H
|
||||
#define TOKENIZER_H
|
||||
|
||||
namespace vm {
|
||||
|
||||
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 != 0;
|
||||
}
|
||||
|
||||
Token next() {
|
||||
const char* p = s;
|
||||
while (*s and *s != delimiter) ++s;
|
||||
return Token(p, s - p);
|
||||
}
|
||||
|
||||
const char* s;
|
||||
char delimiter;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif//TOKENIZER_H
|
@ -12,9 +12,13 @@
|
||||
#include "stdio.h"
|
||||
#include "stdint.h"
|
||||
#include "string.h"
|
||||
#include "assert.h"
|
||||
#include "errno.h"
|
||||
|
||||
#include "constants.h"
|
||||
#include "finder.h"
|
||||
#include "stream.h"
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
#define UNREACHABLE abort()
|
||||
|
||||
@ -28,6 +32,8 @@ using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
namespace local {
|
||||
|
||||
#ifndef POINTER_SIZE
|
||||
# define POINTER_SIZE sizeof(void*)
|
||||
#endif
|
||||
@ -177,7 +183,7 @@ class Output {
|
||||
void write(int i) {
|
||||
static const int Size = 32;
|
||||
char s[Size];
|
||||
int c UNUSED = snprintf(s, Size, "%d", i);
|
||||
int c UNUSED = ::snprintf(s, Size, "%d", i);
|
||||
assert(c > 0 and c < Size);
|
||||
write(s);
|
||||
}
|
||||
@ -213,63 +219,6 @@ class FileOutput : public Output {
|
||||
}
|
||||
};
|
||||
|
||||
class Stream {
|
||||
public:
|
||||
Stream(FILE* stream, bool close):
|
||||
stream(stream), close(close)
|
||||
{
|
||||
assert(stream);
|
||||
}
|
||||
|
||||
~Stream() {
|
||||
if (close) fclose(stream);
|
||||
}
|
||||
|
||||
void skip(unsigned size) {
|
||||
fseek(stream, size, SEEK_CUR);
|
||||
}
|
||||
|
||||
void read(uint8_t* data, unsigned size) {
|
||||
fread(data, 1, size, stream);
|
||||
}
|
||||
|
||||
uint8_t read1() {
|
||||
uint8_t v;
|
||||
read(&v, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
uint16_t read2() {
|
||||
uint16_t a = read1();
|
||||
uint16_t b = read1();
|
||||
return (a << 8) | b;
|
||||
}
|
||||
|
||||
uint32_t read4() {
|
||||
uint32_t a = read2();
|
||||
uint32_t b = read2();
|
||||
return (a << 16) | b;
|
||||
}
|
||||
|
||||
uint64_t read8() {
|
||||
uint64_t a = read4();
|
||||
uint64_t b = read4();
|
||||
return (a << 32) | b;
|
||||
}
|
||||
|
||||
uint32_t readFloat() {
|
||||
return read4();
|
||||
}
|
||||
|
||||
uint64_t readDouble() {
|
||||
return read8();
|
||||
}
|
||||
|
||||
private:
|
||||
FILE* stream;
|
||||
bool close;
|
||||
};
|
||||
|
||||
class Object {
|
||||
public:
|
||||
typedef enum {
|
||||
@ -1384,8 +1333,8 @@ parseJavaClass(Object* type, Stream* s, Object* declarations)
|
||||
}
|
||||
|
||||
Object*
|
||||
parseType(Object::ObjectType type, Object* p, Object* declarations,
|
||||
const char* javaClassDirectory)
|
||||
parseType(Finder* finder, Object::ObjectType type, Object* p,
|
||||
Object* declarations)
|
||||
{
|
||||
const char* name = string(car(p));
|
||||
|
||||
@ -1400,9 +1349,16 @@ parseType(Object::ObjectType type, Object* p, Object* declarations,
|
||||
bool isJavaType = javaName and *javaName != '[';
|
||||
|
||||
if (isJavaType) {
|
||||
const char* file = append(javaClassDirectory, "/", javaName, ".class");
|
||||
Stream s(fopen(file, "rb"), true);
|
||||
class Client: public Stream::Client {
|
||||
public:
|
||||
virtual void NO_RETURN handleError() {
|
||||
abort();
|
||||
}
|
||||
} client;
|
||||
System::Region* region = finder->find(append(javaName, ".class"));
|
||||
Stream s(&client, region->start(), region->length());
|
||||
parseJavaClass(t, &s, declarations);
|
||||
region->dispose();
|
||||
}
|
||||
|
||||
for (p = cdr(p); p; p = cdr(p)) {
|
||||
@ -1429,14 +1385,13 @@ parseType(Object::ObjectType type, Object* p, Object* declarations,
|
||||
}
|
||||
|
||||
Object*
|
||||
parseDeclaration(Object* p, Object* declarations,
|
||||
const char* javaClassDirectory)
|
||||
parseDeclaration(Finder* finder, Object* p, Object* declarations)
|
||||
{
|
||||
const char* spec = string(car(p));
|
||||
if (equal(spec, "type")) {
|
||||
return parseType(Object::Type, cdr(p), declarations, javaClassDirectory);
|
||||
return parseType(finder, Object::Type, cdr(p), declarations);
|
||||
} else if (equal(spec, "pod")) {
|
||||
return parseType(Object::Pod, cdr(p), declarations, javaClassDirectory);
|
||||
return parseType(finder, Object::Pod, cdr(p), declarations);
|
||||
} else {
|
||||
fprintf(stderr, "unexpected declaration spec: %s\n", spec);
|
||||
abort();
|
||||
@ -1444,7 +1399,7 @@ parseDeclaration(Object* p, Object* declarations,
|
||||
}
|
||||
|
||||
Object*
|
||||
parse(Input* in, const char* javaClassDirectory)
|
||||
parse(Finder* finder, Input* in)
|
||||
{
|
||||
Object* eos = Singleton::make(Object::Eos);
|
||||
List declarations;
|
||||
@ -1452,7 +1407,7 @@ parse(Input* in, const char* javaClassDirectory)
|
||||
Object* o;
|
||||
while ((o = read(in, eos, 0)) != eos) {
|
||||
declarations.append
|
||||
(parseDeclaration(o, declarations.first, javaClassDirectory));
|
||||
(parseDeclaration(finder, o, declarations.first));
|
||||
}
|
||||
|
||||
return declarations.first;
|
||||
@ -1522,7 +1477,7 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
|
||||
if (not unsafe) {
|
||||
out->write("const unsigned ");
|
||||
out->write(capitalize(::typeName(memberOwner(member))));
|
||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
||||
out->write(capitalize(memberName(member)));
|
||||
out->write(" = ");
|
||||
writeOffset(out, offset);
|
||||
@ -1547,7 +1502,7 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
writeAccessorName(out, member, unsafe);
|
||||
if (memberOwner(member)->type == Object::Pod) {
|
||||
out->write("(");
|
||||
out->write(capitalize(::typeName(memberOwner(member))));
|
||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("(Thread* t UNUSED, object");
|
||||
@ -1563,13 +1518,13 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
out->write(" assert(t, t->m->unsafe or ");
|
||||
out->write("instanceOf(t, arrayBodyUnsafe");
|
||||
out->write("(t, t->m->types, Machine::");
|
||||
out->write(capitalize(::typeName(memberOwner(member))));
|
||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
||||
out->write("Type)");
|
||||
out->write(", o));\n");
|
||||
|
||||
if (member->type != Object::Scalar) {
|
||||
out->write(" assert(t, i < ");
|
||||
out->write(::typeName(memberOwner(member)));
|
||||
out->write(local::typeName(memberOwner(member)));
|
||||
out->write("Length(t, o));\n");
|
||||
}
|
||||
}
|
||||
@ -1599,7 +1554,7 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
out->write("[");
|
||||
}
|
||||
|
||||
out->write(capitalize(::typeName(memberOwner(member))));
|
||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
||||
out->write(capitalize(memberName(member)));
|
||||
|
||||
if (member->type != Object::Scalar) {
|
||||
@ -2221,62 +2176,83 @@ void
|
||||
usageAndExit(const char* command)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s <java class directory> "
|
||||
"usage: %s <classpath> <input file> <output file> "
|
||||
"{enums,declarations,constructors,initializations,"
|
||||
"java-initializations}\n",
|
||||
command);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
} // namespace local
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" uint64_t
|
||||
vmNativeCall(void*, void*, unsigned, unsigned)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
vmJump(void*, void*, void*, void*, uintptr_t, uintptr_t)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
int
|
||||
main(int ac, char** av)
|
||||
{
|
||||
if ((ac != 2 and ac != 3)
|
||||
or (ac == 3
|
||||
and not equal(av[2], "enums")
|
||||
and not equal(av[2], "declarations")
|
||||
and not equal(av[2], "constructors")
|
||||
and not equal(av[2], "initializations")
|
||||
and not equal(av[2], "java-initializations")))
|
||||
if (ac != 5
|
||||
or not (local::equal(av[4], "enums")
|
||||
or local::equal(av[4], "declarations")
|
||||
or local::equal(av[4], "constructors")
|
||||
or local::equal(av[4], "initializations")
|
||||
or local::equal(av[4], "java-initializations")))
|
||||
{
|
||||
usageAndExit(av[0]);
|
||||
local::usageAndExit(av[0]);
|
||||
}
|
||||
|
||||
FileInput in(0, stdin, false);
|
||||
System* system = makeSystem(0);
|
||||
Finder* finder = makeFinder(system, av[1], 0);
|
||||
|
||||
Object* declarations = parse(&in, av[1]);
|
||||
|
||||
FileOutput out(0, stdout, false);
|
||||
|
||||
if (ac == 2 or equal(av[2], "enums")) {
|
||||
writeEnums(&out, declarations);
|
||||
FILE* inStream = ::fopen(av[2], "rb");
|
||||
if (inStream == 0) {
|
||||
fprintf(stderr, "unable to open %s: %s\n", av[2], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
local::FileInput in(0, inStream, false);
|
||||
|
||||
if (ac == 2 or equal(av[2], "declarations")) {
|
||||
local::Object* declarations = local::parse(finder, &in);
|
||||
|
||||
finder->dispose();
|
||||
system->dispose();
|
||||
|
||||
FILE* outStream = ::fopen(av[3], "wb");
|
||||
if (outStream == 0) {
|
||||
fprintf(stderr, "unable to open %s: %s\n", av[3], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
local::FileOutput out(0, outStream, false);
|
||||
|
||||
if (local::equal(av[4], "enums")) {
|
||||
local::writeEnums(&out, declarations);
|
||||
} else if (local::equal(av[4], "declarations")) {
|
||||
out.write("const unsigned TypeCount = ");
|
||||
out.Output::write(typeCount(declarations));
|
||||
out.Output::write(local::typeCount(declarations));
|
||||
out.write(";\n\n");
|
||||
|
||||
writePods(&out, declarations);
|
||||
writeAccessors(&out, declarations);
|
||||
writeSizes(&out, declarations);
|
||||
writeInitializerDeclarations(&out, declarations);
|
||||
writeConstructorDeclarations(&out, declarations);
|
||||
}
|
||||
|
||||
if (ac == 2 or equal(av[2], "constructors")) {
|
||||
writeInitializers(&out, declarations);
|
||||
writeConstructors(&out, declarations);
|
||||
}
|
||||
|
||||
if (ac == 2 or equal(av[2], "initializations")) {
|
||||
writeInitializations(&out, declarations);
|
||||
}
|
||||
|
||||
if (ac == 2 or equal(av[2], "java-initializations")) {
|
||||
writeJavaInitializations(&out, declarations);
|
||||
local::writePods(&out, declarations);
|
||||
local::writeAccessors(&out, declarations);
|
||||
local::writeSizes(&out, declarations);
|
||||
local::writeInitializerDeclarations(&out, declarations);
|
||||
local::writeConstructorDeclarations(&out, declarations);
|
||||
} else if (local::equal(av[4], "constructors")) {
|
||||
local::writeInitializers(&out, declarations);
|
||||
local::writeConstructors(&out, declarations);
|
||||
} else if (local::equal(av[4], "initializations")) {
|
||||
local::writeInitializations(&out, declarations);
|
||||
} else if (local::equal(av[4], "java-initializations")) {
|
||||
local::writeJavaInitializations(&out, declarations);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user