[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 53/99: Implement Winding & Unwinding
From: |
Christopher Allan Webber |
Subject: |
[Guile-commits] 53/99: Implement Winding & Unwinding |
Date: |
Sun, 10 Oct 2021 21:50:59 -0400 (EDT) |
cwebber pushed a commit to branch compile-to-js-merge
in repository guile.
commit 479294fc056b5c0e8cb0ca20a1bdf760f02898fb
Author: Ian Price <ianprice90@googlemail.com>
AuthorDate: Wed Jun 28 15:03:03 2017 +0100
Implement Winding & Unwinding
* module/language/js-il/runtime.js
(wind, unwind): Implement.
(callcc): Wind when invoking continuation.
---
module/language/js-il/runtime.js | 71 ++++++++++++++++++++++++++++++++++++----
1 file changed, 65 insertions(+), 6 deletions(-)
diff --git a/module/language/js-il/runtime.js b/module/language/js-il/runtime.js
index 5a2afa2..5fc10c2 100644
--- a/module/language/js-il/runtime.js
+++ b/module/language/js-il/runtime.js
@@ -380,7 +380,7 @@ var abort_to_prompt = function(self, k, prompt) {
kont = new scheme.Closure(f, 0);
};
- unwind(idx);
+ unwind(scheme.dynstack, idx); // FIXME:
var handler = frame.handler;
args.unshift(kont);
@@ -396,8 +396,17 @@ var call_with_values = function (self, k, producer,
consumer) {
};
var callcc = function (self, k, closure) {
+ var dynstack = scheme.dynstack.slice();
+
var f = function (self, k2) {
var args = Array.prototype.slice.call(arguments, 2);
+
+ var i = shared_stack_length(dynstack, scheme.dynstack);
+
+ unwind(scheme.dynstack, i);
+ wind(dynstack, i);
+ scheme.dynstack = dynstack;
+
return k.apply(k,args);
};
return closure.fun(closure, k, new scheme.Closure(f, 0));
@@ -461,8 +470,17 @@ scheme.primitives["fluid-ref"] = function (fluid) {
scheme.primitives["variable?"] = not_implemented_yet;
// Dynamic Wind
-scheme.primitives["wind"] = not_implemented_yet;
-scheme.primitives["unwind"] = not_implemented_yet;
+scheme.primitives["wind"] = function(enter, leave) {
+ var frame = new scheme.frame.DynWind(enter, leave);
+ scheme.dynstack.unshift(frame);
+};
+
+scheme.primitives["unwind"] = function () {
+ var frame = scheme.dynstack.shift();
+ if (!(frame instanceof scheme.frame.DynWind)) {
+ throw "not a dynamic wind frame";
+ };
+};
// Misc
scheme.primitives["prompt"] = function(escape_only, tag, handler){
@@ -470,9 +488,45 @@ scheme.primitives["prompt"] = function(escape_only, tag,
handler){
scheme.dynstack.unshift(frame);
};
-var unwind = function (idx) {
- // TODO: call winders
- scheme.dynstack = scheme.dynstack.slice(idx+1);
+var shared_stack_length = function (dynstack1, dynstack2) {
+ // Assumes that if it matches at i then it matches for all x<i,
+ // which will be fine given that we don't reuse frames
+ var size1 = dynstack1.length;
+ var size2 = dynstack2.length;
+ var last = Math.min(size1, size2);
+
+ var i = last-1;
+ for (; i >= 0; i--) {
+ if (dynstack1[i] === dynstack2[i]) {
+ break;
+ }
+ };
+
+ return i + 1;
+};
+
+var wind = function (dynstack, idx) {
+ for (var i = idx; i < dynstack.length; i++) {
+ var frame = dynstack[i];
+ if (frame instanceof scheme.frame.DynWind) {
+ // TODO: how to handle continuations and errors in this?
+ frame.wind.fun(frame.wind, scheme.initial_cont);
+ } else {
+ throw "unsupported frame type -- wind";
+ }
+ }
+};
+
+var unwind = function (dynstack, idx) {
+ for (var i = dynstack.length - 1; i >= idx; i--) {
+ var frame = dynstack[i];
+ if (frame instanceof scheme.frame.DynWind) {
+ // TODO: how to handle continuations and errors in this?
+ frame.unwind.fun(frame.unwind, scheme.initial_cont);
+ } else {
+ throw "unsupported frame type -- unwind";
+ }
+ }
};
var find_prompt = function(prompt) {
@@ -509,6 +563,11 @@ scheme.frame.Fluid = function(fluid, old_value) {
this.old_value = old_value;
};
+scheme.frame.DynWind = function(wind, unwind) {
+ this.wind = wind;
+ this.unwind = unwind;
+};
+
// Module Cache
scheme.module_cache["guile"] = scheme.env;
- [Guile-commits] 78/99: Implement Hook Builtins, (continued)
- [Guile-commits] 78/99: Implement Hook Builtins, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 81/99: Argument to make-fluid is optional, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 83/99: Implement variable-bound? builtin, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 88/99: read argument to --depends switch, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 89/99: extra-dependencies go before boot-dependencies, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 90/99: Mention all arguments to guild jslink in --help, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 92/99: Merge branch 'compile-to-js-2017' into compile-to-js-rebase, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 99/99: Compile cps to bytecode by default, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 24/99: Primitives create multiple argument continuations., Christopher Allan Webber, 2021/10/10
- [Guile-commits] 14/99: Add binop type, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 53/99: Implement Winding & Unwinding,
Christopher Allan Webber <=
- [Guile-commits] 63/99: Implement hashtable built-ins, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 66/99: Implement misc built-ins, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 61/99: define! primitive only takes one argument., Christopher Allan Webber, 2021/10/10
- [Guile-commits] 69/99: Unwind prompt frames, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 67/99: Make child structs applicable., Christopher Allan Webber, 2021/10/10
- [Guile-commits] 74/99: Reimplement JS module system primitives., Christopher Allan Webber, 2021/10/10
- [Guile-commits] 95/99: Fix import of lower-cps in compile-js.scm, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 73/99: Implement unboxed integer primitives., Christopher Allan Webber, 2021/10/10
- [Guile-commits] 76/99: Separate public / private module lookups, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 77/99: Search for variables in imports., Christopher Allan Webber, 2021/10/10