mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +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();
|
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),
|
objectPools(0),
|
||||||
staticTableArray(0),
|
staticTableArray(0),
|
||||||
virtualThunks(0),
|
virtualThunks(0),
|
||||||
|
receiveMethod(0),
|
||||||
codeAllocator(s, 0, 0)
|
codeAllocator(s, 0, 0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -5952,33 +5953,52 @@ class MyProcessor: public Processor {
|
|||||||
(t->m->system->handleSegFault(&segFaultHandler)));
|
(t->m->system->handleSegFault(&segFaultHandler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void callWithCurrentContinuation(Thread* vmt, object method,
|
virtual void callWithCurrentContinuation(Thread* vmt, object receiver) {
|
||||||
object this_)
|
|
||||||
{
|
|
||||||
MyThread* t = static_cast<MyThread*>(vmt);
|
MyThread* t = static_cast<MyThread*>(vmt);
|
||||||
|
|
||||||
|
object method;
|
||||||
object continuation;
|
object continuation;
|
||||||
void* base;
|
void* base;
|
||||||
void* stack;
|
void* stack;
|
||||||
|
|
||||||
{ PROTECT(t, method);
|
{ PROTECT(t, receiver);
|
||||||
PROTECT(t, this_);
|
|
||||||
|
|
||||||
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)) {
|
if (LIKELY(t->exception == 0)) {
|
||||||
void* ip;
|
method = findInterfaceMethod
|
||||||
continuation = makeCurrentContinuation(t, &ip, &base, &stack);
|
(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)) {
|
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,
|
virtual void feedResultToContinuation(Thread* vmt, object continuation,
|
||||||
object result)
|
object result)
|
||||||
{
|
{
|
||||||
MyThread* t = static_cast<MyThread*>(vmt);
|
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);
|
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,
|
virtual void walkContinuationBody(Thread* t, Heap::Walker* w, object o,
|
||||||
unsigned start)
|
unsigned start)
|
||||||
{
|
{
|
||||||
@ -6018,6 +6062,7 @@ class MyProcessor: public Processor {
|
|||||||
object objectPools;
|
object objectPools;
|
||||||
object staticTableArray;
|
object staticTableArray;
|
||||||
object virtualThunks;
|
object virtualThunks;
|
||||||
|
object receiveMethod;
|
||||||
SegFaultHandler segFaultHandler;
|
SegFaultHandler segFaultHandler;
|
||||||
FixedAllocator codeAllocator;
|
FixedAllocator codeAllocator;
|
||||||
};
|
};
|
||||||
|
@ -134,10 +134,14 @@ class Processor {
|
|||||||
boot(Thread* t, BootImage* image) = 0;
|
boot(Thread* t, BootImage* image) = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
callWithCurrentContinuation(Thread* t, object method, object this_) = 0;
|
callWithCurrentContinuation(Thread* t, object receiver) = 0;
|
||||||
|
|
||||||
virtual void
|
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
|
virtual void
|
||||||
walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start)
|
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)) {
|
if (typeSuper(type)) {
|
||||||
for (Object* p = typeMethods(typeSuper(type)); p; p = cdr(p)) {
|
for (Object* p = typeMethods(typeSuper(type)); p; p = cdr(p)) {
|
||||||
addMethod(type, car(p));
|
addMethod(type, car(p));
|
||||||
@ -1372,23 +1366,25 @@ parseType(Object::ObjectType type, Object* p, Object* declarations,
|
|||||||
|
|
||||||
Type* t = Type::make(type, name, javaName);
|
Type* t = Type::make(type, name, javaName);
|
||||||
|
|
||||||
if (javaName and *javaName != '[') {
|
bool isJavaType = javaName and *javaName != '[';
|
||||||
assert(cdr(p) == 0);
|
|
||||||
|
|
||||||
|
if (isJavaType) {
|
||||||
const char* file = append(javaClassDirectory, "/", javaName, ".class");
|
const char* file = append(javaClassDirectory, "/", javaName, ".class");
|
||||||
Stream s(fopen(file, "rb"), true);
|
Stream s(fopen(file, "rb"), true);
|
||||||
parseJavaClass(t, &s, declarations);
|
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)) {
|
if (type == Object::Type and typeSuper(t)) {
|
||||||
for (Object* p = typeMethods(typeSuper(t)); p; p = cdr(p)) {
|
for (Object* p = typeMethods(typeSuper(t)); p; p = cdr(p)) {
|
||||||
addMethod(t, car(p));
|
addMethod(t, car(p));
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
(type jobject java/lang/Object)
|
(type jobject java/lang/Object)
|
||||||
|
|
||||||
(type class java/lang/Class)
|
(type class java/lang/Class
|
||||||
|
(array void* vtable))
|
||||||
|
|
||||||
(type singleton
|
(type singleton
|
||||||
(array uintptr_t body))
|
(array uintptr_t body))
|
||||||
@ -103,7 +104,7 @@
|
|||||||
(type array
|
(type array
|
||||||
(noassert array object body))
|
(noassert array object body))
|
||||||
|
|
||||||
(type continuation
|
(type continuation avian/Continuations$Continuation
|
||||||
(object next)
|
(object next)
|
||||||
(object method)
|
(object method)
|
||||||
(void* address)
|
(void* address)
|
||||||
@ -111,6 +112,8 @@
|
|||||||
(uintptr_t framePointerOffset)
|
(uintptr_t framePointerOffset)
|
||||||
(array uintptr_t body))
|
(array uintptr_t body))
|
||||||
|
|
||||||
|
(type callbackReceiver avian/CallbackReceiver)
|
||||||
|
|
||||||
(type string java/lang/String)
|
(type string java/lang/String)
|
||||||
|
|
||||||
(type thread java/lang/Thread)
|
(type thread java/lang/Thread)
|
||||||
|
Loading…
Reference in New Issue
Block a user