Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
register callback for marshal in VM
  • Loading branch information
ringabout committed Mar 2, 2022
commit 339fa750c5854300564bc7d2aaa9f22b7d438d25
17 changes: 3 additions & 14 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import
std/[strutils, tables, parseutils],
msgs, vmdef, vmgen, nimsets, types, passes,
parser, vmdeps, idents, trees, renderer, options, transf,
vmmarshal, gorgeimpl, lineinfos, btrees, macrocacheimpl,
gorgeimpl, lineinfos, btrees, macrocacheimpl,
modulegraphs, sighashes, int128, vmprofiler

import ast except getstr
Expand Down Expand Up @@ -1219,7 +1219,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
c.callbacks[-prc.offset-2].value(
VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[ptr UncheckedArray[TFullReg]](addr regs[0]),
currentException: c.currentExceptionA,
currentLineInfo: c.debug[pc]))
currentLineInfo: c.debug[pc],
callbackNode: bb))
elif importcCond(c, prc):
if compiletimeFFI notin c.config.features:
globalError(c.config, c.debug[pc], "VM not allowed to do FFI, see `compiletimeFFI`")
Expand Down Expand Up @@ -2095,18 +2096,6 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
while typ.kind == tyTypeDesc and typ.len > 0: typ = typ[0]
createStr regs[ra]
regs[ra].node.strVal = typ.typeToString(preferExported)
of opcMarshalLoad:
let ra = instr.regA
let rb = instr.regB
inc pc
let typ = c.types[c.code[pc].regBx - wordExcess]
putIntoReg(regs[ra], loadAny(regs[rb].node.strVal, typ, c.cache, c.config, c.idgen))
of opcMarshalStore:
decodeB(rkNode)
inc pc
let typ = c.types[c.code[pc].regBx - wordExcess]
createStrKeepNode(regs[ra])
storeAny(regs[ra].node.strVal, typ, regs[rb].regToNode, c.config)

c.profiler.leave(c)

Expand Down
6 changes: 3 additions & 3 deletions compiler/vmdef.nim
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ type
opcNBindSym, opcNDynBindSym,
opcSetType, # dest.typ = types[Bx]
opcTypeTrait,
opcMarshalLoad, opcMarshalStore,
opcSymOwner,
opcSymIsInstantiationOf

Expand Down Expand Up @@ -238,6 +237,7 @@ type
slots*: ptr UncheckedArray[TFullReg]
currentException*: PNode
currentLineInfo*: TLineInfo
callbackNode*: PNode
VmCallback* = proc (args: VmArgs) {.closure.}

PCtx* = ref TCtx
Expand Down Expand Up @@ -307,8 +307,8 @@ proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.disca
const
firstABxInstr* = opcTJmp
largeInstrs* = { # instructions which use 2 int32s instead of 1:
opcSubStr, opcConv, opcCast, opcNewSeq, opcOf,
opcMarshalLoad, opcMarshalStore}
opcSubStr, opcConv, opcCast, opcNewSeq, opcOf
}
slotSomeTemp* = slotTempUnknown
relativeJumps* = {opcTJmp, opcFJmp, opcJmp, opcJmpBack}

Expand Down
27 changes: 0 additions & 27 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,6 @@ proc codeListing(c: PCtx, result: var string, start=0; last = -1) =
let idx = x.regBx-wordExcess
result.addf("\t$#\tr$#, $# ($#)", opc.toStr, x.regA,
c.constants[idx].renderTree, $idx)
elif opc in {opcMarshalLoad, opcMarshalStore}:
let y = c.code[i+1]
result.addf("\t$#\tr$#, r$#, $#", opc.toStr, x.regA, x.regB,
c.types[y.regBx-wordExcess].typeToString)
inc i
else:
result.addf("\t$#\tr$#, $#", opc.toStr, x.regA, x.regBx-wordExcess)
result.add("\t# ")
Expand Down Expand Up @@ -1383,22 +1378,6 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
# mGCref, mGCunref,
globalError(c.config, n.info, "cannot generate code for: " & $m)

proc genMarshalLoad(c: PCtx, n: PNode, dest: var TDest) =
## Signature: proc to*[T](data: string): T
if dest < 0: dest = c.getTemp(n.typ)
var tmp = c.genx(n[1])
c.gABC(n, opcMarshalLoad, dest, tmp)
c.gABx(n, opcMarshalLoad, 0, c.genType(n.typ))
c.freeTemp(tmp)

