mirror of
https://github.com/corda/corda.git
synced 2025-01-16 01:40:17 +00:00
snapshot
This commit is contained in:
parent
1301a6a1c8
commit
4493fe824e
@ -1,12 +1,12 @@
|
|||||||
(type class
|
(type class
|
||||||
(uint32_t id)
|
(uint16_t flags)
|
||||||
(uint16_t fixedSize)
|
(uint16_t fixedSize)
|
||||||
(uint16_t arrayElementSize)
|
(uint16_t arrayElementSize)
|
||||||
(object objectMask)
|
(object objectMask)
|
||||||
(uint16_t flags)
|
|
||||||
(object name)
|
(object name)
|
||||||
(object super)
|
(object super)
|
||||||
(object interfaceTable)
|
(object interfaceTable)
|
||||||
|
(object virtualTable)
|
||||||
(object fieldTable)
|
(object fieldTable)
|
||||||
(object methodTable)
|
(object methodTable)
|
||||||
(object staticTable)
|
(object staticTable)
|
||||||
@ -72,6 +72,15 @@
|
|||||||
(object second)
|
(object second)
|
||||||
(object third))
|
(object third))
|
||||||
|
|
||||||
|
(type hashMap
|
||||||
|
(object size)
|
||||||
|
(object array))
|
||||||
|
|
||||||
|
(type list
|
||||||
|
(object size)
|
||||||
|
(object front)
|
||||||
|
(object rear))
|
||||||
|
|
||||||
(type trace
|
(type trace
|
||||||
(object method)
|
(object method)
|
||||||
(uint32_t ip)
|
(uint32_t ip)
|
||||||
@ -148,7 +157,7 @@
|
|||||||
(type double
|
(type double
|
||||||
(uint64_t value))
|
(uint64_t value))
|
||||||
|
|
||||||
(type rawArray
|
(type array
|
||||||
(array object body))
|
(array object body))
|
||||||
|
|
||||||
(type objectArray
|
(type objectArray
|
||||||
|
327
src/vm.cpp
327
src/vm.cpp
@ -17,21 +17,23 @@ typedef unsigned Type;
|
|||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
enum ObjectType {
|
|
||||||
NullType,
|
|
||||||
CollectedType,
|
|
||||||
|
|
||||||
#include "type-enums.h"
|
|
||||||
|
|
||||||
OtherType
|
|
||||||
};
|
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
Type typeOf(object);
|
|
||||||
object& objectClass(object);
|
|
||||||
void assert(Thread* t, bool v);
|
void assert(Thread* t, bool v);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T&
|
||||||
|
cast(object p, unsigned offset)
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<T*>(static_cast<uint8_t*>(p) + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
object&
|
||||||
|
objectClass(object o)
|
||||||
|
{
|
||||||
|
return cast<object>(o, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#include "type-header.h"
|
#include "type-header.h"
|
||||||
|
|
||||||
class Machine {
|
class Machine {
|
||||||
@ -395,13 +397,6 @@ make(Thread* t, object class_)
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T&
|
|
||||||
cast(object p, unsigned offset)
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<T*>(static_cast<uint8_t*>(p) + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
object
|
object
|
||||||
makeString(Thread* t, const char* format, ...)
|
makeString(Thread* t, const char* format, ...)
|
||||||
{
|
{
|
||||||
@ -493,15 +488,16 @@ makeNoSuchMethodError(Thread* t, object message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
isLongOrDouble(object o)
|
isLongOrDouble(Thread* t, object o)
|
||||||
{
|
{
|
||||||
return typeOf(o) == LongType or typeOf(o) == DoubleType;
|
return objectClass(o) == t->vm->longClass
|
||||||
|
or objectClass(o) == t->vm->doubleClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
getField(Thread* t, object instance, object field)
|
getField(Thread* t, object instance, object field)
|
||||||
{
|
{
|
||||||
switch (rawArrayBody(t, fieldSpec(t, field))[0]) {
|
switch (arrayBody(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':
|
||||||
@ -529,7 +525,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 (rawArrayBody(t, fieldSpec(t, field))[0]) {
|
switch (arrayBody(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;
|
||||||
@ -565,14 +561,14 @@ setField(Thread* t, object o, object field, object value)
|
|||||||
inline object
|
inline object
|
||||||
getStatic(Thread* t, object field)
|
getStatic(Thread* t, object field)
|
||||||
{
|
{
|
||||||
return rawArrayBody(t, classStaticTable(t, fieldClass(t, field)))
|
return arrayBody(t, classStaticTable(t, fieldClass(t, field)))
|
||||||
[fieldOffset(t, field)];
|
[fieldOffset(t, field)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
setStatic(Thread* t, object field, object value)
|
setStatic(Thread* t, object field, object value)
|
||||||
{
|
{
|
||||||
set(t, rawArrayBody(t, classStaticTable(t, fieldClass(t, field)))
|
set(t, arrayBody(t, classStaticTable(t, fieldClass(t, field)))
|
||||||
[fieldOffset(t, field)], value);
|
[fieldOffset(t, field)], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,20 +579,18 @@ instanceOf(Thread* t, object class_, object o)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeOf(class_) == InterfaceType) {
|
if (objectClass(class_) == t->vm->interfaceClass) {
|
||||||
Type id = interfaceId(t, class_);
|
|
||||||
for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) {
|
for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) {
|
||||||
object itable = classInterfaceTable(t, oc);
|
object itable = classInterfaceTable(t, oc);
|
||||||
for (unsigned i = 0; i < rawArrayLength(t, itable); i += 2) {
|
for (unsigned i = 0; i < arrayLength(t, itable); i += 2) {
|
||||||
if (interfaceId(t, rawArrayBody(t, itable)[i]) == id) {
|
if (arrayBody(t, itable)[i] == class_) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Type id = classId(t, class_);
|
|
||||||
for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) {
|
for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) {
|
||||||
if (classId(t, oc) == id) {
|
if (oc == class_) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -608,11 +602,11 @@ instanceOf(Thread* t, object class_, object o)
|
|||||||
object
|
object
|
||||||
findInterfaceMethod(Thread* t, object method, object o)
|
findInterfaceMethod(Thread* t, object method, object o)
|
||||||
{
|
{
|
||||||
Type id = interfaceId(t, methodClass(t, method));
|
object interface = methodClass(t, method);
|
||||||
object itable = classInterfaceTable(t, objectClass(o));
|
object itable = classInterfaceTable(t, objectClass(o));
|
||||||
for (unsigned i = 0; i < rawArrayLength(t, itable); i += 2) {
|
for (unsigned i = 0; i < arrayLength(t, itable); i += 2) {
|
||||||
if (interfaceId(t, rawArrayBody(t, itable)[i]) == id) {
|
if (arrayBody(t, itable)[i] == interface) {
|
||||||
return rawArrayBody(t, rawArrayBody(t, itable)[i + 1])
|
return arrayBody(t, arrayBody(t, itable)[i + 1])
|
||||||
[methodOffset(t, method)];
|
[methodOffset(t, method)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,7 +616,7 @@ findInterfaceMethod(Thread* t, object method, object o)
|
|||||||
inline object
|
inline object
|
||||||
findMethod(Thread* t, object method, object class_)
|
findMethod(Thread* t, object method, object class_)
|
||||||
{
|
{
|
||||||
return rawArrayBody(t, classMethodTable(t, class_))
|
return arrayBody(t, classVirtualTable(t, class_))
|
||||||
[methodOffset(t, method)];
|
[methodOffset(t, method)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,9 +629,8 @@ findVirtualMethod(Thread* t, object method, object o)
|
|||||||
bool
|
bool
|
||||||
isSuperclass(Thread* t, object class_, object base)
|
isSuperclass(Thread* t, object class_, object base)
|
||||||
{
|
{
|
||||||
Type id = classId(t, class_);
|
|
||||||
for (object oc = classSuper(t, base); oc; oc = classSuper(t, oc)) {
|
for (object oc = classSuper(t, base); oc; oc = classSuper(t, oc)) {
|
||||||
if (classId(t, oc) == id) {
|
if (oc == class_) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -668,8 +661,8 @@ find(Thread* t, object class_, object table, object reference,
|
|||||||
{
|
{
|
||||||
object n = referenceName(t, reference);
|
object n = referenceName(t, reference);
|
||||||
object s = referenceSpec(t, reference);
|
object s = referenceSpec(t, reference);
|
||||||
for (unsigned i = 0; i < rawArrayLength(t, table); ++i) {
|
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
||||||
object field = rawArrayBody(t, table)[i];
|
object field = arrayBody(t, table)[i];
|
||||||
if (strcmp(byteArrayBody(t, name(t, field)),
|
if (strcmp(byteArrayBody(t, name(t, field)),
|
||||||
byteArrayBody(t, n)) == 0 and
|
byteArrayBody(t, n)) == 0 and
|
||||||
strcmp(byteArrayBody(t, spec(t, field)),
|
strcmp(byteArrayBody(t, spec(t, field)),
|
||||||
@ -711,11 +704,18 @@ hash(const int8_t* s, unsigned length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t
|
inline uint32_t
|
||||||
hashByteArray(Thread* t, object array)
|
byteArrayHash(Thread* t, object array)
|
||||||
{
|
{
|
||||||
return hash(byteArrayBody(t, array), byteArrayLength(t, array) - 1);
|
return hash(byteArrayBody(t, array), byteArrayLength(t, array) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint32_t
|
||||||
|
methodHash(Thread* t, object method)
|
||||||
|
{
|
||||||
|
return byteArrayHash(t, methodName(t, method))
|
||||||
|
^ byteArrayHash(t, methodSpec(t, method));
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
byteArrayEqual(Thread* t, object a, object b)
|
byteArrayEqual(Thread* t, object a, object b)
|
||||||
{
|
{
|
||||||
@ -725,32 +725,104 @@ byteArrayEqual(Thread* t, object a, object b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
hashMapFind(Thread* t, object map, uint32_t hash, object key,
|
hashMapFindNode(Thread* t, object map, object key,
|
||||||
bool (*equal)(Thread*, object, object))
|
uint32_t (*hash)(Thread*, object),
|
||||||
|
bool (*equal)(Thread*, object, object))
|
||||||
{
|
{
|
||||||
unsigned index = hash & (rawArrayLength(t, map) - 1);
|
object array = hashMapArray(t, map);
|
||||||
object n = rawArrayBody(t, map)[index];
|
if (array) {
|
||||||
while (n) {
|
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
||||||
if (equal(t, tripleFirst(t, n), key)) {
|
object n = arrayBody(t, array)[index];
|
||||||
return tripleSecond(t, n);
|
while (n) {
|
||||||
|
if (equal(t, tripleFirst(t, n), key)) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = tripleThird(t, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = tripleThird(t, n);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
inline object
|
||||||
hashMapInsert(Thread* t, object map, uint32_t hash, object key, object value)
|
hashMapFind(Thread* t, object map, object key,
|
||||||
|
uint32_t (*hash)(Thread*, object),
|
||||||
|
bool (*equal)(Thread*, object, object))
|
||||||
{
|
{
|
||||||
unsigned index = hash & (rawArrayLength(t, map) - 1);
|
object n = hashMapFindNode(t, map, key, hash, equal);
|
||||||
object n = rawArrayBody(t, map)[index];
|
return (n ? tripleSecond(t, n) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hashMapGrow(Thread* t, object map, uint32_t (*hash)(Thread*, object))
|
||||||
|
{
|
||||||
PROTECT(t, map);
|
PROTECT(t, map);
|
||||||
|
|
||||||
|
object oldArray = hashMapArray(t, map);
|
||||||
|
unsigned oldLength = (oldArray ? arrayLength(t, oldArray) : 0);
|
||||||
|
PROTECT(t, oldArray);
|
||||||
|
|
||||||
|
unsigned newLength = (oldLength ? oldLength * 2 : 32);
|
||||||
|
object newArray = makeArray(t, newLength);
|
||||||
|
memset(arrayBody(t, newArray), o, newLength * sizeof(object));
|
||||||
|
|
||||||
|
if (oldArray) {
|
||||||
|
for (unsigned i = 0; i < length; ++i) {
|
||||||
|
object next;
|
||||||
|
for (object p = arrayBody(t, oldArray)[i]; p; p = next) {
|
||||||
|
next = tripleThird(t, p);
|
||||||
|
|
||||||
|
object key = tripleFirst(t, p);
|
||||||
|
unsigned index = hash(t, key) & (newLength - 1);
|
||||||
|
object n = arrayBody(t, newArray)[index];
|
||||||
|
|
||||||
|
set(t, tripleThird(t, p), n);
|
||||||
|
set(t, arrayBody(t, newArray)[index], p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set(t, hashMapArray(t, map), newArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hashMapInsert(Thread* t, object map, object key, object value,
|
||||||
|
uint32_t (*hash)(Thread*, object))
|
||||||
|
{
|
||||||
|
PROTECT(t, map);
|
||||||
|
|
||||||
|
object array = hashMapArray(t, map);
|
||||||
|
PROTECT(t, array);
|
||||||
|
|
||||||
|
++ hashMapSize(t, map);
|
||||||
|
|
||||||
|
if (array == 0 or hashMapSize(t, map) >= arrayLength(t, array) * 2) {
|
||||||
|
hashMapGrow(t, map, hash);
|
||||||
|
array = hashMapArray(t, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned index = hash & (arrayLength(t, array) - 1);
|
||||||
|
object n = arrayBody(t, array)[index];
|
||||||
|
|
||||||
n = makeTriple(t, key, value, n);
|
n = makeTriple(t, key, value, n);
|
||||||
|
|
||||||
set(t, rawArrayBody(t, map)[index], n);
|
set(t, arrayBody(t, array)[index], n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
listAppend(Thread* t, object list, object value)
|
||||||
|
{
|
||||||
|
PROTECT(t, list);
|
||||||
|
|
||||||
|
++ listSize(t, list);
|
||||||
|
|
||||||
|
object p = makePair(t, value, 0);
|
||||||
|
if (listFront(t, list)) {
|
||||||
|
set(t, pairSecond(t, listRear(t, list)), p);
|
||||||
|
} else {
|
||||||
|
set(t, listFront(t, list), p);
|
||||||
|
}
|
||||||
|
set(t, listRear(t, list), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -765,23 +837,23 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
object superInterfaces = classInterfaceTable(t, classSuper(t, class_));
|
object superInterfaces = classInterfaceTable(t, classSuper(t, class_));
|
||||||
PROTECT(t, superInterfaces);
|
PROTECT(t, superInterfaces);
|
||||||
|
|
||||||
for (unsigned i = 0; i < rawArrayLength(t, superInterfaces); i += 2) {
|
for (unsigned i = 0; i < arrayLength(t, superInterfaces); i += 2) {
|
||||||
object name = interfaceName(t, rawArrayBody(t, superInterfaces)[i]);
|
object name = interfaceName(t, arrayBody(t, superInterfaces)[i]);
|
||||||
hashMapInsert(t, map, hashByteArray(t, name), name, name);
|
hashMapInsert(t, map, name, name, byteArrayHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned count = s.read2();
|
unsigned count = s.read2();
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
object name = rawArrayBody(t, pool)[s.read2()];
|
object name = arrayBody(t, pool)[s.read2()];
|
||||||
hashMapInsert(t, map, hashByteArray(t, name), name, name);
|
hashMapInsert(t, map, name, name, byteArrayHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
object interfaceTable = 0;
|
object interfaceTable = 0;
|
||||||
if (hashMapSize(t, map)) {
|
if (hashMapSize(t, map)) {
|
||||||
interfaceTable = makeRawArray(t, hashMapSize(t, map));
|
interfaceTable = makeArray(t, hashMapSize(t, map));
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (object it = hmIterator(t, map); it; it = hmIteratorNext(t, it)) {
|
for (object it = hmIterator(t, map); it; it = hmIteratorNext(t, it)) {
|
||||||
set(t, rawArrayBody(t, interfaceTable)[i], hmIteratorKey(t, it));
|
set(t, arrayBody(t, interfaceTable)[i], hmIteratorKey(t, it));
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -801,7 +873,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
= classFixedSize(t, classSuper(t, class_)) * sizeof(void*);
|
= classFixedSize(t, classSuper(t, class_)) * sizeof(void*);
|
||||||
unsigned staticOffset = 0;
|
unsigned staticOffset = 0;
|
||||||
|
|
||||||
object fieldTable = makeRawArray(t, count);
|
object fieldTable = makeArray(t, count);
|
||||||
PROTECT(t, fieldTable);
|
PROTECT(t, fieldTable);
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
@ -818,8 +890,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
object value = makeField(t,
|
object value = makeField(t,
|
||||||
flags,
|
flags,
|
||||||
0, // offset
|
0, // offset
|
||||||
rawArrayBody(t, pool)[name],
|
arrayBody(t, pool)[name],
|
||||||
rawArrayBody(t, pool)[spec],
|
arrayBody(t, pool)[spec],
|
||||||
class_);
|
class_);
|
||||||
|
|
||||||
if (flags & ACC_STATIC) {
|
if (flags & ACC_STATIC) {
|
||||||
@ -833,14 +905,14 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
memberOffset += fieldSize(t, value);
|
memberOffset += fieldSize(t, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, rawArrayBody(t, fieldTable)[i], value);
|
set(t, arrayBody(t, fieldTable)[i], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, classFieldTable(t, class_), fieldTable);
|
set(t, classFieldTable(t, class_), fieldTable);
|
||||||
|
|
||||||
if (staticOffset) {
|
if (staticOffset) {
|
||||||
object staticTable = makeRawArray(t, staticOffset);
|
object staticTable = makeArray(t, staticOffset);
|
||||||
memset(rawArrayBody(t, staticTable), 0, staticOffset * sizeof(void*));
|
memset(arrayBody(t, staticTable), 0, staticOffset * sizeof(void*));
|
||||||
|
|
||||||
set(t, classStaticTable(t, class_), staticTable);
|
set(t, classStaticTable(t, class_), staticTable);
|
||||||
}
|
}
|
||||||
@ -864,14 +936,14 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
|
|
||||||
unsigned virtualCount = 0;
|
unsigned virtualCount = 0;
|
||||||
|
|
||||||
object superVTable = classVTable(t, super);
|
object superVirtualTable = classVirtualTable(t, super);
|
||||||
PROTECT(t, superVTable);
|
PROTECT(t, superVirtualTable);
|
||||||
|
|
||||||
if (superVTable) {
|
if (superVirtualTable) {
|
||||||
virtualCount = rawArrayLength(t, superVTable);
|
virtualCount = arrayLength(t, superVirtualTable);
|
||||||
for (unsigned i = 0; i < virtualCount; ++i) {
|
for (unsigned i = 0; i < virtualCount; ++i) {
|
||||||
object method = rawArrayBody(t, superVTable)[i];
|
object method = arrayBody(t, superVirtualTable)[i];
|
||||||
hashMapInsert(t, map, hashMethod(t, method), method, method);
|
hashMapInsert(t, map, method, method, byteArrayHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,7 +952,7 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
|
|
||||||
unsigned count = s.read2();
|
unsigned count = s.read2();
|
||||||
if (count) {
|
if (count) {
|
||||||
object methodTable = makeRawArray(t, count);
|
object methodTable = makeArray(t, count);
|
||||||
PROTECT(t, methodTable);
|
PROTECT(t, methodTable);
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
@ -891,7 +963,7 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
object code = 0;
|
object code = 0;
|
||||||
unsigned attributeCount = s.read2();
|
unsigned attributeCount = s.read2();
|
||||||
for (unsigned j = 0; j < attributeCount; ++j) {
|
for (unsigned j = 0; j < attributeCount; ++j) {
|
||||||
object name = rawArrayBody(t, pool)[s.read2()];
|
object name = arrayBody(t, pool)[s.read2()];
|
||||||
if (strcmp(reinterpret_cast<const int8_t*>("Code"),
|
if (strcmp(reinterpret_cast<const int8_t*>("Code"),
|
||||||
byteArrayBody(t, name)) == 0)
|
byteArrayBody(t, name)) == 0)
|
||||||
{
|
{
|
||||||
@ -904,15 +976,14 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
object value = makeMethod(t,
|
object value = makeMethod(t,
|
||||||
flags,
|
flags,
|
||||||
0, // offset
|
0, // offset
|
||||||
parameterCount(rawArrayBody(t, pool)[spec]),
|
parameterCount(arrayBody(t, pool)[spec]),
|
||||||
rawArrayBody(t, pool)[name],
|
arrayBody(t, pool)[name],
|
||||||
rawArrayBody(t, pool)[spec],
|
arrayBody(t, pool)[spec],
|
||||||
class_,
|
class_,
|
||||||
code);
|
code);
|
||||||
|
|
||||||
if ((flags & ACC_STATIC) == 0) {
|
if ((flags & ACC_STATIC) == 0) {
|
||||||
object p = hashMapFindNode
|
object p = hashMapFindNode(t, map, method, methodHash, methodEqual);
|
||||||
(t, map, hashMethod(t, method), method, methodEqual);
|
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
methodOffset(t, value) = methodOffset(t, tripleFirst(t, p));
|
methodOffset(t, value) = methodOffset(t, tripleFirst(t, p));
|
||||||
@ -926,31 +997,30 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, rawArrayBody(t, methodTable)[i], value);
|
set(t, arrayBody(t, methodTable)[i], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, classMethodTable(t, class_), methodTable);
|
set(t, classMethodTable(t, class_), methodTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virtualCount) {
|
if (virtualCount) {
|
||||||
object vtable = makeRawArray(t, virtualCount);
|
object vtable = makeArray(t, virtualCount);
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
|
||||||
if (superVTable) {
|
if (superVirtualTable) {
|
||||||
for (; i < rawArrayLength(t, superVTable); ++i) {
|
for (; i < arrayLength(t, superVirtualTable); ++i) {
|
||||||
object method = rawArrayBody(t, superVTable)[i];
|
object method = arrayBody(t, superVirtualTable)[i];
|
||||||
method = hashMapFind
|
method = hashMapFind(t, map, method, methodHash, methodEqual);
|
||||||
(t, map, hashMethod(t, method), method, methodEqual);
|
|
||||||
|
|
||||||
set(t, rawArrayBody(t, vtable)[i], method);
|
set(t, arrayBody(t, vtable)[i], method);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (object p = listFront(t, newVirtuals); p; p = pairSecond(t, p)) {
|
for (object p = listFront(t, newVirtuals); p; p = pairSecond(t, p)) {
|
||||||
set(t, rawArrayBody(t, vtable)[i++], pairFirst(t, p));
|
set(t, arrayBody(t, vtable)[i++], pairFirst(t, p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, classVTable(t, class_), vtable);
|
set(t, classVirtualTable(t, class_), vtable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,63 +1047,63 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|||||||
s.read2(); // major version
|
s.read2(); // major version
|
||||||
|
|
||||||
unsigned poolCount = s.read2();
|
unsigned poolCount = s.read2();
|
||||||
object pool = makeRawArray(t, poolCount);
|
object pool = makeArray(t, poolCount);
|
||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
for (unsigned i = 0; i < poolCount; ++i) {
|
for (unsigned i = 0; i < poolCount; ++i) {
|
||||||
switch (s.read1()) {
|
switch (s.read1()) {
|
||||||
case CONSTANT_Class: {
|
case CONSTANT_Class: {
|
||||||
set(t, rawArrayBody(t, pool)[i], rawArrayBody(t, pool)[s.read2()]);
|
set(t, arrayBody(t, pool)[i], arrayBody(t, pool)[s.read2()]);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_Fieldref:
|
case CONSTANT_Fieldref:
|
||||||
case CONSTANT_Methodref:
|
case CONSTANT_Methodref:
|
||||||
case CONSTANT_InterfaceMethodref: {
|
case CONSTANT_InterfaceMethodref: {
|
||||||
object c = rawArrayBody(t, pool)[s.read2()];
|
object c = arrayBody(t, pool)[s.read2()];
|
||||||
object nameAndType = rawArrayBody(t, pool)[s.read2()];
|
object nameAndType = arrayBody(t, pool)[s.read2()];
|
||||||
object value = makeReference
|
object value = makeReference
|
||||||
(t, c, pairFirst(t, nameAndType), pairSecond(t, nameAndType));
|
(t, c, pairFirst(t, nameAndType), pairSecond(t, nameAndType));
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_String: {
|
case CONSTANT_String: {
|
||||||
object bytes = rawArrayBody(t, pool)[s.read2()];
|
object bytes = arrayBody(t, pool)[s.read2()];
|
||||||
object value = makeString(t, bytes, 0, byteArrayLength(t, bytes), 0);
|
object value = makeString(t, bytes, 0, byteArrayLength(t, bytes), 0);
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_Integer: {
|
case CONSTANT_Integer: {
|
||||||
object value = makeInt(t, s.read4());
|
object value = makeInt(t, s.read4());
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_Float: {
|
case CONSTANT_Float: {
|
||||||
object value = makeFloat(t, s.readFloat());
|
object value = makeFloat(t, s.readFloat());
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_Long: {
|
case CONSTANT_Long: {
|
||||||
object value = makeLong(t, s.read8());
|
object value = makeLong(t, s.read8());
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_Double: {
|
case CONSTANT_Double: {
|
||||||
object value = makeLong(t, s.readDouble());
|
object value = makeLong(t, s.readDouble());
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_NameAndType: {
|
case CONSTANT_NameAndType: {
|
||||||
object name = rawArrayBody(t, pool)[s.read2()];
|
object name = arrayBody(t, pool)[s.read2()];
|
||||||
object type = rawArrayBody(t, pool)[s.read2()];
|
object type = arrayBody(t, pool)[s.read2()];
|
||||||
object value = makePair(t, name, type);
|
object value = makePair(t, name, type);
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONSTANT_Utf8: {
|
case CONSTANT_Utf8: {
|
||||||
unsigned length = s.read2();
|
unsigned length = s.read2();
|
||||||
object value = makeByteArray(t, length);
|
object value = makeByteArray(t, length);
|
||||||
s.read(reinterpret_cast<uint8_t*>(byteArrayBody(t, value)), length);
|
s.read(reinterpret_cast<uint8_t*>(byteArrayBody(t, value)), length);
|
||||||
set(t, rawArrayBody(t, pool)[i], value);
|
set(t, arrayBody(t, pool)[i], value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: abort(t);
|
default: abort(t);
|
||||||
@ -1049,7 +1119,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|||||||
0, // array size
|
0, // array size
|
||||||
0, // object mask
|
0, // object mask
|
||||||
flags,
|
flags,
|
||||||
rawArrayBody(t, pool)[name],
|
arrayBody(t, pool)[name],
|
||||||
0, // super
|
0, // super
|
||||||
0, // interfaces
|
0, // interfaces
|
||||||
0, // fields
|
0, // fields
|
||||||
@ -1058,7 +1128,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|||||||
0); // initializers
|
0); // initializers
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
object super = resolveClass(t, rawArrayBody(t, pool)[s.read2()]);
|
object super = resolveClass(t, arrayBody(t, pool)[s.read2()]);
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
set(t, classSuper(t, class_), super);
|
set(t, classSuper(t, class_), super);
|
||||||
@ -1078,8 +1148,8 @@ resolveClass(Thread* t, object spec)
|
|||||||
PROTECT(t, spec);
|
PROTECT(t, spec);
|
||||||
ACQUIRE(t, t->vm->classLock);
|
ACQUIRE(t, t->vm->classLock);
|
||||||
|
|
||||||
uint32_t h = hashByteArray(t, spec);
|
object class_ = hashMapFind
|
||||||
object class_ = hashMapFind(t, t->vm->classMap, h, spec, byteArrayEqual);
|
(t, t->vm->classMap, spec, byteArrayHash, byteArrayEqual);
|
||||||
if (class_ == 0) {
|
if (class_ == 0) {
|
||||||
unsigned size;
|
unsigned size;
|
||||||
const uint8_t* data = t->vm->classFinder->find
|
const uint8_t* data = t->vm->classFinder->find
|
||||||
@ -1093,8 +1163,7 @@ resolveClass(Thread* t, object spec)
|
|||||||
|
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
// cache class
|
hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash);
|
||||||
hashMapInsert(t, t->vm->classMap, h, spec, class_);
|
|
||||||
} else {
|
} else {
|
||||||
object message = makeString(t, "%s", byteArrayBody(t, spec));
|
object message = makeString(t, "%s", byteArrayBody(t, spec));
|
||||||
t->exception = makeClassNotFoundException(t, message);
|
t->exception = makeClassNotFoundException(t, message);
|
||||||
@ -1106,14 +1175,14 @@ resolveClass(Thread* t, object spec)
|
|||||||
inline object
|
inline object
|
||||||
resolveClass(Thread* t, object pool, unsigned index)
|
resolveClass(Thread* t, object pool, unsigned index)
|
||||||
{
|
{
|
||||||
object o = rawArrayBody(t, pool)[index];
|
object o = arrayBody(t, pool)[index];
|
||||||
if (typeOf(o) == ByteArrayType) {
|
if (objectClass(o) == t->vm->byteArrayClass) {
|
||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
o = resolveClass(t, o);
|
o = resolveClass(t, o);
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
set(t, rawArrayBody(t, pool)[index], o);
|
set(t, arrayBody(t, pool)[index], o);
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@ -1122,7 +1191,7 @@ inline object
|
|||||||
resolveClass(Thread* t, object container, object& (*class_)(Thread*, object))
|
resolveClass(Thread* t, object container, object& (*class_)(Thread*, object))
|
||||||
{
|
{
|
||||||
object o = class_(t, container);
|
object o = class_(t, container);
|
||||||
if (typeOf(o) == ByteArrayType) {
|
if (objectClass(o) == t->vm->byteArrayClass) {
|
||||||
PROTECT(t, container);
|
PROTECT(t, container);
|
||||||
|
|
||||||
o = resolveClass(t, o);
|
o = resolveClass(t, o);
|
||||||
@ -1137,17 +1206,17 @@ inline object
|
|||||||
resolve(Thread* t, object pool, unsigned index,
|
resolve(Thread* t, object pool, unsigned index,
|
||||||
object (*find)(Thread*, object, object))
|
object (*find)(Thread*, object, object))
|
||||||
{
|
{
|
||||||
object o = rawArrayBody(t, pool)[index];
|
object o = arrayBody(t, pool)[index];
|
||||||
if (typeOf(o) == ReferenceType) {
|
if (objectClass(o) == t->vm->byteArrayClass) {
|
||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
object class_ = resolveClass(t, o, referenceClass);
|
object class_ = resolveClass(t, o, referenceClass);
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
o = find(t, class_, rawArrayBody(t, pool)[index]);
|
o = find(t, class_, arrayBody(t, pool)[index]);
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
set(t, rawArrayBody(t, pool)[index], o);
|
set(t, arrayBody(t, pool)[index], o);
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@ -1297,7 +1366,7 @@ run(Thread* t)
|
|||||||
case arraylength: {
|
case arraylength: {
|
||||||
object array = pop(t);
|
object array = pop(t);
|
||||||
if (LIKELY(array)) {
|
if (LIKELY(array)) {
|
||||||
if (typeOf(array) == ObjectArrayType) {
|
if (objectClass(array) == t->vm->objectArrayClass) {
|
||||||
push(t, makeInt(t, objectArrayLength(t, array)));
|
push(t, makeInt(t, objectArrayLength(t, array)));
|
||||||
} else {
|
} else {
|
||||||
// for all other array types, the length follow the class pointer.
|
// for all other array types, the length follow the class pointer.
|
||||||
@ -1494,7 +1563,7 @@ run(Thread* t)
|
|||||||
|
|
||||||
case dup2: {
|
case dup2: {
|
||||||
object first = stack[sp - 1];
|
object first = stack[sp - 1];
|
||||||
if (isLongOrDouble(first)) {
|
if (isLongOrDouble(t, first)) {
|
||||||
push(t, first);
|
push(t, first);
|
||||||
} else {
|
} else {
|
||||||
object second = stack[sp - 2];
|
object second = stack[sp - 2];
|
||||||
@ -1507,7 +1576,7 @@ run(Thread* t)
|
|||||||
object first = pop(t);
|
object first = pop(t);
|
||||||
object second = pop(t);
|
object second = pop(t);
|
||||||
|
|
||||||
if (isLongOrDouble(first)) {
|
if (isLongOrDouble(t, first)) {
|
||||||
push(t, first);
|
push(t, first);
|
||||||
push(t, second);
|
push(t, second);
|
||||||
push(t, first);
|
push(t, first);
|
||||||
@ -1525,8 +1594,8 @@ run(Thread* t)
|
|||||||
object first = pop(t);
|
object first = pop(t);
|
||||||
object second = pop(t);
|
object second = pop(t);
|
||||||
|
|
||||||
if (isLongOrDouble(first)) {
|
if (isLongOrDouble(t, first)) {
|
||||||
if (isLongOrDouble(second)) {
|
if (isLongOrDouble(t, second)) {
|
||||||
push(t, first);
|
push(t, first);
|
||||||
push(t, second);
|
push(t, second);
|
||||||
push(t, first);
|
push(t, first);
|
||||||
@ -1539,7 +1608,7 @@ run(Thread* t)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object third = pop(t);
|
object third = pop(t);
|
||||||
if (isLongOrDouble(third)) {
|
if (isLongOrDouble(t, third)) {
|
||||||
push(t, second);
|
push(t, second);
|
||||||
push(t, first);
|
push(t, first);
|
||||||
push(t, third);
|
push(t, third);
|
||||||
@ -2188,7 +2257,7 @@ run(Thread* t)
|
|||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case ldc: {
|
case ldc: {
|
||||||
push(t, rawArrayBody(t, codePool(t, code))[codeBody(t, code)[ip++]]);
|
push(t, arrayBody(t, codePool(t, code))[codeBody(t, code)[ip++]]);
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case ldc_w:
|
case ldc_w:
|
||||||
@ -2196,7 +2265,7 @@ run(Thread* t)
|
|||||||
uint8_t index1 = codeBody(t, code)[ip++];
|
uint8_t index1 = codeBody(t, code)[ip++];
|
||||||
uint8_t index2 = codeBody(t, code)[ip++];
|
uint8_t index2 = codeBody(t, code)[ip++];
|
||||||
|
|
||||||
push(t, rawArrayBody(t, codePool(t, code))[(index1 << 8) | index2]);
|
push(t, arrayBody(t, codePool(t, code))[(index1 << 8) | index2]);
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case ldiv: {
|
case ldiv: {
|
||||||
@ -2362,7 +2431,7 @@ run(Thread* t)
|
|||||||
|
|
||||||
case pop2: {
|
case pop2: {
|
||||||
object top = stack[sp - 1];
|
object top = stack[sp - 1];
|
||||||
if (isLongOrDouble(top)) {
|
if (isLongOrDouble(t, top)) {
|
||||||
-- sp;
|
-- sp;
|
||||||
} else {
|
} else {
|
||||||
sp -= 2;
|
sp -= 2;
|
||||||
@ -2558,7 +2627,7 @@ run(Thread* t)
|
|||||||
uint16_t catchType = exceptionHandlerCatchType(eh);
|
uint16_t catchType = exceptionHandlerCatchType(eh);
|
||||||
if (catchType == 0 or
|
if (catchType == 0 or
|
||||||
instanceOf(t,
|
instanceOf(t,
|
||||||
rawArrayBody(t, codePool(t, code))[catchType],
|
arrayBody(t, codePool(t, code))[catchType],
|
||||||
exception))
|
exception))
|
||||||
{
|
{
|
||||||
sp = frameStackBase(t, frame);
|
sp = frameStackBase(t, frame);
|
||||||
|
Loading…
Reference in New Issue
Block a user