[MLton-commit] r5731

Matthew Fluet fluet at mlton.org
Fri Jul 6 15:19:37 PDT 2007


Fixed a *very* long-standing bug in the monomorphisation pass,
reported by Vesa Karvonen.  (AFAICT, the bug has been present since
the original mlton-19990319 release.)

Unlike value variables, type variables are not uniquified by the
front-end passes.  Hence, it is entirely possible for a type variable
in the XML IL (that is a symbol with an associated property list) to
be used as a type variable for multiple polymorphic variables.
Indeed, since explicit type variables in the source derive their
identity from the corresponding source type variable (as a textual
name), there are often many uses of the "'a" type variable throughout
the XML IL program, though with different scopes.

The monomorphisation pass works by setting (via a property) a
monomorphic instantiation for a type variable, which is meant to
persist for the scope of the type variable.  Unfortunately, by
monomorphising a sub-expression, we may end up setting a different
monomorphic instantiation for the same type variable (but
corresponding to a different scope).  There are occasions where the
monomorphisation pass returns from monomorphising a sub-expression to
monomorphise a type.  If the monomorphisation of the sub-expression
set a type variable used by the type, then the type is monomorphised
under the wrong monomorphic instantiation.

It turns out that monomorphising a type never results in setting a
type variable's monomorphic instantation.  Hence, for a PolyVal, it
suffices to monomorphise the type before monomorphising the
expression.  (This change suffices for Vesa's code.)

For a Fun (i.e., a recursive collection of polymorphic functions),
however, there are multiple calls to monomorphise a lambda, each of
which may reset a type variable's monomorphic instantiation.  Hence,
the proper monomorphic instantiation must be esablished for each
lambda.  (This wasn't triggered by Vesa's code.)


----------------------------------------------------------------------

U   mlton/trunk/doc/changelog
U   mlton/trunk/mlton/xml/monomorphise.fun

----------------------------------------------------------------------

Modified: mlton/trunk/doc/changelog
===================================================================
--- mlton/trunk/doc/changelog	2007-07-06 21:27:53 UTC (rev 5730)
+++ mlton/trunk/doc/changelog	2007-07-06 22:19:35 UTC (rev 5731)
@@ -1,5 +1,9 @@
 Here are the changes since version 20051202.
 
+* 2007-07-6
+   - Fixed a long-standing bug in monomorphisation pass.  Thanks to
+     Vesa Karvonen for the bug report.
+
 * 2007-05-18
    - Native amd64 code generator for amd64-* targets.
    - Eliminate native option from -codegen flag.
@@ -13,7 +17,7 @@
    - Added real/word casts in MLton structure.
 
 * 2007-04-12
-   - Added primitivs for bit cast of word to/from real.
+   - Added primitives for bit cast of word to/from real.
    - Implement PackReal<N>{Big,Little} using PackWord<N>{Big,Little}
      and bit casts.
 
@@ -1299,7 +1303,7 @@
 * 2001-9-21
   - Fixed MLton.World.{load,save} so that the saved world does not store the
     max heap size.  Instead, the max heap size is computed upon load world in
-    exactly the same way as at program startup.  This fixes a long standing (but
+    exactly the same way as at program startup.  This fixes a long-standing (but
     only recently noticed) problem in which mlton (which uses a saved world)
     would attempt to use as much memory as was on the machine used to build
     world.mlton.

Modified: mlton/trunk/mlton/xml/monomorphise.fun
===================================================================
--- mlton/trunk/mlton/xml/monomorphise.fun	2007-07-06 21:27:53 UTC (rev 5730)
+++ mlton/trunk/mlton/xml/monomorphise.fun	2007-07-06 22:19:35 UTC (rev 5731)
@@ -371,13 +371,15 @@
                    fn () =>
                    List.fold
                    (Cache.toList cache, [], fn ((ts, ve), decs) =>
-                    (setTyvars (tyvars, ts)
+                    (setVar (var, fn _ => ve)
                      ; let 
+                          val _ = setTyvars (tyvars, ts)
+                          val ty = monoType ty
                           val {decs = decs', result} = Sexp.dest (monoExp exp)
                        in 
                           decs'
                           @ (Sdec.MonoVal {var = SvarExp.var ve,
-                                           ty = monoType ty,
+                                           ty = ty,
                                            exp = SprimExp.Var result} :: decs)
                        end))
                 end
@@ -398,16 +400,21 @@
                    fn () =>
                    List.revMap
                    (Cache.toList cache, fn (ts, xs) =>
-                    (setTyvars (tyvars, ts)
-                     ; Vector.foreach2 (decs, xs, fn ({var, ...}, var') =>
-                                        setVar (var, fn _ => var'))
+                    (Vector.foreach2 (decs, xs, fn ({var, ...}, ve) =>
+                                      setVar (var, fn _ => ve))
                      ; (Sdec.Fun
                         {tyvars = Vector.new0 (),
                          decs = (Vector.map2
                                  (decs, xs, fn ({ty, lambda, ...}, ve) =>
-                                  {var = SvarExp.var ve,
-                                   ty = monoType ty,
-                                   lambda = monoLambda lambda}))})))
+                                  let
+                                     val _ = setTyvars (tyvars, ts)
+                                     val ty = monoType ty
+                                     val lambda = monoLambda lambda
+                                  in
+                                     {var = SvarExp.var ve,
+                                      ty = ty,
+                                      lambda = lambda}
+                                  end))})))
                 end
            | Xdec.Exception {con, arg} =>
                 let




More information about the MLton-commit mailing list