proc genMarshalStore(c: PCtx, n: PNode, dest: var TDest) =
## Signature: proc `$$`*[T](x: T): string
if dest < 0: dest = c.getTemp(n.typ)
var tmp = c.genx(n[1])
c.gABC(n, opcMarshalStore, dest, tmp)
c.gABx(n, opcMarshalStore, 0, c.genType(n[1].typ))
c.freeTemp(tmp)

proc unneededIndirection(n: PNode): bool =
n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef

Expand Down Expand Up @@ -2054,12 +2033,6 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
elif s.kind == skMethod:
localError(c.config, n.info, "cannot call method " & s.name.s &
" at compile time")
elif matches(s, "stdlib.marshal.to"):
# XXX marshal load&store should not be opcodes, but use the
# general callback mechanisms.
genMarshalLoad(c, n, dest)
elif matches(s, "stdlib.marshal.$$"):
genMarshalStore(c, n, dest)
else:
genCall(c, n, dest)
clearDest(c, n, dest)
Expand Down
38 changes: 37 additions & 1 deletion compiler/vmops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ from system/formatfloat import addFloatRoundtrip, addFloatSprintf


# There are some useful procs in vmconv.
import vmconv
import vmconv, vmmarshal

template mathop(op) {.dirty.} =
registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`)
Expand Down Expand Up @@ -139,6 +139,7 @@ when defined(nimHasInvariant):
of backend: result = $conf.backend
of libPath: result = conf.libpath.string
of gc: result = $conf.selectedGC
of mm: result = $conf.selectedGC

proc querySettingSeqImpl(conf: ConfigRef, switch: BiggestInt): seq[string] =
template copySeq(field: untyped): untyped =
Expand All @@ -155,6 +156,9 @@ when defined(nimHasInvariant):
proc stackTrace2(c: PCtx, msg: string, n: PNode) =
stackTrace(c, PStackFrame(prc: c.prc.sym, comesFrom: 0, next: nil), c.exceptionInstr, msg, n.info)


import astalgo

proc registerAdditionalOps*(c: PCtx) =

template wrapIterator(fqname: string, iter: untyped) =
Expand Down Expand Up @@ -349,3 +353,35 @@ proc registerAdditionalOps*(c: PCtx) =
addFloatSprintf(p.strVal, x)

wrapIterator("stdlib.os.envPairsImplSeq"): envPairs()

registerCallback c, "stdlib.marshal.to", proc(a: VmArgs) =
let typ = a.callbackNode.sym.typ[0]
case typ.kind
of tyInt..tyInt64, tyUInt..tyUInt64:
setResult(a, loadAny(a.getString(0), typ, c.cache, c.config, c.idgen).intVal)
of tyFloat..tyFloat128:
setResult(a, loadAny(a.getString(0), typ, c.cache, c.config, c.idgen).floatVal)
else:
setResult(a, loadAny(a.getString(0), typ, c.cache, c.config, c.idgen))


registerCallback c, "stdlib.marshal.$$", proc(a: VmArgs) =
let p = a.getReg(0)
var res: string

var node: PNode
case p.kind
of rkInt:
node = newIntNode(nkIntLit, p.intVal)
of rkFloat:
node = newFloatNode(nkFloatLit, p.floatVal)
of rkNode:
node = p.node
of rkRegisterAddr:
node = p.regAddr.node
of rkNodeAddr:
node = p.nodeAddr[]
else: doAssert false

storeAny(res, a.callbackNode.sym.typ[1], node, c.config)
setResult(a, res)
23 changes: 23 additions & 0 deletions tests/stdlib/tmarshal.nim
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,26 @@ block:

let a: ref A = new(B)
doAssert $$a[] == "{}" # not "{f: 0}"

template checkMarshal(data: typed) =
let orig = data
let m = $$orig
let old = to[typeof(orig)](m)
doAssert data == old

template main() =
type
Book = object
page: int
name: string

let book = Book(page: 12, name: "persona")

checkMarshal(486)
checkMarshal(3.14)
checkMarshal("azure sky")
checkMarshal(book)


static: main()
main()