summary refs log tree commit diff stats
path: root/compiler/ccgreset.nim
blob: 29791afdccabbaf0c3639130391d03283666f7e9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#
#
#           The Nim Compiler
#        (c) Copyright 2020 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# included from cgen.nim

## Code specialization instead of the old, incredibly slow 'genericReset'
## implementation.

proc specializeResetT(p: BProc, accessor: Rope, typ: PType)

proc specializeResetN(p: BProc, accessor: Rope, n: PNode;
                     typ: PType) =
  if n == nil: return
  case n.kind
  of nkRecList:
    for i in 0..<n.len:
      specializeResetN(p, accessor, n[i], typ)
  of nkRecCase:
    if (n[0].kind != nkSym): internalError(p.config, n.info, "specializeResetN")
    let disc = n[0].sym
    if disc.loc.snippet == "": fillObjectFields(p.module, typ)
    if disc.loc.t == nil:
      internalError(p.config, n.info, "specializeResetN()")
    lineF(p, cpsStmts, "switch ($1.$2) {$n", [accessor, disc.loc.snippet])
    for i in 1..<n.len:
      let branch = n[i]
      assert branch.kind in {nkOfBranch, nkElse}
      if branch.kind == nkOfBranch:
        genCaseRange(p, branch)
      else:
        lineF(p, cpsStmts, "default:$n", [])
      specializeResetN(p, accessor, lastSon(branch), typ)
      lineF(p, cpsStmts, "break;$n", [])
    lineF(p, cpsStmts, "} $n", [])
    specializeResetT(p, "$1.$2" % [accessor, disc.loc.snippet], disc.loc.t)
  of nkSym:
    let field = n.sym
    if field.typ.kind == tyVoid: return
    if field.loc.snippet == "": fillObjectFields(p.module, typ)
    if field.loc.t == nil:
      internalError(p.config, n.info, "specializeResetN()")
    specializeResetT(p, "$1.$2" % [accessor, field.loc.snippet], field.loc.t)
  else: internalError(p.config, n.info, "specializeResetN()")

proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
  if typ == nil: return

  case typ.kind
  of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred,
     tySink, tyOwned:
    specializeResetT(p, accessor, skipModifier(typ))
  of tyArray:
    let arraySize = lengthOrd(p.config, typ.indexType)
    var i: TLoc = getTemp(p, getSysType(p.module.g.graph, unknownLineInfo, tyInt))
    linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
            [i.snippet, arraySize])
    specializeResetT(p, ropecg(p.module, "$1[$2]", [accessor, i.snippet]), typ.elementType)
    lineF(p, cpsStmts, "}$n", [])
  of tyObject:
    var x = typ.baseClass
    if x != nil: x = x.skipTypes(skipPtrs)
    specializeResetT(p, accessor.parentObj(p.module), x)
    if typ.n != nil: specializeResetN(p, accessor, typ.n, typ)
  of tyTuple:
    let typ = getUniqueType(typ)
    for i, a in typ.ikids:
      specializeResetT(p, ropecg(p.module, "$1.Field$2", [accessor, i]), a)

  of tyString, tyRef, tySequence:
    lineCg(p, cpsStmts, "#unsureAsgnRef((void**)&$1, NIM_NIL);$n", [accessor])

  of tyProc:
    if typ.callConv == ccClosure:
      lineCg(p, cpsStmts, "#unsureAsgnRef((void**)&$1.ClE_0, NIM_NIL);$n", [accessor])
      lineCg(p, cpsStmts, "$1.ClP_0 = NIM_NIL;$n", [accessor])
    else:
      lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
  of tyChar, tyBool, tyEnum, tyRange, tyInt..tyUInt64:
    lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
  of tyCstring, tyPointer, tyPtr, tyVar, tyLent:
    lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
  of tySet:
    case mapSetType(p.config, typ)
    of ctArray:
      lineCg(p, cpsStmts, "#nimZeroMem($1, sizeof($2));$n",
          [accessor, getTypeDesc(p.module, typ)])
    of ctInt8, ctInt16, ctInt32, ctInt64:
      lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
    else:
      raiseAssert "unexpected set type kind"
  of tyNone, tyEmpty, tyNil, tyUntyped, tyTyped, tyGenericInvocation,
      tyGenericParam, tyOrdinal, tyOpenArray, tyForward, tyVarargs,
      tyUncheckedArray, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
      tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot,
      tyAnything, tyStatic, tyFromExpr, tyConcept, tyVoid, tyIterable:
    discard

proc specializeReset(p: BProc, a: TLoc) =
  specializeResetT(p, rdLoc(a), a.t)