Annotation of researchv10no/cmd/sml/src/codegen/backpatch.sml, revision 1.1

1.1     ! root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
        !             2: signature BACKPATCH =
        !             3: sig
        !             4:     eqtype Label
        !             5:     val newlabel : unit -> Label
        !             6:     type JumpKind
        !             7:     val emitstring : string -> unit
        !             8:     val align : unit -> unit
        !             9:     val define : Label -> unit
        !            10:     val jump : JumpKind*Label -> unit
        !            11:     val mark : unit -> unit
        !            12:     val finish : unit -> string
        !            13: end
        !            14: 
        !            15: signature JUMPS =
        !            16: sig
        !            17:   type JumpKind
        !            18:   val sizejump : JumpKind*int*int*int -> int
        !            19:   val emitjump : JumpKind*int*int*int -> string
        !            20:   val emitlong : int -> string
        !            21: end
        !            22: 
        !            23: functor Backpatch(Kind: JUMPS) : BACKPATCH =
        !            24: struct 
        !            25:   open Kind System.Tags
        !            26:   type Label = int ref
        !            27:   fun newlabel() = ref 0
        !            28: 
        !            29:   datatype Desc
        !            30:         = BYTES of string * Desc | JUMP of JumpKind * Label * int ref * Desc
        !            31:         | LABEL of Label * Desc | ALIGN of Desc | MARK of Desc | NIL
        !            32: 
        !            33:   fun compress(len, sl as [s], r0 as BYTES(t,r)) =
        !            34:              let val lent = size t
        !            35:               in if len+len > lent andalso lent < 500 andalso len<500
        !            36:                    then compress(len+lent, t::sl, r)
        !            37:                   else BYTES(s, r0)
        !            38:              end
        !            39:     | compress(len, sl, r0 as BYTES(t,r)) =
        !            40:              let val lent = size t
        !            41:               in if len+len > lent andalso lent < 500
        !            42:                    then compress(len+lent, t::sl, r)
        !            43:                   else BYTES(implode sl, r0)
        !            44:              end
        !            45:     | compress(len, sl, r0) = BYTES(implode sl, r0)
        !            46: 
        !            47:   val refs = ref NIL
        !            48:   fun emitstring s = refs := compress(size s, [s],!refs)
        !            49:   fun align() = refs := ALIGN(!refs)
        !            50:   fun mark() = refs := MARK(!refs)
        !            51:   fun define lab = refs := LABEL(lab, !refs)
        !            52:   fun jump(k,lab) = refs := JUMP(k,lab,ref 0, !refs)
        !            53: 
        !            54:   fun reverse(r,NIL) = r
        !            55:     | reverse(r,BYTES(s,q)) = reverse(BYTES(s,r),q)
        !            56:     | reverse(r,ALIGN q) = reverse(ALIGN r, q)
        !            57:     | reverse(r,MARK q) = reverse(MARK r, q)
        !            58:     | reverse(r,LABEL(lab,q)) = reverse(LABEL(lab,r), q)
        !            59:     | reverse(r,JUMP(k,lab,x,q)) = reverse(JUMP(k,lab,x,r),q)
        !            60: 
        !            61:   fun finish() =
        !            62:    let val changed = ref true
        !            63: 
        !            64:        fun labels (pos, BYTES(s,rest)) = labels(pos+size s,rest)
        !            65:          | labels (pos, JUMP(k,l,ref size, rest)) = labels(pos+size, rest)
        !            66:         | labels (pos, LABEL(l,rest)) = (l := pos; labels(pos,rest))
        !            67:         | labels (pos, lab as ALIGN rest) = labels(((pos+3)div 4)*4, rest)
        !            68:         | labels (pos, MARK rest) = labels(pos+4, rest)
        !            69:         | labels (pos, NIL) = ()
        !            70: 
        !            71:        fun adjust (pos, BYTES(s,rest)) = adjust(pos+size s,rest)
        !            72:         | adjust (pos, JUMP(k, l, r as ref size, rest)) =
        !            73:                let val s = sizejump(k, size, pos, !l)
        !            74:                in  if s > size then (r := s; changed := true) else ();
        !            75:                     adjust(pos+size, rest)
        !            76:                end
        !            77:         | adjust (pos, LABEL(l,rest)) = adjust(pos,rest)
        !            78:         | adjust (pos, ALIGN rest) = adjust(((pos+3)div 4)*4, rest)
        !            79:         | adjust (pos, MARK rest) = adjust(pos+4, rest)
        !            80:         | adjust (pos, NIL) = ()
        !            81: 
        !            82:        fun chunk(pos, BYTES(s,r)) = s :: chunk(pos+size s,r)
        !            83:         | chunk(pos, JUMP(k,l,ref size, r)) =
        !            84:                    emitjump(k,size,pos,!l) :: chunk(pos+size,r)
        !            85:         | chunk(pos, LABEL(l, rest)) = chunk(pos,rest)
        !            86:         | chunk(pos, ALIGN rest) =
        !            87:                (case pos mod 4
        !            88:                  of 0 => chunk(pos,rest)
        !            89:                   | 1 => "\000\000\000" :: chunk(pos+3,rest)
        !            90:                   | 2 => "\000\000" :: chunk(pos+2,rest)
        !            91:                   | 3 => "\000" :: chunk(pos+1,rest))
        !            92:         | chunk(pos, MARK r) =
        !            93:               emitlong(((pos+4)div 4)*power_tags+tag_backptr) 
        !            94:                :: chunk(pos+4, r)
        !            95:         | chunk(pos, NIL) = nil
        !            96: 
        !            97:        val reflist = reverse (ALIGN NIL, !refs) before refs := NIL
        !            98:     in  ErrorMsg.debugmsg "relocating...";
        !            99:         while !changed
        !           100:           do (changed := false; labels(0, reflist); adjust(0, reflist));
        !           101:         ErrorMsg.debugmsg "about to output";
        !           102:        implode(chunk(0, reflist))
        !           103:    end
        !           104: end (* functor BackPatch *)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.