Continuation.java 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package kawa.lang;
  2. import gnu.mapping.*;
  3. /* #ifdef use:java.lang.invoke */
  4. import java.lang.invoke.*;
  5. /* #else */
  6. // import gnu.mapping.CallContext.MethodHandle;
  7. /* #endif */
  8. /**
  9. * A Continuation "represents an entire (default) future for the computation.
  10. * This implemementation is based on Java exceptions, and is restricted
  11. * to "upward" (?) continuation (i.e. catch/throw-type uses).
  12. * @author Per Bothner
  13. */
  14. public class Continuation extends MethodProc
  15. {
  16. public boolean invoked;
  17. static int counter;
  18. int id;
  19. public Continuation (CallContext ctx)
  20. {
  21. super(true, applyMethodCont);
  22. }
  23. public static final MethodHandle applyMethodCont =
  24. lookupApplyHandle(Continuation.class, "applyMethodCont");
  25. public static Object applyMethodCont(Procedure proc, CallContext ctx) throws Throwable {
  26. Continuation cont = (Continuation) proc;
  27. if (cont.invoked)
  28. throw new GenericError
  29. ("implementation restriction: continuation can only be used once");
  30. throw new CalledContinuation (ctx.getRestArgsArray(), cont, ctx);
  31. }
  32. public static void handleException$X (Throwable ex, Continuation cont,
  33. CallContext ctx)
  34. throws Throwable
  35. {
  36. CalledContinuation cex;
  37. if (! (ex instanceof CalledContinuation)
  38. || (cex = (CalledContinuation) ex).continuation != cont)
  39. throw ex;
  40. cont.invoked = true;
  41. Object[] values = cex.values;
  42. int nvalues = values.length;
  43. for (int i = 0; i < nvalues; i++)
  44. ctx.consumer.writeObject(values[i]);
  45. }
  46. public static Object handleException (Throwable ex, Continuation cont)
  47. throws Throwable
  48. {
  49. CalledContinuation cex;
  50. if (! (ex instanceof CalledContinuation)
  51. || (cex = (CalledContinuation) ex).continuation != cont)
  52. throw ex;
  53. cont.invoked = true;
  54. return Values.make(cex.values);
  55. }
  56. public final String toString()
  57. {
  58. return "#<continuation " + id + (invoked ? " (invoked)>" : ">");
  59. }
  60. }