diff --git a/compiler/stz-el.stanza b/compiler/stz-el.stanza index dfa12b70f..250a0670e 100644 --- a/compiler/stz-el.stanza +++ b/compiler/stz-el.stanza @@ -2399,14 +2399,22 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage : ;Compute binding table. ;Every entry in the binding table, x => e, indicates that - ;x is defined exactly once by the EObject or ENewObject instruction. - defn binding-table (e:EBody) -> IntTable : - val table = IntListTable() + ;x is defined exactly once by the + ;EObject, ENewObject, or EDef instruction. + defn binding-table (e:EBody) -> IntTable : + val table = IntListTable() val remove-set = IntSet() + defn remove-varloc-vars (i:EIns) : + do(add{remove-set, n(_)}, varlocs(i)) for i in ins(e) do : - match(i:EObject|ENewObject) : add(table, n(x(i)), i) - else : do(add{remove-set, n(_)}, varlocs(i)) - to-inttable $ + match(i) : + (i:EObject|ENewObject) : add(table, n(x(i)), i) + (i:EDef) : + match(x(i), y(i)) : + (x:EVarLoc, y:ELiteral) : add(table, n(x), y) + (x, y) : remove-varloc-vars(i) + (i) : remove-varloc-vars(i) + to-inttable $ for entry in table seq? : if remove-set[key(entry)] : None() else if length(value(entry)) == 1 : One(key(entry) => head(value(entry))) @@ -2423,7 +2431,7 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage : ;field. Calls fail() if not a match. defn unbox-object-get (e:EObjectGet, vt:VarTable, - bindings:IntTable) -> [EVarLoc, EImm] : + bindings:IntTable) -> [EVarLoc, EImm] : val v = y(e) as? EVar val o = get?(bindings, n(v)) as? ENewObject val value = ys(o)[index(e)] @@ -2431,18 +2439,24 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage : [x(e), value] ;If the given ELoad expression corresponds to a retrieval - ;of a known object field then return the destination and the field. + ;of a known object field or literal value then + ;return the destination and the field or value. ;Calls fail() if not a match. defn unbox-load (e:ELoad, vt:VarTable, - bindings:IntTable, ) -> [EVarLoc, EImm] : + bindings:IntTable, ) -> [EVarLoc, EImm] : val field = loc(e) as? EField val v = y(loc(field) as? EDeref) as? EVar - val o = get?(bindings, n(v)) as? EObject - fail() when mutable-field?(defstruct-table, n(o), index(field)) - val value = ys(o)[index(field)] - fail() when not immutable?(vt,value) - [x(e), value] + match(get?(bindings, n(v))) : + (o:EObject) : + fail() when mutable-field?(defstruct-table, n(o), index(field)) + val value = ys(o)[index(field)] + fail() when not immutable?(vt,value) + [x(e), value] + (o:ELiteral) : + fail() when (index(field) != 0 or value(o) is-not Byte|Int|Long|Float|Double) + [x(e), ELSLiteral(value(o))] + (o) : fail() ;Perform unboxing folds in the given body. ;Assumes that all nested bodies have already been folded.