vm.nim 70 KB

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