summary refs log tree commit diff stats
path: root/tests/system
ModeNameSize
d---------helpers44log stats plain
-rw-r--r--t7894.nim250log stats plain blame
-rw-r--r--talloc.nim1125log stats plain blame
-rw-r--r--talloc2.nim787log stats plain blame
-rw-r--r--tdeepcopy.nim2200log stats plain blame
-rw-r--r--tenum_array_repr.nim280log stats plain blame
-rw-r--r--tio.nim1918log stats plain blame
-rw-r--r--tnilconcats.nim315log stats plain blame
-rw-r--r--tostring.nim2340log stats plain blame
-rw-r--r--tparams.nim705log stats plain blame
-rw-r--r--trealloc.nim497log stats plain blame
-rw-r--r--tsystem_misc.nim2010log stats plain blame
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#
#
#           The Nim Compiler
#        (c) Copyright 2021 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Integrity checking for a set of .rod files.
## The set must cover a complete Nim project.

import sets

when defined(nimPreviewSlimSystem):
  import std/assertions

import ".." / [ast, modulegraphs]
import packed_ast, bitabs, ic

type
  CheckedContext = object
    g: ModuleGraph
    thisModule: int32
    checkedSyms: HashSet[ItemId]
    checkedTypes: HashSet[ItemId]

proc checkType(c: var CheckedContext; typeId: PackedItemId)
proc checkForeignSym(c: var CheckedContext; symId: PackedItemId)
proc checkNode(c: var CheckedContext; tree: PackedTree; n: NodePos)

proc checkTypeObj(c: var CheckedContext; typ: PackedType) =
  for child in typ.types:
    checkType(c, child)
  if typ.n != emptyNodeId:
    checkNode(c, c.g.packed[c.thisModule].fromDisk.bodies, NodePos typ.n)
  if typ.sym != nilItemId:
    checkForeignSym(c, typ.sym)
  if typ.owner != nilItemId:
    checkForeignSym(c, typ.owner)
  checkType(c, typ.typeInst)

proc checkType(c: var CheckedContext; typeId: PackedItemId) =
  if typeId == nilItemId: return
  let itemId = translateId(typeId, c.g.packed, c.thisModule, c.g.config)
  if not c.checkedTypes.containsOrIncl(itemId):
    let oldThisModule = c.thisModule
    c.thisModule = itemId.module
    checkTypeObj c, c.g.packed[itemId.module].fromDisk.types[itemId.item]
    c.thisModule = oldThisModule

proc checkSym(c: var CheckedContext; s: PackedSym) =
  if s.name != LitId(0):
    assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId s.name
  checkType c, s.typ
  if s.ast != emptyNodeId:
    checkNode(c, c.g.packed[c.thisModule].fromDisk.bodies, NodePos s.ast)
  if s.owner != nilItemId:
    checkForeignSym(c, s.owner)

proc checkLocalSym(c: var CheckedContext; item: int32) =
  let itemId = ItemId(module: c.thisModule, item: item)
  if not c.checkedSyms.containsOrIncl(itemId):
    checkSym c, c.g.packed[c.thisModule].fromDisk.syms[item]

proc checkForeignSym(c: var CheckedContext; symId: PackedItemId) =
  let itemId = translateId(symId, c.g.packed, c.thisModule, c.g.config)
  if not c.checkedSyms.containsOrIncl(itemId):
    let oldThisModule = c.thisModule
    c.thisModule = itemId.module
    checkSym c, c.g.packed[itemId.module].fromDisk.syms[itemId.item]
    c.thisModule = oldThisModule

proc checkNode(c: var CheckedContext; tree: PackedTree; n: NodePos) =
  if tree[n.int].typeId != nilItemId:
    checkType(c, tree[n.int].typeId)
  case n.kind
  of nkEmpty, nkNilLit, nkType, nkNilRodNode:
    discard
  of nkIdent:
    assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId n.litId
  of nkSym:
    checkLocalSym(c, tree.nodes[n.int].operand)
  of directIntLit:
    discard
  of externIntLit, nkFloatLit..nkFloat128Lit:
    assert c.g.packed[c.thisModule].fromDisk.numbers.hasLitId n.litId
  of nkStrLit..nkTripleStrLit:
    assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId n.litId
  of nkModuleRef:
    let (n1, n2) = sons2(tree, n)
    assert n1.kind == nkInt32Lit
    assert n2.kind == nkInt32Lit
    checkForeignSym(c, PackedItemId(module: n1.litId, item: tree.nodes[n2.int].operand))
  else:
    for n0 in sonsReadonly(tree, n):
      checkNode(c, tree, n0)

proc checkTree(c: var CheckedContext; t: PackedTree) =
  for p in allNodes(t): checkNode(c, t, p)

proc checkLocalSymIds(c: var CheckedContext; m: PackedModule; symIds: seq[int32]) =
  for symId in symIds:
    assert symId >= 0 and symId < m.syms.len, $symId & " " & $m.syms.len

proc checkModule(c: var CheckedContext; m: PackedModule) =
  # We check that:
  # - Every symbol references existing types and symbols.
  # - Every tree node references existing types and symbols.
  for i in 0..high(m.syms):
    checkLocalSym c, int32(i)

  checkTree c, m.toReplay
  checkTree c, m.topLevel

  for e in m.exports:
    assert e[1] >= 0 and e[1] < m.syms.len
    assert e[0] == m.syms[e[1]].name

  for e in m.compilerProcs:
    assert e[1] >= 0 and e[1] < m.syms.len
    assert e[0] == m.syms[e[1]].name

  checkLocalSymIds c, m, m.converters
  checkLocalSymIds c, m, m.methods
  checkLocalSymIds c, m, m.trmacros
  checkLocalSymIds c, m, m.pureEnums
  #[
    To do: Check all these fields:

    reexports*: seq[(LitId, PackedItemId)]
    macroUsages*: seq[(PackedItemId, PackedLineInfo)]

    typeInstCache*: seq[(PackedItemId, PackedItemId)]
    procInstCache*: seq[PackedInstantiation]
    attachedOps*: seq[(TTypeAttachedOp, PackedItemId, PackedItemId)]
    methodsPerType*: seq[(PackedItemId, int, PackedItemId)]
    enumToStringProcs*: seq[(PackedItemId, PackedItemId)]
  ]#

proc checkIntegrity*(g: ModuleGraph) =
  var c = CheckedContext(g: g)
  for i in 0..high(g.packed):
    # case statement here to enforce exhaustive checks.
    case g.packed[i].status
    of undefined:
      discard "nothing to do"
    of loading:
      assert false, "cannot check integrity: Module still loading"
    of stored, storing, outdated, loaded:
      c.thisModule = int32 i
      checkModule(c, g.packed[i].fromDisk)