mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
finish initial sketch of dynamicWind implementation
This commit is contained in:
parent
4305fdc7f3
commit
364f31b785
@ -21,27 +21,27 @@ public abstract class Continuations {
|
|||||||
Runnable after)
|
Runnable after)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
UnwindResult result = dynamicWind2(buffer, thunk, after);
|
UnwindResult result = dynamicWind2(before, thunk, after);
|
||||||
if (result.continuation != null) {
|
if (result.continuation != null) {
|
||||||
after.run();
|
after.run();
|
||||||
if (result.exception != null) {
|
if (result.exception != null) {
|
||||||
result.continuation.handleException(result.exception);
|
result.continuation.handleException(result.exception);
|
||||||
} else {
|
} else {
|
||||||
result.continuation.handleResult(result.value);
|
result.continuation.handleResult(result.result);
|
||||||
}
|
}
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
} else {
|
} else {
|
||||||
return (T) result.value;
|
return (T) result.result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native UnwindResult dynamicWind2(Runnable before,
|
private static native UnwindResult dynamicWind2(Runnable before,
|
||||||
Callable<T> thunk,
|
Callable thunk,
|
||||||
Runnable after)
|
Runnable after)
|
||||||
throws Exception;
|
throws Exception;
|
||||||
|
|
||||||
private static UnwindResult wind(Runnable before,
|
private static UnwindResult wind(Runnable before,
|
||||||
Callable<T> thunk,
|
Callable thunk,
|
||||||
Runnable after)
|
Runnable after)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
@ -65,7 +65,7 @@ public abstract class Continuations {
|
|||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
continuation.handleException(exception);
|
continuation.handleException(exception);
|
||||||
} else {
|
} else {
|
||||||
continuation.handleResult(value);
|
continuation.handleResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
|
313
src/compile.cpp
313
src/compile.cpp
@ -49,13 +49,14 @@ class MyThread: public Thread {
|
|||||||
public:
|
public:
|
||||||
class CallTrace {
|
class CallTrace {
|
||||||
public:
|
public:
|
||||||
CallTrace(MyThread* t):
|
CallTrace(MyThread* t, object method):
|
||||||
t(t),
|
t(t),
|
||||||
base(t->base),
|
base(t->base),
|
||||||
stack(t->stack),
|
stack(t->stack),
|
||||||
continuation(t->continuation),
|
continuation(t->continuation),
|
||||||
nativeMethod(0),
|
nativeMethod((methodFlags(t, method) & ACC_NATIVE) ? method : 0),
|
||||||
targetMethod(0),
|
targetMethod(0),
|
||||||
|
originalMethod(method),
|
||||||
next(t->trace)
|
next(t->trace)
|
||||||
{
|
{
|
||||||
t->trace = this;
|
t->trace = this;
|
||||||
@ -77,6 +78,7 @@ class MyThread: public Thread {
|
|||||||
object continuation;
|
object continuation;
|
||||||
object nativeMethod;
|
object nativeMethod;
|
||||||
object targetMethod;
|
object targetMethod;
|
||||||
|
object originalMethod;
|
||||||
CallTrace* next;
|
CallTrace* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1371,7 +1373,7 @@ releaseLock(MyThread* t, object method, void* stack)
|
|||||||
|
|
||||||
void
|
void
|
||||||
findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
||||||
void** targetStack)
|
void** targetStack, unsigned* oldArgumentFootprint = 0)
|
||||||
{
|
{
|
||||||
void* ip = t->ip;
|
void* ip = t->ip;
|
||||||
void* base = t->base;
|
void* base = t->base;
|
||||||
@ -1386,7 +1388,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
|||||||
while (*targetIp == 0) {
|
while (*targetIp == 0) {
|
||||||
object method = methodForIp(t, ip);
|
object method = methodForIp(t, ip);
|
||||||
if (method) {
|
if (method) {
|
||||||
void* handler = findExceptionHandler(t, method, ip, forContinuation);
|
void* handler = findExceptionHandler(t, method, ip);
|
||||||
|
|
||||||
if (handler) {
|
if (handler) {
|
||||||
*targetIp = handler;
|
*targetIp = handler;
|
||||||
@ -1418,12 +1420,16 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
|||||||
*targetStack = static_cast<void**>(stack)
|
*targetStack = static_cast<void**>(stack)
|
||||||
+ t->arch->frameReturnAddressSize();
|
+ t->arch->frameReturnAddressSize();
|
||||||
|
|
||||||
|
if (oldArgumentFootprint) {
|
||||||
|
*oldArgumentFootprint
|
||||||
|
= t->arch->argumentFootprint(methodParameterFootprint(t, target));
|
||||||
|
}
|
||||||
|
|
||||||
while (t->continuation) {
|
while (t->continuation) {
|
||||||
object method = continuationMethod(t, t->continuation);
|
object method = continuationMethod(t, t->continuation);
|
||||||
|
|
||||||
void* handler = findExceptionHandler
|
void* handler = findExceptionHandler
|
||||||
(t, method, continuationAddress(t, t->continuation),
|
(t, method, continuationAddress(t, t->continuation));
|
||||||
forContinuation);
|
|
||||||
|
|
||||||
if (handler) {
|
if (handler) {
|
||||||
t->exceptionHandler = handler;
|
t->exceptionHandler = handler;
|
||||||
@ -1548,6 +1554,9 @@ unwind(MyThread* t)
|
|||||||
object&
|
object&
|
||||||
objectPools(MyThread* t);
|
objectPools(MyThread* t);
|
||||||
|
|
||||||
|
object&
|
||||||
|
rewindMethod(MyThread* t);
|
||||||
|
|
||||||
uintptr_t
|
uintptr_t
|
||||||
defaultThunk(MyThread* t);
|
defaultThunk(MyThread* t);
|
||||||
|
|
||||||
@ -5309,15 +5318,33 @@ callContinuation(MyThread* t, object continuation, object result,
|
|||||||
vmJump(ip, base, stack, t, reinterpret_cast<uintptr_t>(result), 0);
|
vmJump(ip, base, stack, t, reinterpret_cast<uintptr_t>(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t*
|
int8_t*
|
||||||
returnSpec(MyThread* t, object method)
|
returnSpec(MyThread* t, object method)
|
||||||
{
|
{
|
||||||
uint8_t* s = &byteArrayBody(t, methodSpec(t, method));
|
int8_t* s = &byteArrayBody(t, methodSpec(t, method), 0);
|
||||||
while (*s and *s != ')') ++ s;
|
while (*s and *s != ')') ++ s;
|
||||||
expect(t, *s == ')');
|
expect(t, *s == ')');
|
||||||
return s + 1;
|
return s + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
returnClass(MyThread* t, object method)
|
||||||
|
{
|
||||||
|
int8_t* spec = returnSpec(t, method);
|
||||||
|
unsigned length = strlen(reinterpret_cast<char*>(spec));
|
||||||
|
object name;
|
||||||
|
if (*spec == '[') {
|
||||||
|
name = makeByteArray(t, length + 1);
|
||||||
|
memcpy(&byteArrayBody(t, name, 0), spec, length);
|
||||||
|
} else {
|
||||||
|
assert(t, *spec == 'L');
|
||||||
|
assert(t, spec[length - 1] == ';');
|
||||||
|
name = makeByteArray(t, length - 1);
|
||||||
|
memcpy(&byteArrayBody(t, name, 0), spec + 1, length - 2);
|
||||||
|
}
|
||||||
|
return resolveClass(t, name);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
compatibleReturnType(MyThread* t, object oldMethod, object newMethod)
|
compatibleReturnType(MyThread* t, object oldMethod, object newMethod)
|
||||||
{
|
{
|
||||||
@ -5326,10 +5353,14 @@ compatibleReturnType(MyThread* t, object oldMethod, object newMethod)
|
|||||||
} else if (methodReturnCode(t, oldMethod) == methodReturnCode(t, newMethod))
|
} else if (methodReturnCode(t, oldMethod) == methodReturnCode(t, newMethod))
|
||||||
{
|
{
|
||||||
if (methodReturnCode(t, oldMethod) == ObjectField) {
|
if (methodReturnCode(t, oldMethod) == ObjectField) {
|
||||||
uint8_t* oldSpec = returnSpec(t, oldMethod);
|
PROTECT(t, newMethod);
|
||||||
uint8_t* newSpec = returnSpec(t, newMethod);
|
|
||||||
|
|
||||||
|
object oldClass = returnClass(t, oldMethod);
|
||||||
|
PROTECT(t, oldClass);
|
||||||
|
|
||||||
|
object newClass = returnClass(t, newMethod);
|
||||||
|
|
||||||
|
return isAssignableFrom(t, oldClass, newClass);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5338,120 +5369,6 @@ compatibleReturnType(MyThread* t, object oldMethod, object newMethod)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
|
||||||
findUnwindContinuation(MyThread* t, object oldContinuation,
|
|
||||||
object newContinuation)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object
|
|
||||||
findRewindContinuation(MyThread* t, object oldContinuation,
|
|
||||||
object newContinuation)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
callContinuation(MyThread* t, object continuation, object result,
|
|
||||||
object exception)
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
Call,
|
|
||||||
Unwind,
|
|
||||||
Rewind,
|
|
||||||
Throw
|
|
||||||
} action;
|
|
||||||
|
|
||||||
object nextContinuation = 0;
|
|
||||||
|
|
||||||
if (t->continuation == null
|
|
||||||
or continuationContext(t, t->continuation)
|
|
||||||
!= continuationContext(t, continuation))
|
|
||||||
{
|
|
||||||
PROTECT(t, continuation);
|
|
||||||
PROTECT(t, result);
|
|
||||||
PROTECT(t, exception);
|
|
||||||
|
|
||||||
if (not compatibleReturnType
|
|
||||||
(t, t->trace->originalMethod, continuationContextMethod
|
|
||||||
(t, continuationContext(t, t->continuation))))
|
|
||||||
{
|
|
||||||
t->exception = makeIncompatibleContinuationException(t);
|
|
||||||
action = Throw;
|
|
||||||
} else {
|
|
||||||
nextContinuation = findUnwindContinuation
|
|
||||||
(t, t->continuation, continuation);
|
|
||||||
|
|
||||||
if (nextContinuation) {
|
|
||||||
result = makeUnwindResult(t, continuation, result, exception);
|
|
||||||
action = Unwind;
|
|
||||||
} else {
|
|
||||||
nextContinuation = findRewindContinuation
|
|
||||||
(t, t->continuation, continuation);
|
|
||||||
|
|
||||||
if (nextContinuation) {
|
|
||||||
action = Rewind;
|
|
||||||
|
|
||||||
if (rewindMethod(t) == 0) {
|
|
||||||
const char* const className = "avian/Continuations";
|
|
||||||
const char* const methodName = "rewind";
|
|
||||||
const char* const methodSpec
|
|
||||||
= "(Ljava/lang/Runnable;Lavian/Callback;Ljava/lang/Object;"
|
|
||||||
"Ljava/lang/Throwable;)V";
|
|
||||||
|
|
||||||
object method = resolveMethod
|
|
||||||
(t, className, methodName, methodSpec);
|
|
||||||
|
|
||||||
if (method) {
|
|
||||||
rewindMethod(t) == 0;
|
|
||||||
} else {
|
|
||||||
object message = makeString
|
|
||||||
(t, "%s %s not found in %s",
|
|
||||||
methodName, methodSpec, className);
|
|
||||||
|
|
||||||
t->exception = makeNoSuchMethodError(t, message);
|
|
||||||
action = Throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
action = Call;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* ip;
|
|
||||||
void* base;
|
|
||||||
void* stack;
|
|
||||||
findUnwindTarget(t, &ip, &base, &stack);
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case Call: {
|
|
||||||
callContinuation
|
|
||||||
(t, unwindContinuation, result, exception, ip, base, stack);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Unwind: {
|
|
||||||
callContinuation(t, nextContinuation, result, 0, ip, base, stack);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Rewind: {
|
|
||||||
jumpAndInvoke
|
|
||||||
(t, rewindMethod(t), base, stack, oldArgumentFootprint, 3,
|
|
||||||
continuationContextBefore(t, nextContinuation), nextContinuation,
|
|
||||||
result, exception);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Throw: {
|
|
||||||
vmJump(ip, base, stack, t, 0, 0);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
abort(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
jumpAndInvoke(MyThread* t, object method, void* base, void* stack,
|
jumpAndInvoke(MyThread* t, object method, void* base, void* stack,
|
||||||
unsigned oldArgumentFootprint, unsigned argumentCount,
|
unsigned oldArgumentFootprint, unsigned argumentCount,
|
||||||
@ -5484,6 +5401,131 @@ jumpAndInvoke(MyThread* t, object method, void* base, void* stack,
|
|||||||
arguments);
|
arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
callContinuation(MyThread* t, object continuation, object result,
|
||||||
|
object exception)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
Call,
|
||||||
|
Unwind,
|
||||||
|
Rewind,
|
||||||
|
Throw
|
||||||
|
} action;
|
||||||
|
|
||||||
|
object nextContinuation = 0;
|
||||||
|
|
||||||
|
if (t->continuation == 0
|
||||||
|
or continuationContext(t, t->continuation)
|
||||||
|
!= continuationContext(t, continuation))
|
||||||
|
{
|
||||||
|
PROTECT(t, continuation);
|
||||||
|
PROTECT(t, result);
|
||||||
|
PROTECT(t, exception);
|
||||||
|
|
||||||
|
if (compatibleReturnType
|
||||||
|
(t, t->trace->originalMethod, continuationContextMethod
|
||||||
|
(t, continuationContext(t, t->continuation))))
|
||||||
|
{
|
||||||
|
object oldContext;
|
||||||
|
object unwindContext;
|
||||||
|
|
||||||
|
if (t->continuation) {
|
||||||
|
oldContext = continuationContext(t, t->continuation);
|
||||||
|
unwindContext = oldContext;
|
||||||
|
} else {
|
||||||
|
oldContext = 0;
|
||||||
|
unwindContext = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
object rewindContext = 0;
|
||||||
|
|
||||||
|
for (object newContext = continuationContext(t, continuation);
|
||||||
|
newContext; newContext = continuationContextNext(t, newContext))
|
||||||
|
{
|
||||||
|
if (newContext == oldContext) {
|
||||||
|
unwindContext = 0;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
rewindContext = newContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unwindContext
|
||||||
|
and continuationContextContinuation(t, unwindContext))
|
||||||
|
{
|
||||||
|
nextContinuation = continuationContextContinuation(t, unwindContext);
|
||||||
|
result = makeUnwindResult(t, continuation, result, exception);
|
||||||
|
action = Unwind;
|
||||||
|
} else if (rewindContext
|
||||||
|
and continuationContextContinuation(t, rewindContext))
|
||||||
|
{
|
||||||
|
nextContinuation = continuationContextContinuation(t, rewindContext);
|
||||||
|
action = Rewind;
|
||||||
|
|
||||||
|
if (rewindMethod(t) == 0) {
|
||||||
|
PROTECT(t, nextContinuation);
|
||||||
|
|
||||||
|
const char* const className = "avian/Continuations";
|
||||||
|
const char* const methodName = "rewind";
|
||||||
|
const char* const methodSpec
|
||||||
|
= "(Ljava/lang/Runnable;Lavian/Callback;Ljava/lang/Object;"
|
||||||
|
"Ljava/lang/Throwable;)V";
|
||||||
|
|
||||||
|
object method = resolveMethod
|
||||||
|
(t, className, methodName, methodSpec);
|
||||||
|
|
||||||
|
if (method) {
|
||||||
|
rewindMethod(t) = method;
|
||||||
|
} else {
|
||||||
|
object message = makeString
|
||||||
|
(t, "%s %s not found in %s",
|
||||||
|
methodName, methodSpec, className);
|
||||||
|
|
||||||
|
t->exception = makeNoSuchMethodError(t, message);
|
||||||
|
action = Throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t->exception = makeIncompatibleContinuationException(t);
|
||||||
|
action = Throw;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
action = Call;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ip;
|
||||||
|
void* base;
|
||||||
|
void* stack;
|
||||||
|
unsigned oldArgumentFootprint;
|
||||||
|
findUnwindTarget(t, &ip, &base, &stack, &oldArgumentFootprint);
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case Call: {
|
||||||
|
callContinuation
|
||||||
|
(t, nextContinuation, result, exception, ip, base, stack);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Unwind: {
|
||||||
|
callContinuation(t, nextContinuation, result, 0, ip, base, stack);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Rewind: {
|
||||||
|
jumpAndInvoke
|
||||||
|
(t, rewindMethod(t), base, stack, oldArgumentFootprint, 3,
|
||||||
|
continuationContextBefore(t, nextContinuation), nextContinuation,
|
||||||
|
result, exception);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Throw: {
|
||||||
|
vmJump(ip, base, stack, t, 0, 0);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ArgumentList {
|
class ArgumentList {
|
||||||
public:
|
public:
|
||||||
ArgumentList(Thread* t, uintptr_t* array, unsigned size, bool* objectMask,
|
ArgumentList(Thread* t, uintptr_t* array, unsigned size, bool* objectMask,
|
||||||
@ -5618,11 +5660,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
|||||||
|
|
||||||
uint64_t result;
|
uint64_t result;
|
||||||
|
|
||||||
{ MyThread::CallTrace trace(t);
|
{ MyThread::CallTrace trace(t, method);
|
||||||
|
|
||||||
if (methodFlags(t, method) & ACC_NATIVE) {
|
|
||||||
trace.nativeMethod = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(t, arguments->position == arguments->size);
|
assert(t, arguments->position == arguments->size);
|
||||||
|
|
||||||
@ -5745,6 +5783,8 @@ class MyProcessor: public Processor {
|
|||||||
staticTableArray(0),
|
staticTableArray(0),
|
||||||
virtualThunks(0),
|
virtualThunks(0),
|
||||||
receiveMethod(0),
|
receiveMethod(0),
|
||||||
|
windMethod(0),
|
||||||
|
rewindMethod(0),
|
||||||
codeAllocator(s, 0, 0)
|
codeAllocator(s, 0, 0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -5839,12 +5879,15 @@ class MyProcessor: public Processor {
|
|||||||
v->visit(&staticTableArray);
|
v->visit(&staticTableArray);
|
||||||
v->visit(&virtualThunks);
|
v->visit(&virtualThunks);
|
||||||
v->visit(&receiveMethod);
|
v->visit(&receiveMethod);
|
||||||
|
v->visit(&windMethod);
|
||||||
|
v->visit(&rewindMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MyThread::CallTrace* trace = t->trace; trace; trace = trace->next) {
|
for (MyThread::CallTrace* trace = t->trace; trace; trace = trace->next) {
|
||||||
v->visit(&(trace->continuation));
|
v->visit(&(trace->continuation));
|
||||||
v->visit(&(trace->nativeMethod));
|
v->visit(&(trace->nativeMethod));
|
||||||
v->visit(&(trace->targetMethod));
|
v->visit(&(trace->targetMethod));
|
||||||
|
v->visit(&(trace->originalMethod));
|
||||||
}
|
}
|
||||||
|
|
||||||
v->visit(&(t->continuation));
|
v->visit(&(t->continuation));
|
||||||
@ -6255,7 +6298,7 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
if (LIKELY(t->exception == 0)) {
|
if (LIKELY(t->exception == 0)) {
|
||||||
jumpAndInvoke
|
jumpAndInvoke
|
||||||
(t, method, base, stack, oldArgumentFootprint, 3, before, thunk,
|
(t, windMethod, base, stack, oldArgumentFootprint, 3, before, thunk,
|
||||||
after);
|
after);
|
||||||
} else {
|
} else {
|
||||||
unwind(t);
|
unwind(t);
|
||||||
@ -6296,6 +6339,8 @@ class MyProcessor: public Processor {
|
|||||||
object staticTableArray;
|
object staticTableArray;
|
||||||
object virtualThunks;
|
object virtualThunks;
|
||||||
object receiveMethod;
|
object receiveMethod;
|
||||||
|
object windMethod;
|
||||||
|
object rewindMethod;
|
||||||
SegFaultHandler segFaultHandler;
|
SegFaultHandler segFaultHandler;
|
||||||
FixedAllocator codeAllocator;
|
FixedAllocator codeAllocator;
|
||||||
};
|
};
|
||||||
@ -6906,6 +6951,12 @@ objectPools(MyThread* t)
|
|||||||
return processor(t)->objectPools;
|
return processor(t)->objectPools;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object&
|
||||||
|
rewindMethod(MyThread* t)
|
||||||
|
{
|
||||||
|
return processor(t)->rewindMethod;
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t
|
uintptr_t
|
||||||
defaultThunk(MyThread* t)
|
defaultThunk(MyThread* t)
|
||||||
{
|
{
|
||||||
|
@ -1726,6 +1726,12 @@ makeInterruptedException(Thread* t)
|
|||||||
return makeInterruptedException(t, 0, makeTrace(t), 0);
|
return makeInterruptedException(t, 0, makeTrace(t), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
makeIncompatibleContinuationException(Thread* t)
|
||||||
|
{
|
||||||
|
return makeIncompatibleContinuationException(t, 0, makeTrace(t), 0);
|
||||||
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
makeStackOverflowError(Thread* t)
|
makeStackOverflowError(Thread* t)
|
||||||
{
|
{
|
||||||
|
@ -136,6 +136,9 @@ class Processor {
|
|||||||
virtual void
|
virtual void
|
||||||
callWithCurrentContinuation(Thread* t, object receiver) = 0;
|
callWithCurrentContinuation(Thread* t, object receiver) = 0;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
dynamicWind(Thread* t, object before, object thunk, object after) = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
feedResultToContinuation(Thread* t, object continuation, object result) = 0;
|
feedResultToContinuation(Thread* t, object continuation, object result) = 0;
|
||||||
|
|
||||||
|
@ -175,6 +175,9 @@
|
|||||||
|
|
||||||
(type exceptionInInitializerError java/lang/ExceptionInInitializerError)
|
(type exceptionInInitializerError java/lang/ExceptionInInitializerError)
|
||||||
|
|
||||||
|
(type incompatibleContinuationException
|
||||||
|
avian/IncompatibleContinuationException)
|
||||||
|
|
||||||
(type number java/lang/Number)
|
(type number java/lang/Number)
|
||||||
|
|
||||||
(type byte java/lang/Byte)
|
(type byte java/lang/Byte)
|
||||||
|
Loading…
Reference in New Issue
Block a user