vm.nim 69 KB

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