summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xlib/pure/times.nim63
-rwxr-xr-x[-rw-r--r--]lib/system.nim0
-rwxr-xr-xlib/system/systhread.nim27
-rwxr-xr-x[-rw-r--r--]lib/windows/psapi.nim0
-rwxr-xr-xlib/windows/winlean.nim3
-rwxr-xr-xrod/ccgstmts.nim34
-rwxr-xr-xrod/options.nim2
-rwxr-xr-xtests/accept/compile/tcputime.nim13
-rwxr-xr-x[-rw-r--r--]tests/accept/compile/tdictdestruct.nim0
-rwxr-xr-x[-rw-r--r--]tests/accept/compile/tgetstartmilsecs.nim0
-rwxr-xr-x[-rw-r--r--]tests/accept/run/texplicitgeneric1.nim0
-rwxr-xr-x[-rw-r--r--]tests/accept/run/texplicitgeneric2.nim0
-rwxr-xr-x[-rw-r--r--]tests/accept/run/treraise.nim14
-rw-r--r--tests/accept/run/tunhandledexc.nim16
-rwxr-xr-x[-rw-r--r--]tests/accept/run/tvariantasgn.nim0
-rwxr-xr-x[-rw-r--r--]tests/accept/run/tvariantstack.nim0
-rw-r--r--tests/accept/run/twrongexc.nim6
-rwxr-xr-xweb/news.txt6
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.