...
 
Commits (1)
......@@ -73,18 +73,21 @@ GNU_EXPR_JSOURCES = \
expr/TypeValue.java \
expr/VarValueTracker.java
JAVAX_SCRIPT_EXTRA = \
expr/AbstractScriptEngineFactory.java \
expr/KawaScriptBindings.java \
expr/KawaScriptEngine.java
GNU_CONTINUATIONS_JSOURCES = \
expr/continuations/Helpers.java \
expr/continuations/CallCC.java \
expr/continuations/Continuation.java \
expr/continuations/DelimitedContinuation.java \
expr/continuations/TopLevelHandler.java \
expr/continuations/Shift.java \
expr/continuations/Reset.java \
expr/FragmentAndInstrument.java
JAVAX_SCRIPT_EXTRA = \
expr/AbstractScriptEngineFactory.java \
expr/KawaScriptBindings.java \
expr/KawaScriptEngine.java
GNU_LISTS_JSOURCES = \
lists/AbstractCharVector.java \
lists/AbstractFormat.java \
......
......@@ -312,18 +312,21 @@ GNU_EXPR_JSOURCES = \
expr/TypeValue.java \
expr/VarValueTracker.java
JAVAX_SCRIPT_EXTRA = \
expr/AbstractScriptEngineFactory.java \
expr/KawaScriptBindings.java \
expr/KawaScriptEngine.java
GNU_CONTINUATIONS_JSOURCES = \
expr/continuations/Helpers.java \
expr/continuations/CallCC.java \
expr/continuations/Continuation.java \
expr/continuations/DelimitedContinuation.java \
expr/continuations/TopLevelHandler.java \
expr/continuations/Shift.java \
expr/continuations/Reset.java \
expr/FragmentAndInstrument.java
JAVAX_SCRIPT_EXTRA = \
expr/AbstractScriptEngineFactory.java \
expr/KawaScriptBindings.java \
expr/KawaScriptEngine.java
GNU_LISTS_JSOURCES = \
lists/AbstractCharVector.java \
lists/AbstractFormat.java \
......
......@@ -7,8 +7,11 @@ import gnu.expr.continuations.Helpers.ContinuationException;
import gnu.expr.continuations.Helpers.ContinuationFrame;
import static gnu.expr.continuations.TopLevelHandler.topLevelHandler;
import static gnu.expr.continuations.CallCC.callcc;
import static gnu.expr.continuations.Shift.shift;
import static gnu.expr.continuations.Reset.reset;
import gnu.kawa.functions.GetNamedPart;
import static gnu.kawa.reflect.Throw.primitiveThrow;
import gnu.mapping.Procedure;
import java.util.HashMap;
import kawa.standard.Scheme;
import kawa.standard.SchemeCompilation;
......@@ -355,10 +358,22 @@ public class FragmentAndInstrument extends ExpExpVisitor<Void> {
return decl;
}
protected boolean isCallCC(Expression exp) {
private boolean isCallCC(Expression exp) {
return isApplyOf(exp, gnu.kawa.functions.CallCC.callcc);
}
private boolean isShift(Expression exp) {
return isApplyOf(exp, shift);
}
private boolean isReset(Expression exp) {
return isApplyOf(exp, reset);
}
protected boolean isApplyOf(Expression exp, Procedure proc) {
if (exp instanceof ApplyExp) {
ApplyExp aexp = (ApplyExp) exp;
if (aexp.getFunctionValue() == gnu.kawa.functions.CallCC.callcc)
if (aexp.getFunctionValue() == proc)
return true;
if (aexp.args.length > 0
&& aexp.args[0] instanceof ReferenceExp) {
......@@ -367,7 +382,7 @@ public class FragmentAndInstrument extends ExpExpVisitor<Void> {
if (decl != null
&& (decl.getValue() instanceof QuoteExp
&& ((QuoteExp)decl.getValue()).getValue()
== gnu.kawa.functions.CallCC.callcc)) {
== proc)) {
return true;
}
}
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package gnu.expr.continuations;
import gnu.expr.continuations.Helpers.ContinuationFrame;
import gnu.mapping.Procedure1;
import java.util.ArrayList;
/**
*
* @author andrebask
*/
public class DelimitedContinuation extends Continuation {
public DelimitedContinuation(ArrayList<ContinuationFrame> newFrames,
ArrayList<ContinuationFrame> oldFrames) {
super(newFrames, oldFrames);
}
public Object apply1(final Object val) throws Throwable {
Procedure1 t = new Procedure1() {
@Override
public Object apply1(Object arg1) throws Throwable {
return reloadFrames(0, frames.size() - 2, val);
}
};
return Reset.runInTopLevelHandler(t);
}
/**
* Resumes the current continuation.
* When the call/cc is called, the stack is unwinded and saved
* on the heap. Immediately after the call/cc call, the current
* continuation is resumed using this function. see also {@see
* gnu.expr.continuations.TopLevelHandler}.
*/
Object resume(final Object restartValue) throws Throwable {
return reloadFrames(1, frames.size()-1, restartValue);
}
/**
* Performs the actual reloading.
* Iterates over the list of frames in reverse order to re-establish
* the saved continuation with the passed value.
*/
Object reloadFrames(int startIndex, int endIndex, Object restartValue)
throws Throwable {
Object continueValue = restartValue;
for (int i = endIndex; i >= startIndex; i -= 1) {
ContinuationFrame frame = frames.get(i);
try {
continueValue = frame.computation.apply1(continueValue);
} catch (Helpers.ContinuationException sce) {
sce.append(frame.continuation);
throw sce;
}
}
return continueValue;
}
}
......@@ -83,6 +83,12 @@ public class Helpers {
}
}
public static class DelimitedContinuationException extends ContinuationException {
public DelimitedContinuation toContinuation() throws Exception {
return new DelimitedContinuation(newCapturedFrames, reloadedFrames);
}
}
public static void extend(ContinuationException c, ContinuationFrame extension){
c.extend(extension);
}
......
package gnu.expr.continuations;
import gnu.bytecode.ClassType;
import gnu.bytecode.CodeAttr;
import gnu.bytecode.Method;
import gnu.expr.ApplyExp;
import gnu.expr.Compilation;
import gnu.expr.Target;
import gnu.expr.continuations.Helpers.DelimitedContinuationException;
import gnu.expr.continuations.Helpers.ExitException;
import gnu.mapping.Procedure;
import gnu.mapping.Procedure1;
/**
*
* @author andrebask
*/
public class Reset extends TopLevelHandler {
public static final Reset reset = new Reset();
public void compile(ApplyExp exp, Compilation comp, Target target) {
CodeAttr code = comp.getCode();
Method resetMethod = ClassType.make("gnu.expr.continuations.Reset")
.getDeclaredStaticMethod("runInTopLevelHandler", 1);
exp.getArg(1).compile(comp, ClassType.make("gnu.mapping.Procedure"));
code.emitInvokeStatic(resetMethod);
}
/**
* Runs inside an exception handler the first computation of a top
* level expression, managing the capture of continuations and the
* invocation of saved continuation.
*/
public static Object runInTopLevelHandler(Procedure initialFrame)
throws Throwable {
try {
return initialFrame.apply1(null);
} catch (DelimitedContinuationException ce) {
// assemble the list of frames in a Continution Object.
final Continuation k = ce.toContinuation();
return k.resume(k);
}
}
}
package gnu.expr.continuations;
import gnu.bytecode.ClassType;
import gnu.bytecode.CodeAttr;
import gnu.bytecode.Method;
import gnu.expr.ApplyExp;
import gnu.expr.Compilation;
import gnu.expr.Target;
import gnu.expr.continuations.Helpers.ContinuationException;
import gnu.expr.continuations.Helpers.ContinuationFrame;
import gnu.expr.continuations.Helpers.DelimitedContinuationException;
import gnu.mapping.Procedure;
import gnu.mapping.Procedure1;
/**
*
* @author andrebask
*/
public class Shift extends Procedure1 {
public static final Shift shift = new Shift();
public Object apply1(Object arg1) throws Throwable {
return shift((Procedure) arg1);
}
public void compile(ApplyExp exp, Compilation comp, Target target) {
CodeAttr code = comp.getCode();
Method shiftMethod = ClassType.make("gnu.expr.continuations.Shift")
.getDeclaredStaticMethod("shift", 1);
exp.getArg(1).compile(comp, ClassType.make("gnu.expr.continuations.Helpers.Frame"));
code.emitInvokeStatic(shiftMethod);
}
public static Object shift(final Procedure receiver)
throws ContinuationException {
try {
// begin unwind the stack
throw new DelimitedContinuationException();
} catch (DelimitedContinuationException sce) {
sce.extend(new ContinuationFrame(receiver));
throw sce;
}
}
}
......@@ -57,9 +57,9 @@ public class TopLevelHandler extends Procedure1 {
try {
// invoke the first computation of a top level expression.
return initialFrame.apply1(null);
} catch (ContinuationException sce) {
} catch (ContinuationException ce) {
// assemble the list of frames in a Continution Object.
final Continuation k = sce.toContinuation();
final Continuation k = ce.toContinuation();
// send to the top level handler a computation that will
// resume the captured continuation.
......