Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 28 additions & 14 deletions compiler/stz-el.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -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<EObject|ENewObject> :
val table = IntListTable<EObject|ENewObject>()
;x is defined exactly once by the
;EObject, ENewObject, or EDef instruction.
defn binding-table (e:EBody) -> IntTable<ELItem> :
val table = IntListTable<ELItem>()
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<EObject|ENewObject> $
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<ELItem> $
for entry in table seq? :
if remove-set[key(entry)] : None()
else if length(value(entry)) == 1 : One(key(entry) => head(value(entry)))
Expand All @@ -2423,26 +2431,32 @@ 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<EObject|ENewObject>) -> [EVarLoc, EImm] :
bindings:IntTable<ELItem>) -> [EVarLoc, EImm] :
val v = y(e) as? EVar
val o = get?(bindings, n(v)) as? ENewObject
val value = ys(o)[index(e)]
fail() when not immutable?(vt,value)
[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<EObject|ENewObject>, ) -> [EVarLoc, EImm] :
bindings:IntTable<ELItem>, ) -> [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.
Expand Down