Number: 1401 Title: Posix.Process.waitpid_nh is buggy. Keywords: waitpid_nj Submitter: Stephen Weeks Date: 6/18/98 Version: 110.0.3 System: x86-linux Severity: medium Problem: The program below (Code: section) causes the error: uncaught exception SysErr: unknown child status I believe the program should terminate. The call to waitpid_nh is raising the exception, but it should return NONE. Code: open Posix.Process val _ = case fork() of NONE => (sleep(Time.fromSeconds 5); exit 0w0) | SOME pid => (waitpid_nh(W_CHILD pid, []); ()) Transcript: Comments: Fix: The problem is in runtime/c-libs/posix-process/waitpid.c. The status buffer should not be checked if WNOHANG was used and the result pid was 0. Test: bug1401.1.sml Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1402 Title: Word.fmt incorrectly uses lowercase letters for hex digits. Keywords: Word.fmt Submitter: Stephen Weeks Date: 6/18/98 Version: 110.0.3 System: x86-linux Severity: Problem: The code: Word.fmt StringCvt.HEX 0wxABCDEF returns: "abcdef" According to the basis library specification http://cm.bell-labs.com/cm/cs/what/smlnj/doc/basis/pages/word.html#SIG:WORD.fmt:VAL, the hexadecimal digits 10-15 are represented as [A-F]. Hence, the correct result is "ABCDEF". Comments: Fix: Test: bug1402.1.sml Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1403 Title: Possible bug is Posix.FileSys.pathconf Keywords: pathconf Submitter: Stephen Weeks Date: 6/21/98 Version: 110.0.3 System: x86-linux Severity: Problem: I am confused by the fact that pathconf returns SOME 0w0 instead of NONE when a property is false. This does not appear to agree with the basis library specification: http://cm.bell-labs.com/cm/cs/what/smlnj/doc/basis/pages/posix-file-sys.html#SIG:POSIX_FILE_SYS.pathconf:VAL For example, on my machine, the following code: Posix.FileSys.pathconf("/bin/ls", "VDISABLE"); returns the following: val it = SOME 0wx0 : Word32.word option I believe that it should return NONE. Comments: Fix: The C code for mkValue in src/runtime/c-libs/posix-filesys/pathconf.c has the following test: if (val >= 0) { Perhaps this should be: if (val > 0) { Test: tests.posix/bug1403.1.sml Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1404 Title: Parser combinator implements bind incorrectly Keywords: SML/NJ library, parser combinators Submitter: Andrew Kennedy Andrew.Kennedy@persimmon.co.uk Date: 06/23/98 Version: 110 System: Any/All Any Unix Subsystem: SML/NJ Library Severity: minor Problem: ParserComb.bind has wrong implementation -- it doesn't eat its input if the parse succeeds. Comments: Obviously the parser combinators haven't been used. Please test them! Fix: Replace p2' t1 getc strm by p2' t1 getc strm1 Test: ? Owner: jhr, erg Status: fixed in 110.8 [jhr, 8/5/98] ---------------------------------------------------------------------- Number: 1405 Title: Posix.TTY discrepancy with Basis Library spec Keywords: Submitter: Stephen Weeks Date: 6/24/98 Version: 110.0.3 System: x86-linux Severity: Problem: According to the Basis Library spec http://cm.bell-labs.com/cm/cs/what/smlnj/doc/basis/pages/posix-tty.html, the following functions should be defined in Posix.TTY.TC getattr setattr sendbreak drain flush flow However, in SML/NJ, they are defined in Posix.TTY Comments: Fix: Test: ? Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1406 Title: STRING does not agree with Basis Library spec Keywords: STRING Submitter: Stephen Weeks Date: 6/25/98 Version: 110.0.3 System: x86-linux Severity: Problem: The Basis Library spec says that the STRING signature should contain a structure specification: structure Char : CHAR The SML/NJ implementation omits this. Comments: [jhr, 6/25/97] This is still an open issue in the design of the basis (including type defs vs substructures). Until this is resolved, we are holding off changes to the SML/NJ signatures. Fix: Test: ? Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1407 Title: ARRAY does not agree with Basis Library spec Keywords: ARRAY Submitter: Stephen Weeks Date: 6/25/98 Version: 110.0.3 System: x86-linux Severity: major Problem: As part of the ARRAY signature, SML/NJ has the value specification: val array0 : 'a array The Basis Library spec does not include this. Comments: Fix: Test: bug1407.1.sml Owner: jhr Status: fixed in 110.0.6 ---------------------------------------------------------------------- Number: 1408 Title: OrdSet.app order doesn't agree with comment Keywords: Submitter: George Russell george@persimmon.com Date: 07/07/98 Version: 110.6 System: Alpha Digital Unix 4.0B Subsystem: Other Severity: cosmetic Problem: IntBinarySet.app appears to apply the function to the elements of the set in INCREASING order. This is what I want, but the relevant bit of ord-set-sig.sml says > val app : (item -> unit) -> set -> unit > (* Apply a function to the entries of the set > * in decreasing order *) Code: IntBinarySet.app (print o Int.toString) (IntBinarySet.addList(IntBinarySet.empty,[1,2,3,4])); Transcript: Standard ML of New Jersey v110.6 [FLINT v1.41], May 21, 1998 [CM; autoload enabled] - IntBinarySet.app(print o Int.toString)(IntBinarySet.addList(IntBinarySet.empty,[1,2,3,4])); [Autoloading...] [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/lib-base-sig.sml.bin... done] [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/lib-base.sml.bin... done] [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/ord-key-sig.sml.bin... done] [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/ord-set-sig.sml.bin... done] [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/int-binary-set.sml.bin...GC #0.0.0.0.1.3: (8 ms) done] [Autoloading done.] 1234val it = () : unit Comments: Fix: Test: bug1408.1.sml Owner: jhr, erg Status: open ---------------------------------------------------------------------- Number: 1409 Title: Swaps reals in a structure or tuple Keywords: reals modules tuples Submitter: Elsa L. Gunter elsa@research.bell-labs.com Date: 07/13/98 Version: 110.7 System: x86 Linux 2.0 and after Subsystem: SML compiler Severity: critical Problem: If you create a functor that creates at least 7 real values, and you apply the functor to get a structure, and you rebind those values, two of the values will get swapped (see code). Additional information: You seem to need at leat 7 real values for this problem to occur. It is also important that they first be generated inside a functor. It is seems necesary that the rebinding is taking place in a function that has at least two cases to it, and that the argument to the function is itself generated by a function application. In the code, the tuple at the end paira calculated values with what they should be. Code: functor T () = struct val g = 1.0 val f = 2.0 val m = 3.0 val p = 4.0 val q = 5.0 val u = 6.0 val h = 7.0 end; structure E = struct datatype t = A | B fun b _ = B val s = b() structure C = T () val {g,f,m,h,p,q,u} = case s of A => {g = C.g, f = C.f, m = C.m, h = C.h, p = C.p, q = C.q, u = C.u} | _ => {g = C.g, f = C.f, m = C.m, h = C.h, p = C.p, q = C.q, u = C.u} end; val test = ((E.g , 1.0),(E.f , 2.0),(E.m , 3.0),(E.p ,4.0),(E.q , 5.0),(E.u , 6.0), (E.h , 7.0 )) Transcript: tiree% /home/sml/Versions/110.7/bin/sml Standard ML of New Jersey v110.7 [FLINT v1.41], June 2, 1998 val use = fn : string -> unit - use "pay.sml"; [opening pay.sml] functor T : structure E : sig structure C : datatype t = A | B val b : 'a -> t val f : real val g : real val h : real val m : real val p : real val q : real val s : t val u : real end val test = ((1.0,1.0),(2.0,2.0),(3.0,3.0),(4.0,4.0),(6.0,5.0),(5.0,6.0),(7.0,7.0)) : (real * real) * (real * real) * (real * real) * (real * real) * (real * real) * (real * real) * (real * real) val it = () : unit Comments: Fix: [Zhong, 7/13/98] It is caused by the usual misuse of "foldr" (instead of "foldl") in one of my argument spilling algorithms. The fix of Elsa's bug involves changes to the file named "FLINT/cps/cpstrans.sml" (attached) in 110.7. Test: bug1409.1.sml Owner: Zhong Status: fixed in 110.7.2 [Zhong, 7/13/98] ---------------------------------------------------------------------- Number: 1410 Title: no comments in %header Keywords: %header comments Submitter: Elsa L. Gunter elsa@research.bell-labs.com Date: 07/13/98 Version: 110.0.3 System: Any/All Any Unix Subsystem: ML-Yacc Severity: minor Problem: Comments in the argument to %header in the input .grm file to ml-yacc are not correctly parsed. In fact, they cause a false error to be generated. Code: %% %term ident of string | EOF %nonterm START of lambda_term %eop EOF %pos int %header (functor L()(* test *)) %% START : ident (ident) Transcript: tiree% ml-yacc lam.grm lam.grm, line 6: Error: syntax error: deleting PERCENT_HEADER BOGUS_VALUE UNKNOWN ? ml-yacc: uncaught exception Semantic Comments: I originally encountered this bug because it occurs in the file yacc.grm in the code for ml-yacc. I will probably fix it myself eventually if nobody else gets there first. Fix: Test: Owner: Andrew Status: open ---------------------------------------------------------------------- Number: 1411 Title: bad type checking of lazy fun declaration Keywords: lazy, type checking Submitter: Philip Wadler Date: 7/8/98 Version: 110.7.1 System: - Severity: major Problem: An incorrect type is inferred for a lazy fun declaration Code: Compiler.Control.lazysml := true; datatype lazy 'a stream = Nil | Cons of 'a * 'a stream; fun lazy map f Nil = Nil | map f (Cons(x,xs)) = Cons(f x, map f xs); Transcript: datatype 'a stream = Cons of 'a * 'a stream ?.susp | Nil type 'a stream = 'a ?.stream ?.susp stdIn:10.3-11.47 Warning: match nonexhaustive stdIn:10.3-11.47 Warning: match nonexhaustive (f,$ Nil) => ... val map = fn : 'a -> 'b ?.stream ?.susp -> 'c ?.stream ?.susp Comments: Fix: In elaborate/elabcore.sml, only the first clause of the map_ function was being processed, because a recursive function wasn't recursing on the rest of the clauses. Test: tests.lazy/bug1411.1.sml Owner: dbm Status: fixed in 110.7.2 ---------------------------------------------------------------------- Number: 1412 Title: lazy datatype spec expands to duplicate type specs Keywords: lazy, datatype specs, signatures Submitter: Philip Wadler Date: 7/9/98 Version: 110.7.1 System: - Severity: major Problem: Because the strict and lazy type names generated by a lazy datatype specifications are the same, signature elaboration complains about duplicate specifications. Code: signature STREAM = sig datatype lazy stream = Nil | Cons of string * stream end; structure Stream : STREAM = struct datatype lazy stream = Nil | Cons of string * stream end; Transcript: - use "bug1412.1.sml"; [opening bug1412.1.sml] GC #0.0.0.0.1.6: (3 ms) bug1412.1.sml:5.3-7.31 Error: duplicate specifications for type constructor stream in signature Comments: (Andrew being too clever!) Fix: make the internal (strict) datatype name distinct from the external suspended version (e.g. stream! and stream, respectively), as in Wadler's original expansion. This affects compiler/Semant/elaborate/elabtype.sml in the function elabDATATYPEdec. Test: tests.lazy/bug1412.1.sml Owner: dbm Status: fixed in 110.7.2 [dbm, 7/22/98] ---------------------------------------------------------------------- Number: 1413 Title: can't read from instream from process created by Unix.execute Keywords: Unix.exectute, TextIO, IO, processes Submitter: Elsa Gunter Date: 7/20/97 Version: 110.0.3, 110.7 System: mipseb-irix6.2, sparc-solaris2.5, x86-linux Severity: major Problem: A process is created using Unix.execute, and output is sent to that process, flushed, and the output stream is closed. When input from the process is read it contains (part of) a "Bad file number" error message. Code: val execute = Unix.streamsOf o Unix.execute; val (instrm,outstrm) = execute("cat",[]); TextIO.output(outstrm,"abcd"); TextIO.flushOut outstrm; TextIO.closeOut outstrm; val s = TextIO.inputAll instrm; Transcript: - val execute = Unix.streamsOf o Unix.execute; val execute = fn : string * string list -> TextIO.instream * TextIO.outstream - val (instrm,outstrm) = execute("cat",[]); val instrm = - : TextIO.instream val outstrm = - : TextIO.outstream - TextIO.output(outstrm,"abcd"); val it = () : unit - TextIO.flushOut outstrm; val it = () : unit - TextIO.closeOut outstrm; val it = () : unit - val s = TextIO.inputAll instrm; val s = "\nuncaught exception SysErr: Bad file number [badf]\n raised at: Date: 7/21/98 Version: 110.7 (not 110.0.3?) System: - Severity: major Problem: Instantiating a signature containing a sharing constraint causes "Compiler bug: Instantiate: unexpected DATATYPE 354" Code: signature SIG1 = sig type t type u datatype c = C of u and d = D of t * c (* needed! *) end; signature SIG2 = sig type s = int (* <------ that is the culprit I think *) end; signature SIG3 = sig structure A : SIG1 structure B : SIG2 sharing type B.s = A.c (* not valid *) end; Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 - use "test/bugs/bug1414.1.sml"; [opening test/bugs/bug1414.1.sml] signature SIG1 = sig type t type u datatype c = C of u datatype d = D of t * c end signature SIG2 = sig type s = int end Error: Compiler bug: Instantiate: unexpected DATATYPE 354 Comments: [dbm] The sharing should be rejected, because int can't share with a datatype, but a sensible error message should be generated instead of a compiler bug. It may be that 110.0.3 accepts this code without an error because instantiation is not turned on for signature declarations. [Michael Siff, 7/21/98] But actually, my original code (not as simple) was like: signature SIG2 sig structure A : ORD_KEY type s = A.ord_key end and this too resulted in bug 1414. I have since corrected it to be: signature SIG2 sig structure A : ORD_KEY type s sharing type s = A.ord_key end Fix: Test: bug1414.1.sml, bug1414.2.sml Owner: dbm, Zhong Status: fixed in 110.9 (dbm) ---------------------------------------------------------------------- Number: 1415 Title: Date.fmt raises Date on large strings Keywords: Date.fmt Submitter: Stephen Weeks Date: 8/6/98 Version: 110.7 System: x86-linux Severity: Problem: Date.fmt raises Date when you pass it a format string of length 512 or greater, as demonstrated by the following program. Code: Date.fmt (implode(List.tabulate(512, fn _ => #" "))) (Date.fromTimeLocal(Time.now())); Transcript: uncaught exception Date raised at: boot/date.sml:60.41-60.45 Comments: Fix: runtime/c-libs/smlnj-date/strftime.c should allocate a larger buffer when the call to strftime returns 0. [jhr] Upon further examination, I think that this should be fixed in SML. We can break the format string apart and feed it to strftime a piece at a time. Once we have all of the results, then we can concatenate the final result. This avoids the potential problem of stressing the C memory allocator in pathalogical cases. [Weeks, 8/6/98] I agree that this works, but you'll have to be pretty conservative on the chunk size, or make a pass over the format string to get an upper bound on the size of the result string. [jhr, 8/6/98] We need to make a pass over the format string anyway to check for illegal format options (we cannot rely on strftime to do this). This is something that our implementation does not do yet, but it should. Test: bug1415.1.sml Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1416 Title: Date.fmt produces incorrect results on %j, %U, %W, and % Keywords: Date.fmt Submitter: Stephen Weeks Date: 8/6/98 Version: 110.7 System: x86-linux Severity: Problem: Date.fmt produces incorrect results for format directives that depend on tm_yday, i.e. %j, %U, and %W. It also does not follow the spec for format directives that are undefined, e.g. %z. Code: Date.fmt("%j %U %W %z") (Date.fromTimeLocal(Time.now())) Transcript: val it = "001 00 00 " : string Comments: Fix: In PervEnv/Basis/date.sml toTM should return the appropriate value for tm_yday, not 0. Test: bug1416.1.sml Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1417 Title: problems with datatype replication in functors Keywords: modules, datatype replication Submitter: Chris Paris Date: 8/14/98 Version: 110 System: sparc-solaris2.5 (untested on others) Severity: life threatening! Problem: Datatype replication involving mutually recursive datatypes sometimes fails. Code: (* bug1417.1.sml *) signature DB = sig type foo = int datatype partition_classes = STATIC_CLASSES of foo and alloc_class = ALLOC_CLASS of unit end; functor Evolve(Db : DB) = struct datatype partition_classes = datatype Db.partition_classes end; (* bug1417.2.sml *) signature DB = sig datatype transaction = TRANSACTION of lockinfo and lockinfo = READLOCK of unit end functor Evolve(Db : DB) : DB = struct datatype lockinfo = datatype Db.lockinfo datatype transaction = datatype Db.transaction end; Another example from Leif Kornstaedt (7/5/99): (* bug1417.3.sml *) signature S = sig type t datatype u = C1 and v = C2 of t end functor F(type t) :> S where type t = t = struct type t = t datatype u = C1 and v = C2 of t end structure M1 = F(type t = int) structure M2 = struct datatype v = datatype M1.v end Transcript: Standard ML of New Jersey, Version 110, December 9, 1997 [CM; autoload enabled] - use "bug1417.1.sml"; [opening bug1417.1.sml] Error: Compiler bug: TypesUtil: expandTyc:PATHtyc - use "bug1417.2.sml"; [opening bug1417.2.sml] bug1417.2.sml:7.13-11.8 Error: value type in structure doesn't match signature spec name: TRANSACTION spec: Db.lockinfo -> Db.transaction actual: ?.lockinfo -> Db.transaction Comments: Works in 110.7 and 110.8. However, it is not practical for me to port from 110 to the current bleeding edge. Fix: Test: bug1417.1.sml, bug1417.2.sml Owner: dbm, Zhong Status: fixed in 110.8, open in 110.0.4 ---------------------------------------------------------------------- Number: 1418 Title: CM.set_path is a constant function Keywords: CM, CMPATH, CM.set_path Submitter: Elsa Gunter Date: 8/13/98 Version: 110.0.8 (110.0.3?) System: - Severity: major Problem: CM.set_path always returns nil, even after a path has been set. Transcript: - CM.set_path NONE; val it = [] : string list - CM.set_path (SOME ["/home/sml/Versions/110.8/lib"]); val it = [] : string list - CM.set_path NONE; val it = [] : string list Comments: Fix: (Matthias verify?) In cm/cm.sml change the definition of set_path to: fun set_path arg = (if isSome arg then EntityDesc.clear () else (); map AbsPath.elab (CmConfig.path (Option.map (List.map AbsPath.rigidcur) arg))) Test: tests.cm/bug1418.1.sml Owner: Blume Status: fixed in 110.9 (Blume) ---------------------------------------------------------------------- Number: 1419 Title: incorrect printing of signature containing "where type" Keywords: signatures, where type, printing Submitter: Dave MacQueen Date: 8/17/98 Version: 110.0.3, 110.8 System: - Severity: minor Problem: When a signature including a where type specification is printed it can appear as though free variable capture has occurred, even though it hasn't. Code: signature S = sig type s type t end; signature S1 = sig type s structure A : S where type t = s end; Transcript: - signature S = sig type s type t end; signature S = sig type s type t end - signature S1 = = sig = type s = structure A : S where type t = s = end; signature S1 = sig type s structure A : sig type s type t = s (* this refers to the outer s! *) end end Comments: This is a result of the way where types are elaborated. The type definition is moved inward to the site of the type specification that it applies to, but after the rhs has been elaborated, so there is no danger of free variable capture. But when printed, the transformed signature looks like free variable capture has happened. Fix: Test: bug1419.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1420 Title: improper printing of "multiple defs at tycon spec" warning message Keywords: error messages, printing Submitter: Dave MacQueen Date: 8/17/98 Version: 110.8 System: - Severity: medium Problem: An "" is printed for the path of a tycon spec in the "multiple defs at tycon spec" warning message. Code: Transcript: - use "test/bugs/bug1386.1.sml"; [opening test/bugs/bug1386.1.sml] signature CAT = sig eqtype cat val c : cat end signature L_F = sig eqtype t structure Cat : sig type cat = t val c : cat end val r : t end test/bugs/bug1386.1.sml:17.9-22.4 Warning: multiple defs at tycon spec: (secondary definitions ignored) test/bugs/bug1386.1.sml:21.13-21.27 Error: operator and operand don't agree [tycon mismatch] operator domain: ?.cat * ?.cat operand: ?.cat * ?.t in expression: Cat.c = LF.r Comments: Fix: Test: bug1420.1.sml (derived from bug1386.1.sml) Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1421 Title: incorrect type comparison for val spec in signature match Keywords: signature matching Submitter: Norman Ramsey Date: 8/18/98 Version: 110.0.3, 110.8 System: - Severity: major Problem: The following declarations are rejected, but should not be. Code: signature E = sig type 'a err val OK : 'a -> 'a err val map : ('a -> 'b) -> 'a err -> 'b err end; structure E1 : E = struct type 'a err = 'a fun OK x = x fun map1 f = f val map = map1 (* causes an error ... *) end; Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 - use "test/bugs/bug1421.1.sml"; [opening test/bugs/bug1421.1.sml] signature E = sig type 'a err val OK : 'a -> 'a err val map : ('a -> 'b) -> 'a err -> 'b err end test/bugs/bug1421.1.sml:9.1-14.4 Error: value type in structure doesn't match signature spec name: map spec: ('a -> 'b) -> 'a ?.E1.err -> 'b ?.E1.err actual: 'a -> 'a Comments: Fix: In typesutil.sml, function equalType, add "IBOUND _" in addition to "VARty _" patterns for fourth and fifth clauses of function eq. Test: bug1421.1.sml Owner: Zhong Status: fixed in 110.9, 110.0.4 [Zhong, 8/18/98] ---------------------------------------------------------------------- Number: 1422 Title: Core dump on Sparc when using lazy features Keywords: lazy, sparc Submitter: Matthias Blume blume@kurims.kyoto-u.ac.jp Date: 08/18/98 Version: 110.8 System: Sparc Solaris SunOS helium 5.6 Generic_105181-04 sun4u sparc SUNW,Ultra-1 Subsystem: SML compiler Severity: critical Problem: The following code crashes version 110.8 with a core dump on the Sparc (Solaris on Ultra-1). The same code does NOT crash on x86 (Linux). Could this be related to bug 1389? If so, this would mean that the problem is probably NOT in the code generator since we are using a brand-new one... A problem in the runtime system/GC perhaps? Code: Compiler.Control.lazysml := true; datatype lazy l = Nil | Cons of int * l; fun fst _ Nil = [] | fst 0 _ = [] | fst n (Cons (x, l)) = x :: fst (n - 1) l; val rec lazy ones = Cons (1, ones); fst 10 ones; Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 - Compiler.Control.lazysml := true; val it = () : unit - datatype lazy l = Nil | Cons of int * l; datatype l! = Cons of int * l! ?.susp | Nil type l = l! ?.susp - fun fst _ Nil = [] = | fst 0 _ = [] = | fst n (Cons (x, l)) = x :: fst (n - 1) l; val fst = fn : int -> l -> int list - val rec lazy ones = Cons (1, ones); GC #0.0.0.0.1.7: (10 ms) val ones = $$ : l! ?.susp - fst 10 ones; Bus error Comments: The same code runs fine on the X86 (Pentium notebook running Linux): [blume@hana blume]$ ML/8/bin/sml Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - Compiler.Control.lazysml := true; val it = () : unit - datatype lazy l = Nil | Cons of int * l; datatype l! = Cons of int * l! ?.susp | Nil type l = l! ?.susp - fun fst _ Nil = [] = | fst 0 _ = [] = | fst n (Cons (x, l)) = x :: fst (n - 1) l; val fst = fn : int -> l -> int list - val rec lazy ones = Cons (1, ones); GC #0.0.0.0.1.19: (10 ms) val ones = $$ : l! ?.susp - fst 10 ones; val it = [1,1,1,1,1,1,1,1,1,1] : int list [Matthias, 8/28/98] > [Lal] I have not been able to find the bug exhibited by the lazy evaluation > program you sent. It is clear that it is not specific to the sparc but > generic to MLRISC. > > I therefore suspected the implementation of mkspecial, getspecial, and > setspecial -- but they all seem to be correct. Well, maybe they aren't correct after all. I now recall an incident that occured a while ago: CM crashed on me (with a bus error), and I was able to resolve that problem (although it was never explained) by eliminating the use of the built-in "suspension" facility (delay/force). The problem occured on the Alpha, which at that time was one of the few MLRISC-based implementations. Since I assume that the implementation technology for delay/force back then and laziness now is the same, I would really suggest we should look into this again. (Back when the problem occured first, someone more or less dismissed it as unimportant and surely not to be blamed on get/set/mkspecial. I didn't pursue the issue any further because it didn't seem mission-critical at the time.) Fix: [Lal] I have committed a change to CodeGen/main/mlriscGen.sml that fixes bug1422. Test: bug1422.1.sml Owner: Leung, Lal? Status: fixed in 110.8.1 [Lal] ---------------------------------------------------------------------- Number: 1423 Title: 2.0 + 2.0 = nan Keywords: reals Submitter: George Russell george@persimmon.com Date: 08/10/98 Version: 110.8 System: Sparc Solaris uname -a returns SunOS rosalind 5.5.1 Generic_103640-18 sun4m sparc SUNW,... Subsystem: SML compiler Severity: critical Problem: Floating point doesn't work! Code: 2.0 + 2.0; Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - 2.0 + 2.0; val it = nan : real Comments: [Alan] Unfortunately, we are unable to reproduce on this end. [George] That's odd. Are you sure you've tried it on Sparc/Solaris? I was wondering whether this new ML-RISC was to blame. [Alan] Yes, it's odd. I've tried to repro it on various sparc/solaris/sun-os combinations with no luck: SunOS valis 5.6 Generic_105181-06 sun4m sparc SUNW,SPARCstation-5 SunOS optlab2 5.5.1 Generic_103640-08 sun4u sparc SUNW,Ultra-1 SunOS merv 4.1.4 2 sun4m SunOS vex 5.5.1 Generic_103640-18 sun4u sparc SUNW,Ultra-2 The new MLRISC is likely to be the culprit. [Alan] Could you also check to see if Real.==(2.0+2.0, 4.0) returns true? [George] It returns false [Alan] That's very strange. Could you send me the dumps for the following? val a = 2.0 val b = 2.0 + 2.0 val c = Real.toManExp a val d = Real.toManExp b val e = Real.toManExp Real.posInf val f = Real.==(1.0/0.0,Real.posInf) val g = Real.==(2.0+2.0,Real.posInf) and Compiler.Control.CG.printFlowgraph := Compiler.Control.CG.AFTER_RA; 2.0 + 2.0; [Lal] Only occurs on older sparcs. Fix: Test: bug1423.1.sml Owner: Alan Leung Status: fixed in 110.8.1 [Leung, Lal] ---------------------------------------------------------------------- Number: 1424 Title: inadaquate signature matching error message Keywords: Submitter: Date: Version: System: Severity: Problem: Bad signature matching error message. Does not specify which type names did not match. Transcript: ../MLRISC/X86/X86RegAlloc.sml:1.9-80.4 Error: type name does not match definitional specification ../MLRISC/X86/X86RegAlloc.sml:1.9-80.4 Error: type name does not match definitional specification Comments: Fix: Test: ? Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1425 Title: Compiler bug: Literals: unexpected CPS header in litsplit Keywords: code generation, floating point Submitter: John Reppy Date: 5/21/98 Version: 110.5.1 System: ? Severity: major Problem: real division causes compiler bug Code: Transcript: - 1.1-1.0; val it = 0.1 : real - it/2.0; Error: Compiler bug: Literals: unexpected CPS header in litsplit Comments: Fix: Test: bug1425.1.sml Owner: Zhong Status: fixed in 110.6 ---------------------------------------------------------------------- Number: 1426 Title: smlnj-c interface function, second call core dumps Keywords: smlnj-c, foreign function call Submitter: "Karsten Lueth" Date: 7/28/98 Version: 110.0.3 System: sparc/solaris Severity: major Problem: I have some problems with C interface of SML.110. When I try to call a ML function from C, it will only work at the first call. When call the same function for a second time, it will crash with a segmentaton fault. Code: The C function: void x(int (*f)()) { int i; i = f(); i = f(); } The ML registration: val x = registerCFn("x", [CfunctionT([],CintT)], CvoidT); Transcript: Comments: Fix: Riccardo fixed the bug which had to do with gc. Test: - Owner: Riccardo, jhr Status: fixed in 110.8.1 [Riccardo] ---------------------------------------------------------------------- Number: 1427 Title: End-of-file marks in Stream IO Keywords: IO Submitter: Andrew Appel Date: 08/17/98 Version: 110.8 System: Any/All Any Unix Subsystem: SML basis library Severity: minor Problem: When buffered input is done from a stream device (pipe, tty, socket), there can be multiple end-of-file marks (i.e., zero-length inputs). This is only partially reflected in functional stream input. The program below demonstrates, when the following sequence is typed into the interactive standard input: "abcdef\n^D^Dabcde\n" The sequence of inputs should be, "abcdef\n", "", "", "abcde\n", and indeed the first time through this is the case. But the second time the same functional input stream is read, the sequence is "abcdef\n", "abcde\n"; the empty strings are lost. This violates the rule that for any TextIO.StreamIO.instream f, input(f) = input(f) Code: structure TS = TextIO.StreamIO fun test f = let val f0 = TextIO.getInstream f fun g(i,0) = () | g(i,k) = let val (s,i') = TS.input i in print (Int.toString (size s) ^ "\n"); g(i',k-1) end in g(f0,4); print "***\n"; g(f0,4) end Transcript: 7 0 0 6 *** 7 6 Comments: Fix this in bin-io-fn.sml and text-io-fn.sml by having an explicit end-of-file mark in the sequence of buffers. Fix: Test: Owner: jhr? Status: fixed in 110.9.1 ---------------------------------------------------------------------- Number: 1428 Title: CM docs out of date Keywords: Tools.stdShellProcessor Submitter: Norman Ramsey Date: 08/18/98 Version: 110.8 System: Any/All Any Unix Subsystem: Compilation manager (CM) Severity: minor Problem: Tools.stdShellProcessor appears to have a new type which is not reflected in the example on page 23 of the manual: lex+source.nw:9.2-10.69 Error: operator and operand don't agree [tycon mismatch] operator domain: {mkCommand:unit -> string, tool:string} operand: {command:string, tool:string} in expression: Tools.stdShellProcessor {command=command,tool="ML-Lex+"} Code: functor LexSourceFun (structure Tools: CMTOOLS val command: string) = struct local val runlex = Tools.stdShellProcessor { command = command, tool = "ML-Lex+" } fun rule source = let val smlfile = source ^ ".sml" in [(smlfile, SOME "sml")] end val validator = Tools.stdTStampValidator val processor = runlex (* install MlLex class *) open Tools val class = "mllex+" fun sfx s = addClassifier (stdSfxClassifier { sfx = s, class = class }) in val _ = addToolClass { class = class, rule = dontcare rule, validator = validator, processor = processor } val _ = sfx "lex+" val _ = sfx "l+" end end Transcript: [opening lex+source.sml] lex+source.nw:9.2-10.69 Error: operator and operand don't agree [tycon mismatch] operator domain: {mkCommand:unit -> string, tool:string} operand: {command:string, tool:string} in expression: Tools.stdShellProcessor {command=command,tool="ML-Lex+"} Comments: Fix: update the documentation Test: Owner: Blume Status: fixed in 110.8.2 (Blume) ---------------------------------------------------------------------- Number: 1429 Title: two problems with StreamIO.setPosOut Keywords: I/O, StreamIO, setPosOut Submitter: Andrew Appel Date: 8/19/98 Version: 110.8 System: - Severity: medium Problem: In reading text-io-fn.sml (StreamIO.setPosOut) I noticed two minor bugs: 1. setPosOut should flush the buffer before changing position 2. setPosOut raises an exception whose string refers to "getPosOut" Comments: Fix: Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1430 Title: heap2exec broken Keywords: heap2exec, executables Submitter: Carlos Puchol Date: 8/20/98 Version: System: Severity: Problem: it seems like heap2exec is not bundling things right. Transcript: $ /usr/local/sml/110/bin/sml +@SMLload=tl2strl.heap.sparc-solaris Usage: tl2strl [-v] [-cr] [-ch] [-h] $ /usr/local/sml/110/bin/heap2exec +/usr/local/sml/110/runtime-standalone/run.sparc-solaris +tl2strl.heap.sparc-solaris tl2strl bundling /usr/local/sml/110/runtime-standalone/run.sparc-solaris bundling tl2strl.heap.sparc-solaris setting heap offset to 167556. done. $ ./tl2strl ./tl2strl: Fatal error -- unable to open heap image "sml-image" Comments: Fix: Test: Owner: Lorenz Status: open ---------------------------------------------------------------------- Number: 1431 Title: yypos in ml-lex is off by one (or two) Keywords: ml-lex Submitter: John Reppy Submitter: George Russell Date: 08/22/98, 9/8/98 Version: 110.0.3 System: Any/All Any Unix Subsystem: ML-Lex Severity: major Problem: The first character in the input stream is being assigned position 2. It probably should get the value 0, since this would correspond with standard indexing conventions for ML, but a value of 1 would also be okay --- 2 seems like a bug. Code: (ML-Lex file test.lex follows) type lexresult=int val error=TextIO.print fun eof _ = ~1 %% %% . => (print("yypos="^Int.toString yypos);Char.ord(String.sub(yytext,0))); Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - use "test.lex.sml"; [opening test.lex.sml] GC #0.0.0.0.1.7: (14 ms) GC #0.0.0.0.2.27: (21 ms) GC #0.0.0.1.3.46: (34 ms) structure Mlex : sig structure Internal : structure UserDeclarations : exception LexError val makeLexer : (int -> string) -> unit -> Internal.result end val it = () : unit - Mlex.makeLexer(fn i=>TextIO.inputN(TextIO.stdIn,i))(); a yypos=2val it = 97 : Mlex.Internal.result Comments: [jhr] This is an annoying bug (I spent half a day discovering it just a couple of weeks ago). Andrew Appel claims that it has been known for some time, but there was a concern that if it was fixed, then the fix might break people's code that depended on the incorrect behavior. Personally, I'd like to see it fixed, but at least we should document it. Fix: Test: - Owner: Andrew? Status: open ---------------------------------------------------------------------- Number: 1432 Title: signature match fails for datatype specs if "where type" is used Keywords: signatures, datatypes, "where" clause Submitter: Matthias Blume Date: 08/31/98 Version: 110.8.1 System: Any/All Any Unix Subsystem: SML compiler Severity: major Problem: Information about a type being a datatype is lost when the type spec was augmented using a "where type" clause. This is true even if left and right side of the equation in the "where" clause are already known to be datatypes. This problem is new in 110.8.1. It did not occur in 110.8. (The problem occurs within the CML sources.) Code: signature S1 = sig datatype dt = DT end; signature S2 = sig structure nestedS1 : S1 end; structure globalS1 = struct datatype dt = DT end; functor F2 ( structure argS : S2 where type nestedS1.dt = globalS1.dt ) = struct structure myS1 : S1 = argS.nestedS1 end; Transcript: - use "t.sml"; [opening t.sml] t.sml:18.5-18.40 Error: type dt must be a datatype Comments: In the source code given above, if you delete the "where type" clause on line 15, then everything elaborates fine. [Matthias (original message)] I tried to locally fix the CML sources to be able to compile them under 110.8.1. But I run into a strange problem. When compiling src/cml/src/IO/text-io-fn.sml I see the following errors: ... [compiling IO/text-io-fn.sml -> IO/CM/sparc-unix/text-io-fn.sml.bin] IO/text-io-fn.sml:880.24-883.31 Error: type reader must be a datatype IO/text-io-fn.sml:880.24-883.31 Error: type writer must be a datatype This message refers to the instantiation of the ChanIO functor. Apparently, somehow the compiler seems to think that the reader/writer types in PIO aren't datatypes. Why is that? If they really aren't, then I can't seem to understand the structure of the sources. But if they are, then why does the compiler think they aren't? Is this somehow related to Dave's fix of bug 1364? Does the fix need another fix? Fix: Added "repl:bool" field to TYCspec argument to indicate when a spec is a datatype replication spec (either directly or indirectly via a "where type" definition that applies to the spec). The repl field is definied in ElabSig (Semant/elaborate/elabsig.sml). The information is used in Instantiate, where the type instances associated with a repl spec are unwrapped (in function fixUpTycEnt). This will make checkTycBinding in SigMatch work properly when matching a datatype spec against a type created by signature instantiation (as in the example above). Test: bug1432.1.sml, ..., bug1432.8.sml Owner: dbm Status: fixed in 110.9 (110.8.2) and 110.0.4 [dbm, 9/14/98] ---------------------------------------------------------------------- Number: 1433 Title: eqtype u=t doesn't force eqtype. Keywords: modules Submitter: George Russell george@persimmon.co.uk Date: 08/28/98 Version: 110.8 System: Alpha Digital Unix 4.0B Subsystem: SML compiler Severity: minor Problem: eqtype t=u seems to be an SML/NJ extension so it is not defined how it should work, but in my opinion this code should typecheck. Code: structure A :> sig type t eqtype u=t val v: u end= struct type t=int type u=int val v=1 end; (A.v=A.v); Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - structure A:>sig type t eqtype u=t val v:u end = = struct type t=int type u=int val v=1 end; structure A : sig type t type u = t val v : u end - (A.v=A.v); stdIn:8.1-8.10 Error: operator and operand don't agree [equality type required] operator domain: ''Z * ''Z operand: A.u * A.u in expression: A.v = A.v Comments: See bug 1152 (which appears to be related but which was fixed). [dbm, 9/10/98] Thanks for the bug report, which is now bug 1433. There is certainly something bogus here, since A.t is abstract (and therefore not an equality type), while A.u is specified to be an equality type and is equal to A.t. Probably there should be an error when the signature constraint is matched in the declaration of A. You are right that the "eqtype u = t" is not supported in the SML '97 Definition, but I believe that one can construct an equivalent situation with "where type": signature S = sig type t structure X : sig eqtype u end where type u = t val v : X.u end; This signature should not elaborate successfully according to rule (64), but it currently does elaborate in SML/NJ 110.0.3 through 110.8. Fix: Partial fix, for direct eqtype definitional specs: Added an error check to elabTYPEspec in elabsig.sml to generate an error message when an eqtype spec includes a definition. This still leaves open the problem of what to do when a definition is applied to an eqtype spec through a where type defn. It is rather difficult to fix the "where type" version. The problem is that when the rhs of the where type def (here "t") is elaborated by elabType within ElabSig, the type constructed contains the relatized (PATHtyc) version of T, and it is not possible to determine the equality property of PATHtycs. Perhaps this could be dealt with by adding an equality property field to PATHtycs. Test: bug1433.1.sml, bug1433.2.sml Owner: dbm Status: open (partially fixed in 110.9) ---------------------------------------------------------------------- Number: 1434 Title: bogus "Error: non-constructor applied to argument in pattern: ::" Keywords: types patterns list infix Submitter: Elsa L. Gunter elsa@research.bell-labs.com Date: 09/01/98 Version: 110.8 System: x86 Linux 2.0.0 Subsystem: SML compiler Severity: minor Problem: When a non-existant structure is opened within another structure, subsequent occurrences of :: in patterns fail to be treated as constructors and raise a bogus "Error: non-constructor applied to argument in pattern: ::" message. Code: structure A = struct open B val (x::y) = [1,2] end; Transcript: coll% sml Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - use "test.sml"; [opening test.sml] test.sml:3.1-3.7 Error: unbound structure: B test.sml:4.5-4.29 Error: non-constructor applied to argument in pattern: :: - structure A = struct open B val (x::y) = [1,2] end; = = = = stdIn:8.1-8.7 Error: unbound structure: B stdIn:9.5-9.19 Error: non-constructor applied to argument in pattern: :: Comments: Fix: Test: bug1434.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1435 Title: ML-Yacc documentation needs to be updated Keywords: ml-yacc, documentation Submitter: John Reppy Date: 8/19/08 Version: 110.0.3 - 110.8 System: - Severity: major Problem: The ML-Yacc documentation ought to be updated to reflect the use of CM (e.g., section 5 currently talks about loading "base.sml"). Comments: Fix: Test: - Owner: Andrew? Status: open ---------------------------------------------------------------------- Number: 1436 Title: representation exception raised by C function Keywords: pretty printing, Representation exception, C interface Submitter: ammons@cs.wisc.edu Date: 9/4/1998 Version: 110.0.3 System: sparc-solaris2.6, x86-linux2.0.30 Severity: major Problem: The pretty printer throws an exception while pretty printing some values massaged from values returned by interfaced C code. Code: C side. Add this line to cfun-list.h: C_CALLS_CFUNC("test", test, void *, (void)) and define test as void* test(void) { return (void*) test; } Create a new runtime. ML side. Register the test function. Unwrap the returned caddr and wrap it back up with a new datatype, as in the following transcript: Transcript: whitelight:objs$ sml @SMLrun=./run.x86-linux Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - CM.make'("/usr/local/smlnj-110/install/smlnj-c/sources.cm"); [starting dependency analysis] [scanning /usr/local/smlnj-110/install/smlnj-c/sources.cm] [checking /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/sources.cm.stable ... not usable] GC #0.0.0.0.1.4: (20 ms) [dependency analysis completed] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/c-calls.sig.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cutil.sig.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cutil.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.sig.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.defaults.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.gcc-x86-linux.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.gcc-sparc-sunos.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.cc-mipseb-irix5.sml.bin... done] [recovering /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/c-calls.sml.bin... done] [introducing new bindings into toplevel environment...] val it = () : unit - structure C = CCalls(structure CCInfo = GCCInfoX86Linux); structure C : C_CALLS - datatype mud = Mud of C.caddr; datatype mud = Mud of ?.C.CAddress.caddr - fun make_mud(C.Caddr a) = Mud a; stdIn:20.1-20.32 Warning: match nonexhaustive Caddr a => ... val make_mud = fn : C.cdata -> mud - val f_test = C.registerAutoFreeCFn("test", [], C.CaddrT); val f_test = fn : C.cdata list -> C.cdata - f_test []; val it = Caddr - : C.cdata - make_mud(f_test []); uncaught exception Representation raised at: boot/Unsafe/object.sml:65.19-65.33 print/ppobj.sml:354.20 print/ppobj.sml:354.20 util/pp.sml:554.6 - Comments: Fix: Test: - Owner: Lorenz?, Zhong? Status: open ---------------------------------------------------------------------- Number: 1437 Title: Unix.signal missing Keywords: Unix, signals Submitter: Stephen Weeks Date: 9/8/98 Version: 110.7 System: x86-linux Severity: Problem: The type signal is missing from the Unix structure. Comments: Fix: Test: - Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1438 Title: Wrong types for TextIO.StreamIO.inputAll and TextIO.StreamIO.mkInstream Keywords: types, IO, TextIO, StreamIO Submitter: Elsa L. Gunter Date: 09/14/98 Version: 110.8 System: Any/All Any Unix Subsystem: SML basis library Severity: minor Problem: The types for inputAll and mkInstream in TextIO.StreamIO are wrong under Unix (but right under Win32). They are TextIO.StreamIO.inputAll : ?.TextIO.instream -> TextIO.StreamIO.vector * ?.TextIO.instream TextIO.StreamIO.mkInstream : TextIO.StreamIO.reader * TextIO.StreamIO.vector option -> ?.TextIO.instream but the Standard Basis says they should be TextIO.StreamIO.inputAll : TextIO.StreamIO.instream -> TextIO.StreamIO.vector TextIO.StreamIO.mkInstream : TextIO.StreamIO.reader * TextIO.StreamIO.vector -> TextIO.Stream.instream That is, inputAll is returning an extra instream, and mkInstream is taking a vector option instead of a vector. Also note that the type ?.TextIO.insteam is being printed in place of TextIO.StreamIO.instream. This is rather confusing at best. Code: val x = (TextIO.StreamIO.inputAll,TextIO.StreamIO.mkInstream); Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - val x = (TextIO.StreamIO.inputAll,TextIO.StreamIO.mkInstream); val x = (fn,fn) : (?.TextIO.instream -> TextIO.StreamIO.vector * ?.TextIO.instream) * (TextIO.StreamIO.reader * TextIO.StreamIO.vector option -> ?.TextIO.instream) Comments: The types seem to be right under Win32, although I think it prints ?.TextIO.instream in place of TextIO.StreamIO.instream there as well. Fix: Test: Owner: jhr, Appel Status: fixed in 110.8.1 [Andrew] ---------------------------------------------------------------------- Number: 1439 Title: OS.FileSys.access raises inappropriate SysErr exception Keywords: exception, file-system Submitter: Elsa L. Gunter elsa@research.bell-labs.com Date: 09/14/98 Version: 110.8 System: Any/All Windows NT 4.0 Subsystem: SML compiler Severity: minor Problem: OS.FileSys.access raises "uncaught exception SysErr: access: cannot get file attributes" when a file doesn't exist under Windows NT, but it returns false under linux. The Standard Basis says: "The function will only raise OS.SysErr for errors unrelated to resolving the the pathname and related permissions, such as being interupted by a signal during the system call." Code: (* Let "toto" be a file that doesn't exist *) val x = OS.FileSys.access ("toto",[]); Transcript: I don't have easy access to WIndows NT at the moment, but the line in quotes in the Description of Problem was cut from a real session. Comments: Fix: Test: Owner: jhr, Appel Status: open ---------------------------------------------------------------------- Number: 1440 Title: CM.set_path has no effect in Win 32 or Irix 6.4 Keywords: CM search path Submitter: Elsa L. Gunter elsa@research.bell-labs.com Date: 09/14/98 Version: 110.8 System: x86 Windows NT 4.0 Subsystem: Compilation manager (CM) Severity: critical Problem: CM.set_path always returns the same list in Win 32 and Irix 6.4. This appears to reflect an unchanging search path for CM under these operating systems. Code: val x = (CM.set_path (SOME ["/usr/local/hol"]); CM.set_path NONE); Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - val x = (CM.set_path (SOME ["/usr/local/hol"]); CM.set_path NONE); val x = [".","/home/sml/Versions/110.8/lib"] : string list Comments: This works in the linux version and the solaris version. [Matthias, 10/9/98] I have no access to a Win32 version, but (as expected) this bug does not seem to exist on the Irix 6.4 version. I suspect that it was a transient problem related to some out-of-date sources. (There is no reason whatsoever why CM.set_path should behave differently on different systems.) See also bug 1418. Fix: Test: tests.cm/bug1418.sml Owner: Blume Status: fixed in 110.8.1 (IRIX, Solaris, Windows?) ---------------------------------------------------------------------- Number: 1441 Title: reading input from stdIn in emacs under Windows Keywords: input, Windows Submitter: Robert Harper Date: 9/14/98 Version: 110.8 System: x86/Windows Severity: minor Problem: If I invoke a function, say, read(), that reads from stdIn, the trailing newline from the invocation "read();" gets read as input. Code: Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 - fun read () = TextIO.input TextIO.stdIn; val read = fn : unit -> TextIO.vector - read (); val it = "\n" : TextIO.vector - (* To get this final prompt I have to hit return *) Comments: This is running under emacs (emacs 20.3.1 on a PC running NT4.0SP3). It appears to work properly from the cmd prompt. Perhaps it's an emacs bug after all. [Lorenz, 9/15/98] The emacs shell mode under NT/W95 (gnu emacs) is known to be buggy in this respect. I reported a number of bugs, similar to those below, to Voelker over a year ago and they apparently still remain open. If the problems appear at the DOS prompt as well, please let me know. Fix: - Test: - Owner: Riccardo, Lorenz Status: not a bug ---------------------------------------------------------------------- Number: 1442 Title: EOF to terminate read terminates top level in emacs under Windows Keywords: input, I/O, Windows Submitter: Robert Harper Date: 9/14/98 Version: 110.8 System: x86/Windows Severity: minor Problem: I invoke a function, say, read(), that reads from stdIn. Then if I send eof to terminate the read, it returns and then also closes the top level for me, exiting sml. Transcript: - fun read () = TextIO.input TextIO.stdIn; val read = fn : unit -> TextIO.vector - read(); abcdval it = "abcd" : TextIO.vector Comments: This is running under emacs (emacs 20.3.1 on a PC running NT4.0SP3). It appears to work properly from the cmd prompt. Perhaps it's an emacs bug after all. [Lorenz, 9/15/98] The emacs shell mode under NT/W95 (gnu emacs) is known to be buggy in this respect. I reported a number of bugs, similar to those below, to Voelker over a year ago and they apparently still remain open. If the problems appear at the DOS prompt as well, please let me know. Fix: - Test: - Owner: Riccardo, Lorenz Status: not a bug ---------------------------------------------------------------------- Number: 1443 Title: Real.toManExp broken -- wrong exponent returned. Keywords: Real64.toManExp (file: real64.sml) Submitter: dew@pgroup.com (David Wohlford) Date: 9/16/1998 Version: 110.0.3 System: any arch/any OS Severity: minor/major Problem: Real.toManExp returns incorrect values for the exponent of floating point numbers. For example, Real.toManExp 7.0 => {exp=3, man=0.875}. The exponent should be 2. Also, Real.toManExp 0.0 returns {exp=~1022, man=0.0}. I believe 1.0 * (2^(e_min-1)) is the standard for representing 0.0. The problem seems to be that there is a spurious addition of 1 to the exponent to work around a previous bug in logb. This doesn't seem to be necessary anymore, and other code in the module with similar exponent-extracting needs doesn't do this anymore (I think -- should check to be sure). [dbm] May be related to bug 1362. Code: Real.toManExp 7.0; Real.toManExp 0.0; Transcript: - Compiler.version; val it = {date="January 30, 1998",system="Standard ML of New Jersey", version_id=[110,0,3]} : {date:string, system:string, version_id:int list} - Real.toManExp 7.0; val it = {exp=3,man=0.875} : {exp:int, man:real} - Real.toManExp 0.0; val it = {exp=~1022,man=0.0} : {exp:int, man:real} - Real.toManExp 1.0; val it = {exp=1,man=0.5} : {exp:int, man:real} Comments: It looks like the mantissa is only correct given this incorrect exponent. With this function as it is, it is hard to write a function that will take a real number and return/write a bit-representation of the number (e.g. for outputting constant initializations to a .s file). [Aleksandar Nanevski [mailto:aleks+@cs.cmu.edu], 7/19/00] Real.toManExp doesn't return the correct values for numbers close to maxFinite: - Real.toManExp Real.maxFinite; val it = {exp=0,man=1.79769313486e308} : {exp:int, man:real} when the exp should be actually 1023, and the man something else. Here's the code that implements this function in the Basis: (* AARGH! Our version of logb gives a value that's one less than the rest of the world's logb functions. We should fix this systematically some time. *) fun toManExp x = case I.+(Assembly.A.logb x, 1) of ~1023 => if x==0.0 then {man=x,exp=0} else let val {man=m,exp=e} = toManExp(x*1048576.0) in {man=m,exp=I.-(e,20)} end | 1024 => {man=x,exp=0} | i => {man=Assembly.A.scalb(x,I.~ i),exp=i} Now, to implement a new version of toManExp, I will not be able to access these Assembly.A functions. So the code will necessarily be tricky and slow. This bug has been pointed out a long time ago actually. I found it in the openbug list for SML-NJ under the numbers 1319, 1362 and 1443. There is also one other thing that worries me -- it involves the fp arithmetic on Pentium. The Pentium has 80 bit long internal registers for floating point operations. This means that after a chain of operations has been performed using values from the registers, the final result will be rounded to 64 bits and stored in memory. However, while this improves the stability of numerical computations, it is not quite by the IEEE standard (or rather, the standard is a bit vague on that issue). What happens is that if your computation has been performed solely in the registers you'll get a different result then if some of the intermediate results has been pushed to memory and then retrieved back into a register. So, logically equivalent expressions, whose equality can be proved in the IEEE standard may give different results, depending on how the register allocation has been performed. Aside, it breaks the extended floats on Pentium, unless special care is taken to do these rounding after every operation (which is slow), or set specific FP unit flags which prevent the additional bits from being used -- which will probably have to be done by installing a C function into the runtime system. I haven't noticed any bad instances of this problem so far, but that's mainly because I didn't run too extensive tests. Anyway, I wanted to make you aware of this problem, since it looks to me that the consequences are beyond just extended floats, and rather influence the correctness of the whole compiler -- it doesn't look very pretty to me to have provably equivalent programs (provable under the `axioms' of the IEEE standard) produce different values on the same machine, let alone on different machines. Again, I'm not sure that SML-NJ actually does this badly; I wouldn't know until I test everything. But, I have a nagging feeling, which grew after I saw SML-NJ basis implementation of the Real.minPos: local (* The x86 uses extended precision (80 bits) internally, therefore * it is necessary to write out the result of r * 0.5 to get * 64 bit precision. *) val mem = InlineT.PolyArray.array(1, minNormalPos) val update = InlineT.PolyArray.update val subscript = InlineT.PolyArray.chkSub fun f () = let val r = subscript(mem, 0) val y = r * 0.5 in update(mem, 0, y); if subscript(mem, 0) == 0.0 then r else f () end in val minPos = f() end Do you perhaps happen to know any details on this already? If yes, it can save me some time in hacking and debugging. [Aleksandar Nanevski [mailto:aleks+@cs.cmu.edu], 7/20/00] As you asked, the file with fixes for the bugs I've noticed in the Real structure is attached. Even though it still uses some of the old functions in the cases when they do behave correctly, it should be easy for the SML-NJ people to plug in the assembly primitives and fix the bugs in the standard basis. (********************************************** ** Real.sml ** sml ** ** Aleksandar Nanevski ** ** Fixes the bug in Real.toManExp. It didn't ** work for numbers with exponents around ** Real.maxFinite. ** ** Implementation of fromManExp and split which ** do not depend on the rounding mode. Important ** since these functions are used in InfInt and ** Rational to approximate numbers to their ** nearest float. Besides, as they were originally, ** they violated the specification given in the ** Standard Basis. ** ** ** TODO: ** - fromManExp should set the overflow and ** underflow flags when appropriate. **********************************************) structure Real : REAL = struct structure I = Int open Real infix == val p512 = Real.fromManExp{man=1.0, exp=512} val q512 = Real.fromManExp{man=1.0, exp=Int.~ 512} fun toManExp x = if x >= 1.0 then (* the exponent is positive, so we can divide by 2^512 with no overflow or underflow *) let val {man=m, exp=k} = Real.toManExp (q512 * x) in {man=m, exp=Int.+(k, 512)} end else if x == 0.0 then {man=0.0, exp=0} else (* the exponent is negative, so we can multiply by 2^512 with no overflow or underflow *) let val {man=m, exp=k} = Real.toManExp (p512 * x) in {man=m, exp=Int.-(k, 512)} end (* original fromManExp depends on the rounding mode when *) (* overflowing or underflowing; this is not specified by *) (* the standard basis, and is not good for some functions *) (* on infinite integers and rationals *) val maxFinHalfPos = 0.5 * maxFinite val maxFinHalfNeg = ~maxFinHalfPos val minPosDouble = 2.0 * minPos val minNegDouble = ~minPosDouble fun fromManExp {man=m, exp=e} = if (m >= 0.5 andalso m <= 1.0 orelse m <= ~0.5 andalso m >= ~1.0) then if I.>(e, 1020) then if m > 0.0 then if I.>(e, 1050) then posInf else let fun f(i, x) = if i=0 then x else if (x > maxFinHalfPos) then posInf else f(I.-(i, 1), x+x) in f(I.-(e, 1020), Real.fromManExp{man=m, exp=1020}) end else if I.>(e, 1050) then negInf else let fun f(i, x) = if i=0 then x else if (x < maxFinHalfNeg) then negInf else f(I.-(i, 1), x+x) in f(I.-(e, 1020), Real.fromManExp{man=m, exp=1020}) end else if I.<(e, I.~ 1020) then if I.<(e, I.~ 1200) then 0.0 else if m > 0.0 then let fun f(i, x) = if i = 0 then x else if (x < minPosDouble) then 0.0 (* with setting the underflow flag *) else f(I.-(i, 1), x*0.5) in f(I.-(1020, e), Real.fromManExp{man=m, exp=I.~ 1020}) end else let fun f(i, x) = if i=0 then x else if (x > minNegDouble) then 0.0 (* with setting the underflow flag *) else f(I.-(i, 1), x*0.5) in f(I.-(1020, e), Real.fromManExp{man=m, exp=I.~ 1020}) end else Real.fromManExp{man=m, exp=e} (* This is the common case! *) else let val {man=m', exp=e'} = toManExp m in fromManExp{man=m', exp=I.+(e', e)} end (* SML-NJ calls this maxInt; I changed it's name into *) (* maxPosInt. It is the smallest float with the property *) (* *) (* Forall x:float. (x >= maxPosInt) => (x:int) *) (* *) (* It is equal to 2^52. *) val maxPosInt = 4503599627370496.0 val maxNegInt = ~ maxPosInt (* split and realMod should be independent of the rounding mode *) fun split x = if x > 0.0 then if x > maxPosInt then {whole=x, frac=0.0} (* how to make a signed zero? *) else (* SML-NJ says this rounds according to the rounding mode. *) (* It seems though it doesn't do the job for exponents *) (* above 53 under other roundings; hence the check above *) (* Besides, a check as above is needed anyway if we want *) (* to return correctly as specified by the Basis, on *) (* inputs x=posInf and x=negInf. SML-NJ had an error *) (* there too, even under the default rounding *) let val w = (x + maxPosInt) - maxPosInt val f = x - w (* this is computed exactly *) in (* check the signs *) if f < 0.0 then {whole=w-1.0, frac=1.0+f} else {whole=w, frac=f} end else if x < maxNegInt then {whole=x, frac=0.0} (* how to make a signed zero? *) else let val w = (x - maxPosInt) + maxPosInt val f = x - w in if f > 0.0 then {whole=w+1.0, frac=f-1.0} else {whole=w, frac=f} end val realMod = #frac o split end Fix: Test: bug1443.1.sml Owner: jhr, Andrew Status: open ---------------------------------------------------------------------- Number: 1444 Title: First Century Blues Keywords: Dates Submitter: George Russell george@persimmon.co.uk Date: 09/17/98 Version: 110.8 System: Alpha Digital Unix 4.0B Subsystem: SML basis library Severity: minor Problem: Date.toString does not conform with the standard. It prints Year 1 as " 0 1" and (perhaps this is more likely to be noticed) the first day of the month as " 1" (not "01" as seems implied by the basis document). Code: Date.date{year=1,month=Date.Jan,day=1,hour=0,minute=0,second=0,offset=NONE}; Date.toString it; Transcript: Date.date{year=1,month=Date.Jan,day=1,hour=0,minute=0,second=0,offset=NONE}; val it = DATE {day=1,hour=0,isDst=NONE,minute=0,month=Jan,offset=NONE,second=0,wday=Mon, yday=0,year=1} : Date.date - Date.toString it; val it = "Mon Jan 1 00:00:00 0 1" : string Comments: Fix: Test: bug1444.1.sml Owner: jhr? Status: open ---------------------------------------------------------------------- Number: 1445 Title: uncaught Unbound in FLINT/trans/transtypes.sml Keywords: FLINT, transtypes, types Submitter: Dave MacQueen Date: 9/21/98 Version: 110.0.3 - 110.8.1 System: - Severity: major Problem: Elaborating a functor decl causes an uncaught exception Unbound (probably EntityEnv.Unbound?). Code: signature S1 = sig type t val x : t (* needed *) end; signature S2 = sig structure T : S1 end; signature S3 = sig type s datatype t = Kt of s (* s needed *) end; (* ok *) functor F1 (structure C : S2 structure D : S2 structure E : S3 sharing D.T = C.T sharing type E.t = C.T.t) = struct end; (* ok *) functor F2 (structure C : S2 structure D : S2 where T = C.T structure E : S3 where type t = C.T.t) = struct end; (* uncaught exception Unbound at FLINT/trans/transtypes.sml:277.33-277.43 *) functor F (structure C : S2 structure D : S2 where T = C.T (* needed *) structure E : S3 sharing type E.t = C.T.t) = (* needed *) struct end; Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 - use "x1.sml"; [opening x1.sml] signature S1 = sig type t val x : t end GC #0.0.0.0.1.2: (10 ms) signature S2 = sig structure T : sig type t val x : t end end signature S3 = sig type s datatype t = Kt of s end functor F1 : functor F2 : uncaught exception Unbound raised at: FLINT/trans/transtypes.sml:277.33-277.43 FLINT/trans/translate.sml:150.39 Comments: In 110.0.3 error message is: uncaught exception Unbound raised at: translate/transmodules.sml:80.33-80.43 translate/translate.sml:129.39 If the parameter signature for F is declared separately, as in signature S4 = sig structure C : S2 structure D : S2 where T = C.T (* needed *) structure E : S3 sharing type E.t = C.T.t end; functor F(X:S4) = struct end; then the elaboration of the S4 declaration succeeds, but the functor declaration fails as before. Fix: In Instantiate/buildStrClass/finalize, eliminate the conditional on eqSig(sign,sign') in the SOME(VARstrDef...) case for defining finalEnt, always returning (GENERATE_ENT false). The bug code illustrates that even when signatures agree, a VARstrDef can introduce external free entVars (in this case for type s in S3), requiring some context entityEnv (see also mkEntEnv later in instantiate.sml). Test: bug1445.1.sml, bug1445.2.sml Owner: Zhong, dbm Status: fixed in 110.9 [dbm, Zhong] ---------------------------------------------------------------------- Number: 1446 Title: "Translate: unexpected tyvar INSTANTIATED in mkPE" in lazy code Keywords: lazy, translate Submitter: Phil Wadler Date: 9/22/98 Version: 110.8.1 System: - Severity: major Problem: Certain lazy declarations cause: Compiler bug: Translate: unexpected tyvar INSTANTIATED in mkPE Code: (* bug1446.1.sml *) infixr 5 >>; datatype lazy series = >> of int * series; fun lazy recip () = (* ok if "lazy" removed on this line *) let val rec lazy rs = 1 >> rs in rs end; ============ (* bug1446.2.sml *) datatype lazy series = >> of int * series; fun lazy tail (x>>xs) = xs; fun lazy plus (f>>fs,g>>gs) = f+g >> plus(fs,gs); let val rec lazy rs = let val lazy rs1 = tail rs in 0 >> 1 >> plus(rs1,rs) end in rs end; Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 - Compiler.Control.lazysml := true; val it = () : unit - use "test/src/lazy/ps2.sml"; [opening test/src/lazy/ps2.sml] infixr 5 >> datatype series! = >> of int * series! ?.susp type series = series! ?.susp Error: Compiler bug: Translate: unexpected tyvar INSTANTIATED in mkPE Comments: Fix: [Zhong] The bug was caused by the fact that we were not generating new copies of the "forceExp" function in the elabDec function in Semantics/elaborate/elabcore.sml. Test: bug1446.1.sml, bug1446.2.sml Owner: dbm, Zhong Status: fixed in 110.9.1 [Zhong, 9/24/98] ---------------------------------------------------------------------- Number: 1447 Title: Real.fmt fails on large real number Keywords: Real, format, conversion, StringCvt Submitter: Dave MacQueen Date: 10/6/98 Version: 110.8.2+ System: sparc/solaris 2.5.1 Severity: medium Problem: Real.fmt adds a spurious .1 when converting round real numbers above 91827364509181.0 to a string. Code: (* bug1447.1.sml *) Real.fmt (StringCvt.FIX(SOME 0)) 91827364509181.0; Real.fmt (StringCvt.FIX(SOME 1)) 91827364509181.0; Real.fmt (StringCvt.FIX(SOME 2)) 91827364509181.0; Real.fmt (StringCvt.FIX(SOME 0)) 91827364509182.0; Real.fmt (StringCvt.FIX(SOME 1)) 91827364509182.0; Real.fmt (StringCvt.FIX(SOME 2)) 91827364509182.0; Real.fmt (StringCvt.FIX(SOME 0)) 91827364509183.0; Real.fmt (StringCvt.FIX(SOME 1)) 91827364509183.0; Real.fmt (StringCvt.FIX(SOME 2)) 91827364509183.0; Transcript: - use "/home/sml/Dev/bugs/tests/bug1447.1.sml"; [opening /home/sml/Dev/bugs/tests/bug1447.1.sml] val it = "91827364509181" : string val it = "91827364509181.0" : string val it = "91827364509181.00" : string val it = "91827364509182" : string val it = "91827364509182.1" : string val it = "91827364509182.10" : string val it = "91827364509183" : string val it = "91827364509183.1" : string val it = "91827364509183.10" : string val it = () : unit Comments: This comes from the basis/real.sml regression test. It causes test 11c to fail. Fix: Test: bug1447.1.sml Owner: jhr? Status: open ---------------------------------------------------------------------- Number: 1448 Title: Real.round does not round to nearest even for ties Keywords: Real, round Submitter: Dave MacQueen Date: 10/6/98 Version: 110.8.2+ System: sparc/solaris 2.5.1 Severity: major Problem: Real.round rounds upward, rather than to the nearest even, in the case of a tie. Code: Real.round 0.5; Real.round 1.5; Real.round 2.5; Real.round (~0.5); Real.round (~1.5); Transcript: - Real.round 0.5; val it = 1 : int - Real.round 1.5; val it = 2 : int - Real.round 2.5; val it = 3 : int - Real.round(~0.5); val it = 0 : int - Real.round(~1.5); val it = ~1 : int Comments: This comes from test 7a in the basis/real.sml regression tests. Fix: Test: bug1448.1.sml Owner: dbm Status: fixed in 110.0.6 [dbm] ---------------------------------------------------------------------- Number: 1449 Title: FFT benchmark gives wrong answers. Keywords: reals Submitter: Andrew Kennedy andrew@persimmon.co.uk Date: 10/07/98 Version: 110.8 System: Any/All Other (describe below) Subsystem: SML compiler Severity: major Problem: The FFT benchmark gives the wrong answers on all architectures that we have tested. Code: structure Main = struct local open Array Math val printr = print o Real.toString val printi = print o Int.toString in val PI = 3.14159265358979323846 val tpi = 2.0 * PI fun fft px py np = let fun find_num_points i m = if i < np then find_num_points (i+i) (m+1) else (i,m) val (n,m) = find_num_points 2 1 in if n <> np then let fun loop i = if i > n then () else ( update(px, i, 0.0); update(py, i, 0.0); loop (i+1)) in loop (np+1); print "Use "; printi n; print " point fft\n" end else (); let fun loop_k k n2 = if k >= m then () else let val n4 = n2 div 4 val e = tpi / (real n2) fun loop_j j a = if j > n4 then () else let val a3 = 3.0 * a val cc1 = cos(a) val ss1 = sin(a) val cc3 = cos(a3) val ss3 = sin(a3) fun loop_is is id = if is >= n then () else let fun loop_i0 i0 = if i0 >= n then () else let val i1 = i0 + n4 val i2 = i1 + n4 val i3 = i2 + n4 val r1 = sub(px, i0) - sub(px, i2) val _ = update(px, i0, sub(px, i0) + sub(px, i2)) val r2 = sub(px, i1) - sub(px, i3) val _ = update(px, i1, sub(px, i1) + sub(px, i3)) val s1 = sub(py, i0) - sub(py, i2) val _ = update(py, i0, sub(py, i0) + sub(py, i2)) val s2 = sub(py, i1) - sub(py, i3) val _ = update(py, i1, sub(py, i1) + sub(py, i3)) val s3 = r1 - s2 val r1 = r1 + s2 val s2 = r2 - s1 val r2 = r2 + s1 val _ = update(px, i2, r1*cc1 - s2*ss1) val _ = update(py, i2, ~s2*cc1 - r1*ss1) val _ = update(px, i3, s3*cc3 + r2*ss3) val _ = update(py, i3, r2*cc3 - s3*ss3) in loop_i0 (i0 + id) end in loop_i0 is; loop_is (2 * id - n2 + j) (4 * id) end in loop_is j (2 * n2); loop_j (j+1) (e * real j) end in loop_j 1 0.0; loop_k (k+1) (n2 div 2) end in loop_k 1 n end; (************************************) (* Last stage, length=2 butterfly *) (************************************) let fun loop_is is id = if is >= n then () else let fun loop_i0 i0 = if i0 > n then () else let val i1 = i0 + 1 val r1 = sub(px, i0) val _ = update(px, i0, r1 + sub(px, i1)) val _ = update(px, i1, r1 - sub(px, i1)) val r1 = sub(py, i0) val _ = update(py, i0, r1 + sub(py, i1)) val _ = update(py, i1, r1 - sub(py, i1)) in loop_i0 (i0 + id) end in loop_i0 is; loop_is (2*id - 1) (4 * id) end in loop_is 1 4 end; (*************************) (* Bit reverse counter *) (*************************) let fun loop_i i j = if i >= n then () else (if i < j then (let val xt = sub(px, j) in update(px, j, sub(px, i)); update(px, i, xt) end; let val xt = sub(py, j) in update(py, j, sub(py, i)); update(py, i, xt) end) else (); let fun loop_k k j = if k < j then loop_k (k div 2) (j-k) else j+k val j' = loop_k (n div 2) j in loop_i (i+1) j' end) in loop_i 1 1 end; n end fun abs x = if x >= 0.0 then x else ~x fun test np = let val _ = (printi np; print "... ") val enp = real np val npm = (np div 2) - 1 val pxr = array (np+2, 0.0) val pxi = array (np+2, 0.0) val t = PI / enp val _ = update(pxr, 1, (enp - 1.0) * 0.5) val _ = update(pxi, 1, 0.0) val n2 = np div 2 val _ = update(pxr, n2+1, ~0.5) val _ = update(pxi, n2+1, 0.0) fun loop_i i = if i > npm then () else let val j = np - i val _ = update(pxr, i+1, ~0.5) val _ = update(pxr, j+1, ~0.5) val z = t * real i val y = ~0.5*(cos(z)/sin(z)) val _ = update(pxi, i+1, y) val _ = update(pxi, j+1, ~y) in loop_i (i+1) end val _ = loop_i 1 (*** val _ = print "\n" fun loop_i i = if i > 15 then () else (print i; print "\t"; print (sub(pxr, i+1)); print "\t"; print (sub(pxi, i+1)); print "\n"; loop_i (i+1)) val _ = loop_i 0 ***) val _ = fft pxr pxi np (*** fun loop_i i = if i > 15 then () else (print i; print "\t"; print (sub(pxr, i+1)); print "\t"; print (sub(pxi, i+1)); print "\n"; loop_i (i+1)) val _ = loop_i 0 ***) fun loop_i i zr zi kr ki = if i >= np then (zr,zi) else let val a = abs(sub(pxr, i+1) - real i) val (zr, kr) = if zr < a then (a, i) else (zr, kr) val a = abs(sub(pxi, i+1)) val (zi, ki) = if zi < a then (a, i) else (zi, ki) in loop_i (i+1) zr zi kr ki end val (zr, zi) = loop_i 0 0.0 0.0 0 0 val zm = if abs zr < abs zi then zi else zr in printr zm; print "\n" end fun loop_np i np = if i > 13 then () else (test np; loop_np (i+1) (np*2)) fun main () = loop_np 1 16 end end Transcript: SML/NJ: 16... 8.881784197e~16 32... 3.5527136788e~15 64... 1.06581410364e~14 128... 2.84217094304e~14 256... 5.68434188608e~14 512... 1.16795462191e~13 1024... 3.41060513165e~13 2048... 7.95807864051e~13 4096... 1.40154554629e~12 8192... 3.63797880709e~12 16384... 7.27595761418e~12 32768... 1.45519152284e~11 65536... 2.91038304567e~11 MLJ (and Moscow ML): 16... 8.88178419700E~16 32... 2.66453525910E~15 64... 1.42108547152E~14 128... 2.93098878501E~14 256... 5.86197757002E~14 512... 1.70530256582E~13 1024... 3.41060513165E~13 2048... 9.09494701773E~13 4096... 1.81898940355E~12 8192... 5.45696821064E~12 16384... 1.09139364213E~11 32768... 2.18278728426E~11 65536... 5.82076609135E~11 Comments: Fix: Test: bug1449.1.sml Owner: Lal? Status: open ---------------------------------------------------------------------- Number: 1450 Title: bugs in Array2.fromList and Array2.row Keywords: Array2 fromList row Submitter: Huh Choong Gil earny@mathx.kaist.ac.kr Date: 10/10/98 Version: 110.0.3 System: Any/All Any Unix Subsystem: SML basis library Severity: major Problem: wrong behavior of Array2.fromList and Array2.row Code: from src/sml-nj/boot/array2.sml fun fromList [] = {data = Assembly.array0, nrows = 0, ncols = 0} ... List.revAppend (revCol, l)) ... end fun row ({data, nrows, ncols}, i) = let ... else mkVec (stop+nrows-1, []) end Transcript: * bug of Array2.fromList - val a = Array2.fromList [[1,2],[3,4],[5,6]]; val a = - : int Array2.array - Array2.app Array2.RowMajor (fn x => print (Int.toString x)) a; 125634val it = () : unit * bug of Array2.row - val b = Array2.tabulate Array2.RowMajor (2,1,fn _ => 1); val b = - : int Array2.array - Array2.nRows b; val it = 2 : int - Array2.row (b,1); uncaught exception subscript out of bounds raised at: boot/array2.sml:114.21-114.26 Comments: Fix: * bug of Array2.fromList The problem is the line List.revAppend (revCol, l)) in fun Array2.fromList of array2.sml which i think should be List.@(l, List.rev revCol)) * bug of Array2.row the problem is the line else mkVec (stop+nrows-1, []) in fun Array2.row of array2.sml which i think should be else mkVec (stop+ncols-1, []) Test: Owner: jhr Status: fixed in 110.9.1 and in 110.0.4 [jhr, 10/19/98] ---------------------------------------------------------------------- Number: 1451 Title: Math.sin(large number) is wrong Keywords: maths Submitter: George Russell george@persimmon.com Date: 10/13/98 Version: 110.8 System: Alpha Digital Unix 4.0B Subsystem: SML basis library Severity: minor Problem: sin(large number) returns ~1.0, 1.0 or 0.0 Code: Math.sin(1e16); Math.sin(1.1e16); Math.sin(1.2e16); Math.sin(1.3e16); Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - Math.sin(1e16); val it = 0.0 : real - Math.sin(1.1e16); val it = ~1.0 : real - Math.sin(1.2e16); val it = 1.0 : real - Math.sin(1.3e16); val it = 0.0 : real Comments: This values are inconsistent - if sin(x)=0, sin(x+y)= -1, then x= 0 mod 2pi, y= 3pi/2 mod 2pi; therefore sin(x+2y)=0 and sin(x+3y)=1. Fix: Do what fdlibm does and use multiprecision arithmetic to compute x mod 2pi exactly. This is the ideal solution, since it ensures consistency, even though the results aren't very meaningful. Otherwise, return an answer which is obviously wrong (EG NaN or x), since the program surely must be. Test: Owner: jhr, Andrew Status: open ---------------------------------------------------------------------- Number: 1452 Title: Math.sinh(small number)=0.0 Keywords: reals Submitter: George Russell george@persimmon.com Date: 10/13/98 Version: 110.8 System: Alpha Digital Unix 4.0B Subsystem: SML basis library Severity: minor Problem: For small x, sinh(x) is approximately x. However New Jersey thinks it is 0. Code: Math.sinh(1e~20); Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 val use = fn : string -> unit - Math.sinh(1e~20); val it = 0.0 : real Comments: Similar considerations apply to Math.tanh. Fix: I suspect that SML/NJ is using a formula which is something like sinh(x)=(e^x - e^{-x})/2. For small x, e^x=1, so SML/NJ falls into the ancient trap of subtracting two nearly equal quantities. One way of circumventing this is to use the expm1 function (available on Digital Unix, Sparc-Solaris and Linux at least) which is equal to e^x -1. Then we have sinh(x)=0.5*expm1(x)*(1+ 1/(expm1(x)+1)). (See fdlibm for more details). Test: bug1452.1.sml Owner: jhr, Andrew Status: open ---------------------------------------------------------------------- Number: 1453 Title: Compiler bug: LtyExtern: incorrect lambda types in lt_select Keywords: lazy compiler Submitter: Kevin Watkins kw+@cs.cmu.edu Date: 10/22/98 Version: 110.8, 110.9.1 System: x86 Linux 2.0.32 (Redhat 4.2) Subsystem: SML compiler Severity: major Problem: Compiler internal error was reported while processing source code using `lazy' and a polymorphic datatype. Note: the following val _ = Compiler.Control.lazysml := true; datatype lazy stream = Nil | Cons of unit * stream; val rec lazy x = Cons(raise Subscript, x); is accepted. Code: val _ = Compiler.Control.lazysml := true; datatype lazy 'a stream = Nil | Cons of 'a * 'a stream; val rec lazy x = Cons(raise Subscript, x); Transcript: gs73$ sml Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 [CM; autoload enabled] - val _ = Compiler.Control.lazysml := true; - datatype lazy 'a stream = Nil | Cons of 'a * 'a stream; datatype 'a stream! = Cons of 'a * 'a stream! ?.susp | Nil type 'a stream = 'a stream! ?.susp - val rec lazy x = Cons(raise Subscript, x); Error: Compiler bug: LtyExtern: incorrect lambda types in lt_select Comments: Fix: Test: tests.lazy/bug1453.1.sml Owner: dbm, Zhong Status: open ---------------------------------------------------------------------- Number: 1454 Title: Unexpected force of lazy suspension in pattern match Keywords: lazy pattern-match Submitter: Kevin Watkins kw+@cs.cmu.edu Date: 10/22/98 Version: 110.8 System: x86 Linux 2.0.32 (Redhat 4.2) Subsystem: SML compiler Severity: major Problem: The implementation of `lazy' in 110.8 does not seem to respect the semantics described in Wadler et al (How to add laziness to a strict language without even being odd). I have provided source code for a simple example which demonstrates the problem in the place provided on this bug report form. It raises an exception rather than returning [] as one would expect. Code: val _ = Compiler.Control.lazysml := true; datatype lazy stream = Nil | Cons of int * stream; fun take (s, 0) = [] | take (Nil, _) = raise Subscript | take (Cons(x, s), n) = x::take(s, n-1); val rec lazy don't_force_me = Cons(raise Fail "Was forced", don't_force_me); (* should return [] but raises Fail instead *) take(don't_force_me, 0); Transcript: gs73$ sml Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 [CM; autoload enabled] - val _ = Compiler.Control.lazysml := true; - datatype lazy stream = Nil | Cons of int * stream; datatype stream! = Cons of int * stream! ?.susp | Nil type stream = stream! ?.susp - fun take (s, 0) = [] = | take (Nil, _) = raise Subscript = | take (Cons(x, s), n) = x::take(s, n-1); val take = fn : stream! ?.susp * int -> int list - val rec lazy don't_force_me = Cons(raise Fail "Was forced", = don't_force_me); GC #0.0.0.0.1.16: (0 ms) val don't_force_me = $$ : stream! ?.susp - (* should return [] but raises Fail instead *) - take(don't_force_me, 0); uncaught exception Fail: Was forced raised at: stdIn:15.42-15.59 Comments: One might argue that the semantics of pattern matching should allow the behavior I'm claiming is incorrect. However, the very example with which the Wadler et al paper motivates the "even" versus "odd" definition of lazy data structures fails. Here is the code from Figure 3 of the paper: datatype lazy 'a stream = Nil | Cons of 'a * 'a stream; fun lazy map f Nil = Nil | map f (Cons(x,xs)) = Cons(f x, map f xs); fun lazy countdown n = Cons (n, countdown (n-1)); fun cutoff 0 xs = [] | cutoff n Nil = [] | cutoff n (Cons(x,xs)) = x :: cutoff (n-1) xs; The motivating example is in section 2.1 of the paper. Since `sqrt' no longer raises an exception in this version of SML, I will use `div' instead. We would expect cutoff 4 (map (fn x => 100 div x) (countdown 4)); to return [25, 33, 50, 100] but instead it raises Div. [Related report from Bob Harper, 10/1/98] Compiler.Control.lazysml := true; datatype lazy 'a stream = && of 'a * 'a stream; infixr &&; fun shd (h && _) = h; fun stl (_ && t) = t; (* eager *) fun lazy ltl (_ && t) = t; (* lazy *) fun lazy smap f (h && t) = (f h) && (smap f t) fun lazy szip (h && t, h' && t') = (h, h') && (szip (t, t')); val rec lazy s = 1 && 1 && smap (op +) (szip (s, stl s)) My expectation is that I should be able to take shd s and shd(stl s) without problem, but that taking shd (stl (stl s)) should loop. However, it loops the first time I take shd s. I don't get it. Apparently the second argument to the first "&&" is not suspended properly, or something like that. Could you please explain? Also, compare the following: val rec lazy s1 = 1 && s2 and lazy s2 = 1 && s3 and lazy s3 = smap (op +) (szip (s1, s2)) which works fine, as does the version in which s2 is replaced by stl s1. What gives? I would've thought these would be equivalent. Fix: Test: tests.lazy/bug1454.1.sml, bug1454.2.sml Owner: dbm, Wadler Status: open ---------------------------------------------------------------------- Number: 1455 Title: IntInf not properly supported Keywords: IntInf Submitter: Henry Cejtin Date: 10/30/98 Version: 110.8 System: Any/All Any Unix Subsystem: SML compiler Severity: minor Problem: According to the basis documentation (integer.html), if an implementation provides the IntInf structure, then LargeInt.int is supposed to be the same as IntInf.int. Similarly, literals should be accepted for IntInf.int constants. I.e., val x: IntInf.int = 9 should be accepted. Finally, the standard infix arithmetic operations, (+, -, ...) should be overloaded for IntInf.int. Comments: [dbm, 2/11/99] Support for IntInf is optional, but we should add it. The signature of IntInf is currently incomplete (lacks bitwise operations), and a higher performance implementation using primop support would be desirable. Fix: Test: Owner: jhr, Lal Status: not a bug ---------------------------------------------------------------------- Number: 1456 Title: Int.sameSign Keywords: Int.sameSign Submitter: Henry Cejtin henry@research.nj.nec.com Date: 10/30/98 Version: 110.8 System: Any/All Any Unix Subsystem: SML basis library Severity: minor Problem: The basis documentation says that Int.sameSign (x, y) should be equivalent to Int.sign x = Int.sign y Int.sign 0 --> 0 Int.sign 1 --> 1 and yet Int.sameSign (0, 1) -> true From experiments, it seems that sameSign (x, y) is simply testing if the sign bit of x and y is the same. Actually, I find this to be more useful, but either the documentation or the behavior should be changed. Note, the same behavior is exhibited by Int32.sameSign. Code: Int.sameSign (0, 1); Int32.sameSign (0, 1); Transcript: - Int.sameSign (0, 1); val it = true : bool - Int32.sameSign (0, 1); val it = true : bool Comments: Fix: Test: bug1456.1.sml Owner: jhr, Lal Status: open ---------------------------------------------------------------------- Number: 1457 Title: Posix.FileSys.readdir Keywords: Posix.Filesys.readdir Submitter: Henry Cejtin henry@research.nj.nec.com Date: 10/30/98 Version: 110.8 System: Any/All Any Unix Subsystem: SML basis library Severity: major Problem: In Posix.FileSys, what is the argument for readdir having the signature dirstream -> string instead of dirstream -> string option and having it return the empty string if there are no more directories? This seems completely insane to me. Note, that the C readdir() returns NULL when there are no more directories, so even it is closer to a string option. Comments: [jhr, 2/8/99] This is a basis spec issue; we implement the spec. Fix: Change Posix.FileSys.readdir so that it returns a string option, with NONE indicating the end of the directory has been reached. Test: Owner: jhr Status: not a bug ---------------------------------------------------------------------- Number: 1458 Title: Uninformative IO exception message / crash Keywords: IO Submitter: Allyn Dimock Date: 11/04/98 Version: 110.0.3 full-cm System: SGI Severity: minor Problem: Transcript below typed at command loop causes crash. The crash is probably a "feature" rather than a bug -- I should restore the old value of out before closing the temporary stream. But: it would be nice to have the error handled and something more informative than "" printed out. Code: Transcript: - val oldout = !Control.Print.out; val oldout = {flush=fn,say=fn} : {flush:unit -> unit, say:string -> unit} - val out = TextIO.openOut("xxx.xxx"); val out = - : TextIO.outstream - val sayout = {say = fn(s) => TextIO.output (out,s), flush = fn() => TextIO.flushOut(out)}; val sayout = {flush=fn,say=fn} : {flush:unit -> unit, say:TextIO.vector -> unit} - Control.Print.out := sayout; SmlnjFrontEnd.smlnjFrontEnd("test1a.sml"); GC #1.9.15.56.197.4729: (9 ms) ================== SMLNJ Lambda Term: ================== Untyped Cil Term: let.14 i: = .3{0=1.1:,1=2.2:} in i.7: GC #1.9.15.57.198.4747: (15 ms) GC #1.9.15.58.199.4753: (26 ms) %time cumsec #call name 33.33 .01 0 Major GC ...... GC #1.9.16.61.202.4768: (0 ms) TextIO.closeOut(out); /usr/local/sml/bin/sml-full-cm: Fatal error -- Uncaught exception Io with raised at boot/IO/text-io-fn.sml:444.14-444.56 Process sml-full-cm exited abnormally with code 1 by the way, the contents of xxx.xxx is: arctic 37% more xxx.xxx val it = () : unit - [opening test1a.sml] FN(v3 : S{}, i2 = RECORD(1,2) SRECORD(i2)) val it = () : unit - arctic 38% Comments: (Attempt to use mcprint to a file) [jhr, 11/4/98] This is a "feature" of having an interactive top-level loop that shares its streams with executing programs. Fix: Test: Owner: jhr Status: not a bug ---------------------------------------------------------------------- Number: 1459 Title: segmentation fault after an interrupt Keywords: core dump, interrupt Submitter: Elsa Gunter Date: 11/13/98 Version: 110.9.1 System: x86/Linux Severity: major Problem: Yesterday, just before I went home, I encountered the following bad bahavior form sml version 110.9.1 running under Linux: Transcript: ... GC #4.38.85.145.802.29587: (40 ms) GC #4.38.85.145.803.29589: (40 ms) GC #4.38.85.145.804.29590: (10 ms) GC #4.38.85.145.805.29622: (20 ms) GC #4.39.86.146.806.29700: (120 ms) Interrupt - use "cm-make.sml"; GC #4.39.86.146.807.29706: (30 ms) /usr/local/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x804c34d 481.0u 4.6s 11:47.57 68.6% 0+0k 0+0io 941pf+0w cambridge% Comments: The compiler was busy compiling something big, and I didn't need it to finish and I didn't want to wait for it, so I interupted it. Then I tried to use another file and it immediately died on me. I can't reproduce the problem, but I thought I shiuld pass it along especially since there was some information generated when it died. Fix: Test: Owner: ? Status: not reproducible ---------------------------------------------------------------------- Number: 1460 Title: CM.stabilize(') fails when calling BinIO under Win32 Keywords: CM, IO Submitter: Elsa L. Gunter, elsa@research.bell-labs.com Date: 11/13/98 Version: 110.9.1 System: x86-win32 ie. windows nt, windows 95 (I haven't checked 98 yet) Severity: major Problem: When CM.stabilize' is called it fails with an IO exception generated by BinIO.inputAll claiming an subscript is out of bounds Code: File [test.sml] structure A = struct end File [test.cm] Group is test.sml val _ = CM.stabilize'{group="test.cm", recursively=false}; Transcript: Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 - val _ = CM.stabilize'{group="test.cm", recursively=false}; [starting dependency analysis] [scanning test.cm] [checking CM\x86-win32\test.cm.stable... not usable] [parsing test.sml] [Creating directory CM\DEPEND ...] [dependency analysis completed] [compiling test.sml -> CM\x86-win32\test.sml.bin] [Creating directory CM\x86-win32 ...] [wrote CM\x86-win32\test.sml.bin] [starting dependency analysis] [dependency analysis completed] writing CM\x86-win32\test.cm.stable failed] uncaught exception Io: inputAll failed on "CM\x86-win32\test.sml.bin" with exception subscript out of bounds raised at: PervEnv/IO/bin-io-fn.sml:107.14-107.56 ../cm/decl/decl.sml:260.41 ../cm/util/interrupt.sml:35.58-35.61 ../cm/decl/decl.sml:376.45-376.48 ../cm/decl/decl.sml:384.8-384.11 - - Comments: It doesn't matter whether a CM.make' has been done on the group test.cm, or not. [Blume] It appears that inputAll on Win32 is the culprit. Fix: Test: - Owner: Lorenz, Riccardo Status: open ---------------------------------------------------------------------- Number: 1461 Title: Changing directories confuses CM sharing Keywords: CM, share Submitter: Elsa L. Gunter, elsa@research.bell-labs.com Date: 12/10/98 Version: 110.9.1 System: x86-linux Severity: major Problem: When the directory is changed on CM, by exporting a heap and restarting it in a different place, or by using OS.FileSys.chDir, CM seems to loose track of modules that it has already loaded and executed. Code: (* Code and Instructions *) Make the following directories: bug bug/bug1 bug/bug2 Create the following files: (* bug/bug1/first.sml *) structure First = struct val x = ref 0 end (*------------------------------------*) (* bug/bug1/first.cm *) Library structure First is first.sml : shared (*------------------------------------*) (* bug/bug2/second.sml *) structure Second = struct val y = !First.x end (*------------------------------------*) (* bug/bug2/second.cm *) Library structure Second is ../bug1/first.cm second.sml : shared (*------------------------------------*) (* bug/load1.sml *) val _ = CM.make' {group = "/bug/bug1/first.cm", force_relink = false}; val _ = First.x := 3; fun finish () = CM.make' {group = "/bug/bug2/second.cm", force_relink = false}; val _ = SMLofNJ.exportML "bug"; (*------------------------------------*) Now while in the directory bug, start sml and execute use "load1.sml"; finish(); Stop sml, then start <> and execute finish(); Second.y; Stop sml, cd .., then start <> and execute finish(); Second.y; The fisrt value of Second.y is 3, while the second is 0. I claim the second is wrong. To see an alternate way of generating the same problem, add the following files: (*------------------------------------*) (* bug/bug2/third.sml *) structure Third = struct val y = !First.x end (*------------------------------------*) (* bug/bug2/third.cm *) Library structure Third is ../bug1/first.cm third.sml : shared (*------------------------------------*) (* bug/load2.sml *) val _ = CM.make' {group = "/bug/bug1/first.cm", force_relink = false}; val _ = First.x := 3; val _ = CM.make' {group = "/bug/bug2/second.cm", force_relink = false}; Second.y; val _ = OS.FileSys.chDir ".." (* any place different, really *) val _ = CM.make' {group = "/bug/bug2/third.cm", force_relink = false}; Third.y; val result = (Second.y = Third.y); (*------------------------------------*) Now, while in the bug directory, start sml and execute use "load2.sml" I claim the value of result should be true, but is false. I append a tar-gzip-uuencoded copy of the bug directory at the end of this report. Transcript: norfolk% ls -R bug1/ bug2/ load1.sml load2.sml bug1: first.cm first.sml bug2: second.cm second.sml third.cm third.sml norfolk% sml Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 val use = fn : string -> unit - use "load1.sml"; [opening load1.sml] [starting dependency analysis] [scanning /home/elsa/bug/bug1/first.cm] [checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable] [parsing /home/elsa/bug/bug1/first.sml] [Creating directory /home/elsa/bug/bug1/CM/DEPEND ...] [dependency analysis completed] [compiling /home/elsa/bug/bug1/first.sml -> /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin] [Creating directory /home/elsa/bug/bug1/CM/x86-unix ...] [wrote /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin] [introducing new bindings into toplevel environment...] val finish = fn : unit -> bool GC #1.1.1.1.1.14: (120 ms) write 1,0: 27020 bytes [0x40c00000..0x40c0698c) @ 0x2000 write 1,1: 7800 bytes [0x40c60008..0x40c61e80) @ 0x9000 write 1,2: 11692 bytes [0x40cb0000..0x40cb2dac) @ 0xb000 write 1,3: 2656 bytes [0x40d20000..0x40d20a60) @ 0xe000 write 2,0: 70136 bytes [0x40d80000..0x40d911f8) @ 0xf000 write 2,1: 73480 bytes [0x40e30008..0x40e41f10) @ 0x21000 write 2,2: 16948 bytes [0x40ef0000..0x40ef4234) @ 0x33000 write 2,3: 2304 bytes [0x40f20000..0x40f20900) @ 0x38000 write 2,0: 5 big objects (5 pages) @ 0x39000 write 3,0: 27584 bytes [0x40f40000..0x40f46bc0) @ 0x3a450 write 3,1: 59736 bytes [0x40f70008..0x40f7e960) @ 0x41450 write 3,2: 18660 bytes [0x40fc0000..0x40fc48e4) @ 0x50450 write 3,3: 1288 bytes [0x40fe0000..0x40fe0508) @ 0x55450 write 4,0: 228 bytes [0x41000000..0x410000e4) @ 0x56450 write 4,1: 264 bytes [0x41010008..0x41010110) @ 0x57450 write 4,2: 124 bytes [0x41020000..0x4102007c) @ 0x58450 write 4,3: 24 bytes [0x41030000..0x41030018) @ 0x59450 write 5,0: 371204 bytes [0x41050000..0x410aaa04) @ 0x5a450 write 5,1: 575864 bytes [0x41220008..0x412ac980) @ 0xb5450 write 5,2: 147236 bytes [0x414e0000..0x41503f24) @ 0x142450 write 5,3: 52220 bytes [0x415a0000..0x415acbfc) @ 0x166450 write 5,0: 323 big objects (6625 pages) @ 0x173450 val it = () : unit - finish(); [starting dependency analysis] [scanning /home/elsa/bug/bug2/second.cm] [checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable] [parsing /home/elsa/bug/bug2/second.sml] [Creating directory /home/elsa/bug/bug2/CM/DEPEND ...] [dependency analysis completed] [compiling /home/elsa/bug/bug2/second.sml -> /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin] [Creating directory /home/elsa/bug/bug2/CM/x86-unix ...] [wrote /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin] [introducing new bindings into toplevel environment...] val it = true : bool - norfolk% sml @SMLload=bug; uncaught exception Io: input failed on "load1.sml", Bad file number raised at: PervEnv/IO/text-io-fn.sml:113.14-113.56 Parse/main/frontend.sml:92.32 Parse/main/frontend.sml:92.32 - finish(); [starting dependency analysis] [scanning /home/elsa/bug/bug2/second.cm] [checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable] [dependency analysis completed] [recovering /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin... done] [introducing new bindings into toplevel environment...] val it = true : bool - Second.y; val it = 3 : int - GC #0.0.0.0.1.5: (20 ms) norfolk% cd .. norfolk% sml @SMLload=bug/bug uncaught exception Io: input failed on "load1.sml", Bad file number raised at: PervEnv/IO/text-io-fn.sml:113.14-113.56 Parse/main/frontend.sml:92.32 Parse/main/frontend.sml:92.32 - finish(); [starting dependency analysis] [scanning /home/elsa/bug/bug2/second.cm] [checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable] [scanning /home/elsa/bug/bug1/first.cm] [checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable] GC #0.0.0.0.1.3: (10 ms) [dependency analysis completed] [recovering /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin... done] [recovering /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin... done] [introducing new bindings into toplevel environment...] val it = true : bool - Second.y; val it = 0 : int - norfolk% cd bug norfolk% sml Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 val use = fn : string -> unit - use "load2.sml"; [opening load2.sml] [starting dependency analysis] [scanning /home/elsa/bug/bug1/first.cm] [checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable] [dependency analysis completed] [recovering /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin... done] [introducing new bindings into toplevel environment...] [starting dependency analysis] [scanning /home/elsa/bug/bug2/second.cm] [checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable] GC #0.0.0.0.1.10: (10 ms) [dependency analysis completed] [recovering /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin... done] [introducing new bindings into toplevel environment...] val it = 3 : int [starting dependency analysis] [scanning /home/elsa/bug/bug2/third.cm] [checking /home/elsa/bug/bug2/CM/x86-unix/third.cm.stable... not usable] [scanning /home/elsa/bug/bug1/first.cm] [checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable] [parsing /home/elsa/bug/bug2/third.sml] [dependency analysis completed] [recovering /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin... done] [compiling /home/elsa/bug/bug2/third.sml -> /home/elsa/bug/bug2/CM/x86-unix/third.sml.bin] [wrote /home/elsa/bug/bug2/CM/x86-unix/third.sml.bin] [introducing new bindings into toplevel environment...] val it = 0 : int val result = false : bool val it = () : unit - norfolk% Comments: Here is a uuencoded, gzipped, tar file with the test files and directories. Unpacked version can be found in bugs/tests.cm/bug1461. ========= begin 644 bug.tgz M'XL(`"XF<#8``^U946^B0!#VM?R*.5Y.FP9W%W9)VOATESY<[/7!>V\0ETJ* M8!:X2"[WWV]!04M[M4UD-7:_Q*BX,A-FOIEO9Z?YX[#7,5W%[ND![1KQTKD:>8)@!Z/4D^%O1/#5,9?OG"72?"1^+O8 M!L`($:SCKP)-_(-0I)GE+SJP(-^#-QE__4KOE/*"KK/W8QU?Q7@1;M8;0I!,9O+X(5C$#P`)#!8\W\L\2&_^3D M])_6_TK0Q#_E?A+/.A&`^^H_1G2K_^1"6?\98[K^J\`K^F]29<):`%K6\]V! M7+?.$ZT)SP-M_G!5_K_KS(3_M?^UVFBN_^Y MH,7_(\U_Z);_Y2RXG/\XFO\JT**];O^?#"7_H\2;D6ZH7V$?_QFAS?S'9N7Y M#W+U_E\-2IH_2)I_N[,6WA/_"G\>19(OY15S.$\6?%@^E^&+4T+SRKBX``@2 MX?,'P:,P?I)_";PHY7]O#*.^ZZ9VP/4([)W+[S*V,Y*JK+UA;KUUL8H=$_<3 MZS:,^*1(+7_^/11@6I8)_4OPX@*6D>=SF(5!P`6/LRL0W(NB`BX''_:QELW[ M7*RJ:^.AX&D>9?+W?NVZ_+Q9,KA1J:AJ_N,C\M_>[O\I8ZSBOZO/?Y5`*?^# M/(8@C,-T#OU!!W6@-CNY&R?!SQ\67RT3D=V-P93W,>6"8S]M#8W3PC_5`W1N $`"@````` ` end ========= Fix: Test: tests.cm/bug1461 Owner: Matthias Status: fixed in 110.20 [Matthias] ---------------------------------------------------------------------- Number: 1462 Title: Error in "g" format handling Keywords: Format (SMLofNJ-LIB) Submitter: David McClain dmcclain@azstarnet.com Date: 12/12/98 Version: 110.0.3 System: x86 Windows NT 4.0 sr 3 (build 1381) Subsystem: SML/NJ Library Severity: minor Problem: Machine and OS Independent: The handling of the "%g" format code for reals incorrectly omits the decimal point, so that, e.g., Format.format "%g" [Format.REAL 1.2E8] ---> 12e08. It's relatively simple to fix the omission in the "format" function, in module Format.sml. Code: See above... Transcript: see above... Comments: None. But, NICE WORK! Please keep it up!! Fix: fun format s = let val fmts = compileFormat s fun doField (flags, wid, ty, arg) = let fun padFn s = (case (#ljust flags, wid) of (_, NoPad) => s | (false, Wid i) => padLeft(s, i) | (true, Wid i) => padRight(s, i) (* end case *)) fun zeroPadFn (sign, s) = (case wid of NoPad => raise BadFormat | (Wid i) => zeroLPad(s, i - (String.size sign)) (* end case *)) fun negate i = ((PosInt(~i)) handle _ => MaxInt) fun doSign i = (case (i < 0, #sign flags, #neg_char flags) of (false, AlwaysSign, _) => ("+", PosInt i) | (false, BlankSign, _) => (" ", PosInt i) | (false, _, _) => ("", PosInt i) | (true, _, TildeSign) => ("~", negate i) | (true, _, _) => ("-", negate i) (* end case *)) fun doRealSign sign = (case (sign, #sign flags, #neg_char flags) of (false, AlwaysSign, _) => "+" | (false, BlankSign, _) => " " | (false, _, _) => "" | (true, _, TildeSign) => "~" | (true, _, _) => "-" (* end case *)) fun doExpSign (exp, isCap) = let val e = if isCap then "E" else "e" fun mkExp e = zeroLPad(Int.toString e, 2) in case (exp < 0, #neg_char flags) of (false, _) => [e, mkExp exp] | (true, TildeSign) => [e, "~", mkExp(~exp)] | (true, _) => [e, "-", mkExp(~exp)] (* end case *) end fun octal i = let val (sign, i) = doSign i val sign = if (#base flags) then sign^"0" else sign val s = intToOctal i in if (#zero_pad flags) then sign ^ zeroPadFn(sign, s) else padFn (sign ^ s) end fun decimal i = let val (sign, i) = doSign i val s = intToStr i in if (#zero_pad flags) then sign ^ zeroPadFn(sign, s) else padFn (sign ^ s) end fun hexidecimal i = let val (sign, i) = doSign i val sign = if (#base flags) then sign^"0x" else sign val s = intToHex i in if (#zero_pad flags) then sign ^ zeroPadFn(sign, s) else padFn (sign ^ s) end fun capHexidecimal i = let val (sign, i) = doSign i val sign = if (#base flags) then sign^"0X" else sign val s = intToHeX i in if (#zero_pad flags) then sign ^ zeroPadFn(sign, s) else padFn (sign ^ s) end in case (ty, arg) of (OctalField, LINT i) => octal i | (OctalField, INT i) => octal(Int.toLarge i) | (IntField, LINT i) => decimal i | (IntField, INT i) => decimal(Int.toLarge i) | (HexField, LINT i) => hexidecimal i | (HexField, INT i) => hexidecimal(Int.toLarge i) | (CapHexField, LINT i) => capHexidecimal i | (CapHexField, INT i) => capHexidecimal(Int.toLarge i) | (CharField, CHR c) => padFn(String.str c) | (BoolField, BOOL false) => padFn "false" | (BoolField, BOOL true) => padFn "true" | (StrField, ATOM s) => padFn(Atom.toString s) | (StrField, STR s) => padFn s | (RealField{prec, format=F_Format}, REAL r) => let val {sign, mantissa} = RealFormat.realFFormat(r, prec) val sign = doRealSign sign in if ((prec = 0) andalso (#base flags)) then padFn(concat[sign, mantissa, "."]) else padFn(sign ^ mantissa) end | (RealField{prec, format=E_Format isCap}, REAL r) => let val {sign, mantissa, exp} = RealFormat.realEFormat(r, prec) val sign = doRealSign sign val expStr = doExpSign(exp, isCap) in if ((prec = 0) andalso (#base flags)) then padFn(concat(sign :: mantissa :: "." :: expStr)) else padFn(concat(sign :: mantissa :: expStr)) end | (RealField{prec, format=G_Format isCap}, REAL r) => let val prec = if (prec = 0) then 1 else prec val {sign, whole, frac, exp} = RealFormat.realGFormat(r, prec) val sign = doRealSign sign val expStr = (case exp of SOME e => doExpSign(e, isCap) | NONE => []) val num = if (#base flags) then let val diff = prec - ((size whole) + (size frac)) in if (diff > 0) then zeroRPad(frac, (size frac)+diff) else frac end else if (frac = "") then "" else ("." ^ frac) in (* Here is a cheap fix, but it will conflict with the line above... *) padFn(concat(sign::whole::"."::frac::expStr)) end | (_, LEFT(w, arg)) => let val flags = { sign = (#sign flags), neg_char = (#neg_char flags), zero_pad = (#zero_pad flags), base = (#base flags), ljust = true, large = false } in doField (flags, Wid w, ty, arg) end | (_, RIGHT(w, arg)) => doField (flags, Wid w, ty, arg) | _ => raise BadFmtList (* end case *) end fun doArgs ([], [], l) = SS.concat(rev l) | doArgs ((Raw s)::rf, args, l) = doArgs(rf, args, s::l) | doArgs (Field(flags, wid, ty)::rf, arg::ra, l) = doArgs (rf, ra, SS.all (doField (flags, wid, ty, arg)) :: l) | doArgs _ = raise BadFmtList in fn args => doArgs (fmts, args, []) end (* format *) Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1463 Title: Broken ARRAY2 Code Keywords: indexing/projection Submitter: David McClain dmcclain@azstarnet.com Date: 12/13/98 Version: 110.0.3 System: x86 Windows NT 4.0 r 3 (build 1381) Subsystem: SML basis library Severity: major Problem: Indexing for projection of rows works incorrectly. Code: structure A2 = Array2; val x = A2.tabulate A2.RowMajor (2,3,fn (r,c) => 10 * r + c); A2.row(x,0); --> val it = #[0,1] : int vector (* Nope! *) A2.row(x,1); --> val it = #[10,11] : int vector (* ditto *) A2.column(x,0); --> val it = #[0,10] : int vector (* these are okay *) A2.column(x,1); --> val it = #[1,11] : int vector A2.column(x,2); --> val it = #[2,12] : int vector Transcript: see above Comments: Looks like I need to implement my own... Fix: This one is a bit beyond me at this early time... Test: bug1463.1.sml Owner: jhr, Emden Status: fixed in 110.9.1 and in 110.0.4 [jhr] ---------------------------------------------------------------------- Number: 1464 Title: unnecessary instantiation of local nongeneralized types Keywords: type checking, generalization Submitter: Matthias Blume Date: 12/16/98 Version: 110.x System: - Severity: minor Problem: It think it is unnecessary to instantiate any non-generalized type vars that belong to definitions between "local" and "in". Those definitions never escape to the top level (which is the only place where they would hurt). Code: Transcript: Comments: [dbm] Declarations in local part of a local dec should be treated the same as the declarations in let expressions. Fix: Test: Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1465 Title: Type variables not as general as Definition. Keywords: type variable Submitter: Stephen Weeks Date: 12/17/98 Version: Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 System: x86-linux Severity: Problem: The class of type variables allowed is not as general as allowed in the Definition. For example, I believe the following four declarations are valid. Code: type '' t = int type '_ t = int type ''' t = int type ''1 t = int Transcript: Comments: Fix: In ml.lex, the case for type variables should be changed from: "'"("'"?)("_"|{num})?{id} to the following: "'"{idchars}* Test: bug1465.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1466 Title: GC signal never sent Keywords: runtime, GC Submitter: Roland McGrath Date: 12/16/1998 Version: 110.8 System: x86-linux Severity: minor Problem: The Signals.sigGC signal is never in fact raised. Furthermore, in fixing this I discovered the additional bug that any ML signal causes an extra unwarranted minor GC. In the case of the GC signal, this iterates infinitely, running the sigGC handler function repeatedly and nothing else. Code: (* set the GC handler to print so we can tell *) open Signals; setHandler (sigGC, HANDLER (fn (_,_,k) => (print "foobar\n"; k))); (* force a collection *) SMLofNJ.Internals.GC.doGC 99; (* it should have printed "foobar\n", but it didn't *) Transcript: Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 [full] val use = fn : string -> unit - open Signals; opening Signals eqtype signal datatype sig_action = DEFAULT | HANDLER of signal * int * unit ?.cont -> unit ?.cont | IGNORE val listSignals : unit -> signal list val toString : signal -> string val fromString : string -> signal option val setHandler : signal * sig_action -> sig_action val overrideHandler : signal * sig_action -> sig_action val inqHandler : signal -> sig_action datatype sigmask = MASK of signal list | MASKALL val maskSignals : sigmask -> unit val unmaskSignals : sigmask -> unit val masked : unit -> sigmask val pause : unit -> unit val sigINT : signal val sigALRM : signal val sigTERM : signal val sigGC : signal - setHandler (sigGC, HANDLER (fn (_,_,k) => (print "foobar\n"; k))); val it = IGNORE : sig_action - SMLofNJ.Internals.GC.doGC 99; GC #1.1.1.1.1.11: (62 ms) val it = () : unit Comments: For some reason I have not ascertained, there are always at least two collections at once (the sigGC handler is always called at least twice). I don't think this is right, but two is closer to one than zero is by my reckoning. [jhr, 12/16/98] The GC signal got disabled a while back when I was fixing some problems with the signal handlers. It will be fixed in the new run-time system that we are working on (should be out in Feb 1999). GC signals should not be generated for minor collections, so the infinite loop that you encountered can be avoided. [Roland McGrath] > Firstly, do you agree with my analysis that handling an ML signal induces a > spurious minor collection and my fix to avoid that by restoring the real > limit pointer? In my view it is that bug, not signalling on minor > collections, that is responsible for the infinite loop. (And, harmless > though it may be, I would like to avoid the extra unwarranted > collection--when we have clock ticks arriving as ML signals, the cost of > the extra collection might become a practical concern.) [jhr] In the earlier implementation, where GC signals were actually generated, I chose to only generate them for "major" collections. Minor collections happen at a very high rate, and it seems excessive to generate a signal for each one. As far as the extra collection goes, avoiding it in your situation is probably worth while, but I don't think that it is worth fixing for the current run-time. I'll try to avoid it in the new run-time. [Roland McGrath] > Secondly, I think I really would like to have my signal handler run for > minor collections. I am interested in your opinion on this. My use of the > GC signal is, along with weak pointers, to implement finalizers for a > special kind of object (i.e. an ML record held weakly is logically keeping > alive a foreign object that must be explicitly deallocated). These objects > have extent appropriate for minor collections (they are a kind of call > frame). As they may be created and become garbage very quickly, I am > concerned about delaying their collection until a major collection. (I can > work around the problem by catching an actual resource shortage, forcing a > major collection (with SMLofNJ.Internals.GC.doGC), and retrying the > allocation, before diagnosing it as an out-of-resource exception.) [jhr] In the new collector, we directly support finalized objects (using Dybvig's guardian scheme), but we do not finalize objects on minor collections. In a copy collected system, finalization should never be relied on to free objects in a timely fashion. You will need some backup to force finalization (by doing GC), when a scare resource is exhausted. Handling weak pointers and finalized objects requires extra overhead, which I'd like to avoid in minor collections. Fix: The following patch to the runtime does three things: 1 (gc/call-gc.c). Call GCSignal at the end of InvokeGC. I don't know if this is the right place to call it, but it's the obvious one. It delivers the signal to whichever vproc invoked the GC, which seems correct. 2 (kernel/run-ml). When handling an ML signal, reset the limit pointer to the real heap limit if we do not perform a GC. This should probably go in a subroutine in gc/*.c, and I don't think it dtrt for MP. 3 (mach-dep/signal-util.c). I don't think this was actually necessary to fix anything, since numPendingSigs and numPendingSysSigs are added together and the sum tested. But it just looked wrong to me. Index: smlnj/runtime/gc/call-gc.c diff -c smlnj/runtime/gc/call-gc.c:1.1.1.1 smlnj/runtime/gc/call-gc.c:1.2 *** smlnj/runtime/gc/call-gc.c:1.1.1.1 Tue Oct 6 18:05:08 1998 --- smlnj/runtime/gc/call-gc.c Wed Dec 16 16:50:48 1998 *************** *** 230,235 **** --- 230,237 ---- ASSIGN(ProfCurrent, PROF_RUNTIME); + GCSignal (msp->ml_vproc); + } /* end of InvokeGC */ Index: smlnj/runtime/kernel/run-ml.c diff -c smlnj/runtime/kernel/run-ml.c:1.1.1.2 smlnj/runtime/kernel/run-ml.c:1.2 *** smlnj/runtime/kernel/run-ml.c:1.1.1.2 Tue Oct 6 18:10:03 1998 --- smlnj/runtime/kernel/run-ml.c Wed Dec 16 16:50:48 1998 *************** *** 17,22 **** --- 17,23 ---- #include "c-library.h" #include "profile.h" #include "gc.h" + #include "../gc/heap.h" /* XXX for HEAP_LIMIT */ /* local functions */ PVT void UncaughtExn (ml_val_t e); *************** *** 90,95 **** --- 91,103 ---- /* check for GC */ if (NeedGC (msp, 4*ONE_K)) InvokeGC (msp, 0); + else + /* Reset the limit pointer since no actual GC happened. + Otherwise, we would do a spurious GC before handling + the signal (which is especially problematical for + the GC signal!). */ + msp->ml_limitPtr = HEAP_LIMIT(msp->ml_heap); + /* invoke the ML signal handler */ ChooseSignal (vsp); msp->ml_arg = MakeHandlerArg (msp, sigh_resume); Index: smlnj/runtime/mach-dep/signal-util.c diff -c smlnj/runtime/mach-dep/signal-util.c:1.1.1.1 smlnj/runtime/mach-dep/signal-util.c:1.2 *** smlnj/runtime/mach-dep/signal-util.c:1.1.1.1 Tue Oct 6 18:05:10 1998 --- smlnj/runtime/mach-dep/signal-util.c Wed Dec 16 16:50:48 1998 *************** *** 31,39 **** vsp->vp_sigCode = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].sigNum; vsp->vp_sigCount = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].count; if (IS_SYSTEM_SIG(vsp->vp_sigCode)) ! vsp->vp_numPendingSigs -= vsp->vp_sigCount; else ! vsp->vp_numPendingSysSigs -= vsp->vp_sigCount; /* advance the pending queue */ if ((--vsp->vp_numInQ == 0) || (++vsp->vp_nextPendingSig == NUM_SIGS)) --- 31,39 ---- vsp->vp_sigCode = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].sigNum; vsp->vp_sigCount = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].count; if (IS_SYSTEM_SIG(vsp->vp_sigCode)) ! vsp->vp_numPendingSysSigs -= vsp->vp_sigCount; else ! vsp->vp_numPendingSigs -= vsp->vp_sigCount; /* advance the pending queue */ if ((--vsp->vp_numInQ == 0) || (++vsp->vp_nextPendingSig == NUM_SIGS)) Test: - Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1467 Title: Looping functions fail in FLINT Keywords: FLINT Submitter: Allen Leung leunga@cs.nyu.edu Date: 12/30/98 Version: 110.11 System: Any/All Any Unix Subsystem: SML compiler Severity: minor Problem: FLINT fails on functions such as fun loop() = loop() or fun loop i = loop i Note: The previous bug reported by me is actually caused by this simple problem. Please discard previous report. Code: Transcript: - fun loop() = loop(); looking up unbound v27{3,3} while in fcontract phase uncaught exception IntmapF raised at: ../comp-lib/intmapf.sml:199.25-199.32 FLINT/opt/fcontract.sml:327.13 FLINT/main/flintcomp.sml:146.13 - fun loop i = loop i; while in reify phase uncaught exception RecoverLty raised at: ../comp-lib/intmap.sml:28.41-28.44 FLINT/main/flintcomp.sml:146.13 Comments: [jhr, 12/30/98] It appears that this bug was introduced in 110.10. Fix: Test: Owner: Zhong Status: open ---------------------------------------------------------------------- Number: 1468 Title: ccalls crashes on Cfunction(fn _ => Cvoid) Keywords: runtime, ccalls Submitter: Roland McGrath Date: 12/30/1998 Version: 110.8 System: x86-linux Severity: minor Problem: An ML function called from C that returns Cvoid crashes the runtime. Code: Transcript: Comments: I did not provide source or transcript because it requires a runtime with ccalls compiled in and hacked with some C function available via CCalls that makes a callback to ML. Passing such a function `Cfunction(fn _ => Cvoid)' will crash the runtime when that ML function attempts to return to C. Fix: Patch to runtime/c-libs/smlnj-ccalls/c-calls-fns.c follows. Index: c-calls-fns.c =================================================================== RCS file: /projects/express/cvsroot/smlnj/runtime/c-libs/smlnj-ccalls/c-calls-fns.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -b -p -r1.2 -r1.3 --- c-calls-fns.c 1998/12/16 20:00:01 1.2 +++ c-calls-fns.c 1998/12/30 19:43:18 1.3 @@ -178,6 +178,12 @@ PVT Word_t convert_result(ml_state_t *ms char *t = chp->rettype; int err; + if (*t == 'V') + /* The return type is void, meaning val must be Cvoid + * and our return value will be ignored by the C caller. + */ + return 0; + /* front-end of interface guarantees that ret is a valid * return value for a C function: Word_t or some pointer */ Test: * Owner: Lorenz, Riccardo Status: open ---------------------------------------------------------------------- Number: 1469 Title: Integer assignment should be unboxed assign Keywords: FLINT convert Submitter: Allen Leung leunga@cs.nyu.edu Date: 12/30/98 Version: 110.11 System: Any/All Any Unix Subsystem: SML compiler Severity: major Problem: Integer assignment should use unboxedassign. In 110.11 storelist maintainence instructions are generated for assignments such as x := y where x : int ref Note: mandelbrot runs about twice as slow on the HP and 1/3 slower on the sparc when compared to 110.9.1 Code: Compiler.Control.CG.printit := true; val x = ref 0; fun f y = x := y; Transcript: ************************************************* v481(v497[PV],v496[PV],v495[C],v494[PV],v493[PV],v492[PV],v491[I]) = v496.1 -> v498[PV] assign(v498,v491) v495(v495,v494,v493,v492,(I)0) ************************************************* Comments: [jhr, 12/30/98] This one is probably my fault. When I put in the new array representation support, I had to make := and Array.update be different (the Array.update has an extra level of indirection). I guess that I must have broken the type-based specialization. [jhr, 12/30/98] I just took a look at the code (from the 110.11 sources), and I'm not sure why the optimization isn't being done. Here is the code from FLINT/cpsopt/contract.sml: fun setter (P.update, [_, _, INT _]) = P.unboxedupdate | setter (P.update, [_, _, REAL _]) = P.boxedupdate | setter (P.update, [_, _, STRING _]) = P.boxedupdate | setter (P.update, [_, _, VAR v]) = (case #info(get v) of (FNinfo _) => P.boxedupdate | (RECinfo _) => P.boxedupdate | (OFFinfo _) => P.boxedupdate | _ => P.update (* end case *)) | setter (P.assign, [_, INT _]) = P.unboxedassign | setter (i, _) = i It looks like assignment of int refs should be translated to an unboxedassign. [Zhong, 12/30/98] This is not the right place. To fix it, you need to add a new "UNBOXEDASSIGN" primop into the FLINT/kernel/primop.{sig,sml}. Then add the following case to the "classPrim" function in FLINT/reps/wrapping.sml: | (PO.ASSIGN, [tc]) => (* special *) let val np = if LT.tc_upd_prim tc = PO.UNBOXEUPDATE then PO.UNBOXEDASSIGN else p in ((d, np, lt, ts), false, false) end Fix: [jhr, 12/30/98] I've put in a fix (supplied by Zhong) for this bug and it seems to work (at least the cps says "unboxedassign"). I'll commit these changes for 110.12; note that the pickler has changed to handle the new UNBOXEDASSIGN primop. Test: bug1469.1.sml Owner: jhr Status: fixed in 110.12 ---------------------------------------------------------------------- Number: 1470 Title: compilation blowup (in FLINT?) Keywords: compiler performance Submitter: Daniel Wang Date: 9/10/98 Version: 110.0.3 System: - Severity: major Problem: Should I expect this to elaborate in a resonable amount of time for 110.0.3. The signature elaborates in almost no time, but when elaborating the structure things get bogged down. The FLINT types should be able to represent this type efficiently right? So is this a performance bug in the elaborator? When sml gets bogged down elaborating the structure it's space usage seems to be constant. Code: signature PRIMS = sig datatype ('a,'b) sum = L of 'a | R of 'b type b1 = unit type b2 = (b1,b1) sum type b3 = (b2,b2) sum type b4 = (b3,b3) sum type b5 = (b4,b4) sum type b6 = (b5,b5) sum type b7 = (b6,b6) sum type b8 = (b7,b7) sum type b9 = (b8,b8) sum type b10 = (b9,b9) sum type b11 = (b10,b10) sum type b12 = (b11,b11) sum type b13 = (b12,b12) sum type b14 = (b13,b13) sum type b15 = (b14,b14) sum type b16 = (b15,b15) sum type b17 = (b16,b16) sum type b18 = (b17,b17) sum type b19 = (b18,b18) sum type b20 = (b19,b19) sum type b21 = (b20,b20) sum type b22 = (b21,b21) sum type b23 = (b22,b22) sum type b24 = (b23,b23) sum type b25 = (b24,b24) sum type b26 = (b25,b25) sum type b27 = (b26,b26) sum type b28 = (b27,b27) sum type b29 = (b28,b28) sum type b30 = (b29,b29) sum type b31 = (b30,b30) sum type b32 = (b31,b31) sum end structure Prims :> PRIMS = struct datatype ('a,'b) sum = L of 'a | R of 'b type b1 = unit type b2 = (b1,b1) sum type b3 = (b2,b2) sum type b4 = (b3,b3) sum type b5 = (b4,b4) sum type b6 = (b5,b5) sum type b7 = (b6,b6) sum type b8 = (b7,b7) sum type b9 = (b8,b8) sum type b10 = (b9,b9) sum type b11 = (b10,b10) sum type b12 = (b11,b11) sum type b13 = (b12,b12) sum type b14 = (b13,b13) sum type b15 = (b14,b14) sum type b16 = (b15,b15) sum type b17 = (b16,b16) sum type b18 = (b17,b17) sum type b19 = (b18,b18) sum type b20 = (b19,b19) sum type b21 = (b20,b20) sum type b22 = (b21,b21) sum type b23 = (b22,b22) sum type b24 = (b23,b23) sum type b25 = (b24,b24) sum type b26 = (b25,b25) sum type b27 = (b26,b26) sum type b28 = (b27,b27) sum type b29 = (b28,b28) sum type b30 = (b29,b29) sum type b31 = (b30,b30) sum type b32 = (b31,b31) sum end Comments: Fix: Test: Owner: dbm, Zhong Status: open ---------------------------------------------------------------------- Number: 1471 Title: interrupt ignored in heap image created in background Keywords: interrupt, signal handling Submitter: Matthias Blume Date: 10/20/98 Version: 110.9.1 System: - Severity: minor Problem: I just ran into a nasty little problem. (I'd rate it a "minor" problem, but maybe it can be fixed.) When I installed 110.9.1 over here, I wanted to capture an install log. So I did config/install.sh >logfile 2>&1 and since this meant I wouldn't be able to see anything anyway, I thought I _SEND THIS COMMAND INTO THE BACKGROUND_ ... config/install.sh >logfile 2>&1 & But sending a command into the background like this means that SIGINT gets disabled. Somehow, ML inherits the disabled interrupt, which means that the resulting heap image will ignore control-C. Now, the obvious workaround is not to do what I did, but perhaps there is a way of avoiding this potential problem. (?) Comments: [jhr] This is the desired semantics under Unix. Background processes are started with SIGINT ignored, and it is bad form to change that (you don't want a ^C to the forground to kill all of your backgroup processes do you?). [Matthias] You misunderstood my desire: I don't want to have signals turned back on while "makeml" (or "config/install.sh") is running. After all, I had sent it to the background because I didn't want to be bothered by it. The problem is that with the resulting heap-image, which will run later in a separate process and _not_ in the background, interrupts are _still_ disabled. [jhr] I see. Looking at the code, I think that this problem may be fixed by changing the "AtInit" cleaner for signals from resetSigTbl to initSigTbl, but this means that there is no persistence of signal handlers across exportML, which may cause other problems. [jhr, 2/8/99] This is a feature, not a bug. [Matthias, 4/20/99] I don't agree with John's comment that bug 1471 be not a bug. Why? What's the point of inheriting (via the heap image) the ignored signals of a different process which perhaps ran a long time ago, on a different machine, perhaps in the background, etc.? I would like to submit the following view: 1. Signals that are inherited by the usual Unix semantics (via fork and exec) should be considered part of the process environment (together with the stuff that one can access via OS.Process.getEnv). This process environment will be set up anew every time we start a new SML/NJ process and does not get propagated via heap images. 2. Signals that have actively been set by the process are no longer considered part of the process environment but part of the process state itself. Those signals will get propagated via heap images. I can see that this "part of the environment"/"part of the process state" dichotomy may require some additional hair to be introduced into the implementation of signal. However, I find the above intuitive and more consistent than what we have now. Fix: Test: Owner: jhr Status: not a bug??? ---------------------------------------------------------------------- Number: 1472 Title: datatype involving real are treated as equality types Keywords: equality types, datatypes, real Submitter: Nevin Heintze Date: 10/23/98 Version: 110.9.1 System: - Severity: major Problem: With the definition: datatype expression = RealConst of real | Cast of ctype * expression and ctype = Struct of declarator and declarator = Array_d of expression the frontend allows declarator to be treated as an equality type, but it should not. For example: (fn (x:declarator, y) => (x = y)); gives val it = fn : declarator * declarator -> bool whereas (fn (x:Real.real, y) => (x = y)) gives an error operator domain: ''Z * ''Z operand: real * 'Y in expression: x = y However, both should give an error. Code: Transcript: Comments: Fix: Test: bug1472.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1473 Title: weak pointer to a string causes core dump Keywords: weak pointers Submitter: Daniel Wang Date: 12/2/98 Version: 110.9.1 System: ? Severity: minor Problem: Should this be broken? Is there a work around... (LiftLitteral flag???) Code: Transcript: Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 val use = fn : string -> unit - val x = SMLofNJ.Weak.weak' "this is a string"; val x = - : ?.Weak.weak' - SMLofNJ.Internals.GC.doGC 100; GC #1.1.1.1.1.5: /home/danwang/SMLNJ/110.9.1/dist/bin/sml: Fatal error -- weak big object Process sml exited abnormally with code 1 Comments: [Matthias, 12/3/98] Can't you wrap a ref around your string? In any case, weak pointers to state-free objects ("values") are semantically troublesome. (See the discussion on the SML/NJ web pages.) Your safest bet is to make sure you only create weak pointers to things like references. As a side benefit this would work around the bug (feature?) that you described above. [jhr, 2/8/99] This should be fixed with the new literal representation. Fix: Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1474 Title: Uncaught exception Compile "translate failed" Keywords: CM redundant match Submitter: Elsa L. Gunter elsa@research.bell-labs.com Date: 01/07/99 Version: 110.9.1 System: x86 Linux Subsystem: Compilation manager (CM) Severity: minor Problem: When CM encounters a bad pattern where the match is redundant, in addition to reporting an error, it raises uncaught exception Compile: "translate failed" Code: (* sources.cm *) Group is translate_bug.sml (*--------------------------------------------------------------*) (* translate_bug.sml *) structure C = struct datatype t = A | B val f = fn A => () | A => () end Transcript: % sml Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 val use = fn : string -> unit - CM.make(); [starting dependency analysis] [scanning sources.cm] [checking CM/x86-unix/sources.cm.stable... not usable] [parsing translate_bug.sml] [dependency analysis completed] [compiling translate_bug.sml -> CM/x86-unix/translate_bug.sml.bin] translate_bug.sml:4.10-4.30 Error: match redundant and nonexhaustive A => ... --> A => ... uncaught exception Compile: "translate failed" raised at: TopLevel/batch/binfile.sml:466.38-466.65 ../cm/sched/recompile.sml:203.38-203.41 Comments: If you use the file translate_bug.sml instead of doing CM.make, the exception is not raised. Fix: Test: Owner: Matthias Status: fixed in 110.20 [Matthias] ---------------------------------------------------------------------- Number: 1475 Title: CM uncaught exception Compile elaborate Keywords: CM pattern matching Submitter: Elsa L. Gunter elsa@research.bell-labs.com Date: 01/07/99 Version: 110.9.1 System: x86 Linux Subsystem: Compilation manager (CM) Severity: minor Problem: When CM encounter a bad pattern having a constant constructor applied to an arguement, in addition to giving and error, it raises an uncaught exception Compile: "elaborate failed" Code: (* sources.cm *) Group is elaborate_bug.sml (*------------------------------------------------------------------*) (* elaborate_bug.sml *) structure C = struct datatype t = A val f = fn A a => () end Transcript: % sml Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 val use = fn : string -> unit - CM.make(); [starting dependency analysis] [scanning sources.cm] [checking CM/x86-unix/sources.cm.stable... not usable] [parsing elaborate_bug.sml] [Creating directory CM/DEPEND ...] [dependency analysis completed] [compiling elaborate_bug.sml -> CM/x86-unix/elaborate_bug.sml.bin] elaborate_bug.sml:4.10-4.22 Error: constant constructor applied to argument in pattern:A uncaught exception Compile: "elaborate failed" raised at: TopLevel/batch/binfile.sml:466.38-466.65 ../cm/sched/recompile.sml:203.38-203.41 Comments: When elaborate_bug.sml is used instead of being loaded via CM.make, the uncaught exception does not occur. Fix: Test: Owner: Matthias Status: fixed in 110.20 [Matthias] ---------------------------------------------------------------------- Number: 1476 Title: Missing operation in WORD Keywords: WORD ~ Submitter: Henry Cejtin henry@research.nj.nec.com Date: 11/02/98 Version: 1108 System: Any/All Any Unix Subsystem: SML basis library Severity: Problem: This is not a bug as much as a missing operation. The WORD signature should have the ~ operation defined in it. words represent integers modulo 2^?, so negation makes perfect sense. It is currently available via 0w0 - ? but should be directly supported. Comments: A new feature request. Fix: Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1477 Title: assembler syntax nits for X86.prim.asm Keywords: runtime, asm, X86.prim.asm Submitter: Roland McGrath Date: 11/18/1998 Version: 110.8 System: x86-linux, x86-freebsd, x86-netbsd Severity: cosmetic Problem: assembler on these system wants * before register in indirect jump Code: n/a Transcript: n/a Comments: The GNU assembler, which is used on all the free x86 operating systems, wants a * prefix on register names in indirect jmp instructions. Without the * it generates a warning, but to my knowledge still assembles the instructions correctly. The X86.prim.asm code allows for this syntax, by use of the `via' macro. My patch defines this macro to * for systems that use the GNU assembler, and fixes one instruction missing a "via" and one instruction where an inappropriate "via" was inserted. The patch includes a check for OPSYS_OSKIT, which is a new symbol for our research project's (unpublished) system, so you might not want to include that symbol in the check. Fix: patch to mach-dep/X86.prim.asm attached below Index: X86.prim.asm =================================================================== RCS file: /projects/express/cvsroot/smlnj/runtime/mach-dep/X86.prim.asm,v retrieving revision 1.1.1.3 retrieving revision 1.5 diff -u -b -p -r1.1.1.3 -r1.5 --- X86.prim.asm 1998/10/06 22:21:35 1.1.1.3 +++ X86.prim.asm 1998/11/17 19:51:53 1.5 @@ -101,7 +101,13 @@ #define PSEUDOREG_1 vreg12 #define PSEUDOREG_2 vreg13 +#if (defined(OPSYS_LINUX) || \ + defined(OPSYS_FREEBSD) || defined(OPSYS_NETBSD) || \ + defined(OPSYS_OSKIT)) +#define via * +#else #define via +#endif DATA @@ -173,7 +179,7 @@ LABEL(CSYM(ML_X86Frame)) /* ptr to the m jb 9f; \ lea 1b, temp; /* temp holds resume address */ \ movl IMMED(maskval), mask; \ - jmp via CSYM(saveregs); \ + jmp CSYM(saveregs); \ 9: /**********************************************************************/ @@ -533,7 +539,7 @@ restore_and_jmp_ml: jmp_ml: movl PCOffMSP(temp),temp cmpl limitptr, allocptr - jmpl temp /* Jump to ML code. */ + jmpl via temp /* Jump to ML code. */ pending: cmpl IMMED(0),InSigHandlerOffVSP(vsp) /* Currently handling signal? */ Test: - Owner: jhr Status: fixed in 110.0.4 ---------------------------------------------------------------------- Number: 1478 Title: Fatal Error win32:fault_handler Keywords: Windows Submitter: Adam Maciak maciak@mu-luebeck.de Date: 01/15/99 Version: 110 System: Other (describe below) Windows 95 a Subsystem: SML compiler Severity: critical Problem: By typing "use filename" SML closed, because of this bug: Fatal Error -- win32:fault:handler: unexpected fault @0x1682clf, code = 0xc0000005 Code: ? Transcript: [custon] C:\sml\bin>sml-cm.bat Standart ML of new Jersey 110.0.3, January 30,1998 [CM&CMB] - use "37.ml"; [opening 37.ml] val lexOrd = fn: char list * char list -> bool c:\SML\BIN~1\RUNX86~1.EXE: Fatal Error -- win32:fault_handler ... Comments: After installing Quicktime, SML crashes each time I want to "use" a file. I have reinstalled SML and Windows many times but the problem could not be solved. [Lorenz, 1/15/99] Could you send the smallest piece of source you can make that exhibits this problem? Do you have an NT system to test this on? Since NT has memory protection and 95 does not, it would indicate if a bug in SML/NJ (or elsewhere, e.g. in Quicktime) is stomping on the address space. Fix: Uninstalling Quicktime solved the problem a little bit, that means, SML crashes not every time i type "use filename", but every 10th - 20th time. Test: Owner: Lorenz, Riccardo Status: open ---------------------------------------------------------------------- Number: 1479 Title: failure to run under IRIX 6.5 Keywords: IRIX Submitter: cporter@sgi.com Date: 1/18/99 Version: 110.0.3? System: mipseb/IRIX 6.5 Severity: major Problem: Compiler fails to build under IRIX 6.5. Comments: Fix: [jhr, 3/15/99] The fix turns out to be quite simple: add "-o32" to the definition of AS in src/runtime/objs/mk.mipseb-irix6 (line 10) and then run the build again. [DBM: is the fix implemented in current working versions?] Test: Owner: jhr? Status: fixed in 110.0.6 ---------------------------------------------------------------------- Number: 1480 Title: eXene unable to open display Keywords: eXene Submitter: Matthias Blume Date: 1/19/99 Version: 110.11 through 110.13 System: sparc Severity: major Problem: A sample program of mine (uses CML and eXene) is unable to open the X display. The exact same source code works under 110.9.1. Here is the error message that I am seeing (I tried with many different settings of the DISPLAY variable -- same error message every time): - Main.run(); eXene: unable to open display ":0.0" Address family not supported by protocol family [000005] ***** shutdown ***** val it = () : unit Transcript: Comments: Library sources that are missing in 110.13 were copied from 110.9.1. Should I be using newer ones from 110.10 or 110.11? [jhr, 1/25/99] My guess is that there is a use of arrays in the run-time system sockets library that didn't get changed to the new representations. It should be easy to track down and fix. Fix: Test: Owner: jhr Status: fixed in 110.19 ---------------------------------------------------------------------- Number: 1481 Title: Error: Compiler bug: EntityEnv: lookEP.1 Keywords: functors, modules Submitter: Romeo Dumitrescu, romeo@ifi.unibas.ch Date: 01/21/1999 Version: 110.0.3 System: sparc-solaris2.7 Severity: minor+ Problem: Compiler error when trying to make a structure from a functor that applies another, undefined functor. Code: signature SIG = sig val f : int -> int end functor Fun2() = struct structure F : SIG = Fun1() end structure S = Fun2() Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - use "bug.sml"; [opening bug.sml] bug.sml:8.22-8.28 Error: unbound functor: Fun1 Error: Compiler bug: EntityEnv: lookEP.1 Comments: This error message was already reported (bug 1317, version 109.33) in the context of missing signature declaration. Fixed in 109.35 Fix: Test: bug1481.1.sml Owner: dbm, Zhong Status: open ---------------------------------------------------------------------- Number: 1482 Title: core dump on x86, Alpha, mipseb Keywords: core dump Submitter: Andrew Bernard Date: 1/25/99 Version: 110.0.3 System: x86/Linux, alpha/unix Severity: critical Problem: I can consistently make the runtime in the 110.0.3 compiler seg fault with the attached piece of code. It appears to happen immediately, 100% of the time on x86/Linux and DEC Alpha. There's a transcript in the comment at the end of the code that shows how it can be reproduced. I thought I should bring this to your attention right away, since the code is rather prosaic and isn't monkeying around with any unsafe/system structures. I tried essentially the same thing by coding it directly (i.e. w/o the modules and the functor instantiation) and everything works fine, so it seems like the module structure is essential. Code: (* ----- nuke.sml ----- *) signature SUM = sig type type1 type type2 datatype t = Type1 of type1 | Type2 of type2 end signature SET = sig type element type t val empty: t val extend: t * element -> t end structure UnitSet = struct type element = unit type t = bool val empty = false fun extend(_, ()) = true end functor SumSet ( structure Sum: SUM structure Set1: SET where type element = Sum.type1 structure Set2: SET where type element = Sum.type2 ) :> SET where type element = Sum.t = struct type element = Sum.t type t = Set1.t * Set2.t val empty = (Set1.empty, Set2.empty) fun extend((set1, set2), Sum.Type1 element1) = (Set1.extend(set1, element1), set2) | extend((set1, set2), Sum.Type2 element2) = (set1, Set2.extend(set2, element2)) end structure UnitUnit = struct type type1 = unit type type2 = unit datatype t = Type1 of type1 | Type2 of type2 end structure UnitUnitSet = SumSet ( structure Sum = UnitUnit structure Set1 = UnitSet structure Set2 = UnitSet ) Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - use "nuke.sml"; [opening nuke.sml] GC #0.0.0.0.1.9: (0 ms) signature SUM = sig type type1 type type2 datatype t = Type1 of type1 | Type2 of type2 end signature SET = sig type element type t val empty : t val extend : t * element -> t end structure UnitSet : sig type element = unit type t = bool val empty : bool val extend : 'a * unit -> bool end functor SumSet : structure UnitUnit : sig datatype t = Type1 of type1 | Type2 of type2 type type1 = unit type type2 = unit end structure UnitUnitSet : SET? val it = () : unit - UnitUnitSet.extend(UnitUnitSet.empty, UnitUnit.Type1()); /usr/local/lib/sml/110b/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x40d1f34e Comments: [Lal, 1/25/99] This does not appear on the alpha using our latest working version, 110.12. [Lal, 2/5/99] It also appears on the mips (110.0.3) as well, and would therefore appear to be machine independent. [dbm, 2/21/01] George Russell provided alternative code for the hyperbolic functions based on Netlib C implementation (GNU GPL'd). See Dev/bugs/1482. Fix: May have been fixed since 110.0.3. In 110.33, works under x86-linux, alpha-dunix, sparc-solaris8. [dbm, 6/11/01] Test: bug1482.1.sml Owner: Zhong, Lal? Status: fixed in 110.33 ---------------------------------------------------------------------- Number: 1483 Title: confusing type error messages (literals, IntInf) Keywords: type error messages Submitter: Elsa Gunter Date: 1/28/99 Version: 110.x System: - Severity: major Problem: In error messages, different types are printed with the same name, so the type mismatch is not apparent. Code: Transcript: Having open IntInf, and not having coerced the numerals into IntInf.int. ../State/prelims.sml:87.16-89.34 Error: operator and operand don't agree [literal] operator domain: int * int operand: int * int in expression: bits_rem - 1 ../State/prelims.sml:88.25-88.40 Error: operator and operand don't agree [literal] operator domain: int * int operand: int * int in expression: num_rem mod 2 GC #0.0.0.1.5.84: (20 ms) ../State/prelims.sml:87.16-89.34 Error: operator and operand don't agree [literal] operator domain: int * int operand: int * int in expression: num_rem div 2 Comments: [dbm, 2/5/99] The problem arrises from the fact that the type of the literal integers (e.g. "1", "2" in this case) is a special type variable representing the as yet unresolved type of the literal. Since this type can only resolve to Int31.int or Int32.int, it cannot match IntInf.int. The literal type variable prints as "int", as does IntInf.int, since IntInf has been opened. Fix: Make the type distinctions evident by some form of annotation. E.g. 'int[Lit] for the integer literal type variable. Test: bug1483.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1484 Title: reorder optimization disabled by FLINT Keywords: FLINT, reorder Submitter: Mads Tofte Date: 2/15/98 Version: 110.0.3 and later System: - Severity: major Problem: The optimization that reordered elements of a literal list (& vector?) to avoid building up a large number of temporaries during the list construction is now often disabled because type abstractions/applications in FLINT keep polymorphic literals (e.g. nil?) from being treated as pure, effect-free expressions whose evaluation can be reordered. This was noticed in the lexical analyzer for Cobol in Anno Domini. Comments: Fix: Test: Owner: Zhong (FLINT) Status: open ---------------------------------------------------------------------- Number: 1485 Title: quadratic(?) blowup compiling long sequence of val bindings Keywords: translate, FLINT Submitter: Konrad Slind Date: 1/8/99 Version: 110.0.3, 110.9.1 System: - Severity: major Problem: The compilation of a structure whose body consists of a sequence of simple val declarations appears to take time quadratic in the length of the declaration sequence. This was discovered by Konrad Slind when compiling machine generated "theory" files that contained (1) a long sequence of fairly simple val declarations (2) creation of a big vector containing the values from (1) (3) a large case statement. This bug report only addresses the compile time behavior of (1), but (2) seems to be nonlinear too. Konrad's files compiled very slowly under SML/NJ, about an order of magnitude slower than under Moscow ML. The slowdown was serious enough to drastically increase the time for building the Konrad's system relative to Moscow ML. Code: structure A = struct fun f _ = () val A1 = f 0; val A2 = f 0; . . . val A499 = f 0; val A500 = f 0; end Measurements: The following measurements compare several SML/NJ versions on a 501 declaration test case. vex: Ultrasparc 2, 200MHz; Solaris 2.5.1 slow1-500.sml (500 declarations, two structures) SML/NJ 0.93 ----------- 507 lines closure 20.661024s execution 22.457779s GC time 3.698343s total(usr) 26.230111s total(sys) 0.668325s code bytes: 66476 SML/NJ 110.0.3 -------------- Code Size 56888 Source Lines 502 Compiler 080 closure 27.47u 0.22s 0.78g Compiler 100 spill 5.33u 0.21s 0.62g TOTAL 34.96u 0.59s 1.74g SML/NJ 110.9.1 -------------- Code Size 52376 Source Lines 502 Compiler 080 closure 28.43u 0.09s 0.81g Compiler 120 cpsgen 15.75u 0.89s 4.81g TOTAL 45.47u 1.13s 5.81g SML/NJ 110.10 ------------- Code Size 52376 Source Lines 502 Compiler 080 closure 27.38u 0.23s 1.23g Compiler 120 cpsgen 16.58u 1.07s 4.75g TOTAL 45.39u 1.43s 6.23g The following measurements compare compilation times for structures of various sizes: 100, 200, 300, 400, 500, 1000, using SML/NJ 110.9.1. vex: Ultrasparc 2, 200MHz; Solaris 2.5.1 100 decls --------- Code Size 7376 Source Lines 102 Compiler 080 closure 0.33u 0.02s 0.01g Compiler 120 cpsgen 0.59u 0.06s 0.08g TOTAL 1.12u 0.09s 0.10g 200 decls --------- Code Size 14544 Source Lines 202 Compiler 080 closure 1.87u 0.01s 0.04g Compiler 120 cpsgen 2.27u 0.22s 0.55g TOTAL 4.61u 0.26s 0.65g 300 decls --------- Code Size 23344 Source Lines 302 Compiler 080 closure 6.70u 0.14s 0.46g Compiler 120 cpsgen 5.62u 0.45s 1.79g TOTAL 12.98u 0.69s 2.31g 400 decls --------- Code Size 32144 Source Lines 402 Compiler 080 closure 14.37u 0.21s 0.95g Compiler 120 cpsgen 10.98u 0.80s 3.99g TOTAL 26.28u 1.09s 5.07g 500 decls --------- Code Size 40944 Source Lines 502 Compiler 080 closure 30.66u 0.26s 1.12g Compiler 120 cpsgen 15.84u 1.11s 5.25g TOTAL 47.70u 1.48s 6.55g 1000 decls ---------- Error: Compiler bug: SparcCG.incOffset - spill area too small Comments: If the right-hand-sides of the val declarations are simplified to a constant (say "val ANNN = 0;", then compilation seems to be linear in the size of the structure. Looking at the CPS code generated for smaller examples, it is clear that terms quadratic in the size of the structure are being generated. The following code defines functions that can be used to generate test files of arbitrary sizes. (* mk_test_slow2 is like mk_test_slow, except that the function f * is defined in the main structure A *) fun mk_test_slow2 {file, length} = let val ostrm = TextIO.openOut file fun mk 0 = (TextIO.output(ostrm, "val A"^Int.toString length^" = f 0;\nend\n"); TextIO.flushOut ostrm; TextIO.closeOut ostrm) | mk n = (TextIO.output (ostrm,"val A"^Int.toString (length - n)^" = f 0;\n"); mk (n - 1)) in (TextIO.output (ostrm, "structure A = struct\nfun f _ = ()\n"); mk (length-1)) end; Fix: Test: (generated) Owner: FLINT, Zhong Status: open ---------------------------------------------------------------------- Number: 1486 Title: Math.pow gives questionable results Keywords: reals math Submitter: Geoff Berry gcb@cs.duke.edu Date: 02/11/99 Version: 110.0.3 System: x86 Linux 2.0.36 Subsystem: SML basis library Severity: major Problem: Math.pow returns results that aren't Real.== to the expected value. For example Real.== (Math.pow (3.0, 2.0), 9.0) = false. Code: Real.== (Math.pow (3.0, 2.0), 9.0); Math.pow (3.0, 2.0) - 9.0; Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - Real.== (Math.pow (3.0, 2.0), 9.0); val it = false : bool - Math.pow (3.0, 2.0) - 9.0; val it = ~1.7763568394e~15 : real Comments: Here is an (seemingly) equivalent C program: #include #include int main () { float a = 3.0; float b = 2.0; float ans = 9.0; printf ("%s\n", (pow (a, b) == ans ? "yes" : "no")); } and running it: [gcb@dynamic bin]$ ~/test yes Fix: Test: bug1486.1.sml Owner: jhr, Andrew Status: open ---------------------------------------------------------------------- Number: 1487 Title: parentheses not permitted in val rec binding Keywords: syntax Submitter: Rob Arthan rda@lemma-one.com Date: 02/17/99 Version: 110.0.3 System: Sparc Solaris Subsystem: SML compiler Severity: minor Problem: The syntax for declarations includes; dec ::= val tyvarseq valbind | ... with valbind ::= pat = exp | rec valbing pat ::= atpat | ... | pat : ty atpat ::= longvid | ... | ( pat ) but the full syntax does not seem to be supported. Code: val rec g : 'a -> 'a = fn x => g x; val rec (f : 'a -> 'a) = fn x => f x; Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - val rec g : 'a -> 'a = fn x => g x; val g = fn : 'a -> 'a - val rec (f : 'a -> 'a) = fn x => f x; stdIn:18.10-18.13 Error: syntax error: deleting ID COLON stdIn:18.17-18.22 Error: syntax error: deleting ARROW TYVAR stdIn:18.24-18.28 Error: syntax error: deleting EQUALOP FN stdIn:18.29-18.35 Error: syntax error: deleting ID DARROW ID Comments: This is a minor problem, but an irritant if you're porting a lot of code with this sort of construct in it (in semantically useful cases). The fix is trivial, but it's a chore. [dbm, 2/17/99] The val declaration syntax is rather peculiar (wish we had fixed this in SML '97), and there are some "legal" constructs have no interest in supporting, like val rec rec rec val and rec and but I think we should and can afford to support the syntax in your bug report. I've added it to the list as bug 1487. Fix: I don't have a fix but the ml.grm uses a production "rvb" for the construct that follows VAL REC and this doesn't seem to allow enough. Test: bug1487.1.sml Owner: dbm, Andrew Status: open ---------------------------------------------------------------------- Number: 1488 Title: Array.fromList of empty list generates bogus "empty" array Keywords: crash empty array Array.fromList Submitter: Perry Cheng Date: 02/17/99 Version: 110.13 System: Alpha Digital Unix 4.0 Subsystem: SML compiler Severity: critical Problem: The following bug was discovered while trying to use MLRISC. In particular, the file ra/liveness.sml tickles this bug. When the Array.fromList function is called on an empty list. The resulting array has length 1 and its first element appears to a bit pattern of zero. So Array.fromList([] : int list) computes to [|0|] At a type, (e.g. int * int), where a bit pattern of zero is not valid value, this will lead to a segmentation fault as the transcript shows. Note also that the interactive loop somehow knows not to try to print this ill-formed array. I believe the problem has to do with changes in array representation. Also, I noticed that Array.array0 no longer exists. Perhaps this is related? This problem can also be exhibited on a SPARC. Code: See transcript. Transcript: Standard ML of New Jersey v110.13 [FLINT v1.5], January 17, 1999 [CM; autoload enabled] - val ls : (int * int) list = []; val ls = [] : (int * int) list - val arr = Array.fromList ls; - Array.length arr; val it = 1 : int - Array.sub(arr,0); Segmentation fault Comments: [jhr, 2/18/99] I think that this bug can be fixed by changing line 808 of compiler/CodeGen/main/mlriscGen.sml from (tag(false, mlZero), CPS.OFFp 0) to (mlZero, CPS.OFFp 0) This will cause the correct length to be stored for arrays of length 0. Fix: Test: bug1488.1.sml Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1489 Title: bad type of equality function defined for abstype Keywords: types, type checking, abstype, equality type Submitter: Rob Arthan Date: 2/18/99 Version: 110.0.3 through 110.13 System: - Severity: major Problem: An equality function defined on an abstype does not have the right type. Code: abstype t = Mkt of int with val mk = Mkt and eq : t * t -> bool = op = end; val x = mk 3 and y = mk 4; eq (x,y); Transcript: - abstype t = Mkt of int = with val mk = Mkt = and eq : t * t -> bool = op = = end; type t val mk = fn : int -> t val eq = fn : t * t -> bool - val x = mk 3 and y = mk 4; val x = - : t val y = - : t - eq (x,y); stdIn:23.1-23.9 Error: operator and operand don't agree [equality type required] operator domain: ''Z * ''Z operand: t * t in expression: eq (x,y) Comments: In any case, as with value polymorphism, I find that making the code "less functional" solves the problem. If I introduce a semantically irrelevant eta-redex, it works as expected: val eq : t*t -> bool = fn (x, y) => x = y; Fix: Test: bug1489.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1490 Title: double error message for bad string constant Keywords: error messages, strings Submitter: Dave MacQueen Date: 4/14/99 Version: 110.15 System: - Severity: minor Problem: Duplicate error messages are produced in response to an ill-formed string expression. Transcript: - "\x"; stdIn:35.1-35.3 Error: unclosed string stdIn:35.4-35.6 Error: unclosed string Comments: Fix: Test: bug1490.1.sml Owner: jhr? Status: open ---------------------------------------------------------------------- Number: 1491 Title: Polymorphic Computation Too Slow Keywords: polymorphism Submitter: Eijiro Sumii sumii@yl.is.s.u-tokyo.ac.jp Date: 03/05/99 Version: 110.0.3 System: Sparc Solaris 2.5.1 Subsystem: SML compiler Severity: major Problem: Whenever I try large polymorphic computation (as below), SML/NJ takes too much time to give a result compared with other implementations or langauges. Code: val S = fn x => fn y => fn z => (x z) (y z) val K = fn x => fn y => x let val six = ((S ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S (K K)) (K K))))) ((S (K K)) (K K)))))) ((S ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S (K K)) (K K))))) ((S (K K)) (K K))))))) ((S K) K))) in six (fn n => 1 + n) 0 end Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - val S = fn x => fn y => fn z => (x z) (y z); val S = fn : ('a -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'c - val K = fn x => fn y => x; val K = fn : 'a -> 'b -> 'a - val six : (int -> int) -> int -> int = ((S ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S (K K)) (K K))))) ((S (K K)) (K K)))))) ((S ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S (K K)) (K K))))) ((S (K K)) (K K))))))) ((S K) K))); = = = = = = = GC #0.0.0.0.1.5: (10 ms) = = = = = GC #0.0.0.0.2.32: (30 ms) GC #0.0.0.1.3.44: (40 ms) GC #0.0.0.1.4.60: (20 ms) GC #0.0.1.2.5.65: (70 ms) GC #0.0.1.2.6.69: (20 ms) GC #0.0.1.2.7.92: (30 ms) GC #0.0.1.2.8.116: (0 ms) GC #0.0.1.2.9.223: (70 ms) GC #0.1.2.3.10.233: (110 ms) GC #0.1.2.3.11.234: (30 ms) GC #0.1.2.3.12.235: (20 ms) GC #0.1.2.3.13.254: (20 ms) GC #0.1.2.3.14.269: (40 ms) GC #0.1.2.3.15.303: (60 ms) GC #0.1.2.4.16.307: (80 ms) GC #0.1.2.4.17.343: (20 ms) GC #0.1.2.4.18.348: (0 ms) val six = fn : (int -> int) -> int -> int - six (fn n => 1 + n) 0; GC #0.1.3.5.19.349: (0 ms) val it = 6 : int - Comments: Fix: Test: tests/bug1491.1.sml Owner: Zhong? Status: open ---------------------------------------------------------------------- Number: 1492 Title: Compile-time performance problem with long list value Keywords: performance, compile time Submitter: Rob Arthan rda@lemma-one.com Date: 03/11/99 Version: 110.0.3 System: x86 Linux 2.0.18 Subsystem: SML compiler Severity: major Problem: I have some code which is partly generated by a home-grown parser generator. The generated code needs to generate a table represented as an array (actually a vector would do, but it uses arrays for historical reason). To get around a problem with a different compiler, the array is generate like this: val x1 = [ ... ]; val x2 = [ ....]; .... val xN = [ ... ]; val xs = Array.fromList(x1 @ x2 @ ... @ xn); this is then wrapped inside a structure whose signature hides x1, x2 etc. This seems to cause a major compiler performance problem. With a little tuning, it can be got to compile in a few minutes on an Ultra SPARC with lots of memory, but on a Pentium 100 running Linux it takes forever - I put it out of its misery after 30 hours. Code: tests.perf/bug1492.1.sml tests.perf/bug1492.2.sml Transcript: The full example issue GC message after GC message and then eventually goes quiet (while still consuming 100% of the CPU time). Comments: I accept that the generated code is not particularly pretty and without much difficulty I can reprogram the output stage of the parser generator, but what will work? divide and conquer (i.e., a tree structure of sub-expressions rather than a list)? doing it by assignments? or what? [Matthias] I just confirmed Rob Arthan's bug report about unacceptable compile-time performance. In my case, I was running 110.9.1 on an UltraSparc with 256M of installed RAM. I put the machine out of its misery after about 14 minutes of CPU time (wall clock time was much more) because it tried to allocate around 700MB of heap. Since this obviously failed, the GC tried less memory and the machine started a swapping frenzy... Here are some observations: 1. The bad phase is cpsgen. This became immediately obvious after setting Compiler.Stats.say{Begin,End} to true. 2. Initially, the process ran for about 12 minutes happily within about 75M. During this phase, the GC ran frequently, collecting up generation 3 (generation 1 being the "youngest"). The GC message read GC #5.29.33.xxxx.xxxx.xxxxx: (xx ms) for about a gazillion of times. 3. Then, suddenly, something changed. Memory consumption jumped, now the GC quickly got to the point where it had to do full collections. Here is a partial transcript: . . . GC #5.29.33.1163.1664.34008: (20 ms) <- see point 2 GC #5.29.33.1164.1665.34017: (20 ms) <- see point 2 GC #5.29.33.1165.1666.34076: (390 ms) <- here things seem to change GC #6.30.34.1166.1667.34085: (1140 ms) <- here things have changed GC #6.30.35.1167.1668.34105: (480 ms) GC #6.31.36.1168.1669.34125: (680 ms) GC #6.32.37.1169.1670.34145: (730 ms) GC #6.33.38.1170.1671.34165: (490 ms) GC #6.34.39.1171.1672.34185: (570 ms) GC #6.35.40.1172.1673.34205: (570 ms) GC #7.36.41.1173.1674.34225: (2110 ms) GC #7.37.42.1174.1675.34235: (460 ms) GC #7.38.43.1175.1676.34238: (600 ms) GC #7.39.44.1176.1677.34246: (650 ms) GC #7.40.45.1177.1678.34249: (540 ms) GC #7.41.46.1178.1679.34256: (530 ms) GC #8.42.47.1179.1680.34259: (2730 ms) GC #8.43.48.1180.1681.34267: (500 ms) GC #8.44.49.1181.1682.34268: (350 ms) GC #8.45.50.1182.1683.34286: (390 ms) GC #8.46.51.1183.1684.34306: (410 ms) GC #9.47.52.1184.1685.34326: (3190 ms) GC #9.48.53.1185.1686.34346: (460 ms) GC #9.49.54.1186.1687.34366: (560 ms) GC #9.50.55.1187.1688.34386: (550 ms) GC #9.51.56.1188.1689.34406: (590 ms) GC #9.52.57.1189.1690.34426: (560 ms) GC #9.53.58.1190.1691.34446: (600 ms) GC #9.54.59.1191.1692.34466: (540 ms) GC #9.55.60.1192.1693.34485: (600 ms) GC #9.56.61.1193.1694.34489: (810 ms) GC #9.57.62.1194.1695.34497: (770 ms) GC #9.58.63.1195.1696.34500: (790 ms) GC #9.59.64.1196.1697.34507: (820 ms) GC #10.60.65.1197.1698.34510: (5060 ms) <- this GC took about 3 min. wall clock time because of paging GC #10.61.66.1198.1699.34517: (480 ms) GC #10.62.67.1199.1700.34520: (440 ms) GC #10.63.68.1200.1701.34527: (490 ms) GC #10.64.69.1201.1702.34530: (390 ms) GC #10.65.70.1202.1703.34537: (440 ms) /hana/blume/bin/sml: Error -- unable to map 242745344 bytes, errno = 11 /hana/blume/bin/sml: Error -- unable to allocate to-space for generation 5; trying smaller size GC #11.66.71.1203.1704.34540: (5780 ms) <- ditto /hana/blume/bin/sml: Error -- unable to map 735117312 bytes, errno = 11 /hana/blume/bin/sml: Error -- unable to allocate to-space for generation 5; trying smaller size GC #12.67.72.1204.1705.34549: (5720 ms) <- ditto At this point I gave up and pressed the interrupt key... My guess is that the above code creates an incredible register pressure which causes the register allocator to lose its bearings... Any other ideas? [Matthias, 3/12/99] Here is one more data point on the compiler time bug... (It should also provide Rob with a reasonable workaround.) I modified Rob's code as follows: 1. I reversed the order of declaration for the slrn'gNNN variables. 2. Each such variable (except the first one) is now immediately concatenated with the previous one. 3. The final call to Array.fromList is performed on the contents of slrn'g0. This effectively interleaves the calls to List.@ with the creation of those variables, leaving only a small number of variables live at any time. As a result, there is *much* less register pressure, and the program compiles fine within a few seconds. (It's still slow, mind you, but the improvement is by several orders of magnitude.) I bet that it will be possible to modify the program that generates this code to do what I did manually. [see test/bug1492.2.sml for code] [Lal, 3/12,99] I tried this with the latest version (110.13), running on a fairly old ultrasparc and it completed fine (not super fast though). GC #11.117.127.152.254.8335: (100 ms) GC #11.118.128.153.255.8388: (90 ms) GC #11.119.129.154.256.8437: (90 ms) structure S : sig val slrp'gotos : (string * int) list array end val it = () : unit val it = {gc="29.040",sys="5.090",tot="135.080",usr="100.950"} : {gc:string, sys:string, tot:string, usr:string} At the very least, 110.13 does a better job in dealing with string literals. I confirmed the same behaviour with 110.9.1 on this machine. [Matthias, 3/12/99] Ok, I tried 110.14 and, indeed, it compiles fine (on an Ultra). Still, the time it takes to do that is a bit frustrating, and memory consumption (during compile) hovers at about 100MB, with a peak at 150MB. It's certainly not good. After re-arranging the code as I described earlier, the 110.14 compiler needs only one major collection as opposed to 12, and memory consumption is at 40MB instead of 100MB. Fix: Test: tests.perf/bug1492.{1,2}.sml Owner: Zhong? Status: open ---------------------------------------------------------------------- Number: 1493 Title: NT Installer messes up PATH in the registrry Keywords: "installer","PATH" Submitter: Parzival parz@videon.wave.ca Date: 03/18/99 Version: 110 System: x86 Windows NT 4 Subsystem: Installation Severity: minor Problem: The Windows NT installer sucessfully installs the software, and it works, but the initial PATH environment variable setting in the registry is replaced with the EXPANDED and DOS specific version of the path string. The registry contains a string that Win NT expands into the command shell environment variable whenever it starts a command shell, i.e. registry: Var name Value .Tex c:\Tex PATH c:\bin;%.Tex%\MikTex\bin;c:\Program Files\TextPad resulting Path value in the command shell: PATH=c:\bin;c:\Tex\MikTex\bin;c:\Program Files\TextPad After installing SMLNJ, in directory "c:\sml", the registry looks like this: registry: Var name Value PATH e:\winnt\system32;e:\winnt;c:\bin;C:\Tex\MikTex\bin;c:\PROGRA~1\TextPad;C:\sml\bin So the installer has replaced the existing regigistry PATH value with a derived version: The user path setting includes the system (user independent) path setting, "\Program Files\" has been replaced by "\PROGRA~1\" (the 8.3 filename alias that NT supports for backwards comptibility with 16 bit programs that can't cope with long or spaces embedded file names), and embedded Since the path still "works", this problem may not be noticed until, say, in the above example, the registry setting for ".Tex" is changed, and the expected change to the path is not realized. I have a horrendous PATH: PATH=%MSDevDir%\bin\ide;%MSDevDir%\bin;%MSVCdir%\bin;%CYGWIN32%\bin; %.WinIcon%\bin;c:\pm3\bin;c:\Reactor\bin;c:\Program Files\textpad; %.Tex%\MikTex\bin;c:\noweb\bin;%IBMPLI%\bin;%.MOSES%\bin; c:\cocktail\bin; and the day after installing SML, it became: PATH=E:\WINNT\system32;E:\WINNT;.;C:\Perl\bin;C:\bin;C:\PROGRA~1\devstudio\sharedide\bin\ide; C:\PROGRA~1\devstudio\sharedide\bin;C:\PROGRA~1\devstudio\vc\bin; C:\CYGNUS/B19/H-i386-cygwin32\bin;C:\WinIcon\bin;c:\pm3\bin; c:\Reactor\bin;c:\PROGRA~1\textpad;c:\Tex\MikTex\bin;c:\noweb\bin; C:\IBMPLIW\bin;C:\MOSES\bin;c:\cocktail\bin;c:\sml\bin; Code: Transcript: Comments: Fix: Your installer is a 16 bit Windows program: Win NT emulates the operations it performs on the Windows 3.x "win.ini" file in the registry. You need to use a 32 bit installer program. Test: Owner: Riccardo Status: open ---------------------------------------------------------------------- Number: 1494 Title: rebound datatype prints incorrectly Keywords: types Submitter: John Reppy jhr@research.bell-labs.com Date: 04/19/99 Version: 110.0.3 System: Any/All Any Unix Subsystem: SML compiler Severity: minor Problem: When rebinding a datatype, the top-level loop prints rhs type name instead of the lhs name. Code: datatype foo = FOO; datatype bar = datatype foo; Transcript: - datatype foo = FOO; datatype foo = FOO - datatype bar = datatype foo; datatype foo = FOO Comments: Fix: Test: bug1494.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1495 Title: 110.16 does not build cleanly on Sparc Keywords: install, ml-yacc Submitter: Matthias Blume Date: 04/22/99 Version: 110.16 System: sparc-solaris: SunOS hana 5.6 Generic_105181-11 sun4u sparc SUNW,Ultra-30 Severity: critical Problem: During config/install.sh, compiling the sources of ml-yacc fails. Code: $ config/install.sh Transcript: ... [opening yacc.grm.sml] GC #0.1.2.3.17.650: (10 ms) GC #0.1.2.3.18.682: (50 ms) GC #0.1.3.4.19.709: (30 ms) GC #0.1.3.4.20.767: (40 ms) GC #0.1.3.4.21.797: (20 ms) GC #0.1.3.4.22.822: (10 ms) GC #0.1.3.4.23.837: (10 ms) GC #0.1.3.4.24.842: (20 ms) GC #0.1.3.5.25.850: (20 ms) GC #0.1.3.5.26.883: (10 ms) Error: Compiler bug: Wrapping: unexpected case in lpsw - !!! build of ml-yacc.sparc-solaris failed Comments: Same code does build properly on linux (x86). [Matthias, 4/23/99] Well, things are *very* bizarre... The problem has nothing to do with the version of the CPU or the OS. Instead, it seems to depend on the NAME OF THE DIRECTORY (!!!) where I install SML/NJ. Go figure... I typically use a directory name that is the part of the version number after the dot. In the case of 110.16 it would be "16". Therefore, my installation attempt took place in /hana/blume/ML/16 This directory is on a local disk that is not accessible from other machines in the network. Therefore, when I tried another machine I had to use a different directory -- and everything went through fine. Later I discovered that the machine "hana" (my Ultra-30) could also install the stuff fine in that other directory. Finally, I started to experiment with that local disk. Directories like /hana/blume/ML/Bizarre etc. worked fine while /hana/blume/ML/16 /hana/blume/ML/17 /hana/blume/ML/XY did not work. So I started thinking that it has something to do with the length of the name. However, /hana/blume/ML/XYZ also did not work. Finally, /hana/blume/ML/WXYZ DID work. Another thing I discovered is that the fragile step seems to be the one where binfiles are turned into the SML heap image. Runtime systems between "working" and "non working" versions are interchangeable (the one from the "non working" directory does work when transplanted into the "working" directory, the one from the "working" directory does not work in a "non working" directory). The same is not true for the heap image -- a heap image transplanted from a "non working" directory into a "working" one still does not work. A heap image that comes from a "working" directory continues to work in a "non working" directory. I have no clue whatsoever what might be going on here. Any ideas? [jhr, 4/23/99] I would guess that there is a string padding problem (ML strings are supposed to have a terminating 0 byte to make them interchangable with the run-time). I would suggest putting in some print statements in the runtime libraries (I assume that it is failing on open?) to see if the string values are bogus. [Matthias, 4/23/99] I also think that it has something to do with string padding. Or more generally: alignment. However, it does not have anything to do with "open", I believe. My message referred to my earlier bug report on this problem where the install script fails during the compilation of the ml-yacc sources: ... [opening yacc.grm.sml] GC #0.1.2.3.17.650: (10 ms) GC #0.1.2.3.18.682: (50 ms) GC #0.1.3.4.19.709: (30 ms) GC #0.1.3.4.20.767: (40 ms) GC #0.1.3.4.21.797: (20 ms) GC #0.1.3.4.22.822: (10 ms) GC #0.1.3.4.23.837: (10 ms) GC #0.1.3.4.24.842: (20 ms) GC #0.1.3.5.25.850: (20 ms) GC #0.1.3.5.26.883: (10 ms) Error: Compiler bug: Wrapping: unexpected case in lpsw Lal tested this and did not see the problem, so I started poking around, trying different machines, directories, etc. My guess is that the new GC API implementation broke something because the same problem did not seem to exist in 110.15. However, it could also be the new code generator and I got "lucky" before (or rather: "unlucky" now). [Lal, 4/30] I tried: /home/george/L/16 which has the same length as: /hana/blume/ML/16 and ml-yacc installed fine. Both the build script and the sources.cm file in the ml-yacc/src directory worked fine. [Matthias, 4/1/99] Hmm. Obviously there _is_ a bug (because it is happening here). If it really is an alignment problem of some sort, then anything could have an impact -- like the size of the shell environment and such. When I get a chance I go and try to find a repeatable instance of the problem so you can have a look at it. Other people are also seeing problems with 110.1[56], so I am fairly confident that it is not just some local problem of mine. (BTW, I have also seen some programs core-dump under 110.16 on the x86.) [Matthias, 5/6/99] I just went through a series of tests regarding the 110.16 install problem that I reported for my Sparc. First, to rule out any impact from the shell environment I ran the script as env -i PATH=/bin:/usr/bin:/usr/local/bin config/install.sh i.e., just barely enough for it to be able to run at all. However, the effect I was seeing is the same as before. So I went through a series of directory names: /hana/blume/M/16 - succeeds /hana/blume/ML/16 - fails /hana/blume/ML/16x - fails /hana/blume/ML/16xx - succeeds /hana/blume/ML/16xxx - succeeds ... ... /hana/blume/ML/16xxxxxxxxxxxxxxxxxxx - succeeds So it looks like I hit some really odd problem that only occurs with a very low probability. I have not been able to figure out what's causing this. Any ideas would be appreciated. (Assuming it is an alignment problem, it surely does not look like a word-boundary alignment problem. Maybe it has to do with a page boundary? What else could go wrong?) Below is a full transcript of the unsuccessful installation attempt. (You'll notice that the script uses /home/blume/ML/16 -- but that one is symbolically linked to /hana/blume/ML/16. I confirmed that the problem also exists if I run the install script directly from /hana/blume/ML/16.) [dbm: transcript in /home/sml/Dev/bugs/bug1495.transcript] [Lal, 5/6/99] If this is a subtle GC bug then in the cases where it fails, it may be possible to run to compeletion with a different allocation size. So in ml-yacc/src execute CM.make() with something like: ../../../bin/sml @SMLalloc=2M Allen reported a bug [bug 1496] that showed up when running the benchmarks. However, the weird thing is that it only shows up after the third repetition. Each repetition starts sml from scratch! [Matthias, 5/7/99] > If this is a subtle GC bug then in the cases where it fails, it may > be possible to run to compeletion with a different allocation size. > So in ml-yacc/src execute CM.make() with something like: > > ../../../bin/sml @SMLalloc=2M Yes, that does it. I tried both cases: 1. building the ML heap image with @SMLalloc=2M and 2. (using the original 512k image) giving this option to the ml-yacc build script. In either case installation goes through fine. (I guess the two cases boil down to the same at some point, but I'm not sure.) In any case, it more and more looks like a GC bug. [jhr, 5/7/99] To be more precise, I would guess that it is a bug in the code generator's implementation of the new GC API. [Matthias, 5/20/99] Sorry for being imprecise. That's exactly my guess also. Fix: * Test: * Owner: Lal Status: fixed in 110.17 [Lal] ---------------------------------------------------------------------- Number: 1496 Title: Barnes-hut loops Keywords: Submitter: Allen Leung (leunga@cs.nyu.edu) Date: 4/28/99 Version: 110.16 System: HP-UX optlab5 B.10.20 A 9000/780 2003074095 two-user license SunOS griffin 5.6 Generic_105181-12 sun4u sparc SUNW,Ultra-1 Severity: Critical Problem: Code: Run the SML97 benchmarks from the ftp site. Barnes-hut fails to complete on HP-UX and Solaris. The program starts to loop after the third trial. The same benchmarks work ok on the x86 though. Transcript: [recovering CM/hppa-unix/load.sml.bin... done] [recovering CM/hppa-unix/grav.sml.bin... done] [recovering CM/hppa-unix/data-io.sml.bin... done] [recovering CM/hppa-unix/getparam.sml.bin... done] [recovering CM/hppa-unix/rand-sig.sml.bin... done] [recovering CM/hppa-unix/rand.sml.bin... done] [recovering CM/hppa-unix/main.sml.bin... done] [recovering ../CM/hppa-unix/timeit.sml.bin... done] [recovering CM/hppa-unix/main2.sml.bin... done] [introducing new bindings into toplevel environment...] val it = true : bool GC #1.1.1.1.2.22: (90 ms) GC #1.1.1.1.3.116: (10 ms) GC #1.1.1.1.4.252: (0 ms) GC #1.1.1.1.5.424: (0 ms) GC #1.1.1.1.6.619: (0 ms) GC #1.1.1.1.7.830: (0 ms) GC #2.2.2.2.8.871: (100 ms) GC #2.2.2.2.9.954: (0 ms) GC #2.2.2.2.10.1061: (0 ms) GC #2.2.2.2.11.1198: (0 ms) GC #2.2.2.2.12.1367: (0 ms) GC #2.2.2.2.13.1562: (0 ms) GC #3.3.3.3.14.1720: (140 ms) GC #3.3.3.3.15.1887: (0 ms) GC #3.3.3.3.16.2084: (0 ms) GC #3.3.3.3.17.2300: (10 ms) GC #3.3.3.3.18.2548: (0 ms) GC #4.4.4.4.19.2569: (130 ms) GC #4.4.4.4.20.2622: (0 ms) GC #4.4.4.4.21.2701: (0 ms) GC #4.4.4.4.22.2810: (0 ms) GC #4.4.4.4.23.2950: (0 ms) GC #4.4.4.4.24.4168: (0 ms) GC #4.4.4.4.25.5426: (0 ms) GC #4.4.4.4.26.6791: (0 ms) GC #4.4.4.4.27.8497: (0 ms) GC #4.4.4.4.28.10387: (0 ms) GC #4.4.4.4.29.12435: (0 ms) GC #4.4.4.4.30.14824: (0 ms) GC #4.4.4.4.31.17344: (0 ms) GC #4.4.4.4.32.20074: (0 ms) GC #4.4.4.4.33.23146: (0 ms) GC #4.4.4.4.34.26296: (0 ms) GC #4.4.4.4.35.29709: (0 ms) GC #4.4.4.4.36.33463: (0 ms) GC #4.4.4.4.37.37243: (10 ms) GC #4.4.4.4.38.41339: (0 ms) GC #4.4.4.4.39.45750: (0 ms) GC #4.4.4.4.40.50187: (0 ms) etc... Comments: Also, there seems to be various phantom segfaults in versions 110.15 and 110.16, usually during long compilations. These appeas on the sparc, hppa and the x86. The x86 segfaults the most. GC problems? Fix: Test: Owner: Lal Status: fixed in 110.17 [Lal] ---------------------------------------------------------------------- Number: 1497 Title: bug in IntInf.scan StringCvt.HEX Keywords: Submitter: Stephen Weeks Date: 05/10/99 Version: 110.9.1 System: x86-linux Severity: Problem: IntInf.scan StringCvt.HEX does not work correctly. For example, the result of scanning the string "0x1" should be 1, but instead 0 is returned. The scanner appears to be ignoring everything after the "0". Code: let val str = "0x1" fun reader offset = if offset = size str then NONE else SOME (String.sub(str, offset), offset + 1) in IntInf.toString(#1(valOf(IntInf.scan StringCvt.HEX reader 0))) end Transcript: Comments: Fix: Test: bug1497.1.sml Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1498 Title: Specialized real arrays not pretty-printed correctly Keywords: Submitter: Allen Leung leunga@cs.nyu.edu Date: 05/05/99 Version: 110.0.6 - 110.27 System: Any/All Any Unix Subsystem: SML compiler Severity: cosmetic Problem: Arrays of type "real Array.array" do not print like other arrays. Instead they print as "prim?". Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - Array.array(3,1); val it = [|1,1,1|] : int array - Array.array(3, "a"); val it = [|"a","a","a"|] : string array - Array.array(3, true); val it = [|true,true,true|] : bool array - Array.array(3,1.0); val it = prim? : real array Comments: [dbm, 4/27/00] It looks like "real Array.array" has probably been converted internally to the RealArray.array (Real64Array.array) representation. For top-level printing, ppObj (MiscUtil/print/ppobj.sml) calls local function ppVal', whose code for arrays (Array.array) is else if TU.eqTycon(tyc,BT.arrayTycon) then (printWithSharing ppstrm (obj,accu, fn (obj,accu) => ppArray(Obj.toArray obj, hd argtys, membersOp, depth, !Control.Print.printLength, accu)) handle Obj.Representation => add_string ppstrm "prim?") If obj is actually a Real64Array.array, then Obj.toArray could fail, raising Obj.Representation and causing "prim?" to be printed. If Obj.toArray doesn't fail, then the definition of ppArray is assuming a polymorphic Array.array, and uses "Array.sub (objs,index)" to extract the real element, presumably getting a bogus value that will cause Obj.Representation to be raised when ppVal' tries to apply Obj.toReal to it: else if TU.eqTycon(tyc,BT.realTycon) then add_string ppstrm (Real.toString(Obj.toReal obj)) This would presumably raise Obj.Representation. [dbm, 4/27/99] It seems odd that _at top level_ there is a discrepency between the known type of a value, real Array.array, and it's representation type, which appears to be RealArray.array. I would have thought that this would cause other problems than printing, though operations like Array.sub seem to work ok: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 ... - val a = Array.array(3,1.0); val a = prim? : real array - Array.sub (a,1); val it = 1.0 : real How is this managed? Does Array.sub do some kind of dynamic check of the representation tag? [Zhong, 4/28/00] Array.sub is applied to "real array" and the compiler automatically specializes it into RealArray.sub --- thus everything works out as expected. If you have a large polymorphic function fun huge (x : 'a array) = .........Array.sub(x, 1)........ ---------------------------------------------------------- val a = Array.array(3, 1.0) val x = huge (a) Then Array.sub can't be specialized, but we pass the type descriptor to "huge" so at runtime we check this type descriptor and use RealArray.sub when it is a real array. Fix: smlnj/src/system/Basis/Implementation/Unsafe/object.sig smlnj/src/system/Basis/Implementation/Unsafe/object.sml added toRealArray function smlnj/src/compiler/MiscUtil/print/ppobj.sml added check for tag Obj.RealArray to array printing case in ppObj Test: bug1498.1.sml Owner: dbm, Zhong Status: fixed in 110.0.7, 110.28 [dbm, 4/28/00] ---------------------------------------------------------------------- Number: 1499 Title: Uncaught exception during compilation of bad signature Keywords: types signature Submitter: Leif Kornstaedt kornstae@ps.uni-sb.de Date: 04/15/99 Version: Version 110.0.3, January 30, 1998 [CM; autoload enabled] System: x86 Linux 2.0.36 Subsystem: SML compiler Severity: minor Problem: An exception escapes during compilation of the bad signature given below. Code: signature Bug = sig type t type t datatype u = C of t and v = D end Transcript: - use "Bug.sig"; [opening Bug.sig] Bug.sig:3.2-7.5 Error: duplicate specifications for type constructor t in signature uncaught exception Unbound raised at: elaborate/elabmod.sml:1364.39-1364.49 Comments: Fix: Test: bug1499.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1500 Title: Runtime system on Linux with glibc2 Keywords: runtime, linux, glibc Submitter: Matthias Blume blume@kurims.kyoto-u.ac.jp Date: 04/19/99 Version: 110.16 System: x86 Linux kernel 2.2.6, glibc 2.1.1 Subsystem: Installation Severity: minor Problem: The runtime system does no longer compile out-of-the-box on one of the brand-new Linux systems that use the new glibc (version 2.1 and higher). The problem is with the file src/runtime/mach-dep/signal-sysdep.h which erroneously redefines a 'struct sigcontext'. The problem can be circumvented by improving the logic of the #if guard that is already in place. Code: Transcript: Comments: Fix: diff -c -r runtime.distrib/mach-dep/signal-sysdep.h runtime/mach-dep/signal-sysdep.h *** runtime.distrib/mach-dep/signal-sysdep.h Wed Feb 24 01:35:26 1999 --- runtime/mach-dep/signal-sysdep.h Mon Apr 19 16:09:56 1999 *************** *** 348,354 **** # if defined(OPSYS_LINUX) /** X86, LINUX **/ ! # ifndef _SIGCONTEXT_H /* older versions of Linux don't define this in */ struct sigcontext { unsigned short gs, __gsh; --- 348,354 ---- # if defined(OPSYS_LINUX) /** X86, LINUX **/ ! # if !defined(_SIGCONTEXT_H) && !defined(sigcontext_struct) /* older versions of Linux don't define this in */ struct sigcontext { unsigned short gs, __gsh; Test: Owner: jhr Status: fixed in 110.17, 110.0.4? ---------------------------------------------------------------------- Number: 1501 Title: Memory leak Keywords: Garbage collection, run-time system Submitter: rolsson@cs.chalmers.se Date: 02/25/1999 Version: 110.0.3 System: x86-linux-2.0.34 Severity: critical Problem: The following small piece of code causes a steady growth in virtual memory size. The rate of increase is about 120 Mbytes per hour on a 400 MHz Pentium II. I have tried it up to 240 Mbytes, which is unreasonable for a program that should require constant space with tail-recursion optimization The leak may be caused by the call to blastWrite. Code: fun word8_to_char( X : Word8.word ) : char = Char.chr( Word8.toInt X ) fun word8vector_to_string( Xs : Word8Vector.vector ) : string = CharVector.tabulate( Word8Vector.length Xs, fn I => word8_to_char( Word8Vector.sub( Xs, I ) ) ) fun fromto( Lower, Upper ) = if Lower > Upper then nil else Lower :: fromto( Lower+1, Upper ) fun f() = let fun g() = fromto(1,500) val S = word8vector_to_string( Unsafe.blastWrite( g() ) ) in f() end Transcript: f(); Comments: My conversion of a Word8Vector.vector to a string is probably naive. [jhr, 2/25/99] Thanks for the report. I don't see why blastWrite would cause a space leak in this case, but I'll look into it. There is an open bug having to do with repeated array allocation, which this may be an instance of. It is also possible, but unlikely that the bug is a compiler bug. BTW your word8vector_to_string function can be replaced by the function Bytes.bytesToString, which is constant-time in SML/NJ. Fix: Avoid blastWrite? Test: * Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1502 Title: compiler failes to build with small allocation space Keywords: gc, allocation space, compiler build Submitter: Lal George Date: 5/13/99 Version: 110.11 and later System: - Severity: critical Problem: All versions of the compiler (earlier than version 110.11) could build with an allocation of 64K. Thus, it appears that there may be a hidden bug in the new array/literal stuff. Code: Transcript: Comments: Fix: Test: Owner: jhr, Lal Status: fixed in 110.17 [Lal] ---------------------------------------------------------------------- Number: 1503 Title: redefinition of `struct sigcontext' under red hat 6.0 Keywords: Submitter: Mattox Beckman beckman@cs.uiuc.edu Date: 05/13/99 Version: 110.6, 110.16 System: x86 Linux Red Hat 6.0 Subsystem: Installation Severity: minor Problem: Installation fails. The error message reported: gcc -ansi -c -O2 -DHOST_X86 -DTARGET_X86 -DOPSYS_UNIX -DOPSYS_LINUX -D_POSIX_SOURCE -D_BSD_SOURCE -DVREGS -DCALLEESAVE=3 -I../objs -I../include ../mach-dep/unix-fault.c In file included from ../mach-dep/unix-fault.c:9: ../mach-dep/signal-sysdep.h:353: redefinition of `struct sigcontext' make[1]: *** [unix-fault.o] Error 1 make[1]: Leaving directory `/opt/sml-110.6/src/runtime/objs' make: *** [all] Error 2 !!! run-time system build failed for some reason I was able to make a workaround by patching signal-sysdep.h. Here is a patch; I wasn't very careful to make sure this would not break anything else, but it seems that this should be okay: 4% diff src/runtime/mach-dep/signal-sysdep.h signal-sysdep.h 88a89 > #define _SIGCONTEXT_H 351a353 > # define _SIGCONTEXT_H Code: config/install.sh Transcript: see above Comments: Same as bug 1500 Fix: see above Test: Owner: jhr Status: fixed in 110.17, 110.0.4? [jhr] ---------------------------------------------------------------------- Number: 1504 Title: problem compiling smlnj-c on linux (red hat 6.0) Keywords: smlnj-c, C interface Submitter: Archisman Rudra Date: 5/16/99 Version: ? System: x86/linux (egcs-2.91.66, red hat 6.0) Severity: medium Problem: I found a small bug in compiling the C interface for sml. It could be architecture/ compiler specific. I am using egcs-2.91.66 on a linux (red hat 6.0) running on x86. In the last step of the compilation, ld gave an undefined symbol for CALL_BIAS in c-entry.o: Comments: Fix: [root@pelican smlnj-ccalls]# diff c-entry.asm.old c-entry.asm 75c75 < subl $CALL_BIAS,%eax /* adjust pc to point at "->" */ --- > subl $ CALL_BIAS,%eax /* adjust pc to point at "->" */ Test: Owner: Lorenz, Riccardo Status: open ---------------------------------------------------------------------- Number: 1505 Title: opaque functor signature match Keywords: modules, signatures, functors, opaque matching Submitter: Matthias Blume Date: 5/19/99 Version: 110.16 System: - Severity: major Problem: Here is a tiny program with higher-order functors (actually, just a structure containing a functor). Trying to compile it results in the error shown below. Why? Code: (strfun.sml) signature S = sig datatype t = C functor F (val v : t) : sig end end; structure S :> S = struct datatype t = C functor F (val v : t) = struct end end; Transcript: - use "strfun.sml"; [opening strfun.sml] strfun.sml:9.1-15.4 Error: value type in structure doesn't match signature spec name: v spec: ?.S.t actual: ?.S.t Comments: Note that if I make the signature match transparent -- S : S instead of S :> S -- then it does compile fine. Fix: Test: bug1505.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1506 Title: Uncaught Overflow/Div exceptions not printed correctly at top level Keywords: uncaught exceptions, printing Submitter: Allen Leung leunga@cs.nyu.edu Date: 05/23/99 Version: 110.16 System: x86 Any Unix Subsystem: SML compiler Severity: minor Problem: In 110.16, on both Solaris and Linux(x86), uncaught exceptions generated by overflow trapping instructions are not printed correctly. (It should print ) The problem seems to be unrelated to the recently discovered gc bug. The same code works correctly on HPUX, BTW. Transcript: ----------------- x86 -------------------------- Standard ML of New Jersey v110.16 [FLINT v1.5], April 15, 1999 val use = fn : string -> unit - 1 div 0; uncaught exception divide by zero raised at: - fun f x = f(x+x); GC #0.0.0.0.1.10: (20 ms) val f = fn : int -> 'a - f 10; stdIn:7.1-7.5 Warning: type vars not generalized because of value restriction are instantiated to dummy types (X1,X2,...) uncaught exception overflow raised at: ------------- Solaris ----------------- Standard ML of New Jersey v110.16 [FLINT v1.5], April 15, 1999 [CM; autoload enabled] - 1 div 0; uncaught exception divide by zero raised at: - fun f x = f(x+x); val f = fn : int -> 'a - f 10; stdIn:11.1-11.5 Warning: type vars not generalized because of value restriction are instantiated to dummy types (X1,X2,...) uncaught exception overflow raised at: Comments: [jhr, 5/23/99] This is a known bug, which I think was introduced when I switched the way that code objects are handled. The way things are supposed to work is that there is a file-name string added to the end of the code objects, which is used to generate this message. The problem is that in the new code-object allocation scheme, the string is not available at the time that the code-object is allocated (in MLRISC). Lal and I have discussed adding a mechanism to the MLRISC API that would allow the clients to pass in extra initialization information to the MLRISC module, but it hasn't been implemented. In the new run-time, I've moved these strings from the code object into run-time system objects, so it will be possible to change the API and set the string after the code object is allocated. Fix: Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1507 Title: compiler does not reach a fix point Keywords: compiler fixpoint, literal lifting, cps optimization, FLINT Submitter: Lal George george@research.bell-labs.com Date: 06/14/99 Version: 110.12 and greater System: Any/All Any Unix Subsystem: SML compiler Severity: critical Problem: Removing the line: val function5 = cycle(rounds, not(!CG.unroll), function4) from FLINT/cpsopt/cpsopt.sml causes the compiler to core dump during a build (makeml). The core dump is obtained after a couple of rounds of compiling the compiler in the process of reaching a fixpoint. Code: Transcript: Comments: This bug occurs on the alpha and x86 and is probably target independent. The first time the bug is manifest is version 110.12, and does not occur in version 110.9.1. The only changes between these versions are: a) the new array representation. b) literal lifting. The new array representation is an unlikely cause since most of the changes are in MLRISC and done after cpsopt. It seems almost certain that the bug is a subtle interaction between literal lifting and cps optimization. The bug is difficult to pin down because it rears its ugly head after at least 3 or 4 rounds of compiling the compiler and building heap images. Literal lifting is currently implemented in CPS. Since everything in CPS is being moved to FLINT, a possible solution to this problem would be to re-implement literal lifting in FLINT. This will have to be done sooner or later anyway, and perhaps this bug will go away in the process. [Zhong, 6/14/99] If literal lifting is really the problem, why can't we turn it off and see if the compiler still reaches a fix point. The liftLiterals flag in Compiler.Control.CG should work as before I assume. Personally, I can't rule out the new array-rep code that quickly. It touches almost every aspect of the compiler and have subtle interaction with representation analysis, primop implementation, etc. [jhr, 6/14/99] > If literal lifting is really the problem, why can't we turn it off > and see if the compiler still reaches a fix point. The liftLiterals > flag in Compiler.Control.CG should work as before I assume. The problem is that turning off literal lifting will break the new array representations. I guess that we could try to retrofit the literal lifting code into 110.9.1 to test this. > > Personally, I can't rule out the new array-rep code that quickly. > It touches almost every aspect of the compiler and have subtle > interaction with representation analysis, primop implementation, etc. Flint/CPS knows nothing about the new array representations. Arrays are just an abstraction at that point. The new representation is only visible when primops are translated to MLRisc instructions. I think that it is quite unlikely that there would be a bug in the new array representations that was sensitive to CPS transformations. On the other hand, since the literal lifting restructures the CPS terms, it seems quite likely that there could be an interaction between unrolling of CPS terms and literal lifting. Fix: Test: Owner: Lal and jhr Status: fixed in 110.25 ---------------------------------------------------------------------- Number: 1508 Title: problems with profiler Keywords: Submitter: Allyn Dimock Date: 6/18/99 Version: 110.03 System: SGI iris4d IRIX64 Severity: minor Problem: several difficulties in using Compile.Profile Code: val profile = ref true fun whenProfiling f = if (!profile) then f() else () ... val _ = whenProfiling (fn() => (Compiler.Profile.reset(); Compiler.Profile.setTimingMode (true) )) val (e1, sinks1) = termAnnot (e, sinks) val _ = whenProfiling (fn() => (print ("Profile of TypInfSources.termAnnot\n"); Compiler.Profile.report (!PPUtil.defaultOutstreamP); Compiler.Profile.reset(); Compiler.Profile.setTimingMode (false) )) val _ = whenProfiling (fn() => (Compiler.Profile.reset(); Compiler.Profile.setTimingMode (true) )) val e2 = typeAnnot (e1, sinks1) val _ = whenProfiling (fn() => (print ("Profile of TypInfSources.termAnnot\n"); Compiler.Profile.report (!PPUtil.defaultOutstreamP); Compiler.Profile.reset(); Compiler.Profile.setTimingMode (false) )) and so on... Transcript: (1) unhandled exception overflow from somewhere in profiled library code during the 4'th chunk of code being profiled. (sorry it takes several hours to get to the place where this profile is being used and I blew away my old log file. The actual code being profiled takes 25 minutes to run with profiling turned off. This doesn't seem long enough to overflow a 32 bit counter. Are you using smaller integers as counters? (2) %time cumsec #call name 50.00 .01 2344 TypInfSinks..termAnnot.termAnnot.typeFn1.typeFn1 50.00 .02 253 MakeProp..putTermProp .00 .02 15602 TypInfSinks..whenDebugging.whenDebugging .00 .02 2473 TermUtil..appSubterms.appSubterms Do you really only sample the clock at 10 millisec intervals? Is ther ea way to get finer granularity? (of course, if you allow me to go to 1 millisec intervals, then I am going to need 3 more bits in the counters than whatever was needed to fix problem (1) (3) the same input with (fn() => (print ("Profile of TypInfSources.termAnnot\n"); Compiler.Profile.report (!PPUtil.defaultOutstreamP); Compiler.Profile.setTimingMode (false) Compiler.Profile.reset(); )) i.e. interchange order of setTimingMode and reset after report. But leave the reset and setTimingMode, before the expression being profiled, unchanged. yields: 50.00 .04 0 Minor GC 37.50 .06 1 PPUtil..flush.flush 12.50 .07 2820 SplayTree..splay.splay.adj.adj 12.50 .07 1012 MakeProp..getActivePropMapEntry.getActivePropMapEntry 12.50 .08 759 IntBinaryMap..find.find.mem.mem.anon 12.50 .08 506 MakeProp..getTermProp.anon .00 ...... many more PPUtil..flush.flush is presumably time spent writing out the previous Compiler.Profile.report (or possibly the current). So it looks like reset and toggling the timingMode didn't have the expected behavior. Comments: Fix: Test: * Owner: ? Status: open ---------------------------------------------------------------------- Number: 1509 Title: Division overflow is not detected properly on the sparc Keywords: Submitter: Allen Leung leunga@cs.nyu.edu Date: 06/22/99 Version: 110.17 System: Sparc Any Unix Subsystem: SML compiler Severity: minor Problem: Integer division overflow is not detected properly on the sparc. This bug has been around since the sparc started using MLRISC as the backend. The bug was my fault; I didn't realize division could overflow. Code: val SOME x = Int32.minInt; x div ~1; Transcript: leunga@griffin:~/SML/src/MLRISC++{183}> sml Standard ML of New Jersey v110.17 [FLINT v1.5], May 20, 1999 [CM; autoload enabled] - val SOME x = Int32.minInt; stdIn:14.1-14.26 Warning: binding not exhaustive SOME x = ... val x = ~2147483648 : Int32.int - x div ~1; val it = 2147483647 : Int32.int Comments: Fix: The fix is in (the upcoming) 110.18 Test: Owner: Lal, Leung Status: fixed in 110.18 (Leung) ---------------------------------------------------------------------- Number: 1510 Title: Signature matching bug makes "casts" possible Keywords: compiler, signature matching Submitter: Leif Kornstaedt Date: 07/05/1999 Version: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 System: x86-linux Severity: major Problem: Type-safety is compromised. Code: functor Cast(type from type to) :> sig type ('a, 'b) t = 'a -> 'b val cast: (from, to) t end = struct type ('a, 'b) t = 'a -> 'a fun cast x = x end structure IntListToIntOption = Cast(type from = int list type to = int option) val it = IntListToIntOption.cast [17] Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - use "castfunctor.sml"; [opening castfunctor.sml] functor Cast : structure IntListToIntOption : sig type ('a,'b) t = 'a -> 'b val cast : (from,to) t end val it = SOME 17 : ?.to val it = () : unit Comments: Fix: dummyargs function in TypesUtil (Semant/types/typesutil.sml) was producing a list of equal types, instead of distinct types. Use Stamps.fresh to generate distinct stamps for each type. Test: bug1510.1.sml, bug1510.2.sml Owner: dbm, Zhong Status: fixed in 110.0.7, 110.28 [dbm, 4/28/00] ---------------------------------------------------------------------- Number: 1511 Title: Compiler problem "tyvarType: CONty" Keywords: compiler Submitter: Leif Kornstaedt Date: 07/05/1999 Version: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 System: x86-linux Severity: minor Problem: Compiler aborts compilation with an error message Code: signature S = sig type ('a, 'b) t = 'a -> 'b val x: ('a, int) t end; structure M :> S = struct type ('a, 'b) t = 'a -> 'a fun x y = y end; Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - use "crash2.sml"; [opening crash2.sml] Error: Compiler bug: TypesUtil: tyvarType: CONty Comments: none Fix: none known Test: bug1511.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1512 Title: Nested absolute indent boxes don't work in PP library Keywords: SML-NJ library -- PP Submitter: David Casperson Date: 07/05/1999 Version: 110.0.3 System: not relevant Severity: ?? Problem: Nested absolute indent boxes are indented relative to the indent which exists at the time the box is created rather than relative to the indent of next outermost box. Code: (*--------------------------------------------------------------------------*) (* show bugs in sml PP package *) OS.FileSys.chDir "/csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/PP/" ; List.map use [ "src/pp-device-sig.sml", "src/pp-stream-sig.sml", "src/pp-token-sig.sml", "src/pp-stream-fn.sml", "devices/simple-textio-dev.sml" ] ; structure StringToken : PP_TOKEN = struct type token = string type style = unit fun string(x:token) = x ; fun style(x:token) = () fun size (x:token) = String.size x ; end; local structure PPStream = PPStreamFn(structure Token = StringToken and Device = SimpleTextIODev) ; open PPStream ; in datatype indent = datatype indent ; val strm1 = openStream (SimpleTextIODev.openDev {dst=TextIO.stdOut, wid=80}) ; val openHOVBox = openHOVBox strm1 ; val openVBox = openVBox strm1 ; val closeBox = (fn () => closeBox strm1) ; val flushStream = (fn () => flushStream strm1) ; val string = string strm1 ; val cut = (fn () => cut strm1) end ; fun go2() = ( openHOVBox (Abs (0)) ; string "Indented(" ; openHOVBox (Rel (0)) ; string "booogle" ; openVBox (Abs(0)) ; (* This should be indented inside the box above, but it isn't*) cut () ; string "line1" ; cut () ; string "line2" ; closeBox () ; cut () ; string ")" ; closeBox () ; cut () ; closeBox () ; flushStream () ) ; go2() ; (*--------------------------------------------------------------------------*) Transcript: (*--------------------------------------------------------------------------*) Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - [opening /csd2/home/casper/Sml/Code/test-pp-bug2.sml] val it = () : unit [opening src/pp-device-sig.sml] signature PP_DEVICE = sig type device type style val sameStyle : style * style -> bool val pushStyle : device * style -> unit val popStyle : device -> unit val defaultStyle : device -> style val depth : device -> int option val lineWidth : device -> int option val textWidth : device -> int option val space : device * int -> unit val newline : device -> unit val string : device * string -> unit val char : device * char -> unit val flush : device -> unit end [opening src/pp-stream-sig.sml] GC #0.0.0.0.1.11: (10 ms) signature PP_STREAM = sig type device type stream type token type style datatype indent = Abs of int | Rel of int val openStream : device -> stream val flushStream : stream -> unit val closeStream : stream -> unit val openHBox : stream -> unit val openVBox : stream -> indent -> unit val openHVBox : stream -> indent -> unit val openHOVBox : stream -> indent -> unit val openBox : stream -> indent -> unit val closeBox : stream -> unit val token : stream -> token -> unit val string : stream -> string -> unit val pushStyle : stream * style -> unit val popStyle : stream -> unit val break : stream -> {nsp:int, offset:int} -> unit val space : stream -> int -> unit val cut : stream -> unit val newline : stream -> unit val nbSpace : stream -> int -> unit val onNewline : stream -> unit -> unit end [opening src/pp-token-sig.sml] signature PP_TOKEN = sig type token type style val string : token -> string val style : token -> style val size : token -> int end [opening src/pp-stream-fn.sml] GC #0.0.0.1.2.37: (20 ms) [Autoloading...] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/hash-string.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fmt-fields.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/real-format.sml.bin...GC #0.0.0.1.3.43: (10 ms) done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue.sml.bin... done] [Autoloading done.] GC #0.0.0.1.4.56: (10 ms) src/pp-stream-fn.sml:294.4-294.78 Warning: binding not exhaustive PP {closed=_,curDepth=_,curIndent=_,dev=_,fmtStk=_,leftTot=leftTot, queue=_,rightTot=rightTot,scanStk=scanStk as ref ( :: ), spaceLeft=_,styleStk=_,width=_} = ... GC #0.0.0.1.5.85: (20 ms) GC #0.0.0.1.6.98: (10 ms) GC #0.0.0.1.7.110: (10 ms) GC #0.0.0.1.8.122: (10 ms) GC #0.0.0.1.9.123: (10 ms) GC #0.0.0.1.10.141: (0 ms) GC #0.0.1.2.11.142: (30 ms) GC #0.0.1.2.12.168: (10 ms) functor PPStreamFn : [opening devices/simple-textio-dev.sml] structure SimpleTextIODev : sig datatype device = ... type style = unit val sameStyle : style * style -> bool val pushStyle : device * style -> unit val popStyle : device -> unit val defaultStyle : device -> style val depth : device -> int option val lineWidth : device -> int option val textWidth : device -> int option val space : device * int -> unit val newline : device -> unit val string : device * string -> unit val char : device * char -> unit val flush : device -> unit val openDev : {dst:TextIO.outstream, wid:int} -> device end val it = [(),(),(),(),()] : unit list structure StringToken : PP_TOKEN GC #0.0.1.2.13.201: (0 ms) datatype indent = Abs of int | Rel of int val strm1 = PP {closed=ref false,curDepth=ref 1,curIndent=ref 0,dev=DEV {dst=-,wid=80}, fmtStk=ref [],leftTot=ref 1,queue=-,rightTot=ref 1, scanStk=ref [(#,#),(#,#)],spaceLeft=ref 80,styleStk=ref [],width=80} : ?.PPStream.stream val openHOVBox = fn : indent -> unit val openVBox = fn : indent -> unit val closeBox = fn : unit -> unit val flushStream = fn : unit -> unit val string = fn : string -> unit val cut = fn : unit -> unit val go2 = fn : unit -> unit Indented(booogle line1 line2)val it = () : unit val it = () : unit - (*--------------------------------------------------------------------------*) Comments: I am not 100% sure what is intended in the original code. I am also not sure if I have sent this report to the right place. The following fix definitely seems to help. The old code has problems because the curIndent may not be set until later. Fix: *************** *** 207,215 **** val PP{curIndent, spaceLeft, width, fmtStk, ...} = strm val spaceLeft' = !spaceLeft val insPt = width - spaceLeft' ! val offset = (case indent ! of (Rel off) => spaceLeft' - off ! | (Abs off) => width - (!curIndent + off) (* end case *)) (***** CAML version does the following: **** val _ = if (insPt > maxIndent) --- 209,218 ---- val PP{curIndent, spaceLeft, width, fmtStk, ...} = strm val spaceLeft' = !spaceLeft val insPt = width - spaceLeft' ! val offset = (case (indent,!fmtStk) ! of ((Rel off),_) => spaceLeft' - off ! | ((Abs off),(_,wid)::_) => wid - off ! | ((Abs off), nil) => width - off (* end case *)) (***** CAML version does the following: **** val _ = if (insPt > maxIndent) Test: * Owner: jhr Status: fixed in 110.0.4 and 110.19 (jhr, 7/5/99) ---------------------------------------------------------------------- Number: 1513 Title: Nested boxes containing breaks mess up scan stack in PP Keywords: SML-NJ library -- PP Submitter: David Casperson Date: 05/07/1999 Version: 110.0.3 System: not relevant Severity: ?? Problem: breaks and end-boxes don't interact correctly Code: (*--------------------------------------------------------------------------*) (* show bugs in sml PP package *) OS.FileSys.chDir "/csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/PP/" ; List.map use [ "src/pp-device-sig.sml", "src/pp-stream-sig.sml", "src/pp-token-sig.sml", "src/pp-stream-fn.sml", "devices/simple-textio-dev.sml" ] ; structure StringToken : PP_TOKEN = struct type token = string type style = unit fun string(x:token) = x ; fun style(x:token) = () fun size (x:token) = String.size x ; end; local structure PPStream = PPStreamFn(structure Token = StringToken and Device = SimpleTextIODev) ; open PPStream ; in datatype indent = datatype indent ; val strm1 = openStream (SimpleTextIODev.openDev {dst=TextIO.stdOut, wid=80}) ; val openHOVBox = openHOVBox strm1 ; val openVBox = openVBox strm1 ; val closeBox = (fn () => closeBox strm1) ; val flushStream = (fn () => flushStream strm1) ; val string = string strm1 ; val cut = (fn () => cut strm1) end ; fun go1 () = ( openHOVBox (Abs(0)) ; string "bad " ; cut () ; (* This should not cause a break!! *) openHOVBox (Abs(0)) ; string "cut " ; cut() ; string "here." ; closeBox() ; cut() ; string " Shouldn't have happened." ; closeBox() ; flushStream () ) ; go1() ; (*--------------------------------------------------------------------------*) Transcript: (*--------------------------------------------------------------------------*) Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - [opening /csd2/home/casper/Sml/Code/test-pp-bug1.sml] val it = () : unit [opening src/pp-device-sig.sml] signature PP_DEVICE = sig type device type style val sameStyle : style * style -> bool val pushStyle : device * style -> unit val popStyle : device -> unit val defaultStyle : device -> style val depth : device -> int option val lineWidth : device -> int option val textWidth : device -> int option val space : device * int -> unit val newline : device -> unit val string : device * string -> unit val char : device * char -> unit val flush : device -> unit end [opening src/pp-stream-sig.sml] GC #0.0.0.0.1.11: (10 ms) signature PP_STREAM = sig type device type stream type token type style datatype indent = Abs of int | Rel of int val openStream : device -> stream val flushStream : stream -> unit val closeStream : stream -> unit val openHBox : stream -> unit val openVBox : stream -> indent -> unit val openHVBox : stream -> indent -> unit val openHOVBox : stream -> indent -> unit val openBox : stream -> indent -> unit val closeBox : stream -> unit val token : stream -> token -> unit val string : stream -> string -> unit val pushStyle : stream * style -> unit val popStyle : stream -> unit val break : stream -> {nsp:int, offset:int} -> unit val space : stream -> int -> unit val cut : stream -> unit val newline : stream -> unit val nbSpace : stream -> int -> unit val onNewline : stream -> unit -> unit end [opening src/pp-token-sig.sml] signature PP_TOKEN = sig type token type style val string : token -> string val style : token -> style val size : token -> int end [opening src/pp-stream-fn.sml] GC #0.0.0.1.2.37: (20 ms) [Autoloading...] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/hash-string.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fmt-fields.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/real-format.sml.bin...GC #0.0.0.1.3.43: (0 ms) done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue-sig.sml.bin... done] [recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue.sml.bin... done] [Autoloading done.] GC #0.0.0.1.4.56: (10 ms) src/pp-stream-fn.sml:294.4-294.78 Warning: binding not exhaustive PP {closed=_,curDepth=_,curIndent=_,dev=_,fmtStk=_,leftTot=leftTot, queue=_,rightTot=rightTot,scanStk=scanStk as ref ( :: ), spaceLeft=_,styleStk=_,width=_} = ... GC #0.0.0.1.5.85: (20 ms) GC #0.0.0.1.6.98: (10 ms) GC #0.0.0.1.7.110: (10 ms) GC #0.0.0.1.8.122: (10 ms) GC #0.0.0.1.9.123: (10 ms) GC #0.0.0.1.10.141: (10 ms) GC #0.0.1.2.11.142: (30 ms) GC #0.0.1.2.12.168: (10 ms) functor PPStreamFn : [opening devices/simple-textio-dev.sml] structure SimpleTextIODev : sig datatype device = ... type style = unit val sameStyle : style * style -> bool val pushStyle : device * style -> unit val popStyle : device -> unit val defaultStyle : device -> style val depth : device -> int option val lineWidth : device -> int option val textWidth : device -> int option val space : device * int -> unit val newline : device -> unit val string : device * string -> unit val char : device * char -> unit val flush : device -> unit val openDev : {dst:TextIO.outstream, wid:int} -> device end val it = [(),(),(),(),()] : unit list structure StringToken : PP_TOKEN GC #0.0.1.2.13.201: (0 ms) datatype indent = Abs of int | Rel of int val strm1 = PP {closed=ref false,curDepth=ref 1,curIndent=ref 0,dev=DEV {dst=-,wid=80}, fmtStk=ref [],leftTot=ref 1,queue=-,rightTot=ref 1, scanStk=ref [(#,#),(#,#)],spaceLeft=ref 80,styleStk=ref [],width=80} : ?.PPStream.stream val openHOVBox = fn : indent -> unit val openVBox = fn : indent -> unit val closeBox = fn : unit -> unit val flushStream = fn : unit -> unit val string = fn : string -> unit val cut = fn : unit -> unit val go1 = fn : unit -> unit bad cut here. Shouldn't have happened.val it = () : unit val it = () : unit - (*--------------------------------------------------------------------------*) Comments: This is clearly just a typo in the source. As it is, any box containing a break messes up the scan stack. Fix: *************** *** 342,349 **** (* check that depth < maxDepth *) ****) enqueueTok (strm, {sz = ref 0, tok = END, len = 0}); ! setSize (strm, false); ! setSize (strm, true); curDepth := depth-1) else raise Fail "unmatched close box" --- 345,352 ---- (* check that depth < maxDepth *) ****) enqueueTok (strm, {sz = ref 0, tok = END, len = 0}); ! setSize (strm, true); (* interchanged with following *) ! setSize (strm, false); (* 05 Jul 1999. dgc. *) curDepth := depth-1) else raise Fail "unmatched close box" Test: * Owner: jhr Status: fixed in 110.0.4 (jhr, 110.0.4) ---------------------------------------------------------------------- Number: 1514 Title: sockets c-library broken Keywords: sockets Submitter: Johannes 5 Joemann Date: 07/07/1999 Version: 110.17 System: Any/All Severity: major Problem: Parameters given from ML to the runtime sockets library are not correctly interpreted, obviously due to a change in their representation (as was pointed out by jhr in bug 1480) that is not reflected in the usage of the appropriate (de-)referencing C macros. So when you try to open a connection you get NO CARRIER;) e.g. SysErr: No such file or directory [noent] Code: Transcript: - UnixSock.toAddr "/tmp/.s.PGSQL.5432"; val it = ADDR - : UnixSock.sock_addr - UnixSock.fromAddr it; val it = "\213 +" : string Comments: The patches below are sufficient to do TCP connections to Postgres and open a Unix domain socket. I didn't check the whole sockets lib, if you think it helps if I check out more, let me know. Since this is the first (and hopefully the last:-) time I looked at this runtime C lib stuff, no guarantee that the patches are in tune with what your intention of using the macros is. It just works the way I did it. Fix: *** connect.c 1999/07/05 23:57:30 1.1 --- connect.c 1999/07/07 03:07:17 *************** *** 21,27 **** ml_val_t addr = REC_SEL(arg, 1); int sts; ! sts = connect (sock, PTR_MLtoC(struct sockaddr, addr), OBJ_LEN(addr)); CHK_RETURN_UNIT(msp, sts); --- 21,27 ---- ml_val_t addr = REC_SEL(arg, 1); int sts; ! sts = connect (sock, GET_SEQ_DATAPTR(struct sockaddr, addr), REC_SELINT(addr, 1)); CHK_RETURN_UNIT(msp, sts); *** from-unixaddr.c 1999/07/07 00:51:23 1.1 --- from-unixaddr.c 1999/07/07 01:00:36 *************** *** 20,26 **** */ ml_val_t _ml_Sock_fromunixaddr (ml_state_t *msp, ml_val_t arg) { ! struct sockaddr_un *addr = PTR_MLtoC(struct sockaddr_un, arg); ASSERT(addr->sun_family == AF_UNIX); --- 20,26 ---- */ ml_val_t _ml_Sock_fromunixaddr (ml_state_t *msp, ml_val_t arg) { ! struct sockaddr_un *addr = GET_SEQ_DATAPTR(struct sockaddr_un, arg); ASSERT(addr->sun_family == AF_UNIX); *** from-inetaddr.c 1999/07/07 01:22:10 1.1 --- from-inetaddr.c 1999/07/07 01:25:21 *************** *** 21,27 **** */ ml_val_t _ml_Sock_frominetaddr (ml_state_t *msp, ml_val_t arg) { ! struct sockaddr_in *addr = PTR_MLtoC(struct sockaddr_in, arg); ml_val_t inAddr, res; ASSERT (addr->sin_family == AF_INET); --- 21,27 ---- */ ml_val_t _ml_Sock_frominetaddr (ml_state_t *msp, ml_val_t arg) { ! struct sockaddr_in *addr = GET_SEQ_DATAPTR(struct sockaddr_in, arg); ml_val_t inAddr, res; ASSERT (addr->sin_family == AF_INET); *** to-inetaddr.c 1999/07/07 02:28:05 1.1 --- to-inetaddr.c 1999/07/07 02:33:17 *************** *** 22,32 **** ml_val_t _ml_Sock_toinetaddr (ml_state_t *msp, ml_val_t arg) { struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; ! memcpy (&addr.sin_addr, REC_SELPTR(char, arg, 0), sizeof(struct in_addr)); addr.sin_port = htons(REC_SELINT(arg, 1)); return ML_CData (msp, &addr, sizeof(struct sockaddr_in)); --- 22,33 ---- ml_val_t _ml_Sock_toinetaddr (ml_state_t *msp, ml_val_t arg) { struct sockaddr_in addr; + ml_val_t inAddr = REC_SEL(arg, 0); memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; ! memcpy (&addr.sin_addr, GET_SEQ_DATAPTR(char, inAddr), sizeof(struct in_addr)); addr.sin_port = htons(REC_SELINT(arg, 1)); return ML_CData (msp, &addr, sizeof(struct sockaddr_in)); Test: * Owner: jhr Status: fixed in 110.31 ---------------------------------------------------------------------- Number: 1515 Title: ML signal handling broken since 110.15 Keywords: runtime, signals Submitter: Roland McGrath Date: 7/19/1999 Version: 110.20 (and back through 110.15) System: all Severity: major Problem: ML signals don't work Code: just try it, clearly noone has since 110.15 Transcript: it crashes, trust me Comments: It seems clear the ML signals code in the runtime never ran once. Fix: Below find a patch to runtime/mach-dep/signal-util.c with the fix. This patch also includes a fix I previously reported that never got merged in. Enjoy. Index: smlnj/runtime/mach-dep/signal-util.c diff -u smlnj/runtime/mach-dep/signal-util.c:1.1.1.2 smlnj/runtime/mach-dep/signal-util.c:1.2.2.2 --- smlnj/runtime/mach-dep/signal-util.c:1.1.1.2 Tue Mar 23 04:14:17 1999 +++ smlnj/runtime/mach-dep/signal-util.c Mon Jul 19 03:14:30 1999 @@ -31,9 +31,9 @@ vsp->vp_sigCode = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].sigNum; vsp->vp_sigCount = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].count; if (IS_SYSTEM_SIG(vsp->vp_sigCode)) - vsp->vp_numPendingSigs -= vsp->vp_sigCount; + vsp->vp_numPendingSysSigs -= vsp->vp_sigCount; else - vsp->vp_numPendingSysSigs -= vsp->vp_sigCount; + vsp->vp_numPendingSigs -= vsp->vp_sigCount; /* advance the pending queue */ if ((--vsp->vp_numInQ == 0) || (++vsp->vp_nextPendingSig == NUM_SIGS)) @@ -89,7 +89,7 @@ ml_val_t MakeResumeCont (ml_state_t *msp, ml_val_t resume[]) { /* allocate the resumption closure */ - ML_AllocWrite(msp, 0, MAKE_DESC(10, DTAG_record)); + ML_AllocWrite(msp, 0, MAKE_DESC(11, DTAG_record)); ML_AllocWrite(msp, 1, PTR_CtoML(resume)); ML_AllocWrite(msp, 2, msp->ml_arg); ML_AllocWrite(msp, 3, msp->ml_cont); @@ -153,16 +153,16 @@ contClosure = PTR_MLtoC(ml_val_t, msp->ml_closure); - msp->ml_arg = contClosure[2]; - msp->ml_cont = contClosure[3]; - msp->ml_closure = contClosure[4]; - msp->ml_linkReg = contClosure[5]; - msp->ml_linkReg = contClosure[6]; - msp->ml_exnCont = contClosure[7]; - msp->ml_varReg = contClosure[8]; - msp->ml_calleeSave[0] = contClosure[9]; - msp->ml_calleeSave[1] = contClosure[10]; - msp->ml_calleeSave[2] = contClosure[11]; + msp->ml_arg = contClosure[1]; + msp->ml_cont = contClosure[2]; + msp->ml_closure = contClosure[3]; + msp->ml_linkReg = contClosure[4]; + msp->ml_pc = contClosure[5]; + msp->ml_exnCont = contClosure[6]; + msp->ml_varReg = contClosure[7]; + msp->ml_calleeSave[0] = contClosure[8]; + msp->ml_calleeSave[1] = contClosure[9]; + msp->ml_calleeSave[2] = contClosure[10]; } /* end of LoadResumeState */ @@ -183,4 +183,3 @@ return FALSE; } /* end of GCSignal */ As well as the fixes to signal-util.c that I sent previously, this additional change to mach-dep/X86.prim.asm was necessary for ML signal handling to work (without this change, it still crashes). I tested x86-linux and x86-freebsd platforms. I don't know if there are analogous bugs in `sigh_resume' routine on other platforms. Index: X86.prim.asm =================================================================== RCS file: /projects/express/cvsroot/smlnj/runtime/mach-dep/X86.prim.asm,v retrieving revision 1.5.2.2 diff -u -b -p -r1.5.2.2 X86.prim.asm --- X86.prim.asm 1999/05/09 19:50:31 1.5.2.2 +++ X86.prim.asm 1999/07/19 23:24:22 @@ -168,7 +168,6 @@ ML_CODE_HDR(sigh_return_a) ENTRY(sigh_resume) movl IMMED(REQ_SIG_RESUME), request_w movl IMMED(ML_unit),stdlink - movl IMMED(ML_unit),stdclos movl IMMED(ML_unit),pc jmp CSYM(set_request) Comments: [Matthias, 7/20/99] Hmm, what exactly are the symptoms of this "broken signals" thing? As far as I can tell, ^C does work as expected on my Linux box. This would indicated that signal handling -- at least for SIGINT -- works. (This is in versions 110.17...110.20.) Am I just being lucky? [Roland McGrath , 7/19/99] I was not quite clear in my description of the problem. It indeed handles the signals fine, it's resuming the interrupted ML code after the handler that crashes every time. Since the handler for SIGINT just throws back to the REPL and never tries to resume the interrupted code, you don't notice it. Try for example: Signals.setHandler (UnixSignals.sigQUIT, Signals.HANDLER (fn (_,_,k) => (print "interrupted\n"; k))); and then generate a SIGQUIT from the keyboard (usually ^\). Here's an example session from 110.16 (the runtime code in question is unchanged between 110.15 and 110.20): Standard ML of New Jersey v110.16 [FLINT v1.5], April 15, 1999 [CM; autoload enabled] - Signals.setHandler (UnixSignals.sigQUIT, Signals.HANDLER (fn (_,_,k) => (print "interrupted\n"; k))); val it = HANDLER fn : Signals.sig_action - [[[[ here I hit ^\ on the terminal ]]]]interrupted /work/express/stock-smlnj/bin/sml: Fatal error -- bogus fault not in ML: (11, 0x804c699) Process sml exited abnormally with code 1 [Matthias, 6/20/01] Amazingly, 1 year and 11 months after the bug was reported (and fixed!), the fix is now finally in... Somehow Roland's patch did get applied only partially; MakeResumeCont still constructed a record with an incorrect descriptor (wrong length). After discussion with John (Reppy) we agreed that the correct solution is to construct a 10-element record after all because "varReg" is supposed to be a per-execution-context value that is not to be overridden when invoking a continuation. (Right now this probably would not have mattered much because we have only one execution context.) Test: * Owner: jhr Status: fixed in 110.34 (06/19/01) by blume and jhr ---------------------------------------------------------------------- Number: 1516 Title: mode bits for heap2exec output file Keywords: heap2exec Submitter: Jeff Foster Date: 7/15/99 Version: - System: - Severity: medium Problem: We recently discovered a minor bug in heap2exec while using it to build a stand-alone program analysis tool. When heap2exec creates the new output file: if ((out_fd = open(argv[EXEC_POS],O_WRONLY|O_CREAT|O_TRUNC)) == -1) { the mode bits for the new file are omitted. Apparently when the O_CREAT flag is specified the mode bits are required. When they are omitted, whatever random garbage is on the stack is used for the mode bits. As a result, whenever we run heap2exec the resulting file has the group sticky bit set, which causes us all sorts of problems. Fix: The solution is to specify the mode bits, e.g., if ((out_fd = open(argv[EXEC_POS],O_WRONLY|O_CREAT|O_TRUNC,0777)) == -1) { Test: Owner: Lorenz Status: fixed (Lorenz, 7/15/99) ---------------------------------------------------------------------- Number: 1517 Title: "New CM-manager" linking bug Keywords: Compilation Manager, private directive, linking Submitter: Simon Helsen, shelsen@acm.org Date: 07/26/99 Version: Standard ML of New Jersey v110.20 [FLINT v1.5], July 16, 1999 System: PentiumII, Linux (Kernel) 2.0.37 Severity: major Problem: The new CM raises an Error due to ill-treating the "private"-directive. The error occurs in the second compilation within one sml session. It seems a plain bug in the implementation of the private directive in CM Code: The following two files already produce the error: test.sml -------- structure Nonsense = struct val id = 4 end sources.cm ---------- Library structure Nonsense is test.sml : private Transcript: for the above example: Standard ML of New Jersey v110.20 [FLINT v1.5], July 16, 1999 - CM.make "sources.cm"; [scanning ./sources.cm] [parsing ./test.sml] [creating directory ./CM/SKEL ...] [compiling ./test.sml] [creating directory ./CM/x86-unix ...] [wrote ./CM/x86-unix/test.sml] [New bindings added.] val it = true : bool - CM.make "sources.cm"; [scanning ./sources.cm] ./sources.cm:4.1-4.9 Error: link-time error in ./test.sml NoCodeBug val it = false : bool - Comments: none [Matthias, 7/27/99] Thanks for the bug report. Looks like I am discarding executable code too early in the case of non-shareable modules. I'll look into this. (I am currently revising the internal recompile logic anyway, so I should be able to fix this problem while doing so.) PS: Could you tell me what you need the "private" directive for? I am looking for a realistic example because I was even thinking of dropping "private" altogether because it causes CM's internal logic to become quite complex -- much more complex than I would like it to be. Fix: - Test: * Owner: Matthias Status: fixed in 110.24 [Matthias, 11/5/99] ---------------------------------------------------------------------- Number: 1518 Title: Posix.IO.FLock.flock type disagrees with basis library spec Keywords: flock Submitter: Stephen Weeks Date: 08/14/99 Version: 110.9.1 System: x86-linux Severity: Problem: The spec does not have the "l_" prefixing each field in the record. Posix.IO.FLock.flock; val it = fn : {l_len:int, l_pid:?.POSIX_IO.pid option, l_start:int, l_type:?.POSIX_IO.lock_type, l_whence:?.POSIX_IO.whence} -> ?.POSIX_IO.FLock.flock Code: Transcript: Comments: Fix: Test: * Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1519 Title: Compiler bug: HppaCG.incOffset - spill area too small Keywords: spill area, HPPA Submitter: Chris Waters Date: 09/01/99 Version: 110.0.3 System: HPPA HPUX Subsystem: SML compiler Severity: major Problem: Using a very large Yacc file the compiler gives up and crashes with the above error. It also returns these messages : raised at: util/errormsg.sml:54.14-54.19 util/stats.sml:164.40 util/stats.sml:164.40 sched/recompile.sml:206.38-206.41 Comments: Fix: Test: Owner: Lal, Allen Status: open ---------------------------------------------------------------------- Number: 1520 Title: Output of type variables Keywords: types Submitter: Andreas Rossberg, rossberg@ps.uni-sb.de Date: 09/03/1999 Version: 110.0.3 System: Linux Severity: cosmetic Problem: When printing types with more than 26^2 type variables, identifiers generated for the higher variables are junk. Code: fun f(x,y) = x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x val f = fn x => (f o f) x Transcript: Was not possible to paste here because it contained invalid characters :-( Comments: - Fix: Just make the function to generate tyvar ids more general. Test: * Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1521 Title: random crashes on AMD K6-III Keywords: x86, AMD, crashes Submitter: Alain Deutsch Date: 8/16/99 Version: ??? System: AMD K6-III/450, Linux Severity: critical Problem: We are experiencing fairly surprising problems with SML/NJ running on an AMD K6-III/450 based Linux machine. Problems are: random SML crashes, often during garbage collection, in the form of various inconsistencies detected by the GC. Our application program runs perfectly on a similar Linux machine that is equipped with an Intel PIII/550. SML/NJ version and Linux version are exactly the same on both machines. Did you hear similar reports by other users ? Do you think this could possibly related to the fact that the K6 has separate instruction and data caches, and that the contents of the instruction cache may be incorrect due to the fact that SML GC relocates code segments ? If so, would a cache flush instruction at the end of GC solve the problem? Code: Transcript: Comments: That might very well be the problem, but one needs to do the flush after code is allocated. The source code uses a macro called FlushICache to invoke flushing of the instruction cache where needed. You migh try changing its definition in runtime/include/cache-flush.h and rebuilding the run-time to see if the problem goes away. Fix: Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1522 Title: Replication of replicated datatype - not allowed Keywords: compiler, modules Submitter: Leif Kornstaedt Date: 08/19/1999 Version: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 System: x86-win32 Severity: major Problem: It is not possible to replicate a datatype defined in a structure with an opaque signature constraint. In my understanding of the Definition, this should be possible (correct me if I'm wrong!). Code: structure S0 = struct datatype t = C | D end; signature S = sig datatype t = datatype S0.t end; structure S1 :> S = struct datatype t = datatype S0.t end; structure S2 = struct datatype t = datatype S1.t end; Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - use "replic.sml"; [opening replic.sml] replic.sml:18.3-18.29 Error: rhs of datatype replication not a datatype Comments: Fix: - Test: bug1522.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1523 Title: installing SML/NJ-C Foreign Function Interface library Keywords: foreign function Submitter: Ovidiu Podisor Ovidiu.Podisor@innovative.ro Date: 09/27/99 Version: 110.0.3, January 30, 1998 System: x86 Linux RedHat 6.0 Subsystem: Installation Severity: critical Problem: Link error when building the run time system with smlnj-ccalls enabled. The problem lies in the fact that CALL_BIAS is not macro-expanded in the line: subl $CALL_BIAS,%eax /* adjust pc to point at "->" */ because of the '$' character. See below for a fix. Transcript: [root@smarald objs]# make -f mk.x86-linux-ccalls (make RUNTIME="run.x86-linux" VERSION="v-x86-linux" CC="gcc -ansi" CFLAGS="-O" CPP="gcc -x c -E -P -ansi" TARGET=X86 DEFS=" -DHOST_X86 -DTARGET_X86 -DOPSYS_UNIX -DOPSYS_LINUX -D_POSIX_SOURCE -D_BSD_SOURCE -DVREGS -DCALLEESAVE=3 -D_SIGCONTEXT_H -DC_CALLS" XOBJS="" XLIBS="" LD_LIBS="" XCLIBS="../c-libs/smlnj-ccalls/libsmlnj-ccalls.a" run.x86-linux) make[1]: Entering directory `/usr/share/smlnj/src/runtime/objs' ... make[2]: Leaving directory `/usr/share/smlnj/src/runtime/memory' gcc -ansi -o run.x86-linux -O main.o c-libraries.o unix-raise-syserr.o ml-options.o new-boot.o load-ml.o run-ml.o globals.o ml-state.o error.o timers.o unix-timers.o qualify-name.o swap-bytes.o unix-fault.o signal-util.o unix-signal.o unix-prof.o prim.o ../c-libs/smlnj-ccalls/libsmlnj-ccalls.a ../c-libs/posix-os/libposix-os.a ../c-libs/smlnj-runtime/libsmlnj-runt.a ../c-libs/smlnj-signals/libsmlnj-sig.a ../c-libs/smlnj-prof/libsmlnj-prof.a ../c-libs/smlnj-sockets/libsmlnj-sock.a ../c-libs/smlnj-time/libsmlnj-time.a ../c-libs/smlnj-date/libsmlnj-date.a ../c-libs/smlnj-math/libsmlnj-math.a ../c-libs/posix-process/libposix-process.a ../c-libs/posix-procenv/libposix-procenv.a ../c-libs/posix-filesys/libposix-filesys.a ../c-libs/posix-io/libposix-io.a ../c-libs/posix-sysdb/libposix-sysdb.a ../c-libs/posix-signal/libposix-signal.a ../c-libs/posix-tty/libposix-tty.a ../c-libs/posix-error/libposix-error.a ../gc/libgc.a ../memory/libmem.a -lm ../c-libs/smlnj-ccalls/libsmlnj-ccalls.a(c-entry.o)(.text+0x6): undefined reference to `CALL_BIAS' collect2: ld returned 1 exit status make[1]: *** [run.x86-linux] Error 1 make[1]: Leaving directory `/usr/share/smlnj/src/runtime/objs' make: *** [all] Error 2 Comments: Fix: [root@smarald smlnj-ccalls]# diff /usr/share/smlnj/src/runtime/c-libs/smlnj-ccalls/c-entry.asm /usr/share/mathc/src/runtime/c-libs/smlnj-ccalls/c-entry.asm 7,12d6 < < #if defined(TARGET_X86) < #define CONCAT(a,b) CONCAT_(a,b) < #define CONCAT_(a,b) a ## b < < #define CALL_BIAS 5 14c8,10 < #define cresult %eax --- > #if defined(TARGET_X86) > #define CALL_BIAS 5 > #define cresult %eax 79c75 < subl CONCAT($,CALL_BIAS),%eax /* adjust pc to point at "->" */ --- > subl $CALL_BIAS,%eax /* adjust pc to point at "->" */ Test: - Owner: Lorenz Status: open ---------------------------------------------------------------------- Number: 1524 Title: Bus Error Keywords: allocation space, GC Submitter: Simon Helsen, shelsen@acm.org Date: 10/7/99 Version: Standard ML of New Jersey v110.23 [FLINT v1.5], October 8, 1999 System: PentiumII 450, Linux (Kernel) 2.0.37 Severity: major Problem: After compilation/loading and linking, CM.make crashes with a "bus error" report on the x86-linux platform. The problem does not occur everywhere (i.e. in some CM library collections it doesn't happen) and it doesn't occur at all on a sparc-unix platform for exactly the same software Code: /home/sml/Dev/bugs/bug1524 (http://optpcs.cs.nyu.edu/~leunga/buserror.tar.gz) Transcript: mlope/control> /home/helsen/languages/ml/smlnj/bin/sml > transcript CM.make "sources.cm"; GC #0.0.0.0.1.7: (10 ms) GC #0.0.0.0.2.49: (20 ms) GC #0.0.0.1.3.121: (30 ms) GC #0.0.0.1.4.165: (20 ms) GC #0.0.0.1.5.219: (20 ms) GC #0.0.0.1.6.222: (10 ms) GC #0.0.0.1.7.239: (0 ms) GC #0.0.0.1.8.247: (0 ms) GC #0.0.0.1.9.273: (0 ms) GC #0.0.0.1.10.297: (10 ms) GC #0.0.1.2.11.323: (60 ms) GC #0.0.1.2.12.378: (10 ms) GC #0.0.1.2.13.395: (10 ms) GC #0.0.1.2.14.404: (0 ms) Bus error mlope/control> ------------------ and diagnostic contains this : ------------------ Standard ML of New Jersey v110.23 [FLINT v1.5], October 8, 1999 - [autoloading] [autoloading done] [scanning ./sources.cm] [scanning ./../library/sources.cm] [scanning ./../library/array/sources.cm] [scanning ./../library/array/../basic/sources.cm] [scanning ./../library/array/../basic/../pervasive/sources.cm] [scanning ./../library/array/../basic/../pervasive/../nj-basis/sources.cm] [scanning ./../library/array/../list/sources.cm] [scanning ./../library/array/../list/../number/sources.cm] [scanning ./../library/array/../list/../number/../smlnj-lib/sources.cm] [scanning ./../library/array/../list/../number/../from_basis.cm] [scanning ./../library/array/../list/../promise/sources.cm] [scanning ./../library/array/../list/../sequence/sources.cm] [scanning ./../library/array/../list/../sequence/../container/sources.cm] [scanning ./../library/directed-graph/sources.cm] [scanning ./../library/directed-graph/../misc/sources.cm] [scanning ./../library/directed-graph/../misc/../time/sources.cm] [scanning ./../library/directed-graph/../property/sources.cm] [scanning ./../library/directed-graph/../set/sources.cm] [scanning ./../library/directed-graph/../set/../trace/sources.cm] [scanning ./../library/env/sources.cm] [scanning ./../library/ml-yacc-lib/sources.cm] [./../library/array/../basic/CM/x86-unix/relation.sig loaded] [./../library/array/../basic/CM/x86-unix/relation.sml loaded] [./../library/array/../basic/../pervasive/../nj-basis/CM/x86-unix/int-inf-sig.sml loaded] [./../library/array/../basic/../pervasive/../nj-basis/CM/x86-unix/int-inf.sml loaded] [./../library/array/../basic/../pervasive/CM/x86-unix/pervasive.sml loaded] [./../library/array/../basic/CM/x86-unix/outstream.sig loaded] [./../library/array/../basic/CM/x86-unix/dynamic-wind.sig loaded] [./../library/array/../basic/CM/x86-unix/dynamic-wind.sml loaded] [./../library/array/../basic/CM/x86-unix/outstream.sml loaded] [./../library/array/../basic/CM/x86-unix/layout.sig loaded] [./../library/array/../basic/CM/x86-unix/order0.sig loaded] [./../library/array/../basic/CM/x86-unix/char0.sig loaded] [./../library/array/../basic/CM/x86-unix/string0.sig loaded] [./../library/array/../basic/CM/x86-unix/char0.sml loaded] [./../library/array/../basic/CM/x86-unix/string0.sml loaded] [./../library/array/../basic/CM/x86-unix/layout.sml loaded] [./../library/array/../basic/CM/x86-unix/instream.sig loaded] [./../library/array/../basic/CM/x86-unix/instream.sml loaded] [./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/random-sig.sml loaded] [./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/lib-base-sig.sml loaded] [./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/lib-base.sml loaded] [./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/random.sml loaded] [./../library/array/../basic/CM/x86-unix/t.sig loaded] [./../library/array/../list/../number/CM/x86-unix/basic-ring.sig loaded] [./../library/array/../list/../number/CM/x86-unix/ring.sig loaded] [./../library/array/../list/../number/CM/x86-unix/ordered-ring.sig loaded] [./../library/array/../list/../number/CM/x86-unix/integer.sig loaded] [./../library/array/../list/../number/CM/x86-unix/fixed-integer.sig loaded] [./../library/array/../basic/CM/x86-unix/iterate.sig loaded] [./../library/array/../basic/CM/x86-unix/iterate.sml loaded] [./../library/array/../list/../number/CM/x86-unix/ring.fun loaded] [./../library/array/../list/../number/CM/x86-unix/basic-ordered-ring.sig loaded] [./../library/array/../list/../number/CM/x86-unix/ordered-ring.fun loaded] [./../library/array/../list/../number/CM/x86-unix/basic-integer.sig loaded] [./../library/array/../list/../number/CM/x86-unix/integer.fun loaded] [./../library/array/../list/../number/CM/x86-unix/fixed-integer.sml loaded] [./../library/array/../basic/CM/x86-unix/ref.sig loaded] [./../library/array/../basic/CM/x86-unix/error.sig loaded] [./../library/array/../basic/CM/x86-unix/error.sml loaded] [./../library/array/../basic/CM/x86-unix/ref.sml loaded] [./../library/array/../list/../number/CM/x86-unix/ring-elt-ref.sig loaded] [./../library/array/../list/../number/CM/x86-unix/ring-elt-ref.fun loaded] [./../library/array/../list/../number/CM/x86-unix/int-ref.sml loaded] [./../library/array/../list/../sequence/../container/CM/x86-unix/container.sig loaded] [./../library/array/../list/../sequence/CM/x86-unix/sequence.sig loaded] [./../library/array/../list/../sequence/CM/x86-unix/destructable.sig loaded] [./../library/array/../list/CM/x86-unix/list.sig loaded] [./../library/array/../list/CM/x86-unix/strict.sig loaded] [./../library/array/../list/../sequence/CM/x86-unix/basic.sig loaded] [./../library/array/../list/../sequence/CM/x86-unix/destructable.fun loaded] [./../library/array/../list/CM/x86-unix/basic.sig loaded] [./../library/array/../list/CM/x86-unix/basic-iter.sig loaded] [./../library/array/../list/CM/x86-unix/list.fun loaded] [./../library/array/../list/CM/x86-unix/strict.fun loaded] [./../library/array/../list/CM/x86-unix/iter.fun loaded] [./../library/array/../list/CM/x86-unix/basic-strict.sig loaded] [./../library/array/../list/CM/x86-unix/basic-strict.fun loaded] [./../library/array/../list/CM/x86-unix/strict.sml loaded] [./../library/array/../list/CM/x86-unix/list-ref.sig loaded] [./../library/array/../list/CM/x86-unix/list-ref.fun loaded] [./CM/x86-unix/region.sig loaded] [./CM/x86-unix/region.fun loaded] [./../library/array/../basic/CM/x86-unix/order.sig loaded] [./../library/directed-graph/../misc/../time/CM/x86-unix/time.sig loaded] [./../library/directed-graph/../misc/../time/CM/x86-unix/time.fun loaded] [./../library/array/../basic/CM/x86-unix/unit.sig loaded] [./../library/array/../basic/CM/x86-unix/unit.sml loaded] [./../library/array/../basic/CM/x86-unix/string.sig loaded] [./../library/array/../basic/CM/x86-unix/string.sml loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/computation.sig loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/trace.sig loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/intermediate-computation.sig loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/string-map.sig loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/trace.fun loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/intermediate-computation.fun loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/string-map.fun loaded] [./../library/directed-graph/../set/../trace/CM/x86-unix/link.sml loaded] [./../library/array/../basic/CM/x86-unix/char.sig loaded] [./../library/array/../basic/CM/x86-unix/char.sml loaded] [./../library/directed-graph/../misc/CM/x86-unix/dir.sig loaded] [./../library/directed-graph/../misc/CM/x86-unix/file.sig loaded] [./../library/directed-graph/../misc/CM/x86-unix/process.sig loaded] [./../library/directed-graph/../misc/CM/x86-unix/process.sml loaded] [./../library/directed-graph/../misc/CM/x86-unix/filesys.fun loaded] [./../library/directed-graph/../misc/../time/CM/x86-unix/date.sig loaded] [./../library/directed-graph/../misc/../time/CM/x86-unix/date.fun loaded] [./../library/array/../basic/CM/x86-unix/bool.sig loaded] [./../library/array/../basic/CM/x86-unix/bool.sml loaded] [./CM/x86-unix/control.sig loaded] [./CM/x86-unix/control.sml loaded] [linking with $basis.cm/basis.cm@145608(general.sig)] [linking with $basis.cm/basis.cm@144582(general.sml)] [linking with $basis.cm/basis.cm@523852(array.sig)] [linking with $basis.cm/basis.cm@506888(array.sml)] [linking with $basis.cm/basis.cm@765896(vector.sig)] [linking with $basis.cm/basis.cm@752000(vector.sml)] [linking with $basis.cm/basis.cm@111449(basis-structs.sml)] [linking with $basis.cm/basis.cm@111212(bind-largest32.sml)] [linking with $basis.cm/basis.cm@111025(basis-time.sml)] [linking with $basis.cm/basis.cm@166594(pre-basis.sml)] [linking with $basis.cm/basis.cm@144377(pre-string.sml)] [linking with $basis.cm/basis.cm@166469(string-cvt.sig)] [linking with $basis.cm/basis.cm@161951(string-cvt.sml)] [linking with $basis.cm/basis.cm@318727(bool.sig)] [linking with $basis.cm/basis.cm@316402(bool.sml)] [linking with $basis.cm/basis.cm@144252(list.sig)] [linking with $basis.cm/basis.cm@134701(list.sml)] [linking with $basis.cm/basis.cm@187864(num-format.sml)] [linking with $basis.cm/basis.cm@168579(num-scan.sml)] [linking with $basis.cm/basis.cm@161778(char.sig)] [linking with $basis.cm/basis.cm@145733(char.sml)] [linking with $basis.cm/basis.cm@134544(string.sig)] [linking with $basis.cm/basis.cm@120266(string.sml)] [linking with $basis.cm/basis.cm@258191(substring.sml)] [linking with $basis.cm/basis.cm@222057(mono-vector.sig)] [linking with $basis.cm/basis.cm@222182(char-vector.sml)] [linking with $basis.cm/basis.cm@215004(mono-array.sig)] [linking with $basis.cm/basis.cm@258396(char-array.sml)] [linking with $basis.cm/basis.cm@558290(substring.sig)] [linking with $basis.cm/basis.cm@558069(text.sig)] [linking with $basis.cm/basis.cm@557410(text.sml)] [linking with $basis.cm/basis.cm@557187(Exports/char.sml)] [linking with $basis.cm/basis.cm@298706(integer.sig)] [linking with $basis.cm/basis.cm@298879(int32.sml)] [linking with $basis.cm/basis.cm@293277(int31.sml)] [linking with $basis.cm/basis.cm@293072(bind-int-32.sml)] [linking with $basis.cm/basis.cm@385679(bind-largeint-32.sml)] [linking with $basis.cm/basis.cm@120141(Unsafe/cinterface.sig)] [linking with $basis.cm/basis.cm@117826(Unsafe/cinterface.sml)] [linking with $basis.cm/basis.cm@324005(ieee-real.sig)] [linking with $basis.cm/basis.cm@318884(ieee-real.sml)] [linking with $basis.cm/basis.cm@292899(word.sig)] [linking with $basis.cm/basis.cm@380702(word31.sml)] [linking with $basis.cm/basis.cm@362732(real-format.sml)] [linking with $basis.cm/basis.cm@347072(math.sig)] [linking with $basis.cm/basis.cm@347197(math64.sml)] [linking with $basis.cm/basis.cm@346867(real.sig)] [linking with $basis.cm/basis.cm@324335(real64.sml)] [linking with $basis.cm/basis.cm@324130(bind-real-32.sml)] [linking with $basis.cm/basis.cm@316229(time.sig)] [linking with $basis.cm/basis.cm@302336(time.sml)] [linking with $basis.cm/basis.cm@557030(date.sig)] [linking with $basis.cm/basis.cm@558447(date.sml)] [linking with $basis.cm/basis.cm@229166(Unix/pre-os.sml)] [linking with $basis.cm/basis.cm@289345(word32.sml)] [linking with $basis.cm/basis.cm@289140(bind-sysword-32.sml)] [linking with $basis.cm/basis.cm@462010(Posix/posix-error.sml)] [linking with $basis.cm/basis.cm@288935(Posix/posix-prelude.sml)] [linking with $basis.cm/basis.cm@285843(Posix/posix-signal.sml)] [linking with $basis.cm/basis.cm@385884(word8.sml)] [linking with $basis.cm/basis.cm@274560(Posix/posix-process.sml)] [linking with $basis.cm/basis.cm@391454(Posix/posix-filesys.sml)] [linking with $basis.cm/basis.cm@449332(Posix/posix-procenv.sml)] [linking with $basis.cm/basis.cm@215129(word8-vector.sml)] [linking with $basis.cm/basis.cm@199067(word8-array.sml)] [linking with $basis.cm/basis.cm@424536(Posix/posix-io.sml)] [linking with $basis.cm/basis.cm@420766(Posix/posix-sysdb.sml)] [linking with $basis.cm/basis.cm@257986(byte.sig)] [linking with $basis.cm/basis.cm@255832(byte.sml)] [linking with $basis.cm/basis.cm@230033(Posix/posix-tty.sml)] [linking with $basis.cm/basis.cm@229876(Posix/posix-error.sig)] [linking with $basis.cm/basis.cm@229719(Posix/posix-signal.sig)] [linking with $basis.cm/basis.cm@198580(Posix/posix-flags.sig)] [linking with $basis.cm/basis.cm@229514(Posix/posix-process.sig)] [linking with $basis.cm/basis.cm@229341(Posix/posix-procenv.sig)] [linking with $basis.cm/basis.cm@228961(Posix/posix-filesys.sig)] [linking with $basis.cm/basis.cm@198862(Posix/posix-io.sig)] [linking with $basis.cm/basis.cm@198737(Posix/posix-sysdb.sig)] [linking with $basis.cm/basis.cm@198391(Posix/posix-tty.sig)] [linking with $basis.cm/basis.cm@198122(Posix/posix.sig)] [linking with $basis.cm/basis.cm@192677(Posix/posix.sml)] [linking with $basis.cm/basis.cm@471548(bind-word-32.sml)] [linking with $basis.cm/basis.cm@111803(OS/os-path.sig)] [linking with $basis.cm/basis.cm@526065(OS/os-path-fn.sml)] [linking with $basis.cm/basis.cm@523977(Unix/os-path.sml)] [linking with $basis.cm/basis.cm@111928(OS/os-filesys.sig)] [linking with $basis.cm/basis.cm@548511(Unix/os-filesys.sml)] [linking with $basis.cm/basis.cm@486850(option.sig)] [linking with $basis.cm/basis.cm@483963(option.sml)] [linking with $basis.cm/basis.cm@483838(NJ/cont.sig)] [linking with $basis.cm/basis.cm@482436(NJ/cont.sml)] [linking with $basis.cm/basis.cm@482279(NJ/signals.sig)] [linking with $basis.cm/basis.cm@488161(NJ/internal-signals.sml)] [linking with $basis.cm/basis.cm@479047(NJ/cleanup.sig)] [linking with $basis.cm/basis.cm@475233(NJ/cleanup.sml)] [linking with $basis.cm/basis.cm@486975(NJ/signals.sml)] [linking with $basis.cm/basis.cm@482122(Unix/unix-signals.sig)] [linking with $basis.cm/basis.cm@480106(Unix/unix-signals.sml)] [linking with $basis.cm/basis.cm@479172(OS/at-exit.sml)] [linking with $basis.cm/basis.cm@111678(OS/os-process.sig)] [linking with $basis.cm/basis.cm@471753(Unix/os-process.sml)] [linking with $basis.cm/basis.cm@110868(OS/os-io.sig)] [linking with $basis.cm/basis.cm@112802(Unix/os-io.sml)] [linking with $basis.cm/basis.cm@110663(OS/os.sig)] [linking with $basis.cm/basis.cm@112306(Unix/os.sml)] [linking with $basis.cm/basis.cm@110040(IO/io.sig)] [linking with $basis.cm/basis.cm@110165(IO/io.sml)] [linking with $basis.cm/basis.cm@767836(exn-name.sml)] [linking with $basis.cm/basis.cm@767471(Exports/general.sml)] [linking with $basis.cm/basis.cm@556825(Exports/int.sml)] [linking with $basis.cm/basis.cm@827719(Exports/int32.sml)] [linking with $basis.cm/basis.cm@668007(Exports/word.sml)] [linking with $basis.cm/basis.cm@766226(Exports/string.sml)] [linking with $basis.cm/basis.cm@792031(Exports/word32.sml)] [linking with $basis.cm/basis.cm@792393(Exports/largeint.sml)] [linking with $basis.cm/basis.cm@794946(Exports/char-vector.sml)] [linking with $basis.cm/basis.cm@827514(Exports/int31.sml)] [linking with $basis.cm/basis.cm@640150(bind-position-32.sml)] [linking with $basis.cm/basis.cm@624019(IO/prim-io.sig)] [linking with $basis.cm/basis.cm@624755(IO/prim-io-fn.sml)] [linking with $basis.cm/basis.cm@624176(IO/text-prim-io.sml)] [linking with $basis.cm/basis.cm@659791(IO/bin-prim-io.sml)] [linking with $basis.cm/basis.cm@623862(IO/os-prim-io.sig)] [linking with $basis.cm/basis.cm@646741(Unix/posix-bin-prim-io.sml)] [linking with $basis.cm/basis.cm@640355(Unix/posix-text-prim-io.sml)] [linking with $basis.cm/basis.cm@620286(IO/clean-io.sml)] [linking with $basis.cm/basis.cm@576018(IO/stream-io.sig)] [linking with $basis.cm/basis.cm@575861(IO/text-stream-io.sig)] [linking with $basis.cm/basis.cm@575688(IO/text-io.sig)] [linking with $basis.cm/basis.cm@576175(IO/text-io-fn.sml)] [linking with $basis.cm/basis.cm@574558(Unix/posix-text-io.sml)] [linking with $basis.cm/basis.cm@573975(Exports/real.sml)] [linking with $basis.cm/basis.cm@867095(NJ/smlnj.sml)] [linking with $basis.cm/basis.cm@889098(NJ/wrap-export.sml)] [linking with $basis.cm/basis.cm@888941(NJ/export.sig)] [linking with $basis.cm/basis.cm@886307(NJ/export.sml)] [linking with $basis.cm/basis.cm@792236(NJ/interval-timer.sig)] [linking with $basis.cm/basis.cm@885073(NJ/interval-timer.sml)] [linking with $basis.cm/basis.cm@884777(NJ/print-hook.sml)] [linking with $basis.cm/basis.cm@836690(timer.sig)] [linking with $basis.cm/basis.cm@837123(internal-timer.sml)] [linking with $basis.cm/basis.cm@747522(real64-vector.sml)] [linking with $basis.cm/basis.cm@730940(real64-array.sml)] [linking with $basis.cm/basis.cm@767298(Unsafe/object.sig)] [linking with $basis.cm/basis.cm@777068(Unsafe/object.sml)] [linking with $basis.cm/basis.cm@573818(Unsafe/poll.sig)] [linking with $basis.cm/basis.cm@775784(Unsafe/poll.sml)] [linking with $basis.cm/basis.cm@767173(Unsafe/unsafe-vector.sig)] [linking with $basis.cm/basis.cm@767048(Unsafe/unsafe-array.sig)] [linking with $basis.cm/basis.cm@766923(Unsafe/unsafe-mono-vector.sig)] [linking with $basis.cm/basis.cm@766449(Unsafe/unsafe-mono-array.sig)] [linking with $basis.cm/basis.cm@766574(Unsafe/unsafe.sig)] [linking with $basis.cm/basis.cm@770835(Unsafe/unsafe.sml)] [linking with $basis.cm/basis.cm@870768(NJ/prof-control.sig)] [linking with $basis.cm/basis.cm@878462(NJ/prof-control.sml)] [linking with $basis.cm/basis.cm@109915(NJ/gc.sig)] [linking with $basis.cm/basis.cm@877506(NJ/gc.sml)] [linking with $basis.cm/basis.cm@870579(NJ/internals.sig)] [linking with $basis.cm/basis.cm@876712(NJ/internals.sml)] [linking with $basis.cm/basis.cm@870217(NJ/sysinfo.sig)] [linking with $basis.cm/basis.cm@872175(NJ/sysinfo.sml)] [linking with $basis.cm/basis.cm@667882(NJ/weak.sig)] [linking with $basis.cm/basis.cm@871459(NJ/weak.sml)] [linking with $basis.cm/basis.cm@870342(NJ/smlnj.sig)] [linking with $basis.cm/basis.cm@870941(Exports/smlnj.sml)] [linking with $basis.cm/basis.cm@574180(Exports/time.sml)] [linking with $basis.cm/basis.cm@791826(Exports/word31.sml)] [linking with $basis.cm/basis.cm@728142(bind-largeword-32.sml)] [linking with $basis.cm/basis.cm@794741(Exports/largeword.sml)] [linking with $basis.cm/basis.cm@727953(pack-word.sig)] [linking with $basis.cm/basis.cm@728347(pack-word-b32.sml)] [linking with $basis.cm/basis.cm@112101(Exports/os.sml)] ------------------ Comments: The problem seems related to the x86-platform and did not occur in previous versions! [Matthias, 10/8/99] I have also experienced such crashes on the x86 platform. There are two easy ways of triggering a crash (in 110.23): 1. Run a CML program, or 2. Reduce the allocation size to 128k or less. Both things are quite annoying. First, I want to play with CML on the x86 platform. But even more importantly, there are systems that have a 128k cache (notably the popular "Celeron A" CPUs), and anything bigger than that in allocation size is going to slow the system down quite noticably. I have just built a 2-CPU Celeron system, and it is screaming fast -- except when I run SML/NJ. (Getting MP support back into SML/NJ would also be nice, btw.) "Celeron A" CPUs are actually faster (or can be faster) than the corresponding PentiumII CPUs because the Celeron has a fast cache (full clock speed) while the PentiumII has a slower cache (half clock speed). The PentiumII cache is 256k, though, which is twice as much as what's on the Celeron. Is there anything inherently preventing SML/NJ from reducing allocation size to 128k? [Allen Leung, 10/8/99] I compiled the recompile the compiler with 'sml @SMLalloc=64k' and 'sml @SMLalloc=128k'. I ran the SMLNJ benchmarks with -alloc 64k. I also tried compiling and running my other ML programs with a small allocation space. But none of these reproduces the crash. This is on a system with dual pentium II xeon cpus and one gig of memory, running Linux 5.2 Kernel 2.2.7. I can crash cml however. The new bug is likely to be caused by the new ra introduced in 110.23. But I suspect the cml bug has some other origin, since the same program I tested also crashed in 110.20. [Matthias, 10/8/99] Well, maybe the problem is confined to the boot sequence. Try the following with 110.23: - Take the original 110.23 distribution files - Do zcat 110.23-config.tar.Z | tar xf - - Edit config/install.sh and change the allocation size for x86 to 128k - Do the usual config/install.sh thing Here is a partial transcript (this is on a PentiumII laptop, but it is identical to the Celeron case): . . [Loading init.cmi/CM/x86-unix/core.sml] [Loading init.cmi/CM/x86-unix/built-in.sml] [Loading init.cmi/CM/x86-unix/pre-perv.sml] [Loading init.cmi/CM/x86-unix/pre-string.sml] /home/blume/ML/23test/bin/.run/run.x86-linux: Fatal error -- unexpected fault, signal = 11, code = 0x804c869 !!! Boot code failed, no heap image built (sml.x86-linux). Command exited with non-zero status 1 If I reduce the size to 64k, the same problem is triggered ever earlier. [Allen Leung, 10/8/99] I can repro this. This also causes the same crash in 110.20. So it seems to be something that's been around for a few releases. [Lal, 10/8/99] This bug does not seem to be x86 specific, but goes back all the way to 110.12. The table below shows the various experiments I did. 110.9.1 will reach the toplevel prompt even with an allocation space of 8k! My feeling is that this bug may be another manifestation of bug 1507. --------------------------------------------------------- version: arch: command: symptom: 110.23 alpha makeml -alloc 128k crash 110.22 alpha makeml -alloc 128k crash 110.20 alpha makeml -alloc 128k crash 110.19 alpha makeml -alloc 128k ok 110.19 alpha makeml -alloc 64k crash 110.18 alpha makeml -alloc 128k ok 110.18 alpha makeml -alloc 64k crash 110.17 alpha makeml -alloc 64k crash 110.16 alpha makeml -alloc 64k crash 110.12 alpha makeml -alloc 64k crash 110.9.1 alpha makeml -alloc 128k ok 110.9.1 alpha makeml -alloc 64k ok 110.9.1 alpha makeml -alloc 32k ok 110.9.1 alpha makeml -alloc 16k ok 110.9.1 alpha makeml -alloc 8k ok [Lal, 10/8/99] There may be two unrelated bugs: 110.{12,13,14} generate a runtime system error with an allocation space of 64k. bin/.run/run.alpha32-dunix: Fatal error -- bad object tag 19, obj = 0x20300f8, desc = 0x20300cc Whereas 110.15 core dumps with an allocation space of 64k. Again, it is possible that this is the same bug. [jhr, 10/8/99] I could believe that the boot sequence might fail on a small allocation space. The boot code is probably not robust w.r.t. checking for heap exhaustion. [Leunga, 10/?/99] I used 110.23 to compile itself, it takes up about 900 secs. Then I used the new image to compile itself; that takes 817 secs, which is comparable to the 814 secs I got before. On the x86, I have modified system/makeml to use ALLOC=256k, since that is used in config/install.sh. I suspect you used the default of 1M to build the x86 image, then redistributed it. On the x86, alloc=1M is slower, probably because of smaller cache. I recommend modifying makeml to use the same ALLOC parameters as config/install.sh; this will prevent a lot of headaches in the future. I found that if you don't do that to makeml, the comparisons are meaningless, even if you start up sml with the appropriate SMLalloc parameter. I have no idea why. In 110.21, I usually compare builds from 'makeml'. [Lal, 10/13/99] I talked with John about the allocation space size issue, and making the default smaller than 1M would not be the right thing to do. It is certainly the right thing to do for the Pentium II, but some newer x86 chips have caches that are 1M, and the numbers vary across the board. A recent message from Blume indicated that a cache size of 32k was best! Currently, config/install.sh does not process command line options but it is sensitive to the architecture since it does: case $ARCH in mips*) ALLOC=1M ;; x86) ALLOC=256k ;; alpha32) ALLOC=512k ;; *) ALLOC=512k ;; esac whereas makeml does have a allocation size command line argument but otherwise defaults to 1M. As you suggest, I have added the above code to makeml to make things consistent at the very least, for now ... Eventually, I think we want to have command line options to config/install.sh. Fix: Test: * Owner: jhr, Lal Status: open ---------------------------------------------------------------------- Number: 1525 Title: Array2 bug Keywords: Array2 Submitter: Ken Larsen Date: 10/12/99 Version: 110.0.5 System: - Severity: major Problem: Array2 doesn't behave as specified. With code below rmTest and cmTest both evaluate to false. Thus, something is wrong in foldi (and in mapi, appi also it turns out). Code: val arr = Array2.tabulate Array2.RowMajor (3,3,fn x => x) val upperRight = {base = arr, row = 0, col = 1, nrows = SOME 2, ncols = NONE} val rm = Array2.foldi Array2.RowMajor (fn(i,j,e,acc)=>((i,j),e) :: acc) [] upperRight fun dup(x, acc) = (x, x) :: acc val rmResult = foldl dup [] [(0,1), (0,2), (1,1), (1,2)] val rmTest = rm = rmResult val cm = Array2.foldi Array2.ColMajor (fn(i,j,e,acc)=>((i,j),e) :: acc) [] upperRight val cmResult = foldl dup [] [(0,1), (1,1), (0,2), (1,2)] val cmTest = cm = cmResult Transcript: Comments: Fix: (fix supplied) Test: bug1525.1.sml Owner: jhr Status: fixed in 110.0.6 [jhr] ---------------------------------------------------------------------- Number: 1526 Title: double-quote representation in strings and characters Keywords: strings, chars Submitter: Michael Siff msiff@mail.slc.edu Date: 11/03/99 Version: 110.0.3 System: Sparc Solaris 2.7 Subsystem: SML basis library Severity: minor Problem: I am getting different behavior from Char.fromString on the string "\"" depending on how I generate it: Compare: - Char.fromString "\""; val it = NONE : char option - Char.fromString (Char.toString (#"\"")); val it = SOME #"\"" : char option - String.sub ("\"", 0); val it = #"\"" : char Code: (* all three tests should result in SOME(#"\""). they do not *) val test1 = Char.fromString "\"" val test2 = SOME(String.sub ("\"", 0)) val test3 = Char.fromString (Char.toString #"\"") Transcript: val test1 = NONE : char option val test2 = SOME #"\"" : char option val test3 = SOME #"\"" : char option Comments: [jhr, 11/7/99] This is a "feature" of the specification. The double quote character must be escaped in a character literal, which is why you get NONE from Char.fromString "\"". Note that Char.toString(#"\"") produces the string "\\\"" (using ML escape syntax), which is a valid SML escape sequence. Fix: clarify documentation of Char.fromString Test: bug1526.1.sml Owner: jhr Status: not a bug ---------------------------------------------------------------------- Number: 1527 Title: assertion failure and unknown tag Keywords: runtime, gc, arrays Submitter: David B. Benson Date: 11/04/99 Version: 110.0.3 System: x86-linux, hppa-hpux Severity: serious Problem: ihppa-hpux: Assertion failure x86-linux: Fatal error -- unknown tag Code: In 3c.tar.gz in ftp ftp.eecs.wsu.edu pub/dbenson See the instuctions at the end of this email message. Transcript: There are two. The different errors in the linux code are a result of using different amounts of printing into the report files, given below. The two good runs each involved producing 49Mbyte report files, which I have snipped out essentially everything. The fatal error messages occur BEFORE the last new line above them, so they resided on the end of the dying line, which I have snipped. Notice that the last newline finally does come out. ---------- hppa-hpux ----------------------------------------------------------- time.stats start: Tue Nov 2 16:26:14 PST 1999 Tue Nov 2 16:26:17 PST 1999 /net/local/sml/bin/sml: Assertion failure (arena->nextw <= arena->tospTop) at "major-gc.c:830" time.stats stop : Tue Nov 2 16:30:44 PST 1999 ---------- x86-linux ------------------------------------------------------------ time.stats start: Sun Oct 31 13:51:57 PST 1999 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0 @ 0x402c0000 in array arena time.stats stop : Sun Oct 31 13:57:12 PST 1999 time.stats start: Sun Oct 31 14:21:15 PST 1999 Sun Oct 31 14:21:15 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 [snip] starting on file /users/dbenson/3c/rca/stats/stats.rca.90.20000.3.6.acqn1290 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x409f0000 in array arena time.stats stop : Sun Oct 31 14:27:03 PST 1999 GOOD RUN time.stats start: Sun Oct 31 14:45:52 PST 1999 Sun Oct 31 14:45:52 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 <>[snip]<> starting on file /users/dbenson/3c/rca/stats/stats.rca.95.20000.3.6.acqn1306 starting on fakes Sun Oct 31 14:58:53 PST 1999 time.stats stop : Sun Oct 31 14:58:53 PST 1999 time.stats start: Sun Oct 31 16:18:55 PST 1999 Sun Oct 31 16:18:56 PST 1999 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x409f0000 in array arena time.stats stop : Sun Oct 31 16:24:53 PST 1999 time.stats start: Sun Oct 31 16:33:56 PST 1999 Sun Oct 31 16:33:56 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 [snip] starting on file /users/dbenson/3c/rca/stats/stats.rca.75.20000.3.4.acqn1247 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x407f0004 in array arena time.stats stop : Sun Oct 31 16:37:00 PST 1999 time.stats start: Sun Oct 31 16:44:13 PST 1999 Sun Oct 31 16:44:13 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 t[snip] starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.2.acqn1189 [snip] starting on file /users/dbenson/3c/rca/stats/stats.rca.70.20000.3.4.acqn1233 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x40550008 in array arena time.stats stop : Sun Oct 31 16:47:09 PST 1999 time.stats start: Sun Oct 31 16:55:32 PST 1999 Sun Oct 31 16:55:32 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 t[snip]g starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.8.acqn1193 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xc @ 0x405f0004 in array arena time.stats stop : Sun Oct 31 16:55:58 PST 1999 time.stats start: Sun Oct 31 17:05:01 PST 1999 Sun Oct 31 17:05:01 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 tg[snip]gt starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.8.acqn1193 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xc @ 0x405f0004 in array arena time.stats stop : Sun Oct 31 17:05:27 PST 1999 time.stats start: Sun Oct 31 17:18:38 PST 1999 Sun Oct 31 17:18:38 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 trialinformation[snip]graphinformation starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.8.acqn1193 /usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xc @ 0x405f0004 in array arena time.stats stop : Sun Oct 31 17:19:09 PST 1999 GOOD RUN time.stats start: Sun Oct 31 17:41:08 PST 1999 Sun Oct 31 17:41:08 PST 1999 starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188 <>[snip]<> starting on file /users/dbenson/3c/rca/stats/stats.rca.95.20000.3.6.acqn1307 Sun Oct 31 17:52:40 PST 1999 time.stats stop : Sun Oct 31 17:52:40 PST 1999 ------------------------------------------------------------------------------------------------ Comments: ---When I use the LONG report format, I get this to run on x86-linux, but this is not a fix. How to install: (1) ftp ftp.eecs.wsu.edu cd pub/dbenson get [binary] 3.tar.gz (almost 28Mbyte) (2) in your HOME directory, uncompress with zcat or whatever. Obtain 3c.tar (almost 86Mbyte file) (3) tar xf 3c.tar will create the entire directory structure, 3c (4) cd 3c/src and read the README. Note: runs relative to HOME environment variable. --- if there are problems with any of these directions or directories of files, please let me know. Comments: [Lal, 11/3/99] Before investigating this further, it would be worth checking if 110.0.5 also exhibits the same problem. If the bug persists and is repeatable it may be possible to thin it down to a small test case. Fix: - Test: ??? Owner: jhr? Status: open ---------------------------------------------------------------------- Number: 1528 Title: Compiler bug: LtyKernel: unexpected TC_FIX freevars in tc_aux Keywords: FLINT, lambda types Submitter: Chris Burdorf Date: 10/27/99 Version: 110.23 System: ? Severity: major Problem: When compiling under 110.23, I get the following error message. Previously I was compiling with 110 with the 109.29 basis library loaded, because I couldn't get the 110 basis library to work. Can you give me any suggestions? Version(s) to revert back to? Error: Compiler bug: LtyKernel: unexpected TC_FIX freevars in tc_aux Code: ??? Transcript: ??? Comments: > (1) 110.23 is a developmental or "working" version, and these versions > tend to be more buggy and less stable than the release version, so I > am curious what features you need that are not available in the > 110.0.3 Release version (by the way, a patch version 110.0.6 of the > release will be available in a few days). I had problems with the 110.3 release version, because some code I got from a guy that no longer works here uses Array2 in a way that won't compile under 110.3. So I changed his usage of Array2 to use the new definition (as I understood it), but then it gronked elsewhere when compiling the program (a tesselator that takes NURBS -> polygons). So, after being unable to find a fix, I just included the smlnj-109.29 basis library and compiled it under 110.3 and it worked. I stuck with it until we got this new high powered linux renderfarm, so I decided to port it to linux, but I couldn't find a 109.29 version for linux, so I decided to try 110.3. I had the same problem on 110.3 as before, so I tried 110.23 and got the reported error. > > (2) 110.23 comes with a version of smlnj-lib that should work with it. > We'd be interested in hearing about the problem you had with the 110 > version of the basis library, since this may indicate a bug that needs > to be fixed. When you say "110 basis library" in your message, do you > mean the 110.23-smlnj-lib.tar.Z package that comes with 110.23, or the > package (actually patch version 110.0.3) that comes with the 110 > Release? The one I use on Linux is 110.23 basis. on Irix I use 109.29 basis. > > (3) This looks like a new and serious bug, so it would be very helpful > if we could reproduce it. If you can't isolate it in a compact piece > of code, is there any chance we could temporarily borrow your code to > isolate it ourselves? Disney won't let me send out code, and the file the bug appears in is several thousand lines long. Is there any way to get the compiler to print what function it is working on? I could probably send you the function that it erros on without problems. > > I guess my advice is to try using 110.0.3 (or 110.0.6 in a few days), > with the version of smlnj-lib that comes with it, unless you have a > strong reason why you need to use a later working version. Among the > post-110.0.3 working versions, 110.9.1 is probably the most stable. > [jhr, 10/28/99] Can you elaborate on the problem you are having with Array2? It should be easy to figure out a work-around or fix, and I'm glad to try to help you do that. I would strongly recommend using 110.0.6, which should be out in a day or so. Among other things, it has several bug fixes in the Array2 implementation (and it builds under RedHat 6.0). [dbm, 10/28/99] It's possible that you tripped over a bug in the array2 module, as John Reppy mentioned in his reply. These bugs have been fixed in the 110.0.6 release, but I don't think the fix got into 110.23. The current interface of the Array2 module (signature ARRAY2) is documented by the following web page. http://www.cs.bell-labs.com/~jhr/sml/basis/pages/array2.html The source code for the ARRAY2 signature is the same in 109.29, 110.0.6, and 110.23 (although the file name changes from array2-sig.sml to array2.sig in 110.23), and I presume the official semantics is still as described in the ARRAY2 web page. The source code for the Array2 implementation (array2.sml) differs in all three versions, and presumably the 110.0.6 version is now correct. Fix: Test: - Owner: jhr, Zhong Status: open ---------------------------------------------------------------------- Number: 1529 Title: The sign of ~0.0 Keywords: "zero","sign","inf" Submitter: Jan Egil Kristiansen janegil@stones.com Date: 10/10/99 Version: 110.0.3 System: x86 Windows NT 4.0sp4 Subsystem: Other Severity: Problem: There must be a difference between 0.0 and ~0.0. How else can the result of a division by zero have a sign? (also see http://lbk.olivant.fo/janegil/datanomps2/mlcomments/zerosign.html) Code: 1.0/0.0; 1.0/(~0.0); (~1.0)/0.0; Transcript: - 1.0/0.0; val it = inf : real - 1.0/(~0.0); val it = inf : real - (~1.0)/0.0; val it = ~inf : real Comments: I expected the 2nd result to equal the 3rd, not the first. (Rather than fixing nan and inf, I'd like to see them scrapped. Neat idea, but it does not work.) Output from MLWorks: MLWorks> 1.0/0.0; 1.0/(~0.0); (~1.0)/0.0; val it : real = inf val it : real = ~inf val it : real = ~inf Fix: Test: bug1529.1.sml Owner: jhr, Lal Status: open ---------------------------------------------------------------------- Number: 1530 Title: ListSetFn should have opaque result [smlnj-lib] Keywords: utility library: ListSetFn Submitter: David B. Benson dbenson@eecs.wsu.edu Date: 11/05/99 Version: 110.0.3 System: x86-linux Severity: serious [scariest problem I've come across] Problem: The following code compiles! ...and then, except for the counter that I put in, loops forever at run time. The difficulty, I believe, is that both of the types are derived from int list, so somehow the compiler thinks that the first argument to union is, in fact a set. But it is not, as it is not ordered, and union then makes a mess for the result. In ugraph.sml, locate HERE in a comment in the code. This shows the problem and a correct call. Code: In src.tar.gz.uu at the end of the message Transcript: Comments: Perhaps SML is supposed to work this way. If so, then the problem is that the utility library code is using transparent types. To avoid breaking working code, I suppose you don't want to change these to opaque signatures. However, it seems sensible to have a OpaqueListSetFn, etc., which does. If you make this change, then I'll have students use the opaque versions of the library code. Up until this, I've always thought of sml, via the type system, as protecting programmers from type errors. This is the only example I have which I consider to be a failure in this regard. Fix: [dbm, 11/4/99] Looks to me like ListSetFn should have an opaque result signature constraint. Test: Owner: jhr, dbm Status: fixed in 110.0.6, 110.0.25 [jhr, 11/7/99] ---------------------------------------------------------------------- Number: 1531 Title: Basis library discrepancies in IntInf and POSIX_FLAGS Keywords: IntInf, Posix.TTY Submitter: Stephen Weeks Date: 11/04/99 Version: 110.9.1 System: x86-linux Severity: Problem: The following changes are needed to make SML/NJ more compliant with the Basis Library spec. in POSIX_FLAGS fromWord -> wordTo in IntInf quotrem -> quotRem divmod -> divMod Comments: [jhr, 11/7/99] Actually, the Basis spec was revised to use the "fromWord" convention (a new version of the spec will be out as soon as the legal issues are settled). We should fix this, but our IntInf structure is not really basis compliant in a number of ways. [dbm, 11/7/99] We need to bring the IntInf implementation into conformance with the spec, and make it a regular part of the Basis environment. Fix: correct Basis documentation Test: - Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1532 Title: Date:DATE missing fromString Keywords: date, parsing, from string Submitter: David B. Benson dbenson@eecs.wsu.edu Date: 11/07/99 Version: 110.0.3 System: x86-linux Severity: very minor, but a chance to complain about the sml standard for dates. Problem: signature DATE is missing fromString, hence not in compliance with the standard. Code: Transcript: Comments: I will have to process some dates of type string produced by my linux box. These do not agree with exact format given in the standard for string dates given in the standard as produced by Date.toString. The difference is only that leading zeros do not appear for days of the month. Later I will need to process dates from software which gives them as 1999 Nov 07 14:54:08 I conclude that the sml standard for Date.fromString is simply much too restrictive. One simply needs the idempotence property that fromString o toString = SOME id while date strings in other formats are certainly also possible and it would be quite useful to have a method to read these in the basis library. A date consists of year: at least four digits month: "Jan" or else "JAN", etc. day: int in the approprate range hours:minutes:seconds in the Unix-style format, except that in the seconds field an optional decimal point followed by one or more digits ought to be allowed, for people who need more precision than I do. Furthermore, some may wish to keep track of leap seconds (or leap milliseconds) as being between midnight and 00:00:00, the beginning of the next day. Hence 24:00:00.002 is a 2 millisecond leap interval. I suppose one might check with the WWV folks at NIST before going to this effort, since they might have a standard. dayofweek: optional: 3 characters timezone: optional: 3 characters and different poeple put these 4 to 6 tokens in different orders. Thinking about this suggests that the basis definition is also wrong in thinking of seconds as an int, at least with providing for milliseconds -- and maybe in the future microseconds, ... I don't need this accuracy but people working on global positioning software, etc., might. Anyway, here is the DateExtension.fromString which I hacked out today. Rather crude, but it'll be enough for my purposes. --------------------------DateExtension.sml----------------------------------- (* DateExtension.sml *) structure DateExtension : sig val fromString: string -> Date.date option end = struct fun monthOption s = let val m = String.implode( let val [c1,c2,c3] = String.explode(s) val (isUpper2,c2') = if Char.isUpper(c2) then (true,Char.toLower(c2)) else (false,c2) val (isUpper3,c3') = if Char.isUpper(c3) then (true,Char.toLower(c3)) else (false,c3) in if (isUpper2 andalso isUpper3) orelse (not isUpper2 andalso isUpper3) then [c1,c2',c3'] else [#"n",#"o",#"t"] end) in (case m of "Jan" => SOME Date.Jan | "Feb" => SOME Date.Feb | "Mar" => SOME Date.Mar | "Apr" => SOME Date.Apr | "May" => SOME Date.May | "Jun" => SOME Date.Jun | "Jul" => SOME Date.Jul | "Aug" => SOME Date.Aug | "Sep" => SOME Date.Sep | "Oct" => SOME Date.Oct | "Nov" => SOME Date.Nov | "Dec" => SOME Date.Dec | _ => NONE) end fun scanMonth [] = [] | scanMonth (m :: ms ) = let val mOption = monthOption(m) in if isSome(mOption) then valOf(mOption) :: (scanMonth ms) else (scanMonth ms) end fun scanForMonth ms = let val [month] = scanMonth ms in month end fun scanForDay [dd] = valOf(Int.fromString(dd)) fun longFirst(s1,s2) = (String.size(s1) < String.size(s2)) fun fromString s = let val toks = ListMergeSort.sort (longFirst) (String.tokens Char.isSpace s) val numberOfTokens = List.length toks in if numberOfTokens < 7 then let val time :: yy :: toks = (toks) val [hh, mm, ss] = String.tokens (fn(c) => (#":" = c)) time val hours = valOf(Int.fromString(hh)) val minutes = valOf(Int.fromString(mm)) val seconds = valOf(Int.fromString(ss)) val year = valOf(Int.fromString(yy)) val (possibleMonths,possibleDays) = List.foldl (fn(a,(ms,ds))=> if String.size(a) = 3 then (a :: ms,ds) else if String.size(a) < 3 then (ms,a :: ds) else raise Fail "not a date") ([],[]) toks val month = scanForMonth(possibleMonths) val day = scanForDay(possibleDays) in SOME(Date.date{year=year,month=month,day=day, hour=hours,minute=minutes,second=seconds, offset=NONE}) end else NONE end handle _ => NONE end (* structure DateExtension *) ; Fix: Test: Owner: Status: open ---------------------------------------------------------------------- Number: 1533 Title: installation failure on Solaris 2.7 Keywords: installation, Solaris, library Submitter: Simon Helsen, shelsen@acm.org Date: 12/2/99 Version: 110.0.6 System: sparc-solaris2.7 Severity: major Problem: installation-script breaks on compiling poll.c Code: NONE Transcript: Machine "leia.informatik.uni-freiburg.de", Solaris 2.7, 96 Mb. >>>> gcc -O -D__STDC__=0 -DHOST_SPARC -DTARGET_SPARC -DOPSYS_UNIX -DOPSYS_SOLARIS -DCALLEESAVE=3 -DUNBOXEDFLOAT=1 -I../../objs -I../../include -I.. -c posix-os-lib.c gcc -O -D__STDC__=0 -DHOST_SPARC -DTARGET_SPARC -DOPSYS_UNIX -DOPSYS_SOLARIS -DCALLEESAVE=3 -DUNBOXEDFLOAT=1 -I../../objs -I../../include -I.. -c poll.c In file included from /usr/include/stropts.h:22, from poll.c:20: /usr/include/sys/stropts.h:315: parse error before `t_uscalar_t' /usr/include/sys/stropts.h:315: warning: no semicolon at end of struct or union /usr/include/sys/stropts.h:334: parse error before `t_uscalar_t' /usr/include/sys/stropts.h:334: warning: no semicolon at end of struct or union /usr/include/sys/stropts.h:337: parse error before `}' *** Error code 1 <<<< Comments: I realise that SML/NJ does not explicitely support Solaris 2.7, but our new Compute Server runs on 2.7. Would be nice if you could take a look. Btw, We have succesfully installed the compiler on Solaris 2.6. I haven't looked into it closely, but it might also be a bug on the Solaris side. stropts.h is quite different in Solaris 2.7. Below, you find the code-part related to the above errors. It suggests that t_uscalar_t is not defined, so perhaps some ordering is wrong (or more includes are needed?). Anyway, our system administrator has also contacted our Sun provider and they're taking a look if something is wrong in their libraries. /usr/include/sys/stropts.h Solaris 2.7 (lines 309 - 340) : ========================================================== /* * Stream I_PEEK ioctl format */ struct strpeek { struct strbuf ctlbuf; struct strbuf databuf; t_uscalar_t flags; }; #if defined(_SYSCALL32) struct strpeek32 { struct strbuf32 ctlbuf; struct strbuf32 databuf; uint32_t flags; }; #endif /* _SYSCALL32 */ /* * Stream I_FDINSERT ioctl format */ struct strfdinsert { struct strbuf ctlbuf; struct strbuf databuf; t_uscalar_t flags; int fildes; int offset; }; #if defined(_SYSCALL32) [jhr, 12/03] We don't have access to a 2.7 machine, but it would help if you could grep for t_uscalar_t in the header files (it looks like that type is not defined). Generally, system header files ought to be self contained, so I would call this a Solaris bug :). Fix: Test: - Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1534 Title: polymorphic equality for concrete eqtypes ... Keywords: polymorphic equality, concrete eqtypes Submitter: Lal George and Dave MacQueen Date: 11/23/99 Version: 110.24 System: all Severity: major Problem: polymorphic equality is being generated for concrete eqtypes. e.g. Symbol.symbol list. Code: file type line numbers ----- ------------ -------------- ml-yacc/lib/parser2.sml LrTable.term 435, 439, 129 Implementation/Unix/unix.sml file_desc 76 Semant/basics/stamps.sml PersStamp.persstamp 19 Semant/basics/sympaths.sml Symbol.symbol list 36 FLINT/kernel/ltykernel.sml tycI, fflag and rflag 300 Transcript: Comments: Fix: Test: Owner: Zhong, dbm, ? Status: open ---------------------------------------------------------------------- Number: 1535 Title: Large ml-yacc generated file fails to compile on HP-UX Keywords: Submitter: David J. King, David.King@motorola.com Date: 11/18/1999 Version: 110.0.3 System: HP-UX 10.20 Severity: major Problem: After lots of garbage collecting there is a fatal error Code: Included in attachment Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - CM.make(); : : [compiling ttcn.grm.sml -> CM/hppa-unix/ttcn.grm.sml.bin] : : GC #11.153.174.217.480.14379: (890 ms) GC #11.154.175.218.481.14399: (1350 ms) GC #11.155.176.219.482.14412: (910 ms) GC #11.156.177.220.483.14420: (980 ms) GC #11.157.178.221.484.14438: (1940 ms) GC #11.158.179.222.485.14446: (860 ms) GC #11.159.180.223.486.14466: (940 ms) GC #12.160.181.224.487.14474: (4980 ms) GC #12.161.182.225.488.14495: (870 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 101187584 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #13.162.183.226.489.14503: (4810 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 173080576 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #14.163.184.227.490.14510: (3850 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 181403648 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #15.164.185.228.491.14531: (5020 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 186253312 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #16.165.186.229.492.14552: (4980 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 194314240 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #17.166.187.230.493.14573: (5200 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 197328896 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #18.167.188.231.494.14594: (4890 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 200605696 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #19.168.189.232.495.14615: (5360 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 207683584 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #20.169.190.233.496.14636: (5740 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 214630400 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #21.170.191.234.497.14657: (5940 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 221708288 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #22.171.192.235.498.14678: (5690 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 228786176 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #23.172.193.236.499.14699: (6370 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 235732992 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #24.173.194.237.500.14720: (6420 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 242810880 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #25.174.195.238.501.14741: (6330 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 249888768 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size GC #26.175.196.239.502.14752: (6970 ms) /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 256835584 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate to-space for generation 5; trying smaller size /org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 52559872 bytes, errno = 12 /org/erl/projects/ptk/sml-97/bin/sml-cm: Fatal error -- unable to allocate minimum size Comments: The same code has worked on a sparc-sun-solaris2 machine. Perhaps a space leak? [Allen, 11/22/99] I found out what the problem with this bug is. It is not space leak, but because huge compilation units are passed to the graph coloring register allocator. If you have enough memory eventually the allocator will get to a point where all spill space has run out. Here are the main culprits: Basic blocks Max Block Size Interference graph Cluster 1: 287 >16K instrs nodes=16942 edges=4212732 moves=6 Cluster 2: 9907 nodes=22369 edges=162292 moves=11767 Actually, your program exposes a few performance problems in the register allocator. Some algorithmic improvements will be in release 110.25, which will improve cluster 2's compilation time. For cluster 1, graph coloring will always be slow because the huge number of interferences. (Hmmm... perhaps a linear scan allocator should be implemented for these special cases.) The interferences is created by a piece of code like this: datatype foo = T of int | ... val terms = (T 0):: (T 1):: (T 2):: (T 3):: (T 4):: (T 5):: ... (T 625):: nil which is generated by ml-yacc. The problem is the right associatitivity of :: and left-to-right evaluation rule of ML. I think this particular problem can be fixed by modifying ml-yacc so that it generates code like: infix $$ fun x $$ y = y::x val terms = nil $$ (T 625) $$ ... (T 4) $$ (T 3) $$ (T 2) $$ (T 1) $$ (T 0) Here's patch to do this. The original file is from release 110.24. [David King] Thanks for the fix. After lots of GCs ttcn.grm.sml now compiles. But alas the next file "ttcn_keywords.sml" fails! It is attached with the others below. The file contains a large list, and it fails in the same way as before. So I guess a workaround is to use the $$ operator instead of [....]. [Allen, 11/23] Yes, I think that's the thing to do now. This sounds like a pretty annoying problem, but I think it can be easily fixed. In ttcn.grm.sml, I suspect if you add some non-trivial actions (like print statements) to the parser it'll actually speed up the compilation. The slow compilation is because everything is grouped into one huge compilation unit after CPS conversion. [Allen, 2/17/00] Bug 1535 is a spilling problem. Because of the way (huge) lists are generated in mlyacc, the ra has to keep spilling. I changed the lists generation code so that lists are consed in reversed, which makes the ra terminate much faster. But then I ran into value polymophism restriction problems in the generated code, which is bug 1538. In any case 110.26 is already using these fixes; I think there should not be any problem. Fix: Test: - Owner: Lal, Allen Status: open ---------------------------------------------------------------------- Number: 1536 Title: ml-lex, ml-yacc path compiled into .heap/sml-cm.x86-win32 dump. Keywords: CM, ml-lex, ml-yacc Submitter: Michael Sofka sofkam@rpi.edu Date: 12/05/99 Version: 110.0.6 System: x86 Windows 95 any Subsystem: Installation Severity: major Problem: When running CM.make(), c:/sml-build/110.0.6/bin/ml-lex, instead of just ml-lex. If SML (or at least ml-lex.bat and ml-yacc.bat) are not installed in c:/sml-build/110.0.6/bin CM does not remake the *.lex.sml and *.grm.sml files. Code: This can be tested by running CM.make(); in the chap2 directory of the tiger source. Transcript: E:\users\mike\source\tiger\chap2>sml Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM&CMB] - CM.make(); [starting dependency analysis] [scanning sources.cm] [checking CM\x86-win32\sources.cm.stable ... not usable] [c:/sml-build/110.0.6/bin/ml-lex tiger.lex] [scanning H:\sml\lib\smlnj-lib.cm -> H:\sml\src\smlnj-lib\Util\smlnj-lib.cm] [checking H:\sml\src\smlnj-lib\Util\CM\x86-win32\smlnj-lib.cm.stable ...GC #0.0. 0.0.1.14: (60 ms) ok - stable] [dependency analysis completed] [recovering CM\x86-win32\tokens.sig.bin...GC #0.0.0.0.2.59: (60 ms) done] [recovering CM\x86-win32\tokens.sml.bin... done] [recovering CM\x86-win32\errormsg.sml.bin... done] [recovering CM\x86-win32\tiger.lex.sml.bin... done] [recovering CM\x86-win32\driver.sml.bin... done] [introducing new bindings into toplevel environment...] val it = () : unit - Comments: Fix: Define new MLLex, MLYacc, etc groups. However, the c:/sml-build/... path is pervasive enough in the sml-cm.x86-win32 heap that I back-leveled to 110.0.3 for now. :-) Test: Owner: Status: open ---------------------------------------------------------------------- Number: 1537 Title: compiler blowup with large andalso expression Keywords: compiler, performance, boolean expressions Submitter: Dave MacQueen Date: 1/9/00 Version: 110.26- System: - Severity: critical Problem: compilation time (and space?) blows up when compiling a large andalso expression Code: val x1 = true; val x2 = true; val x3 = true; val x4 = true; val x5 = true; val x6 = true; val x7 = true; val x8 = true; val x9 = true; val x10 = true; val x11 = true; val x12 = true; val x13 = true; val x14 = true; val x15 = true; val x16 = true; val x17 = true; val x18 = true; val x19 = true; val x20 = true; val x = x1 andalso x2 andalso x3 andalso x4 andalso x5 andalso x6 andalso x7 andalso x8 andalso x9 andalso x10 andalso x11 andalso x12 andalso x13 andalso x14 andalso x15 andalso x16 andalso x17 andalso x18 andalso x19 andalso x20; Transcript: - use "andalso20.sml"; GC #5.19.20.22.23.626: (0 ms) [opening andalso1.sml] val x1 = true : bool val x2 = true : bool val x3 = true : bool val x4 = true : bool val x5 = true : bool val x6 = true : bool val x7 = true : bool val x8 = true : bool val x9 = true : bool val x10 = true : bool val x11 = true : bool val x12 = true : bool val x13 = true : bool val x14 = true : bool val x15 = true : bool val x16 = true : bool val x17 = true : bool val x18 = true : bool val x19 = true : bool val x20 = true : bool GC #5.19.21.23.24.650: (10 ms) GC #5.19.21.23.25.661: (20 ms) GC #5.19.22.24.26.698: (50 ms) ... GC #22.546.549.553.556.12401: (100 ms) GC #22.547.550.554.557.12424: (130 ms) GC #22.548.551.555.558.12447: (120 ms) GC #22.549.552.556.559.12470: (120 ms) GC #22.550.553.557.560.12493: (110 ms) GC #22.551.554.558.561.12516: (130 ms) GC #23.552.555.559.562.12539: (16580 ms) Interrupt GC #23.553.556.560.563.12541: (10 ms) - GC #23.553.556.561.564.12542: (10 ms) Comments: A version with 10 variables takes about 4 seconds to compile. A version with 12 variables takes about 18 seconds to compile. A version with 15 variables fails afer 7 minutes with a "too many instructions" error: - use "andalso15.sml"; ... <7 minutes later> GC #24.765.779.810.1071.34149: (400 ms) GC #24.766.780.811.1072.34169: (390 ms) Error: MLRisc bug: ClusterRA.mkNodes: too many instructions 110.25 compiles all these test cases (10, 12, 20 variables) almost instantly. Clearly there is an exponential blowup going on, probably involving the construction of a humungous data structure. It appears the blowup is caused by the FLINT-related changes in 110.26, perhaps involving an interaction with the recent MLRISC changes. This problem might account for the compilation slowdown between 110.25 and 110.26 (I hope so). This was discovered when one of the regression tests failed to terminate (coresml/tests/d001a-ac.sml). Fix: Test: Owner: Zhong, Stefan, Lal, Allen Status: open ---------------------------------------------------------------------- Number: 1538 Title: mlyacc generates bad code Keywords: Submitter: Allen Leung leunga@cs.nyu.edu Date: 12/06/99 Version: 110.25 System: Any/All Any Unix Subsystem: Installation Severity: major Problem: A previous performance hack I submitted to mlyacc turns out to cause problems. The hack was to replace x :: y with y $$ x, making the compiler spill less. But sometimes code like this is generated: infix 5 $$ fun x $$ y = y::x val preferred_change = (nil, nil $$ (T 9)):: nil The problem is that $$ fails the value polymorphism test. Code: Recompile the compiler Transcript: [compiling $cm-lib.cm/parse/cm.grm.sml] ../cm/parse/cm.grm.sml:419.1-423.4 Warning: type vars not generalized because of value restriction are instantiated to dummy types (X1,X2,...) GC #18.560.763.1133.3954.155244: (20 ms) ignature spec name: preferred_change spec: (Token.LrTable.term list * Token.LrTable.term list) list actual: (?.X1 list * Token.LrTable.term list) list Comments: [Lal, 12/7/99] I tried the fix for both cm.grm and ml.grm and it seemed to work fine. Fix: In file ml-yacc/src/yacc.sml, make the following changes. Note: I'm not sure it is 100% correct but it seems to work for me so far. *** yacc-old.sml Thu Dec 2 12:26:11 1999 --- yacc.sml Mon Dec 6 22:48:51 1999 *************** *** 238,244 **** fun printChange () = ! (sayln "val preferred_change = "; app (fn (d,i) => (say"("; printTermList d; say ","; printTermList i; sayln ")::" --- 238,244 ---- fun printChange () = ! (sayln "val preferred_change : (term list * term list) list = "; app (fn (d,i) => (say"("; printTermList d; say ","; printTermList i; sayln ")::" *************** *** 297,303 **** printBoolCase noshift; printNames (); printErrValues value; ! say "val terms = "; printTermList ecTerms; sayln "end" end --- 297,303 ---- printBoolCase noshift; printNames (); printErrValues value; ! say "val terms : term list = "; printTermList ecTerms; sayln "end" end Test: Owner: Leung, Andrew Status: open (?) ---------------------------------------------------------------------- Number: 1539 Title: Array equality uses polyEqual Keywords: polyEqual, array Submitter: Allen Leung Date: 12/06/99 Version: 110.25 System: Any/All Any Unix Subsystem: Installation Severity: minor Problem: Array equality is object identity so it can probably be handled better. I suppose the reason why this is not optimized is because of the change to the new array representation. Code: Standard ML of New Jersey v110.25 [FLINT v1.5], December 1, 1999 - fun f(a: int Array.array, b : int Array.array) = a = b; [autoloading] GC #0.0.0.0.1.2: (30 ms) [autoloading done] stdIn:1.52 Warning: calling polyEqual val f = fn : int array * int array -> bool Comments: [jhr, 12/6/99] This is not optimized because there is no primop for comparing arrays. Pointer equality on the headers is not correct; you've got to do pointer equality on the data objects. Fix: Test: Owner: Status: open ---------------------------------------------------------------------- Number: 1540 Title: FreeBSD compilation Keywords: Submitter: Peter housel@acm.org Date: 12/13/99 Version: 110.25 System: Any/All FreeBSD 4.0-CURRENT Subsystem: Installation Severity: critical Problem: When linking the runtime on FreeBSD-4.0 the linker can't find the assembly-language primitives. Comments: Fix: The check for GLOBALS_HAVE_UNDERSCORE in src/runtime/include/asm-base.h needs to change from ... || defined(OPSYS_FREEBSD) || ... to ... || (defined(OPSYS_FREEBSD) && !defined(__ELF__)) || ... since the ELF-format toolset doesn't prepend an underscore. Fix: [jhr] I believe that this is fixed in 110.0.6 (by assuming that all FREEBSD systems are ELF systems). I'll merge the fix into the 110.25 branch. [jhr] I've committed a change to include/asm-base.h for this problem. Test: Owner: jhr Status: fixed in 110.25 (and 110.0.6) ---------------------------------------------------------------------- Number: 1541 Title: Array2.array equality type incorrect Keywords: Submitter: Stephen Weeks Date: 1/1/2000 Version: 110.9.1 System: x86-linux Severity: major Problem: The basis library spec for Array2.array states that "type t array admits equality even if ty does not". Thus, the following transcript is in error. Transcript: - Array2.fromList[[1.0]] = Array2.fromList[[2.0]]; stdIn:13.1-13.48 Error: operator and operand don't agree [equality type required] operator domain: ''Z * ''Z operand: real Array2.array * real Array2.array in expression: Array2.fromList ((1.0 :: nil) :: nil) = Array2.fromList ((2.0 :: nil) :: nil) Comments: Fix: Test: bug1541.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1542 Title: No syntax error when the equals identifier ("=") is re-bound Keywords: "syntax", "equals", "=", "re-bound" Submitter: Gary Fuehrer (fuehrer@seabase.com) Date: 1/11/2000 Version: 110.26 and earlier System: any Severity: minor Problem: When an attempt is made to re-bind the equals identifier ("=") in a datbind, conbind, or exbind, no syntax error is generated. Code: datbind & conbind: "datatype = = =" exbind: "exception = of int" Transcript: Comments: Fix: Test: bug1542.1.sml, bug1542.2.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1543 Title: DivZero exception in FreeBSD-current Keywords: exception FreeBSD installation Submitter: Thomas Crimi Date: 1/21/00 Version: 110.0.6 System: x86, Any/All FreeBSD 4.0 Subsystem: Installation Severity: major Problem: The installation compilation raises a fatal exception. I've noted this also bootstrapping 110.9.1, the version FreeBSD installs by default. I switched it to 110.0.6 removing the one patched the FreeBSD project included to support ELF. Code: ./install.sh (or FreeBSD's 'make install' in ports) Transcript: Loading: entity/CM/x86-unix/lexer.sml.bin...failed. Trying to compile entity/lexer.sml... GC #0.1.2.4.46.2225: (6 ms) GC #0.1.3.5.47.2278: (25 ms) GC #0.1.3.5.48.2327: (6 ms) uncaught exception divide by zero raised at: translate/wrapping.sml:119.10 - !!! build of sml-cm.x86-bsd failed *** Error code 1 Comments: I will test under 3.4-Release that the same exception does not occur. [Crimi, 1/23/00] The FreeBSD signal's interface has changed slightly, while the testing hasn't been extensive (only simple 1 div 0 at the command line), a patch has been generated to allow sml 110.0.6 to compile on FreeBSD-current. The patches are being submitted to the FreeBSD ports maintainer. Fix: *** src.old/runtime/mach-dep/signal-sysdep.h Sat Jan 22 18:15:21 2000 --- src/runtime/mach-dep/signal-sysdep.h Sun Jan 23 01:46:53 2000 *************** *** 396,403 **** # elif defined(OPSYS_FREEBSD) /** x86, FreeBSD **/ # define SIG_FAULT1 SIGFPE ! # define INT_DIVZERO(s, c) (((s) == SIGFPE) && ((c) == FPE_INTDIV_TRAP)) ! # define INT_OVFLW(s, c) (((s) == SIGFPE) && ((c) == FPE_INTOVF_TRAP)) # define SIG_GetCode(info, scp) (info) # define SIG_GetPC(scp) ((scp)->sc_pc) --- 396,403 ---- # elif defined(OPSYS_FREEBSD) /** x86, FreeBSD **/ # define SIG_FAULT1 SIGFPE ! # define INT_DIVZERO(s, c) (((s) == SIGFPE) && ((c) == FPE_INTDIV)) ! # define INT_OVFLW(s, c) (((s) == SIGFPE) && ((c) == FPE_INTOVF)) # define SIG_GetCode(info, scp) (info) # define SIG_GetPC(scp) ((scp)->sc_pc) Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1544 Title: SML/NJ 110.0.3 inlining bug Keywords: inlining, nontermination Submitter: Allyn Dimock Date: 02/02/00 Version: 110.03 System: sparc-solaris2.7 Severity: critical Problem: Failure to eta-expand within a function body leads to compiler space growing to point where machine thrashes virtual memory... Code: The following code compiles very quickly under CM: fun compTyEnv (envs as (env1,env2,assumpts)) = let (* partially curried for recursive call *) fun compTySub (t1, t2) = compTyEnv (envs) (t1, t2) fun compTy (t1, t2) = ... in compTy end The following version takes a lot of time (until killed) and space for compilation: fun compTyEnv (envs as (env1,env2,assumpts)) = let (* partially curried for recursive call *) val compTySub = compTyEnv (envs) fun compTy (t1, t2) = ... in compTy end Transcript: First version: - CM.make' ("STcompare.cm"); [starting dependency analysis] GC #0.0.1.2.21.604: (0 ms) [parsing STcompare.sml] GC #0.0.1.2.22.692: (20 ms) !% Warning: units not accessible due to filtering: TypInfSTset.sml ../FIL2CIL/SML2CIL/sml-symbol.sml ../FIL2CIL/SML2CIL/Flint2Cildt.sml ConstructorName.sml ExternalOrDeadLabels.sml [dependency analysis completed] GC #0.0.1.2.23.715: (10 ms) GC #0.0.1.2.24.752: (10 ms) [compiling STcompare.sml -> CM/sparc-unix/STcompare.sml.bin] GC #0.0.1.2.25.776: (10 ms) GC #0.0.1.2.26.787: (10 ms) GC #0.0.1.2.27.803: (0 ms) [wrote CM/sparc-unix/STcompare.sml.bin] [introducing new bindings into toplevel environment...] val it = () : unit - Second version: - CM.make' ("STcompare.cm"); [starting dependency analysis] GC #0.0.1.2.28.864: (0 ms) [parsing STcompare.sml] !% Warning: units not accessible due to filtering: TypInfSTset.sml ../FIL2CIL/SML2CIL/sml-symbol.sml ../FIL2CIL/SML2CIL/Flint2Cildt.sml ConstructorName.sml ExternalOrDeadLabels.sml [dependency analysis completed] GC #0.0.1.2.29.1000: (10 ms) [compiling STcompare.sml -> CM/sparc-unix/STcompare.sml.bin] GC #0.1.2.3.30.1052: (70 ms) GC #0.1.2.3.31.1064: (10 ms) GC #0.1.2.3.32.1098: (0 ms) [wrote CM/sparc-unix/STcompare.sml.bin] GC #0.1.2.3.33.1119: (50 ms) GC #1.2.3.4.34.1122: (270 ms) ... GC #7.37.38.39.69.1227: (2470 ms) Interrupt (at which point the memory size shown in top had grown by about 50M. An earlier attempt had gotten the machine thrashing while climbing to over 500M before I killed the process) Comments: Since the val is inside a function, I assume that the problem is an inlining bug: unrolling the function an arbitrary number of times. But I don't know enough of SML/NJ internals to be certain. Note that it claims to have written the bin file before it starts to loop. [dbm, 2/17/00] Need complete test cases. [see: /home/sml/Dev/bugs/1544/bug1544.1.sml] [dbm, 2/21/99] It took me a while to discover the obvious, but it looks to me like you have a loop at execution time, rather than at compile time. You can confirm this by turning on the Stats: Compiler.Stats.sayBegin := true; This will show that the looping doesn't happen until execution time, after compilation has finished. Here is a small piece of code that I claim is equivalent, for the purpose of analyzing the divergence: fun compTyEnv x = let val compTySub = compTyEnv x (* following version ok, because compTyEnv doesn't get called *) fun compTySub z = compTyEnv x z *) in (fn _ => ()) end; val compare = compTyEnv (); (* execution (not compilation!) diverges *) Note that the divergence occurs when the defn of compare is evaluated. Fix: none necessary Test: - Owner: dbm Status: not a bug ---------------------------------------------------------------------- Number: 1545 Title: Datatypes involving the equality type variables are not treated as intended. Submitter: Sukyoung Ryu, puppy@ropas.kaist.ac.kr Date: 02/08/00 Version: 110.0.3 System: - Severity: medium Problem: Datatypes involving the equality type variables are not treated as intended. With the definition: fun f (x:''a) = x the function f has the type ''a -> ''a but, with the definition: datatype ''a t = A of ''a; the datatype constructor A has the type 'a -> 'a t Transcript: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - fun f (x:''a) = x; val f = fn : ''a -> ''a - datatype ''a t = A of ''a; datatype 'a t = A of 'a - A; val it = fn : 'a -> 'a t Comments: [dbm, 2/17/00] This is not a bug, but the expected behavior. When using a type variable as a formal parameter in a type or datatype declaration (or spec), the equality property of the type variable has no significance. In other words, it is not possible to restrict the parameter of a type operator to be an equality type, so using an equality type variable has no special effect. There should probably be a compiler warning when an equality type variable is used in this context, since it generally indicates that the programmer is confused about this point [dbm, 2/18/00] In response to a query from Matthias, here is a further explanation. The purpose of an equality type variable (''a) in the polymorphic type of a function is to indicate that an equality operation may be applied to a value of that type when the body of the function is evaluated. This isn't relevant to other uses of type variables as formal parameters in parametric type/datatype definitions. For instance, in a definition like type 'a foo = 'a * int you are defining a type operator that maps a type t to the type t * int. One could imagine defining type operators with a restricted domain (say only equality types), but I don't see how this would be useful. One might argue that with a definition like type ''a foo = ''a * int you could claim that any well-formed type "t foo" was an equality type (because t would have to be an equality type for "t foo" to be well-formed), but this doesn't seem to differ significantly from the current situation, where we can certify that "t foo" is an equality type if t is. Hence such restricted type operators are not supported in the language design, and the second version of the definition of foo is treated as equivalent to the first version. If I recall correctly, in Haskell one can define type classes that require a type parameter to be of a given type class. But that is so that functions defined for the new type class can use functions associated with the parameter type (similar to functors in SML). Since SML type/datatype declarations don't define functions associated with a type (except for simple, pure structural operations like those encoded as data constructors), they don't need to require functions to be associated with the parameter type. If you want to map a type with assocated functions to a new type with associated functions, SML provides functors. Fix: - Owner: dbm Status: not a bug ---------------------------------------------------------------------- Number: 1546 Title: Value restriction bug Keywords: types Submitter: Andreas Rossberg Date: 2/08/00 Version: 110.0.3 System: Any/All Any Unix Subsystem: SML compiler Severity: major Problem: The value restriction is not implemented properly: in some cases involving polymorphic constructors non-expansive expressions seem to get analyzed as being expansive. Code: datatype 'a t = C of 'a | D val C x = C C Transcript: - datatype 'a t = C of 'a | D; datatype 'a t = C of 'a | D - val C x = C C; stdIn:26.1-26.14 Warning: type vars not generalized because of value restriction are instantiated to dummy types (X1,X2,...) stdIn:26.1-26.14 Warning: binding not exhaustive C x = ... val x = fn : ?.X1 -> ?.X1 t Comments: Strangely enough, the bug does not occur with: datatype 'a t = C of 'a val C x = C C [Matthias, 2/8/00] This is not a bug with the compiler but a (well-known) bug in the definition. The thing that makes this binding a non-value is the fact that it is (formally) refutable. [dbm, 2/17/00] SML/NJ is actually more strict than the Definition in this instance. There is a strict interpretation of the value restriction which regards a binding such as val C x = C C as a nonvalue binding because the pattern matching involved introduces a potential "effect": the raising of the Bind exception if the pattern doesn't match. Of course it is clear that the pattern does match in this simple case, and the compiler could statically perform the matching and transform this into the form val x = C but in other cases like val C x = y one can't tell whether there will be an exception raised or not, so the compiler treats all such bindings as nonvalue bindings. [Matthias, 2/18/00] I had some private e-mail exchange with Andreas on this topic, and one complaint that came up was that the only mention of this behavior as far as the documentation is concerned is deeply buried in the "conversion guide". This is a bit misleading because if I am not actually converting old code I am unlikely to look into the conversion guide but would rather hunt for "SML/NJ extensions to SML" or "how SML/NJ deviates from the Definiton", or some such. Maybe this is worth fixing... [dbm, 2/18/00] You are right, this should be documented more clearly. We used to have a section of the 0.93 manual devoted to language issues (including discrepancies from the Definition), but we don't have this in the current Web documentation. The closest analogue is "Special Features of SML/NJ", which could have an additional section covering this sort of issue. Fix: Test: Owner: dbm, Zhong Status: not a bug (language discrepancy) ---------------------------------------------------------------------- Number: 1547 Title: Treatment of definitional structure specs is bogus Keywords: modules Submitter: Andreas Rossberg rossberg@ps.uni-sb.de Date: 02/08/00 Version: 110.0.3 System: Any/All Any Unix Subsystem: SML compiler Severity: major Problem: Definitional structure specs seem to get ignored during signature matching, rendering the type system unsound. The sample program below results in a Representation exception. Code: signature S = sig type t val x: t val f: t -> string end; structure A :> S = struct type t = int val x = 1 val f = Int.toString end; structure B :> S = struct type t = string val x = "1" fun f s = s end; signature SS = sig structure X : S = A end; structure C :> SS = struct structure X = B end; val x = C.X.f(A.x); Transcript: - C.X.f(A.x); uncaught exception Representation raised at: boot/Unsafe/object.sml:69.19-69.33 print/ppobj.sml:354.20 print/ppobj.sml:354.20 print/ppobj.sml:354.20 print/ppobj.sml:354.20 util/pp.sml:554.6 [in 110.0.6] Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - use "tests/bug1547.1.sml"; [opening tests/bug1547.1.sml] signature S = sig type t val x : t val f : t -> string end structure A : S structure B : S signature SS = sig structure X : sig type t val x : t val f : t -> string end end tests/bug1547.1.sml:10.1-10.47 Error: structure def spec for X not matched Comments: Interestingly, the declaration val _ = C.X.f(A.x) does not cause an exception. Is the function call optimized away as dead code? As a side note: I would love to see the documentation on NJ extensions to the module language be more complete and easier to find (I searched for half an hour until I found it as part of the SML'97 conversion guide). [jhr, 2/8/00] This appears to be fixed in 110.0.6 (at least the compiler issues an error on the definition of C). Fix: Test: bug1547.1.sml Owner: dbm Status: fixed in 110.0.6 (and 110.25) ---------------------------------------------------------------------- Number: 1548 Title: open and signature matching with polymorphic type constructors Keywords: signature matching Submitter: Stephen Weeks Date: 02/09/00 Version: 110.9.1 (also 110.0.6 and 110.25) System: x86-linux Severity: Problem: The following code should type check. It does not. Code: functor F(V: sig type t val v: t end): sig type 'a u val v: 'a u end = struct open V type 'a u = t end On the other hand, the following *does* type check (as it should). All I did was add the "val v = v" binding. functor F(V: sig type t val v: t end): sig type 'a u val v: 'a u end = struct open V type 'a u = t val v = v end Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - use "tests/bug1548.1.sml"; [opening tests/bug1548.1.sml] tests/bug1548.1.sml:3.9-13.4 Error: value type in structure doesn't match signature spec name: v spec: _ V.t actual: V.t Comments: [dbm, 2/17/00] This is a rather peculiar corner of the language, and there could be some question about whether a monotype (like t) should match a polymorphic (albeit degenerate) polytype spec, but given the following behavior in the core language, I guess it should work. - type 'a u = int; type 'a u = int - val x : 'a u = 3; val x = 3 : _ u [Weeks, 2/17/00] I would also like to argue that this is a very useful feature of the language, since I often write functors that take polymorphic type constructors as arguments, and want to instantiate them at monotypes. A common case is sequence types, where I have a functor that I want to work on both polymorphic lists and monomorphic strings. Fix: Test: bug1548.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1549 Title: reproducable segmentation violation Keywords: Submitter: swasey@cs.cmu.edu Date: 2/11/00 Version: 110.9.1 110.25 System: x86-linux (redhat linux 5.2, kernel 2.0.36) sparc-solaris (SunOS 5.5.1) alpha32-dunix (OSF1 V4.0 (Rev 878) + patches) Severity: critical Problem: SML/NJ 110.9.1 fails when executing the code below. On linux I see a segmentation violation. On solaris I see a segmentation violation and a core file. On dunix I see an illegal instruction and a core file. SML/NJ 110.25 fails with a segmentation violation when executing the code on linux. I haven't tried this with 110.25 on any other platforms. Code: signature NUMBER = sig type t end signature VEC = sig structure Number : NUMBER type t val fromSeq : Number.t Vector.vector -> t val toSeq : t -> Number.t Vector.vector end functor PointFromVector(structure Vec : VEC) = struct structure Vec = Vec end signature GEOMETRY_PRIMS = sig structure Point : sig structure Vec : VEC end end functor GeometryPrims2d (structure Number : NUMBER) : GEOMETRY_PRIMS = struct structure Vec = struct structure Number = Number type t = Number.t * Number.t fun fromSeq #[x, y] : t = (x, y) fun toSeq (x,y) = #[x, y] end structure Point = PointFromVector(structure Vec = Vec) end structure RealNumber = struct type t = real end structure RealGeometryPrims2d = GeometryPrims2d(structure Number = RealNumber) local (* #[6.0,0.0] avoids errors *) val vs = RealGeometryPrims2d.Point.Vec.toSeq (6.0, 0.0) in val foo = Array.tabulate (Vector.length vs, fn i => Vector.sub (vs, i)) end Transcript: ### ### 110.9.1 on linux ### Script started on Fri Feb 11 23:44:26 2000 ; uname -a Linux pickled.fox.cs.cmu.edu 2.0.36 #1-PENTIUM+MU-002 Wed Dec 16 01:10:20 EST 1998 i686 unknown ; sml Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 [CM; autoload enabled] - use "min.sml"; [opening min.sml] min.sml:31.13-36.16 Warning: match nonexhaustive #[x,y] => ... GC #0.0.0.0.1.12: (10 ms) /usr/local/lib/sml/110.9.1/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x40c1dbc1 status=1 ; Script done on Fri Feb 11 23:44:34 2000 ### ### 110.25 on linux ### Script started on Fri Feb 11 23:53:46 2000 ; uname -a Linux burnt.fox.cs.cmu.edu 2.0.36 #1-PENTIUM+MU-002 Wed Dec 16 01:10:20 EST 1998 i686 unknown ; sml25 Standard ML of New Jersey v110.25 [FLINT v1.5], December 1, 1999 - use "min.sml"; [opening min.sml] [autoloading] [autoloading done] min.sml:31.13-36.16 Warning: match nonexhaustive #[x,y] => ... /usr0/swasey/foxnet/110.25/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x4061c78b status=1 ; Script done on Fri Feb 11 23:54:00 2000 Comments: 110.0.3 doesn't fail. Sorry the code snippet is so long. When I try to take anything else away, the bug doesn't show up. The workaround we're using is to avoid #[]. [dbm, 2/17/00] Also doesn't fail under 110.0.6/(sparc or x86). [dbm, 6/11/01] Now doesn't fail under 110.33 (x86-linux, alpha-dunix, or sparc-solaris8). Assumed fixed by some change since 110.25. Fix: Test: bug1549.1.sml Owner: Zhong Status: fixed (110.33 or earlier) ---------------------------------------------------------------------- Number: 1550 Title: type error message open to misinterpretation Keywords: Submitter: David B. Benson Date: 2/13/00 Version: 110.0.6 System: x86-linux Severity: quite minor Problem: In the "operator is not a function" type error message, the operator type specification might be misconstrued as specifying the operator itself. Transcript: - datatype d = A; datatype d = A - A 3; stdIn:26.1-26.4 Error: operator is not a function [tycon mismatch] operator: d in expression: A 3 Fix: [dbm, 2/17/00] The message could be made unambiguous by using "operator type" in place of "operator", as in stdIn:26.1-26.4 Error: operator is not a function [tycon mismatch] operator type: d in expression: A 3 Test: Owner: dbm Status: not a bug ---------------------------------------------------------------------- Number: 1551 Title: unexpected behavior with bogus escape sequence in a string Keywords: strings, escape sequence Submitter: "Son Vu" Date: 2/10/00 Version: 110.0.6, 110.25 System: - Severity: minor Problem: When an improper escape sequence appears in a string literal, an "unclosed string" error message occurs (in fact, a pair of such messages occurs). Transcript: - val x = "\c"; stdIn:29.9-29.11 Error: unclosed string stdIn:29.12-29.14 Error: unclosed string - val x = "\d"; stdIn:2.4-2.6 Error: unclosed string stdIn:2.7-2.9 Error: unclosed string - val x = "abc\def"; stdIn:2.4-2.9 Error: unclosed string stdIn:31.3-31.5 Error: unclosed string Comments: [dbm] What is the expected treatment of undefined escape sequences? Perhaps a more precise error message could be provided (e.g. "bad escape sequence in string"). [jhr, 2/17/00] It should report "illegal string escape". Actually, ml.lex looks like it is supposed to do this, but clearly it doesn't for some reason. Fix: Test: bug1551.1.sml Owner: ? Status: open ---------------------------------------------------------------------- Number: 1552 Title: Nonexaustive match failure during compilation Keywords: Submitter: David B. Benson Date: 2/17/00 Version: 110.0.6 System: x86-linux Severity: quite minor Problem: Compiler has a Match failure. Code: Heap.sml OptionQueue.sml sources.cm ----------------------------Heap.sml----------begin (* Heap.sml *) nonfix == ~= ; val == = (op =) and ~= = (op <>) ; infix 4 == ~= ; fun id x = x ; signature PRIORITY_QUEUE = sig structure Priority : REP_KEY type 'a heap val empty : 'a heap val isEmpty : 'a heap -> bool val insert : 'a heap -> 'a * Priority.ord_key -> 'a heap val min : 'a heap -> ('a GriesBurton.queue * Priority.ord_key) option val remove : 'a heap -> 'a heap option end (* signature PRIORITY_QUEUE *) ; functor HeapFn(structure Priority : REP_KEY) : PRIORITY_QUEUE = struct structure Priority : REP_KEY = Priority open GriesBurton; abstype 'a heap = Lf | Br of ('a queue * Priority.ord_key) * 'a heap * 'a heap with val empty = Lf fun isEmpty Lf = true | isEmpty _ = false local fun enqueues(ontoq,fromq) = let val fromqXOption = dequeue(fromq) in if isSome(fromqXOption) then let val (fromq,x) = valOf fromqXOption in enqueues(enqueue(SOME(x,ontoq)),fromq) end else ontoq end fun insert' Lf datas = (print("inserting notequal: "^Priority.toString(priority)^"\n"); Br(datas,Lf,Lf) ) | insert' (Br(v as (xq,priority),t1,t2)) (w as (yq,priority')) = let val which = Priority.compare(priority',priority) in if (which == LESS) then Br(w,insert' t2 v,t1) else if (which == EQUAL) then (print("inserting equal: "^Priority.toString(priority)^"\n"); Br((enqueues(xq,yq),priority),t1,t2) ) else (* which == GREATER *) Br(v,insert' t2 w,t1) end in fun insert heap (x,priority) = insert' heap (enqueue(SOME(x,enqueue NONE)),priority) end(*local*) fun min (Br(data,_,_)) = SOME data | min _ = NONE local fun leftrem (Br(v,Lf,Lf)) = (v,Lf) | leftrem (Br(v,t1,t2)) = let val (w,t) = leftrem t1 in (w,Br(v,t2,t)) end fun siftdown (v,Lf,Lf) = Br(v,Lf,Lf) | siftdown (w as (_,priority),t as Br(v as (_,priority'),Lf,Lf),Lf) = let val which = Priority.compare(priority,priority') in if (which == LESS) then Br(w,t,Lf) else if (which == EQUAL) then raise Fail "Heap.siftdown: EQUAL 1" else (* priority > priority' *) Br(v,Br(w,Lf,Lf),Lf) end | siftdown (w as (_,priority),t1 as Br(v1 as (_,priority1),p1,q1), t2 as Br(v2 as (_,priority2),p2,q2)) = let val w1 = Priority.compare(priority,priority1) val w2 = Priority.compare(priority,priority2) in if (w1 ~= GREATER) andalso (w2 ~= GREATER) then if (w1 == EQUAL) orelse (w2 == EQUAL) then raise Fail "Heap.siftdown: EQUAL 2" else Br(w,t1,t2) else let val w12 = Priority.compare(priority1,priority2) in if (w12 == LESS) then Br(v1,siftdown(w,p1,q1),t2) else if (w12 == EQUAL) then raise Fail "Heap.siftdown: EQUAL 3" else (* priority1 > priority2 *) Br(v2,t1,siftdown(w,p2,q2)) end end in fun remove Lf = NONE | remove (Br(_,Lf,_)) = SOME Lf | remove (Br(_,t1,t2)) = SOME( let val (w,t) = leftrem t1 in siftdown(w,t2,t) end) handle Match => raise Fail "Heap.remove: Match" end(*local*) end(*abstype*) end (* functor HeapFn *) ; ----------------------------Heap.sml----------end ----------------------------OptionQueue.sml----------begin (* OptionQueue.sml *) (* copyright 2000 by David B. Benson *) (* licensed under the provisions of the Open Software Foundation license, 2000 Jan 01 *) nonfix == ~= ; val == = (op =) and ~= = (op <>) ; infix 4 == ~= ; fun id x = x ; signature OPTION_QUEUE = sig type 'x queue val enqueue : ('x * 'x queue) option -> 'x queue val dequeue : 'x queue -> ('x queue * 'x) option val toList : 'x queue -> 'x list end (* signature QUEUE *) ; structure GriesBurton : OPTION_QUEUE = struct datatype 'x queue = GB of 'x list * 'x list fun enqueue NONE = GB([],[]) | enqueue (SOME(x,GB(front,back))) = GB(front,x::back) fun dequeue (GB([],[])) = NONE | dequeue (GB([],back as (x::xs))) = dequeue(GB(rev back, [])) | dequeue (GB(x::xs,back)) = SOME(GB(xs,back),x) fun toList queue = let val xqXOption = dequeue queue in if isSome xqXOption then let val (xq,x) = valOf xqXOption in x :: (toList xq) end else [] end end (* structure GriesBurton *) ; ----------------------------OptionQueue.sml----------end ----------------------------sources.cm----------begin Group signature PRIORITY_QUEUE signature OPTION_QUEUE functor HeapFn structure GriesBurton is smlnj-lib.cm OptionQueue.sml Heap.sml ----------------------------sources.cm----------end Transcript: ----------------------------bug.transcript-------------begin Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - CM.make(); [starting dependency analysis] [scanning sources.cm] [checking CM/x86-unix/sources.cm.stable ... not usable] [scanning /hard/local/sml110.0.6/lib/smlnj-lib.cm -> /hard/local/sml110.0.6/src/smlnj-lib/Util/smlnj-lib.cm] [checking /hard/local/sml110.0.6/src/smlnj-lib/Util/CM/x86-unix/smlnj-lib.cm.stable ... ok - stable] [parsing OptionQueue.sml] OptionQueue.sml:5.1-5.13: declaration not tracked by CM OptionQueue.sml:5.16-5.48: declaration not tracked by CM OptionQueue.sml:5.51-5.64: declaration not tracked by CM OptionQueue.sml:6.1-6.13: declaration not tracked by CM [Creating directory CM/DEPEND ...] [parsing Heap.sml] Heap.sml:3.1-3.13: declaration not tracked by CM Heap.sml:3.16-3.48: declaration not tracked by CM Heap.sml:3.51-3.64: declaration not tracked by CM Heap.sml:4.1-4.13: declaration not tracked by CM [dependency analysis completed] [compiling OptionQueue.sml -> CM/x86-unix/OptionQueue.sml.bin] [Creating directory CM/x86-unix ...] [wrote CM/x86-unix/OptionQueue.sml.bin] [compiling Heap.sml -> CM/x86-unix/Heap.sml.bin] Heap.sml:8.4-14.43 Error: unbound signature: REP_KEY Heap.sml:17.16-17.44 Error: unbound signature: REP_KEY Heap.sml:19.25-19.32 Error: unbound signature: REP_KEY Heap.sml:42.78-42.86 Error: unbound variable or constructor: priority uncaught exception nonexhaustive match failure raised at: modules/sigmatch.sml:845.14 modules/sigmatch.sml:884.25 modules/sigmatch.sml:966.24 elaborate/elabmod.sml:1223.8 elaborate/elabmod.sml:1328.33 util/stats.sml:164.40 sched/recompile.sml:206.38-206.41 - ----------------------------bug.transcript-------------end Comments: This version of the standard heap code is seriously broken, but the bug issue is only the small matter of the compiler giving up. Correcting the sources.cm to locate REP_KEY and fixing the problem on line 42 resulted in the compiler generating code, but this isn't a priority queue implementation! Fix: Test: Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1553 Title: "dependency cycle in instantiate" insufficiently informative Keywords: signatures, sharing, rigid types, error messages Submitter: David B. Benson Date: 2000 Feb 18 Version: 110.0.6 System: x86-linux Severity: minor Problem: With a 109 line signature, it will be difficult to determine the problem -- which ought not exist as this is a minor variation on a signature for the basis library. [see line marked bug BUG] (It appears that this might be an actual bug in sml110.0.6, since the marked line occurs in the basis library signature.) Code: structure S : sig type flags val toWord : flags -> Word32.word val fromWord : Word32.word -> flags val flags : flags list -> flags val allSet : flags * flags -> bool val anySet : flags * flags -> bool type mode = flags val irwxu : mode val irusr : mode val iwusr : mode val ixusr : mode val irwxg : mode val irgrp : mode val iwgrp : mode val ixgrp : mode val irwxo : mode val iroth : mode val iwoth : mode val ixoth : mode val isuid : mode val isgid : mode (**** Comment out the following line to obtain a compilation. bug BUG ****) sharing type flags = mode end Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - [starting dependency analysis] [scanning sources.cm] [checking CM/x86-unix/sources.cm.stable ... not usable] [dependency analysis completed] [recovering CM/x86-unix/LittleChi.sml.bin... done] [recovering CM/x86-unix/Path.sml.bin... done] [compiling PosixPath.sml -> CM/x86-unix/PosixPath.sml.bin] PosixPath.sml:8.1-118.4 Error: dependency cycle in instantiate !* CM error: compile: elaboration failed Comments: [dbm, 2/21/00] Thanks for the bug report (#1553). You are right that the error message is not informative, and we should fix this somehow. In my opinion (though maybe not in Mads Tofte's) there is an actual problem with your code. You have a signature structure S : sig type flags ... type mode = flags ... (**** Comment out the following line to obtain a compilation. bug BUG ****) sharing type flags = mode end In SML '97, one can't have a sharing constraint involving a "rigid" type (one which has an explicit definition). My interpretation is that type mode = flags makes mode a "rigid" type, and therefore it can't appear in a sharing spec (the error message should say this clearly). Mads Tofte's interpretation is that an "identity" spec like that for mode doesn't count as a rigid type, it has to be something like type mode = int * flag where the rhs is not a simple type identifier. I find this pedantic. You could argue that your redundant specifications (in the mode type spec and the sharing spec) are consistent with one another and should be allowed, but dealing with consistent but redundant specs in full generality would be a fairly major hassle, for little or no gain. So I consider this a cosmetic bug relating to the obscurity of the error message. [dbm, 2/21/00] The signature above was derived by doing - open Posix.FileSys; and capturing the printout. Thus the signature prettyprinting code is producing bogus signatures that cannot serve as valid input to the compiler. This should be fixed. Fix: Test: bug1553.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1554 Title: CM stale cache problem Keywords: CM Submitter: Norman Ramsey Date: 2/18/00 Version: 110.0.6 System: - Severity: minor Problem: When I ask CM to make' a file that no longer exists, but that existed earlier, it uses the version in its cache instead of complaining that the version on disk has been removed. For example, I got this message even though there is no primop.cm: !* CM error: ML file NW/primop.sml occurs in more than one group: absrtl.cm, pr imop.cm Comments: [Matthias, 2/22/00] While I don't think it will be easy to fix in 110.0.x, this sort of thing should not occur anymore in the new CM. Fix: Test: - Owner: Matthias Status: fixed in 110.20 (?) ---------------------------------------------------------------------- Number: 1555 Title: should check for degenerate sharing Keywords: signatures, sharing constraints Submitter: John Reppy Date: 2/25/00 Version: 110.x System: - Severity: minor Problem: A degenerate sharing constraint like sharing T = T should generate a warning. Comments: Fix: Test: bug1555.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1556 Title: signal race condition Keywords: signals, interval timer Submitter: Allen Stoughton Date: 3/1/2000 Version: 110.0.6 (and earlier and later) System: various unix Severity: major Problem: A simple program using I/O and the interval timer causes an uncaught Match exception. Code: structure Test = struct fun print s = (Signals.maskSignals Signals.MASKALL; TextIO.print s; Signals.unmaskSignals Signals.MASKALL) fun handler(_, _, k) = k fun loop() = (print "."; loop()) fun doit() = let val slice = Time.fromMilliseconds 50 in Signals.setHandler(Signals.sigALRM, Signals.HANDLER handler); SMLofNJ.IntervalTimer.setIntTimer(SOME slice); loop() end end; Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - - use "test.sml"; [opening test.sml] GC #0.0.0.0.1.6: (10 ms) structure Test : sig val doit : unit -> 'a val handler : 'a * 'b * 'c -> 'c val loop : unit -> 'a val print : string -> unit end val it = () : unit - Test.doit(); stdIn:18.1-18.12 Warning: type vars not generalized because of value restriction are instantiated to dummy types (X1,X2,...) ............................................................................... ............................................................................... ............................................................................... ............................................................................... ............................................................................... ............................. /usr/local/bin/sml: Fatal error -- Uncaught exception Match with 0 raised at boot/NJ/internal-signals.sml:287.30 Comments: [jhr, 3/1/2000] Caused by a race condition in the code that sets masking/unmasking of signals. Fix: New version of file sml-nj/boot/NJ/internal-signals.sml (in 110.0.x, or system/Basis/Implementation/NJ/internal-signals.sml in 110.26). Test: (test code would loop in absence of bug) Owner: jhr Status: fixed in 110.0.7, 110.0.26+ ---------------------------------------------------------------------- Number: 1557 Title: OS.Path.toString raises no exception InvalidArc; InvalidArc not implemented Keywords: Submitter: David B. Benson Date: 2000 Feb 13 Version: 110.0.6 System: x86-linux Severity: quite, quite minor Problem: bad paths are translated to strings by OS.Path.toString. The documentation of OS.Path claims an exception InvalidArc which is not implemented. The documentation states that this exception is raised by OS.Path.toString. Is the implementation or the documentation correct? Code: NONE, see transcript Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - OS.Path.Path; val it = Path(-) : exn - val badpath = {isAbs=false,vol="",arcs=["a/b"]}; val badpath = {arcs=["a/b"],isAbs=false,vol=""} : {arcs:string list, isAbs:bool, vol:string} - val pathString = OS.Path.toString{isAbs=false,vol="",arcs=["a/b"]}; val pathString = "a/b" : string - val path = OS.Path.fromString pathString; val path = {arcs=["a","b"],isAbs=false,vol=""} : {arcs:string list, isAbs:bool, vol:string} - if ( path = badpath ) then print "EQUAL" else print "VIOLATION"; VIOLATIONval it = () : unit - OS.Path.InvalidArc; stdIn:6.1-6.19 Error: unbound variable or constructor: InvalidArc in path OS.Path.InvalidArc - Comments: [jhr, 2/27/2000] Probably the documentation. Fix: Correct the documentation(?). Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1558 Title: Char.isCntrl #"\ddd" where ddd >= 128 should be true Keywords: Char.isCntrl Submitter: Stephen Weeks Date: 03/17/00 Version: 110.9.1 System: x86-linux Severity: Problem: Char.isCntrl #"\ddd" where ddd >= 128 should be true. It currently is false. This behavior is also inconsistent with the Basis Library Spec, which states that Char.isCntrl is equivalent to not o Char.isPrint. - Char.isCntrl #"\128"; val it = false : bool - Char.isPrint #"\128"; val it = false : bool Code: Transcript: Comments: [jhr, 4/10/00] We have resolved that this bug is a mistake in the specification. The Char.isCntrl predicate should return true for ASCII control characters, so the SML/NJ implementation is correct. There will be a new version of the Basis specification out RSN, which will correct this mistake. Fix: Amend Basis documentation. Test: * Owner: jhr Status: specification bug ---------------------------------------------------------------------- Number: 1559 Title: non-empty string matches regular expression only in a non-empty way Keywords: Regexp, DFA backend Submitter: Ed Osinski osinski@cs.nyu.edu Date: 03/30/00 Version: 110.0.6 System: Any/All Solaris 2.6 Subsystem: SML/NJ Library Severity: minor Problem: Using the DFA backend, a non-empty string will never generate an empty match with a regular expression. For example, the string "a" will not match regular expression "(ab)?", but the string "" will. Code: structure Test = struct structure RegExp = RegExpFn (structure P = AwkSyntax structure E = DfaEngine) fun scanString s = (case String.size s of 0 => NONE | 1 => SOME (String.sub (s, 0), "") | _ => SOME (String.sub (s, 0), String.extract (s, 1, NONE))) fun test regStr str = (case RegExp.prefix (RegExp.compileString regStr) scanString str of SOME (MatchTree.Match (SOME {pos,len}, _), src') => let fun readN src 0 cs = String.implode (rev cs) | readN src n cs = let val (c,src') = Option.valOf (scanString src) in readN src' (n-1) (c::cs) end in SOME (readN pos len [], src') end | NONE => NONE) end Transcript: $ sml Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - CM.make (); ... - open Test; ... - test "(ab)?" ""; val it = SOME ("","") : (string * string) option - test "(ab)?" "ab"; val it = SOME ("ab","") : (string * string) option - test "(ab)?" "ac"; val it = NONE : (string * string) option - test "(ab)?" "x"; val it = NONE : (string * string) option Comments: The problem seems to be that once it is determined that the string to be matched is non-empty, attempting to perform an empty match are irrevocably abandoned. Fix: I think the following is a fix, involving only the `loop' function in dfa-engine.sml: diff dfa-engine.sml dfa-engine.sml.orig: -------------------------------------------------------------------------- 28c28 < fun loop (state,p,inits,lastAccepting) = --- > fun loop (state,p,inits,lastP,lastS,lastN) = 30c30 < of NONE => lastAccepting --- > of NONE => (lastP,lastS,lastN) 33c33 < of NONE => lastAccepting --- > of NONE => (lastP,lastS,lastN) 36,45c36,37 < of SOME n => loop (new,p+1,s', < SOME (p+1,s',n)) < | NONE => loop (new,p+1,s', < lastAccepting))) < fun try0 stream = < (case (accepting 0) < of SOME n => SOME (n, < M.Match (SOME {pos=stream,len=0},[]), < stream) < | NONE => NONE) --- > of SOME n => loop (new,p+1,s',p+1,s',n) > | NONE => loop (new,p+1,s',lastP,lastS,lastN))) 48,56c40,53 < of NONE => try0 stream < | SOME (c,s') => < (case loop (0,p,stream,NONE) < of NONE => try0 stream < | SOME (last,cs,n) => < SOME (n, < M.Match (SOME {pos=stream, len=last-p}, < []), < cs)) --- > of NONE => (case (accepting 0) > of SOME n => SOME (n,M.Match (SOME {pos=stream,len=0},[]),stream) > | NONE => NONE) > | SOME (c,s') => > if (canStart c) > then let val (last,cs,n) = loop (0,p,stream,~1,stream,0) > in > if (last<0) > then NONE > else SOME (n,M.Match (SOME {pos=stream, > len=last-p}, > []),cs) > end > else NONE -------------------------------------------------------------------------- Test: Owner: Riccardo Status: open ---------------------------------------------------------------------- Number: 1560 Title: Compiler bug: Reconstruct: rator in profiling mode Keywords: profiler, compiler bug Submitter: Larry Paulson Date: 3/21/00 Version: 110.0.3 System: x86-linux Severity: medium Problem: I added the line Compiler.Profile.setProfMode true; to line 21 of Pure/ML-Systems/smlnj.ML, and compiled with Version 110.0.3, I tried to recompile by Code: isabelle Transcript: perch: cd HOL /homes/lcp/isabelle/Repos/HOL perch: nice isatool make make[1]: Entering directory `/Nfs/heaton/usr28/lcp/isabelle/Repos/Pure' Building Pure ... Finished Pure (0:04:30 elapsed time) make[1]: Leaving directory `/Nfs/heaton/usr28/lcp/isabelle/Repos/Pure' Building HOL ... HOL FAILED (see also /homes/lcp/isabelle/heaps/smlnj-110/log/HOL) -> theory -> theory * thm list list * thm list list * thm list list * DatatypeAux.simproc_dist list * thm end Error: Compiler bug: Reconstruct: rator *** Error *** At command "theory" (line 5 of "/Nfs/heaton/usr28/lcp/isabelle/Repos/HOL/In ductive.thy"). Comments: [dbm] Not yet reproduced here. Fix: Test: - Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1561 Title: modulo operator (mod) causes a crash on Alpha Keywords: mod Submitter: Hongwei Xi Date: 04/14/00 Version: 110.0.3 System: Alpha, ** linux ** Subsystem: SML basis library Severity: major Problem: Do the following 4 mod 2; And you get: Fatal error: unexpected fault, signal = 8, code = 0 Code: 4 mod 2; Transcript: Fatal error: unexpected fault, signal = 8, code = 0 Comments: [jhr, 4/14/00] Works ok in 110.0.6. [Lal, 4/14/00] I just discovered that this is an alpha running Linux; a port that was done by one of the local systems people. Fix: Test: Owner: Lal Status: open? ---------------------------------------------------------------------- Number: 1562 Title: CM complains about unrecognized file extension ".fun" Keywords: CM, file extensions, CM plug-ins Submitter: Simon Helsen Date: 4/20/00 Version: 110.27 System: - Severity: minor Problem: CM tries to load a library (fun-ext.cm) which is not there. Transcript: ... [parsing ./library/array/../basic/pair.sig] [attempting to load plugin fun-ext.cm] [scanning ./library/array/../basic/fun-ext.cm] [unable to load plugin fun-ext.cm] [parsing ./library/array/../basic/pair.fun] ... It tries to load fun-ext.cm several times. Comments: [Matthias, 4/20/00] My guess is that Simon has a file named .fun in his pe system. CM does not know about a filename extension "fun", so it goes and tries to load a tool for it. After failing to find one, it falls back to the old behavior of treating unknown files as ML files... The solution is to rename the file to .sml or to add an explicit class specification: .foo : sml Another solution would be to make a "fun-ext.cm" tool class that, when loaded, has the effect of registering "fun" as an extension that maps to the "sml" class... In this case I think that would be overkill, though. [Simon Helsen, 4/25] yes, I have loads of files which have extension ".fun". Every file in my system contains either a signature (.sig) a structure (.sml) or a functor (.fun) This distinction is very practical and I don't want to change that. So, you are saying that to solve this, I have to add "blabla.fun : sml" for every blabla functor? I don't think this is an improvement for CM. I understand you can't make an exception just for my convention (which is actually Steven Weeks' convention - he uses this in his MLTon compiler), but it would be nice if I could tell CM at just one place that extensions .fun should be treated like .sig or .sml Fix: .fun added to the set of extensions that imply class sml Test: Owner: Matthias Status: fixed in 110.28 ---------------------------------------------------------------------- Number: 1563 Title: redundant pathconfig contents with multiple builds Keywords: CM, pathconfig, installation Submitter: Dave MacQueen Date: 4/27/00 Version: 110.27 System: - Severity: medium Problem: If installation is performed for several architectures in the same directory, multiple redundant copies of the pathconfig contents are created in the lib/pathconfig file. Code: Transcript: Comments: Fortunately, the contents don't vary with platform, so the path config bindings all agree. Fix: Test: Owner: Matthias Status: open ---------------------------------------------------------------------- Number: 1564 Title: signature prettyprinting not correct Keywords: pretty printing, signatures, modules Submitter: Dave MacQueen Date: 5/1/2000 Version: 110.27 System: - Severity: medium Problem: When the top level prints signatures, the "end" keywords are not lined up with the corresponding "sig". Code: Transcript: arran$ sml Standard ML of New Jersey v110.27 [FLINT v1.5], April 10, 2000 - use "tests/bug1420.1.sml"; [opening tests/bug1420.1.sml] signature CAT = sig eqtype cat val c : cat end signature L_F = sig eqtype t structure Cat : sig type cat = t val c : cat end val r : t end signature S = sig structure Cat : sig eqtype cat val c : cat end structure LF : sig eqtype t structure Cat : val r : t end end val it = () : unit - arran$ /home/sml/Versions/110.9.1/bin/sml Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 [CM; autoload enabled] - use "tests/bug1420.1.sml"; [opening tests/bug1420.1.sml] signature CAT = sig eqtype cat val c : cat end signature L_F = sig eqtype t structure Cat : sig type cat = t val c : cat end val r : t end signature S = sig structure Cat : sig eqtype cat val c : cat end structure LF : sig eqtype t structure Cat : val r : t end end Comments: Probably caused by the replacement of the old Compiler.PrettyPrint by its emulation using the smlnj-lib prettyprinter. Possibly a bug in the emulation of the old prettyprinter. Fix: Test: bug1420.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1565 Title: Overflow exception while loading IntInf Keywords: IntInf Submitter: Daniel C. Wang danwang@cs.princeton.edu Date: 05/18/00 Version: 110.0.6 System: x86 Other (describe below) Windows 98 Subsystem: SML/NJ Library Severity: major Problem: Using the most recent self-installing executable (I downloaded it last night) any code that uses IntInf from the SML-NJ library dies with an exception when loading the code. Code: --sources.cm-- Group is smlnj-lib.cm test.sml ----test.sml-- val x = IntInf.+(IntInf.fromInt 1,IntInf.fromInt 2) Transcript: - CM.make(); ... [recovering c:\local\src\src\smlnj-lib\Util\CM\x86-win32\int-inf-sig.sml.bin... done] [recovering c:\local\src\src\smlnj-lib\Util\CM\x86-win32\int-inf.sml.bin...GC #0.0.0.1.3.71: (0 ms) done] !* CM error: c:\local\src\src\smlnj-lib\Util\int-inf.sml: exception raised in user code uncaught exception overflow raised at: util/stats.sml:164.40 Comments: The reference to util/stats.sml suggests that this bug is related to the profiling code. Perhaps the smlnj-lib was shipped with profiling turned on? In fact destablizing the library and recompiling int-inf.sml seems to solve the problem. Fix: Recompile the libraries with the shiped compiler. Test: Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1566 Title: GetOpt library not handling option parameters Keywords: GetOpt, command line Submitter: Fermin Reig Date: 5/31/00 Version: 110.? System: - Severity: medium Problem: I've observed the following when using the GetOpt library: prog -o /tmp/foo.out .... The string that getOpt returns is " /tmp/foo.out", including leading white space. In the example above, I get a "SysErr: No such file or directory", whereas everything works fine if I type: prog -o/tmp/foo.out .... man getopt says that required arguments can be separated by white space: A simple short option is a `-' followed by a short option character. If the option has a required argument, it may be written directly after the option character or as the next parameter (ie. separated by whites- pace on the command line). If the option has an optional argument, it must be written directly after the option character if present. Comments: [jhr, 6/22/00] I've looked into this bug, and I cannot reproduce your problem. In fact, looking at the GetOpt code, the only explanation I can think of for this problem is a bug in the shell script that you are using to invoke your sml program. Specifically, I suspect that the -o /tmp/foo.out is getting passed to sml as a single argument, instead of as two distinct arguments. If that is the case, then seeing the leading space on /tmp/foo.out is the desired behaviour. [Riccardo, 6/22/00] I concur with John. If "-o /tmp/foo.out" would be passed to sml as two arguments, then the separating white space would have been eaten by the code to transform the command-line into a list of strings, and it would have been passed to GetOpt as two different elements in the list, with no leading whitespace (which works for options with required arguments). John: it may be good to change the header comment in getopt-sig.sml to reflect the fact that now we don't use exceptions to report errors anymore but rely on a errFn provided to getOpt, and to also reflect that in the comment after the signature of the getOpt function. (I'm look at version 110.0.6 of smlnj-lib). - R Owner: jhr Status: not a bug ---------------------------------------------------------------------- Number: 1567 Title: Error: Compiler bug: InlInfo: Wrong field in INL_STR ! Keywords: elabmod, signature Submitter: Allyn Dimock Date: 06/13/00 Version: 110.05 System: - Severity: major Problem: In compiling a file with multiple errors, just after an error diagnostic about the input: Error: value type in structure doesn't match signature spec message, the compiler prints: Error: Compiler bug: InlInfo: Wrong field in INL_STR ! SML/NJ hangs waiting for input, then when is pressed prints uncaught exception Error raised at: util/errormsg.sml:54.14-54.19 elaborate/elabmod.sml:1223.8 util/stats.sml:164.40 sched/recompile.sml:206.38-206.41 - Error: Compiler bug: InlInfo: Wrong field in INL_STR ! and returns to command loop. Repeating with the same input yields the same error except for no pause between error message and exception backtrace. Partial fix to errors in the source file yields same SML/NJ error after: Error: constructor and argument don't agree. fixing the following error in the source code caused SML/NJ to report all remaining errors in the source code and return correctly with !* CM error: compile: elaboration failed ../reps/TypInfST.sml:7.3-119.2 Error: duplicate specifications for variable or constructor multiAbs in signature change in signature to fix: val multiAbs : TypeVariable.tVar list -> Typ -> Typ val multiAbs : Typ list -> Typ -> Typ to val multiAbs : TypeVariable.tVar list -> Typ -> Typ val multiApp : Typ list -> Typ -> Typ Code: If you need it, remind me to send you the buggy version of TypInfSt.sml and all files that it depends on. Transcript: Standard ML of New Jersey, Version 110.0.5, September 1, 1999 [CM&CMB] - CM.make'("../reps/TypInfST.cm"); [starting dependency analysis] [scanning ../reps/TypInfST.cm] [checking ../reps/CM/sparc-unix/TypInfST.cm.stable ... not usable] ... [recovering ../../src/minimal-graph/stable/CM/sparc-unix/minimal-graph-fn-jef.sml.bin... done] [recovering ../reps/CM/sparc-unix/TypeDataDefns.sml.bin... done] [compiling ../reps/TypInfST.sml -> ../reps/CM/sparc-unix/TypInfST.sml.bin] ../reps/TypInfST.sml:26.25-26.29 Error: unbound type constructor: fVar ../reps/TypInfST.sml:66.23-66.27 Error: unbound type constructor: fVar ../reps/TypInfST.sml:7.3-119.2 Error: duplicate specifications for variable or constructor multiAbs in signature ../reps/TypInfST.sml:339.26-339.29 Error: unbound type constructor: Typ ../reps/TypInfST.sml:338.24-338.27 Error: unbound type constructor: Typ ../reps/TypInfST.sml:325.37-325.40 Error: unbound type constructor: Typ ../reps/TypInfST.sml:325.26-325.29 Error: unbound type constructor: Typ ../reps/TypInfST.sml:323.35-323.38 Error: unbound type constructor: Typ ../reps/TypInfST.sml:317.59-317.62 Error: unbound type constructor: Typ ../reps/TypInfST.sml:317.43-317.46 Error: unbound type constructor: Typ ../reps/TypInfST.sml:304.37-304.40 Error: unbound type constructor: Typ ../reps/TypInfST.sml:298.65-298.68 Error: unbound type constructor: Typ ../reps/TypInfST.sml:296.67-296.70 Error: unbound type constructor: Typ ../reps/TypInfST.sml:294.51-294.54 Error: unbound type constructor: Typ ../reps/TypInfST.sml:292.52-292.55 Error: unbound type constructor: Typ ../reps/TypInfST.sml:291.36-291.39 Error: unbound type constructor: Typ ../reps/TypInfST.sml:291.27-291.30 Error: unbound type constructor: Typ ../reps/TypInfST.sml:956.11-998.51 Error: constructor and argument don't agree in pattern [tycon mismatch] constructor: {fvar:fVar, tags:Label list, types:_ list} -> typm argument: {fvar:'Z, tag:'Y, tags:'X, types:'W} in pattern: VariantType {fvar=fvar,tag=tag,tags=tags,types=types} ../reps/TypInfST.sml:956.11-998.51 Error: constructor and argument don't agree in pattern [tycon mismatch] constructor: {fvar:fVar, tags:Label list, types:_ list} -> typm argument: {fvar:'Z, tag:'Y, tags:'X, types:'W} in pattern: UnionType {fvar=fvar,tag=tag,tags=tags,types=types} Error: Compiler bug: InlInfo: Wrong field in INL_STR ! uncaught exception Error raised at: util/errormsg.sml:54.14-54.19 elaborate/elabmod.sml:1223.8 util/stats.sml:164.40 sched/recompile.sml:206.38-206.41 - Comments: Fix: Test: Owner: dbm, Zhong Status: open ---------------------------------------------------------------------- Number: 1568 Title: installing under digital unix (tru64) 5.0 Keywords: installation, digital unix Submitter: Yichen Xie Date: 6/14/00 Version: 110.28? System: alpha32, dunix (5.0) Severity: major Problem: Using the configuration for dgux 4.0d, sml fails during installation (when trying to write heap image, I think) with: /home/xie/sml2/bin/.run/run.alpha32-dunix: Fatal error -- unexpected fault, signal = 8, code = 0x1 config/install.sh !!! Boot code failed, no heap image (sml.alpha32-dunix). The reason turns out to be that dgux 5.0 handles SIGFPE differently as for dgux 4.0*. Instead of sending FPE_INTOVF_FAULT (0xf), the system sends FPE_INTOVF_TRAP (0x1) when there's an integer overflow. Comments: Fix: The fix is to replace FPE_INTOVF_FAULT w/ FPE_INTOVF_TRAP in runtime/mach-dep/signal-sysdep.h. Or (unrecommended) do # sysconfig -r generic use_faulty_fpe_traps=1 as root. Of course, the following line also needs to be added to config/_arch-n-opsys undef the OSF1) case: V5.*) ARCH=alpha32; OPSYS=dunix ;; Relevant portion of /usr/include/machine/signal.h is attached below. Yichen /usr/include/machine/signal.h ============================= /* FPE signal code usage note: In some previous releases, FAULT codes were incorrectly used when TRAP codes should have been. But, both then and now, true TRAPs and FAULTs could be distinguished by comparing the sc_pc and the sc_trap_pc fields of the signal context block. With a true FAULT, the sc_pc field contains the trigger PC of the faulting instruction. With a true TRAP, sc_pc contains the trap PC where the exception was realized (and so it will be the same as sc_fp_trap_pc). See the ieee(3) man page for details. To continue from a FAULT (with the default IEEE result for the exceptional operation), a signal handler might look something like: void fpe_handler(int sig, int code, struct sigcontext *scp) { . . . . if (scp->sc_pc != scp->sc_fp_trap_pc) scp->sc_pc += 4; . . . . } If it is a true FAULT, incrementing sc_pc by 4 is necessary to advance the PC beyond the exceptional instruction. (Or, the handler could correct the exceptional condition and allow the faulting instruction to re-execute). For existing executables which cannot handle correct TRAP codes, the old, incorrect behavior of always using FAULT codes can be restored by setting a configurable system parameter: # sysconfig -r generic use_faulty_fpe_traps=1 which will cause the system to continue to incorrectly use FAULT codes when TRAP codes should be produced. */ Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1569 Title: segfault in BuildLiterals Keywords: runtime Submitter: Daniel C. Wang danwang@cs.princeton.edu Date: 06/15/00 Version: 110.28 System: Any/All Any Unix Subsystem: SML compiler Severity: major Problem: A bug in src/runtime/build-literals.c causes the runtime to segfault when the first generation is set to a size less than 64k. Code: Load some code with @SMLalloc=x for x < 64k Comments: I've tested a fix that sets availspace to the actual amount of free space and it seems to work, but perhaps an expert can do a better job of it. [Matthias, 6/15/00] I am the one who set alloc to 32k on Celerons. This is because I found that my Celeron at home runs fastest this way. (Tiny second-level cache.) When I did this, I also noticed that the boot sequence crashes when (at bootstrap time) alloc is set so low. But I never saw a crash once the system had already booted. That's why the boot scripts (install.sh, makeml) do not set alloc to such a low value. Anyway, a fix is highly appreciated. Performance on Celerons really hurts when alloc is set higher. [jhr, 6/19/00] The proposed fix is not quite right. If you are trying to support heaps smaller than 64Kb (68Kb actually), then you should use the heap size as the argument to NeedGC. Fix: The bogus code is in line: 100 (of latest CVS version) if (NeedGC(msp, 64*ONE_K)) InvokeGCWithRoots (msp, 0, (ml_val_t *)&lits, &stk, NIL(ml_val_t *)); availSpace = 64*ONE_K; This code incorrectly assumes the available space after the GC is equal to the requested 64*k which isn't true if the first generation size is set to less than 64k. BTW On Linux boxes running on Celerons the current .run-sml script sets @SMLalloc=32k by default. Here's a patch against the latest CVS sources. It be nice if you could verify it fixes the problems you noticed. I ran into the bug when trying to compile the C-- compiler with the version 110.28. If I only new what BuildLiterals did, maybe I could construct a smaller test program to exercise the bug. In anycase here's the patch Index: gc/build-literals.c =================================================================== RCS file: /home/cvs/sml-dist/src/runtime/gc/build-literals.c,v retrieving revision 1.2 diff -c -r1.2 build-literals.c *** gc/build-literals.c 2000/06/01 18:33:49 1.2 --- gc/build-literals.c 2000/06/15 15:22:18 *************** *** 97,105 **** ASSERT(pc < len); availSpace -= 3*WORD_SZB; /* space for stack cons cell */ if (availSpace < ONE_K) { ! if (NeedGC(msp, 64*ONE_K)) ! InvokeGCWithRoots (msp, 0, (ml_val_t *)&lits, &stk, NIL(ml_val_t *)); availSpace = 64*ONE_K; } switch (lits[pc++]) { case I_INT: --- 97,108 ---- ASSERT(pc < len); availSpace -= 3*WORD_SZB; /* space for stack cons cell */ if (availSpace < ONE_K) { ! if (NeedGC(msp, 64*ONE_K)) { ! InvokeGCWithRoots (msp, 0, (ml_val_t *)&lits, &stk, NIL(ml_val_t *)); ! availSpace = GCSpaceFree(msp); ! } else { availSpace = 64*ONE_K; + } } switch (lits[pc++]) { case I_INT: Index: gc/call-gc.c =================================================================== RCS file: /home/cvs/sml-dist/src/runtime/gc/call-gc.c,v retrieving revision 1.3 diff -c -r1.3 call-gc.c *** gc/call-gc.c 2000/06/01 18:33:49 1.3 --- gc/call-gc.c 2000/06/15 15:22:18 *************** *** 354,359 **** --- 354,369 ---- } /* end of NeedGC */ + Word_t GCSpaceFree (ml_state_t *msp) + { + Word_t nbytes; + #if defined(MP_SUPPORT) + nbytes = ((Addr_t)(msp->ml_limitPtr)) - ((Addr_t)(msp->ml_allocPtr)); + #else + nbytes = ((Addr_t)HEAP_LIMIT(msp->ml_heap)) - ((Addr_t)(msp->ml_allocPtr)); + #endif + return nbytes; + } #ifdef SOFT_POLL /* ResetPollLimit: Index: include/gc.h =================================================================== RCS file: /home/cvs/sml-dist/src/runtime/include/gc.h,v retrieving revision 1.2 diff -c -r1.2 gc.h *** include/gc.h 2000/06/01 18:33:50 1.2 --- include/gc.h 2000/06/15 15:22:18 *************** *** 19,24 **** --- 19,25 ---- extern void InvokeGC (ml_state_t *msp, int level); extern void InvokeGCWithRoots (ml_state_t *msp, int level, ...); extern bool_t NeedGC (ml_state_t *msp, Word_t nbytes); + extern Word_t GCSpaceFree(ml_state_t *msp); extern int GetObjGen (ml_val_t obj); extern ml_val_t RecordConcat (ml_state_t *msp, ml_val_t r1, ml_val_t r2); Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1570 Title: RecoverLty exception Keywords: RecoverLty, mutually recursive functions Submitter: Matthias Blume Date: 2000/06/23 11:15:00 JST Version: 110.28.1 System: ALL Severity: critical Problem: This concerns 110.28.1 + recent CVS updates (on the main trunk). The CVS tag is blume-20000619-manual. The problem is that the compiler dies with an exception RecoverLty when compiling a certain set of mutually recursive functions. This seems to be a FLINT problem. There is a "flint.core" file afterwards. The sample code (see below) implements a glorified factorial function. (It serves as a test case for my new BTrace stuff.) Code: structure X = struct fun main n = let fun a (x, 0) = d x | a (x, n) = b (x, n - 1) and b (x, n) = c (x, n) and c (x, n) = a (x, n) and d x = e (x, 3) and e (x, 0) = f x | e (x, n) = e (x, n - 1) and f 0 = 1 | f n = n * g (n - 1) and g n = a (n, 3) in f n end end Transcript: Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000 - use "x.sml"; [opening x.sml] while in specialize phase raised at: ../MLRISC/library/intmap.sml:29.41-29.44 ../compiler/MiscUtil/util/stats.sml:190.40 uncaught exception RecoverLty raised at: ../MLRISC/library/intmap.sml:29.41-29.44 ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/FLINT/main/flintcomp.sml:179.13 ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/TopLevel/interact/evalloop.sml:60.55 ../compiler/TopLevel/interact/evalloop.sml:243.25-243.28 ../compiler/TopLevel/interact/evalloop.sml:60.55 ../compiler/TopLevel/main/compile.sml:244.13-244.58 ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/TopLevel/interact/evalloop.sml:60.55 Comments: I noticed this while experimenting with by "BTrace" module which does an Absyn->Absyn transformation before sending the stuff to FLINT. However, to my initial surprise, the problem occurs when I DO NOT use my new phase (and also occurs in an unmodified) version of SML/NJ but goes away when I turn BTrace on... (In other words, the problem is not mine.) Fix: Test: bug1570.1.sml Owner: Zhong, Stefan Status: open ---------------------------------------------------------------------- Number: 1571 Title: drastic slowdown of startup on alpha Keywords: startup, performance, alpha32 Submitter: Dave MacQueen Date: 6/23/00 Version: 110.28.1+ (CVS version as of about 6/19?), but not 110.28.1 System: alpha32-dunix Severity: critical Problem: There has been a drastic slowdown on the alpha caused by some change that was introduced recently in the repository (before yesterday, I think). Here is the startup time for 110.28: trappist$ cd /home/sml/Versions/110.28 trappist$ time bin/sml < XXX Standard ML of New Jersey v110.28 [FLINT v1.5], May 1, 2000 - real 0m0.86s user 0m0.08s sys 0m0.18s Here is the startup after compiling to a fixpoint with the current repository state: trappist$ cd /home/sml/Dev/dbm/110.26/smlnj trappist$ time bin/sml < XXX Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000 - real 0m53.36s user 0m1.58s sys 0m7.91s Similar but less drastic slowdown has occured for sparc-solaris. vex$ cd /home/sml/Versions/110.28 vex$ time bin/sml < XXX Standard ML of New Jersey v110.28 [FLINT v1.5], May 1, 2000 - real 0m0.65s user 0m0.29s sys 0m0.29s vex$ cd /home/sml/Dev/dbm/110.26/smlnj vex$ time bin/sml < XXX Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000 - real 0m7.12s user 0m1.80s sys 0m3.28s ... but apparently not for x86-linux: arran$ cd /home/sml/Versions/110.28 arran$ time ../../bin/sml < XXX /bin/ksh: ../../bin/sml: not found real 0m0.05s user 0m0.01s sys 0m0.00s arran$ cd /home/sml/Dev/dbm/110.26/smlnj arran$ time ../../bin/sml < XXX /bin/ksh: ../../bin/sml: not found real 0m0.04s user 0m0.00s sys 0m0.01s Code: Transcript: Comments: I am pretty sure this slowdown predates Matthias's checkin of 2000/06/23, and I think it started fairly recently, since I have been doing updates and booting to fixpoints on a regular basis and noticed this slowdown for the first time yesterday (6/22). A quick check indicates that the benchmarks have not slowed down significanly, though we haven't compared 110.28.1+ with 110.28 yet. One planned experiment is to build the 110.28.1 version and check its startup timing. This slow start problem does _not_ exist in 110.28.1 (tag blume-20000606-lazierpickle), as tested on alpha32-dunix, sparc-solaris, x86-linux. So it is due to some change since 6/6/00. [dbm, 6/23/00] On sparc/solaris, the truss command will print out a trace of all system calls. This can be used to test whether the system calls have gone wild. Results: vex$ cd /home/sml/Dev/dbm/110.26/smlnj vex$ truss bin/sml > truss.out 2>&1 < XXX vex$ wc truss.out 85584 308451 2885212 truss.out vex$ cd /home/sml/Versions/110.28 vex$ pwd /home/sml/Versions/110.28 vex$ truss bin/sml > truss.out 2>&1 < XXX vex$ wc truss.out 2204 12251 94638 truss.out So 110.28 does 2204 system calls on startup, while 110.28.1+ does 85584. This would seem to account for the slowdown There is a similar ratio of system calls on x86 (using strace instead of struss), though there isn't a noticeable slowdown for the x86. arran$ cd ../../110.26/smlnj arran$ strace bin/sml > strace.out 2>&1 < XXX arran$ wc strace.out 78895 366131 4488303 strace.out arran$ pwd /home/sml/Dev/dbm/110.26/smlnj arran$ bin/sml Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000 - arran$ cd ../../110.28.1/smlnj arran$ strace bin/sml > strace.out 2>&1 < XXX arran$ wc strace.out 1271 6897 75257 strace.out [jhr, 6/23/00] If you look at the two truss.out files, it appears that the extra work in 110.28.1 has to do with CM. The two files have a fairly common prefix, but the longer one has many sequences of the following form: stat("/n/bopp/shome/sml/Dev/dbm/110.26/smlnj/src/system/sml.boot.sparc-unix/smlnj/int ernal/cm-lib.cm", 0xEFFFF570) Err#2 ENOENT pathconf(".", _PC_PATH_MAX) = 1024 stat("./", 0xEFFFF10C) = 0 stat("/n/bopp/shome/sml/Dev/dbm/110.26/smlnj", 0xEFFFF084) = 0 chdir("/") = 0 lstat("n", 0xEFFFF570) = 0 chdir("n") = 0 lstat("bopp", 0xEFFFF570) = 0 chdir("bopp") = 0 lstat("shome", 0xEFFFF570) = 0 chdir("shome") = 0 lstat("sml", 0xEFFFF570) = 0 chdir("sml") = 0 lstat("Dev", 0xEFFFF570) = 0 chdir("Dev") = 0 lstat("dbm", 0xEFFFF570) = 0 chdir("dbm") = 0 lstat("110.26", 0xEFFFF570) = 0 chdir("110.26") = 0 lstat("smlnj", 0xEFFFF570) = 0 chdir("smlnj") = 0 lstat("src", 0xEFFFF570) = 0 chdir("src") = 0 lstat("system", 0xEFFFF570) = 0 chdir("system") = 0 lstat("sml.boot.sparc-unix", 0xEFFFF570) = 0 chdir("sml.boot.sparc-unix") = 0 lstat("smlnj", 0xEFFFF570) = 0 chdir("smlnj") = 0 lstat("internal", 0xEFFFF570) = 0 chdir("/n/bopp/shome/sml/Dev/dbm/110.26/smlnj") = 0 I assume these are being generated by CM. [Matthias, 6/24/00] I agree, this looks very much like a CM bug. I recently changed (= rewrote from scratch) the pathname handling that is central to all of CM's operation. I think that it is basically sound, but there was a chdir-related bug, and I have the feeling that I got the fix for it wrong. I'll look into it ASAP. Fix: Test: Owner: Matthias Status: fixed in 110.28.1+ [Matthias, 6/24/00] ---------------------------------------------------------------------- Number: 1572 Title: performance slowdown, pequal? Keywords: performance, pequal Submitter: Stefan Monnier Date: 6/12/00 Version: 110.28.1? System: x86-linux Severity: major Problem: I have a strange performance issue here on x86. When running with the latest version checked out of the CVS repository, but using the old CPS-optimizer, I get considerably slower code than with 110.25 (whereas I can't see such a slowdown on SPARC). I figured I might have screwed something up, so I checked further. 110.26 (as defined by the tag v110_26_0 at least) run with FLINTopt turned off and replaced by the old cpsopt is just as fast as 110.25 (unsurprisingly). That means that the slowdown has been introduced between v110_26_0 (the revision that I tagged last December with the intention of making it 110.26) and now. So I checked all the changes I've made since then. They touched (ignoring ml-yacc and sml-mode changes): smlnj/src/compiler/FLINT/ChangeLog smlnj/src/compiler/FLINT/cpsopt/cpsopt.sml smlnj/src/compiler/FLINT/opt/fcontract.sml smlnj/src/compiler/FLINT/opt/switchoff.sml smlnj/src/compiler/FLINT/opt/fixfix.sml smlnj/src/compiler/FLINT/opt/abcopt.sml smlnj/src/compiler/FLINT/main/control.sml smlnj/src/compiler/FLINT/main/flintcomp.sml smlnj/src/compiler/FLINT/reps/equal.sml smlnj/src/compiler/FLINT/reps/typeoper.sml smlnj/src/compiler/FLINT/kernel/primop.sml smlnj/src/compiler/FLINT/kernel/primop.sig smlnj/src/compiler/FLINT/plambda/flintnm.sml smlnj/src/system/testml smlnj/src/cm/semant/semant.sml smlnj/src/compiler/Parse/parse/ml.grm smlnj/src/compiler/TopLevel/viscomp/control.sml smlnj/src/compiler/TopLevel/interact/evalloop.sml The semant.sml change was just fixing a typo that prevented compilation (a missing parenthesis). The evalloop change was to prevent the interactive loop from hiding useful exception information. So I checked out a fresh copy of the latest smlnj and then did: cvs update -r v110_26_0 src/compiler/FLINT cvs update -A src/compiler/FLINT/trans cvs update -r v110_26_0 src/compiler/TopLevel/viscomp/control.sml cvs update -r v110_26_0 src/compiler/Parse/parse/ml.grm [ the v110_26_0 of FLINT/trans/pequal.sml posed problem during compilation because of changes in the environments. ] So, unless I missed a change, this should have reverted all the FLINT changes to v110_26_0. Yet, the performance of that hybrid version (again with FLINTopt turned off and replaced by the old cpsopt) is still the same as that of 110.28.1. Allen tells me that 110.25 with MLRISC updates is _fast_, so I'm tempted to believe that the problem might have been introduced by CM changes. Maybe this new FLINT/trans/pequal.sml code does not do quite the same as before (such as using more registers, which could explain that it impacted x86 but not SPARC) ? I intended to try to go back in time with CVS to see which change introduced this misbehavior, but there's been many tricky bootstrapping steps over those months and the auto-fetched binfiles have all disappeared. So if a bootstrap-wizard could look into it (starting by trying to revert the pequal change, maybe). My tests are carried with the repository's benchmark suite like this: (echo 'Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"]; Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"];'; bin/runit 10 /dev/tty b-hut ) | sh -x ../trunk/src/system/testml (echo 'CM.autoload "host-compiler.cm";'; echo 'Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"]; Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"];'; bin/runit 10 /dev/tty b-hut ) | sh -x ../110.26/src/system/testml With the above example (i.e. barnes-hut), I get a run time of around 2.3 seconds for 110.26 and 2.7 for 110.28. I'd also love to hear just if someone else can or cannot reproduce this problem. To turn off the flint optimizer (revert it back to what it was in 110.25), do: Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"]; To turn the cps optimizer back on, do: Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"]; Code: Transcript: Comments: [Lal, 6/12/00] Stefan wrote: > 110.26 (as defined by the tag v110_26_0 at least) run with FLINTopt > turned off and replaced by the old cpsopt is just as fast as 110.25 > (unsurprisingly). This should not be surprising as the only change to 110.26 was the newFLINT (unless I am mistaken). > That means that the slowdown has been introduced between v110_26_0 > (the revision that I tagged last December with the intention of making > it 110.26) and now. Looking at the performance numbers in your next message, it should be the case that 110.28+cpsopt-newFLINT should be identical to 110.25+newMLRISC. What is the pequal change you are referring to? > I'd also love to hear just if someone else can or cannot reproduce this > problem. To turn off the flint optimizer (revert it back to what it was > in 110.25), do: > > Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"]; > > To turn the cps optimizer back on, do: > > Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"]; > I presume this is using 110.28 and the x86. [Stefan, 6/12/00] > ...What is the pequal change you are referring to? A patch committed as part of "let's get rid of CMStaticEnv". It doesn't seem to do much more than re-format parts of the code and do trivial adaptation between old datastructures and new ones. [Matthias, 6/13/00] Second, I don't think that changes to CM have anything to do with the quality of generated code. However, Stefan seems to have found something regarding polyequal where I may have accidentally broken previously working code during my "CMStaticEnv" trials and tribulations. If some knowledgeable person could have a closer look there, I'd appreciate it! [Stefan, 6/23/00] It's solved, actually. It turned out (embarassingly enough) to be a heap-size problem (Matthias' change to .run-sml was for the worst on processors with 512KB of cache (at least the Pentium-II machine I use for testing). I'd been careful to use the same runtime (which I thought was the place where default heap size was decided), but not the same .run-sml script. Fix: Test: Owner: - Status: not a bug ---------------------------------------------------------------------- Number: 1573 Title: ARRAY array tycon should be an eqtype Keywords: array Submitter: Stephen Weeks Date: 6/26/2000 Version: 110.0.6, 110.9.1, 110.28.1 System: x86-linux Severity: Problem: The basis library spec for ARRAY states that array is an eqtype. Thus the following code should type check. It does not in SML/NJ. Code: functor F(A: ARRAY) = struct val _ = A.fromList [] = A.fromList [] end Comments: [dbm, 6/27/00] Changing the array spec from "type 'a array" to "eqtype 'a array" will not be a complete fix, since the array constructor, like ref, should produce an eqtype regardless of the equality property of its argument. We don't have any way to declare this property of a type constructor. For instance functor F(A: ARRAY) = struct val _ = A.fromList ([]: (int->int) list) = A.fromList [] end would still fail to type check. This is a fundamental hole in the SML type specification mechanism (see "An Abstract Interpretation of ML Equality Kinds" in TACS '91 for further discussion of this point). Fix: src/compiler/PervEnv/Basis/array.sig should be changed [partial fix] Test: bug1573.1.sml Owner: jhr, dbm Status: open ---------------------------------------------------------------------- Number: 1574 Title: Segmentation fault in gc, alpha dunix only Keywords: GC, core dump, alpha Submitter: Allyn Dimock Date: 9/6/00 Version: Version 110.0.6, October 31, 1999 System: [newcoke.eecs.harvard.edu 36] uname OSF1 [newcoke.eecs.harvard.edu 37] uname -m alpha [newcoke.eecs.harvard.edu 38] uname -r V4.0 Severity: critical Problem: I reported a seg fault in garbage collection on the aplha. In the initial report I mentioned that the RTS had been modified with the addition of a routine "BlastSizeStat" similar to BlastWrite, and that the new routine was being called. I have re-run the test with (1) the call to the new routine replaced by "SMLofNJ.Internals.GC.doGC 100000;" (2) an unmodified copy of the RTS. The seg fault persists: sml @SMLload=CIL-NOSIZES @SMLrun=/a/bob/vol/vol1/home/mds/dimock/languages/ml/sm l-nj/bin/.run/run-unmodified.alpha32-dunix >&! ../test/bench/boyer2.sml.sd-us << EOF Controls.dotSFilename := SOME("../test/bench/boyer2.s.sd-us"); SimpleTop.compileFile Controls.simple Controls.Uniform "../test/bench/boyer2.sm l"; EOF Segmentation fault (core dumped) gdb /a/bob/vol/vol1/home/mds/dimock/languages/ml/sml-nj/bin/.run/run-unmodified.alpha32-dunix core GNU gdb 4.18 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "alphaev56-dec-osf4.0e"... (no debugging symbols found)... Core was generated by `run-unmodified.a'. Program terminated with signal 11, Segmentation fault. #0 0x2002c734 in NewDirtyVector () (gdb) backtrace #0 0x2002c734 in NewDirtyVector () #1 0x20031e20 in Flip () #2 0x2002d430 in MajorGC () #3 0x20027f08 in InvokeGC () #4 0x2001e578 in _ml_RunT_gc_ctl () #5 0x2001b4c4 in RunML () #6 0x2001b0d0 in LoadML () #7 0x20019ec0 in main () (gdb) At this point the program is vanilla SML/NJ. Here is the outline of the program that was exported to create the SML heap "CIL-NOSIZES.alpha-dunix": ... get name for heap from command line ... Compiler.Control.Print.printDepth := 1; CM.make' ("SimpleTop.cm") handle _ => OS.Process.exit (OS.Process.failure); ... set some refs in the newly built image ... ignore (SMLofNJ.Internals.CleanUp.addCleaner ("quiet", [SMLofNJ.Internals.CleanUp.AtInit], (fn (_) => SMLofNJ.Internals.GC.messages(false)))); if SMLofNJ.exportML (imageName) handle _ => OS.Process.exit(OS.Process.failure) then ("CIL interactive compiler running on " ^ MLsh.Command.collect (MLsh.Command.exec ("hostname", []))) else OS.Process.exit (OS.Process.success); Code: Way too much, but see below for additional code in RTS. Transcript: Comments: I have run the program interactively -- so no addCleaner, no exportML. I have left GC messages enabled. Same Seg Fault error in NewDirtyVector () One interesting thing to note is the last CG messages: GC #64.4526.5852.12306.99513.2929451: (5425 ms) GC #64.4526.5853.12307.99514.2929476: (5 ms) GC #64.4526.5853.12307.99515.2929507: (6 ms) GC #64.4527.5854.12308.99516.2929539: (15 ms) GC #64.4527.5854.12308.99517.2929571: (9 ms) GC #64.4527.5855.12309.99518.2929602: (20 ms) GC #64.4527.5855.12309.99519.2929635: (9 ms) GC #64.4527.5855.12309.99520.2929665: (9 ms) GC #64.4527.5855.12309.99521.2929674: (8 ms) GC #64.4528.5856.12310.99522.2929750: (33 ms) GC #64.4528.5856.12310.99523.2929792: (7 ms) GC #64.4528.5856.12310.99524.2929825: (5 ms) GC #64.4528.5856.12310.99525.2929853: (4 ms) GC #64.4528.5856.12310.99526.2929882: (4 ms) GC #64.4528.5856.12310.99527.2929910: (4 ms) GC #64.4528.5856.12310.99528.2929925: (3 ms) GC #64.4528.5856.12310.99529.2930051: (3 ms) GC #64.4528.5856.12310.99530.2930052: (4 ms) GC #64.4528.5856.12310.99531.2930058: (16 ms) GC #64.4529.5857.12311.99532.2930192: (46 ms) Segmentation fault (core dumped) The fact that the last working GCs were #64 makes me wonder about the length of a field for counting GCs in the oldest generation. [Dimock, 9/13/00] John H. Reppy writes: > I think that it makes more sense to see what is causing the core > dump, before doing this [trying 110.29]. My guess is that the call > to malloc to allocate a new dirty vector is failing (if so, there > is not much we can do about it, but we could fail more gracefully). Unfortunately it is malloc, needing to allocate a larger dirty vector at gc-util.c line 152. Has there been a space leak fix since 110.0.6 that I might put in? Somewhere around we have some software for detecting possible memory leaks. When I next get a few hours, I can try to find the software and see if it helps. Since it doesn't seem to be running up against my memory limit is there another constraint on memory that is causing malloc to run out? Is malloc allocating out of a fixed chunk of memory somewhere -- it seems unlikely -- In which case how could I expand that memory. here is some gdb output -- do the numbers seem unusual? (gdb under emacs: M-x gdb /a/bob/vol/vol1/home/mds/dimock/languages/ml/sml-nj/bin/.run/run-debugging.alpha32-dunix (gdb) core ~/codefest/top-level/core Core was generated by `run-debugging.al'. Program terminated with signal 11, Segmentation fault. #0 0x2002f4e8 in NewDirtyVector (gen=0x4002ae80) at gc-util.c:153 153 gc-util.c: No such file or directory. (gdb) backtrace #0 0x2002f4e8 in NewDirtyVector (gen=0x4002ae80) at gc-util.c:153 #1 0x200351d0 in Flip (heap=0x4002ce80, min_gc_level=5) at flip.c:160 #2 0x200301c4 in MajorGC (msp=0x40026a80, roots=0x1ffff488, level=5) at major-gc.c:196 #3 0x2002a4ac in InvokeGC (msp=0x40026a80, level=5) at call-gc.c:211 #4 0x2001edc8 in DoGC (msp=0x40026a80, arg=33751156) at gc-ctl.c:104 #5 0x2001ebe8 in _ml_RunT_gc_ctl (msp=0x40026a80, arg=33751176) at gc-ctl.c:45 #6 0x2001b824 in RunML (msp=0x40026a80) at ../kernel/run-ml.c:196 #7 0x2001b390 in LoadML (loadImage=0x1ffff9e4 "CIL-NOSIZES", heapParams=0x40026000) at ../kernel/load-ml.c:38 #8 0x20019c60 in main (argc=3, argv=0x1ffff7c8) at ../kernel/main.c:86 (gdb) dir ~/languages/ml/sml-nj/src/runtime/gc Source directories searched: /home/mds/dimock/languages/ml/sml-nj/src/runtime/gc:$cdir:$cwd (gdb) print gen.dirty $1 = (card_map_t *) 0x0 (gdb) print allocSzB $2 = 396308 (gdb) frame #0 0x2002f4e8 in NewDirtyVector (gen=0x4002ae80) at gc-util.c:153 (gdb) print *gen $3 = {heap = 0x4002ce80, genNum = 5, numGCs = 29, lastPrevGC = 547, ratio = 5, arena = {0x4002af00, 0x4002af80, 0x4002b000, 0x4002b080}, bigObjs = { 0x4006e2c0}, toObj = 0x4002cf40, fromObj = 0x40069980, cacheObj = 0x0, dirty = 0x0} (gdb) up #1 0x200351d0 in Flip (heap=0x4002ce80, min_gc_level=5) at flip.c:160 (gdb) print g $5 = (gen_t *) 0x4002ae80 (gdb) print *g $6 = {heap = 0x4002ce80, genNum = 5, numGCs = 29, lastPrevGC = 547, ratio = 5, arena = {0x4002af00, 0x4002af80, 0x4002b000, 0x4002b080}, bigObjs = { 0x4006e2c0}, toObj = 0x4002cf40, fromObj = 0x40069980, cacheObj = 0x0, dirty = 0x0} (gdb) print *ap $7 = {id = 21504, nextw = 0x5be80000, tospBase = 0x5be80000, tospSizeB = 101449728, tospTop = 0x61f40000, sweep_nextw = 0x5be80000, repairList = 0x0, frspBase = 0x18690000, frspSizeB = 23068672, frspTop = 0x199e7550, oldTop = 0x18690000, nextGen = 0x4002b080, needsRepair = 0, reqSizeB = 0, maxSizeB = 245760000} (gdb) print *heap $8 = {allocBase = 0x2030000, allocSzB = 524288, baseObj = 0x4002cdf0, numGens = 5, cacheGen = 2, numMinorGCs = 223429, gen = {0x4002f380, 0x4002f700, 0x4002a980, 0x4002ac00, 0x4002ae80, 0x4002b100, 0x4002b380, 0x4002b600, 0x40032080, 0x40032300, 0x40032580, 0x40032800, 0x40032a80, 0x40032d00}, numBORegions = 4, bigRegions = 0x2e90000, freeBigObjs = 0x40032f80, weakList = 0x0} (gdb) print min_gc_level $9 = 5 (gdb) up #2 0x200301c4 in MajorGC (msp=0x40026a80, roots=0x1ffff488, level=5) at major-gc.c:196 (gdb) print level $10 = 5 (gdb) print *msp $11 = {ml_heap = 0x4002ce80, ml_vproc = 0x4002f400, ml_allocPtr = 0x20300a0, ml_limitPtr = 0x20af000, ml_roots = {78613176, 41625368, 1, 536992876, 41625368, 78578392, 276758572, 78613184, 55314616, 536993040, 176478928, 354, 55183720, 34271104, 152146372, 54790836, 54791460, 624, 104, 1, 78577672, 1}, ml_pseudoRegs = {1, 1}, ml_storePtr = 1, ml_liveRegMask = 124, ml_faultExn = 1073911152, ml_faultPC = 0} (gdb) print *roots $12 = (unsigned int *) 0x40017a80 (gdb) print **roots $13 = 276758532 (gdb) [Dimock, 9/15/00] John H. Reppy writes: > > I think that it makes more sense to see what is causing the core > dump, before doing this. My guess is that the call to malloc to > allocate a new dirty vector is failing (if so, there is not much > we can do about it, but we could fail more gracefully). > The function memory/malloc.c is not being used. What ever your > OS provides as malloc is what gets used. It looks like bug 1574 remains open after all: (1) Ths swapon info on swap size was correct. (2) A C program can use all that swap space (400GB !) when built with the same switches as run.alpha32-dunix Example: [newcoke.eecs.harvard.edu 18] cc -std -non_shared -T 20000000 -D 40000000 -o flood flood.c [newcoke.eecs.harvard.edu 19] ./flood 6000 1000000 malloc failed after 4109 chunks (4109000000 bytes). [newcoke.eecs.harvard.edu 20] ./flood 4000 1000000 No problem with 4000 chunks (4000000000 bytes). [newcoke.eecs.harvard.edu 21] flood.c is as follows: #include int main(int argc, char **argv) { int chunkcount, chunksize; int i; if (argc != 3) { fprintf(stderr, "Usage: %s: chunkcount chunksize\n", argv[0]); exit(1); } chunkcount = atoi(argv[1]); chunksize = atoi(argv[2]); for (i = 0; i < chunkcount; ++i) { if (0 == malloc(chunksize)) { fprintf(stderr, "\nmalloc failed after %d chunks (%ld bytes).\n", i, (long) i * chunksize); exit(1); } } fprintf(stderr, "\nNo problem with %d chunks (%ld bytes).\n", chunkcount, (long) chunkcount * chunksize); return 0; } Fix: Test: Owner: Status: ---------------------------------------------------------------------- Number: 1575 Title: Bad response to EOF on standard input on Windows 98 Keywords: IO, EOF, Windows Submitter: Allen Stoughton, allen@cis.ksu.edu Date: 09/02/00 Version: 110.0.6 System: x86-win32 (Windows 98) Severity: minor (?) Problem: On Windows 98, if a top-level expression reads from the standard input, and the user types in some characters, followed by CTRL-z, then the expression returns the correct value, but this value and its type are not correctly printed on the standard output. The message that is printed is a suffix of what should be printed. This behavior occurs when running SML/NJ 110.0.6 in the MS-DOS window (i.e., SML/NJ was NOT being run in an Emacs buffer). Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM&CMB] - TextIO.inputAll TextIO.stdIn; once upon a time there was a big house on a hill... on a hill...\n" : TextIO.vector (only part of the normal SML/NJ response was printed) - it; val it = "once upon a time there was a big house on a hill...\n" : TextIO.vector (but it was set to the correct value) - TextIO.inputAll TextIO.stdIn; and on another occasion... vector (only part of the normal SML/NJ response was printed) - Comments: The problem isn't specific to TextIO.inputAll. I wrote a similar function using input, and got the same behavior. [Riccardo, 9/13/00] The Ctrl-Z issue under Win98 exists, and I think it's because fundamentally every Windows version handles EOF slightly differently (WinNT, Win95, Win98, probably Win2K as well). When Lorenz wrote the code originally, it was under NT, plus some correction for Win95, and I presume that the Win98 OS is different enough to require its own slight correction. One short term way of handling the problem is to not use TextIO.inputAll and instead do a series of TextIO.inputLine. [dbm, 9/13/00] The problem doesn't seem to occur on Win NT. [Stoughton, 9/15/00] Simply reading single lines using TextIO.inputLine works fine. But, if I write a function that reads lines until EOF using TextIO.inputLine, then this function suffers from similar problems to TextIO.inputAll. Obviously, it seems to have something to do with reading until EOF.. Fix: Test: * Owner: Riccardo? Status: open ---------------------------------------------------------------------- Number: 1576 Title: buggy Real.!= Keywords: reals Submitter: Matthew Fluet, fluet@cs.cornell.edu Date: 9/11/2000 Version: 110.0.6 (also 110.9.1 and 110.29) System: x86-unix Severity: minor Problem: Real.!= is inconsistent with the basis specification Code: val x = 1.0/0.0 + ~1.0/0.0; val _ = print (concat["x = ", Real.toString x, "\n", "Real.==(x,x) = ", Bool.toString (Real.==(x,x)), "\n", "Real.!=(x,x) = ", Bool.toString (Real.!=(x,x)), "\n", "Real.?=(x,x) = ", Bool.toString (Real.?=(x,x)), "\n", "Real.==(x,1.0) = ", Bool.toString (Real.==(x,1.0)), "\n", "Real.!=(x,1.0) = ", Bool.toString (Real.!=(x,1.0)), "\n", "Real.?=(x,1.0) = ", Bool.toString (Real.?=(x,1.0)), "\n", "Real.==(1.0,1.0) = ", Bool.toString (Real.==(1.0,1.0)), "\n", "Real.!=(1.0,1.0) = ", Bool.toString (Real.!=(1.0,1.0)), "\n", "Real.?=(1.0,1.0) = ", Bool.toString (Real.?=(1.0,1.0)), "\n"]); Transcript: x = nan Real.==(x,x) = false Real.!=(x,x) = false Real.?=(x,x) = true Real.==(x,1.0) = false Real.!=(x,1.0) = false Real.?=(x,1.0) = true Real.==(1.0,1.0) = true Real.!=(1.0,1.0) = false Real.?=(1.0,1.0) = true Comments: According to the basis library spec: == (x, y) != (x, y) The first returns true if and only if neither y nor x is NaN, and y and x are equal, ignoring signs on zeros. This is equivalent to the IEEE = operator. The second function != is equivalent to not o op == and the IEEE ?<> operator. So, I'd expect Real.!=(x,x) = true Real.!=(x,1.0) = true Fix: [Allen] It seems that in [sml-nj|FLINT]/cps/convert.sml, the line | c AP.NEQ = P.fLG should read: | c AP.NEQ = P.fULG Test: bug1576.1.sml Owner: jhr Status: fixed in 110.0.7, 110.29+ [Leung, jhr] ---------------------------------------------------------------------- Number: 1577 Title: Stack Fault during install on Windows 2000 Keywords: Stack Fault ISSET_SE Submitter: Vince Kovarik vkovarik@acm.org Date: 07/24/00 Version: 110.0.6 System: x86 Windows NT 5.00.2195 Subsystem: Installation Severity: major Problem: Using Windows 2000.. Installation starts - then halts with an application error dialog box. The message is: ISSET_SE caused a Stack Fault in module 14C7:0128****ISSET_SE will close where **** are some graphical symbols I couldn't reproduce in this form. After pressing the close button a second dialog comes up with a "Setup Initialization Erropr" and the message: "Setup has detected that unInstallShield is in use. Please close unInstallShield and restart setup. Error 432." unInstallShield had not been started and the same error occurs if the machine is booted and a fresh install is attempted. Comments: [dbm, 9/13/00] We now have a local Windows 2000 installation, and I have confirmed the bug. It looks like we'll have to get an upgrade to InstallShield to correct this, but a new Windows 2000 compatible smlnj.exe should be available with a 110.0.7 patch release soon. Fix: rebuild smlnj.exe with newer version of InstallShield? Test: Owner: dbm, riccardo Status: fixed in 110.0.7 ---------------------------------------------------------------------- Number: 1578 Title: invalid datatype replication causes compiler bug Keywords: Submitter: Stephen Weeks Date: 8/18/00 Version: 110.9.1 System: x86-linux Severity: Problem: The following code causes the compiler bug "Error: Compiler bug: TypesUtil: extractDcons" instead of an error message. Code: type u = int fun f() = let datatype t = datatype u in () end Transcript: Comments: Fix: Test: bug1578.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1579 Title: Duplicate printing of syntax error messages Keywords: error messages Submitter: John Reppy jhr@research.bell-labs.com Date: 08/30/00 Version: 110.29 System: Any/All Any Unix Subsystem: Compilation manager (CM) Severity: cosmetic Problem: Duplicate printing of syntax error messages when using CM to compile a program. Transcript: [parsing (sources.cm):scene.sml] scene.sml:143.20 Error: syntax error: inserting LPAREN sources.cm:37.3-37.12 Error: syntax error scene.sml:143.20 Error: syntax error: inserting LPAREN val it = false : bool Comments: Fix: Test: Owner: Matthias Status: fixed in 110.29+ [Matthias] ---------------------------------------------------------------------- Number: 1580 Title: uncaught exception ltUnbound Keywords: vectors + recursion? Submitter: Andreas Rossberg rossberg@ps.uni-sb.de Date: 09/08/00 Version: 110.0.6 System: x86 Linux Subsystem: SML compiler Severity: major Problem: Internal lookup error during compilation. Code: (* bug1580.1.sml *) datatype a = A1 | A2 of a datatype b = B1 | B2 of b vector fun f A1 = B1 | f(A2 a) = B2(#[f a]) ------------------------------------- (* bug1580.2.sml *) fun vector2List v = Vector.foldr (fn (e,l) => (e::l)) [] v; fun concatVectors v = Vector.concat (vector2List v); fun f d = concatVectors #[concatVectors (Vector.map f #[])]; Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - use "nj-bug.sml"; [opening nj-bug.sml] **** hmmm, I didn't find the variable 1 uncaught exception ltUnbound raised at: basics/ltyenv.sml:251.32-251.41 Comments: If the expression #[f a] is replaced by vector[f a] everything works fine. Note that bug 1396 also involves the same "hmmm..." message, but in the context of a bad use of the # record selector notation. This is also marked as open. See also bug 1549. Fix: Test: bug1580.1.sml, bug1580.2.sml Owner: dbm, Zhong Status: open ---------------------------------------------------------------------- Number: 1581 Title: Problem with constant strings in ML-Lex Keywords: ML-Lex Submitter: Neophytos Michael (nmichael@cs.princeton.edu) Date: 7/19/2000 Version: Standard ML of New Jersey, Version 110.0.3, January 30, 1998 System: sparc-solaris2.7 Severity: minor Problem: It appears that any constant string that contains an oper parenthesis causes ML-Lex to raise an exception and error out. I have a relatively small lexer file that contains the following production: -------------------------------------------------------------------- "(" => (print "Found (\n";Tokens.LPAREN(yypos, yypos + 1)); --------------------------------------------------------------------- Note that the constant string given as an argument to print function, contains an open parenthesis. This causes ML-Lex to report: Transcript: - CM.make(); [starting dependency analysis] [/cmnusr/local/sml/sml-110.0.3/bin/ml-lex mcSyntax.lex] ml-lex: syntax error, line 73: /cmnusr/local/sml/sml-110.0.3/bin/ml-lex: uncaught exception Error !* CM error: ML-Lex failed: /cmnusr/local/sml/sml-110.0.3/bin/ml-lex mcSyntax.lex - If I remove the parenthesis '(' from the string, the error goes away. Code: See above Transcript: See above Comments: The above is trivial to reproduce but if you need a self contained example let me know and I can provide it. Fix: Test: - Owner: ? Status: open ---------------------------------------------------------------------- Number: 1582 Title: SysErr exception connecting to socket Keywords: sockets Submitter: A. Mattox Beckman, Jr. Date: 10/31/00 Version: 110.29 System: - Severity: major Problem: I have a process which listens to port 9999 which I'd like to have communicate with my SML program. Here's what I tried to do: ---------------------------------------- use "sock-util-sig.sml"; use "sock-util.sml"; val thePort = SockUtil.PortNumber 9999; val SOME hostIP = NetHostDB.fromString "128.174.246.77"; val SOME localhostIP = NetHostDB.fromString "127.0.0.1"; (* val s1 = SockUtil.connectINetStrm {addr=hostIP, port=9999}; *) vla s2 = SockUtil.connectINetStrm {addr=localhostIP, port=9999}; ---------------------------------------- For both s1 and s2 I get uncaught exception SysErr: Invalid argument [inval] Code: use "sock-util-sig.sml"; use "sock-util.sml"; val thePort = SockUtil.PortNumber 9999; val SOME hostIP = NetHostDB.fromString "128.174.246.77"; val SOME localhostIP = NetHostDB.fromString "127.0.0.1"; (* val s1 = SockUtil.connectINetStrm {addr=hostIP, port=9999}; *) vla s2 = SockUtil.connectINetStrm {addr=localhostIP, port=9999}; Transcript: Comments: [jhr] This appears to be a bug in 110.29, since the same example works in 110.0.6 and 110.0.7. I have an idea of what might be broken, so we can probably fix this problem for 110.30. [dbm] See also bugs 1480 and 1514, which involve similar sockets problems. 1480 is listed as fixed in 110.19, while 1514 is open. Fix: Test: - Owner: jhr Status: fixed in 110.31 ---------------------------------------------------------------------- Number: 1583 Title: datatype foo = datatype bar raises Unbound exception Keywords: datatype replication Submitter: Allen Leung leunga@cs.nyu.edu Date: 11/22/00 Version: 110.30 System: Any/All Any Unix Subsystem: SML compiler Severity: minor Problem: Datatype definitions of the following form: type bar = ... datatype foo = A | B | C of bar raises exception Unbound when later used in: datatype baz = datatype foo Also, the Unbound exception is caught by CM and CM aborts without printing an error message. The bug in is also in 110.25 but not in 110.0.6 Code: (* This code causes the bug *) signature FOO = sig type bar = string datatype foo = A | B | C of bar end structure Foo = struct type bar = string datatype foo = A | B | C of bar end signature BAR = sig structure Foo : FOO datatype foo = datatype Foo.foo end functor Bar() : BAR = struct structure Foo = Foo datatype foo = datatype Foo.foo end (* But this doesn't *) signature FOO = sig type bar = string datatype foo = A | B | C of string end structure Foo = struct type bar = string datatype foo = A | B | C of string end signature BAR = sig structure Foo : FOO datatype foo = datatype Foo.foo end functor Bar() : BAR = struct structure Foo = Foo datatype foo = datatype Foo.foo end Transcript: - use "BUG2.sml"; [opening BUG2.sml] uncaught exception Unbound raised at: ../compiler/Semant/elaborate/elabmod.sml:1328.39-1328.49 ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/TopLevel/interact/evalloop.sml:61.55 ../compiler/TopLevel/interact/evalloop.sml:243.25-243.28 ../compiler/TopLevel/interact/evalloop.sml:61.55 ../compiler/TopLevel/main/compile.sml:300.13-300.58 ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/TopLevel/interact/evalloop.sml:61.55 - use "BUG4.sml"; GC #0.0.1.2.8.202: (0 ms) [opening BUG4.sml] signature FOO = sig type bar = string datatype foo = A | B | C of string end structure Foo : sig type bar = string datatype foo = A | B | C of string end signature BAR = sig structure Foo : sig type bar = string datatype foo = A | B | C of string end type foo = Foo.foo end functor Bar : val it = () : unit - Comments: Fix: Test: tests/bug1583.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1584 Title: Premature Overloading Resolution Keywords: types, overloading Submitter: Andreas Rossberg rossberg@ps.uni-sb.de Date: 11/23/00 Version: 110.0.6 System: Any/All Any Unix Subsystem: SML compiler Severity: minor Problem: Some overloaded types are resolved to early, making overloading resolution overly restrictive. Code: fun derive(f,dx) = fn x => (f(x + dx) - f(x)) / dx (* This should type check. *) Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - fun derive(f,dx) = fn x => (f(x + dx) - f(x)) / dx; stdIn:17.47 Error: overloaded variable not defined at type symbol: / type: int - Comments: [jhr, 11/27/00] I think that this example is a bit more subtle than you realize. In the full SML definition, "/" is also overloaded (since there can be multiple real types), thus there is a conflict between the default overloading of "+" and "-" (which is int) and the default overloading of "/" (real). [Andreas Rossberg, 11/27/00] If I understand correctly you refer to the fact that the intersection between the overloading classes Num (for + and -) and Real (for /) is neither empty nor singular, but their default elements are different. I see your point. It's a pity that the Definition does not formalize overloading to explain what should happen under these circumstances. There seem to be several possible solutions: (1) always flag an error (is this what NJ does?), (2) if only one of both defaults is in the intersection, take this as the intersection's default type, (3) allow for intermediate overloading classes without defaults (i.e. flag an error only if we actually have to do defaulting). Both (2) and (3) would fix the example. They could work in combination as well. The more general problem however seems to be that the validity of SML programs depends on the overloading the given implementation provides. This is rather ugly and not in the spirit of SML. One possible fix for this might be that overloading is not considered to be resolved simply because an intermediate overloading class becomes singular. Then the example would behave the same on all implementations, regardless of their number of real types. Are there more detailed overloading rules in the Std Basis spec, possibly addressing these problems? (The online version refers to some Appendix C, but that does not seem to be accessible online.) I really would be interested in this, because I'm currently finalizing an SML frontend. [jhr, 11/27/00] I don't think that there is a formal specification of overloading and that fact is a significant weakness of the SML definition. I believe that the way overloading is resolved in SML/NJ is as follows: 1) Any overloaded operator or literal that can be resolved uniquely is done so. 2) Any outstanding overloaded literals are resolved to their default types. 3) repeat step 1 4) assign an outstanding overloaded operators their default type. The code you sent fails on step 4, since mapping + to Int.+ and / to Real./ results in an incompatibility. Fix: Test: tests/bug1584.1.sml Owner: dbm Status: not a bug ---------------------------------------------------------------------- Number: 1585 Title: getpeername in sockets Keywords: sockets, getpeername Submitter: John Reppy Date: 11/21/00 Version: 110.0.7 and (probably) 110.30 System: - Severity: medium Problem: getpeername doesn't work (symptoms?) Comments: Fix: *** ORIGgetpeername.c Fri Dec 3 14:59:28 1999 --- getpeername.c Tue Nov 21 16:08:24 2000 *************** *** 15,40 **** #include "cfun-proto-list.h" #include "sock-util.h" ! /* _ml_Sock_getpeername : sock -> (af * addr) */ ml_val_t _ml_Sock_getpeername (ml_state_t *msp, ml_val_t arg) { ! char data[MAX_SOCK_ADDR_SZB]; ! struct sockaddr *addr; ! int addrLen; ! addr = (struct sockaddr *)data; ! addrLen = MAX_SOCK_ADDR_SZB; ! if (getpeername (INT_MLtoC(arg), addr, &addrLen) < 0) return RAISE_SYSERR(msp, sts); ! else { ! ml_val_t af = ML_SysConst (msp, &_Sock_AddrFamily, ! ntohs(addr->sa_family)); ! ml_val_t cdata = ML_CData(msp, addr, addrLen); ! ml_val_t res; ! ! REC_ALLOC2 (msp, res, af, cdata); ! return res; ! } } /* end of _ml_Sock_getpeername */ --- 15,30 ---- #include "cfun-proto-list.h" #include "sock-util.h" ! /* _ml_Sock_getpeername : sock -> addr */ ml_val_t _ml_Sock_getpeername (ml_state_t *msp, ml_val_t arg) { ! char addr[MAX_SOCK_ADDR_SZB]; ! int addrLen = MAX_SOCK_ADDR_SZB; ! if (getpeername (INT_MLtoC(arg), (struct sockaddr *)addr, &addrLen) < 0) return RAISE_SYSERR(msp, sts); ! else ! return ML_CData(msp, addr, addrLen); } /* end of _ml_Sock_getpeername */ Test: Owner: jhr Status: fixed in 110.0.8 and 110.31 ---------------------------------------------------------------------- Number: 1586 Title: Windoze 9X installation exe has undefined parameters Keywords: Windows installation bug Submitter: Warren Ferguson warren_e_ferguson@hotmail.com Date: 11/05/00 Version: 110.0.7 System: x86 Windows 95 Win98 Subsystem: Installation Severity: minor Problem: Installation announces several parameter names are undefined, starting with PRODUCT_NAME! Transcript: Error dialog boxes containing messages of the form: String PRODUCT_NAME was not found in string table Comments: [dbm, 2/21/01] Complete list of undefined strings is PRODUCT_NAME, TITLE_CAPTIONBAR, FOLDER_NAME, COMPANY_NAME, PRODUCT_VERSION, PRODUCT_KEY, UNINST_KEY. Installation sometimes succeeds after dispatching these warning messages, but apparently sometimes fails. "... so far everything seems to work. The shortcut in the start-program menu isn't set right, but a quick edit sets it to right. The path and set of cm_path are there too, although that might be a carry-over from my previous installation of smlnj." [Rob Hasker, hasker@uwplatt.edu, 1/18/2001, Win98] During install, I get a number of errors of the sort "No setting for PRODUCT_NAME". SML seems to install ok, but the start menu is messed up, there is no uninstall, etc. Fix: Revised contents of is-gen generated InstallShield project files. Test: - Owner: dbm Status: fixed (new 110.0.7 smlnj.exe) ---------------------------------------------------------------------- Number: 1587 Title: Problem with Real.rem Keywords: reals, rem, mod Submitter: Steve Sims sims@reactive-systems.com Date: 11/27/00 Version: 110.0.7 System: x86 Linux Red Hat 7.0 Subsystem: SML basis library Severity: minor Problem: Real.rem does not conform to Basis Definition Code: Transcript: $ sml Standard ML of New Jersey, Version 110.0.7, September 28, 2000 ... - 1.0 - Real.rem(10.0,3.0); val it = ~4.4408920985E~16 : real (* Expected: val it = 0.0 *) Comments: [jhr, 11/27/00] The problem is that Real.rem(10.0, 3.0) is not 1.0. - 1.0 - Real.rem(10.0,3.0); val it = ~4.4408920985E~16 : real so Real.== is returning the correct answer. [Steve Sims, 11/27/00] I am a novice at the subtleties of floating point arithmetic and rounding error, so please forgive me if I'm missing something basic. The documentation for the Basis Library defines rem as follows: rem (x, y) returns the remainder x - n*y, where n = trunc ( x / y). The result has the same sign as x and has absolute value less than the absolute value of y. If x is an infinity or y is 0, rem returns NaN. If y is an infinity, rem returns x. Which to me looks like: fun myRem(r1,r2) = let val n = Real.fromInt(Real.trunc(r1 / r2)) in r1 - (n * r2) end When I use this function I get - 1.0 - myRem(10.0,3.0); val it = 0.0 : real [jhr, 11/27/00] I think that you are correct, so this example should be viewed as a bug in Real.mod. [Steve Sims, 11/27/00] - Real.rem(10.0,3.0); val it = 1.0 : real - Real.==(it,1.0); val it = false : bool Fix: Test: bug1587.1.sml Owner: jhr? Status: open ---------------------------------------------------------------------- Number: 1588 Title: BinIO.inputAll raises Subscript (Windows) Keywords: BinIO inputAll Subscript Submitter: Tom 7 twm@andrew.cmu.edu Date: 11/30/00 Version: Version 110.0.7, September 28, 2000 [CM&CMB] System: x86 Windows NT 2000 Subsystem: SML basis library Severity: minor Problem: BinIO.inputAll raises Subscript in almost all circumstances. (See code and transcript.) I was able to make it succeed when reading "con" (a special file on Win2000), but never for any regular files. Code: (* does not work *) fun readfile f = let val inf = BinIO.openIn f val dat = BinIO.inputAll inf in BinIO.closeIn inf; dat end; (* works *) fun readfile' f = let val inf = BinIO.openIn f fun rd vs = let val v = BinIO.input inf in case Word8Vector.length v of 0 => Word8Vector.concat (rev vs) | _ => rd (v :: vs) end val dat = rd nil in BinIO.closeIn inf; dat end; Transcript: - readfile "sources.cm"; uncaught exception Io: inputAll failed on "sources.cm" with exception subscript out of bounds raised at: boot/IO/bin-io-fn.sml:96.14-96.56 - readfile' "sources.cm"; val it = - : Word8Vector.vector Comments: [jhr, 11/30/00] This bug appears to be windows specific, since the same code works on a Unix machine. I wonder if the problem might be related to using binary I/O on a text file? Have you tried the TextIO equivalant or tried reading a non-text file using this code? [Tom 7, 11/30/00] TextIO.inputAll works as I'd expect. BinIO.inputAll raises the exception on binary files (ie, executables), even a zero-byte file. Fix: Test: - Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1589 Title: incorrect implementation for Posix.TTY Keywords: Posix.TTY Submitter: Anthony Shipman felixadv@access.net.au Date: 11/30/00 Version: N/a System: Any/All Any Unix Subsystem: Other Severity: Problem: The basis library documentation for Posix.TTY describes a CF structure that no longer exists. The TC structure no longer contains getattr..flow Comments: [jhr, 11/30/00] This is a bug in the SML/NJ implementation (which is incomplete). The Basis document is the "correct" specification. Fix: Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1590 Title: compilation manager reads tool files from wrong directory Keywords: compilation manager Submitter: Matthai Philipose matthai@cs.washington.edu Date: 12/01/00 Version: 110.0.6 System: x86 Windows NT 4.0 Subsystem: Installation Severity: minor Problem: I'm using the compilation manager that comes with (the x86 binary distribution of) sml/nj 110.0.6. One of the lines in my .cm file is: parsers/c/c.mlyacc:MLYacc On doing a CM.make(), I get the output: --------------begin output [starting dependency analysis] [scanning sources.cm] [checking CM\x86-win32\sources.cm.stable ... not usable] [c:/sml-build/110.0.6/bin/ml-yacc parsers\c\c.mlyacc] The system cannot find the path specified. !* CM error: ML-Yacc failed: c:/sml-build/110.0.6/bin/ml-yacc parsers\c\c.mlyacc ---------------end output The problem is that I have (and never had, AFAIK) no c:/sml-build/110.0.6/bin directory on my machine. In fact, the right executable for the MLyYacc tool is c:/sml/bin/ml-yacc.bat From the documentation, there does not seem any way of resetting this tool path, so I'm currently prevented from having CM rules that rely on various tools. Code: see above Transcript: see above Comments: [dbm,2/21/01] Bad version of smlnj.exe. Fix: Test: Owner: dbm Status: fixed ---------------------------------------------------------------------- Number: 1591 Title: Duplicate entries after insert() using IntRedBlackMap, WordRedBlackMap Keywords: IntRedBlackMap WordRedBlackMap insert duplicate Submitter: Gary Fuehrer, fuehrer@newmexico.com Date: 12/1/2000 Version: 110.0.7 System: x86-win32 Severity: minor to most, but major to me ;-) Problem: IntRedBlackMap.insert can result in duplicates. Same with WordRedBlackMap.insert. Code: sources.cm: Group is smlnj-lib.cm bug.sml bug.sml: structure Bug = struct structure RedBlackMapFn_Int = RedBlackMapFn(struct type ord_key = int val compare = Int.compare end) structure RedBlackMapFn_Word = RedBlackMapFn(struct type ord_key = word val compare = Word.compare end) fun demonstrate() = let val int_map = IntRedBlackMap.empty val int_map = IntRedBlackMap.insert(int_map, 1, "I'm the only one") val int_map = IntRedBlackMap.insert(int_map, 0, "I'm the only zero") val int_map = IntRedBlackMap.insert(int_map, 0, "I'm the only zero") val int_map' = RedBlackMapFn_Int.empty val int_map' = RedBlackMapFn_Int.insert(int_map', 1, "I'm the only one") val int_map' = RedBlackMapFn_Int.insert(int_map', 0, "I'm the only zero") val int_map' = RedBlackMapFn_Int.insert(int_map', 0, "I'm the only zero") val word_map = WordRedBlackMap.empty val word_map = WordRedBlackMap.insert(word_map, 0w1, "I'm the only one") val word_map = WordRedBlackMap.insert(word_map, 0w0, "I'm the only zero") val word_map = WordRedBlackMap.insert(word_map, 0w0, "I'm the only zero") val word_map' = RedBlackMapFn_Word.empty val word_map' = RedBlackMapFn_Word.insert(word_map', 0w1, "I'm the only one") val word_map' = RedBlackMapFn_Word.insert(word_map', 0w0, "I'm the only zero") val word_map' = RedBlackMapFn_Word.insert(word_map', 0w0, "I'm the only zero") in print("\nIntRedBlackMap\n"); IntRedBlackMap.foldli (fn (k, v, _) => print(Int.toString(k)^ " - " ^ v ^ "\n")) () int_map; print("\nRedBlackMapFn_Int\n"); RedBlackMapFn_Int.foldli (fn (k, v, _) => print(Int.toString(k) ^ " - " ^ v ^ "\n")) () int_map'; print("\nWordRedBlackMap\n"); WordRedBlackMap.foldli (fn (k, v, _) => print(Word.toString(k) ^ " - " ^ v ^ "\n")) () word_map; print("\nRedBlackMapFn_Word\n"); RedBlackMapFn_Word.foldli (fn (k, v, _) => print(Word.toString(k) ^ " - " ^ v ^ "\n")) () word_map' end end Transcript: Standard ML of New Jersey, Version 110.0.7, September 28, 2000 [CM&CMB] - CM.make(); [starting dependency analysis] [scanning sources.cm] [checking CM\x86-win32\sources.cm.stable ... not usable] [scanning E:\CygWin\usr\sml_nj\110.0.7-win32\lib\smlnj-lib.cm -> E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnjlib\Util\smlnj-lib.cm] [checking E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\smlnj-lib.cm.stable ... ok - stable] [dependency analysis completed] [recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\ord-key-sig.sml.bin... done] [recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\lib-base-sig.sml.bin... done] [recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\lib-base.sml.bin... done] [recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\ord-map-sig.sml.bin... done] [recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\redblack-map-fn.sml.bin... done] [recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\int-redblack-map.sml.bin... done] [recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\word-redblack-map.sml.bin... done] [recovering CM\x86-win32\bug.sml.bin... done] [introducing new bindings into toplevel environment...] val it = () : unit - Bug.demonstrate(); IntRedBlackMap 0 - I'm the only zero 0 - I'm the only zero 1 - I'm the only one RedBlackMapFn_Int 0 - I'm the only zero 1 - I'm the only one WordRedBlackMap 0 - I'm the only zero 0 - I'm the only zero 1 - I'm the only one RedBlackMapFn_Word 0 - I'm the only zero 1 - I'm the only one val it = () : unit Comments: Can be worked around using RedBlackMapFn (see above code for an example). There may be similar mistakes in other functions of IntRedBlackMap and WordRedBlackMap; I haven't examined them yet. Fix: Corrected the insert function so it matches the one in redblack-map-fn.sml. int-redblack-map.sml and word-redblack-map.sml: fun insert (MAP(nItems, m), xk, x) = let val nItems' = ref nItems fun ins E = (nItems' := nItems+1; T(R, E, xk, x, E)) | ins (s as T(color, a, yk, y, b)) = if (xk < yk) then (case a of T(R, c, zk, z, d) => if (xk < zk) then (case ins c of T(R, e, wk, w, f) => T(R, T(B,e,wk,w,f), zk, z, T(B,d,yk,y,b)) | c => T(B, T(R,c,zk,z,d), yk, y, b) (* end case *)) BUG 1: else if (xk = yk) FIX 1: else if (xk = zk) BUG 2: then T(color, T(R, c, zk, x, d), yk, y, b) FIX 2: then T(color, T(R, c, xk, x, d), yk, y, b) else (case ins d of T(R, e, wk, w, f) => T(R, T(B,c,zk,z,e), wk, w, T(B,f,yk,y,b)) | d => T(B, T(R,c,zk,z,d), yk, y, b) (* end case *)) | _ => T(B, ins a, yk, y, b) (* end case *)) else if (xk = yk) BUG 3: then T(color, a, yk, x, b) FIX 3: then T(color, a, xk, x, b) else (case b of T(R, c, zk, z, d) => if (xk < zk) then (case ins c of T(R, e, wk, w, f) => T(R, T(B,a,yk,y,e), wk, w, T(B,f,zk,z,d)) | c => T(B, a, yk, y, T(R,c,zk,z,d)) (* end case *)) else if (xk = zk) BUG 4: then T(color, a, yk, y, T(R, c, zk, x, d)) FIX 4: then T(color, a, yk, y, T(R, c, xk, x, d)) else (case ins d of T(R, e, wk, w, f) => T(R, T(B,a,yk,y,c), zk, z, T(B,e,wk,w,f)) | d => T(B, a, yk, y, T(R,c,zk,z,d)) (* end case *)) | _ => T(B, a, yk, y, ins b) (* end case *)) val m = ins m in MAP(!nItems', m) end Test: - Owner: jhr Status: fixed (in 110.0.8, 110.33) ---------------------------------------------------------------------- Number: 1592 Title: Math.pow is not accurate Keywords: "Math.pow" "function" "parameter" Submitter: Jost Waldmann jwaldmann@medinews.de Date: 12/04/00 Version: 110.0.7 System: x86 Windows 95 Subsystem: SML compiler Severity: major Problem: If you use the Math.pow function as a parameter in another function the result you get is not right. Code: trunc( Math.pow(2.0,4.0) ); Real.==(16.0,Math.pow(2.0,4.0)); Transcript: trunc( Math.pow(2.0,4.0) ); val it = 15 :int Real.==(16.0,Math.pow(2.0,4.0)); val it = false :bool Comments: [jhr, 12/4/00] Thanks for the bug report. The current implementation of many of the Math functions leaves a lot to be desired. We are planning to move to using the native C library for these, which should improve their accuracy. Fix: Test: Owner: ? Status: open ---------------------------------------------------------------------- Number: 1593 Title: Pattern matching on word constants causes overflow in the compiler Keywords: Submitter: Allen Leung Date: 12/14/00 Version: 110.31 System: Any/All Any Unix Subsystem: SML compiler Severity: minor Problem: Pattern matching on large word constants causes overflow in the compiler. But no problem with int constants. It's not restricted to 110.31. I can't find one version of SML/NJ that can handle this code. Code: fun f 0w1073741823 = false | f _ = true (* 0w1073741823 is 2^30-1 *) Transcript: leunga@react-ilp.cs.nyu.edu:~/SML/src/MLRISC++{5938}> sml Standard ML of New Jersey v110.30 [FLINT v1.5], November 3, 2000 - 0w1073741823; val it = 0wx3fffffff : word - fun f 0w1073741823 = false | f _ = true; uncaught exception overflow raised at: ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/MiscUtil/util/stats.sml:190.40 ../compiler/TopLevel/interact/evalloop.sml:60.55 - leunga@react-ilp.cs.nyu.edu:~/SML/src/MLRISC++{5939}> ~/SML-110.0.6/sml/bin /home/leunga/SML-110.0.6/sml/bin: Command not found. leunga@react-ilp.cs.nyu.edu:~/SML/src/MLRISC++{5940}> ~/SML-110.0.6/bin/sml use "Standard ML of New Jersey, Version 110.0.6, October 31, 1999 ... - fun f 0w1073741823 = false | f _ = true; Error: Compiler bug: CPSGen: Overflow in cps/generic.sml - Comments: Fix: Test: bug1593.1.sml Owner: jhr? Status: open ---------------------------------------------------------------------- Number: 1594 Title: linker errors on FreeBSD 4.x Keywords: runtime Submitter: Brad Knotwell knotwell@ix.netcom.com Date: 01/04/01 Version: 110.32 System: x86 FreeBSD 4.2 Subsystem: Installation Severity: major Problem: Building the runtime on FreeBSD returns a good number of linker errors. The FreeBSD compiler no longer requires globals assembly definitions to start with an underscore. Removing the defined(OPSYS_FREEBSD) statement from the asm-base.h resolves the problem. Comments: [Brad Knotwell, 1/5/01] For fun, I tried compiling up 110.32 on a x86 NetBSD system. It had the identical problem and I resolved it in an identical manner. [Lal George, 1/5/01] Does the build complete once you fix the assembly definitions? [Brad Knotwell, 1/5/01] Sorry, I should've been more clear. Yes, the runtime links correctly and the rest of the system builds. I only had to remove the OPSYS_FREEBSD from the pre-processor directive worried about GLOBALS_NEED_UNDERSCORE (or somethin' like that, I'm at work). FWIW, I have no idea if this will work on FreeBSD3X and below. Fix: Test: Owner: jhr Status: open ---------------------------------------------------------------------- Number: 1595 Title: suspicious signatures printed when using datatype replication Keywords: datatype replication signature structure REPL Submitter: Tom 7 tom7@cs.cmu.edu Date: 01/14/01 Version: 110.0.7 System: Any/All Any Unix Subsystem: SML compiler Severity: cosmetic Problem: The top-level loop prints out some suspicious results when using datatype replication. In particular, it appears to always report the name of the original datatype, as if it were being redeclared. This seems acceptable (if strange) at top-level, perhaps: - datatype X = datatype bool; datatype bool = false | true - But the result for a structure is quite misleading: - structure Y = struct datatype X = datatype bool end; structure Y : sig datatype bool = false | true end - Structure Y, of course, does not match the signature printed. I'm pretty sure this is merely an artifact of the way datatypes are pretty-printed (I didn't observe any semantic violations). Code: Above. Transcript: Also above. Comments: Fix: Test: Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1596 Title: TransTypes: unexpected FORMAL kind in tycTyc-h Keywords: types, functors, where clause Submitter: Fermin Reig, reig@dcs.gla.ac.uk Date: 1/17/2001 Version: 110.32 System: x86-linux Severity: major (?) Problem: functor applied inside another functor Code: The context is the C-- compiler, that has an MLRISC-based back end. I have a file mlriscFuns.sml with this functor: functor MLRiscFuns (structure MLTreeComp : MLTREECOMP structure FlowGen : FLOWGRAPH_GEN where T = MLTreeComp.T and I = MLTreeComp.I val compile : FlowGen.flowgraph -> unit ) = struct structure T : MLTREE = MLTreeComp.T val iStream as T.Stream.STREAM {emit=emitInstr, ...} = FlowGen.newStream {compile = compile, flowgraph = NONE} end (* MLRiscFuns *) I have a "functor MLRiscGen" similar in spirit to the one in SML/NJ's main/mlriscGen.sml. In particular, MLTreeComp, FlowGen and compile are parameters to the MLRiscGen functor. Inside MLRiscGen, I instantiate, structure Foo = MLRiscFuns(structure MLTreeComp = MLTreeComp structure FlowGen = FlowGen val compile = compile) and I get the error. If I remove this clause: and I = MLTreeComp.I the bug does not happen I assume you should be able to reproduce the error by having mlriscFuns.sml and instantiating Foo inside SML/NJ's MLRiscGen. Otherwise, I can send my sources (but they are big). Transcript: - CM.make "sources.cm"; ... Error: Compiler bug: TransTypes: unexpected FORMAL kind in tycTyc-h val it = false : bool Comments: This is the smallest code I can find that exposes the bug. I use my own copy of MLRISC; That is, in my .cm file, rather than this $/MLRISC.cm I have MLRISC++/cm/MLRISC.cm but I think this should not make a difference with respect to this bug. [Fermin, 1/29/01] I can now provide a little more information about this bug, in case it is useful: If I substitute the where clauses by sharing clauses, I can compile the code just fine. functor MLRiscFuns (structure MLTreeComp : MLTREECOMP structure FlowGen : FLOWGRAPH_GEN sharing FlowGen.T = MLTreeComp.T sharing FlowGen.I = MLTreeComp.I val compile : FlowGen.flowgraph -> unit ) = Fix: Test: Owner: dbm, Zhong Status: open ---------------------------------------------------------------------- Number: 1597 Title: CML withNack bug and possible CM bug Keywords: Submitter: Anthony Shipman, felixadv@access.net.au Date: 01/25/2001 Version: 110.0.7 System: i386-Linux Severity: major Problem: The program below tests the CML withNack() function to time out a request to a server. A fatal exception is thrown in the CML.select call within the client() function in the code below. The exception message is 'Fail: cvar already set' Also for some reason, perhaps to do with CM, the program does nothing and prints nothing if both of the toErr() and print() function declarations are removed from the program. Code: structure Main = struct (* Unless one of these two functions is present the program prints nothing! *) fun toErr msg = TextIO.output(TextIO.stdErr, msg) fun print msg = TextIO.output(TextIO.stdOut, msg) datatype Msg = Msg of unit CML.event val req_chan: Msg CML.chan = CML.channel() val rpl_chan: unit CML.chan = CML.channel() fun server t = let fun loop() = (case CML.recv req_chan of Msg nack => (delay t; CML.select [ CML.sendEvt(rpl_chan, ()), CML.wrap(nack, fn () => print "Got a nack\n")]; loop())) in CML.spawn loop end and reqEvt () = let fun sender nack_evt = (CML.send(req_chan, Msg nack_evt); CML.recvEvt rpl_chan) in CML.withNack sender end and client t = let fun body() = (CML.select[ CML.wrap(reqEvt(), fn () => print "got the reply\n"), CML.wrap(time_out t, fn () => print "client timed out\n")]; print "done client\n") handle x => print(concat["exception: '", exnMessage x, "' in client\n"]) in ignore(CML.spawn body) end and time_out t = CML.timeOutEvt(Time.fromSeconds(Int.toLarge t)) and delay t = CML.sync(time_out t) fun run() = (print "Test\n"; server 3; (* send reply after client times out *) client 2) fun main(arg0, argv) = (RunCML.doit(run, NONE); OS.Process.success) handle x => (print(concat["exception: ", exnMessage x, " in main\n"]); OS.Process.failure) val _ = SMLofNJ.exportFn("nackbug", main) end script to run the program ========================= heap=`basename $0` install=. smlbin=/src/smlnj/current/bin exec $smlbin/.run-sml @SMLload=$install/${heap}.x86-linux "$@" Transcript: > nackbug Test exception: 'Fail: cvar already set' in client Got a nack Comments: [jhr, 1/24/01] The second problem has to do with CM (see the CML FAQ), but I'll try to track down the first problem. [jhr, 1/24/01] I've found and fixed the bug. You can get a new CML tarball at ftp://ftp.research.bell-labs.com/dist/smlnj/packages/cml/20010124.tar.gz Two coding style comments: I don't think that you need the LargeInt.fromInt conversions, since constants are overloaded. Also, you should probably use RunCML.exportFn (instead of SMLofNJ.exportFn) to create executables. Fix: Test: - Owner: jhr, Matthias Status: fixed (in latest CML library) ---------------------------------------------------------------------- Number: 1598 Title: IntInf broken on Windows Keywords: IntInf Submitter: James C. Alexander jca10@po.cwru.edu Date: 1/17/01 Version: 110.0.7? System: Windows Severity: major Problem: We were never able to get Int-Inf to work on pentium machines. It looks like some problem with word length. Comments: [Riccardo, 1/17/01] I presume you are running SML/NJ under Windows? Indeed, that is a known bug with the implementation under Windows. A quick fix that I used in my class follows (directly from one of the assignments): READ ME: There is a bug in the current installation of SML/NJ for Windows that needs to be corrected before doing the second part of the problem set. The fix is simple, you need to delete two files in the installation. This assumes that you have installed SML/NJ in the default location, c:\sml. If not, then adapt accordingly. The two files to delete are: c:\sml\src\smlnj-lib\Util\CM\x86-win32\int-inf-sig.sml.bin c:\sml\src\smlnj-lib\Util\CM\x86-win32\int-inf.sml.bin Basically, deleting these two files will force SML/NJ to recompile the IntInf structure, which takes care of that particular bug. - R Fix: Test: Owner: ? Status: open ---------------------------------------------------------------------- Number: 1599 Title: Nonexhaustive binding failure during compilation of incorrect program Keywords: Submitter: Leif Kornstaedt kornstae@ps.uni-sb.de Date: 01/24/01 Version: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 System: x86 Linux RedHat 7.0 Subsystem: SML compiler Severity: minor Problem: Compiler raises a Bind exception when compiling an erroneous program. Code: signature SIG1 = sig type t end signature SIG2 = sig type t val f: t -> unit end signature SIG3 = sig structure S: SIG1 end functor MkA(structure S1: SIG3): SIG3 = struct open S1 end functor MkB(structure A: SIG2): SIG3 = MkA(structure S1 = struct structure S = A end) functor MkC(structure Ta: SIG2 structure B: SIG3 where S = Ta) = struct end structure A = struct type t = int val f = ignore end structure B = MkB(structure A = A) structure C = MkC(structure A = A structure B = B) Transcript: Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled] - use "sml-nj-bug-nonexhaustive-binding-failure.sml"; [opening sml-nj-bug-nonexhaustive-binding-failure.sml] sml-nj-bug-nonexhaustive-binding-failure.sml:36.15-37.21 Error: unmatched structure specification: Ta uncaught exception nonexhaustive binding failure raised at: modules/sigmatch.sml:576.10-576.44 modules/sigmatch.sml:728.45 modules/sigmatch.sml:884.25 modules/sigmatch.sml:728.45 modules/sigmatch.sml:884.25 modules/sigmatch.sml:966.24 elaborate/elabmod.sml:1223.8 elaborate/elabmod.sml:1223.8 Comments: Fix: Test: bug1599.1.sml Owner: dbm Status: open ---------------------------------------------------------------------- Number: 1600 Title: Word literals are not printed correctly in error messages Keywords: error messages Submitter: John Reppy jhr@research.bell-labs.com Date: 01/24/01 Version: 110+ System: Any/All Any Unix Subsystem: SML compiler Severity: minor Problem: When printing word literals in error messages, the "0w" prefix is not included. This makes the message confusing. Code: 0w1 + 1; Transcript: Standard ML of New Jersey, Version 110.0.7, September 28, 2000 ... - 0w1 + 1; stdIn:25.1-25.8 Error: operator and operand don't agree [literal] operator domain: word * word operand: word * int in expression: 1 + 1 Comments: Fix: Test: Owner: jhr Status: open ----------------------------------------------------------------------