changeset 1020:dfe34fad749d

RPC uses VM support for call/cc
author Adam Chlipala <adamc@hcoop.net>
date Sun, 25 Oct 2009 14:07:10 -0400
parents 68ba074e260f
children 7a4a55e05081
files CHANGELOG lib/js/urweb.js src/compiler.sig src/compiler.sml src/core.sml src/core_print.sml src/core_untangle.sml src/core_util.sml src/effectize.sml src/jscomp.sml src/mono.sml src/mono_print.sml src/mono_reduce.sml src/mono_util.sml src/monoize.sml src/reduce.sml src/reduce_local.sml src/rpcify.sml src/shake.sml src/sources src/tailify.sig src/tailify.sml
diffstat 22 files changed, 59 insertions(+), 471 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Sun Oct 25 13:12:24 2009 -0400
+++ b/CHANGELOG	Sun Oct 25 14:07:10 2009 -0400
@@ -1,3 +1,12 @@
+========
+Next
+========
+
+- Bug fixes
+- Optimization improvements
+- Removed a restriction that prevented some RPCs from compiling
+- New extra demo: conference1
+
 ========
 20091012
 ========
--- a/lib/js/urweb.js	Sun Oct 25 13:12:24 2009 -0400
+++ b/lib/js/urweb.js	Sun Oct 25 14:07:10 2009 -0400
@@ -632,7 +632,7 @@
 
       if (isok) {
         try {
-          execF(k, parse(xhr.responseText));
+          k(parse(xhr.responseText));
         } catch (v) {
           doExn(v);
         }
@@ -854,7 +854,11 @@
 }
 
 function exec0(env, e) {
-  var stack = null;
+  return exec1(env, null, e);
+}
+
+function exec1(env, stack, e) {
+  var stack, usedK = false;
 
   var saveEnv = function() {
     if (stack.next != null && stack.next.data.c != "<")
@@ -883,8 +887,9 @@
       case "f":
         fr.args[fr.pos++] = v;
         if (fr.a == null) {
+          stack = stack.next;
           e = {c: "c", v: fr.f.apply(null, fr.args)};
-          stack = stack.next;
+          if (usedK) return null;
         } else {
           e = fr.a.data;
           fr.a = fr.a.next;
@@ -1014,6 +1019,11 @@
       env = e.env;
       e = e.body;
       break;
+    case "K":
+      { var savedStack = stack.next, savedEnv = env;
+      e = {c: "c", v: function(v) { return exec1(savedEnv, savedStack, {c: "c", v: v}); } };}
+      usedK = true;
+      break;      
     default:
       whine("Unknown Ur expression kind " + e.c);
     }
--- a/src/compiler.sig	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/compiler.sig	Sun Oct 25 14:07:10 2009 -0400
@@ -86,7 +86,6 @@
     val reduce : (Core.file, Core.file) phase
     val unpoly : (Core.file, Core.file) phase
     val specialize : (Core.file, Core.file) phase
-    val tailify : (Core.file, Core.file) phase
     val marshalcheck : (Core.file, Core.file) phase
     val effectize : (Core.file, Core.file) phase
     val monoize : (Core.file, Mono.file) phase
@@ -121,7 +120,6 @@
     val toSpecialize : (string, Core.file) transform 
     val toShake3 : (string, Core.file) transform
     val toEspecialize : (string, Core.file) transform 
-    val toTailify : (string, Core.file) transform
     val toReduce2 : (string, Core.file) transform
     val toShake4 : (string, Core.file) transform
     val toMarshalcheck : (string, Core.file) transform
--- a/src/compiler.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/compiler.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -779,14 +779,7 @@
 
 val toEspecialize = transform especialize "especialize" o toShake3
 
-val tailify = {
-    func = Tailify.frob,
-    print = CorePrint.p_file CoreEnv.empty
-}
-
-val toTailify = transform tailify "tailify" o toEspecialize
-
-val toReduce2 = transform reduce "reduce2" o toTailify
+val toReduce2 = transform reduce "reduce2" o toEspecialize
 
 val toShake4 = transform shake "shake4" o toReduce2
 
--- a/src/core.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/core.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -115,8 +115,7 @@
 
        | ELet of string * con * exp * exp
 
-       | EServerCall of int * exp list * exp * con * con
-       | ETailCall of int * exp list * exp * con * con
+       | EServerCall of int * exp list * con
 
 withtype exp = exp' located
 
--- a/src/core_print.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/core_print.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -438,22 +438,12 @@
                                     newline,
                                     p_exp (E.pushERel env x t) e2]
 
-      | EServerCall (n, es, e, _, _) => box [string "Server(",
-                                             p_enamed env n,
-                                             string ",",
-                                             space,
-                                             p_list (p_exp env) es,
-                                             string ")[",
-                                             p_exp env e,
-                                             string "]"]
-      | ETailCall (n, es, e, _, _) => box [string "Tail(",
-                                           p_enamed env n,
-                                           string ",",
-                                           space,
-                                           p_list (p_exp env) es,
-                                           string ")[",
-                                           p_exp env e,
-                                           string "]"]
+      | EServerCall (n, es, _) => box [string "Server(",
+                                       p_enamed env n,
+                                       string ",",
+                                       space,
+                                       p_list (p_exp env) es,
+                                       string ")"]
 
       | EKAbs (x, e) => box [string x,
                              space,
--- a/src/core_untangle.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/core_untangle.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -48,8 +48,7 @@
         case e of
             ENamed n => try n
           | EClosure (n, _) => try n
-          | EServerCall (n, _, _, _, _) => try n
-          | ETailCall (n, _, _, _, _) => try n
+          | EServerCall (n, _, _) => try n
           | _ => s
     end
 
--- a/src/core_util.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/core_util.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -532,20 +532,12 @@
       | (ELet _, _) => LESS
       | (_, ELet _) => GREATER
 
-      | (EServerCall (n1, es1, e1, _, _), EServerCall (n2, es2, e2, _, _)) =>
+      | (EServerCall (n1, es1, _), EServerCall (n2, es2, _)) =>
         join (Int.compare (n1, n2),
-              fn () => join (joinL compare (es1, es2),
-                             fn () => compare (e1, e2)))
+              fn () => joinL compare (es1, es2))
       | (EServerCall _, _) => LESS
       | (_, EServerCall _) => GREATER
 
-      | (ETailCall (n1, es1, e1, _, _), ETailCall (n2, es2, e2, _, _)) =>
-        join (Int.compare (n1, n2),
-              fn () => join (joinL compare (es1, es2),
-                             fn () => compare (e1, e2)))
-      | (ETailCall _, _) => LESS
-      | (_, ETailCall _) => GREATER
-
       | (EKAbs (_, e1), EKAbs (_, e2)) => compare (e1, e2)
       | (EKAbs _, _) => LESS
       | (_, EKAbs _) => GREATER
@@ -725,27 +717,12 @@
                                           fn e2' =>
                                              (ELet (x, t', e1', e2'), loc))))
 
-              | EServerCall (n, es, e, t1, t2) =>
+              | EServerCall (n, es, t) =>
                 S.bind2 (ListUtil.mapfold (mfe ctx) es,
                       fn es' =>
-                         S.bind2 (mfe ctx e,
-                                 fn e' =>
-                                    S.bind2 (mfc ctx t1,
-                                          fn t1' =>
-                                             S.map2 (mfc ctx t2,
-                                                  fn t2' =>
-                                                     (EServerCall (n, es', e', t1', t2'), loc)))))
-
-              | ETailCall (n, es, e, t1, t2) =>
-                S.bind2 (ListUtil.mapfold (mfe ctx) es,
-                      fn es' =>
-                         S.bind2 (mfe ctx e,
-                                 fn e' =>
-                                    S.bind2 (mfc ctx t1,
-                                          fn t1' =>
-                                             S.map2 (mfc ctx t2,
-                                                  fn t2' =>
-                                                     (ETailCall (n, es', e', t1', t2'), loc)))))
+                         S.map2 (mfc ctx t,
+                              fn t' =>
+                                 (EServerCall (n, es', t'), loc)))
 
               | EKAbs (x, e) =>
                 S.map2 (mfe (bind (ctx, RelK x)) e,
--- a/src/effectize.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/effectize.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -46,7 +46,7 @@
                 EFfi f => effectful f
               | EFfiApp (m, x, _) => effectful (m, x)
               | ENamed n => IM.inDomain (evs, n)
-              | EServerCall (n, _, _, _, _) => IM.inDomain (evs, n)
+              | EServerCall (n, _, _) => IM.inDomain (evs, n)
               | _ => false
 
         fun couldWriteOnload evs = U.Exp.exists {kind = fn _ => false,
@@ -70,7 +70,7 @@
             case e of
                 EFfi ("Basis", "getCookie") => true
               | ENamed n => IM.inDomain (evs, n)
-              | EServerCall (n, _, _, _, _) => IM.inDomain (evs, n)
+              | EServerCall (n, _, _) => IM.inDomain (evs, n)
               | _ => false
 
         fun couldReadCookie evs = U.Exp.exists {kind = fn _ => false,
--- a/src/jscomp.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/jscomp.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -900,10 +900,9 @@
                                  st)
                             end
 
-                          | EServerCall (e, ek, t, eff) =>
+                          | EServerCall (e, t, eff) =>
                             let
                                 val (e, st) = jsE inner (e, st)
-                                val (ek, st) = jsE inner (ek, st)
                                 val (unurl, st) = unurlifyExp loc (t, st)
                             in
                                 (strcat [str ("{c:\"f\",f:rc,a:cons({c:\"c\",v:\""
@@ -911,9 +910,7 @@
                                               ^ "\"},cons("),
                                          e,
                                          str (",cons({c:\"c\",v:function(s){var t=s.split(\"/\");var i=0;return "
-                                              ^ unurl ^ "}},cons("),
-                                         ek,
-                                         str (",cons({c:\"c\",v:"
+                                              ^ unurl ^ "}},cons({c:\"K\"},cons({c:\"c\",v:"
                                               ^ (case eff of
                                                      ReadCookieWrite => "true"
                                                    | _ => "false")
@@ -1165,12 +1162,11 @@
                      ((ESignalSource e, loc), st)
                  end
                  
-               | EServerCall (e1, e2, t, ef) =>
+               | EServerCall (e1, t, ef) =>
                  let
                      val (e1, st) = exp outer (e1, st)
-                     val (e2, st) = exp outer (e2, st)
                  in
-                     ((EServerCall (e1, e2, t, ef), loc), st)
+                     ((EServerCall (e1, t, ef), loc), st)
                  end
                | ERecv (e1, e2, t) =>
                  let
--- a/src/mono.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/mono.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -113,8 +113,8 @@
        | ESignalReturn of exp
        | ESignalBind of exp * exp
        | ESignalSource of exp
-
-       | EServerCall of exp * exp * typ * effect
+                              
+       | EServerCall of exp * typ * effect
        | ERecv of exp * exp * typ
        | ESleep of exp * exp
 
--- a/src/mono_print.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/mono_print.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -335,11 +335,9 @@
                                 p_exp env e,
                                 string ")"]
 
-      | EServerCall (n, e, _, _) => box [string "Server(",
-                                         p_exp env n,
-                                         string ")[",
-                                         p_exp env e,
-                                         string "]"]
+      | EServerCall (n, _, _) => box [string "Server(",
+                                      p_exp env n,
+                                      string ")"]
       | ERecv (n, e, _) => box [string "Recv(",
                                 p_exp env n,
                                 string ")[",
--- a/src/mono_reduce.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/mono_reduce.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -450,7 +450,7 @@
                       | ESignalBind (e1, e2) => summarize d e1 @ summarize d e2
                       | ESignalSource e => summarize d e
 
-                      | EServerCall (e, _, _, _) => summarize d e @ [Unsure]
+                      | EServerCall (e, _, _) => summarize d e @ [Unsure]
                       | ERecv (e, _, _) => summarize d e @ [Unsure]
                       | ESleep (e, _) => summarize d e @ [Unsure]
             in
--- a/src/mono_util.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/mono_util.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -362,14 +362,12 @@
                      fn e' =>
                         (ESignalSource e', loc))
 
-              | EServerCall (s, ek, t, eff) =>
+              | EServerCall (s, t, eff) =>
                 S.bind2 (mfe ctx s,
                          fn s' =>
-                            S.bind2 (mfe ctx ek,
-                                  fn ek' =>
-                                     S.map2 (mft t,
-                                          fn t' =>
-                                             (EServerCall (s', ek', t', eff), loc))))
+                            S.map2 (mft t,
+                                  fn t' =>
+                                     (EServerCall (s', t', eff), loc)))
               | ERecv (s, ek, t) =>
                 S.bind2 (mfe ctx s,
                       fn s' =>
--- a/src/monoize.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/monoize.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -3201,22 +3201,7 @@
                 ((L'.ELet (x, t', e1, e2), loc), fm)
             end
 
-          | L.ETailCall (n, es, ek, _, (L.TRecord (L.CRecord (_, []), _), _)) =>
-            let
-                val (es, fm) = ListUtil.foldlMap (fn (e, fm) => monoExp (env, st, fm) e) fm es
-                val (ek, fm) = monoExp (env, st, fm) ek
-
-                val e = (L'.ENamed n, loc)
-                val e = foldl (fn (arg, e) => (L'.EApp (e, arg), loc)) e es
-                val e = (L'.EApp (e, ek), loc)
-            in
-                (e, fm)
-            end
-          | L.ETailCall _ => (E.errorAt loc "Full scope of tail call continuation isn't known";
-                              Print.eprefaces' [("Expression", CorePrint.p_exp env all)];
-                              (dummyExp, fm))
-
-          | L.EServerCall (n, es, ek, t, (L.TRecord (L.CRecord (_, []), _), _)) =>
+          | L.EServerCall (n, es, t) =>
             let
                 val t = monoType env t
                 val (_, ft, _, name) = Env.lookupENamed env n
@@ -3239,37 +3224,19 @@
                 val call = foldl (fn (e, call) => (L'.EStrcat (call, e), loc))
                                  (L'.EPrim (Prim.String name), loc) call
 
-                val (ek, fm) = monoExp (env, st, fm) ek
-
                 val unit = (L'.TRecord [], loc)
 
-                val ekf = (L'.EAbs ("f",
-                                    (L'.TFun (t,
-                                              (L'.TFun ((L'.TRecord [], loc),
-                                                        (L'.TRecord [], loc)), loc)), loc),
-                                    (L'.TFun (t,
-                                              (L'.TRecord [], loc)), loc),
-                                    (L'.EAbs ("x",
-                                              t,
-                                              (L'.TRecord [], loc),
-                                              (L'.EApp ((L'.EApp ((L'.ERel 1, loc),
-                                                                  (L'.ERel 0, loc)), loc),
-                                                        (L'.ERecord [], loc)), loc)), loc)), loc)
-                val ek = (L'.EApp (ekf, ek), loc)
                 val eff = if IS.member (!readCookie, n) then
                               L'.ReadCookieWrite
                           else
                               L'.ReadOnly
 
-                val e = (L'.EServerCall (call, ek, t, eff), loc)
+                val e = (L'.EServerCall (call, t, eff), loc)
                 val e = liftExpInExp 0 e
                 val e = (L'.EAbs ("_", unit, unit, e), loc)
             in
                 (e, fm)
             end
-          | L.EServerCall _ => (E.errorAt loc "Full scope of server call continuation isn't known";
-                                Print.eprefaces' [("Expression", CorePrint.p_exp env all)];
-                                (dummyExp, fm))
 
           | L.EKAbs _ => poly ()
           | L.EKApp _ => poly ()
--- a/src/reduce.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/reduce.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -409,102 +409,6 @@
                                     case #1 e of
                                         EApp
                                             ((EApp
-                                                  ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _),
-                                                                          t1),
-                                                                   _), t2), _),
-                                                          (EFfi ("Basis", "transaction_monad"), _)), _),
-                                                   (EServerCall (n, es, (EAbs (_, _, _, ke), _), dom, ran), _)), _),
-                                             trans3) =>
-                                        let
-                                            val e' = (EFfi ("Basis", "bind"), loc)
-                                            val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc)
-                                            val e' = (ECApp (e', dom), loc)
-                                            val e' = (ECApp (e', t2), loc)
-                                            val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc)
-                                            val e' = (EApp (e', ke), loc)
-                                            val e' = (EApp (e', E.liftExpInExp 0 trans3), loc)
-                                            val e' = reassoc e'
-                                            val e' = (EAbs ("x", dom, t2, e'), loc)
-                                            val e' = (EServerCall (n, es, e', dom, t2), loc)
-                                        in
-                                            e'
-                                        end
-
-                                      | EApp
-                                            ((EApp
-                                                  ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _),
-                                                                          t1),
-                                                                   _), t2), _),
-                                                          (EFfi ("Basis", "transaction_monad"), _)), _),
-                                                   (EServerCall (n, es, ke, dom, ran), _)), _),
-                                             trans3) =>
-                                        let
-                                            val e' = (EFfi ("Basis", "bind"), loc)
-                                            val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc)
-                                            val e' = (ECApp (e', dom), loc)
-                                            val e' = (ECApp (e', t2), loc)
-                                            val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc)
-                                            val e' = (EApp (e', exp (UnknownE :: env')
-                                                                    (EApp (E.liftExpInExp 0 ke, (ERel 0, loc)), loc)),
-                                                      loc)
-                                            val e' = (EApp (e', E.liftExpInExp 0 trans3), loc)
-                                            val e' = reassoc e'
-                                            val e' = (EAbs ("x", dom, t2, e'), loc)
-                                            val e' = (EServerCall (n, es, e', dom, t2), loc)
-                                        in
-                                            e'
-                                        end
-
-                                      | EApp
-                                            ((EApp
-                                                  ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _),
-                                                                          t1),
-                                                                   _), t2), _),
-                                                          (EFfi ("Basis", "transaction_monad"), _)), _),
-                                                   (ETailCall (n, es, (EAbs (_, _, _, ke), _), dom, ran), _)), _),
-                                             trans3) =>
-                                        let
-                                            val e' = (EFfi ("Basis", "bind"), loc)
-                                            val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc)
-                                            val e' = (ECApp (e', dom), loc)
-                                            val e' = (ECApp (e', t2), loc)
-                                            val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc)
-                                            val e' = (EApp (e', ke), loc)
-                                            val e' = (EApp (e', E.liftExpInExp 0 trans3), loc)
-                                            val e' = reassoc e'
-                                            val e' = (EAbs ("x", dom, t2, e'), loc)
-                                            val e' = (ETailCall (n, es, e', dom, t2), loc)
-                                        in
-                                            e'
-                                        end
-
-                                      | EApp
-                                            ((EApp
-                                                  ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _),
-                                                                          t1),
-                                                                   _), t2), _),
-                                                          (EFfi ("Basis", "transaction_monad"), _)), _),
-                                                   (ETailCall (n, es, ke, dom, ran), _)), _),
-                                             trans3) =>
-                                        let
-                                            val e' = (EFfi ("Basis", "bind"), loc)
-                                            val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc)
-                                            val e' = (ECApp (e', dom), loc)
-                                            val e' = (ECApp (e', t2), loc)
-                                            val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc)
-                                            val e' = (EApp (e', exp (UnknownE :: env')
-                                                                    (EApp (E.liftExpInExp 0 ke, (ERel 0, loc)), loc)),
-                                                      loc)
-                                            val e' = (EApp (e', E.liftExpInExp 0 trans3), loc)
-                                            val e' = reassoc e'
-                                            val e' = (EAbs ("x", dom, t2, e'), loc)
-                                            val e' = (ETailCall (n, es, e', dom, t2), loc)
-                                        in
-                                            e'
-                                        end
-
-                                      | EApp
-                                            ((EApp
                                                   ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), mt),
                                                                            _), _), _), t3), _),
                                                           me), _),
