ccgreset.nim 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2020 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # included from cgen.nim
  10. ## Code specialization instead of the old, incredibly slow 'genericReset'
  11. ## implementation.
  12. proc specializeResetT(p: BProc, accessor: Rope, typ: PType)
  13. proc specializeResetN(p: BProc, accessor: Rope, n: PNode;
  14. typ: PType) =
  15. if n == nil: return
  16. case n.kind
  17. of nkRecList:
  18. for i in 0..<n.len:
  19. specializeResetN(p, accessor, n[i], typ)
  20. of nkRecCase:
  21. if (n[0].kind != nkSym): internalError(p.config, n.info, "specializeResetN")
  22. let disc = n[0].sym
  23. if disc.loc.r == nil: fillObjectFields(p.module, typ)
  24. if disc.loc.t == nil:
  25. internalError(p.config, n.info, "specializeResetN()")
  26. lineF(p, cpsStmts, "switch ($1.$2) {$n", [accessor, disc.loc.r])
  27. for i in 1..<n.len:
  28. let branch = n[i]
  29. assert branch.kind in {nkOfBranch, nkElse}
  30. if branch.kind == nkOfBranch:
  31. genCaseRange(p, branch)
  32. else:
  33. lineF(p, cpsStmts, "default:$n", [])
  34. specializeResetN(p, accessor, lastSon(branch), typ)
  35. lineF(p, cpsStmts, "break;$n", [])
  36. lineF(p, cpsStmts, "} $n", [])
  37. specializeResetT(p, "$1.$2" % [accessor, disc.loc.r], disc.loc.t)
  38. of nkSym:
  39. let field = n.sym
  40. if field.typ.kind == tyVoid: return
  41. if field.loc.r == nil: fillObjectFields(p.module, typ)
  42. if field.loc.t == nil:
  43. internalError(p.config, n.info, "specializeResetN()")
  44. specializeResetT(p, "$1.$2" % [accessor, field.loc.r], field.loc.t)
  45. else: internalError(p.config, n.info, "specializeResetN()")
  46. proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
  47. if typ == nil: return
  48. case typ.kind
  49. of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred,
  50. tySink, tyOwned:
  51. specializeResetT(p, accessor, lastSon(typ))
  52. of tyArray:
  53. let arraySize = lengthOrd(p.config, typ[0])
  54. var i: TLoc
  55. getTemp(p, getSysType(p.module.g.graph, unknownLineInfo, tyInt), i)
  56. linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
  57. [i.r, arraySize])
  58. specializeResetT(p, ropecg(p.module, "$1[$2]", [accessor, i.r]), typ[1])
  59. lineF(p, cpsStmts, "}$n", [])
  60. of tyObject:
  61. for i in 0..<typ.len:
  62. var x = typ[i]
  63. if x != nil: x = x.skipTypes(skipPtrs)
  64. specializeResetT(p, accessor.parentObj(p.module), x)
  65. if typ.n != nil: specializeResetN(p, accessor, typ.n, typ)
  66. of tyTuple:
  67. let typ = getUniqueType(typ)
  68. for i in 0..<typ.len:
  69. specializeResetT(p, ropecg(p.module, "$1.Field$2", [accessor, i]), typ[i])
  70. of tyString, tyRef, tySequence:
  71. lineCg(p, cpsStmts, "#unsureAsgnRef((void**)&$1, NIM_NIL);$n", [accessor])
  72. of tyProc:
  73. if typ.callConv == ccClosure:
  74. lineCg(p, cpsStmts, "#unsureAsgnRef((void**)&$1.ClE_0, NIM_NIL);$n", [accessor])
  75. lineCg(p, cpsStmts, "$1.ClP_0 = NIM_NIL;$n", [accessor])
  76. else:
  77. lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
  78. of tyChar, tyBool, tyEnum, tyInt..tyUInt64:
  79. lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
  80. of tyCString, tyPointer, tyPtr, tyVar, tyLent:
  81. lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
  82. else:
  83. discard
  84. proc specializeReset(p: BProc, a: TLoc) =
  85. specializeResetT(p, rdLoc(a), a.t)