]> gitweb.factorcode.org Git - factor.git/commitdiff
fjsc: use setTimeout to jump out of call stack to prevent stack blowout
authorchris.double <chris.double@double.co.nz>
Sat, 16 Dec 2006 23:45:49 +0000 (23:45 +0000)
committerchris.double <chris.double@double.co.nz>
Sat, 16 Dec 2006 23:45:49 +0000 (23:45 +0000)
apps/furnace-fjsc/resources/bootstrap.js

index a6a27185aad503a0bc97fc6dfde17f7c097a0528..106064f1f4920efad16056c29ed475fe392f52bb 100644 (file)
@@ -25,32 +25,107 @@ function Factor() {
   this.cont = new Continuation();
   this.form = false ;
   this.next = false;
+  this.nesting = 0;
 }
 
 var factor = new Factor();
 
+Factor.prototype.call_next = function(next) {
+  if(this.nesting++ > 150) {
+    this.nesting = 0;
+    setTimeout(next, 0);
+  }
+  else {
+    next();
+  }
+}
+
+Factor.prototype.push_data = function(v, next) {
+  factor.cont.data_stack.push(v);
+  factor.call_next(next);
+}
+
+Factor.prototype.define_word = function(name, source, func, next) {
+  factor.words[name] = new Word(name, source, function(next) {
+    var old = factor.next;
+    factor.next = function() {
+      factor.next = old;
+      factor.call_next(next);
+    }
+    func();
+  });
+  factor.call_next(next);
+}
+
+Factor.prototype.make_quotation = function(source, func) {
+  return new Word("quotation", source, function(next) {
+    var old = factor.next;
+    factor.next = function() {
+      factor.next = old;
+      factor.call_next(next);
+    }
+    func();
+  });
+}
+
+Factor.prototype.server_eval = function(text, next) {
+   var self = this;
+   var callback = {
+      success: function(o) {
+        var v = o.responseText;
+        document.getElementById('compiled').innerHTML="<pre>" + v + "</pre>";
+        document.getElementById('code').value="";
+        var func = eval(v);
+         factor.next = function() { self.display_datastack(); } 
+        func(factor);
+         if(next) 
+           factor.call_next(next);
+      }
+   };
+   this.form.code.value=text;
+   YAHOO.util.Connect.setForm(this.form);
+   YAHOO.util.Connect.asyncRequest('POST', "/responder/fjsc/compile", callback);
+}
+
+Factor.prototype.fjsc_eval = function(form) {
+   this.form = form;
+   this.server_eval(form.code.value);
+}
+
+Factor.prototype.display_datastack = function() {
+   var html=[];
+   html.push("<table border='1'>")
+   for(var i = 0; i < this.cont.data_stack.length; ++i) {
+      html.push("<tr><td>")
+      html.push(this.cont.data_stack[i])
+      html.push("</td></tr>")
+   }
+   html.push("</table>")
+   document.getElementById('stack').innerHTML=html.join("");
+}
+
 factor.words["dup"] = new Word("dup", "primitive", function(next) {
   var stack = factor.cont.data_stack;
   stack[stack.length] = stack[stack.length-1];
-  next();
+  factor.call_next(next);
 });
 
 factor.words["drop"] = new Word("drop", "primitive", function(next) {
   factor.cont.data_stack.pop();
-  next();
+  factor.call_next(next);
 });
 
 factor.words["nip"] = new Word("nip", "primitive", function(next) {
   var stack = factor.cont.data_stack;
   stack[stack.length-2] = stack[stack.length-1];
   stack.pop();
-  next();
+  factor.call_next(next);
 });
 
 factor.words["over"] = new Word("over", "primitive", function(next) {
   var stack = factor.cont.data_stack;
   stack[stack.length] = stack[stack.length-2];
-  next();
+  factor.call_next(next);
 });
 
 factor.words["swap"] = new Word("swap", "primitive", function(next) {
@@ -58,33 +133,33 @@ factor.words["swap"] = new Word("swap", "primitive", function(next) {
   var temp = stack[stack.length-2];
   stack[stack.length-2] = stack[stack.length-1];
   stack[stack.length-1] = temp;
-  next();
+  factor.call_next(next);
 });
 
 factor.words[">r"] = new Word(">r", "primitive", function(next) {
   var data_stack = factor.cont.data_stack;
   var retain_stack = factor.cont.retain_stack;
   retain_stack.push(data_stack.pop());
-  next();
+  factor.call_next(next);
 });
 
 factor.words["r>"] = new Word("r>", "primitive", function(next) {
   var data_stack = factor.cont.data_stack;
   var retain_stack = factor.cont.retain_stack;
   data_stack.push(retain_stack.pop());
-  next();
+  factor.call_next(next);
 });
 
 factor.words["*"] = new Word("*", "primitive", function(next) {
   var stack = factor.cont.data_stack;
   stack.push(stack.pop() * stack.pop());
-  next();
+  factor.call_next(next);
 });
 
 factor.words["+"] = new Word("+", "primitive", function(next) {
   var stack = factor.cont.data_stack;
   stack.push(stack.pop() + stack.pop());
-  next();
+  factor.call_next(next);
 });
 
 factor.words["-"] = new Word("-", "primitive", function(next) {
@@ -92,7 +167,7 @@ factor.words["-"] = new Word("-", "primitive", function(next) {
   var v1 = stack.pop();
   var v2 = stack.pop();
   stack.push(v2 - v1);
-  next();
+  factor.call_next(next);
 });
 
 factor.words["/"] = new Word("/", "primitive", function(next) {
@@ -100,12 +175,12 @@ factor.words["/"] = new Word("/", "primitive", function(next) {
   var v1 = stack.pop();
   var v2 = stack.pop();
   stack.push(v2 / v1);
-  next();
+  factor.call_next(next);
 });
 
 factor.words["."] = new Word(".", "primitive", function(next) {
   alert(factor.cont.data_stack.pop());
-  next();
+  factor.call_next(next);
 });
 
 factor.words["call"] = new Word("call", "primitive", function(next) {
@@ -121,13 +196,13 @@ factor.words["execute"] = new Word("execute", "primitive", function(next) {
 factor.words["clear"] = new Word("clear", "primitive", function(next) {
   factor.cont.data_stack = [];
   factor.cont.retain_stack = [];
-  next();
+  factor.call_next(next);
 });
 
 factor.words["square"] = new Word("square", "primitive", function(next) {  
   var stack = factor.cont.data_stack;
   stack[stack.length-1] = stack[stack.length-1] * stack[stack.length-1];
-  next();
+  factor.call_next(next);
 });
 
 factor.words["if"] = new Word("if", "primitive", function(next) {  
@@ -144,23 +219,23 @@ factor.words["if"] = new Word("if", "primitive", function(next) {
 
 factor.words["f"] = new Word("f", "primitive", function(next) {  
   factor.cont.data_stack.push(false);
-  next();
+  factor.call_next(next);
 });
 
 factor.words["t"] = new Word("t", "primitive", function(next) {  
   factor.cont.data_stack.push(true);
-  next();
+  factor.call_next(next);
 });
 
 factor.words["="] = new Word("=", "primitive", function(next) {   
   var stack = factor.cont.data_stack;
   stack.push(stack.pop()==stack.pop());
-  next();
+  factor.call_next(next);
 });
 
 factor.words["window"] = new Word("window", "primitive", function(next) {  
   factor.cont.data_stack.push(window);
-  next();
+  factor.call_next(next);
 });
 
 factor.words["bootstrap"] = new Word("bootstrap", "primitive", function(next) {  
@@ -178,7 +253,7 @@ factor.words["run-file"] = new Word("run-file", "primitive", function(next) {
     },
     failure: function(o) {
       alert('run-file failed');
-      next();
+      factor.call_next(next);
     }
   };
   YAHOO.util.Connect.asyncRequest('GET', url, callback, null);
@@ -192,7 +267,7 @@ factor.words["callcc0"] = new Word("callcc0", "primitive", function(next) {
   var cont = {
     next: function() {
       factor.next = old_next;
-      next();
+      factor.call_next(next);
     },
     cont: factor.cont
   };
@@ -205,7 +280,7 @@ factor.words["continue"] = new Word("continue", "primitive", function(next) {
   var data_stack = factor.cont.data_stack;
   var cont = data_stack.pop(); 
   factor.cont = cont.cont.clone();
-  (cont.next)();
+  factor.call_next(cont.next);
 });
 
 factor.words["alien-invoke"] = new Word("alien-invoke", "primitive", function(next) {  
@@ -222,69 +297,5 @@ factor.words["alien-invoke"] = new Word("alien-invoke", "primitive", function(ne
   var v = obj[method_name].apply(obj, args);
   if(return_values.length > 0)
     stack.push(v);
-  next();
+  factor.call_next(next);
 });
-
-Factor.prototype.push_data = function(v, next) {
-  factor.cont.data_stack.push(v);
-  next();
-}
-
-Factor.prototype.define_word = function(name, source, func, next) {
-  factor.words[name] = new Word(name, source, function(next) {
-    var old = factor.next;
-    factor.next = function() {
-      factor.next = old;
-      next();
-    }
-    func();
-  });
-  next();
-}
-
-Factor.prototype.make_quotation = function(source, func) {
-  return new Word("quotation", source, function(next) {
-    var old = factor.next;
-    factor.next = function() {
-      factor.next = old;
-      next();
-    }
-    func();
-  });
-}
-
-Factor.prototype.server_eval = function(text, next) {
-   var self = this;
-   var callback = {
-      success: function(o) {
-        var v = o.responseText;
-        document.getElementById('compiled').innerHTML="<pre>" + v + "</pre>";
-        document.getElementById('code').value="";
-        var func = eval(v);
-         factor.next = function() { self.display_datastack(); } 
-        func(factor);
-         if(next) 
-           next();
-      }
-   };
-   this.form.code.value=text;
-   YAHOO.util.Connect.setForm(this.form);
-   YAHOO.util.Connect.asyncRequest('POST', "/responder/fjsc/compile", callback);
-}
-
-Factor.prototype.fjsc_eval = function(form) {
-   this.form = form;
-   this.server_eval(form.code.value);
-}
-
-Factor.prototype.display_datastack = function() {
-   var html=[];
-   html.push("<table border='1'>")
-   for(var i = 0; i < this.cont.data_stack.length; ++i) {
-      html.push("<tr><td>")
-      html.push(this.cont.data_stack[i])
-      html.push("</td></tr>")
-   }
-   html.push("</table>")
-   document.getElementById('stack').innerHTML=html.join("");
-}
\ No newline at end of file