clean up sketch of parseClass() and friends; etc.

This commit is contained in:
Joel Dice 2007-06-17 22:09:02 -06:00
parent f99425d944
commit 1cb866aac1
5 changed files with 170 additions and 121 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);
} }

View File

@ -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))

View File

@ -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;