@@ -792,10 +696,7 @@
                           | ELet (x, t, e1, e2) =>
                             (ELet (x, con env t, exp env e1, exp (UnknownE :: env) e2), loc)
 
-                          | EServerCall (n, es, e, t1, t2) => (EServerCall (n, map (exp env) es, exp env e,
-                                                                            con env t1, con env t2), loc)
-                          | ETailCall (n, es, e, t1, t2) => (ETailCall (n, map (exp env) es, exp env e,
-                                                                        con env t1, con env t2), loc)
+                          | EServerCall (n, es, t) => (EServerCall (n, map (exp env) es, con env t), loc)
             in
                 (*if dangling (edepth' (deKnown env)) r then
                     (Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty all),
--- a/src/reduce_local.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/reduce_local.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -139,8 +139,7 @@
 
       | ELet (x, t, e1, e2) => (ELet (x, t, exp env e1, exp (Unknown :: env) e2), loc)
 
-      | EServerCall (n, es, e, t1, t2) => (EServerCall (n, map (exp env) es, exp env e, t1, t2), loc)
-      | ETailCall (n, es, e, t1, t2) => (ETailCall (n, map (exp env) es, exp env e, t1, t2), loc)
+      | EServerCall (n, es, t) => (EServerCall (n, map (exp env) es, t), loc)
 
 fun reduce file =
     let
--- a/src/rpcify.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/rpcify.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -112,11 +112,7 @@
                                 val st = {exported = exported,
                                           export_decls = export_decls}
 
-                                val k = (ECApp ((EFfi ("Basis", "return"), loc),
-                                                (CFfi ("Basis", "transaction"), loc)), loc)
-                                val k = (ECApp (k, ran), loc)
-                                val k = (EApp (k, (EFfi ("Basis", "transaction_monad"), loc)), loc)
-                                val e' = EServerCall (n, args, k, ran, ran)
+                                val e' = EServerCall (n, args, ran)
                             in
                                 (e', st)
                             end
--- a/src/shake.sml	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/shake.sml	Sun Oct 25 14:07:10 2009 -0400
@@ -137,8 +137,7 @@
             in
                 case e of
                     ENamed n => check n
-                  | EServerCall (n, _, _, _, _) => check n
-                  | ETailCall (n, _, _, _, _) => check n
+                  | EServerCall (n, _, _) => check n
                   | _ => s
             end
 
--- a/src/sources	Sun Oct 25 13:12:24 2009 -0400
+++ b/src/sources	Sun Oct 25 14:07:10 2009 -0400
@@ -131,9 +131,6 @@
 rpcify.sig
 rpcify.sml
 
-tailify.sig
-tailify.sml
-
 tag.sig
 tag.sml
 
--- a/src/tailify.sig	Sun Oct 25 13:12:24 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-(* Copyright (c) 2009, Adam Chlipala
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * - The names of contributors may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *)
-
-signature TAILIFY = sig
-
-    val frob : Core.file -> Core.file
-
-end
--- a/src/tailify.sml	Sun Oct 25 13:12:24 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-(* Copyright (c) 2009, Adam Chlipala
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * - The names of contributors may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *)
-
-structure Tailify :> TAILIFY = struct
-
-open Core
-
-structure U = CoreUtil
-structure E = CoreEnv
-
-fun multiLiftExpInExp n e =
-    if n = 0 then
-        e
-    else
-        multiLiftExpInExp (n - 1) (E.liftExpInExp 0 e)
-
-structure IS = IntBinarySet
-structure IM = IntBinaryMap
-
-type state = {
-     cpsed : exp' IM.map,
-     rpc : IS.set
-}
-
-fun frob file =
-    let
-        fun exp (e, st : state) =
-            case e of
-                ENamed n =>
-                (case IM.find (#cpsed st, n) of
-                     NONE => (e, st)
-                   | SOME re => (re, st))
-                
-              | _ => (e, st)
-
-        and doExp (e, st) = U.Exp.foldMap {kind = fn x => x,
-                                           con = fn x => x,
-                                           exp = exp} st (ReduceLocal.reduceExp e)
-
-        fun decl (d, st : state) =
-            let
-                fun makesServerCall b (e, _) =
-                    case e of
-                        EServerCall _ => true
-                      | ETailCall _ => raise Fail "Tailify: ETailCall too early"
-                      | ENamed n => IS.member (#rpc st, n)
-
-                      | EPrim _ => false
-                      | ERel n => List.nth (b, n)
-                      | ECon (_, _, _, NONE) => false
-                      | ECon (_, _, _, SOME e) => makesServerCall b e
-                      | EFfi _ => false
-                      | EFfiApp (_, _, es) => List.exists (makesServerCall b) es
-                      | EApp (e1, e2) => makesServerCall b e1 orelse makesServerCall b e2
-                      | EAbs (_, _, _, e1) => makesServerCall (false :: b) e1
-                      | ECApp (e1, _) => makesServerCall b e1
-                      | ECAbs (_, _, e1) => makesServerCall b e1
-
-                      | EKAbs (_, e1) => makesServerCall b e1
-                      | EKApp (e1, _) => makesServerCall b e1
-
-                      | ERecord xes => List.exists (fn ((CName s, _), e, _) =>
-                                                       not (String.isPrefix "On" s) andalso makesServerCall b e
-                                                     | (_, e, _) => makesServerCall b e) xes
-                      | EField (e1, _, _) => makesServerCall b e1
-                      | EConcat (e1, _, e2, _) => makesServerCall b e1 orelse makesServerCall b e2
-                      | ECut (e1, _, _) => makesServerCall b e1
-                      | ECutMulti (e1, _, _) => makesServerCall b e1
-
-                      | ECase (e1, pes, _) => makesServerCall b e1
-                                              orelse List.exists (fn (p, e) =>
-                                                                     makesServerCall (List.tabulate (E.patBindsN p,
-                                                                                                  fn _ => false) @ b)
-                                                                                     e) pes
-
-                      | EWrite e1 => makesServerCall b e1
-
-                      | EClosure (_, es) => List.exists (makesServerCall b) es
-
-                      | ELet (_, _, e1, e2) => makesServerCall (makesServerCall b e1 :: b) e2
-
-                val makesServerCall = makesServerCall []
-
-                val (d, st) =
-                    case #1 d of
-                        DValRec vis =>
-                        if List.exists (fn (_, _, _, e, _) => makesServerCall e) vis then
-                            let
-                                val rpc = foldl (fn ((_, n, _, _, _), rpc) =>
-                                                    IS.add (rpc, n)) (#rpc st) vis
-
-                                val (cpsed, vis') =
-                                    foldl (fn (vi as (x, n, t, e, s), (cpsed, vis')) =>
-                                              let
-                                                  fun getArgs (t, acc) =
-                                                      case #1 t of
-                                                          TFun (dom, ran) =>
-                                                          getArgs (ran, dom :: acc)
-                                                        | _ => (rev acc, t)
-                                                  val (ts, ran) = getArgs (t, [])
-                                                  val ran = case #1 ran of
-                                                                CApp (_, ran) => ran
-                                                              | _ => raise Fail "Rpcify: Tail function not transactional"
-                                                  val len = length ts
-
-                                                  val loc = #2 e
-                                                  val args = ListUtil.mapi
-                                                                 (fn (i, _) =>
-                                                                     (ERel (len - i - 1), loc))
-                                                                 ts
-                                                  val k = (EFfi ("Basis", "return"), loc)
-                                                  val trans = (CFfi ("Basis", "transaction"), loc)
-                                                  val k = (ECApp (k, trans), loc)
-                                                  val k = (ECApp (k, ran), loc)
-                                                  val k = (EApp (k, (EFfi ("Basis", "transaction_monad"),
-                                                                     loc)), loc)
-                                                  val re = (ETailCall (n, args, k, ran, ran), loc)
-                                                  val (re, _) = foldr (fn (dom, (re, ran)) =>
-                                                                          ((EAbs ("x", dom, ran, re),
-                                                                            loc),
-                                                                           (TFun (dom, ran), loc)))
-                                                                      (re, ran) ts
-
-                                                  val be = multiLiftExpInExp (len + 1) e
-                                                  val be = ListUtil.foldli
-                                                               (fn (i, _, be) =>
-                                                                   (EApp (be, (ERel (len - i), loc)), loc))
-                                                               be ts
-                                                  val ne = (EFfi ("Basis", "bind"), loc)
-                                                  val ne = (ECApp (ne, trans), loc)
-                                                  val ne = (ECApp (ne, ran), loc)
-                                                  val unit = (TRecord (CRecord ((KType, loc), []),
-                                                                       loc), loc)
-                                                  val ne = (ECApp (ne, unit), loc)
-                                                  val ne = (EApp (ne, (EFfi ("Basis", "transaction_monad"),
-                                                                       loc)), loc)
-                                                  val ne = (EApp (ne, be), loc)
-                                                  val ne = (EApp (ne, (ERel 0, loc)), loc)
-                                                  val tunit = (CApp (trans, unit), loc)
-                                                  val kt = (TFun (ran, tunit), loc)
-                                                  val ne = (EAbs ("k", kt, tunit, ne), loc)
-                                                  val (ne, res) = foldr (fn (dom, (ne, ran)) =>
-                                                                            ((EAbs ("x", dom, ran, ne), loc),
-                                                                             (TFun (dom, ran), loc)))
-                                                                        (ne, (TFun (kt, tunit), loc)) ts
-                                              in
-                                                  (IM.insert (cpsed, n, #1 re),
-                                                   (x, n, res, ne, s) :: vis')
-                                              end)
-                                          (#cpsed st, []) vis
-                            in
-                                ((DValRec (rev vis'), ErrorMsg.dummySpan),
-                                 {cpsed = cpsed,
-                                  rpc = rpc})
-                            end
-                        else
-                            (d, st)
-                      | DVal (x, n, t, e, s) =>
-                        (d,
-                         {cpsed = #cpsed st,
-                          rpc = if makesServerCall e then
-                                    IS.add (#rpc st, n)
-                                else
-                                    #rpc st})
-                      | _ => (d, st)
-            in
-                U.Decl.foldMap {kind = fn x => x,
-                                con = fn x => x,
-                                exp = exp,
-                                decl = fn x => x}
-                               st d
-            end
-
-        val (file, _) = ListUtil.foldlMap decl
-                        {cpsed = IM.empty,
-                         rpc = IS.empty}
-                        file
-    in
-        file
-    end
-
-end