fix #21045; getTime with vmopsDanger is broken; alternative to #21054 (#21056)

* fix #21045 getTime with vmopsDanger is broken; alternative to #21054

* typo
This commit is contained in:
ringabout
2022-12-11 01:57:19 +08:00
committed by GitHub
parent 7a18c1ef44
commit 07be1791ba
5 changed files with 51 additions and 22 deletions

View File

@@ -3283,6 +3283,7 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode,
if constOrNil != nil:
for i in 1..<constOrNil.len:
if constOrNil[i].kind == nkExprColonExpr:
assert constOrNil[i][0].kind == nkSym, "illformed object constr; the field is not a sym"
if constOrNil[i][0].sym.name.id == field.name.id:
genBracedInit(p, constOrNil[i][1], isConst, field.typ, result)
return

View File

@@ -1,4 +1,6 @@
import ast
import ast, idents, lineinfos, astalgo
import vmdef
import std/times
template elementType*(T: typedesc): typedesc =
typeof(block:
@@ -43,3 +45,12 @@ proc toLit*[T](a: T): PNode =
else:
static: doAssert false, "not yet supported: " & $T # add as needed
proc toTimeLit*(a: Time, c: PCtx, obj: PNode, info: TLineInfo): PNode =
# probably refactor it into `toLit` in the future
result = newTree(nkObjConstr)
result.add(newNode(nkEmpty)) # can be changed to a symbol according to PType
for k, ai in fieldPairs(a):
let reti = newNode(nkExprColonExpr)
reti.add newSymNode(lookupInRecord(obj, getIdent(c.cache, k)), info)
reti.add ai.toLit
result.add reti

View File

@@ -328,8 +328,9 @@ proc registerAdditionalOps*(c: PCtx) =
registerCallback c, "stdlib.osproc.execCmdEx", proc (a: VmArgs) {.nimcall.} =
let options = getNode(a, 1).fromLit(set[osproc.ProcessOption])
a.setResult osproc.execCmdEx(getString(a, 0), options).toLit
registerCallback c, "stdlib.times.getTime", proc (a: VmArgs) {.nimcall.} =
setResult(a, times.getTime().toLit)
registerCallback c, "stdlib.times.getTimeImpl", proc (a: VmArgs) =
let obj = a.getNode(0).typ.n
setResult(a, times.getTime().toTimeLit(c, obj, a.currentLineInfo))
proc getEffectList(c: PCtx; a: VmArgs; effectIndex: int) =
let fn = getNode(a, 0)

View File

@@ -953,27 +953,33 @@ proc toWinTime*(t: Time): int64 =
## since `1601-01-01T00:00:00Z`).
result = t.seconds * rateDiff + epochDiff + t.nanosecond div 100
proc getTimeImpl(typ: typedesc[Time]): Time =
discard "implemented in the vm"
proc getTime*(): Time {.tags: [TimeEffect], benign.} =
## Gets the current time as a `Time` with up to nanosecond resolution.
when defined(js):
let millis = newDate().getTime()
let seconds = convert(Milliseconds, Seconds, millis)
let nanos = convert(Milliseconds, Nanoseconds,
millis mod convert(Seconds, Milliseconds, 1).int)
result = initTime(seconds, nanos)
elif defined(macosx):
var a {.noinit.}: Timeval
gettimeofday(a)
result = initTime(a.tv_sec.int64,
convert(Microseconds, Nanoseconds, a.tv_usec.int))
elif defined(posix):
var ts {.noinit.}: Timespec
discard clock_gettime(CLOCK_REALTIME, ts)
result = initTime(ts.tv_sec.int64, ts.tv_nsec.int)
elif defined(windows):
var f {.noinit.}: FILETIME
getSystemTimeAsFileTime(f)
result = fromWinTime(rdFileTime(f))
when nimvm:
result = getTimeImpl(Time)
else:
when defined(js):
let millis = newDate().getTime()
let seconds = convert(Milliseconds, Seconds, millis)
let nanos = convert(Milliseconds, Nanoseconds,
millis mod convert(Seconds, Milliseconds, 1).int)
result = initTime(seconds, nanos)
elif defined(macosx):
var a {.noinit.}: Timeval
gettimeofday(a)
result = initTime(a.tv_sec.int64,
convert(Microseconds, Nanoseconds, a.tv_usec.int))
elif defined(posix):
var ts {.noinit.}: Timespec
discard clock_gettime(CLOCK_REALTIME, ts)
result = initTime(ts.tv_sec.int64, ts.tv_nsec.int)
elif defined(windows):
var f {.noinit.}: FILETIME
getSystemTimeAsFileTime(f)
result = fromWinTime(rdFileTime(f))
proc `-`*(a, b: Time): Duration {.operator, extern: "ntDiffTime".} =
## Computes the duration between two points in time.

10
tests/vm/tvmopsDanger.nim Normal file
View File

@@ -0,0 +1,10 @@
discard """
cmd: "nim c --experimental:vmopsDanger -r $file"
"""
when defined(nimPreviewSlimSystem):
import std/assertions
import std/times
const foo = getTime()
let bar = foo
doAssert bar > low(Time)