mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
finish sketch of resolveField() and resolveMethod() implementations
This commit is contained in:
parent
ef48f14839
commit
7904fa40a3
@ -16,6 +16,7 @@
|
|||||||
(uint16_t flags)
|
(uint16_t flags)
|
||||||
(uint16_t offset)
|
(uint16_t offset)
|
||||||
(object name)
|
(object name)
|
||||||
|
(object spec)
|
||||||
(object class))
|
(object class))
|
||||||
|
|
||||||
(type method
|
(type method
|
||||||
@ -111,7 +112,13 @@
|
|||||||
(type error
|
(type error
|
||||||
(extends throwable))
|
(extends throwable))
|
||||||
|
|
||||||
(type StackOverflowError
|
(type stackOverflowError
|
||||||
|
(extends error))
|
||||||
|
|
||||||
|
(type noSuchFieldError
|
||||||
|
(extends error))
|
||||||
|
|
||||||
|
(type noSuchMethodError
|
||||||
(extends error))
|
(extends error))
|
||||||
|
|
||||||
(type byte
|
(type byte
|
||||||
|
104
src/vm.cpp
104
src/vm.cpp
@ -418,6 +418,22 @@ makeStackOverflowError(Thread* t)
|
|||||||
return makeStackOverflowError(t, 0, makeTrace(t));
|
return makeStackOverflowError(t, 0, makeTrace(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
makeNoSuchFieldError(Thread* t, object message)
|
||||||
|
{
|
||||||
|
PROTECT(t, message);
|
||||||
|
object trace = makeTrace(t);
|
||||||
|
return makeNoSuchFieldError(t, message, trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
makeNoSuchMethodError(Thread* t, object message)
|
||||||
|
{
|
||||||
|
PROTECT(t, message);
|
||||||
|
object trace = makeTrace(t);
|
||||||
|
return makeNoSuchMethodError(t, message, trace);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
isLongOrDouble(object o)
|
isLongOrDouble(object o)
|
||||||
{
|
{
|
||||||
@ -518,60 +534,73 @@ isSuperclass(Thread* t, object class_, object base)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
strcmp(const int8_t* a, const int8_t* b)
|
||||||
|
{
|
||||||
|
return ::strcmp(reinterpret_cast<const char*>(a),
|
||||||
|
reinterpret_cast<const char*>(b));
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
isSpecialMethod(Thread* t, object method, object class_)
|
isSpecialMethod(Thread* t, object method, object class_)
|
||||||
{
|
{
|
||||||
return (classFlags(t, class_) & ACC_SUPER)
|
return (classFlags(t, class_) & ACC_SUPER)
|
||||||
and strcmp("<init>", reinterpret_cast<char*>
|
and strcmp(reinterpret_cast<const int8_t*>("<init>"),
|
||||||
(byteArrayBody(t, methodName(t, method)))) != 0
|
byteArrayBody(t, methodName(t, method))) != 0
|
||||||
and isSuperclass(t, methodClass(t, method), class_);
|
and isSuperclass(t, methodClass(t, method), class_);
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
findField(Thread* t, object class_, object reference)
|
find(Thread* t, object class_, object reference,
|
||||||
|
object& (*table)(Thread*, object),
|
||||||
|
object& (*name)(Thread*, object),
|
||||||
|
object& (*spec)(Thread*, object),
|
||||||
|
object (*makeError)(Thread*, object))
|
||||||
{
|
{
|
||||||
object table = classFieldTable(t, class_);
|
object a = table(t, class_);
|
||||||
object name = referenceName(t, reference);
|
object n = referenceName(t, reference);
|
||||||
for (unsigned i = 0; i < rawArrayLength(t, table); ++i) {
|
object s = referenceSpec(t, reference);
|
||||||
object fieldName = fieldName(t, rawArrayBody(t, table)[i]);
|
for (unsigned i = 0; i < rawArrayLength(t, a); ++i) {
|
||||||
if (strcmp(reinterpret_cast<char*>(byteArrayBody(t, fieldName)),
|
object field = rawArrayBody(t, a)[i];
|
||||||
reinterpret_cast<char*>(byteArrayBody(t, name))) == 0)
|
if (strcmp(byteArrayBody(t, name(t, field)),
|
||||||
|
byteArrayBody(t, n)) == 0 and
|
||||||
|
strcmp(byteArrayBody(t, spec(t, field)),
|
||||||
|
byteArrayBody(t, s)) == 0)
|
||||||
{
|
{
|
||||||
#error compare specs
|
return field;
|
||||||
return rawArrayBody(t, table)[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#error make message
|
|
||||||
t->exception = makeNoSuchFieldError(t, message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
object
|
object message = makeString
|
||||||
findMethod(Thread* t, object class_, object reference)
|
(t, "%s (%s) not found in %s",
|
||||||
{
|
byteArrayBody(t, n),
|
||||||
object table = classMethodTable(t, class_);
|
byteArrayBody(t, s),
|
||||||
object name = referenceName(t, reference);
|
byteArrayBody(t, className(t, class_)));
|
||||||
for (unsigned i = 0; i < rawArrayLength(t, table); ++i) {
|
t->exception = makeError(t, message);
|
||||||
object methodName = methodName(t, rawArrayBody(t, table)[i]);
|
|
||||||
if (strcmp(reinterpret_cast<char*>(byteArrayBody(t, methodName)),
|
|
||||||
reinterpret_cast<char*>(byteArrayBody(t, name))) == 0)
|
|
||||||
{
|
|
||||||
#error compare specs
|
|
||||||
return rawArrayBody(t, table)[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#error make message
|
|
||||||
t->exception = makeNoSuchMethodError(t, message);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
findFieldInClass(Thread* t, object class_, object reference)
|
||||||
|
{
|
||||||
|
return find(t, class_, reference, classFieldTable, fieldName, fieldSpec,
|
||||||
|
makeNoSuchFieldError);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
findMethodInClass(Thread* t, object class_, object reference)
|
||||||
|
{
|
||||||
|
return find(t, class_, reference, classMethodTable, methodName, methodSpec,
|
||||||
|
makeNoSuchMethodError);
|
||||||
|
}
|
||||||
|
|
||||||
inline object
|
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 = rawArrayBody(t, pool)[index];
|
||||||
if (typeOf(o) == ReferenceType) {
|
if (typeOf(o) == ReferenceType) {
|
||||||
PROTECT(pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
object class_ = resolveClass(t, referenceClass(t, o));
|
object class_ = resolveClass(t, referenceClass(t, o));
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
@ -579,22 +608,21 @@ resolve(Thread* t, object pool, unsigned index,
|
|||||||
o = find(t, class_, rawArrayBody(t, pool)[index]);
|
o = find(t, class_, rawArrayBody(t, pool)[index]);
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
return set(t, rawArrayBody(t, pool)[index], o);
|
set(t, rawArrayBody(t, pool)[index], o);
|
||||||
} else {
|
|
||||||
return o;
|
|
||||||
}
|
}
|
||||||
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
resolveField(Thread* t, object pool, unsigned index)
|
resolveField(Thread* t, object pool, unsigned index)
|
||||||
{
|
{
|
||||||
return resolve(t, pool, index, findField);
|
return resolve(t, pool, index, findFieldInClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
resolveMethod(Thread* t, object pool, unsigned index)
|
resolveMethod(Thread* t, object pool, unsigned index)
|
||||||
{
|
{
|
||||||
return resolve(t, pool, index, findMethod);
|
return resolve(t, pool, index, findMethodInClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
|
Loading…
Reference in New Issue
Block a user