(* Copyright (C) 2004-2006, 2008 Henry Cejtin, Matthew Fluet, Suresh * Jagannathan, and Stephen Weeks. * * MLton is released under a BSD-style license. * See the file MLton-LICENSE for details. *) structure Exit = struct structure Status = struct open PreOS.Status val fromInt = fromRep o C_Status.fromInt val toInt = C_Status.toInt o toRep val failure = fromInt 1 val success = fromInt 0 end val exiting = ref false fun atExit f = if !exiting then () else Cleaner.addNew (Cleaner.atExit, f) fun halt (status: Status.t) = Primitive.MLton.halt (Status.toRep status) fun exit (status: Status.t): 'a = if !exiting then raise Fail "MLton.Exit.exit" else let val _ = exiting := true val i = Status.toInt status in if 0 <= i andalso i < 256 then (let open Cleaner in clean atExit end ; halt status ; raise Fail "MLton.Exit.exit") else raise Fail (concat ["MLton.Exit.exit(", Int.toString i, "): ", "exit must have 0 <= status < 256"]) end local val message = PrimitiveFFI.Stdio.print fun 'a wrapSuffix (suffix: unit -> unit) () : 'a = (suffix () ; message "Top-level suffix returned.\n" ; exit Status.failure) handle _ => (message "Top-level suffix raised exception.\n" ; halt Status.failure ; raise Fail "MLton.Exit.wrapSuffix") fun suffixArchiveOrLibrary () = let (* Return to 'lib_open'. *) val () = Primitive.MLton.Thread.returnToC () (* Enter from 'lib_close'. *) val _ = exiting := true val () = let open Cleaner in clean atExit end (* Return to 'lib_close'. *) val () = Primitive.MLton.Thread.returnToC () in () end fun suffixExecutable () = exit Status.success val defaultSuffix = let open Primitive.MLton.Platform.Format in case host of Archive => suffixArchiveOrLibrary | Executable => suffixExecutable | LibArchive => suffixArchiveOrLibrary | Library => suffixArchiveOrLibrary end in val getTopLevelSuffix = Primitive.TopLevel.getSuffix val setTopLevelSuffix = Primitive.TopLevel.setSuffix o wrapSuffix fun 'a defaultTopLevelSuffix ((): unit): 'a = wrapSuffix defaultSuffix () fun 'a topLevelSuffix ((): unit) : 'a = (getTopLevelSuffix () () ; raise Fail "MLton.Exit.topLevelSuffix") end end