diff options
-rw-r--r-- | compiler/transf.nim | 29 | ||||
-rw-r--r-- | compiler/vm.nim | 12 | ||||
-rw-r--r-- | compiler/vmgen.nim | 7 | ||||
-rw-r--r-- | lib/core/seqs.nim | 4 |
4 files changed, 29 insertions, 23 deletions
diff --git a/compiler/transf.nim b/compiler/transf.nim index 800d56b3a..7b2979dea 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -24,7 +24,8 @@ import sempass2, lowerings, destroyer, liftlocals, modulegraphs, lineinfos -proc transformBody*(g: ModuleGraph, prc: PSym, cache = true): PNode +proc transformBody*(g: ModuleGraph, prc: PSym, cache = true; + noDestructors = false): PNode import closureiters, lambdalifting @@ -48,7 +49,7 @@ type inlining: int # > 0 if we are in inlining context (copy vars) nestedProcs: int # > 0 if we are in a nested proc contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break' - deferDetected, tooEarly, needsDestroyPass: bool + deferDetected, tooEarly, needsDestroyPass, noDestructors: bool graph: ModuleGraph PTransf = ref TTransfContext @@ -130,7 +131,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode = let s = n.sym if s.typ != nil and s.typ.callConv == ccClosure: if s.kind in routineKinds: - discard transformBody(c.graph, s) + discard transformBody(c.graph, s, true, c.noDestructors) if s.kind == skIterator: if c.tooEarly: return n else: return liftIterSym(c.graph, n, getCurrOwner(c)) @@ -159,7 +160,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode = return tc = tc.next result = b - + proc transformSym(c: PTransf, n: PNode): PTransNode = result = PTransNode(transformSymAux(c, n)) @@ -243,7 +244,7 @@ proc newLabel(c: PTransf, n: PNode): PSym = result.name = getIdent(c.graph.cache, genPrefix & $result.id) proc transformBlock(c: PTransf, n: PNode): PTransNode = - var labl: PSym + var labl: PSym if c.inlining > 0: labl = newLabel(c, n[0]) idNodeTablePut(c.transCon.mapping, n[0].sym, newSymNode(labl)) @@ -611,7 +612,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = add(stmtList, newAsgnStmt(c, nkFastAsgn, temp, arg.PTransNode)) idNodeTablePut(newC.mapping, formal, temp) - let body = transformBody(c.graph, iter) + let body = transformBody(c.graph, iter, true, c.noDestructors) pushInfoContext(c.graph.config, n.info) inc(c.inlining) add(stmtList, transform(c, body)) @@ -1029,7 +1030,8 @@ template liftDefer(c, root) = if c.deferDetected: liftDeferAux(root) -proc transformBody*(g: ModuleGraph, prc: PSym, cache = true): PNode = +proc transformBody*(g: ModuleGraph, prc: PSym, cache = true; + noDestructors = false): PNode = assert prc.kind in routineKinds if prc.transformedBody != nil: @@ -1037,22 +1039,22 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache = true): PNode = elif nfTransf in prc.ast[bodyPos].flags or prc.kind in {skTemplate}: result = prc.ast[bodyPos] else: - prc.transformedBody = newNode(nkEmpty) # protects from recursion var c = openTransf(g, prc.getModule, "") + c.noDestructors = noDestructors result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly) result = processTransf(c, result, prc) liftDefer(c, result) result = liftLocalsIfRequested(prc, result, g.cache, g.config) - if c.needsDestroyPass: #and newDestructors: + if c.needsDestroyPass and not noDestructors: result = injectDestructorCalls(g, prc, result) if prc.isIterator: result = g.transformClosureIterator(prc, result) - + incl(result.flags, nfTransf) - let cache = cache or prc.typ.callConv == ccInline + let cache = cache or prc.typ.callConv == ccInline if cache: # genProc for inline procs will be called multiple times from diffrent modules, # it is important to transform exactly once to get sym ids and locations right @@ -1072,7 +1074,8 @@ proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode = result = injectDestructorCalls(g, module, result) incl(result.flags, nfTransf) -proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode = +proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode; + noDestructors = false): PNode = if nfTransf in n.flags: result = n else: @@ -1081,6 +1084,6 @@ proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode = liftDefer(c, result) # expressions are not to be injected with destructor calls as that # the list of top level statements needs to be collected before. - if c.needsDestroyPass: + if c.needsDestroyPass and not noDestructors: result = injectDestructorCalls(g, module, result) incl(result.flags, nfTransf) diff --git a/compiler/vm.nim b/compiler/vm.nim index 05ee3b90e..4eef91dfc 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -503,7 +503,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcAsgnFloat64FromInt: let rb = instr.regB ensureKind(rkFloat) - regs[ra].floatVal = cast[float64](int64(regs[rb].intVal)) + regs[ra].floatVal = cast[float64](int64(regs[rb].intVal)) of opcAsgnComplex: asgnComplex(regs[ra], regs[instr.regB]) of opcAsgnRef: @@ -945,10 +945,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = let a = regs[rb].node if a.kind == nkSym: regs[ra].node = if a.sym.ast.isNil: newNode(nkNilLit) - else: + else: let ast = a.sym.ast.shallowCopy for i in 0..<a.sym.ast.len: - ast[i] = a.sym.ast[i] + ast[i] = a.sym.ast[i] ast[bodyPos] = transformBody(c.graph, a.sym) ast.copyTree() of opcSymOwner: @@ -1822,7 +1822,7 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode = "NimScript: attempt to call non-routine: " & sym.name.s) proc evalStmt*(c: PCtx, n: PNode) = - let n = transformExpr(c.graph, c.module, n) + let n = transformExpr(c.graph, c.module, n, noDestructors = true) let start = genStmt(c, n) # execute new instructions; this redundant opcEof check saves us lots # of allocations in 'execute': @@ -1830,7 +1830,7 @@ proc evalStmt*(c: PCtx, n: PNode) = discard execute(c, start) proc evalExpr*(c: PCtx, n: PNode): PNode = - let n = transformExpr(c.graph, c.module, n) + let n = transformExpr(c.graph, c.module, n, noDestructors = true) let start = genExpr(c, n) assert c.code[start].opcode != opcEof result = execute(c, start) @@ -1877,7 +1877,7 @@ const evalPass* = makePass(myOpen, myProcess, myClose) proc evalConstExprAux(module: PSym; g: ModuleGraph; prc: PSym, n: PNode, mode: TEvalMode): PNode = - let n = transformExpr(g, module, n) + let n = transformExpr(g, module, n, noDestructors = true) setupGlobalCtx(module, g) var c = PCtx g.vm let oldMode = c.mode diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index ff1dd391f..79c75f607 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -779,7 +779,7 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) = let src = n.sons[1].typ.skipTypes(abstractRange)#.kind let dst = n.sons[0].typ.skipTypes(abstractRange)#.kind let src_size = getSize(c.config, src) - let dst_size = getSize(c.config, dst) + let dst_size = getSize(c.config, dst) if c.config.target.intSize < 8: signedIntegers.incl(tyInt) unsignedIntegers.incl(tyUInt) @@ -823,7 +823,7 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) = c.freeTemp(tmp) elif src_size == dst_size and src.kind in {tyFloat, tyFloat32, tyFloat64} and - dst.kind in allowedIntegers: + dst.kind in allowedIntegers: let tmp = c.genx(n[1]) if dest < 0: dest = c.getTemp(n[0].typ) if src.kind == tyFloat32: @@ -2153,7 +2153,8 @@ proc genProc(c: PCtx; s: PSym): int = s.ast.sons[miscPos] = x # thanks to the jmp we can add top level statements easily and also nest # procs easily: - let body = transformBody(c.graph, s, cache = not isCompileTimeProc(s)) + let body = transformBody(c.graph, s, cache = not isCompileTimeProc(s), + noDestructors = true) let procStart = c.xjmp(body, opcJmp, 0) var p = PProc(blocks: @[], sym: s) let oldPrc = c.prc diff --git a/lib/core/seqs.nim b/lib/core/seqs.nim index 4dcf6cbbb..84626c473 100644 --- a/lib/core/seqs.nim +++ b/lib/core/seqs.nim @@ -8,9 +8,11 @@ # -import typetraits +# import typetraits # strs already imported allocators for us. +proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".} + ## Default seq implementation used by Nim's core. type NimSeqPayload {.core.}[T] = object |