mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
fixes #25205
fixes #14873
```nim
type
SysLockObj {.importc: "pthread_mutex_t", pure, final,
header: """#include <sys/types.h>
#include <pthread.h>""", byref.} = object
when defined(linux) and defined(amd64):
abi: array[40 div sizeof(clong), clong]
```
Before this PR, in refc, `resetLoc` generates field assignments for each
fields of `importc` object. But the field `abi` is not a genuine field,
which doesn't exits in the struct. We could use `zeroMem` to reset the
memory if not leave it alone
(cherry picked from commit 02609f1872)
112 lines
4.2 KiB
Nim
112 lines
4.2 KiB
Nim
#
|
|
#
|
|
# 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:
|
|
if typ.sym != nil and sfImportc in typ.sym.flags:
|
|
# imported C struct, nimZeroMem
|
|
lineCg(p, cpsStmts, "#nimZeroMem((void**)&$1, sizeof($2));$n",
|
|
[accessor, getTypeDesc(p.module, typ)])
|
|
else:
|
|
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, tyError, 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)
|