// WITH_RUNTIME // FULL_JDK import java.util.concurrent.CompletableFuture fun exception(v: String): CompletableFuture = CompletableFuture.supplyAsync { throw RuntimeException(v) } fun foobar(x: String, y: String) = x + y fun box(): String { var result = "" val future = async() { try { await(exception("OK")) } catch (e: Exception) { result = e.cause?.message!! } "56" } future.join() if (future.get() != "56") return "fail: ${future.get()}" java.lang.Thread.sleep(1000) return result } fun async(coroutine c: FutureController.() -> Continuation): CompletableFuture { val controller = FutureController() c(controller).resume(Unit) return controller.future } class FutureController { val future = CompletableFuture() suspend fun await(f: CompletableFuture, machine: Continuation) { f.whenComplete { value, throwable -> try { if (throwable == null) machine.resume(value) else machine.resumeWithException(throwable) } catch (e: Exception) { future.completeExceptionally(e) } } } operator fun handleResult(value: T, c: Continuation) { future.complete(value) } fun handleException(t: Throwable, c: Continuation) { future.completeExceptionally(t) } }