vm.nim 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This file implements the new evaluation engine for Nim code.
  10. ## An instruction is 1-3 int32s in memory, it is a register based VM.
  11. import ast except getstr
  12. import
  13. strutils, msgs, vmdef, vmgen, nimsets, types, passes,
  14. parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
  15. vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl,
  16. modulegraphs, sighashes, int128
  17. from semfold import leValueConv, ordinalValToString
  18. from evaltempl import evalTemplate
  19. const
  20. traceCode = defined(nimVMDebug)
  21. when hasFFI:
  22. import evalffi
  23. type
  24. PStackFrame* = ref TStackFrame
  25. TStackFrame* = object
  26. prc: PSym # current prc; proc that is evaluated
  27. slots: seq[TFullReg] # parameters passed to the proc + locals;
  28. # parameters come first
  29. next: PStackFrame # for stacking
  30. comesFrom: int
  31. safePoints: seq[int] # used for exception handling
  32. # XXX 'break' should perform cleanup actions
  33. # What does the C backend do for it?
  34. proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int; recursionLimit=100) =
  35. if x != nil:
  36. if recursionLimit == 0:
  37. var calls = 0
  38. var x = x
  39. while x != nil:
  40. inc calls
  41. x = x.next
  42. msgWriteln(c.config, $calls & " calls omitted\n")
  43. return
  44. stackTraceAux(c, x.next, x.comesFrom, recursionLimit-1)
  45. var info = c.debug[pc]
  46. # we now use a format similar to the one in lib/system/excpt.nim
  47. var s = ""
  48. # todo: factor with quotedFilename
  49. if optExcessiveStackTrace in c.config.globalOptions:
  50. s = toFullPath(c.config, info)
  51. else:
  52. s = toFilename(c.config, info)
  53. var line = toLinenumber(info)
  54. var col = toColumn(info)
  55. if line > 0:
  56. s.add('(')
  57. s.add($line)
  58. s.add(", ")
  59. s.add($(col + ColOffset))
  60. s.add(')')
  61. if x.prc != nil:
  62. for k in 1..max(1, 25-s.len): s.add(' ')
  63. s.add(x.prc.name.s)
  64. msgWriteln(c.config, s)
  65. proc stackTraceImpl(c: PCtx, tos: PStackFrame, pc: int,
  66. msg: string, lineInfo: TLineInfo, infoOrigin: InstantiationInfo) {.noinline.} =
  67. # noinline to avoid code bloat
  68. msgWriteln(c.config, "stack trace: (most recent call last)")
  69. stackTraceAux(c, tos, pc)
  70. let action = if c.mode == emRepl: doRaise else: doNothing
  71. # XXX test if we want 'globalError' for every mode
  72. let lineInfo = if lineInfo == TLineInfo.default: c.debug[pc] else: lineInfo
  73. liMessage(c.config, lineInfo, errGenerated, msg, action, infoOrigin)
  74. template stackTrace(c: PCtx, tos: PStackFrame, pc: int,
  75. msg: string, lineInfo: TLineInfo = TLineInfo.default) =
  76. stackTraceImpl(c, tos, pc, msg, lineInfo, instantiationInfo(-2, fullPaths = true))
  77. return
  78. proc bailOut(c: PCtx; tos: PStackFrame) =
  79. stackTrace(c, tos, c.exceptionInstr, "unhandled exception: " &
  80. c.currentExceptionA[3].skipColon.strVal &
  81. " [" & c.currentExceptionA[2].skipColon.strVal & "]")
  82. when not defined(nimComputedGoto):
  83. {.pragma: computedGoto.}
  84. proc ensureKind(n: var TFullReg, kind: TRegisterKind) =
  85. if n.kind != kind:
  86. n = TFullReg(kind: kind)
  87. template ensureKind(k: untyped) {.dirty.} =
  88. ensureKind(regs[ra], k)
  89. template decodeB(k: untyped) {.dirty.} =
  90. let rb = instr.regB
  91. ensureKind(k)
  92. template decodeBC(k: untyped) {.dirty.} =
  93. let rb = instr.regB
  94. let rc = instr.regC
  95. ensureKind(k)
  96. template declBC() {.dirty.} =
  97. let rb = instr.regB
  98. let rc = instr.regC
  99. template decodeBImm(k: untyped) {.dirty.} =
  100. let rb = instr.regB
  101. let imm = instr.regC - byteExcess
  102. ensureKind(k)
  103. template decodeBx(k: untyped) {.dirty.} =
  104. let rbx = instr.regBx - wordExcess
  105. ensureKind(k)
  106. template move(a, b: untyped) {.dirty.} = system.shallowCopy(a, b)
  107. # XXX fix minor 'shallowCopy' overloading bug in compiler
  108. proc derefPtrToReg(address: BiggestInt, typ: PType, r: var TFullReg, isAssign: bool): bool =
  109. # nim bug: `isAssign: static bool` doesn't work, giving odd compiler error
  110. template fun(field, T, rkind) =
  111. if isAssign:
  112. cast[ptr T](address)[] = T(r.field)
  113. else:
  114. r.ensureKind(rkind)
  115. let val = cast[ptr T](address)[]
  116. when T is SomeInteger:
  117. r.field = BiggestInt(val)
  118. else:
  119. r.field = val
  120. return true
  121. ## see also typeinfo.getBiggestInt
  122. case typ.kind
  123. of tyInt: fun(intVal, int, rkInt)
  124. of tyInt8: fun(intVal, int8, rkInt)
  125. of tyInt16: fun(intVal, int16, rkInt)
  126. of tyInt32: fun(intVal, int32, rkInt)
  127. of tyInt64: fun(intVal, int64, rkInt)
  128. of tyUInt: fun(intVal, uint, rkInt)
  129. of tyUInt8: fun(intVal, uint8, rkInt)
  130. of tyUInt16: fun(intVal, uint16, rkInt)
  131. of tyUInt32: fun(intVal, uint32, rkInt)
  132. of tyUInt64: fun(intVal, uint64, rkInt) # note: differs from typeinfo.getBiggestInt
  133. of tyFloat: fun(floatVal, float, rkFloat)
  134. of tyFloat32: fun(floatVal, float32, rkFloat)
  135. of tyFloat64: fun(floatVal, float64, rkFloat)
  136. else: return false
  137. proc createStrKeepNode(x: var TFullReg; keepNode=true) =
  138. if x.node.isNil or not keepNode:
  139. x.node = newNode(nkStrLit)
  140. elif x.node.kind == nkNilLit and keepNode:
  141. when defined(useNodeIds):
  142. let id = x.node.id
  143. x.node[] = TNode(kind: nkStrLit)
  144. when defined(useNodeIds):
  145. x.node.id = id
  146. elif x.node.kind notin {nkStrLit..nkTripleStrLit} or
  147. nfAllConst in x.node.flags:
  148. # XXX this is hacky; tests/txmlgen triggers it:
  149. x.node = newNode(nkStrLit)
  150. # It not only hackey, it is also wrong for tgentemplate. The primary
  151. # cause of bugs like these is that the VM does not properly distinguish
  152. # between variable definitions (var foo = e) and variable updates (foo = e).
  153. include vmhooks
  154. template createStr(x) =
  155. x.node = newNode(nkStrLit)
  156. template createSet(x) =
  157. x.node = newNode(nkCurly)
  158. proc moveConst(x: var TFullReg, y: TFullReg) =
  159. x.ensureKind(y.kind)
  160. case x.kind
  161. of rkNone: discard
  162. of rkInt: x.intVal = y.intVal
  163. of rkFloat: x.floatVal = y.floatVal
  164. of rkNode: x.node = y.node
  165. of rkRegisterAddr: x.regAddr = y.regAddr
  166. of rkNodeAddr: x.nodeAddr = y.nodeAddr
  167. # this seems to be the best way to model the reference semantics
  168. # of system.NimNode:
  169. template asgnRef(x, y: untyped) = moveConst(x, y)
  170. proc copyValue(src: PNode): PNode =
  171. if src == nil or nfIsRef in src.flags:
  172. return src
  173. result = newNode(src.kind)
  174. result.info = src.info
  175. result.typ = src.typ
  176. result.flags = src.flags * PersistentNodeFlags
  177. result.comment = src.comment
  178. when defined(useNodeIds):
  179. if result.id == nodeIdToDebug:
  180. echo "COMES FROM ", src.id
  181. case src.kind
  182. of nkCharLit..nkUInt64Lit: result.intVal = src.intVal
  183. of nkFloatLit..nkFloat128Lit: result.floatVal = src.floatVal
  184. of nkSym: result.sym = src.sym
  185. of nkIdent: result.ident = src.ident
  186. of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
  187. else:
  188. newSeq(result.sons, src.len)
  189. for i in 0..<src.len:
  190. result[i] = copyValue(src[i])
  191. proc asgnComplex(x: var TFullReg, y: TFullReg) =
  192. x.ensureKind(y.kind)
  193. case x.kind
  194. of rkNone: discard
  195. of rkInt: x.intVal = y.intVal
  196. of rkFloat: x.floatVal = y.floatVal
  197. of rkNode: x.node = copyValue(y.node)
  198. of rkRegisterAddr: x.regAddr = y.regAddr
  199. of rkNodeAddr: x.nodeAddr = y.nodeAddr
  200. proc fastAsgnComplex(x: var TFullReg, y: TFullReg) =
  201. x.ensureKind(y.kind)
  202. case x.kind
  203. of rkNone: discard
  204. of rkInt: x.intVal = y.intVal
  205. of rkFloat: x.floatVal = y.floatVal
  206. of rkNode: x.node = y.node
  207. of rkRegisterAddr: x.regAddr = y.regAddr
  208. of rkNodeAddr: x.nodeAddr = y.nodeAddr
  209. proc writeField(n: var PNode, x: TFullReg) =
  210. case x.kind
  211. of rkNone: discard
  212. of rkInt:
  213. if n.kind == nkNilLit:
  214. n[] = TNode(kind: nkIntLit) # ideally, `nkPtrLit`
  215. n.intVal = x.intVal
  216. of rkFloat: n.floatVal = x.floatVal
  217. of rkNode: n = copyValue(x.node)
  218. of rkRegisterAddr: writeField(n, x.regAddr[])
  219. of rkNodeAddr: n = x.nodeAddr[]
  220. proc putIntoReg(dest: var TFullReg; n: PNode) =
  221. case n.kind
  222. of nkStrLit..nkTripleStrLit:
  223. dest = TFullReg(kind: rkNode, node: newStrNode(nkStrLit, n.strVal))
  224. of nkIntLit: # use `nkPtrLit` once this is added
  225. if dest.kind == rkNode: dest.node = n
  226. elif n.typ != nil and n.typ.kind in PtrLikeKinds:
  227. dest = TFullReg(kind: rkNode, node: n)
  228. else:
  229. dest = TFullReg(kind: rkInt, intVal: n.intVal)
  230. of {nkCharLit..nkUInt64Lit} - {nkIntLit}:
  231. dest = TFullReg(kind: rkInt, intVal: n.intVal)
  232. of nkFloatLit..nkFloat128Lit:
  233. dest = TFullReg(kind: rkFloat, floatVal: n.floatVal)
  234. else:
  235. dest = TFullReg(kind: rkNode, node: n)
  236. proc regToNode(x: TFullReg): PNode =
  237. case x.kind
  238. of rkNone: result = newNode(nkEmpty)
  239. of rkInt: result = newNode(nkIntLit); result.intVal = x.intVal
  240. of rkFloat: result = newNode(nkFloatLit); result.floatVal = x.floatVal
  241. of rkNode: result = x.node
  242. of rkRegisterAddr: result = regToNode(x.regAddr[])
  243. of rkNodeAddr: result = x.nodeAddr[]
  244. template getstr(a: untyped): untyped =
  245. (if a.kind == rkNode: a.node.strVal else: $chr(int(a.intVal)))
  246. proc pushSafePoint(f: PStackFrame; pc: int) =
  247. when not defined(nimNoNilSeqs):
  248. if f.safePoints.isNil: f.safePoints = @[]
  249. f.safePoints.add(pc)
  250. proc popSafePoint(f: PStackFrame) =
  251. discard f.safePoints.pop()
  252. type
  253. ExceptionGoto = enum
  254. ExceptionGotoHandler,
  255. ExceptionGotoFinally,
  256. ExceptionGotoUnhandled
  257. proc findExceptionHandler(c: PCtx, f: PStackFrame, exc: PNode):
  258. tuple[why: ExceptionGoto, where: int] =
  259. let raisedType = exc.typ.skipTypes(abstractPtrs)
  260. while f.safePoints.len > 0:
  261. var pc = f.safePoints.pop()
  262. var matched = false
  263. var pcEndExcept = pc
  264. # Scan the chain of exceptions starting at pc.
  265. # The structure is the following:
  266. # pc - opcExcept, <end of this block>
  267. # - opcExcept, <pattern1>
  268. # - opcExcept, <pattern2>
  269. # ...
  270. # - opcExcept, <patternN>
  271. # - Exception handler body
  272. # - ... more opcExcept blocks may follow
  273. # - ... an optional opcFinally block may follow
  274. #
  275. # Note that the exception handler body already contains a jump to the
  276. # finally block or, if that's not present, to the point where the execution
  277. # should continue.
  278. # Also note that opcFinally blocks are the last in the chain.
  279. while c.code[pc].opcode == opcExcept:
  280. # Where this Except block ends
  281. pcEndExcept = pc + c.code[pc].regBx - wordExcess
  282. inc pc
  283. # A series of opcExcept follows for each exception type matched
  284. while c.code[pc].opcode == opcExcept:
  285. let excIndex = c.code[pc].regBx - wordExcess
  286. let exceptType =
  287. if excIndex > 0: c.types[excIndex].skipTypes(abstractPtrs)
  288. else: nil
  289. # echo typeToString(exceptType), " ", typeToString(raisedType)
  290. # Determine if the exception type matches the pattern
  291. if exceptType.isNil or inheritanceDiff(raisedType, exceptType) <= 0:
  292. matched = true
  293. break
  294. inc pc
  295. # Skip any further ``except`` pattern and find the first instruction of
  296. # the handler body
  297. while c.code[pc].opcode == opcExcept:
  298. inc pc
  299. if matched:
  300. break
  301. # If no handler in this chain is able to catch this exception we check if
  302. # the "parent" chains are able to. If this chain ends with a `finally`
  303. # block we must execute it before continuing.
  304. pc = pcEndExcept
  305. # Where the handler body starts
  306. let pcBody = pc
  307. if matched:
  308. return (ExceptionGotoHandler, pcBody)
  309. elif c.code[pc].opcode == opcFinally:
  310. # The +1 here is here because we don't want to execute it since we've
  311. # already pop'd this statepoint from the stack.
  312. return (ExceptionGotoFinally, pc + 1)
  313. return (ExceptionGotoUnhandled, 0)
  314. proc cleanUpOnReturn(c: PCtx; f: PStackFrame): int =
  315. # Walk up the chain of safepoints and return the PC of the first `finally`
  316. # block we find or -1 if no such block is found.
  317. # Note that the safepoint is removed once the function returns!
  318. result = -1
  319. # Traverse the stack starting from the end in order to execute the blocks in
  320. # the intended order
  321. for i in 1..f.safePoints.len:
  322. var pc = f.safePoints[^i]
  323. # Skip the `except` blocks
  324. while c.code[pc].opcode == opcExcept:
  325. pc += c.code[pc].regBx - wordExcess
  326. if c.code[pc].opcode == opcFinally:
  327. discard f.safePoints.pop
  328. return pc + 1
  329. proc opConv(c: PCtx; dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
  330. if desttyp.kind == tyString:
  331. dest.ensureKind(rkNode)
  332. dest.node = newNode(nkStrLit)
  333. let styp = srctyp.skipTypes(abstractRange)
  334. case styp.kind
  335. of tyEnum:
  336. let n = styp.n
  337. let x = src.intVal.int
  338. if x <% n.len and (let f = n[x].sym; f.position == x):
  339. dest.node.strVal = if f.ast.isNil: f.name.s else: f.ast.strVal
  340. else:
  341. for i in 0..<n.len:
  342. if n[i].kind != nkSym: internalError(c.config, "opConv for enum")
  343. let f = n[i].sym
  344. if f.position == x:
  345. dest.node.strVal = if f.ast.isNil: f.name.s else: f.ast.strVal
  346. return
  347. dest.node.strVal = styp.sym.name.s & " " & $x
  348. of tyInt..tyInt64:
  349. dest.node.strVal = $src.intVal
  350. of tyUInt..tyUInt64:
  351. dest.node.strVal = $uint64(src.intVal)
  352. of tyBool:
  353. dest.node.strVal = if src.intVal == 0: "false" else: "true"
  354. of tyFloat..tyFloat128:
  355. dest.node.strVal = $src.floatVal
  356. of tyString:
  357. dest.node.strVal = src.node.strVal
  358. of tyCString:
  359. if src.node.kind == nkBracket:
  360. # Array of chars
  361. var strVal = ""
  362. for son in src.node.sons:
  363. let c = char(son.intVal)
  364. if c == '\0': break
  365. strVal.add(c)
  366. dest.node.strVal = strVal
  367. else:
  368. dest.node.strVal = src.node.strVal
  369. of tyChar:
  370. dest.node.strVal = $chr(src.intVal)
  371. else:
  372. internalError(c.config, "cannot convert to string " & desttyp.typeToString)
  373. else:
  374. case skipTypes(desttyp, abstractVarRange).kind
  375. of tyInt..tyInt64:
  376. dest.ensureKind(rkInt)
  377. case skipTypes(srctyp, abstractRange).kind
  378. of tyFloat..tyFloat64:
  379. dest.intVal = int(src.floatVal)
  380. else:
  381. dest.intVal = src.intVal
  382. if toInt128(dest.intVal) < firstOrd(c.config, desttyp) or toInt128(dest.intVal) > lastOrd(c.config, desttyp):
  383. return true
  384. of tyUInt..tyUInt64:
  385. dest.ensureKind(rkInt)
  386. case skipTypes(srctyp, abstractRange).kind
  387. of tyFloat..tyFloat64:
  388. dest.intVal = int(src.floatVal)
  389. else:
  390. let srcDist = (sizeof(src.intVal) - srctyp.size) * 8
  391. let destDist = (sizeof(dest.intVal) - desttyp.size) * 8
  392. var value = cast[BiggestUInt](src.intVal)
  393. value = (value shl srcDist) shr srcDist
  394. value = (value shl destDist) shr destDist
  395. dest.intVal = cast[BiggestInt](value)
  396. of tyBool:
  397. dest.ensureKind(rkInt)
  398. dest.intVal =
  399. case skipTypes(srctyp, abstractRange).kind
  400. of tyFloat..tyFloat64: int(src.floatVal != 0.0)
  401. else: int(src.intVal != 0)
  402. of tyFloat..tyFloat64:
  403. dest.ensureKind(rkFloat)
  404. case skipTypes(srctyp, abstractRange).kind
  405. of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyBool, tyChar:
  406. dest.floatVal = toBiggestFloat(src.intVal)
  407. else:
  408. dest.floatVal = src.floatVal
  409. of tyObject:
  410. if srctyp.skipTypes(abstractVarRange).kind != tyObject:
  411. internalError(c.config, "invalid object-to-object conversion")
  412. # A object-to-object conversion is essentially a no-op
  413. moveConst(dest, src)
  414. else:
  415. asgnComplex(dest, src)
  416. proc compile(c: PCtx, s: PSym): int =
  417. result = vmgen.genProc(c, s)
  418. when debugEchoCode: c.echoCode result
  419. #c.echoCode
  420. template handleJmpBack() {.dirty.} =
  421. if c.loopIterations <= 0:
  422. if allowInfiniteLoops in c.features:
  423. c.loopIterations = c.config.maxLoopIterationsVM
  424. else:
  425. msgWriteln(c.config, "stack trace: (most recent call last)")
  426. stackTraceAux(c, tos, pc)
  427. globalError(c.config, c.debug[pc], errTooManyIterations % $c.config.maxLoopIterationsVM)
  428. dec(c.loopIterations)
  429. proc recSetFlagIsRef(arg: PNode) =
  430. if arg.kind notin {nkStrLit..nkTripleStrLit}:
  431. arg.flags.incl(nfIsRef)
  432. for i in 0..<arg.safeLen:
  433. arg[i].recSetFlagIsRef
  434. proc setLenSeq(c: PCtx; node: PNode; newLen: int; info: TLineInfo) =
  435. let typ = node.typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc})
  436. let oldLen = node.len
  437. setLen(node.sons, newLen)
  438. if oldLen < newLen:
  439. for i in oldLen..<newLen:
  440. node[i] = getNullValue(typ[0], info, c.config)
  441. const
  442. errNilAccess = "attempt to access a nil address"
  443. errOverOrUnderflow = "over- or underflow"
  444. errConstantDivisionByZero = "division by zero"
  445. errIllegalConvFromXtoY = "illegal conversion from '$1' to '$2'"
  446. errTooManyIterations = "interpretation requires too many iterations; " &
  447. "if you are sure this is not a bug in your code, compile with `--maxLoopIterationsVM:number` (current value: $1)"
  448. errFieldXNotFound = "node lacks field: "
  449. template maybeHandlePtr(node2: PNode, reg: TFullReg, isAssign2: bool): bool =
  450. let node = node2 # prevent double evaluation
  451. if node.kind == nkNilLit:
  452. stackTrace(c, tos, pc, errNilAccess)
  453. let typ = node.typ
  454. if nfIsPtr in node.flags or (typ != nil and typ.kind == tyPtr):
  455. assert node.kind == nkIntLit, $(node.kind)
  456. assert typ != nil
  457. let typ2 = if typ.kind == tyPtr: typ[0] else: typ
  458. if not derefPtrToReg(node.intVal, typ2, reg, isAssign = isAssign2):
  459. # tyObject not supported in this context
  460. stackTrace(c, tos, pc, "deref unsupported ptr type: " & $(typeToString(typ), typ.kind))
  461. true
  462. else:
  463. false
  464. when not defined(nimHasSinkInference):
  465. {.pragma: nosinks.}
  466. proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
  467. var pc = start
  468. var tos = tos
  469. # Used to keep track of where the execution is resumed.
  470. var savedPC = -1
  471. var savedFrame: PStackFrame
  472. var regs: seq[TFullReg] # alias to tos.slots for performance
  473. move(regs, tos.slots)
  474. #echo "NEW RUN ------------------------"
  475. while true:
  476. #{.computedGoto.}
  477. let instr = c.code[pc]
  478. let ra = instr.regA
  479. when traceCode:
  480. template regDescr(name, r): string =
  481. let kind = if r < regs.len: $regs[r].kind else: ""
  482. let ret = name & ": " & $r & " " & $kind
  483. alignLeft(ret, 15)
  484. echo "PC:$pc $opcode $ra $rb $rc" % [
  485. "pc", $pc, "opcode", alignLeft($c.code[pc].opcode, 15),
  486. "ra", regDescr("ra", ra), "rb", regDescr("rb", instr.regB),
  487. "rc", regDescr("rc", instr.regC)]
  488. case instr.opcode
  489. of opcEof: return regs[ra]
  490. of opcRet:
  491. let newPc = c.cleanUpOnReturn(tos)
  492. # Perform any cleanup action before returning
  493. if newPc < 0:
  494. pc = tos.comesFrom
  495. tos = tos.next
  496. let retVal = regs[0]
  497. if tos.isNil:
  498. return retVal
  499. move(regs, tos.slots)
  500. assert c.code[pc].opcode in {opcIndCall, opcIndCallAsgn}
  501. if c.code[pc].opcode == opcIndCallAsgn:
  502. regs[c.code[pc].regA] = retVal
  503. else:
  504. savedPC = pc
  505. savedFrame = tos
  506. # The -1 is needed because at the end of the loop we increment `pc`
  507. pc = newPc - 1
  508. of opcYldYoid: assert false
  509. of opcYldVal: assert false
  510. of opcAsgnInt:
  511. decodeB(rkInt)
  512. regs[ra].intVal = regs[rb].intVal
  513. of opcAsgnFloat:
  514. decodeB(rkFloat)
  515. regs[ra].floatVal = regs[rb].floatVal
  516. of opcCastFloatToInt32:
  517. let rb = instr.regB
  518. ensureKind(rkInt)
  519. regs[ra].intVal = cast[int32](float32(regs[rb].floatVal))
  520. of opcCastFloatToInt64:
  521. let rb = instr.regB
  522. ensureKind(rkInt)
  523. regs[ra].intVal = cast[int64](regs[rb].floatVal)
  524. of opcCastIntToFloat32:
  525. let rb = instr.regB
  526. ensureKind(rkFloat)
  527. regs[ra].floatVal = cast[float32](regs[rb].intVal)
  528. of opcCastIntToFloat64:
  529. let rb = instr.regB
  530. ensureKind(rkFloat)
  531. regs[ra].floatVal = cast[float64](regs[rb].intVal)
  532. of opcCastPtrToInt: # RENAME opcCastPtrOrRefToInt
  533. decodeBImm(rkInt)
  534. case imm
  535. of 1: # PtrLikeKinds
  536. case regs[rb].kind
  537. of rkNode:
  538. regs[ra].intVal = cast[int](regs[rb].node.intVal)
  539. of rkNodeAddr:
  540. regs[ra].intVal = cast[int](regs[rb].nodeAddr)
  541. else:
  542. stackTrace(c, tos, pc, "opcCastPtrToInt: got " & $regs[rb].kind)
  543. of 2: # tyRef
  544. regs[ra].intVal = cast[int](regs[rb].node)
  545. else: assert false, $imm
  546. of opcCastIntToPtr:
  547. let rb = instr.regB
  548. let typ = regs[ra].node.typ
  549. let node2 = newNodeIT(nkIntLit, c.debug[pc], typ)
  550. case regs[rb].kind
  551. of rkInt: node2.intVal = regs[rb].intVal
  552. of rkNode:
  553. if regs[rb].node.typ.kind notin PtrLikeKinds:
  554. stackTrace(c, tos, pc, "opcCastIntToPtr: regs[rb].node.typ: " & $regs[rb].node.typ.kind)
  555. node2.intVal = regs[rb].node.intVal
  556. else: stackTrace(c, tos, pc, "opcCastIntToPtr: regs[rb].kind: " & $regs[rb].kind)
  557. regs[ra].node = node2
  558. of opcAsgnComplex:
  559. asgnComplex(regs[ra], regs[instr.regB])
  560. of opcFastAsgnComplex:
  561. fastAsgnComplex(regs[ra], regs[instr.regB])
  562. of opcAsgnRef:
  563. asgnRef(regs[ra], regs[instr.regB])
  564. of opcNodeToReg:
  565. let ra = instr.regA
  566. let rb = instr.regB
  567. # opcDeref might already have loaded it into a register. XXX Let's hope
  568. # this is still correct this way:
  569. if regs[rb].kind != rkNode:
  570. regs[ra] = regs[rb]
  571. else:
  572. assert regs[rb].kind == rkNode
  573. let nb = regs[rb].node
  574. case nb.kind
  575. of nkCharLit..nkUInt64Lit:
  576. ensureKind(rkInt)
  577. regs[ra].intVal = nb.intVal
  578. of nkFloatLit..nkFloat64Lit:
  579. ensureKind(rkFloat)
  580. regs[ra].floatVal = nb.floatVal
  581. else:
  582. ensureKind(rkNode)
  583. regs[ra].node = nb
  584. of opcLdArr:
  585. # a = b[c]
  586. decodeBC(rkNode)
  587. if regs[rc].intVal > high(int):
  588. stackTrace(c, tos, pc, formatErrorIndexBound(regs[rc].intVal, high(int)))
  589. let idx = regs[rc].intVal.int
  590. let src = regs[rb].node
  591. if src.kind in {nkStrLit..nkTripleStrLit}:
  592. if idx <% src.strVal.len:
  593. regs[ra].node = newNodeI(nkCharLit, c.debug[pc])
  594. regs[ra].node.intVal = src.strVal[idx].ord
  595. else:
  596. stackTrace(c, tos, pc, formatErrorIndexBound(idx, src.strVal.len-1))
  597. elif src.kind notin {nkEmpty..nkFloat128Lit} and idx <% src.len:
  598. regs[ra].node = src[idx]
  599. else:
  600. stackTrace(c, tos, pc, formatErrorIndexBound(idx, src.safeLen-1))
  601. of opcLdArrAddr:
  602. # a = addr(b[c])
  603. decodeBC(rkNodeAddr)
  604. if regs[rc].intVal > high(int):
  605. stackTrace(c, tos, pc, formatErrorIndexBound(regs[rc].intVal, high(int)))
  606. let idx = regs[rc].intVal.int
  607. let src = if regs[rb].kind == rkNode: regs[rb].node else: regs[rb].nodeAddr[]
  608. if src.kind notin {nkEmpty..nkTripleStrLit} and idx <% src.len:
  609. regs[ra].nodeAddr = addr src.sons[idx]
  610. else:
  611. stackTrace(c, tos, pc, formatErrorIndexBound(idx, src.safeLen-1))
  612. of opcLdStrIdx:
  613. decodeBC(rkInt)
  614. let idx = regs[rc].intVal.int
  615. let s = regs[rb].node.strVal
  616. if idx <% s.len:
  617. regs[ra].intVal = s[idx].ord
  618. else:
  619. stackTrace(c, tos, pc, formatErrorIndexBound(idx, s.len-1))
  620. of opcWrArr:
  621. # a[b] = c
  622. decodeBC(rkNode)
  623. let idx = regs[rb].intVal.int
  624. let arr = regs[ra].node
  625. if arr.kind in {nkStrLit..nkTripleStrLit}:
  626. if idx <% arr.strVal.len:
  627. arr.strVal[idx] = chr(regs[rc].intVal)
  628. else:
  629. stackTrace(c, tos, pc, formatErrorIndexBound(idx, arr.strVal.len-1))
  630. elif idx <% arr.len:
  631. writeField(arr[idx], regs[rc])
  632. else:
  633. stackTrace(c, tos, pc, formatErrorIndexBound(idx, arr.safeLen-1))
  634. of opcLdObj:
  635. # a = b.c
  636. decodeBC(rkNode)
  637. let src = regs[rb].node
  638. case src.kind
  639. of nkEmpty..nkNilLit:
  640. # for nkPtrLit, this could be supported in the future, use something like:
  641. # derefPtrToReg(src.intVal + offsetof(src.typ, rc), typ_field, regs[ra], isAssign = false)
  642. # where we compute the offset in bytes for field rc
  643. stackTrace(c, tos, pc, errNilAccess & " " & $("kind", src.kind, "typ", typeToString(src.typ), "rc", rc))
  644. of nkObjConstr:
  645. let n = src[rc + 1].skipColon
  646. regs[ra].node = n
  647. else:
  648. let n = src[rc]
  649. regs[ra].node = n
  650. of opcLdObjAddr:
  651. # a = addr(b.c)
  652. decodeBC(rkNodeAddr)
  653. let src = if regs[rb].kind == rkNode: regs[rb].node else: regs[rb].nodeAddr[]
  654. case src.kind
  655. of nkEmpty..nkNilLit:
  656. stackTrace(c, tos, pc, errNilAccess)
  657. of nkObjConstr:
  658. let n = src.sons[rc + 1]
  659. if n.kind == nkExprColonExpr:
  660. regs[ra].nodeAddr = addr n.sons[1]
  661. else:
  662. regs[ra].nodeAddr = addr src.sons[rc + 1]
  663. else:
  664. regs[ra].nodeAddr = addr src.sons[rc]
  665. of opcWrObj:
  666. # a.b = c
  667. decodeBC(rkNode)
  668. assert regs[ra].node != nil
  669. let shiftedRb = rb + ord(regs[ra].node.kind == nkObjConstr)
  670. let dest = regs[ra].node
  671. if dest.kind == nkNilLit:
  672. stackTrace(c, tos, pc, errNilAccess)
  673. elif dest[shiftedRb].kind == nkExprColonExpr:
  674. writeField(dest[shiftedRb][1], regs[rc])
  675. else:
  676. writeField(dest[shiftedRb], regs[rc])
  677. of opcWrStrIdx:
  678. decodeBC(rkNode)
  679. let idx = regs[rb].intVal.int
  680. if idx <% regs[ra].node.strVal.len:
  681. regs[ra].node.strVal[idx] = chr(regs[rc].intVal)
  682. else:
  683. stackTrace(c, tos, pc, formatErrorIndexBound(idx, regs[ra].node.strVal.len-1))
  684. of opcAddrReg:
  685. decodeB(rkRegisterAddr)
  686. regs[ra].regAddr = addr(regs[rb])
  687. of opcAddrNode:
  688. decodeB(rkNodeAddr)
  689. if regs[rb].kind == rkNode:
  690. regs[ra].nodeAddr = addr(regs[rb].node)
  691. else:
  692. stackTrace(c, tos, pc, "limited VM support for 'addr'")
  693. of opcLdDeref:
  694. # a = b[]
  695. let ra = instr.regA
  696. let rb = instr.regB
  697. case regs[rb].kind
  698. of rkNodeAddr:
  699. ensureKind(rkNode)
  700. regs[ra].node = regs[rb].nodeAddr[]
  701. of rkRegisterAddr:
  702. ensureKind(regs[rb].regAddr.kind)
  703. regs[ra] = regs[rb].regAddr[]
  704. of rkNode:
  705. if regs[rb].node.kind == nkRefTy:
  706. regs[ra].node = regs[rb].node[0]
  707. elif not maybeHandlePtr(regs[rb].node, regs[ra], false):
  708. ## eg: typ.kind = tyObject
  709. ensureKind(rkNode)
  710. regs[ra].node = regs[rb].node
  711. else:
  712. stackTrace(c, tos, pc, errNilAccess & " kind: " & $regs[rb].kind)
  713. of opcWrDeref:
  714. # a[] = c; b unused
  715. let ra = instr.regA
  716. let rc = instr.regC
  717. case regs[ra].kind
  718. of rkNodeAddr:
  719. let n = regs[rc].regToNode
  720. # `var object` parameters are sent as rkNodeAddr. When they are mutated
  721. # vmgen generates opcWrDeref, which means that we must dereference
  722. # twice.
  723. # TODO: This should likely be handled differently in vmgen.
  724. if (nfIsRef notin regs[ra].nodeAddr[].flags and
  725. nfIsRef notin n.flags):
  726. regs[ra].nodeAddr[][] = n[]
  727. else:
  728. regs[ra].nodeAddr[] = n
  729. of rkRegisterAddr: regs[ra].regAddr[] = regs[rc]
  730. of rkNode:
  731. # xxx: also check for nkRefTy as in opcLdDeref?
  732. if not maybeHandlePtr(regs[ra].node, regs[rc], true):
  733. regs[ra].node[] = regs[rc].regToNode[]
  734. regs[ra].node.flags.incl nfIsRef
  735. else: stackTrace(c, tos, pc, errNilAccess)
  736. of opcAddInt:
  737. decodeBC(rkInt)
  738. let
  739. bVal = regs[rb].intVal
  740. cVal = regs[rc].intVal
  741. sum = bVal +% cVal
  742. if (sum xor bVal) >= 0 or (sum xor cVal) >= 0:
  743. regs[ra].intVal = sum
  744. else:
  745. stackTrace(c, tos, pc, errOverOrUnderflow)
  746. of opcAddImmInt:
  747. decodeBImm(rkInt)
  748. #message(c.config, c.debug[pc], warnUser, "came here")
  749. #debug regs[rb].node
  750. let
  751. bVal = regs[rb].intVal
  752. cVal = imm
  753. sum = bVal +% cVal
  754. if (sum xor bVal) >= 0 or (sum xor cVal) >= 0:
  755. regs[ra].intVal = sum
  756. else:
  757. stackTrace(c, tos, pc, errOverOrUnderflow)
  758. of opcSubInt:
  759. decodeBC(rkInt)
  760. let
  761. bVal = regs[rb].intVal
  762. cVal = regs[rc].intVal
  763. diff = bVal -% cVal
  764. if (diff xor bVal) >= 0 or (diff xor not cVal) >= 0:
  765. regs[ra].intVal = diff
  766. else:
  767. stackTrace(c, tos, pc, errOverOrUnderflow)
  768. of opcSubImmInt:
  769. decodeBImm(rkInt)
  770. let
  771. bVal = regs[rb].intVal
  772. cVal = imm
  773. diff = bVal -% cVal
  774. if (diff xor bVal) >= 0 or (diff xor not cVal) >= 0:
  775. regs[ra].intVal = diff
  776. else:
  777. stackTrace(c, tos, pc, errOverOrUnderflow)
  778. of opcLenSeq:
  779. decodeBImm(rkInt)
  780. #assert regs[rb].kind == nkBracket
  781. let high = (imm and 1) # discard flags
  782. if (imm and nimNodeFlag) != 0:
  783. # used by mNLen (NimNode.len)
  784. regs[ra].intVal = regs[rb].node.safeLen - high
  785. else:
  786. # safeArrLen also return string node len
  787. # used when string is passed as openArray in VM
  788. regs[ra].intVal = regs[rb].node.safeArrLen - high
  789. of opcLenStr:
  790. decodeBImm(rkInt)
  791. assert regs[rb].kind == rkNode
  792. regs[ra].intVal = regs[rb].node.strVal.len - imm
  793. of opcIncl:
  794. decodeB(rkNode)
  795. let b = regs[rb].regToNode
  796. if not inSet(regs[ra].node, b):
  797. regs[ra].node.add copyTree(b)
  798. of opcInclRange:
  799. decodeBC(rkNode)
  800. var r = newNode(nkRange)
  801. r.add regs[rb].regToNode
  802. r.add regs[rc].regToNode
  803. regs[ra].node.add r.copyTree
  804. of opcExcl:
  805. decodeB(rkNode)
  806. var b = newNodeIT(nkCurly, regs[ra].node.info, regs[ra].node.typ)
  807. b.add regs[rb].regToNode
  808. var r = diffSets(c.config, regs[ra].node, b)
  809. discardSons(regs[ra].node)
  810. for i in 0..<r.len: regs[ra].node.add r[i]
  811. of opcCard:
  812. decodeB(rkInt)
  813. regs[ra].intVal = nimsets.cardSet(c.config, regs[rb].node)
  814. of opcMulInt:
  815. decodeBC(rkInt)
  816. let
  817. bVal = regs[rb].intVal
  818. cVal = regs[rc].intVal
  819. product = bVal *% cVal
  820. floatProd = toBiggestFloat(bVal) * toBiggestFloat(cVal)
  821. resAsFloat = toBiggestFloat(product)
  822. if resAsFloat == floatProd:
  823. regs[ra].intVal = product
  824. elif 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
  825. regs[ra].intVal = product
  826. else:
  827. stackTrace(c, tos, pc, errOverOrUnderflow)
  828. of opcDivInt:
  829. decodeBC(rkInt)
  830. if regs[rc].intVal == 0: stackTrace(c, tos, pc, errConstantDivisionByZero)
  831. else: regs[ra].intVal = regs[rb].intVal div regs[rc].intVal
  832. of opcModInt:
  833. decodeBC(rkInt)
  834. if regs[rc].intVal == 0: stackTrace(c, tos, pc, errConstantDivisionByZero)
  835. else: regs[ra].intVal = regs[rb].intVal mod regs[rc].intVal
  836. of opcAddFloat:
  837. decodeBC(rkFloat)
  838. regs[ra].floatVal = regs[rb].floatVal + regs[rc].floatVal
  839. of opcSubFloat:
  840. decodeBC(rkFloat)
  841. regs[ra].floatVal = regs[rb].floatVal - regs[rc].floatVal
  842. of opcMulFloat:
  843. decodeBC(rkFloat)
  844. regs[ra].floatVal = regs[rb].floatVal * regs[rc].floatVal
  845. of opcDivFloat:
  846. decodeBC(rkFloat)
  847. regs[ra].floatVal = regs[rb].floatVal / regs[rc].floatVal
  848. of opcShrInt:
  849. decodeBC(rkInt)
  850. let b = cast[uint64](regs[rb].intVal)
  851. let c = cast[uint64](regs[rc].intVal)
  852. let a = cast[int64](b shr c)
  853. regs[ra].intVal = a
  854. of opcShlInt:
  855. decodeBC(rkInt)
  856. regs[ra].intVal = regs[rb].intVal shl regs[rc].intVal
  857. of opcAshrInt:
  858. decodeBC(rkInt)
  859. regs[ra].intVal = ashr(regs[rb].intVal, regs[rc].intVal)
  860. of opcBitandInt:
  861. decodeBC(rkInt)
  862. regs[ra].intVal = regs[rb].intVal and regs[rc].intVal
  863. of opcBitorInt:
  864. decodeBC(rkInt)
  865. regs[ra].intVal = regs[rb].intVal or regs[rc].intVal
  866. of opcBitxorInt:
  867. decodeBC(rkInt)
  868. regs[ra].intVal = regs[rb].intVal xor regs[rc].intVal
  869. of opcAddu:
  870. decodeBC(rkInt)
  871. regs[ra].intVal = regs[rb].intVal +% regs[rc].intVal
  872. of opcSubu:
  873. decodeBC(rkInt)
  874. regs[ra].intVal = regs[rb].intVal -% regs[rc].intVal
  875. of opcMulu:
  876. decodeBC(rkInt)
  877. regs[ra].intVal = regs[rb].intVal *% regs[rc].intVal
  878. of opcDivu:
  879. decodeBC(rkInt)
  880. regs[ra].intVal = regs[rb].intVal /% regs[rc].intVal
  881. of opcModu:
  882. decodeBC(rkInt)
  883. regs[ra].intVal = regs[rb].intVal %% regs[rc].intVal
  884. of opcEqInt:
  885. decodeBC(rkInt)
  886. regs[ra].intVal = ord(regs[rb].intVal == regs[rc].intVal)
  887. of opcLeInt:
  888. decodeBC(rkInt)
  889. regs[ra].intVal = ord(regs[rb].intVal <= regs[rc].intVal)
  890. of opcLtInt:
  891. decodeBC(rkInt)
  892. regs[ra].intVal = ord(regs[rb].intVal < regs[rc].intVal)
  893. of opcEqFloat:
  894. decodeBC(rkInt)
  895. regs[ra].intVal = ord(regs[rb].floatVal == regs[rc].floatVal)
  896. of opcLeFloat:
  897. decodeBC(rkInt)
  898. regs[ra].intVal = ord(regs[rb].floatVal <= regs[rc].floatVal)
  899. of opcLtFloat:
  900. decodeBC(rkInt)
  901. regs[ra].intVal = ord(regs[rb].floatVal < regs[rc].floatVal)
  902. of opcLeu:
  903. decodeBC(rkInt)
  904. regs[ra].intVal = ord(regs[rb].intVal <=% regs[rc].intVal)
  905. of opcLtu:
  906. decodeBC(rkInt)
  907. regs[ra].intVal = ord(regs[rb].intVal <% regs[rc].intVal)
  908. of opcEqRef:
  909. var ret = false
  910. decodeBC(rkInt)
  911. template getTyp(n): untyped =
  912. n.typ.skipTypes(abstractInst)
  913. proc ptrEquality(n1: ptr PNode, n2: PNode): bool =
  914. ## true if n2.intVal represents a ptr equal to n1
  915. let p1 = cast[int](n1)
  916. case n2.kind
  917. of nkNilLit: return p1 == 0
  918. of nkIntLit: # TODO: nkPtrLit
  919. # for example, n1.kind == nkFloatLit (ptr float)
  920. # the problem is that n1.typ == nil so we can't compare n1.typ and n2.typ
  921. # this is the best we can do (pending making sure we assign a valid n1.typ to nodeAddr's)
  922. let t2 = n2.getTyp
  923. return t2.kind in PtrLikeKinds and n2.intVal == p1
  924. else: return false
  925. if regs[rb].kind == rkNodeAddr:
  926. if regs[rc].kind == rkNodeAddr:
  927. ret = regs[rb].nodeAddr == regs[rc].nodeAddr
  928. else:
  929. ret = ptrEquality(regs[rb].nodeAddr, regs[rc].node)
  930. elif regs[rc].kind == rkNodeAddr:
  931. ret = ptrEquality(regs[rc].nodeAddr, regs[rb].node)
  932. else:
  933. let nb = regs[rb].node
  934. let nc = regs[rc].node
  935. if nb.kind != nc.kind: discard
  936. elif (nb == nc) or (nb.kind == nkNilLit): ret = true
  937. elif nb.kind == nkIntLit and nb.intVal == nc.intVal: # TODO: nkPtrLit
  938. let tb = nb.getTyp
  939. let tc = nc.getTyp
  940. ret = tb.kind in PtrLikeKinds and tc.kind == tb.kind
  941. regs[ra].intVal = ord(ret)
  942. of opcEqNimNode:
  943. decodeBC(rkInt)
  944. regs[ra].intVal =
  945. ord(exprStructuralEquivalent(regs[rb].node, regs[rc].node,
  946. strictSymEquality=true))
  947. of opcSameNodeType:
  948. decodeBC(rkInt)
  949. regs[ra].intVal = ord(regs[rb].node.typ.sameTypeOrNil regs[rc].node.typ)
  950. of opcXor:
  951. decodeBC(rkInt)
  952. regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
  953. of opcNot:
  954. decodeB(rkInt)
  955. assert regs[rb].kind == rkInt
  956. regs[ra].intVal = 1 - regs[rb].intVal
  957. of opcUnaryMinusInt:
  958. decodeB(rkInt)
  959. assert regs[rb].kind == rkInt
  960. let val = regs[rb].intVal
  961. if val != int64.low:
  962. regs[ra].intVal = -val
  963. else:
  964. stackTrace(c, tos, pc, errOverOrUnderflow)
  965. of opcUnaryMinusFloat:
  966. decodeB(rkFloat)
  967. assert regs[rb].kind == rkFloat
  968. regs[ra].floatVal = -regs[rb].floatVal
  969. of opcBitnotInt:
  970. decodeB(rkInt)
  971. assert regs[rb].kind == rkInt
  972. regs[ra].intVal = not regs[rb].intVal
  973. of opcEqStr:
  974. decodeBC(rkInt)
  975. regs[ra].intVal = ord(regs[rb].node.strVal == regs[rc].node.strVal)
  976. of opcLeStr:
  977. decodeBC(rkInt)
  978. regs[ra].intVal = ord(regs[rb].node.strVal <= regs[rc].node.strVal)
  979. of opcLtStr:
  980. decodeBC(rkInt)
  981. regs[ra].intVal = ord(regs[rb].node.strVal < regs[rc].node.strVal)
  982. of opcLeSet:
  983. decodeBC(rkInt)
  984. regs[ra].intVal = ord(containsSets(c.config, regs[rb].node, regs[rc].node))
  985. of opcEqSet:
  986. decodeBC(rkInt)
  987. regs[ra].intVal = ord(equalSets(c.config, regs[rb].node, regs[rc].node))
  988. of opcLtSet:
  989. decodeBC(rkInt)
  990. let a = regs[rb].node
  991. let b = regs[rc].node
  992. regs[ra].intVal = ord(containsSets(c.config, a, b) and not equalSets(c.config, a, b))
  993. of opcMulSet:
  994. decodeBC(rkNode)
  995. createSet(regs[ra])
  996. move(regs[ra].node.sons,
  997. nimsets.intersectSets(c.config, regs[rb].node, regs[rc].node).sons)
  998. of opcPlusSet:
  999. decodeBC(rkNode)
  1000. createSet(regs[ra])
  1001. move(regs[ra].node.sons,
  1002. nimsets.unionSets(c.config, regs[rb].node, regs[rc].node).sons)
  1003. of opcMinusSet:
  1004. decodeBC(rkNode)
  1005. createSet(regs[ra])
  1006. move(regs[ra].node.sons,
  1007. nimsets.diffSets(c.config, regs[rb].node, regs[rc].node).sons)
  1008. of opcConcatStr:
  1009. decodeBC(rkNode)
  1010. createStr regs[ra]
  1011. regs[ra].node.strVal = getstr(regs[rb])
  1012. for i in rb+1..rb+rc-1:
  1013. regs[ra].node.strVal.add getstr(regs[i])
  1014. of opcAddStrCh:
  1015. decodeB(rkNode)
  1016. regs[ra].node.strVal.add(regs[rb].intVal.chr)
  1017. of opcAddStrStr:
  1018. decodeB(rkNode)
  1019. regs[ra].node.strVal.add(regs[rb].node.strVal)
  1020. of opcAddSeqElem:
  1021. decodeB(rkNode)
  1022. if regs[ra].node.kind == nkBracket:
  1023. regs[ra].node.add(copyValue(regs[rb].regToNode))
  1024. else:
  1025. stackTrace(c, tos, pc, errNilAccess)
  1026. of opcGetImpl:
  1027. decodeB(rkNode)
  1028. var a = regs[rb].node
  1029. if a.kind == nkVarTy: a = a[0]
  1030. if a.kind == nkSym:
  1031. regs[ra].node = if a.sym.ast.isNil: newNode(nkNilLit)
  1032. else: copyTree(a.sym.ast)
  1033. regs[ra].node.flags.incl nfIsRef
  1034. else:
  1035. stackTrace(c, tos, pc, "node is not a symbol")
  1036. of opcGetImplTransf:
  1037. decodeB(rkNode)
  1038. let a = regs[rb].node
  1039. if a.kind == nkSym:
  1040. regs[ra].node =
  1041. if a.sym.ast.isNil:
  1042. newNode(nkNilLit)
  1043. else:
  1044. let ast = a.sym.ast.shallowCopy
  1045. for i in 0..<a.sym.ast.len:
  1046. ast[i] = a.sym.ast[i]
  1047. ast[bodyPos] = transformBody(c.graph, a.sym, cache=true)
  1048. ast.copyTree()
  1049. of opcSymOwner:
  1050. decodeB(rkNode)
  1051. let a = regs[rb].node
  1052. if a.kind == nkSym:
  1053. regs[ra].node = if a.sym.owner.isNil: newNode(nkNilLit)
  1054. else: newSymNode(a.sym.skipGenericOwner)
  1055. regs[ra].node.flags.incl nfIsRef
  1056. else:
  1057. stackTrace(c, tos, pc, "node is not a symbol")
  1058. of opcSymIsInstantiationOf:
  1059. decodeBC(rkInt)
  1060. let a = regs[rb].node
  1061. let b = regs[rc].node
  1062. if a.kind == nkSym and a.sym.kind in skProcKinds and
  1063. b.kind == nkSym and b.sym.kind in skProcKinds:
  1064. regs[ra].intVal =
  1065. if sfFromGeneric in a.sym.flags and a.sym.owner == b.sym: 1
  1066. else: 0
  1067. else:
  1068. stackTrace(c, tos, pc, "node is not a proc symbol")
  1069. of opcEcho:
  1070. let rb = instr.regB
  1071. if rb == 1:
  1072. msgWriteln(c.config, regs[ra].node.strVal, {msgStdout})
  1073. else:
  1074. var outp = ""
  1075. for i in ra..ra+rb-1:
  1076. #if regs[i].kind != rkNode: debug regs[i]
  1077. outp.add(regs[i].node.strVal)
  1078. msgWriteln(c.config, outp, {msgStdout})
  1079. of opcContainsSet:
  1080. decodeBC(rkInt)
  1081. regs[ra].intVal = ord(inSet(regs[rb].node, regs[rc].regToNode))
  1082. of opcSubStr:
  1083. decodeBC(rkNode)
  1084. inc pc
  1085. assert c.code[pc].opcode == opcSubStr
  1086. let rd = c.code[pc].regA
  1087. createStr regs[ra]
  1088. regs[ra].node.strVal = substr(regs[rb].node.strVal,
  1089. regs[rc].intVal.int, regs[rd].intVal.int)
  1090. of opcParseFloat:
  1091. decodeBC(rkInt)
  1092. inc pc
  1093. assert c.code[pc].opcode == opcParseFloat
  1094. let rd = c.code[pc].regA
  1095. var rcAddr = addr(regs[rc])
  1096. if rcAddr.kind == rkRegisterAddr: rcAddr = rcAddr.regAddr
  1097. elif regs[rc].kind != rkFloat:
  1098. regs[rc] = TFullReg(kind: rkFloat)
  1099. regs[ra].intVal = parseBiggestFloat(regs[rb].node.strVal,
  1100. rcAddr.floatVal, regs[rd].intVal.int)
  1101. of opcRangeChck:
  1102. let rb = instr.regB
  1103. let rc = instr.regC
  1104. if not (leValueConv(regs[rb].regToNode, regs[ra].regToNode) and
  1105. leValueConv(regs[ra].regToNode, regs[rc].regToNode)):
  1106. stackTrace(c, tos, pc,
  1107. errIllegalConvFromXtoY % [
  1108. $regs[ra].regToNode, "[" & $regs[rb].regToNode & ".." & $regs[rc].regToNode & "]"])
  1109. of opcIndCall, opcIndCallAsgn:
  1110. # dest = call regStart, n; where regStart = fn, arg1, ...
  1111. let rb = instr.regB
  1112. let rc = instr.regC
  1113. let bb = regs[rb].node
  1114. let isClosure = bb.kind == nkTupleConstr
  1115. let prc = if not isClosure: bb.sym else: bb[0].sym
  1116. if prc.offset < -1:
  1117. # it's a callback:
  1118. c.callbacks[-prc.offset-2].value(
  1119. VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[ptr UncheckedArray[TFullReg]](addr regs[0]),
  1120. currentException: c.currentExceptionA,
  1121. currentLineInfo: c.debug[pc]))
  1122. elif importcCond(prc):
  1123. if compiletimeFFI notin c.config.features:
  1124. globalError(c.config, c.debug[pc], "VM not allowed to do FFI, see `compiletimeFFI`")
  1125. # we pass 'tos.slots' instead of 'regs' so that the compiler can keep
  1126. # 'regs' in a register:
  1127. when hasFFI:
  1128. if prc.position - 1 < 0:
  1129. globalError(c.config, c.debug[pc],
  1130. "VM call invalid: prc.position: " & $prc.position)
  1131. let prcValue = c.globals[prc.position-1]
  1132. if prcValue.kind == nkEmpty:
  1133. globalError(c.config, c.debug[pc], "cannot run " & prc.name.s)
  1134. var slots2: TNodeSeq
  1135. slots2.setLen(tos.slots.len)
  1136. for i in 0..<tos.slots.len:
  1137. slots2[i] = regToNode(tos.slots[i])
  1138. let newValue = callForeignFunction(c.config, prcValue, prc.typ, slots2,
  1139. rb+1, rc-1, c.debug[pc])
  1140. if newValue.kind != nkEmpty:
  1141. assert instr.opcode == opcIndCallAsgn
  1142. putIntoReg(regs[ra], newValue)
  1143. else:
  1144. globalError(c.config, c.debug[pc], "VM not built with FFI support")
  1145. elif prc.kind != skTemplate:
  1146. let newPc = compile(c, prc)
  1147. # tricky: a recursion is also a jump back, so we use the same
  1148. # logic as for loops:
  1149. if newPc < pc: handleJmpBack()
  1150. #echo "new pc ", newPc, " calling: ", prc.name.s
  1151. var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos)
  1152. newSeq(newFrame.slots, prc.offset+ord(isClosure))
  1153. if not isEmptyType(prc.typ[0]):
  1154. putIntoReg(newFrame.slots[0], getNullValue(prc.typ[0], prc.info, c.config))
  1155. for i in 1..rc-1:
  1156. newFrame.slots[i] = regs[rb+i]
  1157. if isClosure:
  1158. newFrame.slots[rc] = TFullReg(kind: rkNode, node: regs[rb].node[1])
  1159. tos = newFrame
  1160. move(regs, newFrame.slots)
  1161. # -1 for the following 'inc pc'
  1162. pc = newPc-1
  1163. else:
  1164. # for 'getAst' support we need to support template expansion here:
  1165. let genSymOwner = if tos.next != nil and tos.next.prc != nil:
  1166. tos.next.prc
  1167. else:
  1168. c.module
  1169. var macroCall = newNodeI(nkCall, c.debug[pc])
  1170. macroCall.add(newSymNode(prc))
  1171. for i in 1..rc-1:
  1172. let node = regs[rb+i].regToNode
  1173. node.info = c.debug[pc]
  1174. macroCall.add(node)
  1175. var a = evalTemplate(macroCall, prc, genSymOwner, c.config, c.cache)
  1176. if a.kind == nkStmtList and a.len == 1: a = a[0]
  1177. a.recSetFlagIsRef
  1178. ensureKind(rkNode)
  1179. regs[ra].node = a
  1180. of opcTJmp:
  1181. # jump Bx if A != 0
  1182. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  1183. if regs[ra].intVal != 0:
  1184. inc pc, rbx
  1185. of opcFJmp:
  1186. # jump Bx if A == 0
  1187. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  1188. if regs[ra].intVal == 0:
  1189. inc pc, rbx
  1190. of opcJmp:
  1191. # jump Bx
  1192. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  1193. inc pc, rbx
  1194. of opcJmpBack:
  1195. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  1196. inc pc, rbx
  1197. handleJmpBack()
  1198. of opcBranch:
  1199. # we know the next instruction is a 'fjmp':
  1200. let branch = c.constants[instr.regBx-wordExcess]
  1201. var cond = false
  1202. for j in 0..<branch.len - 1:
  1203. if overlap(regs[ra].regToNode, branch[j]):
  1204. cond = true
  1205. break
  1206. assert c.code[pc+1].opcode == opcFJmp
  1207. inc pc
  1208. # we skip this instruction so that the final 'inc(pc)' skips
  1209. # the following jump
  1210. if not cond:
  1211. let instr2 = c.code[pc]
  1212. let rbx = instr2.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  1213. inc pc, rbx
  1214. of opcTry:
  1215. let rbx = instr.regBx - wordExcess
  1216. tos.pushSafePoint(pc + rbx)
  1217. assert c.code[pc+rbx].opcode in {opcExcept, opcFinally}
  1218. of opcExcept:
  1219. # This opcode is never executed, it only holds information for the
  1220. # exception handling routines.
  1221. doAssert(false)
  1222. of opcFinally:
  1223. # Pop the last safepoint introduced by a opcTry. This opcode is only
  1224. # executed _iff_ no exception was raised in the body of the `try`
  1225. # statement hence the need to pop the safepoint here.
  1226. doAssert(savedPC < 0)
  1227. tos.popSafePoint()
  1228. of opcFinallyEnd:
  1229. # The control flow may not resume at the next instruction since we may be
  1230. # raising an exception or performing a cleanup.
  1231. if savedPC >= 0:
  1232. pc = savedPC - 1
  1233. savedPC = -1
  1234. if tos != savedFrame:
  1235. tos = savedFrame
  1236. move(regs, tos.slots)
  1237. of opcRaise:
  1238. let raised =
  1239. # Empty `raise` statement - reraise current exception
  1240. if regs[ra].kind == rkNone:
  1241. c.currentExceptionA
  1242. else:
  1243. regs[ra].node
  1244. c.currentExceptionA = raised
  1245. # Set the `name` field of the exception
  1246. c.currentExceptionA[2].skipColon.strVal = c.currentExceptionA.typ.sym.name.s
  1247. c.exceptionInstr = pc
  1248. var frame = tos
  1249. var jumpTo = findExceptionHandler(c, frame, raised)
  1250. while jumpTo.why == ExceptionGotoUnhandled and not frame.next.isNil:
  1251. frame = frame.next
  1252. jumpTo = findExceptionHandler(c, frame, raised)
  1253. case jumpTo.why:
  1254. of ExceptionGotoHandler:
  1255. # Jump to the handler, do nothing when the `finally` block ends.
  1256. savedPC = -1
  1257. pc = jumpTo.where - 1
  1258. if tos != frame:
  1259. tos = frame
  1260. move(regs, tos.slots)
  1261. of ExceptionGotoFinally:
  1262. # Jump to the `finally` block first then re-jump here to continue the
  1263. # traversal of the exception chain
  1264. savedPC = pc
  1265. savedFrame = tos
  1266. pc = jumpTo.where - 1
  1267. if tos != frame:
  1268. tos = frame
  1269. move(regs, tos.slots)
  1270. of ExceptionGotoUnhandled:
  1271. # Nobody handled this exception, error out.
  1272. bailOut(c, tos)
  1273. of opcNew:
  1274. ensureKind(rkNode)
  1275. let typ = c.types[instr.regBx - wordExcess]
  1276. regs[ra].node = getNullValue(typ, c.debug[pc], c.config)
  1277. regs[ra].node.flags.incl nfIsRef
  1278. of opcNewSeq:
  1279. let typ = c.types[instr.regBx - wordExcess]
  1280. inc pc
  1281. ensureKind(rkNode)
  1282. let instr2 = c.code[pc]
  1283. let count = regs[instr2.regA].intVal.int
  1284. regs[ra].node = newNodeI(nkBracket, c.debug[pc])
  1285. regs[ra].node.typ = typ
  1286. newSeq(regs[ra].node.sons, count)
  1287. for i in 0..<count:
  1288. regs[ra].node[i] = getNullValue(typ[0], c.debug[pc], c.config)
  1289. of opcNewStr:
  1290. decodeB(rkNode)
  1291. regs[ra].node = newNodeI(nkStrLit, c.debug[pc])
  1292. regs[ra].node.strVal = newString(regs[rb].intVal.int)
  1293. of opcLdImmInt:
  1294. # dest = immediate value
  1295. decodeBx(rkInt)
  1296. regs[ra].intVal = rbx
  1297. of opcLdNull:
  1298. ensureKind(rkNode)
  1299. let typ = c.types[instr.regBx - wordExcess]
  1300. regs[ra].node = getNullValue(typ, c.debug[pc], c.config)
  1301. # opcLdNull really is the gist of the VM's problems: should it load
  1302. # a fresh null to regs[ra].node or to regs[ra].node[]? This really
  1303. # depends on whether regs[ra] represents the variable itself or whether
  1304. # it holds the indirection! Due to the way registers are re-used we cannot
  1305. # say for sure here! --> The codegen has to deal with it
  1306. # via 'genAsgnPatch'.
  1307. of opcLdNullReg:
  1308. let typ = c.types[instr.regBx - wordExcess]
  1309. if typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc}).kind in {
  1310. tyFloat..tyFloat128}:
  1311. ensureKind(rkFloat)
  1312. regs[ra].floatVal = 0.0
  1313. else:
  1314. ensureKind(rkInt)
  1315. regs[ra].intVal = 0
  1316. of opcLdConst:
  1317. let rb = instr.regBx - wordExcess
  1318. let cnst = c.constants[rb]
  1319. if fitsRegister(cnst.typ):
  1320. reset(regs[ra])
  1321. putIntoReg(regs[ra], cnst)
  1322. else:
  1323. ensureKind(rkNode)
  1324. regs[ra].node = cnst
  1325. of opcAsgnConst:
  1326. let rb = instr.regBx - wordExcess
  1327. let cnst = c.constants[rb]
  1328. if fitsRegister(cnst.typ):
  1329. putIntoReg(regs[ra], cnst)
  1330. else:
  1331. ensureKind(rkNode)
  1332. regs[ra].node = cnst.copyTree
  1333. of opcLdGlobal:
  1334. let rb = instr.regBx - wordExcess - 1
  1335. ensureKind(rkNode)
  1336. regs[ra].node = c.globals[rb]
  1337. of opcLdGlobalDerefFFI:
  1338. let rb = instr.regBx - wordExcess - 1
  1339. let node = c.globals[rb]
  1340. let typ = node.typ
  1341. doAssert node.kind == nkIntLit, $(node.kind)
  1342. if typ.kind == tyPtr:
  1343. ensureKind(rkNode)
  1344. # use nkPtrLit once this is added
  1345. let node2 = newNodeIT(nkIntLit, c.debug[pc], typ)
  1346. node2.intVal = cast[ptr int](node.intVal)[]
  1347. node2.flags.incl nfIsPtr
  1348. regs[ra].node = node2
  1349. elif not derefPtrToReg(node.intVal, typ, regs[ra], isAssign = false):
  1350. stackTrace(c, tos, pc, "opcLdDeref unsupported type: " & $(typeToString(typ), typ[0].kind))
  1351. of opcLdGlobalAddrDerefFFI:
  1352. let rb = instr.regBx - wordExcess - 1
  1353. let node = c.globals[rb]
  1354. let typ = node.typ
  1355. var node2 = newNodeIT(nkIntLit, node.info, typ)
  1356. node2.intVal = node.intVal
  1357. node2.flags.incl nfIsPtr
  1358. ensureKind(rkNode)
  1359. regs[ra].node = node2
  1360. of opcLdGlobalAddr:
  1361. let rb = instr.regBx - wordExcess - 1
  1362. ensureKind(rkNodeAddr)
  1363. regs[ra].nodeAddr = addr(c.globals[rb])
  1364. of opcRepr:
  1365. decodeB(rkNode)
  1366. createStr regs[ra]
  1367. regs[ra].node.strVal = renderTree(regs[rb].regToNode, {renderNoComments, renderDocComments})
  1368. of opcQuit:
  1369. if c.mode in {emRepl, emStaticExpr, emStaticStmt}:
  1370. message(c.config, c.debug[pc], hintQuitCalled)
  1371. msgQuit(int8(toInt(getOrdValue(regs[ra].regToNode, onError = toInt128(1)))))
  1372. else:
  1373. return TFullReg(kind: rkNone)
  1374. of opcInvalidField:
  1375. stackTrace(c, tos, pc, errFieldXNotFound & regs[ra].node.strVal)
  1376. of opcSetLenStr:
  1377. decodeB(rkNode)
  1378. #createStrKeepNode regs[ra]
  1379. regs[ra].node.strVal.setLen(regs[rb].intVal.int)
  1380. of opcOf:
  1381. decodeBC(rkInt)
  1382. let typ = c.types[regs[rc].intVal.int]
  1383. regs[ra].intVal = ord(inheritanceDiff(regs[rb].node.typ, typ) <= 0)
  1384. of opcIs:
  1385. decodeBC(rkInt)
  1386. let t1 = regs[rb].node.typ.skipTypes({tyTypeDesc})
  1387. let t2 = c.types[regs[rc].intVal.int]
  1388. # XXX: This should use the standard isOpImpl
  1389. let match = if t2.kind == tyUserTypeClass: true
  1390. else: sameType(t1, t2)
  1391. regs[ra].intVal = ord(match)
  1392. of opcSetLenSeq:
  1393. decodeB(rkNode)
  1394. let newLen = regs[rb].intVal.int
  1395. if regs[ra].node.isNil: stackTrace(c, tos, pc, errNilAccess)
  1396. else: c.setLenSeq(regs[ra].node, newLen, c.debug[pc])
  1397. of opcNarrowS:
  1398. decodeB(rkInt)
  1399. let min = -(1.BiggestInt shl (rb-1))
  1400. let max = (1.BiggestInt shl (rb-1))-1
  1401. if regs[ra].intVal < min or regs[ra].intVal > max:
  1402. stackTrace(c, tos, pc, "unhandled exception: value out of range")
  1403. of opcNarrowU:
  1404. decodeB(rkInt)
  1405. regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
  1406. of opcSignExtend:
  1407. # like opcNarrowS, but no out of range possible
  1408. decodeB(rkInt)
  1409. let imm = 64 - rb
  1410. regs[ra].intVal = ashr(regs[ra].intVal shl imm, imm)
  1411. of opcIsNil:
  1412. decodeB(rkInt)
  1413. let node = regs[rb].node
  1414. regs[ra].intVal = ord(
  1415. # Note that `nfIsRef` + `nkNilLit` represents an allocated
  1416. # reference with the value `nil`, so `isNil` should be false!
  1417. (node.kind == nkNilLit and nfIsRef notin node.flags) or
  1418. (not node.typ.isNil and node.typ.kind == tyProc and
  1419. node.typ.callConv == ccClosure and node[0].kind == nkNilLit and
  1420. node[1].kind == nkNilLit))
  1421. of opcNBindSym:
  1422. # cannot use this simple check
  1423. # if dynamicBindSym notin c.config.features:
  1424. # bindSym with static input
  1425. decodeBx(rkNode)
  1426. regs[ra].node = copyTree(c.constants[rbx])
  1427. regs[ra].node.flags.incl nfIsRef
  1428. of opcNDynBindSym:
  1429. # experimental bindSym
  1430. let
  1431. rb = instr.regB
  1432. rc = instr.regC
  1433. idx = int(regs[rb+rc-1].intVal)
  1434. callback = c.callbacks[idx].value
  1435. args = VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[ptr UncheckedArray[TFullReg]](addr regs[0]),
  1436. currentException: c.currentExceptionA,
  1437. currentLineInfo: c.debug[pc])
  1438. callback(args)
  1439. regs[ra].node.flags.incl nfIsRef
  1440. of opcNChild:
  1441. decodeBC(rkNode)
  1442. let idx = regs[rc].intVal.int
  1443. let src = regs[rb].node
  1444. if src.kind in {nkEmpty..nkNilLit}:
  1445. stackTrace(c, tos, pc, "cannot get child of node kind: n" & $src.kind)
  1446. elif idx >=% src.len:
  1447. stackTrace(c, tos, pc, formatErrorIndexBound(idx, src.len-1))
  1448. else:
  1449. regs[ra].node = src[idx]
  1450. of opcNSetChild:
  1451. decodeBC(rkNode)
  1452. let idx = regs[rb].intVal.int
  1453. var dest = regs[ra].node
  1454. if nfSem in dest.flags and allowSemcheckedAstModification notin c.config.legacyFeatures:
  1455. stackTrace(c, tos, pc, "typechecked nodes may not be modified")
  1456. elif dest.kind in {nkEmpty..nkNilLit}:
  1457. stackTrace(c, tos, pc, "cannot set child of node kind: n" & $dest.kind)
  1458. elif idx >=% dest.len:
  1459. stackTrace(c, tos, pc, formatErrorIndexBound(idx, dest.len-1))
  1460. else:
  1461. dest[idx] = regs[rc].node
  1462. of opcNAdd:
  1463. decodeBC(rkNode)
  1464. var u = regs[rb].node
  1465. if nfSem in u.flags and allowSemcheckedAstModification notin c.config.legacyFeatures:
  1466. stackTrace(c, tos, pc, "typechecked nodes may not be modified")
  1467. elif u.kind in {nkEmpty..nkNilLit}:
  1468. stackTrace(c, tos, pc, "cannot add to node kind: n" & $u.kind)
  1469. else:
  1470. u.add(regs[rc].node)
  1471. regs[ra].node = u
  1472. of opcNAddMultiple:
  1473. decodeBC(rkNode)
  1474. let x = regs[rc].node
  1475. var u = regs[rb].node
  1476. if nfSem in u.flags and allowSemcheckedAstModification notin c.config.legacyFeatures:
  1477. stackTrace(c, tos, pc, "typechecked nodes may not be modified")
  1478. elif u.kind in {nkEmpty..nkNilLit}:
  1479. stackTrace(c, tos, pc, "cannot add to node kind: n" & $u.kind)
  1480. else:
  1481. for i in 0..<x.len: u.add(x[i])
  1482. regs[ra].node = u
  1483. of opcNKind:
  1484. decodeB(rkInt)
  1485. regs[ra].intVal = ord(regs[rb].node.kind)
  1486. c.comesFromHeuristic = regs[rb].node.info
  1487. of opcNSymKind:
  1488. decodeB(rkInt)
  1489. let a = regs[rb].node
  1490. if a.kind == nkSym:
  1491. regs[ra].intVal = ord(a.sym.kind)
  1492. else:
  1493. stackTrace(c, tos, pc, "node is not a symbol")
  1494. c.comesFromHeuristic = regs[rb].node.info
  1495. of opcNIntVal:
  1496. decodeB(rkInt)
  1497. let a = regs[rb].node
  1498. if a.kind in {nkCharLit..nkUInt64Lit}:
  1499. regs[ra].intVal = a.intVal
  1500. elif a.kind == nkSym and a.sym.kind == skEnumField:
  1501. regs[ra].intVal = a.sym.position
  1502. else:
  1503. stackTrace(c, tos, pc, errFieldXNotFound & "intVal")
  1504. of opcNFloatVal:
  1505. decodeB(rkFloat)
  1506. let a = regs[rb].node
  1507. case a.kind
  1508. of nkFloatLit..nkFloat64Lit: regs[ra].floatVal = a.floatVal
  1509. else: stackTrace(c, tos, pc, errFieldXNotFound & "floatVal")
  1510. of opcNSymbol:
  1511. decodeB(rkNode)
  1512. let a = regs[rb].node
  1513. if a.kind == nkSym:
  1514. regs[ra].node = copyNode(a)
  1515. else:
  1516. stackTrace(c, tos, pc, errFieldXNotFound & "symbol")
  1517. of opcNIdent:
  1518. decodeB(rkNode)
  1519. let a = regs[rb].node
  1520. if a.kind == nkIdent:
  1521. regs[ra].node = copyNode(a)
  1522. else:
  1523. stackTrace(c, tos, pc, errFieldXNotFound & "ident")
  1524. of opcNodeId:
  1525. decodeB(rkInt)
  1526. when defined(useNodeIds):
  1527. regs[ra].intVal = regs[rb].node.id
  1528. else:
  1529. regs[ra].intVal = -1
  1530. of opcNGetType:
  1531. let rb = instr.regB
  1532. let rc = instr.regC
  1533. case rc
  1534. of 0:
  1535. # getType opcode:
  1536. ensureKind(rkNode)
  1537. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1538. regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.typ, c.debug[pc])
  1539. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1540. regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
  1541. else:
  1542. stackTrace(c, tos, pc, "node has no type")
  1543. of 1:
  1544. # typeKind opcode:
  1545. ensureKind(rkInt)
  1546. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1547. regs[ra].intVal = ord(regs[rb].node.typ.kind)
  1548. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1549. regs[ra].intVal = ord(regs[rb].node.sym.typ.kind)
  1550. #else:
  1551. # stackTrace(c, tos, pc, "node has no type")
  1552. of 2:
  1553. # getTypeInst opcode:
  1554. ensureKind(rkNode)
  1555. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1556. regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.typ, c.debug[pc])
  1557. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1558. regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
  1559. else:
  1560. stackTrace(c, tos, pc, "node has no type")
  1561. else:
  1562. # getTypeImpl opcode:
  1563. ensureKind(rkNode)
  1564. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1565. regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.typ, c.debug[pc])
  1566. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1567. regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
  1568. else:
  1569. stackTrace(c, tos, pc, "node has no type")
  1570. of opcNGetSize:
  1571. decodeBImm(rkInt)
  1572. let n = regs[rb].node
  1573. case imm
  1574. of 0: # size
  1575. if n.typ == nil:
  1576. stackTrace(c, tos, pc, "node has no type")
  1577. else:
  1578. regs[ra].intVal = getSize(c.config, n.typ)
  1579. of 1: # align
  1580. if n.typ == nil:
  1581. stackTrace(c, tos, pc, "node has no type")
  1582. else:
  1583. regs[ra].intVal = getAlign(c.config, n.typ)
  1584. else: # offset
  1585. if n.kind != nkSym:
  1586. stackTrace(c, tos, pc, "node is not a symbol")
  1587. elif n.sym.kind != skField:
  1588. stackTrace(c, tos, pc, "symbol is not a field (nskField)")
  1589. else:
  1590. regs[ra].intVal = n.sym.offset
  1591. of opcNStrVal:
  1592. decodeB(rkNode)
  1593. createStr regs[ra]
  1594. let a = regs[rb].node
  1595. case a.kind
  1596. of nkStrLit..nkTripleStrLit:
  1597. regs[ra].node.strVal = a.strVal
  1598. of nkCommentStmt:
  1599. regs[ra].node.strVal = a.comment
  1600. of nkIdent:
  1601. regs[ra].node.strVal = a.ident.s
  1602. of nkSym:
  1603. regs[ra].node.strVal = a.sym.name.s
  1604. else:
  1605. stackTrace(c, tos, pc, errFieldXNotFound & "strVal")
  1606. of opcNSigHash:
  1607. decodeB(rkNode)
  1608. createStr regs[ra]
  1609. if regs[rb].node.kind != nkSym:
  1610. stackTrace(c, tos, pc, "node is not a symbol")
  1611. else:
  1612. regs[ra].node.strVal = $sigHash(regs[rb].node.sym)
  1613. of opcSlurp:
  1614. decodeB(rkNode)
  1615. createStr regs[ra]
  1616. regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc],
  1617. c.module, c.config)
  1618. of opcGorge:
  1619. decodeBC(rkNode)
  1620. inc pc
  1621. let rd = c.code[pc].regA
  1622. createStr regs[ra]
  1623. if defined(nimsuggest) or c.config.cmd == cmdCheck:
  1624. discard "don't run staticExec for 'nim suggest'"
  1625. regs[ra].node.strVal = ""
  1626. else:
  1627. when defined(nimcore):
  1628. regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
  1629. regs[rc].node.strVal, regs[rd].node.strVal,
  1630. c.debug[pc], c.config)[0]
  1631. else:
  1632. regs[ra].node.strVal = ""
  1633. globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support")
  1634. of opcNError, opcNWarning, opcNHint:
  1635. decodeB(rkNode)
  1636. let a = regs[ra].node
  1637. let b = regs[rb].node
  1638. let info = if b.kind == nkNilLit: c.debug[pc] else: b.info
  1639. if instr.opcode == opcNError:
  1640. stackTrace(c, tos, pc, a.strVal, info)
  1641. elif instr.opcode == opcNWarning:
  1642. message(c.config, info, warnUser, a.strVal)
  1643. elif instr.opcode == opcNHint:
  1644. message(c.config, info, hintUser, a.strVal)
  1645. of opcParseExprToAst:
  1646. decodeB(rkNode)
  1647. # c.debug[pc].line.int - countLines(regs[rb].strVal) ?
  1648. var error: string
  1649. let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
  1650. toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int,
  1651. proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) {.nosinks.} =
  1652. if error.len == 0 and msg <= errMax:
  1653. error = formatMsg(conf, info, msg, arg))
  1654. if error.len > 0:
  1655. c.errorFlag = error
  1656. elif ast.len != 1:
  1657. c.errorFlag = formatMsg(c.config, c.debug[pc], errGenerated,
  1658. "expected expression, but got multiple statements")
  1659. else:
  1660. regs[ra].node = ast[0]
  1661. of opcParseStmtToAst:
  1662. decodeB(rkNode)
  1663. var error: string
  1664. let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
  1665. toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int,
  1666. proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) {.nosinks.} =
  1667. if error.len == 0 and msg <= errMax:
  1668. error = formatMsg(conf, info, msg, arg))
  1669. if error.len > 0:
  1670. c.errorFlag = error
  1671. else:
  1672. regs[ra].node = ast
  1673. of opcQueryErrorFlag:
  1674. createStr regs[ra]
  1675. regs[ra].node.strVal = c.errorFlag
  1676. c.errorFlag.setLen 0
  1677. of opcCallSite:
  1678. ensureKind(rkNode)
  1679. if c.callsite != nil: regs[ra].node = c.callsite
  1680. else: stackTrace(c, tos, pc, errFieldXNotFound & "callsite")
  1681. of opcNGetLineInfo:
  1682. decodeBImm(rkNode)
  1683. let n = regs[rb].node
  1684. case imm
  1685. of 0: # getFile
  1686. regs[ra].node = newStrNode(nkStrLit, toFullPath(c.config, n.info))
  1687. of 1: # getLine
  1688. regs[ra].node = newIntNode(nkIntLit, n.info.line.int)
  1689. of 2: # getColumn
  1690. regs[ra].node = newIntNode(nkIntLit, n.info.col)
  1691. else:
  1692. internalAssert c.config, false
  1693. regs[ra].node.info = n.info
  1694. regs[ra].node.typ = n.typ
  1695. of opcNSetLineInfo:
  1696. decodeB(rkNode)
  1697. regs[ra].node.info = regs[rb].node.info
  1698. of opcEqIdent:
  1699. decodeBC(rkInt)
  1700. # aliases for shorter and easier to understand code below
  1701. var aNode = regs[rb].node
  1702. var bNode = regs[rc].node
  1703. # Skipping both, `nkPostfix` and `nkAccQuoted` for both
  1704. # arguments. `nkPostfix` exists only to tag exported symbols
  1705. # and therefor it can be safely skipped. Nim has no postfix
  1706. # operator. `nkAccQuoted` is used to quote an identifier that
  1707. # wouldn't be allowed to use in an unquoted context.
  1708. if aNode.kind == nkPostfix:
  1709. aNode = aNode[1]
  1710. if aNode.kind == nkAccQuoted:
  1711. aNode = aNode[0]
  1712. if bNode.kind == nkPostfix:
  1713. bNode = bNode[1]
  1714. if bNode.kind == nkAccQuoted:
  1715. bNode = bNode[0]
  1716. # These vars are of type `cstring` to prevent unnecessary string copy.
  1717. var aStrVal: cstring = nil
  1718. var bStrVal: cstring = nil
  1719. # extract strVal from argument ``a``
  1720. case aNode.kind
  1721. of nkStrLit..nkTripleStrLit:
  1722. aStrVal = aNode.strVal.cstring
  1723. of nkIdent:
  1724. aStrVal = aNode.ident.s.cstring
  1725. of nkSym:
  1726. aStrVal = aNode.sym.name.s.cstring
  1727. of nkOpenSymChoice, nkClosedSymChoice:
  1728. aStrVal = aNode[0].sym.name.s.cstring
  1729. else:
  1730. discard
  1731. # extract strVal from argument ``b``
  1732. case bNode.kind
  1733. of nkStrLit..nkTripleStrLit:
  1734. bStrVal = bNode.strVal.cstring
  1735. of nkIdent:
  1736. bStrVal = bNode.ident.s.cstring
  1737. of nkSym:
  1738. bStrVal = bNode.sym.name.s.cstring
  1739. of nkOpenSymChoice, nkClosedSymChoice:
  1740. bStrVal = bNode[0].sym.name.s.cstring
  1741. else:
  1742. discard
  1743. regs[ra].intVal =
  1744. if aStrVal != nil and bStrVal != nil:
  1745. ord(idents.cmpIgnoreStyle(aStrVal, bStrVal, high(int)) == 0)
  1746. else:
  1747. 0
  1748. of opcStrToIdent:
  1749. decodeB(rkNode)
  1750. if regs[rb].node.kind notin {nkStrLit..nkTripleStrLit}:
  1751. stackTrace(c, tos, pc, errFieldXNotFound & "strVal")
  1752. else:
  1753. regs[ra].node = newNodeI(nkIdent, c.debug[pc])
  1754. regs[ra].node.ident = getIdent(c.cache, regs[rb].node.strVal)
  1755. regs[ra].node.flags.incl nfIsRef
  1756. of opcSetType:
  1757. let typ = c.types[instr.regBx - wordExcess]
  1758. if regs[ra].kind != rkNode:
  1759. let temp = regToNode(regs[ra])
  1760. ensureKind(rkNode)
  1761. regs[ra].node = temp
  1762. regs[ra].node.info = c.debug[pc]
  1763. regs[ra].node.typ = typ
  1764. of opcConv:
  1765. let rb = instr.regB
  1766. inc pc
  1767. let desttyp = c.types[c.code[pc].regBx - wordExcess]
  1768. inc pc
  1769. let srctyp = c.types[c.code[pc].regBx - wordExcess]
  1770. if opConv(c, regs[ra], regs[rb], desttyp, srctyp):
  1771. stackTrace(c, tos, pc,
  1772. errIllegalConvFromXtoY % [
  1773. typeToString(srctyp), typeToString(desttyp)])
  1774. of opcCast:
  1775. let rb = instr.regB
  1776. inc pc
  1777. let desttyp = c.types[c.code[pc].regBx - wordExcess]
  1778. inc pc
  1779. let srctyp = c.types[c.code[pc].regBx - wordExcess]
  1780. when hasFFI:
  1781. let dest = fficast(c.config, regs[rb].node, desttyp)
  1782. # todo: check whether this is correct
  1783. # asgnRef(regs[ra], dest)
  1784. putIntoReg(regs[ra], dest)
  1785. else:
  1786. globalError(c.config, c.debug[pc], "cannot evaluate cast")
  1787. of opcNSetIntVal:
  1788. decodeB(rkNode)
  1789. var dest = regs[ra].node
  1790. if dest.kind in {nkCharLit..nkUInt64Lit} and
  1791. regs[rb].kind in {rkInt}:
  1792. dest.intVal = regs[rb].intVal
  1793. elif dest.kind == nkSym and dest.sym.kind == skEnumField:
  1794. stackTrace(c, tos, pc, "`intVal` cannot be changed for an enum symbol.")
  1795. else:
  1796. stackTrace(c, tos, pc, errFieldXNotFound & "intVal")
  1797. of opcNSetFloatVal:
  1798. decodeB(rkNode)
  1799. var dest = regs[ra].node
  1800. if dest.kind in {nkFloatLit..nkFloat64Lit} and
  1801. regs[rb].kind in {rkFloat}:
  1802. dest.floatVal = regs[rb].floatVal
  1803. else:
  1804. stackTrace(c, tos, pc, errFieldXNotFound & "floatVal")
  1805. of opcNSetSymbol:
  1806. decodeB(rkNode)
  1807. var dest = regs[ra].node
  1808. if dest.kind == nkSym and regs[rb].node.kind == nkSym:
  1809. dest.sym = regs[rb].node.sym
  1810. else:
  1811. stackTrace(c, tos, pc, errFieldXNotFound & "symbol")
  1812. of opcNSetIdent:
  1813. decodeB(rkNode)
  1814. var dest = regs[ra].node
  1815. if dest.kind == nkIdent and regs[rb].node.kind == nkIdent:
  1816. dest.ident = regs[rb].node.ident
  1817. else:
  1818. stackTrace(c, tos, pc, errFieldXNotFound & "ident")
  1819. of opcNSetType:
  1820. decodeB(rkNode)
  1821. let b = regs[rb].node
  1822. internalAssert c.config, b.kind == nkSym and b.sym.kind == skType
  1823. internalAssert c.config, regs[ra].node != nil
  1824. regs[ra].node.typ = b.sym.typ
  1825. of opcNSetStrVal:
  1826. decodeB(rkNode)
  1827. var dest = regs[ra].node
  1828. if dest.kind in {nkStrLit..nkTripleStrLit} and
  1829. regs[rb].kind in {rkNode}:
  1830. dest.strVal = regs[rb].node.strVal
  1831. elif dest.kind == nkCommentStmt and regs[rb].kind in {rkNode}:
  1832. dest.comment = regs[rb].node.strVal
  1833. else:
  1834. stackTrace(c, tos, pc, errFieldXNotFound & "strVal")
  1835. of opcNNewNimNode:
  1836. decodeBC(rkNode)
  1837. var k = regs[rb].intVal
  1838. if k < 0 or k > ord(high(TNodeKind)):
  1839. internalError(c.config, c.debug[pc],
  1840. "request to create a NimNode of invalid kind")
  1841. let cc = regs[rc].node
  1842. let x = newNodeI(TNodeKind(int(k)),
  1843. if cc.kind != nkNilLit:
  1844. cc.info
  1845. elif c.comesFromHeuristic.line != 0'u16:
  1846. c.comesFromHeuristic
  1847. elif c.callsite != nil and c.callsite.safeLen > 1:
  1848. c.callsite[1].info
  1849. else:
  1850. c.debug[pc])
  1851. x.flags.incl nfIsRef
  1852. # prevent crashes in the compiler resulting from wrong macros:
  1853. if x.kind == nkIdent: x.ident = c.cache.emptyIdent
  1854. regs[ra].node = x
  1855. of opcNCopyNimNode:
  1856. decodeB(rkNode)
  1857. regs[ra].node = copyNode(regs[rb].node)
  1858. of opcNCopyNimTree:
  1859. decodeB(rkNode)
  1860. regs[ra].node = copyTree(regs[rb].node)
  1861. of opcNDel:
  1862. decodeBC(rkNode)
  1863. let bb = regs[rb].intVal.int
  1864. for i in 0..<regs[rc].intVal.int:
  1865. delSon(regs[ra].node, bb)
  1866. of opcGenSym:
  1867. decodeBC(rkNode)
  1868. let k = regs[rb].intVal
  1869. let name = if regs[rc].node.strVal.len == 0: ":tmp"
  1870. else: regs[rc].node.strVal
  1871. if k < 0 or k > ord(high(TSymKind)):
  1872. internalError(c.config, c.debug[pc], "request to create symbol of invalid kind")
  1873. var sym = newSym(k.TSymKind, getIdent(c.cache, name), c.module.owner, c.debug[pc])
  1874. incl(sym.flags, sfGenSym)
  1875. regs[ra].node = newSymNode(sym)
  1876. regs[ra].node.flags.incl nfIsRef
  1877. of opcNccValue:
  1878. decodeB(rkInt)
  1879. let destKey = regs[rb].node.strVal
  1880. regs[ra].intVal = getOrDefault(c.graph.cacheCounters, destKey)
  1881. of opcNccInc:
  1882. let g = c.graph
  1883. declBC()
  1884. let destKey = regs[rb].node.strVal
  1885. let by = regs[rc].intVal
  1886. let v = getOrDefault(g.cacheCounters, destKey)
  1887. g.cacheCounters[destKey] = v+by
  1888. recordInc(c, c.debug[pc], destKey, by)
  1889. of opcNcsAdd:
  1890. let g = c.graph
  1891. declBC()
  1892. let destKey = regs[rb].node.strVal
  1893. let val = regs[rc].node
  1894. if not contains(g.cacheSeqs, destKey):
  1895. g.cacheSeqs[destKey] = newTree(nkStmtList, val)
  1896. else:
  1897. g.cacheSeqs[destKey].add val
  1898. recordAdd(c, c.debug[pc], destKey, val)
  1899. of opcNcsIncl:
  1900. let g = c.graph
  1901. declBC()
  1902. let destKey = regs[rb].node.strVal
  1903. let val = regs[rc].node
  1904. if not contains(g.cacheSeqs, destKey):
  1905. g.cacheSeqs[destKey] = newTree(nkStmtList, val)
  1906. else:
  1907. block search:
  1908. for existing in g.cacheSeqs[destKey]:
  1909. if exprStructuralEquivalent(existing, val, strictSymEquality=true):
  1910. break search
  1911. g.cacheSeqs[destKey].add val
  1912. recordIncl(c, c.debug[pc], destKey, val)
  1913. of opcNcsLen:
  1914. let g = c.graph
  1915. decodeB(rkInt)
  1916. let destKey = regs[rb].node.strVal
  1917. regs[ra].intVal =
  1918. if contains(g.cacheSeqs, destKey): g.cacheSeqs[destKey].len else: 0
  1919. of opcNcsAt:
  1920. let g = c.graph
  1921. decodeBC(rkNode)
  1922. let idx = regs[rc].intVal
  1923. let destKey = regs[rb].node.strVal
  1924. if contains(g.cacheSeqs, destKey) and idx <% g.cacheSeqs[destKey].len:
  1925. regs[ra].node = g.cacheSeqs[destKey][idx.int]
  1926. else:
  1927. stackTrace(c, tos, pc, formatErrorIndexBound(idx, g.cacheSeqs[destKey].len-1))
  1928. of opcNctPut:
  1929. let g = c.graph
  1930. let destKey = regs[ra].node.strVal
  1931. let key = regs[instr.regB].node.strVal
  1932. let val = regs[instr.regC].node
  1933. if not contains(g.cacheTables, destKey):
  1934. g.cacheTables[destKey] = initBTree[string, PNode]()
  1935. if not contains(g.cacheTables[destKey], key):
  1936. g.cacheTables[destKey].add(key, val)
  1937. recordPut(c, c.debug[pc], destKey, key, val)
  1938. else:
  1939. stackTrace(c, tos, pc, "key already exists: " & key)
  1940. of opcNctLen:
  1941. let g = c.graph
  1942. decodeB(rkInt)
  1943. let destKey = regs[rb].node.strVal
  1944. regs[ra].intVal =
  1945. if contains(g.cacheTables, destKey): g.cacheTables[destKey].len else: 0
  1946. of opcNctGet:
  1947. let g = c.graph
  1948. decodeBC(rkNode)
  1949. let destKey = regs[rb].node.strVal
  1950. let key = regs[rc].node.strVal
  1951. if contains(g.cacheTables, destKey):
  1952. if contains(g.cacheTables[destKey], key):
  1953. regs[ra].node = getOrDefault(g.cacheTables[destKey], key)
  1954. else:
  1955. stackTrace(c, tos, pc, "key does not exist: " & key)
  1956. else:
  1957. stackTrace(c, tos, pc, "key does not exist: " & destKey)
  1958. of opcNctHasNext:
  1959. let g = c.graph
  1960. decodeBC(rkInt)
  1961. let destKey = regs[rb].node.strVal
  1962. regs[ra].intVal =
  1963. if g.cacheTables.contains(destKey):
  1964. ord(btrees.hasNext(g.cacheTables[destKey], regs[rc].intVal.int))
  1965. else:
  1966. 0
  1967. of opcNctNext:
  1968. let g = c.graph
  1969. decodeBC(rkNode)
  1970. let destKey = regs[rb].node.strVal
  1971. let index = regs[rc].intVal
  1972. if contains(g.cacheTables, destKey):
  1973. let (k, v, nextIndex) = btrees.next(g.cacheTables[destKey], index.int)
  1974. regs[ra].node = newTree(nkTupleConstr, newStrNode(k, c.debug[pc]), v,
  1975. newIntNode(nkIntLit, nextIndex))
  1976. else:
  1977. stackTrace(c, tos, pc, "key does not exist: " & destKey)
  1978. of opcTypeTrait:
  1979. # XXX only supports 'name' for now; we can use regC to encode the
  1980. # type trait operation
  1981. decodeB(rkNode)
  1982. var typ = regs[rb].node.typ
  1983. internalAssert c.config, typ != nil
  1984. while typ.kind == tyTypeDesc and typ.len > 0: typ = typ[0]
  1985. createStr regs[ra]
  1986. regs[ra].node.strVal = typ.typeToString(preferExported)
  1987. of opcMarshalLoad:
  1988. let ra = instr.regA
  1989. let rb = instr.regB
  1990. inc pc
  1991. let typ = c.types[c.code[pc].regBx - wordExcess]
  1992. putIntoReg(regs[ra], loadAny(regs[rb].node.strVal, typ, c.cache, c.config))
  1993. of opcMarshalStore:
  1994. decodeB(rkNode)
  1995. inc pc
  1996. let typ = c.types[c.code[pc].regBx - wordExcess]
  1997. createStrKeepNode(regs[ra])
  1998. when not defined(nimNoNilSeqs):
  1999. if regs[ra].node.strVal.isNil: regs[ra].node.strVal = newStringOfCap(1000)
  2000. storeAny(regs[ra].node.strVal, typ, regs[rb].regToNode, c.config)
  2001. inc pc
  2002. proc execute(c: PCtx, start: int): PNode =
  2003. var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil)
  2004. newSeq(tos.slots, c.prc.maxSlots)
  2005. result = rawExecute(c, start, tos).regToNode
  2006. proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
  2007. if sym.kind in routineKinds:
  2008. if sym.typ.len-1 != args.len:
  2009. localError(c.config, sym.info,
  2010. "NimScript: expected $# arguments, but got $#" % [
  2011. $(sym.typ.len-1), $args.len])
  2012. else:
  2013. let start = genProc(c, sym)
  2014. var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
  2015. let maxSlots = sym.offset
  2016. newSeq(tos.slots, maxSlots)
  2017. # setup parameters:
  2018. if not isEmptyType(sym.typ[0]) or sym.kind == skMacro:
  2019. putIntoReg(tos.slots[0], getNullValue(sym.typ[0], sym.info, c.config))
  2020. # XXX We could perform some type checking here.
  2021. for i in 1..<sym.typ.len:
  2022. putIntoReg(tos.slots[i], args[i-1])
  2023. result = rawExecute(c, start, tos).regToNode
  2024. else:
  2025. localError(c.config, sym.info,
  2026. "NimScript: attempt to call non-routine: " & sym.name.s)
  2027. proc evalStmt*(c: PCtx, n: PNode) =
  2028. let n = transformExpr(c.graph, c.module, n)
  2029. let start = genStmt(c, n)
  2030. # execute new instructions; this redundant opcEof check saves us lots
  2031. # of allocations in 'execute':
  2032. if c.code[start].opcode != opcEof:
  2033. discard execute(c, start)
  2034. proc evalExpr*(c: PCtx, n: PNode): PNode =
  2035. let n = transformExpr(c.graph, c.module, n)
  2036. let start = genExpr(c, n)
  2037. assert c.code[start].opcode != opcEof
  2038. result = execute(c, start)
  2039. proc getGlobalValue*(c: PCtx; s: PSym): PNode =
  2040. internalAssert c.config, s.kind in {skLet, skVar} and sfGlobal in s.flags
  2041. result = c.globals[s.position-1]
  2042. include vmops
  2043. proc setupGlobalCtx*(module: PSym; graph: ModuleGraph) =
  2044. if graph.vm.isNil:
  2045. graph.vm = newCtx(module, graph.cache, graph)
  2046. registerAdditionalOps(PCtx graph.vm)
  2047. else:
  2048. refresh(PCtx graph.vm, module)
  2049. proc myOpen(graph: ModuleGraph; module: PSym): PPassContext {.nosinks.} =
  2050. #var c = newEvalContext(module, emRepl)
  2051. #c.features = {allowCast, allowInfiniteLoops}
  2052. #pushStackFrame(c, newStackFrame())
  2053. # XXX produce a new 'globals' environment here:
  2054. setupGlobalCtx(module, graph)
  2055. result = PCtx graph.vm
  2056. proc myProcess(c: PPassContext, n: PNode): PNode =
  2057. let c = PCtx(c)
  2058. # don't eval errornous code:
  2059. if c.oldErrorCount == c.config.errorCounter:
  2060. evalStmt(c, n)
  2061. result = newNodeI(nkEmpty, n.info)
  2062. else:
  2063. result = n
  2064. c.oldErrorCount = c.config.errorCounter
  2065. proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
  2066. myProcess(c, n)
  2067. const evalPass* = makePass(myOpen, myProcess, myClose)
  2068. proc evalConstExprAux(module: PSym;
  2069. g: ModuleGraph; prc: PSym, n: PNode,
  2070. mode: TEvalMode): PNode =
  2071. if g.config.errorCounter > 0: return n
  2072. let n = transformExpr(g, module, n)
  2073. setupGlobalCtx(module, g)
  2074. var c = PCtx g.vm
  2075. let oldMode = c.mode
  2076. c.mode = mode
  2077. let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
  2078. if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
  2079. assert c.code[start].opcode != opcEof
  2080. when debugEchoCode: c.echoCode start
  2081. var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil)
  2082. newSeq(tos.slots, c.prc.maxSlots)
  2083. #for i in 0..<c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty)
  2084. result = rawExecute(c, start, tos).regToNode
  2085. if result.info.col < 0: result.info = n.info
  2086. c.mode = oldMode
  2087. proc evalConstExpr*(module: PSym; g: ModuleGraph; e: PNode): PNode =
  2088. result = evalConstExprAux(module, g, nil, e, emConst)
  2089. proc evalStaticExpr*(module: PSym; g: ModuleGraph; e: PNode, prc: PSym): PNode =
  2090. result = evalConstExprAux(module, g, prc, e, emStaticExpr)
  2091. proc evalStaticStmt*(module: PSym; g: ModuleGraph; e: PNode, prc: PSym) =
  2092. discard evalConstExprAux(module, g, prc, e, emStaticStmt)
  2093. proc setupCompileTimeVar*(module: PSym; g: ModuleGraph; n: PNode) =
  2094. discard evalConstExprAux(module, g, nil, n, emStaticStmt)
  2095. proc prepareVMValue(arg: PNode): PNode =
  2096. ## strip nkExprColonExpr from tuple values recurively. That is how
  2097. ## they are expected to be stored in the VM.
  2098. # Early abort without copy. No transformation takes place.
  2099. if arg.kind in nkLiterals:
  2100. return arg
  2101. result = copyNode(arg)
  2102. if arg.kind == nkTupleConstr:
  2103. for child in arg:
  2104. if child.kind == nkExprColonExpr:
  2105. result.add prepareVMValue(child[1])
  2106. else:
  2107. result.add prepareVMValue(child)
  2108. else:
  2109. for child in arg:
  2110. result.add prepareVMValue(child)
  2111. proc setupMacroParam(x: PNode, typ: PType): TFullReg =
  2112. case typ.kind
  2113. of tyStatic:
  2114. putIntoReg(result, prepareVMValue(x))
  2115. else:
  2116. var n = x
  2117. if n.kind in {nkHiddenSubConv, nkHiddenStdConv}: n = n[1]
  2118. n = n.canonValue
  2119. n.flags.incl nfIsRef
  2120. n.typ = x.typ
  2121. result = TFullReg(kind: rkNode, node: n)
  2122. iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
  2123. let gp = macroSym.ast[genericParamsPos]
  2124. for i in 0..<gp.len:
  2125. let genericParam = gp[i].sym
  2126. let posInCall = macroSym.typ.len + i
  2127. if posInCall < call.len:
  2128. yield (genericParam, call[posInCall])
  2129. # to prevent endless recursion in macro instantiation
  2130. const evalMacroLimit = 1000
  2131. proc errorNode(owner: PSym, n: PNode): PNode =
  2132. result = newNodeI(nkEmpty, n.info)
  2133. result.typ = newType(tyError, owner)
  2134. result.typ.flags.incl tfCheckedForDestructor
  2135. proc evalMacroCall*(module: PSym; g: ModuleGraph;
  2136. n, nOrig: PNode, sym: PSym): PNode =
  2137. if g.config.errorCounter > 0: return errorNode(module, n)
  2138. # XXX globalError() is ugly here, but I don't know a better solution for now
  2139. inc(g.config.evalMacroCounter)
  2140. if g.config.evalMacroCounter > evalMacroLimit:
  2141. globalError(g.config, n.info, "macro instantiation too nested")
  2142. # immediate macros can bypass any type and arity checking so we check the
  2143. # arity here too:
  2144. if sym.typ.len > n.safeLen and sym.typ.len > 1:
  2145. globalError(g.config, n.info, "in call '$#' got $#, but expected $# argument(s)" % [
  2146. n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)])
  2147. setupGlobalCtx(module, g)
  2148. var c = PCtx g.vm
  2149. let oldMode = c.mode
  2150. c.mode = emStaticStmt
  2151. c.comesFromHeuristic.line = 0'u16
  2152. c.callsite = nOrig
  2153. let start = genProc(c, sym)
  2154. var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
  2155. let maxSlots = sym.offset
  2156. newSeq(tos.slots, maxSlots)
  2157. # setup arguments:
  2158. var L = n.safeLen
  2159. if L == 0: L = 1
  2160. # This is wrong for tests/reject/tind1.nim where the passed 'else' part
  2161. # doesn't end up in the parameter:
  2162. #InternalAssert tos.slots.len >= L
  2163. # return value:
  2164. tos.slots[0] = TFullReg(kind: rkNode, node: newNodeI(nkEmpty, n.info))
  2165. # setup parameters:
  2166. for i in 1..<sym.typ.len:
  2167. tos.slots[i] = setupMacroParam(n[i], sym.typ[i])
  2168. let gp = sym.ast[genericParamsPos]
  2169. for i in 0..<gp.len:
  2170. let idx = sym.typ.len + i
  2171. if idx < n.len:
  2172. tos.slots[idx] = setupMacroParam(n[idx], gp[i].sym.typ)
  2173. else:
  2174. dec(g.config.evalMacroCounter)
  2175. c.callsite = nil
  2176. localError(c.config, n.info, "expected " & $gp.len &
  2177. " generic parameter(s)")
  2178. # temporary storage:
  2179. #for i in L..<maxSlots: tos.slots[i] = newNode(nkEmpty)
  2180. result = rawExecute(c, start, tos).regToNode
  2181. if result.info.line < 0: result.info = n.info
  2182. if cyclicTree(result): globalError(c.config, n.info, "macro produced a cyclic tree")
  2183. dec(g.config.evalMacroCounter)
  2184. c.callsite = nil
  2185. c.mode = oldMode