comparison src/jscomp.sml @ 801:5f49a6b759cb

Fix nasty bugs with longjmp() looping for uw_set_input(); and bad variable indexes for nested JavaScript in jscomp
author Adam Chlipala <adamc@hcoop.net>
date Thu, 14 May 2009 18:13:09 -0400
parents e92cfac1608f
children d8f58d488cfb
comparison
equal deleted inserted replaced
800:e92cfac1608f 801:5f49a6b759cb
141 case es of 141 case es of
142 [] => (EPrim (Prim.String ""), loc) 142 [] => (EPrim (Prim.String ""), loc)
143 | [x] => x 143 | [x] => x
144 | x :: es' => (EStrcat (x, strcat loc es'), loc) 144 | x :: es' => (EStrcat (x, strcat loc es'), loc)
145 145
146 fun patDepth (p, _) =
147 case p of
148 PWild => 0
149 | PVar _ => 0
150 | PPrim _ => 0
151 | PCon (_, _, NONE) => 0
152 | PCon (_, _, SOME p) => 1 + patDepth p
153 | PRecord xpts => foldl Int.max 0 (map (fn (_, p, _) => 1 + patDepth p) xpts)
154 | PNone _ => 0
155 | PSome (_, p) => 1 + patDepth p
156
157 val compact =
158 U.Exp.mapB {typ = fn t => t,
159 exp = fn inner => fn e =>
160 case e of
161 ERel n =>
162 if n >= inner then
163 ERel (n - inner)
164 else
165 e
166 | _ => e,
167 bind = fn (inner, b) =>
168 case b of
169 U.Exp.RelE _ => inner+1
170 | _ => inner}
171
146 fun process file = 172 fun process file =
147 let 173 let
148 val (someTs, nameds) = 174 val (someTs, nameds) =
149 foldl (fn ((DVal (_, n, t, e, _), _), (someTs, nameds)) => (someTs, IM.insert (nameds, n, e)) 175 foldl (fn ((DVal (_, n, t, e, _), _), (someTs, nameds)) => (someTs, IM.insert (nameds, n, e))
150 | ((DValRec vis, _), (someTs, nameds)) => 176 | ((DValRec vis, _), (someTs, nameds)) =>
252 listInjectors = TM.insert (#listInjectors st, t', n'), 278 listInjectors = TM.insert (#listInjectors st, t', n'),
253 decoders = #decoders st, 279 decoders = #decoders st,
254 maxName = n' + 1} 280 maxName = n' + 1}
255 281
256 val s = (TFfi ("Basis", "string"), loc) 282 val s = (TFfi ("Basis", "string"), loc)
257 val (e', st) = quoteExp loc t ((EField ((ERel 0, loc), "1"), loc), st) 283 val (e', st) = quoteExp loc t' ((EField ((ERel 0, loc), "1"), loc), st)
258 284
259 val body = (ECase ((ERel 0, loc), 285 val body = (ECase ((ERel 0, loc),
260 [((PNone rt, loc), 286 [((PNone rt, loc),
261 str loc "null"), 287 str loc "null"),
262 ((PSome (rt, (PVar ("x", rt), loc)), loc), 288 ((PSome (rt, (PVar ("x", rt), loc)), loc),
618 | _ => (Print.prefaces "deStrcat" [("e", MonoPrint.p_exp MonoEnv.empty all)]; 644 | _ => (Print.prefaces "deStrcat" [("e", MonoPrint.p_exp MonoEnv.empty all)];
619 raise Fail "Jscomp: deStrcat") 645 raise Fail "Jscomp: deStrcat")
620 646
621 val quoteExp = quoteExp loc 647 val quoteExp = quoteExp loc
622 in 648 in
623 (*Print.prefaces "jsE" [("e", MonoPrint.p_exp MonoEnv.empty e)];*) 649 (*Print.prefaces "jsE" [("e", MonoPrint.p_exp MonoEnv.empty e),
650 ("inner", Print.PD.string (Int.toString inner))];*)
624 651
625 case #1 e of 652 case #1 e of
626 EPrim p => (jsPrim p, st) 653 EPrim p => (jsPrim p, st)
627 | ERel n => 654 | ERel n =>
628 if n < inner then 655 if n < inner then
629 (str ("_" ^ var n), st) 656 (str ("_" ^ var n), st)
630 else 657 else
631 let 658 let
659 (*val () = Print.prefaces "ERel"
660 [("n", Print.PD.string (Int.toString n)),
661 ("inner", Print.PD.string (Int.toString inner)),
662 ("eq", MonoPrint.p_exp MonoEnv.empty
663 (#1 (quoteExp (List.nth (outer, n - inner))
664 ((ERel (n - inner), loc), st))))]*)
632 val n = n - inner 665 val n = n - inner
633 in 666 in
634 quoteExp (List.nth (outer, n)) ((ERel n, loc), st) 667 quoteExp (List.nth (outer, n)) ((ERel n, loc), st)
635 end 668 end
636 669
650 injectors = #injectors st, 683 injectors = #injectors st,
651 listInjectors = #listInjectors st, 684 listInjectors = #listInjectors st,
652 decoders = #decoders st, 685 decoders = #decoders st,
653 maxName = #maxName st} 686 maxName = #maxName st}
654 687
688 val old = e
655 val (e, st) = jsExp mode [] 0 (e, st) 689 val (e, st) = jsExp mode [] 0 (e, st)
690 val new = e
656 val e = deStrcat 0 e 691 val e = deStrcat 0 e
657 692
658 val sc = "_n" ^ Int.toString n ^ "=" ^ e ^ ";\n" 693 val sc = "_n" ^ Int.toString n ^ "=" ^ e ^ ";\n"
659 in 694 in
695 (*Print.prefaces "jsify'" [("old", MonoPrint.p_exp MonoEnv.empty old),
696 ("new", MonoPrint.p_exp MonoEnv.empty new)];*)
660 {decls = #decls st, 697 {decls = #decls st,
661 script = sc :: #script st, 698 script = sc :: #script st,
662 included = #included st, 699 included = #included st,
663 injectors = #injectors st, 700 injectors = #injectors st,
664 listInjectors = #listInjectors st, 701 listInjectors = #listInjectors st,
849 (strcat [e, 886 (strcat [e,
850 str ("._" ^ x)], st) 887 str ("._" ^ x)], st)
851 end 888 end
852 889
853 | ECase (e', pes, {result, ...}) => 890 | ECase (e', pes, {result, ...}) =>
854 (*if closedUpto inner e andalso List.all (fn (_, e) => closedUpto inner e) pes then 891 let
855 let 892 val plen = length pes
856 val (e', st) = quoteExp result ((ERel 0, loc), st) 893
857 in 894 val (cases, st) = ListUtil.foldliMap
858 ((ELet ("js", result, e, e'), loc), 895 (fn (i, (p, e), st) =>
859 st) 896 let
860 end 897 val (e, st) = jsE (inner + E.patBindsN p) (e, st)
861 else*) 898 val fail =
862 let 899 if i = plen - 1 then
863 val plen = length pes 900 str "pf()"
864 901 else
865 val (cases, st) = ListUtil.foldliMap 902 str ("c" ^ Int.toString (i+1) ^ "()")
866 (fn (i, (p, e), st) => 903 val c = jsPat 0 inner p e fail
867 let 904 in
868 val (e, st) = jsE (inner + E.patBindsN p) (e, st) 905 (strcat [str ("c" ^ Int.toString i ^ "=function(){return "),
869 val fail = 906 c,
870 if i = plen - 1 then 907 str "},"],
871 str "pf()" 908 st)
872 else 909 end)
873 str ("c" ^ Int.toString (i+1) ^ "()") 910 st pes
874 val c = jsPat 0 inner p e fail 911
875 in 912 val depth = foldl Int.max 0 (map (fn (p, _) => 1 + patDepth p) pes)
876 (strcat [str ("c" ^ Int.toString i ^ "=function(){return "), 913 val normalDepth = foldl Int.max 0 (map (fn (_, e) => 1 + varDepth e) pes)
877 c, 914 val (e, st) = jsE inner (e', st)
878 str "},"], 915
879 st) 916 val len = inner + len
880 end) 917 val normalVars = List.tabulate (normalDepth, fn n => "_" ^ Int.toString (n + len))
881 st pes 918 val patVars = List.tabulate (depth, fn n => "d" ^ Int.toString n)
882 919 in
883 val (e, st) = jsE inner (e', st) 920 (strcat (str "(function (){ var "
884 in 921 :: str (String.concatWith "," (normalVars @ patVars) ^ ";d0=")
885 (strcat (str "(d0=" 922 :: e
886 :: e 923 :: str ";\nreturn ("
887 :: str "," 924 :: List.revAppend (cases,
888 :: List.revAppend (cases, 925 [str "c0()) } ())"])), st)
889 [str "c0())"])), st) 926 end
890 end
891 927
892 | EStrcat (e1, e2) => 928 | EStrcat (e1, e2) =>
893 let 929 let
894 val (e1, st) = jsE inner (e1, st) 930 val (e1, st) = jsE inner (e1, st)
895 val (e2, st) = jsE inner (e2, st) 931 val (e2, st) = jsE inner (e2, st)
937 (foundJavaScript := true; 973 (foundJavaScript := true;
938 (e, st)) 974 (e, st))
939 | EJavaScript (_, _, SOME e) => 975 | EJavaScript (_, _, SOME e) =>
940 (foundJavaScript := true; 976 (foundJavaScript := true;
941 (strcat [str "cs(function(){return ", 977 (strcat [str "cs(function(){return ",
942 e, 978 compact inner e,
943 str "})"], 979 str "})"],
944 st)) 980 st))
945 981
946 | EClosure _ => unsupported "EClosure" 982 | EClosure _ => unsupported "EClosure"
947 | EQuery _ => unsupported "Query" 983 | EQuery _ => unsupported "Query"
1052 fun str s = (EPrim (Prim.String s), #2 e) 1088 fun str s = (EPrim (Prim.String s), #2 e)
1053 1089
1054 val locals = List.tabulate 1090 val locals = List.tabulate
1055 (varDepth e, 1091 (varDepth e,
1056 fn i => str ("var _" ^ Int.toString (len + i) ^ ";")) 1092 fn i => str ("var _" ^ Int.toString (len + i) ^ ";"))
1093 val old = e
1057 val (e, st) = jsExp m env 0 (e, st) 1094 val (e, st) = jsExp m env 0 (e, st)
1058 in 1095 in
1096 (*Print.prefaces "jsify" [("old", MonoPrint.p_exp MonoEnv.empty old),
1097 ("new", MonoPrint.p_exp MonoEnv.empty e)];*)
1059 (EJavaScript (m, orig, SOME (strcat (#2 e) (locals @ [e]))), st) 1098 (EJavaScript (m, orig, SOME (strcat (#2 e) (locals @ [e]))), st)
1060 end 1099 end
1061 in 1100 in
1062 case e of 1101 case e of
1063 EJavaScript (m, orig, NONE) => 1102 EJavaScript (m, orig, NONE) =>