[polyml] Add -5.5.1-fixes patch to fix two optimizer bugs (trunk commits 1855 and 1867), and to fix TexIO.inp
Jerry James
jjames at fedoraproject.org
Tue Nov 5 17:01:18 UTC 2013
commit 501a0d190d2c969b196065240f9eb8f7761bb181
Author: Jerry James <jamesjer at betterlinux.com>
Date: Tue Nov 5 10:01:19 2013 -0700
Add -5.5.1-fixes patch to fix two optimizer bugs (trunk commits 1855
and 1867), and to fix TexIO.inputN and StreamIO.inputN to return
immediately if asked for zero characters (trunk commit 1874).
polyml-5.5.1-fixes.patch | 171 ++++++++++++++++++++++++++++++++++++++++++++++
polyml.spec | 12 +++-
2 files changed, 181 insertions(+), 2 deletions(-)
---
diff --git a/polyml-5.5.1-fixes.patch b/polyml-5.5.1-fixes.patch
new file mode 100644
index 0000000..76508c2
--- /dev/null
+++ b/polyml-5.5.1-fixes.patch
@@ -0,0 +1,171 @@
+Patches from the upstream polyml-5.5.1-fixes subversion branch. This file
+currently contains the following patches:
+
+------------------------------------------------------------------------
+r1875 | dcjm | 2013-10-30 10:49:05 -0600 (Wed, 30 Oct 2013) | 1 line
+
+Backport commit 1874 from trunk. This fixes TextIO.inputN and StreamIO.inputN so they return immediately if the request is for zero characters.
+------------------------------------------------------------------------
+r1869 | dcjm | 2013-10-11 05:59:58 -0600 (Fri, 11 Oct 2013) | 1 line
+
+Back-port commits 1855 and 1867 from trunk. These fix two optimiser bugs. Includes the regression tests.
+
+Index: polyml/basis/BasicStreamIO.sml
+===================================================================
+--- polyml/basis/BasicStreamIO.sml (revision 1851)
++++ polyml/basis/BasicStreamIO.sml (working copy)
+@@ -213,6 +213,8 @@
+ fun inputN (f, n) =
+ if n < 0
+ then raise Size
++ else if n = 0 (* Defined to return the empty vector and f *)
++ then (emptyVec, f)
+ else
+ let
+ val (vecs, f') = inputNList (f, n)
+Index: polyml/basis/TextIO.sml
+===================================================================
+--- polyml/basis/TextIO.sml (revision 1851)
++++ polyml/basis/TextIO.sml (working copy)
+@@ -597,6 +597,8 @@
+ | inputN' n (ref(Direct(strm as {buffer, bufp, buflimit, ...}))) =
+ if n < 0 orelse n > CharVector.maxLen
+ then raise Size
++ else if n = 0
++ then "" (* Return the empty string without blocking *)
+ else if !buflimit = 0
+ then (* Last read returned end-of-file. Clear the EOF state once
+ we return this empty string. *)
+Index: polyml/mlsource/MLCompiler/CodeTree/CODETREE_OPTIMISER.sml
+===================================================================
+--- polyml/mlsource/MLCompiler/CodeTree/CODETREE_OPTIMISER.sml (revision 1851)
++++ polyml/mlsource/MLCompiler/CodeTree/CODETREE_OPTIMISER.sml (working copy)
+@@ -645,8 +645,9 @@
+ (thisDec :: decs, thisArg @ args, LoadLocal newAddr :: mapList)
+ end
+
+- | mapPattern(ArgPattCurry(currying, ArgPattTuple{allConst=false, filter, ...}) :: patts, n, m) =
+- (* It's a function that returns a tuple. *)
++ | mapPattern(ArgPattCurry(currying as [_], ArgPattTuple{allConst=false, filter, ...}) :: patts, n, m) =
++ (* It's a function that returns a tuple. The function must not be curried because
++ otherwise it returns a function not a tuple. *)
+ let
+ val (thisDec, thisArg, thisMap) =
+ transformFunctionArgument(currying, [LoadArgument m], [LoadArgument n], SOME filter)
+@@ -657,7 +658,7 @@
+
+ | mapPattern(ArgPattCurry(currying as firstArgSet :: _, _) :: patts, n, m) =
+ (* Transform it if it's curried or if there is a tuple in the first arg. *)
+- if List.length currying >= 2 orelse
++ if (*List.length currying >= 2 orelse *) (* This transformation is unsafe. *)
+ List.exists(fn ArgPattTuple{allConst=false, ...} => true | _ => false) firstArgSet
+ then
+ let
+@@ -685,6 +686,13 @@
+
+ and transformFunctionArgument(argumentArgs, loadPack, loadThisArg, filterOpt) =
+ let
++ (* Disable the transformation of curried arguments for the moment.
++ This is unsafe. See Test146. The problem is that this transformation
++ is only safe if the function is applied immediately to all the arguments.
++ However the usage information is propagated so that if the result of
++ the first application is bound to a variable and then that variable is
++ applied it still appears as curried. *)
++ val argumentArgs = [hd argumentArgs]
+ (* We have a function that takes a series of curried argument.
+ Change that so that the function takes a list of arguments. *)
+ val newAddr = ! localCounter before localCounter := ! localCounter + 1
+@@ -1214,9 +1222,11 @@
+ let
+ fun checkArg (ArgPattTuple{allConst=false, ...}) = true
+ (* Function has at least one tupled arg. *)
+- | checkArg (ArgPattCurry(_, ArgPattTuple{allConst=false, ...})) = true
+- (* Function has an arg that is a function that returns a tuple. *)
+- | checkArg (ArgPattCurry(_ :: _ :: _, _)) = true
++ | checkArg (ArgPattCurry([_], ArgPattTuple{allConst=false, ...})) = true
++ (* Function has an arg that is a function that returns a tuple.
++ It must not be curried otherwise it returns a function not a tuple. *)
++ (* This transformation is unsafe. See comment in transformFunctionArgument above. *)
++ (*| checkArg (ArgPattCurry(_ :: _ :: _, _)) = true *)
+ (* Function has an arg that is a curried function. *)
+ | checkArg (ArgPattCurry(firstArgSet :: _, _)) =
+ (* Function has an arg that is a function that
+Index: polyml/Tests/Succeed/Test146.ML
+===================================================================
+--- polyml/Tests/Succeed/Test146.ML (revision 0)
++++ polyml/Tests/Succeed/Test146.ML (revision 1875)
+@@ -0,0 +1,24 @@
++(* Bug in transformation of arguments which are curried functions. It is not
++ safe to transform "f" in the argument to "bar". Although it is curried
++ the application to the first argument "()" is not immediately followed
++ by the application to the second. *)
++
++local
++ val r = ref 0
++in
++ (* Foo should be called exactly once *)
++ fun foo () = (r:= !r+1; fn i => i)
++
++ fun checkOnce () = if !r = 1 then () else raise Fail "bad"
++end;
++
++fun bar f = let val r = f() in (r 1; r 2; List.map r [1, 2, 3]) end;
++
++bar foo;
++
++checkOnce();
++
++exception A and B and C;
++fun rA () = raise A and rB () = raise B;
++fun h (f, g) = let val a = f() in g(); a () end;
++h(rA, rB) handle A => ();
+
+Property changes on: polyml/Tests/Succeed/Test146.ML
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: polyml/Tests/Succeed/Test147.ML
+===================================================================
+--- polyml/Tests/Succeed/Test147.ML (revision 0)
++++ polyml/Tests/Succeed/Test147.ML (revision 1875)
+@@ -0,0 +1,31 @@
++(* Bug in optimiser transformation. A function argument that returns a tuple
++ can be transformed to take a container but only if it is not curried. *)
++
++(* Cut down example from Isabelle that caused an internal error exception. *)
++
++fun one _ [] = raise Fail "bad"
++ | one pred (x :: xs) =
++ if pred x then (x, xs) else raise Fail "bad";
++
++fun foo (scan, f) xs = let val (x, y) = scan xs in (f x, y) end;
++
++fun bar (scan1, scan2) xs =
++ let
++ val (x, ys) = scan1 xs;
++ val (y, zs) = scan2 x ys;
++ in ((x, y), zs) end;
++
++fun bub (scan1, scan2) = foo(bar(scan1, (fn _ => scan2)), op ^);
++
++val qqq: string list -> string * int = bub(one (fn _ => raise Match), (foo((fn _ => raise Match), String.concat)));
++
++(* Further example - This caused a segfault. *)
++
++PolyML.Compiler.maxInlineSize := 1;
++fun f g = let val (x,y) = g 1 2 in x+y end;
++
++fun r (x, y, z) = fn _ => (x, y+z);
++
++val h: int-> int*int = r (4,5,6);
++
++f (fn _ => h);
+
+Property changes on: polyml/Tests/Succeed/Test147.ML
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
diff --git a/polyml.spec b/polyml.spec
index 017ba1f..80577b5 100644
--- a/polyml.spec
+++ b/polyml.spec
@@ -1,16 +1,18 @@
Name: polyml
Version: 5.5.1
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Poly/ML compiler and runtime system
Group: Development/Languages
License: LGPLv2+
URL: http://www.polyml.org
Source0: http://downloads.sourceforge.net/%{name}/%{name}.%{version}.tar.gz
-# 2012-09-20 snapshot of http://www.polyml.org/docs/.
+# 2013-09-17 snapshot of http://www.polyml.org/docs/.
Source1: polyml-docs.tar.xz
# Increase the precision of time information
Patch0: %{name}-5.5.1-time.patch
+# Fixes from the upstream polyml-5.5.1-fixes subversion branch
+Patch1: %{name}-5.5.1-fixes.patch
# The standard solution to kill the libtool-induced RPATH is to edit the
# libtool script to kill it. However, that causes problems for us as we need
@@ -57,6 +59,7 @@ Runtime libraries for Poly/ML.
%setup -q -n polyml.%{version}
%setup -q -T -D -a 1 -n polyml.%{version}
%patch0 -p1
+%patch1 -p1
%build
# Some hand-coded assembler is included. Because it does not contain an
@@ -101,6 +104,11 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%{_libdir}/libpolyml.so.*
%changelog
+* Tue Nov 5 2013 Jerry James <loganjerry at gmail.com> - 5.5.1-2
+- Add -5.5.1-fixes patch to fix two optimizer bugs (trunk commits 1855 and
+ 1867), and to fix TexIO.inputN and StreamIO.inputN to return immediately if
+ asked for zero characters (trunk commit 1874).
+
* Tue Sep 17 2013 Jerry James <loganjerry at gmail.com> - 5.5.1-1
- New upstream version
More information about the scm-commits
mailing list