!7 cprint FreezeStackDemo { transient bool shouldFreeze; start-thread { print(myFunc(5)); // Run normal version print(myFunc_hibernatable(5)); // Run hibernatable version - should be exactly as fast set shouldFreeze; try { myFunc_hibernatable(5); // Run hibernatable version and throw hibernation exception in the middle of it } catch Hib e { print("Frozen stack structure:"); pnlStruct(e.stack); // Convert to virtual stack version which is a bit // slower than the regular one [need benchmark!], // finish the computation and print the result print("Reviving & resuming!"); VStack stack = new Hib(restructure(e.stack)).asVStack(); stepAllWith(stack, r { print(structWithReplacements(stack, "FreezeStackDemo$myFunc_vstack", "myFunc")); }); print("Result: " + stack.latestResult); } } S myFunc(int n) { if (n >= 100) n = 100; if (n <= 0) ret "base"; ret n + " " + myFunc(n-1); } S myFunc_hibernatable(int n) throws Hib { try { if (n >= 100) n = 100; if (n <= 0) if (shouldFreeze) hibernate(); else ret "base"; ret n + " " + myFunc_hibernatable(n-1); } on fail Hib e { e.add(new myFunc_vstack(n)); } } srecord myFunc_vstack(int n) implements VStack.Computable { public void step(VStack stack, O subResult) { if (stack.hasSubResult()) stack._return(n + " " + subResult); else { if (n >= 100) n = 100; if (n <= 0) ret with stack._return("base"); stack.push(new myFunc_vstack(n-1)); } } } }