diff options
-rwxr-xr-x | lib/pure/times.nim | 63 | ||||
-rwxr-xr-x[-rw-r--r--] | lib/system.nim | 0 | ||||
-rwxr-xr-x | lib/system/systhread.nim | 27 | ||||
-rwxr-xr-x[-rw-r--r--] | lib/windows/psapi.nim | 0 | ||||
-rwxr-xr-x | lib/windows/winlean.nim | 3 | ||||
-rwxr-xr-x | rod/ccgstmts.nim | 34 | ||||
-rwxr-xr-x | rod/options.nim | 2 | ||||
-rwxr-xr-x | tests/accept/compile/tcputime.nim | 13 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/accept/compile/tdictdestruct.nim | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/accept/compile/tgetstartmilsecs.nim | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/accept/run/texplicitgeneric1.nim | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/accept/run/texplicitgeneric2.nim | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/accept/run/treraise.nim | 14 | ||||
-rw-r--r-- | tests/accept/run/tunhandledexc.nim | 16 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/accept/run/tvariantasgn.nim | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/accept/run/tvariantstack.nim | 0 | ||||
-rw-r--r-- | tests/accept/run/twrongexc.nim | 6 | ||||
-rwxr-xr-x | web/news.txt | 6 |
18 files changed, 145 insertions, 39 deletions
diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 144a6eb4f..8af7395dd 100755 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -26,7 +26,7 @@ type when defined(posix): type TTime* = distinct int ## distinct type that represents a time - + Ttimeval {.importc: "struct timeval", header: "<sys/select.h>", final, pure.} = object ## struct timeval tv_sec: int ## Seconds. @@ -40,11 +40,14 @@ when defined(posix): importc: "gettimeofday", header: "<sys/time.h>".} elif defined(windows): + import winlean + when defined(vcc): # newest version of Visual C++ defines time_t to be of 64 bits type TTime* = distinct int64 else: type TTime* = distinct int32 + elif defined(ECMAScript): type TTime* {.final.} = object @@ -123,8 +126,8 @@ proc `$` *(time: TTime): string ## converts a calendar time to a string representation. proc getDateStr*(): string - ## gets the current date as a string of the format - ## ``YYYY-MM-DD``. + ## gets the current date as a string of the format ``YYYY-MM-DD``. + proc getClockStr*(): string ## gets the current clock time as a string of the format ``HH:MM:SS``. @@ -140,8 +143,27 @@ proc `<=` * (a, b: TTime): bool = result = a - b <= 0 proc getStartMilsecs*(): int {.deprecated.} - ## get the miliseconds from the start of the program + ## get the miliseconds from the start of the program. **Deprecated since + ## version 0.8.10.** Use ``realTime`` or ``cpuTime`` instead. +when not defined(ECMAScript): + proc epochTime*(): float + ## gets time after the UNIX epoch (1970) in seconds. It is a float + ## because sub-second resolution is likely to be supported (depending + ## on the hardware/OS). + + proc cpuTime*(): float + ## gets time spent that the CPU spent to run the current process in + ## seconds. This may be more useful for benchmarking than ``epochTime``. + ## However, it may measure the real time instead (depending on the OS). + ## The value of the result has no meaning. + ## To generate useful timing values, take the difference between + ## the results of two ``cpuTime`` calls: + ## + ## .. code-block:: nimrod + ## var t0 = cpuTime() + ## doWork() + ## echo "CPU time [s] ", cpuTime() - t0 when not defined(ECMAScript): # C wrapper: @@ -160,7 +182,7 @@ when not defined(ECMAScript): PTimeInfo = ptr structTM PTime = ptr TTime - TClock {.importc: "clock_t".} = distinct int #range[low(int)..high(int)] + TClock {.importc: "clock_t".} = distinct int proc localtime(timer: PTime): PTimeInfo {. importc: "localtime", header: "<time.h>".} @@ -177,8 +199,7 @@ when not defined(ECMAScript): var clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int - - + # our own procs on top of that: proc tmToTimeInfo(tm: structTM): TTimeInfo = const @@ -213,13 +234,13 @@ when not defined(ECMAScript): #echo "clocks per sec: ", clocksPerSec, "clock: ", int(clock()) #return clock() div (clocksPerSec div 1000) when defined(macosx): - result = toInt(toFloat(clock()) / (toFloat(clocksPerSec) / 1000.0)) + result = toInt(toFloat(int(clock())) / (toFloat(clocksPerSec) / 1000.0)) else: result = int(clock()) div (clocksPerSec div 1000) when false: var a: Ttimeval posix_gettimeofday(a) - result = a.tv_sec * 1000 + a.tv_usec + result = a.tv_sec * 1000'i64 + a.tv_usec div 1000'i64 #echo "result: ", result proc getTime(): TTime = return timec(nil) @@ -239,14 +260,13 @@ when not defined(ECMAScript): var cTimeInfo = timeInfo # for C++ we have to make a copy, # because the header of mktime is broken in my version of libc return mktime(timeInfoToTM(cTimeInfo)) - + proc toStringTillNL(p: cstring): string = result = "" var i = 0 while p[i] != '\0' and p[i] != '\10' and p[i] != '\13': add(result, p[i]) inc(i) - return result proc `$`(timeInfo: TTimeInfo): string = # BUGFIX: asctime returns a newline at the end! @@ -269,7 +289,26 @@ when not defined(ECMAScript): proc winTimeToUnixTime*(t: int64): TTime = ## converts a Windows time to a UNIX `TTime` (``time_t``) result = TTime((t - epochDiff) div rateDiff) - + + proc epochTime(): float = + when defined(posix): + var a: Ttimeval + posix_gettimeofday(a) + result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.001 + # why 0.001 instead of 0.00_0001? I don't know. + elif defined(windows): + var f: winlean.Filetime + GetSystemTimeAsFileTime(f) + var i64 = rdFileTime(f) - epochDiff + var secs = i64 div rateDiff + var subsecs = i64 mod rateDiff + result = toFloat(int(secs)) + toFloat(int(subsecs)) * 0.0000001 + else: + {.error: "unknown OS".} + + proc cpuTime(): float = + result = toFloat(int(clock())) / toFloat(clocksPerSec) + else: proc getTime(): TTime {.importc: "new Date", nodecl.} diff --git a/lib/system.nim b/lib/system.nim index 5265c2365..5265c2365 100644..100755 --- a/lib/system.nim +++ b/lib/system.nim diff --git a/lib/system/systhread.nim b/lib/system/systhread.nim new file mode 100755 index 000000000..611191e70 --- /dev/null +++ b/lib/system/systhread.nim @@ -0,0 +1,27 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2010 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +const + isMultiThreaded* = true + maxThreads = 256 + +type + TThread* {.final, pure.} = object + next: ptr TThread + TThreadFunc* = proc (closure: pointer) {.cdecl.} + +proc createThread*(t: var TThread, fn: TThreadFunc) = + nil + +proc destroyThread*(t: var TThread) = + nil + + + + diff --git a/lib/windows/psapi.nim b/lib/windows/psapi.nim index 7d53cf7ca..7d53cf7ca 100644..100755 --- a/lib/windows/psapi.nim +++ b/lib/windows/psapi.nim diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 10915272f..9ebd4504b 100755 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -192,6 +192,9 @@ proc rdFileTime*(f: FILETIME): int64 = proc rdFileSize*(f: TWin32FindData): int64 = result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32) +proc GetSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var FileTime) {. + importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall.} + proc Sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32", importc: "Sleep".} diff --git a/rod/ccgstmts.nim b/rod/ccgstmts.nim index 3cf2123c9..f011f32a0 100755 --- a/rod/ccgstmts.nim +++ b/rod/ccgstmts.nim @@ -268,17 +268,13 @@ proc getRaiseFrmt(p: BProc): string = result = "raiseException((E_Base*)$1, $2);$n" proc genRaiseStmt(p: BProc, t: PNode) = - var - e: PRope - a: TLoc - typ: PType genLineDir(p, t) if t.sons[0] != nil: if gCmd != cmdCompileToCpp: useMagic(p.module, "raiseException") + var a: TLoc InitLocExpr(p, t.sons[0], a) - e = rdLoc(a) - typ = t.sons[0].typ - while typ.kind in {tyVar, tyRef, tyPtr}: typ = typ.sons[0] + var e = rdLoc(a) + var typ = skipTypes(t.sons[0].typ, abstractPtrs) appf(p.s[cpsStmts], getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)]) else: # reraise the last exception: @@ -385,7 +381,8 @@ proc genStringCase(p: BProc, t: PNode) = strings, bitMask, labId: int a: TLoc branches: TRopeSeq - useMagic(p.module, "eqStrings") # count how many constant strings there are in the case: + useMagic(p.module, "eqStrings") + # count how many constant strings there are in the case: strings = 0 for i in countup(1, sonsLen(t) - 1): if t.sons[i].kind == nkOfBranch: inc(strings, sonsLen(t.sons[i]) - 1) @@ -411,7 +408,8 @@ proc genStringCase(p: BProc, t: PNode) = [intLiteral(j), branches[j]]) app(p.s[cpsStmts], '}' & tnl) # else statement: if t.sons[sonsLen(t) - 1].kind != nkOfBranch: - appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.labels)]) # third pass: generate statements + appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.labels)]) + # third pass: generate statements genCaseSecondPass(p, t, labId) else: genCaseGeneric(p, t, "", "if (eqStrings($1, $2)) goto $3;$n") @@ -420,7 +418,7 @@ proc branchHasTooBigRange(b: PNode): bool = for i in countup(0, sonsLen(b) - 2): # last son is block if (b.sons[i].Kind == nkRange) and - (b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit): + b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit: return true result = false @@ -481,8 +479,10 @@ proc genCaseStmt(p: BProc, t: PNode) = genStringCase(p, t) of tyFloat..tyFloat128: genCaseGeneric(p, t, "if ($1 >= $2 && $1 <= $3) goto $4;$n", - "if ($1 == $2) goto $3;$n") # ordinal type: generate a switch statement - else: genOrdinalCase(p, t) + "if ($1 == $2) goto $3;$n") + else: + # ordinal type: generate a switch statement + genOrdinalCase(p, t) proc hasGeneralExceptSection(t: PNode): bool = var length, i, blen: int @@ -561,8 +561,8 @@ proc genTryStmtCpp(p: BProc, t: PNode) = app(p.s[cpsStmts], "excHandler = excHandler->prev;" & tnl) if (i < length) and (t.sons[i].kind == nkFinally): genStmts(p, t.sons[i].sons[0]) - if rethrowFlag != nil: - appf(p.s[cpsStmts], "if ($1) { throw; }$n", [rethrowFlag]) + if rethrowFlag != nil: + appf(p.s[cpsStmts], "if ($1) { throw; }$n", [rethrowFlag]) proc genTryStmt(p: BProc, t: PNode) = # code to generate: @@ -630,9 +630,9 @@ proc genTryStmt(p: BProc, t: PNode) = dec(p.nestedTryStmts) if (i < length) and (t.sons[i].kind == nkFinally): genStmts(p, t.sons[i].sons[0]) - useMagic(p.module, "raiseException") - appf(p.s[cpsStmts], "if ($1.status != 0) { " & - "raiseException($1.exc, $1.exc->name); }$n", [safePoint]) + useMagic(p.module, "raiseException") + appf(p.s[cpsStmts], "if ($1.status != 0) { " & + "raiseException($1.exc, $1.exc->name); }$n", [safePoint]) var breakPointId: int = 0 diff --git a/rod/options.nim b/rod/options.nim index 9ce54a41c..28b58f40a 100755 --- a/rod/options.nim +++ b/rod/options.nim @@ -11,7 +11,7 @@ import os, lists, strutils, nstrtabs const - hasTinyCBackend* = true + hasTinyCBackend* = false type # please make sure we have under 32 options # (improves code efficiency a lot!) diff --git a/tests/accept/compile/tcputime.nim b/tests/accept/compile/tcputime.nim new file mode 100755 index 000000000..2fc46ee64 --- /dev/null +++ b/tests/accept/compile/tcputime.nim @@ -0,0 +1,13 @@ + +import times, os + +var e = epochTime() +var c = cpuTime() + +os.sleep(1500) + +e = epochTime() - e +c = cpuTime() - c + +echo "epochTime: ", e, " cpuTime: ", c + diff --git a/tests/accept/compile/tdictdestruct.nim b/tests/accept/compile/tdictdestruct.nim index 20ca4ba94..20ca4ba94 100644..100755 --- a/tests/accept/compile/tdictdestruct.nim +++ b/tests/accept/compile/tdictdestruct.nim diff --git a/tests/accept/compile/tgetstartmilsecs.nim b/tests/accept/compile/tgetstartmilsecs.nim index 340c78af1..340c78af1 100644..100755 --- a/tests/accept/compile/tgetstartmilsecs.nim +++ b/tests/accept/compile/tgetstartmilsecs.nim diff --git a/tests/accept/run/texplicitgeneric1.nim b/tests/accept/run/texplicitgeneric1.nim index 54fff5246..54fff5246 100644..100755 --- a/tests/accept/run/texplicitgeneric1.nim +++ b/tests/accept/run/texplicitgeneric1.nim diff --git a/tests/accept/run/texplicitgeneric2.nim b/tests/accept/run/texplicitgeneric2.nim index 9bd2f04c8..9bd2f04c8 100644..100755 --- a/tests/accept/run/texplicitgeneric2.nim +++ b/tests/accept/run/texplicitgeneric2.nim diff --git a/tests/accept/run/treraise.nim b/tests/accept/run/treraise.nim index 60b8640c4..18f2b5f54 100644..100755 --- a/tests/accept/run/treraise.nim +++ b/tests/accept/run/treraise.nim @@ -8,10 +8,10 @@ proc genErrors(s: string) = else: raise newException(EsomeotherErr, "bla") -while True: - try: - genErrors("errssor!") - except ESomething: - echo("Error happened") - except: - raise +try: + genErrors("errssor!") +except ESomething: + echo("Error happened") +except: + raise + diff --git a/tests/accept/run/tunhandledexc.nim b/tests/accept/run/tunhandledexc.nim new file mode 100644 index 000000000..36ba5418d --- /dev/null +++ b/tests/accept/run/tunhandledexc.nim @@ -0,0 +1,16 @@ +type + ESomething = object of E_Base + ESomeOtherErr = object of E_Base + +proc genErrors(s: string) = + if s == "error!": + raise newException(ESomething, "Test") + else: + raise newException(EsomeotherErr, "bla") + +when True: + try: + genErrors("errssor!") + except ESomething: + echo("Error happened") + diff --git a/tests/accept/run/tvariantasgn.nim b/tests/accept/run/tvariantasgn.nim index 7d51da845..7d51da845 100644..100755 --- a/tests/accept/run/tvariantasgn.nim +++ b/tests/accept/run/tvariantasgn.nim diff --git a/tests/accept/run/tvariantstack.nim b/tests/accept/run/tvariantstack.nim index 3df8197f2..3df8197f2 100644..100755 --- a/tests/accept/run/tvariantstack.nim +++ b/tests/accept/run/tvariantstack.nim diff --git a/tests/accept/run/twrongexc.nim b/tests/accept/run/twrongexc.nim new file mode 100644 index 000000000..8ba07bbce --- /dev/null +++ b/tests/accept/run/twrongexc.nim @@ -0,0 +1,6 @@ +try: + raise newException(EInvalidValue, "") +except EOverflow: + echo("Error caught") + + diff --git a/web/news.txt b/web/news.txt index 6a65782ff..301cd9ead 100755 --- a/web/news.txt +++ b/web/news.txt @@ -13,10 +13,9 @@ Bugfixes - Bugfix: Passing a ``ref`` pointer to the untyped ``pointer`` type is invalid. - Bugfix: Updated ``keyval`` example. - Bugfix: ``system.splitChunk`` still contained code for debug output. -- Bugfix: ``times.getStartMilsecs`` uses ``gettimeofday`` for Posix. It - used to use ``clock`` which has the wrong semantics. - Bugfix: ``dialogs.ChooseFileToSave`` uses ``STOCK_SAVE`` instead of ``STOCK_OPEN`` for the GTK backend. +- Bugfix: ``raise`` within an exception handler did not work. Changes affecting backwards compatibility @@ -24,6 +23,8 @@ Changes affecting backwards compatibility - Procs not marked as ``procvar`` cannot only be passed to a procvar anymore, unless they are used in the same module. +- Deprecated ``times.getStartMilsecs``: Use ``epochTime`` or ``cpuTime`` + instead. Additions @@ -33,6 +34,7 @@ Additions needs to be recompiled. - Added ``system.reopen``. - Added ``system.getCurrentException``. +- Added ``times.epochTime`` and ``times.cpuTime``. - Implemented explicit type arguments for generics. - Implemented implicit type arguments for generics. |