diff options
-rw-r--r-- | compiler/jsgen.nim | 15 | ||||
-rw-r--r-- | compiler/nimrod.nim | 8 | ||||
-rw-r--r-- | lib/system/jssys.nim | 54 |
3 files changed, 51 insertions, 26 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index a34d8f123..373a11e9a 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -564,7 +564,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = moveInto(p, a, r) var i = 1 if p.target == targetJS and length > 1 and n.sons[i].kind == nkExceptBranch: - appf(p.body, "} catch (EXC) {$n") + appf(p.body, "} catch (EXC) {$n lastJSError = EXC;$n") elif p.target == targetLua: appf(p.body, "end)$n") while i < length and n.sons[i].kind == nkExceptBranch: @@ -1114,6 +1114,8 @@ proc createVar(p: PProc, typ: PType, indirect: bool): PRope = var e = elemType(t) if length > 32: useMagic(p, "arrayConstr") + # XXX: arrayConstr depends on nimCopy. This line shouldn't be necessary. + useMagic(p, "nimCopy") result = ropef("arrayConstr($1, $2, $3)", [toRope(length), createVar(p, e, false), genTypeInfo(p, e)]) else: @@ -1314,7 +1316,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString: binaryExpr(p, n, r, "", "$1 += $2") else: - binaryExpr(p, n, r, "", "$1 = ($1.slice(0,-1)).concat($2)") + binaryExpr(p, n, r, "", "$1 = ($1.slice(0, -1)).concat($2)") # XXX: make a copy of $2, because of Javascript's sucking semantics of mAppendSeqElem: binaryExpr(p, n, r, "", "$1.push($2)") of mConStrStr: genConStrStr(p, n, r) @@ -1341,7 +1343,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = of ast.mDec: if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2") else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") - of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = ($2)-1") + of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0") of mSetLengthSeq: binaryExpr(p, n, r, "", "$1.length = $2") of mCard: unaryExpr(p, n, r, "SetCard", "SetCard($1)") of mLtSet: binaryExpr(p, n, r, "SetLt", "SetLt($1, $2)") @@ -1698,7 +1700,12 @@ proc myClose(b: PPassContext, n: PNode): PNode = var m = BModule(b) if sfMainModule in m.module.flags: let code = wholeCode(m) - var outfile = changeFileExt(completeCFilePath(m.module.filename), "js") + let outfile = + if options.outFile.len > 0: + if options.outFile.isAbsolute: options.outFile + else: getCurrentDir() / options.outFile + else: + changeFileExt(completeCFilePath(m.module.filename), "js") discard writeRopeIfNotEqual(con(genHeader(), code), outfile) proc myOpenCached(s: PSym, rd: PRodReader): PPassContext = diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 38d440ade..efe3d83bf 100644 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -61,8 +61,12 @@ proc handleCmdLine() = tccgen.run() if optRun in gGlobalOptions: if gCmd == cmdCompileToJS: - var ex = quoteShell( - completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir)) + var ex: string + if options.outFile.len > 0: + ex = options.outFile.prependCurDir.quoteShell + else: + ex = quoteShell( + completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir)) execExternalProgram("node " & ex & ' ' & service.arguments) else: var binPath: string diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 1720804c4..52f8873cf 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -12,7 +12,7 @@ when defined(nodejs): else: proc alert*(s: cstring) {.importc, nodecl.} -proc log*(s: cstring) {.importc: "console.log", nodecl.} +proc log*(s: cstring) {.importc: "console.log", varargs, nodecl.} type PSafePoint = ptr TSafePoint @@ -27,11 +27,19 @@ type line: int # current line number filename: cstring + PJSError = ref object + columnNumber {.importc.}: int + fileName {.importc.}: cstring + lineNumber {.importc.}: int + message {.importc.}: cstring + stack {.importc.}: cstring + var framePtr {.importc, nodecl, volatile.}: PCallFrame excHandler {.importc, nodecl, volatile.}: PSafePoint = nil # list of exception handlers # a global variable for the root of all try blocks + lastJSError {.importc, nodecl, volatile.}: PJSError = nil {.push stacktrace: off, profiler:off.} proc nimBoolToStr(x: bool): string {.compilerproc.} = @@ -43,8 +51,12 @@ proc nimCharToStr(x: char): string {.compilerproc.} = result[0] = x proc getCurrentExceptionMsg*(): string = - if excHandler != nil: return $excHandler.exc.msg - return "" + if excHandler != nil and excHandler.exc != nil: + return $excHandler.exc.msg + elif lastJSError != nil: + return $lastJSError.message + else: + return "" proc auxWriteStackTrace(f: PCallFrame): string = type @@ -77,11 +89,13 @@ proc auxWriteStackTrace(f: PCallFrame): string = add(result, "\n") proc rawWriteStackTrace(): string = - if framePtr == nil: - result = "No stack traceback available\n" - else: - result = "Traceback (most recent call last)\n"& auxWriteStackTrace(framePtr) + if framePtr != nil: + result = "Traceback (most recent call last)\n" & auxWriteStackTrace(framePtr) framePtr = nil + elif lastJSError != nil: + result = $lastJSError.stack + else: + result = "No stack traceback available\n" proc raiseException(e: ref E_Base, ename: cstring) {. compilerproc, asmNoStackFrame.} = @@ -472,17 +486,17 @@ proc ze*(a: int): int {.compilerproc.} = proc ze64*(a: int64): int64 {.compilerproc.} = result = a -proc ToU8(a: int): int8 {.asmNoStackFrame, compilerproc.} = +proc toU8*(a: int): int8 {.asmNoStackFrame, compilerproc.} = asm """ return `a`; """ -proc ToU16(a: int): int16 {.asmNoStackFrame, compilerproc.} = +proc toU16*(a: int): int16 {.asmNoStackFrame, compilerproc.} = asm """ return `a`; """ -proc ToU32(a: int): int32 {.asmNoStackFrame, compilerproc.} = +proc toU32*(a: int64): int32 {.asmNoStackFrame, compilerproc.} = asm """ return `a`; """ @@ -503,17 +517,17 @@ proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.} proc nimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} = case n.kind - of nkNone: sysAssert(false, "NimCopyAux") + of nkNone: sysAssert(false, "nimCopyAux") of nkSlot: - asm "`dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ);" + asm "`dest`[`n`.offset] = nimCopy(`src`[`n`.offset], `n`.typ);" of nkList: for i in 0..n.len-1: - NimCopyAux(dest, src, n.sons[i]) + nimCopyAux(dest, src, n.sons[i]) of nkCase: asm """ - `dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ); + `dest`[`n`.offset] = nimCopy(`src`[`n`.offset], `n`.typ); for (var i = 0; i < `n`.sons.length; ++i) { - NimCopyAux(`dest`, `src`, `n`.sons[i][1]); + nimCopyAux(`dest`, `src`, `n`.sons[i][1]); } """ @@ -534,17 +548,17 @@ proc nimCopy(x: pointer, ti: PNimType): pointer = for (var key in `x`) { `result`[key] = `x`[key]; } """ of tyTuple, tyObject: - if ti.base != nil: result = NimCopy(x, ti.base) + if ti.base != nil: result = nimCopy(x, ti.base) elif ti.kind == tyObject: asm "`result` = {m_type: `ti`};" else: asm "`result` = {};" - NimCopyAux(result, x, ti.node) + nimCopyAux(result, x, ti.node) of tySequence, tyArrayConstr, tyOpenArray, tyArray: asm """ `result` = new Array(`x`.length); for (var i = 0; i < `x`.length; ++i) { - `result`[i] = NimCopy(`x`[i], `ti`.base); + `result`[i] = nimCopy(`x`[i], `ti`.base); } """ of tyString: @@ -584,12 +598,12 @@ proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} = else: result = nil -proc ArrayConstr(len: int, value: pointer, typ: PNimType): pointer {. +proc arrayConstr(len: int, value: pointer, typ: PNimType): pointer {. asmNoStackFrame, compilerproc.} = # types are fake asm """ var result = new Array(`len`); - for (var i = 0; i < `len`; ++i) result[i] = NimCopy(`value`, `typ`); + for (var i = 0; i < `len`; ++i) result[i] = nimCopy(`value`, `typ`); return result; """ |