bugfix: exception handling (still not correct)
This commit is contained in:
parent
909f7dbf8c
commit
c441cdb64c
18 changed files with 145 additions and 39 deletions
|
|
@ -26,7 +26,7 @@ type
|
||||||
when defined(posix):
|
when defined(posix):
|
||||||
type
|
type
|
||||||
TTime* = distinct int ## distinct type that represents a time
|
TTime* = distinct int ## distinct type that represents a time
|
||||||
|
|
||||||
Ttimeval {.importc: "struct timeval", header: "<sys/select.h>",
|
Ttimeval {.importc: "struct timeval", header: "<sys/select.h>",
|
||||||
final, pure.} = object ## struct timeval
|
final, pure.} = object ## struct timeval
|
||||||
tv_sec: int ## Seconds.
|
tv_sec: int ## Seconds.
|
||||||
|
|
@ -40,11 +40,14 @@ when defined(posix):
|
||||||
importc: "gettimeofday", header: "<sys/time.h>".}
|
importc: "gettimeofday", header: "<sys/time.h>".}
|
||||||
|
|
||||||
elif defined(windows):
|
elif defined(windows):
|
||||||
|
import winlean
|
||||||
|
|
||||||
when defined(vcc):
|
when defined(vcc):
|
||||||
# newest version of Visual C++ defines time_t to be of 64 bits
|
# newest version of Visual C++ defines time_t to be of 64 bits
|
||||||
type TTime* = distinct int64
|
type TTime* = distinct int64
|
||||||
else:
|
else:
|
||||||
type TTime* = distinct int32
|
type TTime* = distinct int32
|
||||||
|
|
||||||
elif defined(ECMAScript):
|
elif defined(ECMAScript):
|
||||||
type
|
type
|
||||||
TTime* {.final.} = object
|
TTime* {.final.} = object
|
||||||
|
|
@ -123,8 +126,8 @@ proc `$` *(time: TTime): string
|
||||||
## converts a calendar time to a string representation.
|
## converts a calendar time to a string representation.
|
||||||
|
|
||||||
proc getDateStr*(): string
|
proc getDateStr*(): string
|
||||||
## gets the current date as a string of the format
|
## gets the current date as a string of the format ``YYYY-MM-DD``.
|
||||||
## ``YYYY-MM-DD``.
|
|
||||||
proc getClockStr*(): string
|
proc getClockStr*(): string
|
||||||
## gets the current clock time as a string of the format ``HH:MM:SS``.
|
## 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
|
result = a - b <= 0
|
||||||
|
|
||||||
proc getStartMilsecs*(): int {.deprecated.}
|
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):
|
when not defined(ECMAScript):
|
||||||
# C wrapper:
|
# C wrapper:
|
||||||
|
|
@ -160,7 +182,7 @@ when not defined(ECMAScript):
|
||||||
PTimeInfo = ptr structTM
|
PTimeInfo = ptr structTM
|
||||||
PTime = ptr TTime
|
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 {.
|
proc localtime(timer: PTime): PTimeInfo {.
|
||||||
importc: "localtime", header: "<time.h>".}
|
importc: "localtime", header: "<time.h>".}
|
||||||
|
|
@ -177,8 +199,7 @@ when not defined(ECMAScript):
|
||||||
|
|
||||||
var
|
var
|
||||||
clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int
|
clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int
|
||||||
|
|
||||||
|
|
||||||
# our own procs on top of that:
|
# our own procs on top of that:
|
||||||
proc tmToTimeInfo(tm: structTM): TTimeInfo =
|
proc tmToTimeInfo(tm: structTM): TTimeInfo =
|
||||||
const
|
const
|
||||||
|
|
@ -213,13 +234,13 @@ when not defined(ECMAScript):
|
||||||
#echo "clocks per sec: ", clocksPerSec, "clock: ", int(clock())
|
#echo "clocks per sec: ", clocksPerSec, "clock: ", int(clock())
|
||||||
#return clock() div (clocksPerSec div 1000)
|
#return clock() div (clocksPerSec div 1000)
|
||||||
when defined(macosx):
|
when defined(macosx):
|
||||||
result = toInt(toFloat(clock()) / (toFloat(clocksPerSec) / 1000.0))
|
result = toInt(toFloat(int(clock())) / (toFloat(clocksPerSec) / 1000.0))
|
||||||
else:
|
else:
|
||||||
result = int(clock()) div (clocksPerSec div 1000)
|
result = int(clock()) div (clocksPerSec div 1000)
|
||||||
when false:
|
when false:
|
||||||
var a: Ttimeval
|
var a: Ttimeval
|
||||||
posix_gettimeofday(a)
|
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
|
#echo "result: ", result
|
||||||
|
|
||||||
proc getTime(): TTime = return timec(nil)
|
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,
|
var cTimeInfo = timeInfo # for C++ we have to make a copy,
|
||||||
# because the header of mktime is broken in my version of libc
|
# because the header of mktime is broken in my version of libc
|
||||||
return mktime(timeInfoToTM(cTimeInfo))
|
return mktime(timeInfoToTM(cTimeInfo))
|
||||||
|
|
||||||
proc toStringTillNL(p: cstring): string =
|
proc toStringTillNL(p: cstring): string =
|
||||||
result = ""
|
result = ""
|
||||||
var i = 0
|
var i = 0
|
||||||
while p[i] != '\0' and p[i] != '\10' and p[i] != '\13':
|
while p[i] != '\0' and p[i] != '\10' and p[i] != '\13':
|
||||||
add(result, p[i])
|
add(result, p[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
return result
|
|
||||||
|
|
||||||
proc `$`(timeInfo: TTimeInfo): string =
|
proc `$`(timeInfo: TTimeInfo): string =
|
||||||
# BUGFIX: asctime returns a newline at the end!
|
# BUGFIX: asctime returns a newline at the end!
|
||||||
|
|
@ -269,7 +289,26 @@ when not defined(ECMAScript):
|
||||||
proc winTimeToUnixTime*(t: int64): TTime =
|
proc winTimeToUnixTime*(t: int64): TTime =
|
||||||
## converts a Windows time to a UNIX `TTime` (``time_t``)
|
## converts a Windows time to a UNIX `TTime` (``time_t``)
|
||||||
result = TTime((t - epochDiff) div rateDiff)
|
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:
|
else:
|
||||||
proc getTime(): TTime {.importc: "new Date", nodecl.}
|
proc getTime(): TTime {.importc: "new Date", nodecl.}
|
||||||
|
|
||||||
|
|
|
||||||
0
lib/system.nim
Normal file → Executable file
0
lib/system.nim
Normal file → Executable file
27
lib/system/systhread.nim
Executable file
27
lib/system/systhread.nim
Executable file
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
0
lib/windows/psapi.nim
Normal file → Executable file
0
lib/windows/psapi.nim
Normal file → Executable file
|
|
@ -192,6 +192,9 @@ proc rdFileTime*(f: FILETIME): int64 =
|
||||||
proc rdFileSize*(f: TWin32FindData): int64 =
|
proc rdFileSize*(f: TWin32FindData): int64 =
|
||||||
result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32)
|
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",
|
proc Sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32",
|
||||||
importc: "Sleep".}
|
importc: "Sleep".}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -268,17 +268,13 @@ proc getRaiseFrmt(p: BProc): string =
|
||||||
result = "raiseException((E_Base*)$1, $2);$n"
|
result = "raiseException((E_Base*)$1, $2);$n"
|
||||||
|
|
||||||
proc genRaiseStmt(p: BProc, t: PNode) =
|
proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
var
|
|
||||||
e: PRope
|
|
||||||
a: TLoc
|
|
||||||
typ: PType
|
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
if t.sons[0] != nil:
|
if t.sons[0] != nil:
|
||||||
if gCmd != cmdCompileToCpp: useMagic(p.module, "raiseException")
|
if gCmd != cmdCompileToCpp: useMagic(p.module, "raiseException")
|
||||||
|
var a: TLoc
|
||||||
InitLocExpr(p, t.sons[0], a)
|
InitLocExpr(p, t.sons[0], a)
|
||||||
e = rdLoc(a)
|
var e = rdLoc(a)
|
||||||
typ = t.sons[0].typ
|
var typ = skipTypes(t.sons[0].typ, abstractPtrs)
|
||||||
while typ.kind in {tyVar, tyRef, tyPtr}: typ = typ.sons[0]
|
|
||||||
appf(p.s[cpsStmts], getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
|
appf(p.s[cpsStmts], getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
|
||||||
else:
|
else:
|
||||||
# reraise the last exception:
|
# reraise the last exception:
|
||||||
|
|
@ -385,7 +381,8 @@ proc genStringCase(p: BProc, t: PNode) =
|
||||||
strings, bitMask, labId: int
|
strings, bitMask, labId: int
|
||||||
a: TLoc
|
a: TLoc
|
||||||
branches: TRopeSeq
|
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
|
strings = 0
|
||||||
for i in countup(1, sonsLen(t) - 1):
|
for i in countup(1, sonsLen(t) - 1):
|
||||||
if t.sons[i].kind == nkOfBranch: inc(strings, sonsLen(t.sons[i]) - 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]])
|
[intLiteral(j), branches[j]])
|
||||||
app(p.s[cpsStmts], '}' & tnl) # else statement:
|
app(p.s[cpsStmts], '}' & tnl) # else statement:
|
||||||
if t.sons[sonsLen(t) - 1].kind != nkOfBranch:
|
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)
|
genCaseSecondPass(p, t, labId)
|
||||||
else:
|
else:
|
||||||
genCaseGeneric(p, t, "", "if (eqStrings($1, $2)) goto $3;$n")
|
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):
|
for i in countup(0, sonsLen(b) - 2):
|
||||||
# last son is block
|
# last son is block
|
||||||
if (b.sons[i].Kind == nkRange) and
|
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
|
return true
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
|
|
@ -481,8 +479,10 @@ proc genCaseStmt(p: BProc, t: PNode) =
|
||||||
genStringCase(p, t)
|
genStringCase(p, t)
|
||||||
of tyFloat..tyFloat128:
|
of tyFloat..tyFloat128:
|
||||||
genCaseGeneric(p, t, "if ($1 >= $2 && $1 <= $3) goto $4;$n",
|
genCaseGeneric(p, t, "if ($1 >= $2 && $1 <= $3) goto $4;$n",
|
||||||
"if ($1 == $2) goto $3;$n") # ordinal type: generate a switch statement
|
"if ($1 == $2) goto $3;$n")
|
||||||
else: genOrdinalCase(p, t)
|
else:
|
||||||
|
# ordinal type: generate a switch statement
|
||||||
|
genOrdinalCase(p, t)
|
||||||
|
|
||||||
proc hasGeneralExceptSection(t: PNode): bool =
|
proc hasGeneralExceptSection(t: PNode): bool =
|
||||||
var length, i, blen: int
|
var length, i, blen: int
|
||||||
|
|
@ -561,8 +561,8 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
|
||||||
app(p.s[cpsStmts], "excHandler = excHandler->prev;" & tnl)
|
app(p.s[cpsStmts], "excHandler = excHandler->prev;" & tnl)
|
||||||
if (i < length) and (t.sons[i].kind == nkFinally):
|
if (i < length) and (t.sons[i].kind == nkFinally):
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
if rethrowFlag != nil:
|
if rethrowFlag != nil:
|
||||||
appf(p.s[cpsStmts], "if ($1) { throw; }$n", [rethrowFlag])
|
appf(p.s[cpsStmts], "if ($1) { throw; }$n", [rethrowFlag])
|
||||||
|
|
||||||
proc genTryStmt(p: BProc, t: PNode) =
|
proc genTryStmt(p: BProc, t: PNode) =
|
||||||
# code to generate:
|
# code to generate:
|
||||||
|
|
@ -630,9 +630,9 @@ proc genTryStmt(p: BProc, t: PNode) =
|
||||||
dec(p.nestedTryStmts)
|
dec(p.nestedTryStmts)
|
||||||
if (i < length) and (t.sons[i].kind == nkFinally):
|
if (i < length) and (t.sons[i].kind == nkFinally):
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
useMagic(p.module, "raiseException")
|
useMagic(p.module, "raiseException")
|
||||||
appf(p.s[cpsStmts], "if ($1.status != 0) { " &
|
appf(p.s[cpsStmts], "if ($1.status != 0) { " &
|
||||||
"raiseException($1.exc, $1.exc->name); }$n", [safePoint])
|
"raiseException($1.exc, $1.exc->name); }$n", [safePoint])
|
||||||
|
|
||||||
var
|
var
|
||||||
breakPointId: int = 0
|
breakPointId: int = 0
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import
|
||||||
os, lists, strutils, nstrtabs
|
os, lists, strutils, nstrtabs
|
||||||
|
|
||||||
const
|
const
|
||||||
hasTinyCBackend* = true
|
hasTinyCBackend* = false
|
||||||
|
|
||||||
type # please make sure we have under 32 options
|
type # please make sure we have under 32 options
|
||||||
# (improves code efficiency a lot!)
|
# (improves code efficiency a lot!)
|
||||||
|
|
|
||||||
13
tests/accept/compile/tcputime.nim
Executable file
13
tests/accept/compile/tcputime.nim
Executable file
|
|
@ -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
|
||||||
|
|
||||||
0
tests/accept/compile/tdictdestruct.nim
Normal file → Executable file
0
tests/accept/compile/tdictdestruct.nim
Normal file → Executable file
0
tests/accept/compile/tgetstartmilsecs.nim
Normal file → Executable file
0
tests/accept/compile/tgetstartmilsecs.nim
Normal file → Executable file
0
tests/accept/run/texplicitgeneric1.nim
Normal file → Executable file
0
tests/accept/run/texplicitgeneric1.nim
Normal file → Executable file
0
tests/accept/run/texplicitgeneric2.nim
Normal file → Executable file
0
tests/accept/run/texplicitgeneric2.nim
Normal file → Executable file
14
tests/accept/run/treraise.nim
Normal file → Executable file
14
tests/accept/run/treraise.nim
Normal file → Executable file
|
|
@ -8,10 +8,10 @@ proc genErrors(s: string) =
|
||||||
else:
|
else:
|
||||||
raise newException(EsomeotherErr, "bla")
|
raise newException(EsomeotherErr, "bla")
|
||||||
|
|
||||||
while True:
|
try:
|
||||||
try:
|
genErrors("errssor!")
|
||||||
genErrors("errssor!")
|
except ESomething:
|
||||||
except ESomething:
|
echo("Error happened")
|
||||||
echo("Error happened")
|
except:
|
||||||
except:
|
raise
|
||||||
raise
|
|
||||||
|
|
|
||||||
16
tests/accept/run/tunhandledexc.nim
Normal file
16
tests/accept/run/tunhandledexc.nim
Normal file
|
|
@ -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")
|
||||||
|
|
||||||
0
tests/accept/run/tvariantasgn.nim
Normal file → Executable file
0
tests/accept/run/tvariantasgn.nim
Normal file → Executable file
0
tests/accept/run/tvariantstack.nim
Normal file → Executable file
0
tests/accept/run/tvariantstack.nim
Normal file → Executable file
6
tests/accept/run/twrongexc.nim
Normal file
6
tests/accept/run/twrongexc.nim
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
try:
|
||||||
|
raise newException(EInvalidValue, "")
|
||||||
|
except EOverflow:
|
||||||
|
echo("Error caught")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -13,10 +13,9 @@ Bugfixes
|
||||||
- Bugfix: Passing a ``ref`` pointer to the untyped ``pointer`` type is invalid.
|
- Bugfix: Passing a ``ref`` pointer to the untyped ``pointer`` type is invalid.
|
||||||
- Bugfix: Updated ``keyval`` example.
|
- Bugfix: Updated ``keyval`` example.
|
||||||
- Bugfix: ``system.splitChunk`` still contained code for debug output.
|
- 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
|
- Bugfix: ``dialogs.ChooseFileToSave`` uses ``STOCK_SAVE`` instead of
|
||||||
``STOCK_OPEN`` for the GTK backend.
|
``STOCK_OPEN`` for the GTK backend.
|
||||||
|
- Bugfix: ``raise`` within an exception handler did not work.
|
||||||
|
|
||||||
|
|
||||||
Changes affecting backwards compatibility
|
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,
|
- Procs not marked as ``procvar`` cannot only be passed to a procvar anymore,
|
||||||
unless they are used in the same module.
|
unless they are used in the same module.
|
||||||
|
- Deprecated ``times.getStartMilsecs``: Use ``epochTime`` or ``cpuTime``
|
||||||
|
instead.
|
||||||
|
|
||||||
|
|
||||||
Additions
|
Additions
|
||||||
|
|
@ -33,6 +34,7 @@ Additions
|
||||||
needs to be recompiled.
|
needs to be recompiled.
|
||||||
- Added ``system.reopen``.
|
- Added ``system.reopen``.
|
||||||
- Added ``system.getCurrentException``.
|
- Added ``system.getCurrentException``.
|
||||||
|
- Added ``times.epochTime`` and ``times.cpuTime``.
|
||||||
- Implemented explicit type arguments for generics.
|
- Implemented explicit type arguments for generics.
|
||||||
- Implemented implicit type arguments for generics.
|
- Implemented implicit type arguments for generics.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue