mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-20 06:20:38 +00:00
newruntime: progress
This commit is contained in:
@@ -12,6 +12,14 @@
|
||||
|
||||
# included from sempass2.nim
|
||||
|
||||
# Todo:
|
||||
# - specialize destructors for constant arrays of strings
|
||||
# (they don't require any)
|
||||
# - use openArray instead of array to avoid over-specializations
|
||||
# - make 'owned' mean 'sink' in parameters
|
||||
|
||||
import sighashes
|
||||
|
||||
type
|
||||
TLiftCtx = object
|
||||
graph: ModuleGraph
|
||||
@@ -286,25 +294,10 @@ proc seqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
doAssert t.destructor != nil
|
||||
moveCall.add destructorCall(c.graph, t.destructor, x)
|
||||
body.add moveCall
|
||||
when false:
|
||||
# we generate:
|
||||
# if a.len != 0 and a.p != b.p:
|
||||
# `=destroy`(x)
|
||||
# a.len = b.len
|
||||
# a.p = b.p
|
||||
# Note: '@' is either '.' or '->'.
|
||||
body.add genIf(c, genVerbatim("dest@len != 0 && dest@p != src.p", c.info),
|
||||
destructorCall(c.graph, t.destructor, x))
|
||||
body.add genVerbatim("dest@len=src.len; dest@p=src.p;", c.info)
|
||||
of attachedDestructor:
|
||||
# destroy all elements:
|
||||
forallElements(c, t, body, x, y)
|
||||
body.add genBuiltin(c.graph, mDestroy, "destroy", x)
|
||||
when false:
|
||||
var deallocStmt = genVerbatim("dest@region->dealloc(dest@region, dest@p, " &
|
||||
"(dest@p->cap * sizeof($)) + sizeof(NI) + sizeof(void*)); dest@len = 0;", c.info)
|
||||
deallocStmt.typ = t.lastSon
|
||||
body.add genIf(c, genVerbatim("dest@len != 0 && dest@region", c.info), deallocStmt)
|
||||
|
||||
proc strOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
case c.kind
|
||||
@@ -603,19 +596,29 @@ template inst(field, t) =
|
||||
if field.ast != nil:
|
||||
patchBody(c, field.ast, info)
|
||||
|
||||
proc createTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
|
||||
proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) =
|
||||
## In the semantic pass this is called in strategic places
|
||||
## to ensure we lift assignment, destructors and moves properly.
|
||||
## The later 'injectdestructors' pass depends on it.
|
||||
if typ == nil or {tfCheckedForDestructor, tfHasMeta} * typ.flags != {}: return
|
||||
incl typ.flags, tfCheckedForDestructor
|
||||
if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.flags != {}: return
|
||||
incl orig.flags, tfCheckedForDestructor
|
||||
|
||||
let h = sighashes.hashType(orig, {CoType, CoConsiderOwned})
|
||||
var canon = c.graph.canonTypes.getOrDefault(h)
|
||||
var overwrite = false
|
||||
if canon == nil:
|
||||
c.graph.canonTypes[h] = orig
|
||||
canon = orig
|
||||
elif canon != orig:
|
||||
overwrite = true
|
||||
|
||||
# multiple cases are to distinguish here:
|
||||
# 1. we don't know yet if 'typ' has a nontrival destructor.
|
||||
# 2. we have a nop destructor. --> mDestroy
|
||||
# 3. we have a lifted destructor.
|
||||
# 4. We have a custom destructor.
|
||||
# 5. We have a (custom) generic destructor.
|
||||
let typ = typ.skipTypes({tyGenericInst, tyAlias})
|
||||
let typ = canon.skipTypes({tyGenericInst, tyAlias})
|
||||
# we generate the destructor first so that other operators can depend on it:
|
||||
if typ.destructor == nil:
|
||||
liftBody(c, typ, attachedDestructor, info)
|
||||
@@ -629,3 +632,8 @@ proc createTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
|
||||
liftBody(c, typ, attachedSink, info)
|
||||
else:
|
||||
inst(typ.sink, typ)
|
||||
|
||||
if overwrite:
|
||||
orig.destructor = canon.destructor
|
||||
orig.assignment = canon.assignment
|
||||
orig.sink = canon.sink
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
##
|
||||
|
||||
import ast, intsets, tables, options, lineinfos, hashes, idents,
|
||||
incremental, btrees
|
||||
incremental, btrees, sighashes
|
||||
|
||||
type
|
||||
ModuleGraph* = ref object
|
||||
@@ -57,6 +57,7 @@ type
|
||||
opContains*, opNot*: PSym
|
||||
emptyNode*: PNode
|
||||
incr*: IncrementalCtx
|
||||
canonTypes*: Table[SigHash, PType]
|
||||
importModuleCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PSym {.nimcall.}
|
||||
includeFileCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PNode {.nimcall.}
|
||||
recordStmt*: proc (graph: ModuleGraph; m: PSym; n: PNode) {.nimcall.}
|
||||
@@ -138,6 +139,7 @@ proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
||||
result.cacheSeqs = initTable[string, PNode]()
|
||||
result.cacheCounters = initTable[string, BiggestInt]()
|
||||
result.cacheTables = initTable[string, BTree[string, PNode]]()
|
||||
result.canonTypes = initTable[SigHash, PType]()
|
||||
|
||||
proc resetAllModules*(g: ModuleGraph) =
|
||||
initStrTable(g.packageSyms)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import
|
||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
||||
wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
|
||||
modulegraphs, lowerings, sigmatch
|
||||
modulegraphs, lowerings, sigmatch, tables
|
||||
|
||||
when not defined(leanCompiler):
|
||||
import writetracking
|
||||
|
||||
@@ -90,6 +90,7 @@ type
|
||||
CoType
|
||||
CoOwnerSig
|
||||
CoIgnoreRange
|
||||
CoConsiderOwned
|
||||
|
||||
proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag])
|
||||
|
||||
@@ -165,7 +166,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||
c.hashType t.sons[i], flags
|
||||
else:
|
||||
c.hashType t.lastSon, flags
|
||||
of tyAlias, tySink, tyUserTypeClasses, tyInferred, tyOwned:
|
||||
of tyAlias, tySink, tyUserTypeClasses, tyInferred:
|
||||
c.hashType t.lastSon, flags
|
||||
of tyOwned:
|
||||
if CoConsiderOwned in flags:
|
||||
c &= char(t.kind)
|
||||
c.hashType t.lastSon, flags
|
||||
of tyBool, tyChar, tyInt..tyUInt64:
|
||||
# no canonicalization for integral types, so that e.g. ``pid_t`` is
|
||||
|
||||
@@ -413,7 +413,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
|
||||
typ.size = typ.lastSon.size
|
||||
typ.align = typ.lastSon.align
|
||||
|
||||
of tyGenericInst, tyDistinct, tyGenericBody, tyAlias, tySink:
|
||||
of tyGenericInst, tyDistinct, tyGenericBody, tyAlias, tySink, tyOwned:
|
||||
computeSizeAlign(conf, typ.lastSon)
|
||||
typ.size = typ.lastSon.size
|
||||
typ.align = typ.lastSon.align
|
||||
|
||||
Reference in New Issue
Block a user