From: simonpj Date: Mon, 17 Mar 1997 20:35:30 +0000 (+0000) Subject: [project @ 1997-03-17 20:34:25 by simonpj] X-Git-Tag: Approximately_1000_patches_recorded~780 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=2494407a750053daa61718fac371487d04818e57 [project @ 1997-03-17 20:34:25 by simonpj] More small changes towards 2.02 --- diff --git a/Makefile b/Makefile index eca7ef4..204d5ec 100644 --- a/Makefile +++ b/Makefile @@ -65,28 +65,3 @@ dist :: dist-pre include $(TOP)/mk/target.mk dist :: dist-post -# -# Automatically remake update configuration files -# (from autoconf manual) -# -configure: configure.in - autoconf -# -# autoheader might not change config.h.in, so touch a stamp file. -# -mk/config.h.in: mk/stamp-h.in -mk/stamp-h.in: configure.in - autoheader - echo timestamp > mk/stamp-h.in - -mk/config.h: mk/stamp-h -mk/stamp-h: mk/config.h.in config.status - ./config.status - -config.status: configure - ./config.status --recheck - -.PHONY: config - -config: config.status - @: diff --git a/docs/Makefile b/docs/Makefile index 851469d..b2164c4 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,7 +1,7 @@ TOP = .. include $(TOP)/mk/boilerplate.mk -DOC_SRCS = installing.lit release.lit +DOC_SRCS = installing.lit SRC_TEXI2HTML_OPTS += -number -monolithic -invisible xbm diff --git a/docs/installing.lit b/docs/installing.lit index 81bdeee..d2d9bb3 100644 --- a/docs/installing.lit +++ b/docs/installing.lit @@ -784,6 +784,19 @@ and you're on the road again. You need to be a bit careful, though, that any new files you create (if you do any development work) are in the source tree, not a build tree! +Remember, that the source files in the build tree are {\em symbolic +links} to the files in the source tree. (The build tree soon +accumulates lots of built files like @Foo.o@, as well.) You can {\em +delete} a source file from the build tree without affecting the source +tree (though it's an odd thing to do). On the other hand, if you {\em +edit} a source file from the build tree, you'll edit the source-tree +file directly. (You can set up Emacs so that if you edit a source +file from the build tree, Emacs will silently create an edited copy of +the source file in the build tree, leaving the source file unchanged; +but the danger is that you think you've edited the source file whereas +actually all you've done is edit the build-tree copy. More commonly +you do want to edit the source file.) + Like the source tree, the top level of your build tree must (a linked copy of) the root directory of the @fptools@ suite. Inside Makefiles, the root of your build tree is called @$(FPTOOLS_TOP)@. @@ -813,27 +826,32 @@ Or, you might want to compile it with debugging on (so that extra consistency-checking code gets included) or off. And so on. All of this stuff is called the {\em configuration} of your build. -You set the configuration using an exciting two-step process. +You set the configuration using an exciting three-step process. \begin{description} -\item[Step 1: system configuration.] This is easy, provided you -have the programs mentioned in Section~\ref{sect_std-utils}. Just -@cd@ to @$(FPTOOLS)@ and say @gmake configure@. This -command does three things: -\begin{itemize} -\item -It runs a GNU program called @autoconf@, which +\item[Step 1: get ready for configuration.] +Change directory to @$(FPTOOLS)@ and issue the following two commands (with no arguments): +\begin{enumerate} +\item @autoconf@. This GNU program converts @$(FPTOOLS)/configure.in@ to a shell script called @$(FPTOOLS)/configure@. -This step is completely platform-independent; it just means +\item @autoheader@. This second GNU program converts +@$(FPTOOLS)/configure.in@ to @$(FPTOOLS)/mk/config.h.in@. +\end{enumerate} +Both these steps are completely platform-independent; they just mean that the human-written file (@configure.in@) can be short, although -the resulting shell script, @configure@ is long. +the resulting shell script, @configure@, and @mk/config.h.in@, are long. -\item It runs a second GNU program called @autoheader@, which converts -@$(FPTOOLS)/configure.in@ to @$(FPTOOLS)/mk/config.h.in@. -Again, this step is platform-independent. +In case you don't have @autoconf@ and @autoheader@ we distribute +the results, @configure@, and @mk/config.h.in@, with the source distribution. +They aren't kept in the repository, though. -\item It then runs the newly-created @configure@ script. @configure@'s mission +\item[Step 2: system configuration.] +Runs the newly-created @configure@ script, thus: +\begin{verbatim} + ./configure +\end{verbatim} +@configure@'s mission is to scurry round your computer working out what architecture it has, what operating system, whether it has the @vfork@ system call, where @yacc@ is kept, whether @gcc@ is available, where various @@ -853,10 +871,9 @@ all Makefiles. The latter is @#include@d by various C programs, which can thereby make use of configuration information. \end{itemize} -\end{itemize} -\item[Step 2: build configuration.] Next, you say how this build +\item[Step 3: build configuration.] Next, you say how this build of @fptools@ is to differ from the standard defaults by creating a new file @mk/build.mk@ {\em in the build tree}. This file is the one and only @@ -883,18 +900,18 @@ want to change. (The override occurs because the main boilerplate file, For example, @config.mk.in@ contains the definition: \begin{verbatim} - SUBDIRS = glafp-utils literate ghc + ProjectsToBuild = glafp-utils literate ghc hslibs \end{verbatim} The accompanying comment explains that this is the list of enabled projects; that is, if (after configuring) you type @gmake all@ in @FPTOOLS_TOP@ three specified projects will be made. If you want to add @happy@, you can add this line to @build.mk@: \begin{verbatim} - SUBDIRS += happy + ProjectsToBuild += happy \end{verbatim} or, if you prefer, \begin{verbatim} - SUBDIRS = glafp-utils literate ghc happy + ProjectsToBuild = glafp-utils literate ghc hslibs happy \end{verbatim} (GNU @make@ allows existing definitions to have new text appended using the ``@+=@'' operator, which is quite a convenient feature.) @@ -941,10 +958,19 @@ to happen there now. \begin{verbatim} cd /scratch/joe-bloggs/myfptools-sun4 \end{verbatim} +\item Prepare for system configuration: +\begin{verbatim} + autoconf + autoheader +\end{verbatim} +(You can skip this step if you are starting from a source distribution, +and you already have @configure@ and @mk/config.h.in@.) + \item Do system configuration: \begin{verbatim} - gmake configure + ./configure \end{verbatim} + \item Create the file @mk/build.mk@, adding definitions for your desired configuration options. \begin{verbatim} diff --git a/ghc/Makefile b/ghc/Makefile index 3876e1b..42b121c 100644 --- a/ghc/Makefile +++ b/ghc/Makefile @@ -1,5 +1,5 @@ #----------------------------------------------------------------------------- -# $Id: Makefile,v 1.3 1997/03/14 07:53:55 simonpj Exp $ +# $Id: Makefile,v 1.4 1997/03/17 20:34:29 simonpj Exp $ # TOP=. @@ -49,7 +49,7 @@ boot :: $(line) @echo "Booting Prelude libraries" $(line) - @$(MAKE) -C compiler boot + @$(MAKE) -C lib boot # "CONTRIB" is also a SUBDIR, but there is nothing to build there. diff --git a/ghc/compiler/Makefile b/ghc/compiler/Makefile index b0b54d0..972a8ca 100644 --- a/ghc/compiler/Makefile +++ b/ghc/compiler/Makefile @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- -# $Id: Makefile,v 1.8 1997/03/14 07:55:43 simonpj Exp $ +# $Id: Makefile,v 1.9 1997/03/17 20:34:30 simonpj Exp $ TOP = .. include $(TOP)/mk/boilerplate.mk @@ -226,6 +226,7 @@ all :: hsp hsp: parser/printtree.o parser/main.o libhsp.a $(CC) -o $@ $(CC_OPTS) $^ +CLEAN_FILES += hsp #----------------------------------------------------------------------------- # Interface files diff --git a/ghc/compiler/absCSyn/AbsCSyn.lhs b/ghc/compiler/absCSyn/AbsCSyn.lhs index be099d0..28cab79 100644 --- a/ghc/compiler/absCSyn/AbsCSyn.lhs +++ b/ghc/compiler/absCSyn/AbsCSyn.lhs @@ -433,7 +433,7 @@ data MagicId -- Argument and return registers | VanillaReg -- pointers, unboxed ints and chars - PrimRep -- PtrRep, IntRep, CharRep, StablePtrRep or ForeignObjRep + PrimRep -- PtrRep, IntRep, CharRep, StablePtrRep or ForeignObjRep -- (in case we need to distinguish) FAST_INT -- its number (1 .. mAX_Vanilla_REG) diff --git a/ghc/compiler/absCSyn/PprAbsC.lhs b/ghc/compiler/absCSyn/PprAbsC.lhs index b2e60c4..7fba22e 100644 --- a/ghc/compiler/absCSyn/PprAbsC.lhs +++ b/ghc/compiler/absCSyn/PprAbsC.lhs @@ -747,20 +747,22 @@ ppr_casm_results sty [r] liveness (result_type, assign_result) = case r_kind of -{- @ForeignObj@s replaces MallocPtrs and are *not* CReturnable. - Instead, external references have to be turned into ForeignObjs +{- + @ForeignObj@s replaces MallocPtrs and are *not* CReturnable. + Instead, external references have to explicitly turned into ForeignObjs using the primop makeForeignObj#. Benefit: Multiple finalisation routines can be accommodated and the below special case is not needed. Price is, of course, that you have to explicitly wrap `foreign objects' with makeForeignObj#. -+ + ForeignObjRep -> (uppPStr SLIT("StgForeignObj"), uppBesides [ uppPStr SLIT("constructForeignObj"),uppChar '(', liveness, uppComma, result_reg, uppComma, local_var, - pp_paren_semi ]) -} + pp_paren_semi ]) +-} _ -> (pprPrimKind sty r_kind, uppBesides [ result_reg, uppEquals, local_var, uppSemi ]) diff --git a/ghc/compiler/basicTypes/Unique.lhs b/ghc/compiler/basicTypes/Unique.lhs index 5f14e9f..3dbdbcd 100644 --- a/ghc/compiler/basicTypes/Unique.lhs +++ b/ghc/compiler/basicTypes/Unique.lhs @@ -195,6 +195,7 @@ module Unique ( stateTyConKey, synchVarPrimTyConKey, thenMClassOpKey, + toEnumClassOpKey, traceIdKey, trueDataConKey, unpackCString2IdKey, @@ -680,4 +681,5 @@ mainPrimIoKey = mkPreludeMiscIdUnique 67 returnMClassOpKey = mkPreludeMiscIdUnique 68 -- Used for minusClassOp 69 otherwiseIdKey = mkPreludeMiscIdUnique 70 +toEnumClassOpKey = mkPreludeMiscIdUnique 71 \end{code} diff --git a/ghc/compiler/deSugar/DsMonad.lhs b/ghc/compiler/deSugar/DsMonad.lhs index 38e567a..c2034d7 100644 --- a/ghc/compiler/deSugar/DsMonad.lhs +++ b/ghc/compiler/deSugar/DsMonad.lhs @@ -282,7 +282,7 @@ pprDsWarnings sty warns = ppCat [ppPStr SLIT("in the definition of function"), ppQuote (ppr sty fun)] pp_match CaseMatch pats - = ppHang (ppPStr SLIT("in a group of case alternative beginning:")) + = ppHang (ppPStr SLIT("in a group of case alternatives beginning:")) 4 (ppSep [ppSep (map (ppr sty) pats), pp_arrow_dotdotdot]) pp_match PatBindMatch pats diff --git a/ghc/compiler/prelude/PrelInfo.lhs b/ghc/compiler/prelude/PrelInfo.lhs index 98364f2..426eb62 100644 --- a/ghc/compiler/prelude/PrelInfo.lhs +++ b/ghc/compiler/prelude/PrelInfo.lhs @@ -15,7 +15,7 @@ module PrelInfo ( eq_RDR, ne_RDR, le_RDR, lt_RDR, ge_RDR, gt_RDR, max_RDR, min_RDR, compare_RDR, minBound_RDR, maxBound_RDR, enumFrom_RDR, enumFromTo_RDR, enumFromThen_RDR, - enumFromThenTo_RDR, fromEnum_RDR, + enumFromThenTo_RDR, fromEnum_RDR, toEnum_RDR, range_RDR, index_RDR, inRange_RDR, readsPrec_RDR, readList_RDR, showsPrec_RDR, showList_RDR, plus_RDR, times_RDR, ltTag_RDR, eqTag_RDR, gtTag_RDR, eqH_Char_RDR, ltH_Char_RDR, eqH_Word_RDR, ltH_Word_RDR, eqH_Addr_RDR, ltH_Addr_RDR, @@ -299,6 +299,7 @@ knownKeyNames , (enumFromTo_RDR, enumFromToClassOpKey) , (enumFromThenTo_RDR, enumFromThenToClassOpKey) , (fromEnum_RDR, fromEnumClassOpKey) + , (toEnum_RDR, toEnumClassOpKey) , (eq_RDR, eqClassOpKey) , (thenM_RDR, thenMClassOpKey) , (returnM_RDR, returnMClassOpKey) @@ -361,6 +362,7 @@ creturnableClass_RDR = tcQual (fOREIGN, SLIT("CReturnable")) fromInt_RDR = varQual (pREL_BASE, SLIT("fromInt")) fromInteger_RDR = varQual (pREL_BASE, SLIT("fromInteger")) minus_RDR = varQual (pREL_BASE, SLIT("-")) +toEnum_RDR = varQual (pREL_BASE, SLIT("toEnum")) fromEnum_RDR = varQual (pREL_BASE, SLIT("fromEnum")) enumFrom_RDR = varQual (pREL_BASE, SLIT("enumFrom")) enumFromTo_RDR = varQual (pREL_BASE, SLIT("enumFromTo")) diff --git a/ghc/compiler/prelude/PrimOp.lhs b/ghc/compiler/prelude/PrimOp.lhs index bd24ebe..7ba7dd3 100644 --- a/ghc/compiler/prelude/PrimOp.lhs +++ b/ghc/compiler/prelude/PrimOp.lhs @@ -154,7 +154,8 @@ data PrimOp | TakeMVarOp | PutMVarOp | ReadIVarOp | WriteIVarOp - | MakeForeignObjOp -- foreign objects (malloc pointers or any old URL) + | MakeForeignObjOp -- foreign objects (malloc pointers or any old URL) + | WriteForeignObjOp -- modifying foreign objects [obscuro factor: 200] | MakeStablePtrOp | DeRefStablePtrOp \end{code} @@ -413,26 +414,27 @@ tagOf_PrimOp PutMVarOp = ILIT(152) tagOf_PrimOp ReadIVarOp = ILIT(153) tagOf_PrimOp WriteIVarOp = ILIT(154) tagOf_PrimOp MakeForeignObjOp = ILIT(155) -tagOf_PrimOp MakeStablePtrOp = ILIT(156) -tagOf_PrimOp DeRefStablePtrOp = ILIT(157) -tagOf_PrimOp (CCallOp _ _ _ _ _) = ILIT(158) -tagOf_PrimOp ErrorIOPrimOp = ILIT(159) -tagOf_PrimOp ReallyUnsafePtrEqualityOp = ILIT(160) -tagOf_PrimOp SeqOp = ILIT(161) -tagOf_PrimOp ParOp = ILIT(162) -tagOf_PrimOp ForkOp = ILIT(163) -tagOf_PrimOp DelayOp = ILIT(164) -tagOf_PrimOp WaitReadOp = ILIT(165) -tagOf_PrimOp WaitWriteOp = ILIT(166) - -tagOf_PrimOp ParGlobalOp = ILIT(167) -tagOf_PrimOp ParLocalOp = ILIT(168) -tagOf_PrimOp ParAtOp = ILIT(169) -tagOf_PrimOp ParAtAbsOp = ILIT(170) -tagOf_PrimOp ParAtRelOp = ILIT(171) -tagOf_PrimOp ParAtForNowOp = ILIT(172) -tagOf_PrimOp CopyableOp = ILIT(173) -tagOf_PrimOp NoFollowOp = ILIT(174) +tagOf_PrimOp WriteForeignObjOp = ILIT(156) +tagOf_PrimOp MakeStablePtrOp = ILIT(157) +tagOf_PrimOp DeRefStablePtrOp = ILIT(158) +tagOf_PrimOp (CCallOp _ _ _ _ _) = ILIT(159) +tagOf_PrimOp ErrorIOPrimOp = ILIT(160) +tagOf_PrimOp ReallyUnsafePtrEqualityOp = ILIT(161) +tagOf_PrimOp SeqOp = ILIT(162) +tagOf_PrimOp ParOp = ILIT(163) +tagOf_PrimOp ForkOp = ILIT(164) +tagOf_PrimOp DelayOp = ILIT(165) +tagOf_PrimOp WaitReadOp = ILIT(166) +tagOf_PrimOp WaitWriteOp = ILIT(167) + +tagOf_PrimOp ParGlobalOp = ILIT(168) +tagOf_PrimOp ParLocalOp = ILIT(169) +tagOf_PrimOp ParAtOp = ILIT(170) +tagOf_PrimOp ParAtAbsOp = ILIT(171) +tagOf_PrimOp ParAtRelOp = ILIT(172) +tagOf_PrimOp ParAtForNowOp = ILIT(173) +tagOf_PrimOp CopyableOp = ILIT(174) +tagOf_PrimOp NoFollowOp = ILIT(175) tagOf_PrimOp _ = panic# "tagOf_PrimOp: pattern-match" @@ -597,6 +599,7 @@ allThePrimOps ReadIVarOp, WriteIVarOp, MakeForeignObjOp, + WriteForeignObjOp, MakeStablePtrOp, DeRefStablePtrOp, ReallyUnsafePtrEqualityOp, @@ -1147,7 +1150,7 @@ primOpInfo WaitWriteOp %************************************************************************ %* * -\subsubsection[PrimOps-makeForeignObj]{PrimOpInfo for Foreign Objects} +\subsubsection[PrimOps-ForeignObj]{PrimOpInfo for Foreign Objects} %* * %************************************************************************ @@ -1164,7 +1167,7 @@ When a @ForeignObj@ becomes garbage, a user-defined finalisation routine associated with the object is invoked (currently, each ForeignObj has a direct reference to its finaliser). -- SOF -The only function defined over @ForeignObj@s is: +A @ForeignObj@ is created by the @makeForeignObj#@ primitive: \begin{pseudocode} makeForeignObj# :: Addr# -- foreign object @@ -1172,6 +1175,7 @@ makeForeignObj# :: Addr# -- foreign object -> StateAndForeignObj# _RealWorld# ForeignObj# \end{pseudocode} + \begin{code} primOpInfo MakeForeignObjOp = AlgResult SLIT("makeForeignObj#") [] @@ -1179,6 +1183,34 @@ primOpInfo MakeForeignObjOp stateAndForeignObjPrimTyCon [realWorldTy] \end{code} +[Experimental--SOF] +In addition, another @ForeignObj@ primitive is provided for destructively modifying +the external object wrapped up inside a @ForeignObj@. This primitive is used +when a mixed programming interface of implicit and explicit de-allocation is used, +e.g., if @ForeignObj@s are used to implement @Handle@s, then @Handle@s can be +released either explicitly (through @hClose@) or implicitly (via a finaliser). +When releasing/closing the @Handle@ explicitly, care must be taken to avoid having +the finaliser for the embedded @ForeignObj@ attempt the same thing later. +We deal with this situation, by allowing the programmer to destructively modify +the data field of the @ForeignObj@ to hold a special value the finaliser recognises, +and does not attempt to free (e.g., filling the data slot with \tr{NULL}). + +\begin{pseudocode} +writeForeignObj# :: ForeignObj# -- foreign object + -> Addr# -- new data value + -> StateAndForeignObj# _RealWorld# ForeignObj# +\end{pseudocode} + +\begin{code} +primOpInfo WriteForeignObjOp + = let { + s = alphaTy; s_tv = alphaTyVar + } in + PrimResult SLIT("writeForeignObj#") [s_tv] + [foreignObjPrimTy, addrPrimTy, mkStatePrimTy s] + statePrimTyCon VoidRep [s] +\end{code} + %************************************************************************ %* * \subsubsection[PrimOp-stable-pointers]{PrimOpInfo for ``stable pointers''} @@ -1411,6 +1443,7 @@ primOpHeapReq (CCallOp _ _ mayGC@True _ _) = VariableHeapRequired primOpHeapReq (CCallOp _ _ mayGC@False _ _) = NoHeapRequired primOpHeapReq MakeForeignObjOp = VariableHeapRequired +primOpHeapReq WriteForeignObjOp = NoHeapRequired -- this occasionally has to expand the Stable Pointer table primOpHeapReq MakeStablePtrOp = VariableHeapRequired @@ -1557,7 +1590,8 @@ fragilePrimOp :: PrimOp -> Bool fragilePrimOp ParOp = True fragilePrimOp ForkOp = True fragilePrimOp SeqOp = True -fragilePrimOp MakeForeignObjOp = True -- SOF +fragilePrimOp MakeForeignObjOp = True -- SOF +fragilePrimOp WriteForeignObjOp = True -- SOF fragilePrimOp MakeStablePtrOp = True fragilePrimOp DeRefStablePtrOp = True -- ??? JSM & ADR @@ -1629,6 +1663,7 @@ primOpNeedsWrapper DoubleEncodeOp = True primOpNeedsWrapper DoubleDecodeOp = True primOpNeedsWrapper MakeForeignObjOp = True +primOpNeedsWrapper WriteForeignObjOp = True primOpNeedsWrapper MakeStablePtrOp = True primOpNeedsWrapper DeRefStablePtrOp = True diff --git a/ghc/compiler/reader/Lex.lhs b/ghc/compiler/reader/Lex.lhs index 32f20e9..626762d 100644 --- a/ghc/compiler/reader/Lex.lhs +++ b/ghc/compiler/reader/Lex.lhs @@ -531,7 +531,7 @@ is_sym c#= '&'# -> True; '*'# -> True; '+'# -> True; '.'# -> True; '/'# -> True; '<'# -> True; '='# -> True; '>'# -> True; '?'# -> True; '\\'# -> True; '^'# -> True; '|'# -> True; - '-'# -> True; '~'# -> True; _ -> False } + '-'# -> True; '~'# -> True; '@'# -> True; _ -> False } --isAlphanum c || c `elem` ":_'!#$%&*+./<=>?@\\^|-~" -- ToDo: add ISOgraphic diff --git a/ghc/compiler/rename/RnIfaces.lhs b/ghc/compiler/rename/RnIfaces.lhs index 3024b8e..453fda3 100644 --- a/ghc/compiler/rename/RnIfaces.lhs +++ b/ghc/compiler/rename/RnIfaces.lhs @@ -32,7 +32,9 @@ import HsPragmas ( noGenPragmas ) import RdrHsSyn ( SYN_IE(RdrNameHsDecl), SYN_IE(RdrNameInstDecl), RdrName, rdrNameOcc ) -import RnEnv ( newGlobalName, lookupRn, addImplicitOccsRn, availName, availNames, addAvailToNameSet ) +import RnEnv ( newGlobalName, lookupRn, addImplicitOccsRn, + availName, availNames, addAvailToNameSet, pprAvail + ) import RnSource ( rnHsType ) import RnMonad import ParseIface ( parseIface ) @@ -275,6 +277,7 @@ importDecl :: Name -> Necessity -> RnMG (Maybe RdrNameHsDecl) importDecl name necessity = checkSlurped name `thenRn` \ already_slurped -> if already_slurped then + -- traceRn (ppSep [ppStr "Already slurped:", ppr PprDebug name]) `thenRn_` returnRn Nothing -- Already dealt with else if isWiredInName name then @@ -336,37 +339,45 @@ that we know just what instances to bring into scope. \begin{code} getWiredInDecl name - = -- Force in the home module in case it has instance decls for - -- the thing we are interested in - (if not is_tycon || mod == gHC__ then - returnRn () -- Mini hack 1: no point for non-tycons; and if we - -- do this we find PrelNum trying to import PackedString, - -- because PrelBase's .hi file mentions PackedString.unpackString - -- But PackedString.hi isn't built by that point! - -- - -- Mini hack 2; GHC is guaranteed not to have - -- instance decls, so it's a waste of time - -- to read it + = get_wired `thenRn` \ avail -> + recordSlurp Nothing avail `thenRn_` + + -- Force in the home module in case it has instance decls for + -- the thing we are interested in. + -- + -- Mini hack 1: no point for non-tycons/class; and if we + -- do this we find PrelNum trying to import PackedString, + -- because PrelBase's .hi file mentions PackedString.unpackString + -- But PackedString.hi isn't built by that point! + -- + -- Mini hack 2; GHC is guaranteed not to have + -- instance decls, so it's a waste of time to read it + -- + -- NB: We *must* look at the availName of the slurped avail, + -- not the name passed to getWiredInDecl! Why? Because if a data constructor + -- or class op is passed to getWiredInDecl we'll pull in the whole data/class + -- decl, and recordSlurp will record that fact. But since the data constructor + -- isn't a tycon/class we won't force in the home module. And even if the + -- type constructor/class comes along later, loadDecl will say that it's already + -- been slurped, so getWiredInDecl won't even be called. Pretty obscure bug, this was. + let + main_name = availName avail + main_is_tc = case avail of { AvailTC _ _ -> True; Avail _ -> False } + (mod,_) = modAndOcc main_name + doc_str = ppSep [ppPStr SLIT("Need home module for wired in thing"), ppr PprDebug name] + in + (if not main_is_tc || mod == gHC__ then + returnRn () else loadInterface doc_str mod `thenRn_` returnRn () ) `thenRn_` - get_wired `thenRn` \ avail -> - recordSlurp Nothing avail `thenRn_` returnRn Nothing -- No declaration to process further where - doc_str = ppSep [ppPStr SLIT("Need home module for wired in thing"), ppr PprDebug name] - (mod,_) = modAndOcc name - maybe_wired_in_tycon = maybeWiredInTyConName name - is_tycon = maybeToBool maybe_wired_in_tycon - maybe_wired_in_id = maybeWiredInIdName name - Just the_tycon = maybe_wired_in_tycon - Just the_id = maybe_wired_in_id get_wired | is_tycon -- ... a type constructor = get_wired_tycon the_tycon - -- Else, must be a wired-in-Id | (isDataCon the_id) -- ... a wired-in data constructor = get_wired_tycon (dataConTyCon the_id) @@ -374,6 +385,12 @@ getWiredInDecl name | otherwise -- ... a wired-in non data-constructor = get_wired_id the_id + maybe_wired_in_tycon = maybeWiredInTyConName name + is_tycon = maybeToBool maybe_wired_in_tycon + maybe_wired_in_id = maybeWiredInIdName name + Just the_tycon = maybe_wired_in_tycon + Just the_id = maybe_wired_in_id + get_wired_id id = addImplicitOccsRn (nameSetToList id_mentioned) `thenRn_` @@ -406,7 +423,8 @@ checkSlurped name returnRn (name `elemNameSet` slurped_names) recordSlurp maybe_version avail - = getIfacesRn `thenRn` \ ifaces -> + = -- traceRn (ppSep [ppStr "Record slurp:", pprAvail PprDebug avail]) `thenRn_` + getIfacesRn `thenRn` \ ifaces -> let Ifaces this_mod mod_vers export_envs decls slurped_names imp_names insts inst_mods = ifaces new_slurped_names = addAvailToNameSet slurped_names avail diff --git a/ghc/compiler/rename/RnMonad.lhs b/ghc/compiler/rename/RnMonad.lhs index 5d29108..8a3ebf6 100644 --- a/ghc/compiler/rename/RnMonad.lhs +++ b/ghc/compiler/rename/RnMonad.lhs @@ -468,7 +468,6 @@ addOccurrenceName necessity name (RnDown loc names_var errs_var occs_var) l_down | otherwise = readMutVarSST occs_var `thenSST` \ occs -> --- pprTrace "Add occurrence:" (ppr PprDebug name) $ writeMutVarSST occs_var ((name,necessity) : occs) `thenSST_` returnSST name where diff --git a/ghc/compiler/specialise/Specialise.lhs b/ghc/compiler/specialise/Specialise.lhs index 0692bd8..d49604a 100644 --- a/ghc/compiler/specialise/Specialise.lhs +++ b/ghc/compiler/specialise/Specialise.lhs @@ -1291,27 +1291,13 @@ specExpr :: CoreExpr -- expression. specExpr (Var v) args - = specId v $ \ lookupId v `thenSM` \ vlookup -> - case vlookup of - Lifted vl vu - -> -- Binding has been lifted, need to extract un-lifted value - -- NB: a function binding will never be lifted => args always null - -- i.e. no call instance required or call to be constructed - ASSERT (null args) - returnSM (bindUnlift vl vu (Var vu), singleFvUDs (VarArg vl)) - - NoLift vatom@(VarArg new_v) - -> mapSM specOutArg args `thenSM` \ arg_info -> - mkCallInstance v new_v arg_info `thenSM` \ call_uds -> - mkCall new_v arg_info `thenSM` \ call -> - let - call mkGenApp (Var new_id) [arg | (arg, _, _) <- arg_infos]) - uds = unionUDList [call_uds, - singleFvUDs vatom, - unionUDList [uds | (_,uds,_) <- arg_info] - ] - in - returnSM (call, {- tickSpecCall speced -} uds) + = specId v $ \ v_arg -> + case v_arg of + LitArg lit -> ASSERT( null args ) + returnSM (Lit lit, emptyUDs) + + VarArg new_v -> mkCallInstance v new_v args `thenSM` \ uds -> + returnSM (mkGenApp (Var new_v) args, uds) specExpr expr@(Lit _) null_args = ASSERT (null null_args) @@ -1354,9 +1340,8 @@ specPrimOp :: PrimOp specExpr (App fun arg) args - = -- If TyArg, arg will be processed; otherwise, left alone - specArg arg `thenSM` \ new_arg -> - specExpr fun (new_arg : args) `thenSM` \ (expr,uds) -> + = specArg arg `thenSM` \ new_arg -> + specExpr fun (new_arg : args) `thenSM` \ (expr,uds) -> returnSM (expr, uds) specExpr (Lam (ValBinder binder) body) (arg : args) | isValArg arg @@ -1564,18 +1549,18 @@ partition_args args ---------- specId :: Id - -> (Id -> SpecM (CoreExpr, UsageDetails)) + -> (CoreArg -> SpecM (CoreExpr, UsageDetails)) -> SpecM (CoreExpr, UsageDetails) specId v = lookupId v `thenSM` \ vlookup -> case vlookup of Lifted vl vu - -> thing_inside vu `thenSM` \ (expr, uds) -> + -> thing_inside (VarArg vu) `thenSM` \ (expr, uds) -> returnSM (bindUnlift vl vu expr, singleFvUDs (VarArg vl) `unionUDs` uds) NoLift vatom - -> thing_inside vatom `thenSM` \ (expr, uds) -> + -> thing_inside vatom `thenSM` \ (expr, uds) -> returnSM (expr, singleFvUDs vatom `unionUDs` uds) specArg :: CoreArg @@ -1933,7 +1918,7 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis newTyVars (length [() | Nothing <- spec_tys]) `thenSM` \ poly_tyvars -> let -- arg_tys is spec_tys with tyvars instead of the Nothing spec_tys - -- which correspond to unspeciailsed args + -- which correspond to unspecialised args arg_tys :: [Type] (_,arg_tys) = mapAccumL do_the_wotsit poly_tyvars spec_tys @@ -2060,246 +2045,53 @@ mkCallInstance :: Id -> [CoreArg] -> SpecM UsageDetails -mkCallInstance id new_id [] - = returnSM emptyUDs - mkCallInstance id new_id args - - -- No specialised versions for "error" and friends are req'd. - -- This is a special case in core lint etc. - - | isBottomingId id + | null args || -- No args at all + isBottomingId id || -- No point in specialising "error" and friends + -- even at unboxed types + idWantsToBeINLINEd id || -- It's going to be inlined anyway + not enough_args || -- Not enough type and dict args + not interesting_overloading -- Overloaded types are just tyvars = returnSM emptyUDs - -- No call instances for SuperDictSelIds - -- These are a special case in mkCall - - | maybeToBool (isSuperDictSelId_maybe id) - = returnSM emptyUDs - - -- There are also no call instances for ClassOpIds - -- However, we need to process it to get any second-level call - -- instances for a ConstMethodId extracted from its SpecEnv - | otherwise - = let - (tyvars, class_tyvar_pairs) = getIdOverloading id - constrained_tyvars = map snd class_tyvar_pairs -- May contain dups - constraint_vec = [tyvar `elem` constrained_tyvars | tyvar <- tyvars] + = returnSM (singleCI new_id spec_tys dicts) - arg_res = take_type_args tyvars class_tyvar_pairs args - enough_args = maybeToBool arg_res - - - (Just (tys, dicts, rest_args)) = arg_res - - record_spec id tys - = (record, lookup, spec_tys) - where - spec_tys = specialiseCallTys constraint_vec tys - - record = any (not . isTyVarTy) (catMaybes spec_tys) - - lookup = lookupSpecEnv (getIdSpecialisation id) tys - in - if (not enough_args) then - pprTrace "Specialise:recordCallInst: Unsaturated Type & Dict Application:\n\t" - (ppCat (ppr PprDebug id : map (ppr_arg PprDebug) args)) $ - returnSM emptyUDs - - else - case record_spec id tys of - (False, _, _) - -> -- pprTrace "CallInst:NotReqd\n" - -- (ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)]) - (returnSM emptyUDs) - - (True, Nothing, spec_tys) - -> if isClassOpId id then -- No CIs for class ops, dfun will give SPEC inst - returnSM emptyUDs - else - -- pprTrace "CallInst:Reqd\n" - -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)], - -- ppCat [ppPStr SLIT("CI"), ppCat (map (pprMaybeTy PprDebug) spec_tys), - -- ppCat (map (ppr PprDebug) dicts)]]) - (returnSM (singleCI new_id spec_tys dicts)) - - (True, Just (spec_id, tys_left, toss), _) - -> if maybeToBool (isConstMethodId_maybe spec_id) then - -- If we got a const method spec_id see if further spec required - -- NB: const method is top-level so spec_id will not be cloned - case record_spec spec_id tys_left of - (False, _, _) - -> -- pprTrace "CallInst:Exists\n" - -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)], - -- ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id, - -- ppr PprDebug (tys_left ++ drop toss dicts)]]) - (returnSM emptyUDs) - - (True, Nothing, spec_tys) - -> -- pprTrace "CallInst:Exists:Reqd\n" - -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)], - -- ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id, - -- ppr PprDebug (tys_left ++ drop toss dicts)], - -- ppCat [ppPStr SLIT("CI"), ppCat (map (pprMaybeTy PprDebug) spec_tys), - -- ppCat (map (ppr PprDebug) (drop toss dicts))]]) - (returnSM (singleCI spec_id spec_tys (drop toss dicts))) - - (True, Just (spec_spec_id, tys_left_left, toss_toss), _) - -> -- pprTrace "CallInst:Exists:Exists\n" - -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)], - -- ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id, - -- ppr PprDebug (tys_left ++ drop toss dicts)], - -- ppCat [ppPStr SLIT("->"), ppr PprDebug spec_spec_id, - -- ppr PprDebug (tys_left_left ++ drop (toss + toss_toss) dicts)]]) - (returnSM emptyUDs) - - else - -- pprTrace "CallInst:Exists\n" - -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)], - -- ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id, - -- ppr PprDebug (tys_left ++ drop toss dicts)]]) - (returnSM emptyUDs) - - -take_type_args (_:tyvars) class_tyvar_pairs (TyArg ty : args) - = case (take_type_args tyvars class_tyvar_pairs args) of - Nothing -> Nothing + where + (tyvars, class_tyvar_pairs) = getIdOverloading id + constrained_tyvars = map snd class_tyvar_pairs -- May contain dups + constraint_vec = [tyvar `elem` constrained_tyvars | tyvar <- tyvars] + + arg_res = take_type_args tyvars class_tyvar_pairs args + enough_args = maybeToBool arg_res + (Just (tys, dicts, rest_args)) = arg_res + + interesting_overloading = any (not . isTyVarTy) (catMaybes spec_tys) + spec_tys = specialiseCallTys constraint_vec tys + + ----------------- Rather a gruesome help-function --------------- + take_type_args (_:tyvars) (TyArg ty : args) + = case (take_type_args tyvars args) of + Nothing -> Nothing Just (tys, dicts, others) -> Just (ty:tys, dicts, others) -take_type_args (_:tyvars) class_tyvar_pairs [] = Nothing + take_type_args (_:tyvars) [] = Nothing -take_type_args [] class_tyvar_pairs args + take_type_args [] args = case (take_dict_args class_tyvar_pairs args) of Nothing -> Nothing Just (dicts, others) -> Just ([], dicts, others) -take_dict_args (_:class_tyvar_pairs) (dict : args) | isValArg dict + take_dict_args (_:class_tyvar_pairs) (dict : args) | isValArg dict = case (take_dict_args class_tyvar_pairs args) of Nothing -> Nothing Just (dicts, others) -> Just (dict:dicts, others) -take_dict_args (_:class_tyvar_pairs) [] = Nothing + take_dict_args (_:class_tyvar_pairs) args = Nothing -take_dict_args [] args = Just ([], args) + take_dict_args [] args = Just ([], args) \end{code} -\begin{code} -mkCall :: Id - -> [(CoreArg, UsageDetails, CoreExpr -> CoreExpr)] - -> SpecM CoreExpr - -mkCall new_id arg_infos = returnSM ( - -{- - | maybeToBool (isSuperDictSelId_maybe new_id) - && any isUnboxedType ty_args - -- No specialisations for super-dict selectors - -- Specialise unboxed calls to SuperDictSelIds by extracting - -- the super class dictionary directly form the super class - -- NB: This should be dead code since all uses of this dictionary should - -- have been specialised. We only do this to keep core-lint happy. - = let - Just (_, super_class) = isSuperDictSelId_maybe new_id - super_dict_id = case lookupClassInstAtSimpleType super_class (head ty_args) of - Nothing -> panic "Specialise:mkCall:SuperDictId" - Just id -> id - in - returnSM (False, Var super_dict_id) - - | otherwise - = case lookupSpecEnv (getIdSpecialisation new_id) ty_args of - Nothing -> checkUnspecOK new_id ty_args ( - returnSM (False, unspec_call) - ) - - Just spec_1_details@(spec_id_1, tys_left_1, dicts_to_toss_1) - -> let - -- It may be necessary to specialsie a constant method spec_id again - (spec_id, tys_left, dicts_to_toss) = - case (maybeToBool (isConstMethodId_maybe spec_id_1), - lookupSpecEnv (getIdSpecialisation spec_id_1) tys_left_1) of - (False, _ ) -> spec_1_details - (True, Nothing) -> spec_1_details - (True, Just (spec_id_2, tys_left_2, dicts_to_toss_2)) - -> (spec_id_2, tys_left_2, dicts_to_toss_1 + dicts_to_toss_2) - - args_left = toss_dicts dicts_to_toss val_args - in - checkSpecOK new_id ty_args spec_id tys_left ( - - -- The resulting spec_id may be a top-level unboxed value - -- This can arise for: - -- 1) constant method values - -- eq: class Num a where pi :: a - -- instance Num Double# where pi = 3.141# - -- 2) specilised overloaded values - -- eq: i1 :: Num a => a - -- i1 Int# d.Num.Int# ==> i1.Int# - -- These top level defns should have been lifted. - -- We must add code to unlift such a spec_id. - - if isUnboxedType (idType spec_id) then - ASSERT (null tys_left && null args_left) - if toplevelishId spec_id then - liftId spec_id `thenSM` \ (lift_spec_id, unlift_spec_id) -> - returnSM (True, bindUnlift lift_spec_id unlift_spec_id - (Var unlift_spec_id)) - else - pprPanic "Specialise:mkCall: unboxed spec_id not top-level ...\n" - (ppCat [ppr PprDebug new_id, - ppInterleave ppNil (map (pprParendGenType PprDebug) ty_args), - ppPStr SLIT("==>"), - ppr PprDebug spec_id]) - else - let - (vals_left, _, unlifts_left) = unzip3 args_left - applied_tys = mkTyApp (Var spec_id) tys_left - applied_vals = mkGenApp applied_tys vals_left - in - returnSM (True, applyBindUnlifts unlifts_left applied_vals) - ) - where - (tys_and_vals, _, unlifts) = unzip3 args - unspec_call = applyBindUnlifts unlifts (mkGenApp (Var new_id) tys_and_vals) - - - -- ty_args is the types at the front of the arg list - -- val_args is the rest of the arg-list - - (ty_args, val_args) = get args - where - get ((TyArg ty,_,_) : args) = (ty : tys, rest) where (tys,rest) = get args - get args = ([], args) - - - -- toss_dicts chucks away dict args, checking that they ain't types! - toss_dicts 0 args = args - toss_dicts n ((a,_,_) : args) - | isValArg a = toss_dicts (n-1) args - -\end{code} - -\begin{code} -checkUnspecOK :: Id -> [Type] -> a -> a -checkUnspecOK check_id tys - = if isLocallyDefined check_id && any isUnboxedType tys - then pprPanic "Specialise:checkUnspecOK: unboxed instance for local id not found\n" - (ppCat [ppr PprDebug check_id, - ppInterleave ppNil (map (pprParendGenType PprDebug) tys)]) - else id - -checkSpecOK :: Id -> [Type] -> Id -> [Type] -> a -> a -checkSpecOK check_id tys spec_id tys_left - = if any isUnboxedType tys_left - then pprPanic "Specialise:checkSpecOK: unboxed type args in specialised application\n" - (ppAboves [ppCat [ppr PprDebug check_id, - ppInterleave ppNil (map (pprParendGenType PprDebug) tys)], - ppCat [ppr PprDebug spec_id, - ppInterleave ppNil (map (pprParendGenType PprDebug) tys_left)]]) - else id --} -\end{code} \begin{code} mkTyConInstance :: Id @@ -2374,8 +2166,7 @@ type SpecM result -> UniqSupply -> result -initSM m uniqs - = m nullTyVarEnv nullIdEnv uniqs +initSM m uniqs = m nullTyVarEnv nullIdEnv uniqs returnSM :: a -> SpecM a thenSM :: SpecM a -> (a -> SpecM b) -> SpecM b @@ -2404,7 +2195,7 @@ newSpecIds :: [Id] -- The id of which to make a specialised version newSpecIds new_ids maybe_tys dicts_to_ignore tvenv idenv us = [ mkSpecId uniq id maybe_tys (spec_id_ty id) (selectIdInfoForSpecId id) - | (id,uniq) <- zipEqual "newSpecIds" new_ids uniqs ] + | (id,uniq) <- zipEqual "newSpecIds" new_ids uniqs ] where uniqs = getUniques (length new_ids) us spec_id_ty id = specialiseTy (idType id) maybe_tys dicts_to_ignore @@ -2592,3 +2383,124 @@ mapAndUnzip4SM f (x:xs) = f x `thenSM` \ (r1,r2,r3,r4) -> returnSM ((r1:rs1),(r2:rs2),(r3:rs3),(r4:rs4)) -} \end{code} + + + +===================== OLD CODE, scheduled for deletion ================= + +\begin{code} +{- +mkCall :: Id + -> [(CoreArg, UsageDetails, CoreExpr -> CoreExpr)] + -> SpecM CoreExpr + +mkCall new_id arg_infos = returnSM ( + + | maybeToBool (isSuperDictSelId_maybe new_id) + && any isUnboxedType ty_args + -- No specialisations for super-dict selectors + -- Specialise unboxed calls to SuperDictSelIds by extracting + -- the super class dictionary directly form the super class + -- NB: This should be dead code since all uses of this dictionary should + -- have been specialised. We only do this to keep core-lint happy. + = let + Just (_, super_class) = isSuperDictSelId_maybe new_id + super_dict_id = case lookupClassInstAtSimpleType super_class (head ty_args) of + Nothing -> panic "Specialise:mkCall:SuperDictId" + Just id -> id + in + returnSM (False, Var super_dict_id) + + | otherwise + = case lookupSpecEnv (getIdSpecialisation new_id) ty_args of + Nothing -> checkUnspecOK new_id ty_args ( + returnSM (False, unspec_call) + ) + + Just spec_1_details@(spec_id_1, tys_left_1, dicts_to_toss_1) + -> let + -- It may be necessary to specialsie a constant method spec_id again + (spec_id, tys_left, dicts_to_toss) = + case (maybeToBool (isConstMethodId_maybe spec_id_1), + lookupSpecEnv (getIdSpecialisation spec_id_1) tys_left_1) of + (False, _ ) -> spec_1_details + (True, Nothing) -> spec_1_details + (True, Just (spec_id_2, tys_left_2, dicts_to_toss_2)) + -> (spec_id_2, tys_left_2, dicts_to_toss_1 + dicts_to_toss_2) + + args_left = toss_dicts dicts_to_toss val_args + in + checkSpecOK new_id ty_args spec_id tys_left ( + + -- The resulting spec_id may be a top-level unboxed value + -- This can arise for: + -- 1) constant method values + -- eq: class Num a where pi :: a + -- instance Num Double# where pi = 3.141# + -- 2) specilised overloaded values + -- eq: i1 :: Num a => a + -- i1 Int# d.Num.Int# ==> i1.Int# + -- These top level defns should have been lifted. + -- We must add code to unlift such a spec_id. + + if isUnboxedType (idType spec_id) then + ASSERT (null tys_left && null args_left) + if toplevelishId spec_id then + liftId spec_id `thenSM` \ (lift_spec_id, unlift_spec_id) -> + returnSM (True, bindUnlift lift_spec_id unlift_spec_id + (Var unlift_spec_id)) + else + pprPanic "Specialise:mkCall: unboxed spec_id not top-level ...\n" + (ppCat [ppr PprDebug new_id, + ppInterleave ppNil (map (pprParendGenType PprDebug) ty_args), + ppPStr SLIT("==>"), + ppr PprDebug spec_id]) + else + let + (vals_left, _, unlifts_left) = unzip3 args_left + applied_tys = mkTyApp (Var spec_id) tys_left + applied_vals = mkGenApp applied_tys vals_left + in + returnSM (True, applyBindUnlifts unlifts_left applied_vals) + ) + where + (tys_and_vals, _, unlifts) = unzip3 args + unspec_call = applyBindUnlifts unlifts (mkGenApp (Var new_id) tys_and_vals) + + + -- ty_args is the types at the front of the arg list + -- val_args is the rest of the arg-list + + (ty_args, val_args) = get args + where + get ((TyArg ty,_,_) : args) = (ty : tys, rest) where (tys,rest) = get args + get args = ([], args) + + + -- toss_dicts chucks away dict args, checking that they ain't types! + toss_dicts 0 args = args + toss_dicts n ((a,_,_) : args) + | isValArg a = toss_dicts (n-1) args + +\end{code} + +\begin{code} +checkUnspecOK :: Id -> [Type] -> a -> a +checkUnspecOK check_id tys + = if isLocallyDefined check_id && any isUnboxedType tys + then pprPanic "Specialise:checkUnspecOK: unboxed instance for local id not found\n" + (ppCat [ppr PprDebug check_id, + ppInterleave ppNil (map (pprParendGenType PprDebug) tys)]) + else id + +checkSpecOK :: Id -> [Type] -> Id -> [Type] -> a -> a +checkSpecOK check_id tys spec_id tys_left + = if any isUnboxedType tys_left + then pprPanic "Specialise:checkSpecOK: unboxed type args in specialised application\n" + (ppAboves [ppCat [ppr PprDebug check_id, + ppInterleave ppNil (map (pprParendGenType PprDebug) tys)], + ppCat [ppr PprDebug spec_id, + ppInterleave ppNil (map (pprParendGenType PprDebug) tys_left)]]) + else id +-} +\end{code} diff --git a/ghc/compiler/typecheck/TcGenDeriv.lhs b/ghc/compiler/typecheck/TcGenDeriv.lhs index e589426..4587e18 100644 --- a/ghc/compiler/typecheck/TcGenDeriv.lhs +++ b/ghc/compiler/typecheck/TcGenDeriv.lhs @@ -366,6 +366,8 @@ we use both @con2tag_Foo@ and @tag2con_Foo@ functions, as well as a \begin{verbatim} instance ... Enum (Foo ...) where + toEnum i = tag2con_Foo i + enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo] -- or, really... @@ -390,11 +392,17 @@ For @enumFromTo@ and @enumFromThenTo@, we use the default methods. gen_Enum_binds :: TyCon -> RdrNameMonoBinds gen_Enum_binds tycon - = enum_from `AndMonoBinds` + = to_enum `AndMonoBinds` + enum_from `AndMonoBinds` enum_from_then `AndMonoBinds` from_enum where tycon_loc = getSrcLoc tycon + + to_enum + = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $ + mk_easy_App (tag2con_RDR tycon) [a_RDR] + enum_from = mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $ untag_Expr tycon [(a_RDR, ah_RDR)] $ diff --git a/ghc/compiler/utils/FastString.lhs b/ghc/compiler/utils/FastString.lhs index ab54af7..21f61fd 100644 --- a/ghc/compiler/utils/FastString.lhs +++ b/ghc/compiler/utils/FastString.lhs @@ -134,10 +134,10 @@ concatFS :: [FastString] -> FastString concatFS ls = mkFastString (concat (map (unpackFS) ls)) -- ToDo: do better headFS :: FastString -> Char -headFS (FastString _ l# ba#) = - if l# ># 0# then C# (indexCharArray# ba# 0#) else error "headFS: empty FS" -headFS (CharStr a# l#) = - if l# ># 0# then C# (indexCharOffAddr# a# 0#) else error "headFS: empty FS" +headFS f@(FastString _ l# ba#) = + if l# ># 0# then C# (indexCharArray# ba# 0#) else error ("headFS: empty FS: " ++ unpackFS f) +headFS f@(CharStr a# l#) = + if l# ># 0# then C# (indexCharOffAddr# a# 0#) else error ("headFS: empty FS: " ++ unpackFS f) tailFS :: FastString -> FastString tailFS (FastString _ l# ba#) = mkFastSubStringBA# ba# 1# (l# -# 1#) diff --git a/ghc/docs/Makefile b/ghc/docs/Makefile index 2f99b93..cf8be1f 100644 --- a/ghc/docs/Makefile +++ b/ghc/docs/Makefile @@ -6,6 +6,6 @@ include $(TOP)/mk/boilerplate.mk # export WAYS= -SUBDIRS = users_guide install_guide release_notes state_interface +SUBDIRS = users_guide include $(TOP)/mk/target.mk diff --git a/ghc/driver/ghc-asm.lprl b/ghc/driver/ghc-asm.lprl index f243433..89cc4b1 100644 --- a/ghc/driver/ghc-asm.lprl +++ b/ghc/driver/ghc-asm.lprl @@ -348,9 +348,20 @@ sub mangle_asm { # multi-line regexp matching: local($*) = 1; local($i, $c); + + &init_TARGET_STUFF(); &init_FUNNY_THINGS(); + # perl4 on alphas SEGVs when give ${foo} substitutions in patterns. + # To avoid them we declare some locals that allows to avoid using curlies. + local($TUS) = ${T_US}; + local($TPOSTLBL) = ${T_POST_LBL}; + local($TMOVEDIRVS) = ${T_MOVE_DIRVS}; + local($TPREAPP) = ${T_PRE_APP}; + local($TCOPYDIRVS) = ${T_COPY_DIRVS}; + local($TDOTWORD) = ${T_DOT_WORD}; + open(INASM, "< $in_asmf") || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n"); open(OUTASM,"> $out_asmf") @@ -374,10 +385,9 @@ sub mangle_asm { $i = 0; $chkcat[0] = 'misc'; $chk[0] = ''; while () { - next if $T_STABBY && /^\.stab.*${T_US}__stg_split_marker/o; + next if $T_STABBY && /^\.stab.*$TUS[@]?__stg_split_marker/o; next if $T_STABBY && /^\.stab.*ghc.*c_ID/; - next if /${T_PRE_APP}(NO_)?APP/o; - + next if /$TPREAPP(NO_)?APP/o; next if /^;/ && $TargetPlatform =~ /^hppa/; next if /(^$|^\t\.file\t|^ # )/ && $TargetPlatform =~ /^(mips|powerpc)-/; @@ -408,12 +418,12 @@ sub mangle_asm { $chkcat[$i] = 'literal'; $chksymb[$i] = $1; - } elsif ( /^${T_US}__stg_split_marker(\d+)${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?__stg_split_marker(\d+)$TPOSTLBL[@]?$/o ) { $chk[++$i] = $_; $chkcat[$i] = 'splitmarker'; $chksymb[$i] = $1; - } elsif ( /^${T_US}([A-Za-z0-9_]+)_info${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_info$TPOSTLBL[@]?$/o ) { $symb = $1; $chk[++$i] = $_; $chkcat[$i] = 'infotbl'; @@ -423,40 +433,40 @@ sub mangle_asm { $infochk{$symb} = $i; - } elsif ( /^${T_US}([A-Za-z0-9_]+)_entry${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_entry$TPOSTLBL[@]?$/o ) { $chk[++$i] = $_; $chkcat[$i] = 'slow'; $chksymb[$i] = $1; $slowchk{$1} = $i; - } elsif ( /^${T_US}([A-Za-z0-9_]+)_fast\d+${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_fast\d+$TPOSTLBL[@]?$/o ) { $chk[++$i] = $_; $chkcat[$i] = 'fast'; $chksymb[$i] = $1; $fastchk{$1} = $i; - } elsif ( /^${T_US}([A-Za-z0-9_]+)_closure${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_closure$TPOSTLBL[@]?$/o ) { $chk[++$i] = $_; $chkcat[$i] = 'closure'; $chksymb[$i] = $1; $closurechk{$1} = $i; - } elsif ( /^${T_US}ghc.*c_ID${T_POST_LBL}/o ) { + } elsif ( /^$TUS[@]?ghc.*c_ID$TPOSTLBL/o ) { $chk[++$i] = $_; $chkcat[$i] = 'consist'; - } elsif ( /^(${T_US}__gnu_compiled_c|gcc2_compiled\.)${T_POST_LBL}/o ) { + } elsif ( /^($TUS[@]?__gnu_compiled_c|gcc2_compiled\.)$TPOSTLBL/o ) { ; # toss it - } elsif ( /^${T_US}ErrorIO_call_count${T_POST_LBL}$/o # HACK!!!! - || /^${T_US}[A-Za-z0-9_]+\.\d+${T_POST_LBL}$/o - || /^${T_US}.*_CAT${T_POST_LBL}$/o # PROF: _entryname_CAT - || /^${T_US}CC_.*_struct${T_POST_LBL}$/o # PROF: _CC_ccident_struct - || /^${T_US}.*_done${T_POST_LBL}$/o # PROF: _module_done - || /^${T_US}_module_registered${T_POST_LBL}$/o # PROF: _module_registered + } elsif ( /^$TUS[@]?ErrorIO_call_count$TPOSTLBL[@]?$/o # HACK!!!! + || /^$TUS[A-Za-z0-9_]+\.\d+$TPOSTLBL[@]?$/o + || /^$TUS[@]?.*_CAT$TPOSTLBL[@]?$/o # PROF: _entryname_CAT + || /^$TUS[@]?CC_.*_struct$TPOSTLBL[@]?$/o # PROF: _CC_ccident_struct + || /^$TUS[@]?.*_done$TPOSTLBL[@]?$/o # PROF: _module_done + || /^$TUS[@]?_module_registered$TPOSTLBL[@]?$/o # PROF: _module_registered ) { $chk[++$i] = $_; $chkcat[$i] = 'data'; @@ -467,26 +477,26 @@ sub mangle_asm { $chkcat[$i] = 'bss'; $chksymb[$i] = $1; - } elsif ( /^${T_US}(ret_|djn_)/o ) { + } elsif ( /^$TUS[@]?(ret_|djn_)/o ) { $chk[++$i] = $_; $chkcat[$i] = 'misc'; $chksymb[$i] = ''; - } elsif ( /^${T_US}vtbl_([A-Za-z0-9_]+)${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?vtbl_([A-Za-z0-9_]+)$TPOSTLBL[@]?$/o ) { $chk[++$i] = $_; $chkcat[$i] = 'vector'; $chksymb[$i] = $1; $vectorchk{$1} = $i; - } elsif ( /^${T_US}([A-Za-z0-9_]+)DirectReturn${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)DirectReturn$TPOSTLBL[@]?$/o ) { $chk[++$i] = $_; $chkcat[$i] = 'direct'; $chksymb[$i] = $1; $directchk{$1} = $i; - } elsif ( /^${T_US}[A-Za-z0-9_]+_upd${T_POST_LBL}$/o ) { + } elsif ( /^$TUS[@]?[A-Za-z0-9_]+_upd$TPOSTLBL[@]?$/o ) { $chk[++$i] = $_; $chkcat[$i] = 'misc'; $chksymb[$i] = ''; @@ -506,7 +516,7 @@ sub mangle_asm { $chkcat[$i] = 'toss'; $chksymb[$i] = $1; - } elsif ( /^${T_US}[A-Za-z0-9_]/o + } elsif ( /^$TUS[@]?[A-Za-z0-9_]/o && ( $TargetPlatform !~ /^hppa/ # need to avoid local labels in this case || ! /^L\$\d+$/ ) && ( $TargetPlatform !~ /^powerpc/ # ditto @@ -515,9 +525,9 @@ sub mangle_asm { chop($thing = $_); print STDERR "Funny global thing?: $_" unless $KNOWN_FUNNY_THING{$thing} - || /^${T_US}_(PRIn|PRStart).*${T_POST_LBL}$/o # pointer reversal GC routines - || /^${T_US}CC_.*${T_POST_LBL}$/o # PROF: _CC_ccident - || /^${T_US}_reg.*${T_POST_LBL}$/o; # PROF: __reg + || /^$TUS[@]?_(PRIn|PRStart).*$TPOSTLBL[@]?$/o # pointer reversal GC routines + || /^$TUS[@]?CC_.*$TPOSTLBL$/o # PROF: _CC_ccident ([@]? is a silly hack (see above)) + || /^$TUS[@]?_reg.*$TPOSTLBL$/o; # PROF: __reg $chk[++$i] = $_; $chkcat[$i] = 'misc'; $chksymb[$i] = ''; @@ -644,7 +654,7 @@ sub mangle_asm { # On Alphas, the prologue mangling is done a little later (below) # toss all calls to __DISCARD__ - $c =~ s/^\t(call|jbsr|jal)\s+${T_US}__DISCARD__\n//go; + $c =~ s/^\t(call|jbsr|jal)\s+$TUS[@]?__DISCARD__\n//go; # MIPS: that may leave some gratuitous asm macros around # (no harm done; but we get rid of them to be tidier) @@ -667,16 +677,18 @@ sub mangle_asm { # pin a funny end-thing on (for easier matching): $c .= 'FUNNY#END#THING'; - while ( $c =~ /${T_MOVE_DIRVS}FUNNY#END#THING/o ) { + while ( $c =~ /$TMOVEDIRVS[@]?FUNNY#END#THING/o ) { # [@]? is a silly hack to avoid having to use curlies for T_PRE_APP + # (this SEGVs perl4 on alphas, you see) + $to_move = $1; if ( $i < ($numchks - 1) - && ( $to_move =~ /${T_COPY_DIRVS}/ + && ( $to_move =~ /$TCOPYDIRVS/ || ($TargetPlatform =~ /^hppa/ && $to_move =~ /align/ && $chkcat[$i+1] eq 'literal') )) { $chk[$i + 1] = $to_move . $chk[$i + 1]; # otherwise they're tossed } - $c =~ s/${T_MOVE_DIRVS}FUNNY#END#THING/FUNNY#END#THING/o; + $c =~ s/$TMOVEDIRVS[@]?FUNNY#END#THING/FUNNY#END#THING/o; # [@]? is a hack (see above) } if ( $TargetPlatform =~ /^alpha-/ && $c =~ /^\t\.ent\s+(\S+)/ ) { @@ -816,7 +828,7 @@ sub mangle_asm { # entry code will be put here! # paranoia - if ( $chk[$infochk{$symb}] =~ /${T_DOT_WORD}\s+([A-Za-z0-9_]+_entry)$/o + if ( $chk[$infochk{$symb}] =~ /$TDOTWORD[@]?\s+([A-Za-z0-9_]+_entry)$/o && $1 ne "${T_US}${symb}_entry" ) { print STDERR "!!! entry point???\n",$chk[$infochk{$symb}]; } @@ -856,7 +868,7 @@ sub mangle_asm { # references to fast-entry point. # (questionable re hppa and mips...) print STDERR "still has jump to fast entry point:\n$c" - if $c =~ /${T_US}${symb}_fast/; # NB: paranoia + if $c =~ /$TUS[@]?$symb[@]?_fast/; # NB: paranoia } print OUTASM $T_HDR_entry; @@ -1218,18 +1230,24 @@ sub rev_tbl { local($after) = ''; local(@lines) = split(/\n/, $tbl); local($i, $extra, $words_to_pad, $j); - - for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t${T_DOT_WORD}\s+/o; $i++) { + + # see comment in mangleAsm as to why this silliness is needed. + local($TDOTWORD) = ${T_DOT_WORD}; + local($TDOTGLOBAL) = ${T_DOT_GLOBAL}; + local($TUS) = ${T_US}; + local($TPOSTLBL) = ${T_POST_LBL}; + + for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t$TDOTWORD\s+/o; $i++) { $label .= $lines[$i] . "\n", - next if $lines[$i] =~ /^[A-Za-z0-9_]+_info${T_POST_LBL}$/o - || $lines[$i] =~ /${T_DOT_GLOBAL}/o - || $lines[$i] =~ /^${T_US}vtbl_\S+${T_POST_LBL}$/o; + next if $lines[$i] =~ /^[A-Za-z0-9_]+_info$TPOSTLBL[@]?$/o + || $lines[$i] =~ /$TDOTGLOBAL/o + || $lines[$i] =~ /^$TUS[@]?vtbl_\S+$TPOSTLBL[@]?$/o; $before .= $lines[$i] . "\n"; # otherwise... } if ( $TargetPlatform !~ /^hppa/ ) { - for ( ; $i <= $#lines && $lines[$i] =~ /^\t${T_DOT_WORD}\s+/o; $i++) { + for ( ; $i <= $#lines && $lines[$i] =~ /^\t$TDOTWORD\s+/o; $i++) { push(@words, $lines[$i]); } } else { # hppa weirdness @@ -1287,6 +1305,10 @@ sub mini_mangle_asm_i386 { &init_TARGET_STUFF(); + # see mangleAsm comment + local($TUS) = ${T_US}; + local($TPOSTLBL)=${T_POST_LBL}; + open(INASM, "< $in_asmf") || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n"); open(OUTASM,"> $out_asmf") @@ -1296,7 +1318,7 @@ sub mini_mangle_asm_i386 { print OUTASM; next unless - /^${T_US}(PerformGC|StackOverflow|Yield|PerformReschedule)_wrapper${T_POST_LBL}\n/o; + /^$TUS[@]?(PerformGC|StackOverflow|Yield|PerformReschedule)_wrapper$TPOSTLBL\n/o; print OUTASM "\tmovl \%esp, ${T_US}__temp_esp\n"; print OUTASM "\tmovl \%eax, ${T_US}__temp_eax\n"; } diff --git a/ghc/includes/StgMacros.lh b/ghc/includes/StgMacros.lh index 3732beb..56d6523 100644 --- a/ghc/includes/StgMacros.lh +++ b/ghc/includes/StgMacros.lh @@ -2094,7 +2094,7 @@ do { \ StorageMgrInfo.ForeignObjList = result; \ \ \ -/*fprintf(stderr,"DEBUG: ForeignObj(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n", \ + /*fprintf(stderr,"DEBUG: ForeignObj(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n", \ result, \ result[0],result[1], \ result[2],result[3]);*/ \ @@ -2105,6 +2105,8 @@ do { \ (r) = (P_) result; \ } while (0) +#define writeForeignObjZh(res,datum) ((PP_) ForeignObj_CLOSURE_DATA(res)) = ((P_)datum) + #else #define makeForeignObjZh(r, liveness, mptr, finalise) \ do { \ @@ -2113,6 +2115,13 @@ do { \ EXIT(EXIT_FAILURE); \ } while(0) +#define writeForeignObjZh(res,datum) \ +do { \ + fflush(stdout); \ + fprintf(stderr, "writeForeignObj#: no foreign object support.\n");\ + EXIT(EXIT_FAILURE); \ +} while(0) + #endif /* !PAR */ \end{code} diff --git a/ghc/lib/Makefile b/ghc/lib/Makefile index 6236c38..76e8dbf 100644 --- a/ghc/lib/Makefile +++ b/ghc/lib/Makefile @@ -4,7 +4,7 @@ # # Makefile for building the GHC Prelude libraries umpteen ways # -# $Id: Makefile,v 1.5 1997/03/14 05:30:36 sof Exp $ +# $Id: Makefile,v 1.6 1997/03/17 20:34:49 simonpj Exp $ # # ################################################################################# @@ -52,14 +52,15 @@ endif # per-module flags -ghc/PackedString_HC_OPTS = -monly-3-regs -required/Directory_HC_OPTS = -monly-3-regs -concurrent/Parallel_HC_OPTS = -fglasgow-exts +ghc/PackedString_HC_OPTS += -monly-3-regs +required/Directory_HC_OPTS += -monly-3-regs +concurrent/Parallel_HC_OPTS += -fglasgow-exts +required/Time_HC_OPTS += -monly-3-regs #----------------------------------------------------------------------------- # Dependency generation -SRC_MKDEPENDHS_OPTS += -irequired:ghc:hbc:glaExts:concurrent +SRC_MKDEPENDHS_OPTS += -irequired:ghc:hbc:glaExts:concurrent -I$(GHC_INCLUDE_DIR) #----------------------------------------------------------------------------- # Rules diff --git a/ghc/lib/cbits/stgio.h b/ghc/lib/cbits/stgio.h index 8c0d2cb..d6b9b02 100644 --- a/ghc/lib/cbits/stgio.h +++ b/ghc/lib/cbits/stgio.h @@ -59,6 +59,10 @@ StgInt getBufferMode PROTO((StgForeignObj)); /* getClockTime.lc */ StgInt getClockTime PROTO((StgByteArray, StgByteArray)); +StgAddr showTime PROTO((I_, StgByteArray, StgByteArray)); +StgAddr toClockSec PROTO((I_, I_, I_, I_, I_, I_, I_, StgByteArray)); +StgAddr toLocalTime PROTO((I_, StgByteArray, StgByteArray)); +StgAddr toUTCTime PROTO((I_, StgByteArray, StgByteArray)); /* getCPUTime.lc */ StgByteArray getCPUTime PROTO((StgByteArray)); diff --git a/ghc/lib/ghc/GHC.hi-boot b/ghc/lib/ghc/GHC.hi-boot index 884bba0..d751f95 100644 --- a/ghc/lib/ghc/GHC.hi-boot +++ b/ghc/lib/ghc/GHC.hi-boot @@ -210,6 +210,7 @@ indexAddrOffAddr# ForeignObj# makeForeignObj# + writeForeignObj# StablePtr# makeStablePtr# diff --git a/ghc/lib/ghc/IOBase.lhs b/ghc/lib/ghc/IOBase.lhs index 4a952f7..8f1ad25 100644 --- a/ghc/lib/ghc/IOBase.lhs +++ b/ghc/lib/ghc/IOBase.lhs @@ -399,11 +399,19 @@ type Handle = MutableVar RealWorld Handle__ data Handle__ = ErrorHandle IOError | ClosedHandle +#ifndef PAR | SemiClosedHandle ForeignObj (Addr, Int) | ReadHandle ForeignObj (Maybe BufferMode) Bool | WriteHandle ForeignObj (Maybe BufferMode) Bool | AppendHandle ForeignObj (Maybe BufferMode) Bool | ReadWriteHandle ForeignObj (Maybe BufferMode) Bool +#else + | SemiClosedHandle Addr (Addr, Int) + | ReadHandle Addr (Maybe BufferMode) Bool + | WriteHandle Addr (Maybe BufferMode) Bool + | AppendHandle Addr (Maybe BufferMode) Bool + | ReadWriteHandle Addr (Maybe BufferMode) Bool +#endif -- Standard Instances as defined by the Report.. diff --git a/ghc/lib/ghc/IOHandle.lhs b/ghc/lib/ghc/IOHandle.lhs index 50e1300..a3f64ce 100644 --- a/ghc/lib/ghc/IOHandle.lhs +++ b/ghc/lib/ghc/IOHandle.lhs @@ -23,7 +23,7 @@ import IOBase import PrelTup import PrelBase import GHC -import Foreign ( makeForeignObj ) +import Foreign ( makeForeignObj, writeForeignObj ) import PrelList (span) #if defined(__CONCURRENT_HASKELL__) import ConcBase @@ -68,7 +68,11 @@ writeHandle h v = stToIO (writeVar h v) %********************************************************* \begin{code} +#ifndef PAR filePtr :: Handle__ -> ForeignObj +#else +filePtr :: Handle__ -> Addr +#endif filePtr (SemiClosedHandle fp _) = fp filePtr (ReadHandle fp _ _) = fp filePtr (WriteHandle fp _ _) = fp @@ -116,8 +120,13 @@ stdin = unsafePerformPrimIO ( _ccall_ getLock (``stdin''::Addr) 0 >>= \ rc -> (case rc of 0 -> new_handle ClosedHandle - 1 -> makeForeignObj (``stdin''::Addr) (``&freeStdChannel''::Addr) >>= \ fp -> + 1 -> +#ifndef PAR + makeForeignObj (``stdin''::Addr) (``&freeStdChannel''::Addr) >>= \ fp -> new_handle (ReadHandle fp Nothing False) +#else + new_handle (ReadHandle ``stdin'' Nothing False) +#endif _ -> constructError "stdin" >>= \ ioError -> new_handle (ErrorHandle ioError) ) >>= \ handle -> @@ -130,8 +139,13 @@ stdout = unsafePerformPrimIO ( _ccall_ getLock (``stdout''::Addr) 1 >>= \ rc -> (case rc of 0 -> new_handle ClosedHandle - 1 -> makeForeignObj (``stdout''::Addr) (``&freeStdChannel''::Addr) >>= \ fp -> + 1 -> +#ifndef PAR + makeForeignObj (``stdout''::Addr) (``&freeStdChannel''::Addr) >>= \ fp -> new_handle (WriteHandle fp Nothing False) +#else + new_handle (WriteHandle ``stdout'' Nothing False) +#endif _ -> constructError "stdout" >>= \ ioError -> new_handle (ErrorHandle ioError) ) >>= \ handle -> @@ -144,8 +158,13 @@ stderr = unsafePerformPrimIO ( _ccall_ getLock (``stderr''::Addr) 1 >>= \ rc -> (case rc of 0 -> new_handle ClosedHandle - 1 -> makeForeignObj (``stderr''::Addr) (``&freeStdChannel''::Addr) >>= \ fp -> + 1 -> +#ifndef PAR + makeForeignObj (``stderr''::Addr) (``&freeStdChannel''::Addr) >>= \ fp -> new_handle (WriteHandle fp (Just NoBuffering) False) +#else + new_handle (WriteHandle ``stderr'' (Just NoBuffering) False) +#endif _ -> constructError "stderr" >>= \ ioError -> new_handle (ErrorHandle ioError) ) >>= \ handle -> @@ -170,8 +189,12 @@ openFile :: FilePath -> IOMode -> IO Handle openFile f m = stToIO (_ccall_ openFile f m') >>= \ ptr -> if ptr /= ``NULL'' then - stToIO (makeForeignObj ptr ((``&freeFile'')::Addr)) >>= \ fp -> +#ifndef PAR + makeForeignObj ptr ((``&freeFile'')::Addr) `thenIO_Prim` \ fp -> newHandle (htype fp Nothing False) +#else + newHandle (htype ptr Nothing False) +#endif else stToIO (constructError "openFile") >>= \ ioError@(IOError hn iot msg) -> let @@ -226,11 +249,12 @@ hClose :: Handle -> IO () hClose handle = readHandle handle >>= \ htype -> - writeHandle handle ClosedHandle >> case htype of ErrorHandle ioError -> + writeHandle handle htype >> fail ioError ClosedHandle -> + writeHandle handle htype >> ioe_closedHandle handle SemiClosedHandle fp (buf,_) -> (if buf /= ``NULL'' then @@ -245,19 +269,30 @@ hClose handle = has been performed, the ForeignObj embedded in the Handle is still lying around in the heap, so care is taken to avoid closing the file object when the ForeignObj - is finalised. (see freeFile()) -} + is finalised. -} if rc == 0 then - return () +#ifndef PAR + -- Mark the foreign object data value as gone to the finaliser (freeFile()) + writeForeignObj fp ``NULL'' `thenIO_Prim` \ () -> +#endif + writeHandle handle ClosedHandle else + writeHandle handle htype >> constructErrorAndFail "hClose" else - return () + writeHandle handle htype other -> - _ccall_ closeFile (filePtr other) `thenIO_Prim` \ rc -> + let fp = filePtr other in + _ccall_ closeFile fp `thenIO_Prim` \ rc -> if rc == 0 then - return () +#ifndef PAR + -- Mark the foreign object data + writeForeignObj fp ``NULL'' `thenIO_Prim` \ () -> +#endif + writeHandle handle ClosedHandle else + writeHandle handle htype >> constructErrorAndFail "hClose" \end{code} @@ -427,7 +462,11 @@ hSetBuffering handle mode = BlockBuffering Nothing -> -2 BlockBuffering (Just n) -> n +#ifndef PAR hcon :: Handle__ -> (ForeignObj -> (Maybe BufferMode) -> Bool -> Handle__) +#else + hcon :: Handle__ -> (Addr -> (Maybe BufferMode) -> Bool -> Handle__) +#endif hcon (ReadHandle _ _ _) = ReadHandle hcon (WriteHandle _ _ _) = WriteHandle hcon (AppendHandle _ _ _) = AppendHandle diff --git a/ghc/lib/glaExts/Foreign.lhs b/ghc/lib/glaExts/Foreign.lhs index 8273434..81abc4f 100644 --- a/ghc/lib/glaExts/Foreign.lhs +++ b/ghc/lib/glaExts/Foreign.lhs @@ -79,12 +79,21 @@ instance CReturnable () -- Why, exactly? instance CCallable ForeignObj instance CCallable ForeignObj# -eqForeignObj :: ForeignObj -> ForeignObj -> Bool -makeForeignObj :: Addr -> Addr -> PrimIO ForeignObj +eqForeignObj :: ForeignObj -> ForeignObj -> Bool +makeForeignObj :: Addr -> Addr -> PrimIO ForeignObj +writeForeignObj :: ForeignObj -> Addr -> PrimIO () -makeForeignObj (A# obj) (A# finaliser) = ST $ \ (S# s#) -> +{- derived op - attaching a free() finaliser to a malloc() allocated reference. -} +makeMallocPtr :: Addr -> PrimIO ForeignObj + +makeForeignObj (A# obj) (A# finaliser) = ST ( \ (S# s#) -> case makeForeignObj# obj finaliser s# of - StateAndForeignObj# s1# fo# -> (ForeignObj fo#, S# s1#) + StateAndForeignObj# s1# fo# -> (ForeignObj fo#, S# s1#)) + +writeForeignObj (ForeignObj fo#) (A# datum#) = ST ( \ (S# s#) -> + case writeForeignObj# fo# datum# s# of { s1# -> ((), S# s1#) } ) + +makeMallocPtr a = makeForeignObj a (``&free''::Addr) eqForeignObj mp1 mp2 = unsafePerformPrimIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int) diff --git a/ghc/lib/required/Directory.lhs b/ghc/lib/required/Directory.lhs index e9f70e9..d7fdf7d 100644 --- a/ghc/lib/required/Directory.lhs +++ b/ghc/lib/required/Directory.lhs @@ -1,8 +1,7 @@ % % (c) The AQUA Project, Glasgow University, 1994-1997 % - -\section[Directory]{Module @Directory@} +\section[Directory]{Directory interface} A directory contains a series of entries, each of which is a named reference to a file system object (file, directory etc.). Some @@ -18,23 +17,36 @@ some operating systems, it may also be possible to have paths which are relative to the current directory. \begin{code} -module Directory ( --- Permissions(Permissions), - createDirectory, removeDirectory, removeFile, - renameDirectory, renameFile, getDirectoryContents, - getCurrentDirectory, setCurrentDirectory -{- - ,doesFileExist, doesDirectoryExist, - getPermissions, setPermissions, +{-# OPTIONS -#include #-} +module Directory + ( + Permissions(Permissions), + + createDirectory, + removeDirectory, + renameDirectory, + getDirectoryContents, + getCurrentDirectory, + setCurrentDirectory, + + removeFile, + renameFile, + + doesFileExist, + doesDirectoryExist, + getPermissions, + setPermissions, getModificationTime --} - ) where + ) where -import Prelude +import PrelBase import Foreign import IOBase -import STBase ( PrimIO ) -import PackedString ( packCBytesST, unpackPS ) +import STBase +import ArrBase +import PackedString ( packCBytesST, unpackPS, psToByteArrayST ) +import Time ( ClockTime(..) ) + \end{code} %********************************************************* @@ -52,6 +64,11 @@ renameFile :: FilePath -> FilePath -> IO () getDirectoryContents :: FilePath -> IO [FilePath] getCurrentDirectory :: IO FilePath setCurrentDirectory :: FilePath -> IO () +doesFileExist :: FilePath -> IO Bool +doesDirectoryExist :: FilePath -> IO Bool +getPermissions :: FilePath -> IO Permissions +setPermissions :: FilePath -> Permissions -> IO () +getModificationTime :: FilePath -> IO ClockTime \end{code} @@ -61,8 +78,9 @@ setCurrentDirectory :: FilePath -> IO () %* * %********************************************************* -The @Permissions@ type is used to record whether certain operations are permissible on a -file/directory: +The @Permissions@ type is used to record whether certain +operations are permissible on a file/directory: +[to whom? - owner/group/world - the Report don't say much] \begin{code} data Permissions @@ -70,7 +88,6 @@ data Permissions readable, writeable, executable, searchable :: Bool } deriving (Eq, Ord, Read, Show) - \end{code} %********************************************************* @@ -410,25 +427,26 @@ setCurrentDirectory path = \begin{code} -{- -doesFileExist :: FilePath -> IO Bool +--doesFileExist :: FilePath -> IO Bool doesFileExist name = psToByteArrayST name `thenIO_Prim` \ path -> _ccall_ access path (``F_OK''::Int) `thenIO_Prim` \ rc -> return (rc == 0) -doesDirectoryExist :: FilePath -> IO Bool -doesDirectoryExist name = - (getFileStatus >>= isDirectory) `catch` (\ _ -> return False) +--doesDirectoryExist :: FilePath -> IO Bool +doesDirectoryExist name = + (getFileStatus name >>= \ st -> return (isDirectory st)) + `catch` + (\ _ -> return False) -getModificationTime :: FilePath -> IO Bool +--getModificationTime :: FilePath -> IO ClockTime getModificationTime name = - getFileStatus >>= \ st -> - return (modificationTime st) + getFileStatus name >>= \ st -> + modificationTime st -getPermissions :: FilePath -> IO Permissions +--getPermissions :: FilePath -> IO Permissions getPermissions name = - getFileStatus >>= \ st -> + getFileStatus name >>= \ st -> let fm = fileMode st isect v = intersectFileMode v fm == v @@ -441,5 +459,99 @@ getPermissions name = searchable = not (isRegularFile st) && isect ownerExecuteMode } ) --} + +--setPermissions :: FilePath -> Permissions -> IO () +setPermissions name (Permissions r w e s) = + let + read# = case (if r then ownerReadMode else ``0'') of { W# x# -> x# } + write# = case (if w then ownerWriteMode else ``0'') of { W# x# -> x# } + exec# = case (if e || s then ownerExecuteMode else ``0'') of { W# x# -> x# } + + mode = I# (word2Int# (read# `or#` write# `or#` exec#)) + in + psToByteArrayST name `thenIO_Prim` \ path -> + _ccall_ chmod path mode `thenIO_Prim` \ rc -> + if rc == 0 then + return () + else + fail (IOError Nothing SystemError "Directory.setPermissions") + +\end{code} + + +(Sigh)..copied from Posix.Files to avoid dep. on posix library + +\begin{code} +type FileStatus = ByteArray Int + +getFileStatus :: FilePath -> IO FileStatus +getFileStatus name = + psToByteArrayST name `thenIO_Prim` \ path -> + newCharArray (0,``sizeof(struct stat)'') `thenIO_Prim` \ bytes -> + _casm_ ``%r = stat(%0,(struct stat *)%1);'' path bytes + `thenIO_Prim` \ rc -> + if rc == 0 then + unsafeFreezeByteArray bytes `thenIO_Prim` \ stat -> + return stat + else + fail (IOError Nothing SystemError "Directory.getFileStatus") + +modificationTime :: FileStatus -> IO ClockTime +modificationTime stat = + malloc1 `thenIO_Prim` \ i1 -> + _casm_ ``((unsigned long *)%1)[0] = ((struct stat *)%0)->st_mtime;'' stat i1 `thenIO_Prim` \ () -> + cvtUnsigned i1 `thenIO_Prim` \ secs -> + return (TOD secs 0) + where + malloc1 = ST $ \ (S# s#) -> + case newIntArray# 1# s# of + StateAndMutableByteArray# s2# barr# -> (MutableByteArray bnds barr#, S# s2#) + + bnds = (0,1) + -- The C routine fills in an unsigned word. We don't have `unsigned2Integer#,' + -- so we freeze the data bits and use them for an MP_INT structure. Note that + -- zero is still handled specially, although (J# 1# 1# (ptr to 0#)) is probably + -- acceptable to gmp. + + cvtUnsigned (MutableByteArray _ arr#) = ST $ \ (S# s#) -> + case readIntArray# arr# 0# s# of + StateAndInt# s2# r# -> + if r# ==# 0# then + (0, S# s2#) + else + case unsafeFreezeByteArray# arr# s2# of + StateAndByteArray# s3# frozen# -> (J# 1# 1# frozen#, S# s3#) + +isDirectory :: FileStatus -> Bool +isDirectory stat = unsafePerformPrimIO $ + _casm_ ``%r = S_ISDIR(((struct stat *)%0)->st_mode);'' stat >>= \ rc -> + return (rc /= 0) + +isRegularFile :: FileStatus -> Bool +isRegularFile stat = unsafePerformPrimIO $ + _casm_ ``%r = S_ISREG(((struct stat *)%0)->st_mode);'' stat >>= \ rc -> + return (rc /= 0) + + +\end{code} + +\begin{code} +type FileMode = Word +ownerReadMode :: FileMode +ownerReadMode = ``S_IRUSR'' + +ownerWriteMode :: FileMode +ownerWriteMode = ``S_IWUSR'' + +ownerExecuteMode :: FileMode +ownerExecuteMode = ``S_IXUSR'' + +intersectFileMode :: FileMode -> FileMode -> FileMode +intersectFileMode (W# m1#) (W# m2#) = W# (m1# `and#` m2#) + +fileMode :: FileStatus -> FileMode +fileMode stat = unsafePerformPrimIO $ + _casm_ ``%r = ((struct stat *)%0)->st_mode;'' stat >>= \ mode -> + return mode + \end{code} diff --git a/ghc/lib/required/IO.lhs b/ghc/lib/required/IO.lhs index 34d5a33..c727c00 100644 --- a/ghc/lib/required/IO.lhs +++ b/ghc/lib/required/IO.lhs @@ -39,7 +39,7 @@ import IOHandle -- much of the real stuff is in here import PackedString ( nilPS, packCBytesST, unpackPS ) import PrelBase import GHC -import Foreign ( makeForeignObj ) +import Foreign ( makeForeignObj, writeForeignObj ) \end{code} %********************************************************* @@ -289,11 +289,14 @@ lazyReadBlock handle = then return nilPS else packCBytesST bytes buf) >>= \ some -> if bytes < 0 then - makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp -> - ioToST (writeHandle handle (SemiClosedHandle null_fp (``NULL'', 0))) - >> _ccall_ free buf >>= \ () -> _ccall_ closeFile fp >> +#ifndef PAR + writeForeignObj fp ``NULL'' >> + ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >> +#else + ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >> +#endif returnPrimIO (unpackPS some) else ioToST (writeHandle handle htype) >> @@ -314,11 +317,14 @@ lazyReadLine handle = then return nilPS else packCBytesST bytes buf) >>= \ some -> if bytes < 0 then - makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp -> - ioToST (writeHandle handle (SemiClosedHandle null_fp (``NULL'', 0))) - >> _ccall_ free buf >>= \ () -> _ccall_ closeFile fp >> +#ifndef PAR + writeForeignObj fp ``NULL'' >> + ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >> +#else + ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >> +#endif returnPrimIO (unpackPS some) else ioToST (writeHandle handle htype) >> @@ -336,10 +342,13 @@ lazyReadChar handle = SemiClosedHandle fp buf_info -> _ccall_ readChar fp >>= \ char -> if char == ``EOF'' then - makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp -> - ioToST (writeHandle handle (SemiClosedHandle null_fp buf_info)) - >> _ccall_ closeFile fp >> +#ifndef PAR + writeForeignObj fp ``NULL'' >> + ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >> +#else + ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >> +#endif returnPrimIO "" else ioToST (writeHandle handle htype) >> @@ -425,10 +434,18 @@ hPutStr handle str = else constructErrorAndFail "hPutStr" where +#ifndef PAR writeLines :: ForeignObj -> String -> PrimIO Bool +#else + writeLines :: Addr -> String -> PrimIO Bool +#endif writeLines = writeChunks ``BUFSIZ'' True +#ifndef PAR writeBlocks :: ForeignObj -> Int -> String -> PrimIO Bool +#else + writeBlocks :: Addr -> Int -> String -> PrimIO Bool +#endif writeBlocks fp size s = writeChunks size False fp s {- @@ -443,8 +460,11 @@ hPutStr handle str = a whole lot quicker. -- SOF 3/96 -} +#ifndef PAR writeChunks :: Int -> Bool -> ForeignObj -> String -> PrimIO Bool - +#else + writeChunks :: Int -> Bool -> Addr -> String -> PrimIO Bool +#endif writeChunks (I# bufLen) chopOnNewLine fp s = newCharArray (0,I# bufLen) >>= \ arr@(MutableByteArray _ arr#) -> let @@ -478,7 +498,11 @@ hPutStr handle str = in shoveString 0# s +#ifndef PAR writeChars :: ForeignObj -> String -> PrimIO Bool +#else + writeChars :: Addr -> String -> PrimIO Bool +#endif writeChars fp "" = returnPrimIO True writeChars fp (c:cs) = _ccall_ filePutc fp (ord c) >>= \ rc -> diff --git a/ghc/lib/required/Time.lhs b/ghc/lib/required/Time.lhs index 881166d..0c172e9 100644 --- a/ghc/lib/required/Time.lhs +++ b/ghc/lib/required/Time.lhs @@ -9,6 +9,8 @@ clock times, including timezone information (i.e, the functionality of its use of Coordinated Universal Time (UTC). \begin{code} +{-# OPTIONS -#include "cbits/timezone.h" -#include "cbits/stgio.h" #-} + module Time ( CalendarTime(..), @@ -16,20 +18,23 @@ module Time Day, CalendarTime(CalendarTime), TimeDiff(TimeDiff), - ClockTime, + ClockTime(..), -- non-standard, lib. report gives this as abstract getClockTime, addToClockTime, diffClockTimes, toCalendarTime, toUTCTime, toClockTime, - calendarToTimeString, formatCalendarTime + calendarTimeToString, formatCalendarTime ) where import PrelBase import ST -import IOBase ( IOError(..), constructErrorAndFail ) +import IOBase import ArrBase import STBase - +import ST +import Ix +import Char (intToDigit) import PackedString (unpackPS, packCBytesST) -import PosixUtil (allocWords, allocChars) +import Locale + \end{code} One way to partition and give name to chunks of a year and a week: @@ -53,8 +58,7 @@ Clock times may be compared, converted to strings, or converted to an external calendar time @CalendarTime@. \begin{code} -data ClockTime = TOD Integer Integer - deriving (Eq, Ord) +data ClockTime = TOD Integer Integer deriving (Eq, Ord) \end{code} When a @ClockTime@ is shown, it is converted to a string of the form @@ -244,7 +248,7 @@ toCalendarTime (TOD sec@(J# a# s# d#) psec) = unsafePerformPrimIO $ _ccall_ strlen zone >>= \ len -> packCBytesST len zone >>= \ tzname -> returnPrimIO (CalendarTime (1900+year) mon mday hour min sec psec - wday yday (unpackPS tzname) tz (isdst /= 0)) + (toEnum wday) yday (unpackPS tzname) tz (isdst /= 0)) toUTCTime :: ClockTime -> CalendarTime toUTCTime (TOD sec@(J# a# s# d#) psec) = unsafePerformPrimIO ( @@ -265,7 +269,7 @@ toUTCTime (TOD sec@(J# a# s# d#) psec) = unsafePerformPrimIO ( _casm_ ``%r = ((struct tm *)%0)->tm_wday;'' tm >>= \ wday -> _casm_ ``%r = ((struct tm *)%0)->tm_yday;'' tm >>= \ yday -> returnPrimIO (CalendarTime (1900+year) mon mday hour min sec psec - wday yday "UTC" 0 False) + (toEnum wday) yday "UTC" 0 False) ) toClockTime :: CalendarTime -> ClockTime @@ -287,79 +291,93 @@ toClockTime (CalendarTime year mon mday hour min sec psec wday yday tzname tz is bottom :: (Int,Int) bottom = error "Time.bottom" + + +-- (copied from PosixUtil, for now) +-- Allocate a mutable array of characters with no indices. + +allocChars :: Int -> ST s (MutableByteArray s ()) +allocChars (I# size#) = ST $ \ (S# s#) -> + case newCharArray# size# s# of + StateAndMutableByteArray# s2# barr# -> (MutableByteArray bot barr#, S# s2#) + where + bot = error "Time.allocChars" + +-- Allocate a mutable array of words with no indices + +allocWords :: Int -> ST s (MutableByteArray s ()) +allocWords (I# size#) = ST $ \ (S# s#) -> + case newIntArray# size# s# of + StateAndMutableByteArray# s2# barr# -> (MutableByteArray bot barr#, S# s2#) + where + bot = error "Time.allocWords" + \end{code} \begin{code} -calendarTimeToString :: CalendarTime -> String -calendarTimeToString  =  formatCalendarTime defaultTimeLocale "%c" - -formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String -formatCalendarTime l  - fmt  - ct@(CalendarTime  - year mon  - day hour  - min sec  - sdec  -                        wday yday tzname _ _) - = doFmt fmt -  where  - doFmt ('%':c:cs) = decode c ++ doFmt cs -   doFmt (c:cs) = c : doFmt cs -   doFmt "" = "" - -   to12 h = let h' = h `mod` 12 in if h == 0 then 12 else h - -   decode 'A' = fst (wdays l  !! fromEnum wday) -   decode 'a' = snd (wdays l  !! fromEnum wday) -   decode 'B' = fst (months l !! fromEnum mon) -   decode 'b' = snd (months l !! fromEnum mon) -   decode 'h' = snd (months l !! fromEnum mon) -   decode 'C' = show2 (year `quot` 100) -   decode 'c' = doFmt (dateTimeFmt l) -   decode 'D' = doFmt "%m/%d/%y" -   decode 'd' = show2 day -   decode 'e' = show2' day -   decode 'H' = show2 hour -   decode 'I' = show2 (to12 hour) -   decode 'j' = show3 yday -   decode 'k' = show2' hour -   decode 'l' = show2' (to12 hour) -   decode 'M' = show2 min -   decode 'm' = show2 (fromEnum mon+1) -   decode 'n' = "\n" -   decode 'p' = (if hour < 12 then fst else snd) (amPm l) -   decode 'R' = doFmt "%H:%M" -   decode 'r' = doFmt (time12Fmt l) -   decode 'T' = doFmt "%H:%M:%S" -   decode 't' = "\t" -   decode 'S' = show2 sec -   decode 's' = show2 sec -- Implementation-dependent, sez the lib doc.. -   decode 'U' = show2 ((yday + 7 - fromEnum wday) `div` 7) -   decode 'u' = show (let n = fromEnum wday in if n == 0 then 7 else n) -   decode 'V' =  -    let (week, days) =  -          (yday + 7 - if fromEnum wday > 0 then  -                         fromEnum wday - 1 else 6) `divMod` 7 -    in   - show2 (if  days >= 4  - then week+1  -           else if week == 0 then 53 else week) -   decode 'W' =  -    show2 ((yday + 7 - if fromEnum wday > 0 then  -                          fromEnum wday - 1 else 6) `div` 7) -   decode 'w' = show (fromEnum wday) -   decode 'X' = doFmt (timeFmt l) -   decode 'x' = doFmt (dateFmt l) -   decode 'Y' = show year -   decode 'y' = show2 (year `rem` 100) -   decode 'Z' = tzname -   decode '%' = "%" -   decode c   = [c] - -show2, show2', show3 :: Int -> String -show2 x = [intToDigit (x `quot` 10), intToDigit (x `rem` 10)] -show2' x = if x < 10 then [ ' ', intToDigit x] else show2 x -show3 x = intToDigit (x `quot` 100) : show2 (x `rem` 100) - +calendarTimeToString :: CalendarTime -> String +calendarTimeToString = formatCalendarTime defaultTimeLocale "%c" + +formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String +formatCalendarTime l fmt ct@(CalendarTime year mon day hour min sec sdec + wday yday tzname _ _) = + doFmt fmt + where doFmt ('%':c:cs) = decode c ++ doFmt cs + doFmt (c:cs) = c : doFmt cs + doFmt "" = "" + to12 h = let h' = h `mod` 12 in if h == 0 then 12 else h + decode 'A' = fst (wDays l !! fromEnum wday) + decode 'a' = snd (wDays l !! fromEnum wday) + decode 'B' = fst (months l !! fromEnum mon) + decode 'b' = snd (months l !! fromEnum mon) + decode 'h' = snd (months l !! fromEnum mon) + decode 'C' = show2 (year `quot` 100) + decode 'c' = doFmt (dateTimeFmt l) + decode 'D' = doFmt "%m/%d/%y" + decode 'd' = show2 day + decode 'e' = show2' day + decode 'H' = show2 hour + decode 'I' = show2 (to12 hour) + decode 'j' = show3 yday + decode 'k' = show2' hour + decode 'l' = show2' (to12 hour) + decode 'M' = show2 min + decode 'm' = show2 (fromEnum mon+1) + decode 'n' = "\n" + decode 'p' = (if hour < 12 then fst else snd) (amPm l) + decode 'R' = doFmt "%H:%M" + decode 'r' = doFmt (time12Fmt l) + decode 'T' = doFmt "%H:%M:%S" + decode 't' = "\t" + decode 'S' = show2 sec + decode 's' = show2 sec -- Implementation-dependent, sez the lib doc.. + decode 'U' = show2 ((yday + 7 - fromEnum wday) `div` 7) + decode 'u' = show (let n = fromEnum wday in + if n == 0 then 7 else n) + decode 'V' = + let (week, days) = + (yday + 7 - if fromEnum wday > 0 then + fromEnum wday - 1 else 6) `divMod` 7 + in show2 (if days >= 4 then + week+1 + else if week == 0 then 53 else week) + + decode 'W' = + show2 ((yday + 7 - if fromEnum wday > 0 then + fromEnum wday - 1 else 6) `div` 7) + decode 'w' = show (fromEnum wday) + decode 'X' = doFmt (timeFmt l) + decode 'x' = doFmt (dateFmt l) + decode 'Y' = show year + decode 'y' = show2 (year `rem` 100) + decode 'Z' = tzname + decode '%' = "%" + decode c = [c] + +show2, show2', show3 :: Int -> String +show2 x = [intToDigit (x `quot` 10), intToDigit (x `rem` 10)] + +show2' x = if x < 10 then [ ' ', intToDigit x] else show2 x + +show3 x = intToDigit (x `quot` 100) : show2 (x `rem` 100) \end{code} diff --git a/ghc/mk/boilerplate.mk b/ghc/mk/boilerplate.mk index 96782a0..08e36c9 100644 --- a/ghc/mk/boilerplate.mk +++ b/ghc/mk/boilerplate.mk @@ -24,11 +24,9 @@ TOP:=$(GHC_TOP) # ----------------------------------------------------------------- # Everything after this point # augments or overrides previously set variables. -# (these files are optional, so `make' won't fret if -# cannot get to them). # ----------------------------------------------------------------- --include $(TOP)/mk/paths.mk --include $(TOP)/mk/opts.mk +include $(TOP)/mk/paths.mk +include $(TOP)/mk/opts.mk include $(TOP)/mk/suffix.mk diff --git a/ghc/mk/paths.mk b/ghc/mk/paths.mk index d7b30e7..635956a 100644 --- a/ghc/mk/paths.mk +++ b/ghc/mk/paths.mk @@ -10,9 +10,13 @@ HaskellCompilerType = $(WithGhcHcType) # What ways to build the RTS+libs WAYS=$(GhcLibWays) +GCap=-optc-DGCap +#GC2s=-optc-DGC2s +#GC1s=-optc-DGC1s MKDEPENDHSSRC = $(GHC_UTILS_DIR)/mkdependHS UNLIT = $(GHC_UNLIT_DIR)/unlit +GHC_UNLIT = $(GHC_UNLIT_DIR)/unlit GHC_UNLIT_DIR = $(GHC_UTILS_DIR)/unlit #----------------------------------------------------------------------------- @@ -29,10 +33,10 @@ endif # Ugen ifdef UseInstalledUtils -UGEN = ugen +UGEN = ugen else UGEN = $(UGEN_DIR)/ugen -UGENSRC = $(GHC_UTILS_DIR)/ugen +UGEN_DIR = $(GHC_UTILS_DIR)/ugen endif #----------------------------------------------------------------------------- diff --git a/ghc/runtime/Makefile b/ghc/runtime/Makefile index ff991b0..b5713a4 100644 --- a/ghc/runtime/Makefile +++ b/ghc/runtime/Makefile @@ -1,5 +1,5 @@ #----------------------------------------------------------------------------- -# $Id: Makefile,v 1.4 1997/03/14 05:11:52 sof Exp $ +# $Id: Makefile,v 1.5 1997/03/17 20:34:59 simonpj Exp $ # This is the Makefile for the runtime-system stuff. # This stuff is written in C (and cannot be written in Haskell). @@ -159,9 +159,9 @@ LIBOBJS = $(patsubst %.lc,%.$(way_)o,$(SRCS_RTS_LC)) \ # # dependencies # -SRC_HC_OPTS += -I$(GHC_INCLUDE_DIR) -O -optc-DIN_GHC_RTS=1 -I$(GHC_RUNTIME_DIR)/storage +SRC_HC_OPTS += -I$(GHC_INCLUDE_DIR) $(GCap) $(GC2s) $(GC1s) -O -optc-DIN_GHC_RTS=1 -I$(GHC_RUNTIME_DIR)/storage -SRC_MKDEPENDC_OPTS += $(GCap) $(GC2s) $(GC1s) +SRC_MKDEPENDC_OPTS += -I$(GHC_INCLUDE_DIR) $(GCap) $(GC2s) $(GC1s) #----------------------------------------------------------------------------- # file-specific options diff --git a/ghc/runtime/prims/PrimMisc.lc b/ghc/runtime/prims/PrimMisc.lc index 953ed15..021e0aa 100644 --- a/ghc/runtime/prims/PrimMisc.lc +++ b/ghc/runtime/prims/PrimMisc.lc @@ -43,6 +43,8 @@ stg_exit (n) /* can't call regular "exit" from Haskell because it has no return value */ I_ n; { + /* Storage manager shutdown */ + shutdownHaskell(); EXIT(n); return(0); /* GCC warning food */ } diff --git a/mk/config.mk.in b/mk/config.mk.in index c8fa245..0cc939b 100644 --- a/mk/config.mk.in +++ b/mk/config.mk.in @@ -181,6 +181,11 @@ GhcLibHcOpts= -split-objs -odir $(basename $*) # Build the Haskell Readline bindings? # HsLibsWithReadline=YES +# +# Include path to readline.h +# (no path == in standard include path) +# +ReadlineIncludePath= # Build the socket libraries? # @@ -192,6 +197,9 @@ HsLibsWithSockets=YES # HsLibWays=$(GhcLibWays) +# Option flags for hslibs are by default the same as for the options +# used for the prelude libs (see above). +HsLibHcOpts=$(GhcLibHcOpts) ################################################################################# # @@ -265,37 +273,32 @@ NoFibHcOpts= # ################################################################################# -# These variables are all ":=" variables so that you can easily attach -# extra stuff to the end of them, like this: -# -# libdir := $(libdir)/ghc - -TMPDIR := /tmp +TMPDIR = /tmp # FPTOOLS_TOP: the top of the fptools hierarchy, absolute path. -FPTOOLS_TOP_ABS := @hardtop@ +FPTOOLS_TOP_ABS = @hardtop@ # # Installation directories, we don't use half of these, # but since the configure script has them on offer while # passing through, we might as well set them. -prefix := @prefix@ -exec_prefix := @exec_prefix@ -bindir := @bindir@ -sbindir := @sbindir@ -libexecdir := @libexecdir@ -datadir := @datadir@ -sysconfdir := @datadir@ -sharedstatedir := @sharedstatedir@ -localstatedir := @localstatedir@ -libdir := @libdir@ -infodir := @infodir@ -includedir := @includedir@ -oldincludedir := @oldincludedir@ -mandir := @mandir@ -srcdir := @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @datadir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +includedir = @includedir@ +oldincludedir = @oldincludedir@ +mandir = @mandir@ +srcdir = @srcdir@ ################################################################################# # diff --git a/mk/target.mk b/mk/target.mk index 28b3d7c..d1d1129 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -689,15 +689,16 @@ ifneq "$(filter -monolithic,$(TEXI2HTML_OPTS))" "" $(LIT2TEXI) -S -c $(LIT2TEXI_OPTS) -o $(patsubst %.html,%.itxi,$@) $(addsuffix .lit,$(basename $@)) $(LIT2TEXI) -S $(LIT2TEXI_OPTS) -o $(patsubst %.html,%.texi,$@) $(addsuffix .itxi,$(basename $@)) $(TEXI2HTML) $(TEXI2HTML_OPTS) $(patsubst %.html,%.texi,$@) + cp $(TEXI2HTML_PREFIX)invisible.xbm . else $(RM) html/$(basename $@)* $(MKDIRHIER) html $(LIT2TEXI) -S -c $(LIT2TEXI_OPTS) -o $(patsubst %.html,%.itxi,$@) $(addsuffix .lit,$(basename $@)) $(LIT2TEXI) -S $(LIT2TEXI_OPTS) -o html/$(patsubst %.html,%.texi,$@) $(addsuffix .itxi,$(basename $@)) (cd html; ../$(TEXI2HTML) $(TEXI2HTML_OPTS) $(patsubst %.html,%.texi,$@); cd ..) + cp $(TEXI2HTML_PREFIX)invisible.xbm html/ @touch $@ endif - ########################################### # # Targets: clean