mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
more work on continuation support
This commit is contained in:
parent
eb3bd25aa1
commit
66c4867f18
16
classpath/avian/Callback.java
Normal file
16
classpath/avian/Callback.java
Normal file
@ -0,0 +1,16 @@
|
||||
/* Copyright (c) 2009, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public interface Callback<T> {
|
||||
public void handleResult(T result);
|
||||
public void handleException(Throwable exception);
|
||||
}
|
15
classpath/avian/CallbackReceiver.java
Normal file
15
classpath/avian/CallbackReceiver.java
Normal file
@ -0,0 +1,15 @@
|
||||
/* Copyright (c) 2009, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public interface CallbackReceiver<T> {
|
||||
public T receive(Callback<T> callback) throws Exception;
|
||||
}
|
27
classpath/avian/Continuations.java
Normal file
27
classpath/avian/Continuations.java
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (c) 2009, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public abstract class Continuations {
|
||||
public static native <T> T callWithCurrentContinuation
|
||||
(CallbackReceiver<T> receiver) throws Exception;
|
||||
|
||||
public static native <T> T dynamicWind(Runnable before,
|
||||
Callable<T> thunk,
|
||||
Runnable after) throws Exception;
|
||||
|
||||
private static class Continuation<T> implements Callback<T> {
|
||||
public native void handleResult(T result);
|
||||
public native void handleException(Throwable exception);
|
||||
}
|
||||
}
|
15
classpath/java/util/concurrent/Callable.java
Normal file
15
classpath/java/util/concurrent/Callable.java
Normal file
@ -0,0 +1,15 @@
|
||||
/* Copyright (c) 2009, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.util.concurrent;
|
||||
|
||||
public interface Callable<T> {
|
||||
public T call() throws Exception;
|
||||
}
|
@ -847,3 +847,38 @@ Java_java_net_URL_00024ResourceInputStream_close(Thread*, jclass, jlong peer)
|
||||
{
|
||||
reinterpret_cast<System::Region*>(peer)->dispose();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_avian_Continuations_callWithCurrentContinuation(Thread* t,
|
||||
object,
|
||||
uintptr_t* arguments)
|
||||
{
|
||||
t->m->processor->callWithCurrentContinuation
|
||||
(t, reinterpret_cast<object>(*arguments));
|
||||
|
||||
abort(t);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_avian_Continuation_handleResult(Thread* t,
|
||||
object,
|
||||
uintptr_t* arguments)
|
||||
{
|
||||
t->m->processor->feedResultToContinuation
|
||||
(t, reinterpret_cast<object>(arguments[0]),
|
||||
reinterpret_cast<object>(arguments[1]));
|
||||
|
||||
abort(t);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_avian_Continuation_handleException(Thread* t,
|
||||
object,
|
||||
uintptr_t* arguments)
|
||||
{
|
||||
t->m->processor->feedExceptionToContinuation
|
||||
(t, reinterpret_cast<object>(arguments[0]),
|
||||
reinterpret_cast<object>(arguments[1]));
|
||||
|
||||
abort(t);
|
||||
}
|
||||
|
@ -5553,6 +5553,7 @@ class MyProcessor: public Processor {
|
||||
objectPools(0),
|
||||
staticTableArray(0),
|
||||
virtualThunks(0),
|
||||
receiveMethod(0),
|
||||
codeAllocator(s, 0, 0)
|
||||
{ }
|
||||
|
||||
@ -5952,33 +5953,52 @@ class MyProcessor: public Processor {
|
||||
(t->m->system->handleSegFault(&segFaultHandler)));
|
||||
}
|
||||
|
||||
virtual void callWithCurrentContinuation(Thread* vmt, object method,
|
||||
object this_)
|
||||
{
|
||||
virtual void callWithCurrentContinuation(Thread* vmt, object receiver) {
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
|
||||
object method;
|
||||
object continuation;
|
||||
void* base;
|
||||
void* stack;
|
||||
|
||||
{ PROTECT(t, method);
|
||||
PROTECT(t, this_);
|
||||
{ PROTECT(t, receiver);
|
||||
|
||||
compile(t, ::codeAllocator(t), 0, method);
|
||||
if (receiveMethod == 0) {
|
||||
const char* const className = "avian/CallbackReceiver";
|
||||
const char* const methodName = "receive";
|
||||
const char* const methodSpec = "(Lavian/Callback;)Ljava/lang/Object;";
|
||||
|
||||
receiveMethod = resolveMethod(t, className, methodName, methodSpec);
|
||||
|
||||
if (receiveMethod == 0) {
|
||||
object message = makeString
|
||||
(t, "%s %s not found in %s", methodName, methodSpec, className);
|
||||
t->exception = makeNoSuchMethodError(t, message);
|
||||
}
|
||||
}
|
||||
|
||||
if (LIKELY(t->exception == 0)) {
|
||||
void* ip;
|
||||
continuation = makeCurrentContinuation(t, &ip, &base, &stack);
|
||||
method = findInterfaceMethod
|
||||
(t, receiveMethod, objectClass(t, receiver));
|
||||
PROTECT(t, method);
|
||||
|
||||
compile(t, ::codeAllocator(t), 0, method);
|
||||
if (LIKELY(t->exception == 0)) {
|
||||
void* ip;
|
||||
continuation = makeCurrentContinuation(t, &ip, &base, &stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LIKELY(t->exception == 0)) {
|
||||
callWithContinuation(t, method, this_, continuation, base, stack);
|
||||
callWithContinuation(t, method, receiver, continuation, base, stack);
|
||||
} else {
|
||||
unwind(t);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void callContinuation(Thread* vmt, object continuation,
|
||||
object result)
|
||||
virtual void feedResultToContinuation(Thread* vmt, object continuation,
|
||||
object result)
|
||||
{
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
|
||||
@ -5997,6 +6017,30 @@ class MyProcessor: public Processor {
|
||||
vmJump(ip, base, stack, t, reinterpret_cast<uintptr_t>(result), 0);
|
||||
}
|
||||
|
||||
virtual void feedExceptionToContinuation(Thread* vmt, object continuation,
|
||||
object exception)
|
||||
{
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
|
||||
assert(t, t->exception == 0);
|
||||
|
||||
void* ip;
|
||||
void* base;
|
||||
void* stack;
|
||||
findUnwindTarget(t, &ip, &base, &stack);
|
||||
|
||||
t->trace->nativeMethod = 0;
|
||||
t->trace->targetMethod = 0;
|
||||
|
||||
t->continuation = continuation;
|
||||
|
||||
t->exception = exception;
|
||||
|
||||
findUnwindTarget(t, &ip, &base, &stack);
|
||||
|
||||
vmJump(ip, base, stack, t, 0, 0);
|
||||
}
|
||||
|
||||
virtual void walkContinuationBody(Thread* t, Heap::Walker* w, object o,
|
||||
unsigned start)
|
||||
{
|
||||
@ -6018,6 +6062,7 @@ class MyProcessor: public Processor {
|
||||
object objectPools;
|
||||
object staticTableArray;
|
||||
object virtualThunks;
|
||||
object receiveMethod;
|
||||
SegFaultHandler segFaultHandler;
|
||||
FixedAllocator codeAllocator;
|
||||
};
|
||||
|
@ -134,10 +134,14 @@ class Processor {
|
||||
boot(Thread* t, BootImage* image) = 0;
|
||||
|
||||
virtual void
|
||||
callWithCurrentContinuation(Thread* t, object method, object this_) = 0;
|
||||
callWithCurrentContinuation(Thread* t, object receiver) = 0;
|
||||
|
||||
virtual void
|
||||
callContinuation(Thread* t, object continuation, object result) = 0;
|
||||
feedResultToContinuation(Thread* t, object continuation, object result) = 0;
|
||||
|
||||
virtual void
|
||||
feedExceptionToContinuation(Thread* t, object continuation,
|
||||
object exception) = 0;
|
||||
|
||||
virtual void
|
||||
walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start)
|
||||
|
@ -1323,12 +1323,6 @@ parseJavaClass(Object* type, Stream* s, Object* declarations)
|
||||
}
|
||||
}
|
||||
|
||||
if (equal(typeJavaName(type), "java/lang/Class")) {
|
||||
// add inline vtable
|
||||
addMember(type, Array::make
|
||||
(type, 0, "void*", "vtable", sizeOf("void*", 0)));
|
||||
}
|
||||
|
||||
if (typeSuper(type)) {
|
||||
for (Object* p = typeMethods(typeSuper(type)); p; p = cdr(p)) {
|
||||
addMethod(type, car(p));
|
||||
@ -1372,23 +1366,25 @@ parseType(Object::ObjectType type, Object* p, Object* declarations,
|
||||
|
||||
Type* t = Type::make(type, name, javaName);
|
||||
|
||||
if (javaName and *javaName != '[') {
|
||||
assert(cdr(p) == 0);
|
||||
bool isJavaType = javaName and *javaName != '[';
|
||||
|
||||
if (isJavaType) {
|
||||
const char* file = append(javaClassDirectory, "/", javaName, ".class");
|
||||
Stream s(fopen(file, "rb"), true);
|
||||
parseJavaClass(t, &s, declarations);
|
||||
} else {
|
||||
for (p = cdr(p); p; p = cdr(p)) {
|
||||
if (type == Object::Type) {
|
||||
parseSubdeclaration(t, car(p), declarations);
|
||||
} else {
|
||||
Object* member = parseMember(t, car(p), declarations);
|
||||
assert(member->type == Object::Scalar);
|
||||
addMember(t, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (p = cdr(p); p; p = cdr(p)) {
|
||||
if (type == Object::Type) {
|
||||
parseSubdeclaration(t, car(p), declarations);
|
||||
} else {
|
||||
Object* member = parseMember(t, car(p), declarations);
|
||||
assert(member->type == Object::Scalar);
|
||||
addMember(t, member);
|
||||
}
|
||||
}
|
||||
|
||||
if (not isJavaType) {
|
||||
if (type == Object::Type and typeSuper(t)) {
|
||||
for (Object* p = typeMethods(typeSuper(t)); p; p = cdr(p)) {
|
||||
addMethod(t, car(p));
|
||||
|
@ -1,6 +1,7 @@
|
||||
(type jobject java/lang/Object)
|
||||
|
||||
(type class java/lang/Class)
|
||||
(type class java/lang/Class
|
||||
(array void* vtable))
|
||||
|
||||
(type singleton
|
||||
(array uintptr_t body))
|
||||
@ -103,7 +104,7 @@
|
||||
(type array
|
||||
(noassert array object body))
|
||||
|
||||
(type continuation
|
||||
(type continuation avian/Continuations$Continuation
|
||||
(object next)
|
||||
(object method)
|
||||
(void* address)
|
||||
@ -111,6 +112,8 @@
|
||||
(uintptr_t framePointerOffset)
|
||||
(array uintptr_t body))
|
||||
|
||||
(type callbackReceiver avian/CallbackReceiver)
|
||||
|
||||
(type string java/lang/String)
|
||||
|
||||
(type thread java/lang/Thread)
|
||||
|
Loading…
Reference in New Issue
Block a user