diff --git a/compiler/layeredtable.nim b/compiler/layeredtable.nim index d01697405a24a..39c927d0e10e1 100644 --- a/compiler/layeredtable.nim +++ b/compiler/layeredtable.nim @@ -2,11 +2,18 @@ import std/tables import ast type - LayeredIdTable* {.acyclic.} = ref object + LayeredIdTableObj* {.acyclic.} = object topLayer*: TypeMapping - nextLayer*: LayeredIdTable + nextLayer*: ref LayeredIdTableObj previousLen*: int # used to track if bindings were added +const useRef = defined(gcMarkAndSweep) + +when useRef: + type LayeredIdTable* = ref LayeredIdTableObj +else: + type LayeredIdTable* = LayeredIdTableObj + proc initLayeredTypeMap*(pt: sink TypeMapping = initTypeMapping()): LayeredIdTable = result = LayeredIdTable(topLayer: pt, nextLayer: nil) @@ -17,12 +24,23 @@ proc currentLen*(pt: LayeredIdTable): int = pt.previousLen + pt.topLayer.len proc newTypeMapLayer*(pt: LayeredIdTable): LayeredIdTable = - result = LayeredIdTable(topLayer: initTable[ItemId, PType](), nextLayer: pt, previousLen: pt.currentLen) + result = LayeredIdTable(topLayer: initTable[ItemId, PType](), previousLen: pt.currentLen) + when useRef: + result.nextLayer = pt + else: + new(result.nextLayer) + result.nextLayer[] = pt proc setToPreviousLayer*(pt: var LayeredIdTable) {.inline.} = - pt = pt.nextLayer + when useRef: + pt = pt.nextLayer + else: + when defined(gcDestructors): + pt = pt.nextLayer[] + else: + pt = shallowCopy(pt.nextLayer[]) -proc lookup(typeMap: LayeredIdTable, key: ItemId): PType = +proc lookup(typeMap: ref LayeredIdTableObj, key: ItemId): PType = result = nil var tm = typeMap while tm != nil: @@ -30,8 +48,17 @@ proc lookup(typeMap: LayeredIdTable, key: ItemId): PType = if result != nil: return tm = tm.nextLayer -template lookup*(typeMap: LayeredIdTable, key: PType): PType = +template lookup*(typeMap: ref LayeredIdTableObj, key: PType): PType = lookup(typeMap, key.itemId) -proc put*(typeMap: LayeredIdTable, key, value: PType) {.inline.} = +when not useRef: + proc lookup(typeMap: LayeredIdTableObj, key: ItemId): PType {.inline.} = + result = getOrDefault(typeMap.topLayer, key) + if result == nil and typeMap.nextLayer != nil: + result = lookup(typeMap.nextLayer, key) + + template lookup*(typeMap: LayeredIdTableObj, key: PType): PType = + lookup(typeMap, key.itemId) + +proc put*(typeMap: var LayeredIdTable, key, value: PType) {.inline.} = typeMap.topLayer[key.itemId] = value