mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
lots of new instructions and bugfixes
This commit is contained in:
parent
b0500a881c
commit
8ae36c05b7
@ -1,12 +1,14 @@
|
||||
package java.io;
|
||||
|
||||
public class PrintStream extends OutputStream {
|
||||
private static final byte[] newline
|
||||
= System.getProperty("line.separator").getBytes();
|
||||
|
||||
private final OutputStream out;
|
||||
private final boolean autoFlush;
|
||||
|
||||
private static class Static {
|
||||
private static final byte[] newline
|
||||
= System.getProperty("line.separator").getBytes();
|
||||
}
|
||||
|
||||
public PrintStream(OutputStream out, boolean autoFlush) {
|
||||
this.out = out;
|
||||
this.autoFlush = autoFlush;
|
||||
@ -33,14 +35,14 @@ public class PrintStream extends OutputStream {
|
||||
public synchronized void println(String s) {
|
||||
try {
|
||||
out.write(s.getBytes());
|
||||
out.write(newline);
|
||||
out.write(Static.newline);
|
||||
if (autoFlush) flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public synchronized void println() {
|
||||
try {
|
||||
out.write(newline);
|
||||
out.write(Static.newline);
|
||||
if (autoFlush) flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
285
src/compile.cpp
285
src/compile.cpp
@ -32,6 +32,30 @@ throwNew(Thread* t, object class_)
|
||||
unwind(t);
|
||||
}
|
||||
|
||||
void
|
||||
throw_(Thread* t, object o)
|
||||
{
|
||||
if (o) {
|
||||
t->exception = makeNullPointerException(t);
|
||||
} else {
|
||||
t->exception = o;
|
||||
}
|
||||
unwind(t);
|
||||
}
|
||||
|
||||
object
|
||||
makeBlankObjectArray(Thread* t, object class_, int32_t length)
|
||||
{
|
||||
return makeObjectArray(t, class_, length, true);
|
||||
}
|
||||
|
||||
object
|
||||
makeBlankArray(Thread* t, object (*constructor)(Thread*, uintptr_t, bool),
|
||||
int32_t length)
|
||||
{
|
||||
return constructor(t, length, true);
|
||||
}
|
||||
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(System* s, unsigned minimumCapacity):
|
||||
@ -402,6 +426,17 @@ class Assembler {
|
||||
code.append(v);
|
||||
}
|
||||
|
||||
void add(int32_t v, Register dst, unsigned offset) {
|
||||
rex();
|
||||
unsigned i = (isByte(v) ? 0x83 : 0x81);
|
||||
offsetInstruction(i, 0, 0x40, 0x80, rax, dst, offset);
|
||||
if (isByte(v)) {
|
||||
code.append(v);
|
||||
} else {
|
||||
code.append4(v);
|
||||
}
|
||||
}
|
||||
|
||||
void sub(Register src, Register dst) {
|
||||
rex();
|
||||
code.append(0x29);
|
||||
@ -470,9 +505,9 @@ class Assembler {
|
||||
code.append(0xe0 | reg);
|
||||
}
|
||||
|
||||
void je(Label& label) {
|
||||
void conditional(Label& label, unsigned condition) {
|
||||
code.append(0x0f);
|
||||
code.append(0x84);
|
||||
code.append(condition);
|
||||
label.reference();
|
||||
}
|
||||
|
||||
@ -486,32 +521,50 @@ class Assembler {
|
||||
code.append4(0);
|
||||
}
|
||||
|
||||
void je(Label& label) {
|
||||
conditional(label, 0x84);
|
||||
}
|
||||
|
||||
void je(unsigned javaIP) {
|
||||
conditional(javaIP, 0x84);
|
||||
}
|
||||
|
||||
void jne(Label& label) {
|
||||
code.append(0x0f);
|
||||
code.append(0x85);
|
||||
label.reference();
|
||||
conditional(label, 0x85);
|
||||
}
|
||||
|
||||
void jne(unsigned javaIP) {
|
||||
conditional(javaIP, 0x85);
|
||||
}
|
||||
|
||||
void jg(Label& label) {
|
||||
conditional(label, 0x8f);
|
||||
}
|
||||
|
||||
void jg(unsigned javaIP) {
|
||||
conditional(javaIP, 0x8f);
|
||||
}
|
||||
|
||||
void jge(Label& label) {
|
||||
conditional(label, 0x8d);
|
||||
}
|
||||
|
||||
void jge(unsigned javaIP) {
|
||||
conditional(javaIP, 0x8d);
|
||||
}
|
||||
|
||||
void jl(Label& label) {
|
||||
conditional(label, 0x8c);
|
||||
}
|
||||
|
||||
void jl(unsigned javaIP) {
|
||||
conditional(javaIP, 0x8c);
|
||||
}
|
||||
|
||||
void jle(Label& label) {
|
||||
conditional(label, 0x8e);
|
||||
}
|
||||
|
||||
void jle(unsigned javaIP) {
|
||||
conditional(javaIP, 0x8e);
|
||||
}
|
||||
@ -539,7 +592,8 @@ localOffset(int v, int parameterFootprint)
|
||||
{
|
||||
v *= BytesPerWord;
|
||||
if (v < parameterFootprint) {
|
||||
return v + (BytesPerWord * 2) + FrameFootprint;
|
||||
return (parameterFootprint - v - BytesPerWord) + (BytesPerWord * 2)
|
||||
+ FrameFootprint;
|
||||
} else {
|
||||
return -(v + BytesPerWord - parameterFootprint);
|
||||
}
|
||||
@ -574,11 +628,9 @@ sseRegister(Thread* t, unsigned index)
|
||||
}
|
||||
|
||||
unsigned
|
||||
parameterOffset(Thread* t, object method, unsigned index)
|
||||
parameterOffset(unsigned index)
|
||||
{
|
||||
return FrameFootprint
|
||||
+ (((methodParameterFootprint(t, method) - index - 1) + 2)
|
||||
* BytesPerWord);
|
||||
return FrameFootprint + ((index + 2) * BytesPerWord);
|
||||
}
|
||||
|
||||
class Compiler: public Assembler {
|
||||
@ -635,7 +687,7 @@ class Compiler: public Assembler {
|
||||
|
||||
void compileCall(uintptr_t function, uintptr_t arg1) {
|
||||
if (BytesPerWord == 4) {
|
||||
pushAddress(arg1);
|
||||
push(arg1);
|
||||
push(rbp, FrameThread);
|
||||
} else {
|
||||
mov(arg1, rsi);
|
||||
@ -650,6 +702,42 @@ class Compiler: public Assembler {
|
||||
}
|
||||
}
|
||||
|
||||
void compileCall(uintptr_t function, Register arg1) {
|
||||
if (BytesPerWord == 4) {
|
||||
push(arg1);
|
||||
push(rbp, FrameThread);
|
||||
} else {
|
||||
mov(arg1, rsi);
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(function, rax);
|
||||
call(rax);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 2, rsp);
|
||||
}
|
||||
}
|
||||
|
||||
void compileCall(uintptr_t function, uintptr_t arg1, Register arg2) {
|
||||
if (BytesPerWord == 4) {
|
||||
push(arg2);
|
||||
push(arg1);
|
||||
push(rbp, FrameThread);
|
||||
} else {
|
||||
mov(arg2, rdx);
|
||||
mov(arg1, rsi);
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(function, rax);
|
||||
call(rax);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 3, rsp);
|
||||
}
|
||||
}
|
||||
|
||||
void compileCall(uintptr_t function, Register arg1, Register arg2) {
|
||||
if (BytesPerWord == 4) {
|
||||
push(arg2);
|
||||
@ -682,6 +770,12 @@ class Compiler: public Assembler {
|
||||
- reinterpret_cast<uintptr_t>(t);
|
||||
|
||||
void* function = resolveNativeMethod(t, method);
|
||||
if (UNLIKELY(function == 0)) {
|
||||
object message = makeString
|
||||
(t, "%s", &byteArrayBody(t, methodCode(t, method), 0));
|
||||
t->exception = makeUnsatisfiedLinkError(t, message);
|
||||
return;
|
||||
}
|
||||
|
||||
push(rbp);
|
||||
mov(rsp, rbp);
|
||||
@ -696,17 +790,24 @@ class Compiler: public Assembler {
|
||||
} else {
|
||||
index = 1;
|
||||
}
|
||||
|
||||
unsigned parameterCodes[methodParameterCount(t, method)];
|
||||
MethodSpecIterator it
|
||||
(t, reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, methodSpec(t, method), 0)));
|
||||
|
||||
MethodSpecIterator it(t, reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, methodSpec(t, method), 0)));
|
||||
for (unsigned i = 0; it.hasNext(); ++i) {
|
||||
parameterCodes[i] = fieldCode(t, *it.next());
|
||||
}
|
||||
|
||||
unsigned stackFootprint;
|
||||
unsigned parameterCodeIndex = methodParameterCount(t, method);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
while (it.hasNext()) {
|
||||
unsigned offset = parameterOffset(t, method, index);
|
||||
while (parameterCodeIndex) {
|
||||
unsigned offset = parameterOffset(index);
|
||||
|
||||
switch (fieldCode(t, *it.next())) {
|
||||
switch (parameterCodes[--parameterCodeIndex]) {
|
||||
case BooleanField:
|
||||
case ByteField:
|
||||
case ShortField:
|
||||
@ -741,7 +842,8 @@ class Compiler: public Assembler {
|
||||
sub(BytesPerWord, rax);
|
||||
push(rax); // push pointer to class pointer
|
||||
} else {
|
||||
unsigned offset = parameterOffset(t, method, 0);
|
||||
unsigned offset = parameterOffset
|
||||
(methodParameterFootprint(t, method) - 1);
|
||||
mov(rbp, rax);
|
||||
add(offset, rax);
|
||||
push(rax); // push pointer to this pointer
|
||||
@ -760,10 +862,10 @@ class Compiler: public Assembler {
|
||||
|
||||
stackFootprint = 0;
|
||||
|
||||
while (it.hasNext()) {
|
||||
unsigned offset = parameterOffset(t, method, index);
|
||||
while (parameterCodeIndex) {
|
||||
unsigned offset = parameterOffset(index);
|
||||
|
||||
switch (fieldCode(t, *it.next())) {
|
||||
switch (parameterCodes[--parameterCodeIndex]) {
|
||||
case BooleanField:
|
||||
case ByteField:
|
||||
case ShortField:
|
||||
@ -817,7 +919,8 @@ class Compiler: public Assembler {
|
||||
mov(rbp, rsi);
|
||||
sub(BytesPerWord, rsi); // push pointer to class pointer
|
||||
} else {
|
||||
unsigned offset = parameterOffset(t, method, 0);
|
||||
unsigned offset = parameterOffset
|
||||
(methodParameterFootprint(t, method) - 1);
|
||||
mov(rbp, rsi);
|
||||
add(offset, rsi); // push pointer to this pointer
|
||||
}
|
||||
@ -897,6 +1000,31 @@ class Compiler: public Assembler {
|
||||
push(rbp, localOffset(3, parameterFootprint));
|
||||
break;
|
||||
|
||||
case anewarray: {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
|
||||
Label nonnegative(this);
|
||||
|
||||
pop(rax);
|
||||
cmp(0, rax);
|
||||
jle(nonnegative);
|
||||
|
||||
compileCall
|
||||
(reinterpret_cast<uintptr_t>(throwNew),
|
||||
reinterpret_cast<uintptr_t>
|
||||
(arrayBody(t, t->m->types,
|
||||
Machine::NegativeArraySizeExceptionType)));
|
||||
|
||||
nonnegative.mark();
|
||||
compileCall(reinterpret_cast<uintptr_t>(makeBlankObjectArray),
|
||||
reinterpret_cast<uintptr_t>(class_),
|
||||
rax);
|
||||
push(rax);
|
||||
} break;
|
||||
|
||||
case areturn:
|
||||
case ireturn:
|
||||
case freturn:
|
||||
@ -936,6 +1064,11 @@ class Compiler: public Assembler {
|
||||
pop(rbp, localOffset(3, parameterFootprint));
|
||||
break;
|
||||
|
||||
case athrow:
|
||||
pop(rax);
|
||||
compileCall(reinterpret_cast<uintptr_t>(throw_), rax);
|
||||
break;
|
||||
|
||||
case bipush: {
|
||||
push(static_cast<int8_t>(codeBody(t, code, ip++)));
|
||||
} break;
|
||||
@ -948,7 +1081,7 @@ class Compiler: public Assembler {
|
||||
|
||||
Label next(this);
|
||||
|
||||
pop(rax);
|
||||
mov(rsp, 0, rax);
|
||||
cmp(0, rax);
|
||||
je(next);
|
||||
|
||||
@ -970,7 +1103,7 @@ class Compiler: public Assembler {
|
||||
} break;
|
||||
|
||||
case dup:
|
||||
push(rsp, BytesPerWord);
|
||||
push(rsp, 0);
|
||||
break;
|
||||
|
||||
case getfield: {
|
||||
@ -1031,7 +1164,7 @@ class Compiler: public Assembler {
|
||||
object table = classStaticTable(t, fieldClass(t, field));
|
||||
|
||||
mov(reinterpret_cast<uintptr_t>(table), rax);
|
||||
add(fieldOffset(t, field), rax);
|
||||
add((fieldOffset(t, field) * BytesPerWord) + ArrayBody, rax);
|
||||
|
||||
switch (fieldCode(t, field)) {
|
||||
case ByteField:
|
||||
@ -1082,6 +1215,16 @@ class Compiler: public Assembler {
|
||||
}
|
||||
} break;
|
||||
|
||||
case goto_: {
|
||||
int16_t offset = codeReadInt16(t, code, ip);
|
||||
jmp((ip - 3) + offset);
|
||||
} break;
|
||||
|
||||
case goto_w: {
|
||||
int32_t offset = codeReadInt32(t, code, ip);
|
||||
jmp((ip - 5) + offset);
|
||||
} break;
|
||||
|
||||
case iadd:
|
||||
pop(rax);
|
||||
pop(rcx);
|
||||
@ -1223,14 +1366,11 @@ class Compiler: public Assembler {
|
||||
jle((ip - 3) + offset);
|
||||
} break;
|
||||
|
||||
case goto_: {
|
||||
int16_t offset = codeReadInt16(t, code, ip);
|
||||
jmp((ip - 3) + offset);
|
||||
} break;
|
||||
|
||||
case goto_w: {
|
||||
int32_t offset = codeReadInt32(t, code, ip);
|
||||
jmp((ip - 5) + offset);
|
||||
case iinc: {
|
||||
uint8_t index = codeBody(t, code, ip++);
|
||||
int8_t c = codeBody(t, code, ip++);
|
||||
|
||||
add(c, rbp, localOffset(index, parameterFootprint));
|
||||
} break;
|
||||
|
||||
case instanceof: {
|
||||
@ -1326,6 +1466,13 @@ class Compiler: public Assembler {
|
||||
pushReturnValue(t, methodReturnCode(t, target));
|
||||
} break;
|
||||
|
||||
case isub:
|
||||
pop(rax);
|
||||
pop(rcx);
|
||||
sub(rax, rcx);
|
||||
push(rcx);
|
||||
break;
|
||||
|
||||
case ldc:
|
||||
case ldc_w: {
|
||||
uint16_t index;
|
||||
@ -1378,6 +1525,66 @@ class Compiler: public Assembler {
|
||||
push(rax);
|
||||
} break;
|
||||
|
||||
case newarray: {
|
||||
uint8_t type = codeBody(t, code, ip++);
|
||||
|
||||
Label nonnegative(this);
|
||||
|
||||
pop(rax);
|
||||
cmp(0, rax);
|
||||
jge(nonnegative);
|
||||
|
||||
compileCall
|
||||
(reinterpret_cast<uintptr_t>(throwNew),
|
||||
reinterpret_cast<uintptr_t>
|
||||
(arrayBody(t, t->m->types,
|
||||
Machine::NegativeArraySizeExceptionType)));
|
||||
|
||||
nonnegative.mark();
|
||||
|
||||
object (*constructor)(Thread*, uintptr_t, bool);
|
||||
switch (type) {
|
||||
case T_BOOLEAN:
|
||||
constructor = makeBooleanArray;
|
||||
break;
|
||||
|
||||
case T_CHAR:
|
||||
constructor = makeCharArray;
|
||||
break;
|
||||
|
||||
case T_FLOAT:
|
||||
constructor = makeFloatArray;
|
||||
break;
|
||||
|
||||
case T_DOUBLE:
|
||||
constructor = makeDoubleArray;
|
||||
break;
|
||||
|
||||
case T_BYTE:
|
||||
constructor = makeByteArray;
|
||||
break;
|
||||
|
||||
case T_SHORT:
|
||||
constructor = makeShortArray;
|
||||
break;
|
||||
|
||||
case T_INT:
|
||||
constructor = makeIntArray;
|
||||
break;
|
||||
|
||||
case T_LONG:
|
||||
constructor = makeLongArray;
|
||||
break;
|
||||
|
||||
default: abort(t);
|
||||
}
|
||||
|
||||
compileCall(reinterpret_cast<uintptr_t>(makeBlankArray),
|
||||
reinterpret_cast<uintptr_t>(constructor),
|
||||
rax);
|
||||
push(rax);
|
||||
} break;
|
||||
|
||||
case pop_: {
|
||||
add(BytesPerWord, rsp);
|
||||
} break;
|
||||
@ -1446,7 +1653,7 @@ class Compiler: public Assembler {
|
||||
object table = classStaticTable(t, fieldClass(t, field));
|
||||
|
||||
mov(reinterpret_cast<uintptr_t>(table), rax);
|
||||
add(fieldOffset(t, field), rax);
|
||||
add((fieldOffset(t, field) * BytesPerWord) + ArrayBody, rax);
|
||||
|
||||
switch (fieldCode(t, field)) {
|
||||
case ByteField:
|
||||
@ -1486,6 +1693,10 @@ class Compiler: public Assembler {
|
||||
ret();
|
||||
break;
|
||||
|
||||
case sipush: {
|
||||
push(static_cast<int16_t>(codeReadInt16(t, code, ip)));
|
||||
} break;
|
||||
|
||||
default:
|
||||
abort(t);
|
||||
}
|
||||
@ -1575,7 +1786,7 @@ compileMethod2(MyThread* t, object method)
|
||||
Compiler c(t->m->system);
|
||||
c.compile(t, method);
|
||||
|
||||
object compiled = makeCompiled(t, 0, c.code.length(), false);
|
||||
object compiled = makeCompiled(t, c.code.length(), false);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
|
||||
c.code.copyTo(&compiledBody(t, compiled, 0));
|
||||
@ -1635,7 +1846,7 @@ compileStub(Thread* t)
|
||||
Compiler c(t->m->system);
|
||||
c.compileStub(static_cast<MyThread*>(t));
|
||||
|
||||
object stub = makeCompiled(t, 0, c.code.length(), false);
|
||||
object stub = makeCompiled(t, c.code.length(), false);
|
||||
c.code.copyTo(&compiledBody(t, stub, 0));
|
||||
|
||||
return stub;
|
||||
@ -1811,10 +2022,14 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
||||
unsigned returnCode = methodReturnCode(t, method);
|
||||
unsigned returnType = fieldType(t, returnCode);
|
||||
|
||||
void* frame = t->frame;
|
||||
|
||||
uint64_t result = vmInvoke
|
||||
(&compiledBody(t, methodCompiled(t, method), 0), arguments->array,
|
||||
arguments->position * BytesPerWord, returnType);
|
||||
|
||||
t->frame = frame;
|
||||
|
||||
object r;
|
||||
switch (returnCode) {
|
||||
case ByteField:
|
||||
|
@ -1760,16 +1760,7 @@ interpret(Thread* t)
|
||||
object class_ = methodClass(t, frameMethod(t, frame));
|
||||
if (isSpecialMethod(t, method, class_)) {
|
||||
class_ = classSuper(t, class_);
|
||||
|
||||
if (classVirtualTable(t, class_) == 0) {
|
||||
PROTECT(t, method);
|
||||
PROTECT(t, class_);
|
||||
|
||||
resolveClass(t, className(t, class_));
|
||||
if (UNLIKELY(exception)) goto throw_;
|
||||
|
||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||
}
|
||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||
|
||||
code = findMethod(t, method, class_);
|
||||
} else {
|
||||
@ -1804,16 +1795,7 @@ interpret(Thread* t)
|
||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
||||
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
||||
|
||||
if (classVirtualTable(t, class_) == 0) {
|
||||
PROTECT(t, method);
|
||||
PROTECT(t, class_);
|
||||
|
||||
resolveClass(t, className(t, class_));
|
||||
if (UNLIKELY(exception)) goto throw_;
|
||||
|
||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||
}
|
||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||
|
||||
code = findMethod(t, method, class_);
|
||||
goto invoke;
|
||||
@ -2494,10 +2476,7 @@ interpret(Thread* t)
|
||||
} goto loop;
|
||||
|
||||
case sipush: {
|
||||
uint8_t byte1 = codeBody(t, code, ip++);
|
||||
uint8_t byte2 = codeBody(t, code, ip++);
|
||||
|
||||
pushInt(t, static_cast<int16_t>((byte1 << 8) | byte2));
|
||||
pushInt(t, static_cast<int16_t>(codeReadInt16(t, code, ip)));
|
||||
} goto loop;
|
||||
|
||||
case swap: {
|
||||
@ -2766,11 +2745,6 @@ invoke(Thread* t, object method)
|
||||
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
||||
method = findInterfaceMethod(t, method, class_);
|
||||
} else {
|
||||
if (classVirtualTable(t, class_) == 0) {
|
||||
resolveClass(t, className(t, class_));
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
}
|
||||
|
||||
method = findMethod(t, method, class_);
|
||||
}
|
||||
}
|
||||
|
@ -1451,8 +1451,6 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
||||
|
||||
m->bootstrapClassMap = makeHashMap(this, 0, 0);
|
||||
|
||||
#include "type-java-initializations.cpp"
|
||||
|
||||
object loaderMap = makeHashMap(this, 0, 0);
|
||||
set(t, systemClassLoaderMap(t, m->loader), loaderMap);
|
||||
|
||||
@ -1462,6 +1460,17 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
||||
m->jniInterfaceTable = makeVector(this, 0, 0, false);
|
||||
|
||||
m->localThread->set(this);
|
||||
|
||||
#include "type-java-initializations.cpp"
|
||||
|
||||
enter(t, Thread::ActiveState);
|
||||
|
||||
resolveClass
|
||||
(t, className(t, arrayBody(t, m->types, Machine::ClassType)));
|
||||
resolveClass
|
||||
(t, className(t, arrayBody(t, m->types, Machine::IntArrayType)));
|
||||
resolveClass
|
||||
(t, className(t, arrayBody(t, m->types, Machine::ByteArrayType)));
|
||||
} else {
|
||||
parent->child = this;
|
||||
}
|
||||
@ -1472,6 +1481,8 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
||||
this->javaThread = makeThread
|
||||
(this, reinterpret_cast<int64_t>(this), 0, 0, 0, 0, m->loader);
|
||||
}
|
||||
|
||||
enter(this, Thread::IdleState);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -56,6 +56,7 @@ const unsigned WeakReferenceFlag = 1 << 1;
|
||||
const unsigned NeedInitFlag = 1 << 2;
|
||||
const unsigned InitFlag = 1 << 3;
|
||||
const unsigned PrimitiveFlag = 1 << 4;
|
||||
const unsigned BootstrapFlag = 1 << 5;
|
||||
|
||||
// method flags:
|
||||
const unsigned ClassInitFlag = 1 << 0;
|
||||
|
@ -40,6 +40,12 @@ equal(const char* a, const char* b)
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
startsWith(const char* a, const char* b)
|
||||
{
|
||||
return strncmp(a, b, strlen(a)) == 0;
|
||||
}
|
||||
|
||||
class Object {
|
||||
public:
|
||||
typedef enum {
|
||||
@ -1354,6 +1360,22 @@ writeConstructors(Output* out, Object* declarations)
|
||||
}
|
||||
}
|
||||
|
||||
if (typeJavaName(o)
|
||||
and not equal("class", typeName(o))
|
||||
and startsWith("java/", typeJavaName(o)))
|
||||
{
|
||||
out->write(" object class__ ");
|
||||
out->write("= arrayBody(t, t->m->types, Machine::");
|
||||
out->write(capitalize(typeName(o)));
|
||||
out->write("Type);\n");
|
||||
|
||||
out->write(" if (classVmFlags(t, class__) & BootstrapFlag) {\n");
|
||||
out->write(" classVmFlags(t, class__) &= ~BootstrapFlag;\n");
|
||||
out->write(" resolveClass(t, className(t, class__));\n");
|
||||
out->write(" assert(t, t->exception == 0);\n");
|
||||
out->write(" }\n");
|
||||
}
|
||||
|
||||
out->write(" object o = allocate(t, ");
|
||||
writeOffset(out, typeOffset(o), true);
|
||||
out->write(");\n");
|
||||
@ -1522,7 +1544,18 @@ writeInitialization(Output* out, Object* type)
|
||||
}
|
||||
|
||||
out->write(" object class_ = makeClass");
|
||||
out->write("(t, 0, 0, 0, ");
|
||||
out->write("(t, 0, ");
|
||||
|
||||
if (typeJavaName(type)
|
||||
and not equal("class", typeName(type))
|
||||
and startsWith("java/", typeJavaName(type)))
|
||||
{
|
||||
out->write("BootstrapFlag");
|
||||
} else {
|
||||
out->write("0");
|
||||
}
|
||||
|
||||
out->write(", 0, ");
|
||||
out->write(typeFixedSize(type));
|
||||
out->write(", ");
|
||||
out->write(typeArrayElementSize(type));
|
||||
|
@ -53,7 +53,6 @@
|
||||
(object compiled))
|
||||
|
||||
(type compiled
|
||||
(nogc object method)
|
||||
(array uint8_t body))
|
||||
|
||||
(type nativeMethodData
|
||||
|
Loading…
Reference in New Issue
Block a user