diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-01-04 15:59:10 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-01-04 15:59:10 +0100 |
commit | 464d037c1758243664d46595ab4bd800d86e041f (patch) | |
tree | 2885cc822fa362f6f5b8603b882feab6e0a02a18 /compiler | |
parent | 2e635ab28cb60be5e63e01ecf074596ccc385696 (diff) | |
parent | 2cf94fe7e74afcd48aa8ee19f59231baf56737d6 (diff) | |
download | Nim-464d037c1758243664d46595ab4bd800d86e041f.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cgen.nim | 8 | ||||
-rw-r--r-- | compiler/extccomp.nim | 2 | ||||
-rw-r--r-- | compiler/jsgen.nim | 4 | ||||
-rw-r--r-- | compiler/passes.nim | 4 | ||||
-rw-r--r-- | compiler/renderer.nim | 1 | ||||
-rw-r--r-- | compiler/sem.nim | 10 | ||||
-rw-r--r-- | compiler/semexprs.nim | 6 | ||||
-rw-r--r-- | compiler/transf.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 47 |
9 files changed, 64 insertions, 20 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 217138dd0..573a14927 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1258,7 +1258,7 @@ proc resetModule*(m: BModule) = # indicate that this is now cached module # the cache will be invalidated by nullifying gModules - m.fromCache = true + #m.fromCache = true m.g = nil # we keep only the "merge info" information for the module @@ -1390,7 +1390,7 @@ proc writeModule(m: BModule, pending: bool) = # generate code for the init statements of the module: let cfile = getCFile(m) - if not m.fromCache or optForceFullMake in gGlobalOptions: + if m.rd == nil or optForceFullMake in gGlobalOptions: genInitCode(m) finishTypeDescriptions(m) if sfMainModule in m.module.flags: @@ -1465,10 +1465,10 @@ proc cgenWriteModules*(backend: RootRef, config: ConfigRef) = if g.generatedHeader != nil: finishModule(g.generatedHeader) while g.forwardedProcsCounter > 0: for m in cgenModules(g): - if not m.fromCache: + if m.rd == nil: finishModule(m) for m in cgenModules(g): - if m.fromCache: + if m.rd != nil: m.updateCachedModule else: m.writeModule(pending=true) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 5299b2dbf..62990593d 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -253,7 +253,7 @@ compiler tcc: compilerExe: "tcc", cppCompiler: "", compileTmpl: "-c $options $include -o $objfile $file", - buildGui: "UNAVAILABLE!", + buildGui: "-Wl,-subsystem=gui", buildDll: " -shared", buildLib: "", # XXX: not supported yet linkerExe: "tcc", diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 65a6a5dae..dac2de746 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -2051,10 +2051,10 @@ proc genConv(p: PProc, n: PNode, r: var TCompRes) = return case dest.kind: of tyBool: - r.res = "(($1)? 1:0)" % [r.res] + r.res = "(!!($1))" % [r.res] r.kind = resExpr of tyInt: - r.res = "($1|0)" % [r.res] + r.res = "(($1)|0)" % [r.res] else: # TODO: What types must we handle here? discard diff --git a/compiler/passes.nim b/compiler/passes.nim index b84fe2f4d..29b27627d 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -18,7 +18,7 @@ import type TPassContext* = object of RootObj # the pass's context - fromCache*: bool # true if created by "openCached" + rd*: PRodReader # != nil if created by "openCached" PPassContext* = ref TPassContext @@ -118,7 +118,7 @@ proc openPassesCached(g: ModuleGraph; a: var TPassContextArray, module: PSym, if not isNil(gPasses[i].openCached): a[i] = gPasses[i].openCached(g, module, rd) if a[i] != nil: - a[i].fromCache = true + a[i].rd = rd else: a[i] = nil diff --git a/compiler/renderer.nim b/compiler/renderer.nim index d4b401c02..6735cc1ce 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -719,6 +719,7 @@ proc gcase(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) var length = sonsLen(n) + if length == 0: return var last = if n.sons[length-1].kind == nkElse: -2 else: -1 if longMode(g, n, 0, last): incl(c.flags, rfLongMode) putWithSpace(g, tkCase, "case") diff --git a/compiler/sem.nim b/compiler/sem.nim index ababbd303..1098e9961 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -74,7 +74,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode = localError(arg.info, errExprXHasNoType, renderTree(arg, {renderNoComments})) # error correction: - result = copyNode(arg) + result = copyTree(arg) result.typ = formal else: result = indexTypesMatch(c, formal, arg.typ, arg) @@ -168,9 +168,9 @@ proc commonType*(x, y: PType): PType = proc endsInNoReturn(n: PNode): bool = # check if expr ends in raise exception or call of noreturn proc var it = n - while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0: + while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0: it = it.lastSon - result = it.kind == nkRaiseStmt or + result = it.kind == nkRaiseStmt or it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags proc commonType*(x: PType, y: PNode): PType = @@ -501,6 +501,8 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContext = result = myOpen(graph, module, rd.cache) + +proc replayMethodDefs(graph: ModuleGraph; rd: PRodReader) = for m in items(rd.methods): methodDef(graph, m, true) proc isImportSystemStmt(n: PNode): bool = @@ -607,6 +609,8 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = addCodeForGenerics(c, result) if c.module.ast != nil: result.add(c.module.ast) + if c.rd != nil: + replayMethodDefs(graph, c.rd) popOwner(c) popProcCon(c) if c.runnableExamples != nil: testExamples(c) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index a0f519820..51e75e91f 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1425,11 +1425,7 @@ proc semProcBody(c: PContext, n: PNode): PNode = openScope(c) result = semExpr(c, n) if c.p.resultSym != nil and not isEmptyType(result.typ): - # transform ``expr`` to ``result = expr``, but not if the expr is already - # ``result``: - if result.kind == nkSym and result.sym == c.p.resultSym: - discard - elif result.kind == nkNilLit: + if result.kind == nkNilLit: # or ImplicitlyDiscardable(result): # new semantic: 'result = x' triggers the void context result.typ = nil diff --git a/compiler/transf.nim b/compiler/transf.nim index 6bc809fd2..f8f7f8746 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -914,7 +914,7 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode = # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip # this step! We have to rely that the semantic pass transforms too errornous # nodes into an empty node. - if c.fromCache or nfTransf in n.flags: return n + if c.rd != nil or nfTransf in n.flags: return n pushTransCon(c, newTransCon(owner)) result = PNode(transform(c, n)) popTransCon(c) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 3790a8392..17878b656 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -30,7 +30,7 @@ import strutils, ast, astalgo, types, msgs, renderer, vmdef, trees, intsets, rodread, magicsys, options, lowerings - +import platform from os import splitFile when hasFFI: @@ -761,6 +761,49 @@ proc genCard(c: PCtx; n: PNode; dest: var TDest) = c.gABC(n, opcCard, dest, tmp) c.freeTemp(tmp) +proc genIntCast(c: PCtx; n: PNode; dest: var TDest) = + const allowedIntegers = {tyInt..tyInt64, tyUInt..tyUInt64, tyChar} + var signedIntegers = {tyInt8..tyInt32} + var unsignedIntegers = {tyUInt8..tyUInt32, tyChar} + let src = n.sons[1].typ.skipTypes(abstractRange)#.kind + let dst = n.sons[0].typ.skipTypes(abstractRange)#.kind + let src_size = src.getSize + + if platform.intSize < 8: + signedIntegers.incl(tyInt) + unsignedIntegers.incl(tyUInt) + if src_size == dst.getSize and src.kind in allowedIntegers and + dst.kind in allowedIntegers: + let tmp = c.genx(n.sons[1]) + var tmp2 = c.getTemp(n.sons[1].typ) + let tmp3 = c.getTemp(n.sons[1].typ) + if dest < 0: dest = c.getTemp(n[0].typ) + proc mkIntLit(ival: int): int = + result = genLiteral(c, newIntTypeNode(nkIntLit, ival, getSysType(tyInt))) + if src.kind in unsignedIntegers and dst.kind in signedIntegers: + # cast unsigned to signed integer of same size + # signedVal = (unsignedVal xor offset) -% offset + let offset = 1 shl (src_size * 8 - 1) + c.gABx(n, opcLdConst, tmp2, mkIntLit(offset)) + c.gABC(n, opcBitxorInt, tmp3, tmp, tmp2) + c.gABC(n, opcSubInt, dest, tmp3, tmp2) + elif src.kind in signedIntegers and dst.kind in unsignedIntegers: + # cast signed to unsigned integer of same size + # unsignedVal = (offset +% signedVal +% 1) and offset + let offset = (1 shl (src_size * 8)) - 1 + c.gABx(n, opcLdConst, tmp2, mkIntLit(offset)) + c.gABx(n, opcLdConst, dest, mkIntLit(offset+1)) + c.gABC(n, opcAddu, tmp3, tmp, dest) + c.gABC(n, opcNarrowU, tmp3, TRegister(src_size*8)) + c.gABC(n, opcBitandInt, dest, tmp3, tmp2) + else: + c.gABC(n, opcAsgnInt, dest, tmp) + c.freeTemp(tmp) + c.freeTemp(tmp2) + c.freeTemp(tmp3) + else: + globalError(n.info, errGenerated, "VM is only allowed to 'cast' between integers of same size") + proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = case m of mAnd: c.genAndOr(n, opcFJmp, dest) @@ -1844,7 +1887,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = if allowCast in c.features: genConv(c, n, n.sons[1], dest, opcCast) else: - globalError(n.info, errGenerated, "VM is not allowed to 'cast'") + genIntCast(c, n, dest) of nkTypeOfExpr: genTypeLit(c, n.typ, dest) of nkComesFrom: |