diff options
Diffstat (limited to 'compiler/jsgen.nim')
-rw-r--r-- | compiler/jsgen.nim | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 4772aecb5..a3423b1d5 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -33,7 +33,7 @@ import ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os, times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils, - intsets, cgmeth + intsets, cgmeth, lowerings type TTarget = enum @@ -113,7 +113,7 @@ proc rdLoc(a: TCompRes): PRope {.inline.} = result = ropef("$1[$2]", a.address, a.res) proc newProc(globals: PGlobals, module: BModule, procDef: PNode, - options: TOptions): PProc = + options: TOptions): PProc = result = PProc( blocks: @[], options: options, @@ -601,15 +601,13 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = if p.target == targetJS: app(p.body, "} finally {" & tnl & "excHandler = excHandler.prev;" & tnl) if i < length and n.sons[i].kind == nkFinally: - gen(p, n.sons[i].sons[0], a) - moveInto(p, a, r) + genStmt(p, n.sons[i].sons[0]) if p.target == targetJS: app(p.body, "}" & tnl) if p.target == targetLua: # we need to repeat the finally block for Lua ... if i < length and n.sons[i].kind == nkFinally: - gen(p, n.sons[i].sons[0], a) - moveInto(p, a, r) + genStmt(p, n.sons[i].sons[0]) proc genRaiseStmt(p: PProc, n: PNode) = genLineDir(p, n) @@ -942,22 +940,21 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = case s.kind of skVar, skLet, skResult: r.kind = resExpr - if mapType(n.typ) == etyObject: + if mapType(n.sons[0].typ) == etyObject: # make addr() a no-op: r.typ = etyNone r.res = s.loc.r r.address = nil - elif sfGlobal in s.flags: - # globals are always indirect accessible - r.typ = etyBaseIndex - r.address = toRope("Globals") - r.res = makeJSString(ropeToStr(s.loc.r)) - elif sfAddrTaken in s.flags: + elif {sfGlobal, sfAddrTaken} * s.flags != {}: + # for ease of code generation, we do not distinguish between + # sfAddrTaken and sfGlobal. r.typ = etyBaseIndex r.address = s.loc.r r.res = toRope("0") else: - internalError(n.info, "genAddr: 4") + # 'var openArray' for instance produces an 'addr' but this is harmless: + gen(p, n.sons[0], r) + #internalError(n.info, "genAddr: 4 " & renderTree(n)) else: internalError(n.info, "genAddr: 2") of nkCheckedFieldExpr: genCheckedFieldAddr(p, n, r) @@ -981,7 +978,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = of skVar, skLet, skParam, skTemp, skResult: if s.loc.r == nil: internalError(n.info, "symbol has no generated name: " & s.name.s) - var k = mapType(s.typ) + let k = mapType(s.typ) if k == etyBaseIndex: r.typ = etyBaseIndex if {sfAddrTaken, sfGlobal} * s.flags != {}: @@ -990,7 +987,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = else: r.address = s.loc.r r.res = con(s.loc.r, "_Idx") - elif k != etyObject and sfAddrTaken in s.flags: + elif k != etyObject and {sfAddrTaken, sfGlobal} * s.flags != {}: r.res = ropef("$1[0]", [s.loc.r]) else: r.res = s.loc.r @@ -1078,8 +1075,16 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) = proc genEcho(p: PProc, n: PNode, r: var TCompRes) = useMagic(p, "rawEcho") - app(r.res, "rawEcho") - genArgs(p, n, r) + app(r.res, "rawEcho(") + let n = n[1].skipConv + internalAssert n.kind == nkBracket + for i in countup(0, sonsLen(n) - 1): + let it = n.sons[i] + if it.typ.isCompileTimeOnly: continue + if i > 0: app(r.res, ", ") + genArg(p, it, r) + app(r.res, ")") + r.kind = resExpr proc putToSeq(s: string, indirect: bool): PRope = result = toRope(s) @@ -1162,8 +1167,9 @@ proc createVar(p: PProc, typ: PType, indirect: bool): PRope = internalError("createVar: " & $t.kind) result = nil -proc isIndirect(v: PSym): bool = - result = (sfAddrTaken in v.flags) and (mapType(v.typ) != etyObject) and +proc isIndirect(v: PSym): bool = + result = {sfAddrTaken, sfGlobal} * v.flags != {} and + (mapType(v.typ) != etyObject) and v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator} proc genVarInit(p: PProc, v: PSym, n: PNode) = @@ -1203,13 +1209,17 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) = proc genVarStmt(p: PProc, n: PNode) = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] - if a.kind == nkCommentStmt: continue - assert(a.kind == nkIdentDefs) - assert(a.sons[0].kind == nkSym) - var v = a.sons[0].sym - if lfNoDecl in v.loc.flags: continue - genLineDir(p, a) - genVarInit(p, v, a.sons[2]) + if a.kind != nkCommentStmt: + if a.kind == nkVarTuple: + let unpacked = lowerTupleUnpacking(a, p.prc) + genStmt(p, unpacked) + else: + assert(a.kind == nkIdentDefs) + assert(a.sons[0].kind == nkSym) + var v = a.sons[0].sym + if lfNoDecl notin v.loc.flags: + genLineDir(p, a) + genVarInit(p, v, a.sons[2]) proc genConstant(p: PProc, c: PSym) = if lfNoDecl notin c.loc.flags and not p.g.generatedSyms.containsOrIncl(c.id): @@ -1425,7 +1435,7 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) = r.res = toRope("{") r.kind = resExpr for i in countup(1, sonsLen(n) - 1): - if i > 0: app(r.res, ", ") + if i > 1: app(r.res, ", ") var it = n.sons[i] internalAssert it.kind == nkExprColonExpr gen(p, it.sons[1], a) @@ -1667,9 +1677,9 @@ proc newModule(module: PSym): BModule = proc genHeader(): PRope = result = ropef("/* Generated by the Nim Compiler v$1 */$n" & "/* (c) 2014 Andreas Rumpf */$n$n" & - "$nvar Globals = this;$n" & "var framePtr = null;$n" & - "var excHandler = null;$n", + "var excHandler = null;$n" & + "var lastJSError = null;$n", [toRope(VersionAsString)]) proc genModule(p: PProc, n: PNode) = |