vm.nim 81 KB

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