vm.nim 75 KB

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