mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
clean up sketch of parseClass() and friends; etc.
This commit is contained in:
parent
f99425d944
commit
1cb866aac1
2
makefile
2
makefile
@ -33,8 +33,6 @@ stdcpp-cflags = $(fast) $(cflags)
|
|||||||
|
|
||||||
type-headers = \
|
type-headers = \
|
||||||
$(bld)/type-header.h \
|
$(bld)/type-header.h \
|
||||||
$(bld)/type-enums.h \
|
|
||||||
$(bld)/type-enum-cases.h \
|
|
||||||
$(bld)/type-declarations.h \
|
$(bld)/type-declarations.h \
|
||||||
$(bld)/type-constructors.h \
|
$(bld)/type-constructors.h \
|
||||||
$(bld)/type-primary-inits.h
|
$(bld)/type-primary-inits.h
|
||||||
|
@ -215,8 +215,13 @@ enum Constant {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const unsigned ACC_PUBLIC = 1 << 0;
|
const unsigned ACC_PUBLIC = 1 << 0;
|
||||||
|
const unsigned ACC_PRIVATE = 1 << 1;
|
||||||
|
const unsigned ACC_PROTECTED = 1 << 2;
|
||||||
|
const unsigned ACC_STATIC = 1 << 3;
|
||||||
const unsigned ACC_FINAL = 1 << 4;
|
const unsigned ACC_FINAL = 1 << 4;
|
||||||
const unsigned ACC_SUPER = 1 << 5;
|
const unsigned ACC_SUPER = 1 << 5;
|
||||||
|
const unsigned ACC_VOLATILE = 1 << 6;
|
||||||
|
const unsigned ACC_TRANSIENT = 1 << 7;
|
||||||
const unsigned ACC_INTERFACE = 1 << 9;
|
const unsigned ACC_INTERFACE = 1 << 9;
|
||||||
const unsigned ACC_ABSTRACT = 1 << 10;
|
const unsigned ACC_ABSTRACT = 1 << 10;
|
||||||
|
|
||||||
|
@ -992,9 +992,9 @@ writeSubtypeAssertions(Output* out, Object* o)
|
|||||||
{
|
{
|
||||||
for (Object* p = typeSubtypes(o); p; p = cdr(p)) {
|
for (Object* p = typeSubtypes(o); p; p = cdr(p)) {
|
||||||
Object* st = car(p);
|
Object* st = car(p);
|
||||||
out->write(" or typeOf(o) == ");
|
out->write(" or objectClass(o) == t->vm->");
|
||||||
out->write(capitalize(typeName(st)));
|
out->write(typeName(st));
|
||||||
out->write("Type");
|
out->write("Class");
|
||||||
writeSubtypeAssertions(out, st);
|
writeSubtypeAssertions(out, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1027,9 +1027,9 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
|||||||
out->write(") {\n");
|
out->write(") {\n");
|
||||||
|
|
||||||
if (not unsafe and memberOwner(member)->type == Object::Type) {
|
if (not unsafe and memberOwner(member)->type == Object::Type) {
|
||||||
out->write(" assert(t, objectClass(o) == 0 or typeOf(o) == ");
|
out->write(" assert(t, objectClass(o) == 0 or objectClass(o) == t->vm->");
|
||||||
out->write(capitalize(::typeName(memberOwner(member))));
|
out->write(::typeName(memberOwner(member)));
|
||||||
out->write("Type");
|
out->write("Class");
|
||||||
writeSubtypeAssertions(out, memberOwner(member));
|
writeSubtypeAssertions(out, memberOwner(member));
|
||||||
out->write(");\n");
|
out->write(");\n");
|
||||||
}
|
}
|
||||||
@ -1328,65 +1328,6 @@ writeConstructors(Output* out, Object* declarations)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
writeEnums(Output* out, Object* declarations)
|
|
||||||
{
|
|
||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
|
||||||
Object* o = car(p);
|
|
||||||
switch (o->type) {
|
|
||||||
case Object::Type: {
|
|
||||||
out->write(capitalize(typeName(o)));
|
|
||||||
out->write("Type,\n");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
lispStyle(const char* s)
|
|
||||||
{
|
|
||||||
unsigned length = 0;
|
|
||||||
for (const char* p = s; *p; ++p) {
|
|
||||||
if (*p >= 'A' and *p <= 'Z') ++ length;
|
|
||||||
++ length;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* n = static_cast<char*>(malloc(length + 1));
|
|
||||||
assert(n);
|
|
||||||
char* np = n;
|
|
||||||
for (const char* p = s; *p; ++p) {
|
|
||||||
if (*p >= 'A' and *p <= 'Z') {
|
|
||||||
*(np++) = '-';
|
|
||||||
*(np++) = 'a' + (*p - 'A');
|
|
||||||
} else {
|
|
||||||
*(np++) = *p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*np = 0;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
writeEnumCases(Output* out, Object* declarations)
|
|
||||||
{
|
|
||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
|
||||||
Object* o = car(p);
|
|
||||||
switch (o->type) {
|
|
||||||
case Object::Type: {
|
|
||||||
out->write("case ");
|
|
||||||
out->write(capitalize(typeName(o)));
|
|
||||||
out->write("Type: return \"");
|
|
||||||
out->write(lispStyle(typeName(o)));
|
|
||||||
out->write("\";\n");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
writeDeclarations(Output* out, Object* declarations)
|
writeDeclarations(Output* out, Object* declarations)
|
||||||
{
|
{
|
||||||
@ -1551,8 +1492,7 @@ void
|
|||||||
usageAndExit(const char* command)
|
usageAndExit(const char* command)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s {header,enums,enum-cases,declarations,constructors,"
|
"usage: %s {header,declarations,constructors,primary-inits}\n",
|
||||||
"primary-inits}\n",
|
|
||||||
command);
|
command);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
@ -1565,8 +1505,6 @@ main(int ac, char** av)
|
|||||||
if ((ac != 1 and ac != 2)
|
if ((ac != 1 and ac != 2)
|
||||||
or (ac == 2
|
or (ac == 2
|
||||||
and not equal(av[1], "header")
|
and not equal(av[1], "header")
|
||||||
and not equal(av[1], "enums")
|
|
||||||
and not equal(av[1], "enum-cases")
|
|
||||||
and not equal(av[1], "declarations")
|
and not equal(av[1], "declarations")
|
||||||
and not equal(av[1], "constructors")
|
and not equal(av[1], "constructors")
|
||||||
and not equal(av[1], "primary-inits")))
|
and not equal(av[1], "primary-inits")))
|
||||||
@ -1586,14 +1524,6 @@ main(int ac, char** av)
|
|||||||
writeConstructorDeclarations(&out, declarations);
|
writeConstructorDeclarations(&out, declarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ac == 1 or equal(av[1], "enums")) {
|
|
||||||
writeEnums(&out, declarations);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ac == 1 or equal(av[1], "enum-cases")) {
|
|
||||||
writeEnumCases(&out, declarations);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ac == 1 or equal(av[1], "declarations")) {
|
if (ac == 1 or equal(av[1], "declarations")) {
|
||||||
writeDeclarations(&out, declarations);
|
writeDeclarations(&out, declarations);
|
||||||
}
|
}
|
||||||
|
@ -73,11 +73,16 @@
|
|||||||
(object third))
|
(object third))
|
||||||
|
|
||||||
(type hashMap
|
(type hashMap
|
||||||
(object size)
|
(uint32_t size)
|
||||||
(object array))
|
(object array))
|
||||||
|
|
||||||
|
(type hashMapIterator
|
||||||
|
(object map)
|
||||||
|
(object node)
|
||||||
|
(unsigned index))
|
||||||
|
|
||||||
(type list
|
(type list
|
||||||
(object size)
|
(uint32_t size)
|
||||||
(object front)
|
(object front)
|
||||||
(object rear))
|
(object rear))
|
||||||
|
|
||||||
@ -137,7 +142,7 @@
|
|||||||
(int8_t value))
|
(int8_t value))
|
||||||
|
|
||||||
(type boolean
|
(type boolean
|
||||||
(int8_t byte))
|
(int8_t value))
|
||||||
|
|
||||||
(type short
|
(type short
|
||||||
(int16_t value))
|
(int16_t value))
|
||||||
|
187
src/vm.cpp
187
src/vm.cpp
@ -19,7 +19,8 @@ typedef unsigned Type;
|
|||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
void assert(Thread* t, bool v);
|
void assert(Thread*, bool);
|
||||||
|
object resolveClass(Thread*, object);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T&
|
inline T&
|
||||||
@ -34,8 +35,6 @@ objectClass(object o)
|
|||||||
return cast<object>(o, 0);
|
return cast<object>(o, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "type-header.h"
|
|
||||||
|
|
||||||
class Machine {
|
class Machine {
|
||||||
public:
|
public:
|
||||||
System* sys;
|
System* sys;
|
||||||
@ -45,11 +44,12 @@ class Machine {
|
|||||||
Thread* exclusive;
|
Thread* exclusive;
|
||||||
unsigned activeCount;
|
unsigned activeCount;
|
||||||
unsigned liveCount;
|
unsigned liveCount;
|
||||||
unsigned nextClassId;
|
|
||||||
System::Monitor* stateLock;
|
System::Monitor* stateLock;
|
||||||
System::Monitor* heapLock;
|
System::Monitor* heapLock;
|
||||||
System::Monitor* classLock;
|
System::Monitor* classLock;
|
||||||
object classMap;
|
object classMap;
|
||||||
|
|
||||||
|
#include "type-declarations.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
class Thread {
|
class Thread {
|
||||||
@ -97,6 +97,8 @@ class Thread {
|
|||||||
Protector* protector;
|
Protector* protector;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "type-header.h"
|
||||||
|
|
||||||
void enter(Thread* t, Thread::State state);
|
void enter(Thread* t, Thread::State state);
|
||||||
|
|
||||||
class MonitorResource {
|
class MonitorResource {
|
||||||
@ -148,7 +150,6 @@ init(Machine* m, System* sys, Heap* heap, ClassFinder* classFinder)
|
|||||||
m->sys = sys;
|
m->sys = sys;
|
||||||
m->heap = heap;
|
m->heap = heap;
|
||||||
m->classFinder = classFinder;
|
m->classFinder = classFinder;
|
||||||
m->nextClassId = OtherType + 1;
|
|
||||||
|
|
||||||
if (not sys->success(sys->make(&(m->stateLock))) or
|
if (not sys->success(sys->make(&(m->stateLock))) or
|
||||||
not sys->success(sys->make(&(m->heapLock))) or
|
not sys->success(sys->make(&(m->heapLock))) or
|
||||||
@ -497,7 +498,7 @@ isLongOrDouble(Thread* t, object o)
|
|||||||
inline object
|
inline object
|
||||||
getField(Thread* t, object instance, object field)
|
getField(Thread* t, object instance, object field)
|
||||||
{
|
{
|
||||||
switch (arrayBody(t, fieldSpec(t, field))[0]) {
|
switch (byteArrayBody(t, fieldSpec(t, field))[0]) {
|
||||||
case 'B':
|
case 'B':
|
||||||
return makeByte(t, cast<int8_t>(instance, fieldOffset(t, field)));
|
return makeByte(t, cast<int8_t>(instance, fieldOffset(t, field)));
|
||||||
case 'C':
|
case 'C':
|
||||||
@ -525,7 +526,7 @@ getField(Thread* t, object instance, object field)
|
|||||||
inline void
|
inline void
|
||||||
setField(Thread* t, object o, object field, object value)
|
setField(Thread* t, object o, object field, object value)
|
||||||
{
|
{
|
||||||
switch (arrayBody(t, fieldSpec(t, field))[0]) {
|
switch (byteArrayBody(t, fieldSpec(t, field))[0]) {
|
||||||
case 'B':
|
case 'B':
|
||||||
cast<int8_t>(o, fieldOffset(t, field)) = byteValue(t, value);
|
cast<int8_t>(o, fieldOffset(t, field)) = byteValue(t, value);
|
||||||
break;
|
break;
|
||||||
@ -709,6 +710,14 @@ byteArrayHash(Thread* t, object array)
|
|||||||
return hash(byteArrayBody(t, array), byteArrayLength(t, array) - 1);
|
return hash(byteArrayBody(t, array), byteArrayLength(t, array) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
byteArrayEqual(Thread* t, object a, object b)
|
||||||
|
{
|
||||||
|
return a == b or
|
||||||
|
((byteArrayLength(t, a) == byteArrayLength(t, b)) and
|
||||||
|
strcmp(byteArrayBody(t, a), byteArrayBody(t, b)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32_t
|
inline uint32_t
|
||||||
methodHash(Thread* t, object method)
|
methodHash(Thread* t, object method)
|
||||||
{
|
{
|
||||||
@ -717,11 +726,11 @@ methodHash(Thread* t, object method)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
byteArrayEqual(Thread* t, object a, object b)
|
methodEqual(Thread* t, object a, object b)
|
||||||
{
|
{
|
||||||
return a == b or
|
return a == b or
|
||||||
((byteArrayLength(t, a) == byteArrayLength(t, b)) and
|
(byteArrayEqual(t, methodName(t, a), methodName(t, b)) and
|
||||||
strcmp(byteArrayBody(t, a), byteArrayBody(t, b)) == 0);
|
byteArrayEqual(t, methodSpec(t, a), methodSpec(t, b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
@ -764,10 +773,10 @@ hashMapGrow(Thread* t, object map, uint32_t (*hash)(Thread*, object))
|
|||||||
|
|
||||||
unsigned newLength = (oldLength ? oldLength * 2 : 32);
|
unsigned newLength = (oldLength ? oldLength * 2 : 32);
|
||||||
object newArray = makeArray(t, newLength);
|
object newArray = makeArray(t, newLength);
|
||||||
memset(arrayBody(t, newArray), o, newLength * sizeof(object));
|
memset(arrayBody(t, newArray), 0, newLength * sizeof(object));
|
||||||
|
|
||||||
if (oldArray) {
|
if (oldArray) {
|
||||||
for (unsigned i = 0; i < length; ++i) {
|
for (unsigned i = 0; i < oldLength; ++i) {
|
||||||
object next;
|
object next;
|
||||||
for (object p = arrayBody(t, oldArray)[i]; p; p = next) {
|
for (object p = arrayBody(t, oldArray)[i]; p; p = next) {
|
||||||
next = tripleThird(t, p);
|
next = tripleThird(t, p);
|
||||||
@ -789,19 +798,21 @@ void
|
|||||||
hashMapInsert(Thread* t, object map, object key, object value,
|
hashMapInsert(Thread* t, object map, object key, object value,
|
||||||
uint32_t (*hash)(Thread*, object))
|
uint32_t (*hash)(Thread*, object))
|
||||||
{
|
{
|
||||||
PROTECT(t, map);
|
|
||||||
|
|
||||||
object array = hashMapArray(t, map);
|
object array = hashMapArray(t, map);
|
||||||
PROTECT(t, array);
|
PROTECT(t, array);
|
||||||
|
|
||||||
++ hashMapSize(t, map);
|
++ hashMapSize(t, map);
|
||||||
|
|
||||||
if (array == 0 or hashMapSize(t, map) >= arrayLength(t, array) * 2) {
|
if (array == 0 or hashMapSize(t, map) >= arrayLength(t, array) * 2) {
|
||||||
|
PROTECT(t, map);
|
||||||
|
PROTECT(t, key);
|
||||||
|
PROTECT(t, value);
|
||||||
|
|
||||||
hashMapGrow(t, map, hash);
|
hashMapGrow(t, map, hash);
|
||||||
array = hashMapArray(t, map);
|
array = hashMapArray(t, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned index = hash & (arrayLength(t, array) - 1);
|
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
||||||
object n = arrayBody(t, array)[index];
|
object n = arrayBody(t, array)[index];
|
||||||
|
|
||||||
n = makeTriple(t, key, value, n);
|
n = makeTriple(t, key, value, n);
|
||||||
@ -809,6 +820,40 @@ hashMapInsert(Thread* t, object map, object key, object value,
|
|||||||
set(t, arrayBody(t, array)[index], n);
|
set(t, arrayBody(t, array)[index], n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
hashMapIterator(Thread* t, object map)
|
||||||
|
{
|
||||||
|
object array = hashMapArray(t, map);
|
||||||
|
if (array) {
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, array); ++i) {
|
||||||
|
if (arrayBody(t, array)[i]) {
|
||||||
|
return makeHashMapIterator(t, map, arrayBody(t, array)[i], i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
hashMapIteratorNext(Thread* t, object it)
|
||||||
|
{
|
||||||
|
object map = hashMapIteratorMap(t, it);
|
||||||
|
object node = hashMapIteratorNode(t, it);
|
||||||
|
unsigned index = hashMapIteratorIndex(t, it);
|
||||||
|
|
||||||
|
if (tripleThird(t, node)) {
|
||||||
|
return makeHashMapIterator(t, map, tripleThird(t, node), index + 1);
|
||||||
|
} else {
|
||||||
|
object array = hashMapArray(t, map);
|
||||||
|
for (unsigned i = index; i < arrayLength(t, array); ++i) {
|
||||||
|
if (arrayBody(t, array)[i]) {
|
||||||
|
return makeHashMapIterator(t, map, arrayBody(t, array)[i], i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
listAppend(Thread* t, object list, object value)
|
listAppend(Thread* t, object list, object value)
|
||||||
{
|
{
|
||||||
@ -854,18 +899,19 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
PROTECT(t, interfaceTable);
|
PROTECT(t, interfaceTable);
|
||||||
|
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
object it = hmIterator(t, map);
|
object it = hashMapIterator(t, map);
|
||||||
PROTECT(t, it);
|
PROTECT(t, it);
|
||||||
|
|
||||||
for (; it; it = hmIteratorNext(t, it)) {
|
for (; it; it = hashMapIteratorNext(t, it)) {
|
||||||
object interface = resolveClass(t, hmIteratorKey(t, it));
|
object interface = resolveClass
|
||||||
|
(t, tripleFirst(t, hashMapIteratorNode(t, it)));
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
set(t, arrayBody(t, interfaceTable)[i++], interface);
|
set(t, arrayBody(t, interfaceTable)[i++], interface);
|
||||||
|
|
||||||
// we'll fill in this table in parseMethodTable():
|
// we'll fill in this table in parseMethodTable():
|
||||||
object vtable = makeArray
|
object vtable = makeArray
|
||||||
(t, arraySize(t, interfaceMethodTable(t, interface)));
|
(t, arrayLength(t, interfaceMethodTable(t, interface)));
|
||||||
set(t, arrayBody(t, interfaceTable)[i++], vtable);
|
set(t, arrayBody(t, interfaceTable)[i++], vtable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -873,6 +919,43 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
set(t, classInterfaceTable(t, class_), interfaceTable);
|
set(t, classInterfaceTable(t, class_), interfaceTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isReferenceField(Thread* t, object field)
|
||||||
|
{
|
||||||
|
switch (byteArrayBody(t, fieldSpec(t, field))[0]) {
|
||||||
|
case 'L':
|
||||||
|
case '[':
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
fieldSize(Thread* t, object field)
|
||||||
|
{
|
||||||
|
switch (byteArrayBody(t, fieldSpec(t, field))[0]) {
|
||||||
|
case 'B':
|
||||||
|
return 1;
|
||||||
|
case 'C':
|
||||||
|
case 'S':
|
||||||
|
case 'Z':
|
||||||
|
return 2;
|
||||||
|
case 'D':
|
||||||
|
case 'J':
|
||||||
|
return 8;
|
||||||
|
case 'F':
|
||||||
|
case 'I':
|
||||||
|
return 4;
|
||||||
|
case 'L':
|
||||||
|
case '[':
|
||||||
|
return sizeof(void*);
|
||||||
|
|
||||||
|
default: abort(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||||
{
|
{
|
||||||
@ -947,11 +1030,11 @@ parseCode(Thread* t, Stream& s, object pool)
|
|||||||
|
|
||||||
object eht = makeExceptionHandlerTable(t, ehtLength);
|
object eht = makeExceptionHandlerTable(t, ehtLength);
|
||||||
for (unsigned i = 0; i < ehtLength; ++i) {
|
for (unsigned i = 0; i < ehtLength; ++i) {
|
||||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht) + i;
|
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
||||||
eh->start = s.read2();
|
exceptionHandlerStart(eh) = s.read2();
|
||||||
eh->end = s.read2();
|
exceptionHandlerEnd(eh) = s.read2();
|
||||||
eh->ip = s.read2();
|
exceptionHandlerIp(eh) = s.read2();
|
||||||
eh->catchType = s.read2();
|
exceptionHandlerCatchType(eh) = s.read2();
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, codeExceptionHandlerTable(t, code), eht);
|
set(t, codeExceptionHandlerTable(t, code), eht);
|
||||||
@ -964,8 +1047,36 @@ parseCode(Thread* t, Stream& s, object pool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
parameterCount(Thread* t, object spec)
|
||||||
|
{
|
||||||
|
unsigned count = 0;
|
||||||
|
const char* s = reinterpret_cast<const char*>(byteArrayBody(t, spec));
|
||||||
|
++ s; // skip '('
|
||||||
|
while (*s and *s != ')') {
|
||||||
|
switch (*s) {
|
||||||
|
case 'L':
|
||||||
|
while (*s and *s != ';') ++ s;
|
||||||
|
++ s;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
while (*s == '[') ++ s;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
++ s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||||
{
|
{
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
@ -975,7 +1086,7 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
|
|
||||||
unsigned virtualCount = 0;
|
unsigned virtualCount = 0;
|
||||||
|
|
||||||
object superVirtualTable = classVirtualTable(t, super);
|
object superVirtualTable = classVirtualTable(t, classSuper(t, class_));
|
||||||
PROTECT(t, superVirtualTable);
|
PROTECT(t, superVirtualTable);
|
||||||
|
|
||||||
if (superVirtualTable) {
|
if (superVirtualTable) {
|
||||||
@ -1017,7 +1128,7 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
object value = makeMethod(t,
|
object value = makeMethod(t,
|
||||||
flags,
|
flags,
|
||||||
0, // offset
|
0, // offset
|
||||||
parameterCount(arrayBody(t, pool)[spec]),
|
parameterCount(t, arrayBody(t, pool)[spec]),
|
||||||
arrayBody(t, pool)[name],
|
arrayBody(t, pool)[name],
|
||||||
arrayBody(t, pool)[spec],
|
arrayBody(t, pool)[spec],
|
||||||
class_,
|
class_,
|
||||||
@ -1031,17 +1142,16 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
set(t, classInitializer(t, class_), value);
|
set(t, classInitializer(t, class_), value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object p = hashMapFindNode(t, map, method, methodHash, methodEqual);
|
object p = hashMapFindNode(t, map, value, methodHash, methodEqual);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
methodOffset(t, value) = methodOffset(t, tripleFirst(t, p));
|
methodOffset(t, value) = methodOffset(t, tripleFirst(t, p));
|
||||||
|
|
||||||
set(t, tripleSecond(t, p), value);
|
set(t, tripleSecond(t, p), value);
|
||||||
} else {
|
} else {
|
||||||
methodOffset(t, value) = offset++;
|
methodOffset(t, value) = virtualCount++;
|
||||||
|
|
||||||
listAppend(t, newVirtuals, value);
|
listAppend(t, newVirtuals, value);
|
||||||
++ virtualCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,8 +1278,9 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|||||||
|
|
||||||
case CONSTANT_Utf8: {
|
case CONSTANT_Utf8: {
|
||||||
unsigned length = s.read2();
|
unsigned length = s.read2();
|
||||||
object value = makeByteArray(t, length);
|
object value = makeByteArray(t, length + 1);
|
||||||
s.read(reinterpret_cast<uint8_t*>(byteArrayBody(t, value)), length);
|
s.read(reinterpret_cast<uint8_t*>(byteArrayBody(t, value)), length);
|
||||||
|
byteArrayBody(t, value)[length] = 0;
|
||||||
set(t, arrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1181,18 +1292,18 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|||||||
unsigned name = s.read2();
|
unsigned name = s.read2();
|
||||||
|
|
||||||
object class_ = makeClass(t,
|
object class_ = makeClass(t,
|
||||||
t->vm->nextClassId++,
|
flags,
|
||||||
0, // fixed size
|
0, // fixed size
|
||||||
0, // array size
|
0, // array size
|
||||||
0, // object mask
|
0, // object mask
|
||||||
flags,
|
|
||||||
arrayBody(t, pool)[name],
|
arrayBody(t, pool)[name],
|
||||||
0, // super
|
0, // super
|
||||||
0, // interfaces
|
0, // interfaces
|
||||||
|
0, // vtable
|
||||||
0, // fields
|
0, // fields
|
||||||
0, // methods
|
0, // methods
|
||||||
0, // static table
|
0, // static table
|
||||||
0); // initializers
|
0); // initializer
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
object super = resolveClass(t, arrayBody(t, pool)[s.read2()]);
|
object super = resolveClass(t, arrayBody(t, pool)[s.read2()]);
|
||||||
@ -2144,9 +2255,9 @@ run(Thread* t)
|
|||||||
object method = resolveMethod(t, codePool(t, code), index);
|
object method = resolveMethod(t, codePool(t, code), index);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, fieldClass(t, field));
|
object clinit = classInitializer(t, methodClass(t, method));
|
||||||
if (clinit) {
|
if (clinit) {
|
||||||
set(t, classInitializer(t, fieldClass(t, field)), 0);
|
set(t, classInitializer(t, methodClass(t, method)), 0);
|
||||||
code = clinit;
|
code = clinit;
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
parameterCount = 0;
|
parameterCount = 0;
|
||||||
@ -2416,9 +2527,9 @@ run(Thread* t)
|
|||||||
object class_ = resolveClass(t, codePool(t, code), index);
|
object class_ = resolveClass(t, codePool(t, code), index);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, fieldClass(t, field));
|
object clinit = classInitializer(t, class_);
|
||||||
if (clinit) {
|
if (clinit) {
|
||||||
set(t, classInitializer(t, fieldClass(t, field)), 0);
|
set(t, classInitializer(t, class_), 0);
|
||||||
code = clinit;
|
code = clinit;
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
parameterCount = 0;
|
parameterCount = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user