vm.nim 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741
  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
  19. from semfold import leValueConv, ordinalValToString
  20. from evaltempl import evalTemplate
  21. from modulegraphs import ModuleGraph
  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($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(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(s)
  72. proc stackTrace(c: PCtx, tos: PStackFrame, pc: int,
  73. msg: TMsgKind, arg = "", n: PNode = nil) =
  74. msgWriteln("stack trace: (most recent call last)")
  75. stackTraceAux(c, tos, pc)
  76. # XXX test if we want 'globalError' for every mode
  77. let lineInfo = if n == nil: c.debug[pc] else: n.info
  78. if c.mode == emRepl: globalError(lineInfo, msg, arg)
  79. else: localError(lineInfo, msg, arg)
  80. proc bailOut(c: PCtx; tos: PStackFrame) =
  81. stackTrace(c, tos, c.exceptionInstr, errUnhandledExceptionX,
  82. c.currentExceptionA.sons[3].skipColon.strVal)
  83. when not defined(nimComputedGoto):
  84. {.pragma: computedGoto.}
  85. proc myreset(n: var TFullReg) = reset(n)
  86. template ensureKind(k: untyped) {.dirty.} =
  87. if regs[ra].kind != k:
  88. myreset(regs[ra])
  89. regs[ra].kind = 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 createStrKeepNode(x: var TFullReg; keepNode=true) =
  110. if x.node.isNil or not keepNode:
  111. x.node = newNode(nkStrLit)
  112. elif x.node.kind == nkNilLit and keepNode:
  113. when defined(useNodeIds):
  114. let id = x.node.id
  115. system.reset(x.node[])
  116. x.node.kind = nkStrLit
  117. when defined(useNodeIds):
  118. x.node.id = id
  119. elif x.node.kind notin {nkStrLit..nkTripleStrLit} or
  120. nfAllConst in x.node.flags:
  121. # XXX this is hacky; tests/txmlgen triggers it:
  122. x.node = newNode(nkStrLit)
  123. # It not only hackey, it is also wrong for tgentemplate. The primary
  124. # cause of bugs like these is that the VM does not properly distinguish
  125. # between variable defintions (var foo = e) and variable updates (foo = e).
  126. include vmhooks
  127. template createStr(x) =
  128. x.node = newNode(nkStrLit)
  129. template createSet(x) =
  130. x.node = newNode(nkCurly)
  131. proc moveConst(x: var TFullReg, y: TFullReg) =
  132. if x.kind != y.kind:
  133. myreset(x)
  134. x.kind = y.kind
  135. case x.kind
  136. of rkNone: discard
  137. of rkInt: x.intVal = y.intVal
  138. of rkFloat: x.floatVal = y.floatVal
  139. of rkNode: x.node = y.node
  140. of rkRegisterAddr: x.regAddr = y.regAddr
  141. of rkNodeAddr: x.nodeAddr = y.nodeAddr
  142. # this seems to be the best way to model the reference semantics
  143. # of system.NimNode:
  144. template asgnRef(x, y: untyped) = moveConst(x, y)
  145. proc copyValue(src: PNode): PNode =
  146. if src == nil or nfIsRef in src.flags:
  147. return src
  148. result = newNode(src.kind)
  149. result.info = src.info
  150. result.typ = src.typ
  151. result.flags = src.flags * PersistentNodeFlags
  152. result.comment = src.comment
  153. when defined(useNodeIds):
  154. if result.id == nodeIdToDebug:
  155. echo "COMES FROM ", src.id
  156. case src.kind
  157. of nkCharLit..nkUInt64Lit: result.intVal = src.intVal
  158. of nkFloatLit..nkFloat128Lit: result.floatVal = src.floatVal
  159. of nkSym: result.sym = src.sym
  160. of nkIdent: result.ident = src.ident
  161. of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
  162. else:
  163. newSeq(result.sons, sonsLen(src))
  164. for i in countup(0, sonsLen(src) - 1):
  165. result.sons[i] = copyValue(src.sons[i])
  166. proc asgnComplex(x: var TFullReg, y: TFullReg) =
  167. if x.kind != y.kind:
  168. myreset(x)
  169. x.kind = y.kind
  170. case x.kind
  171. of rkNone: discard
  172. of rkInt: x.intVal = y.intVal
  173. of rkFloat: x.floatVal = y.floatVal
  174. of rkNode: x.node = copyValue(y.node)
  175. of rkRegisterAddr: x.regAddr = y.regAddr
  176. of rkNodeAddr: x.nodeAddr = y.nodeAddr
  177. proc putIntoNode(n: var PNode; x: TFullReg) =
  178. case x.kind
  179. of rkNone: discard
  180. of rkInt: n.intVal = x.intVal
  181. of rkFloat: n.floatVal = x.floatVal
  182. of rkNode:
  183. if nfIsRef in x.node.flags: n = x.node
  184. else: n[] = x.node[]
  185. of rkRegisterAddr: putIntoNode(n, x.regAddr[])
  186. of rkNodeAddr: n[] = x.nodeAddr[][]
  187. proc putIntoReg(dest: var TFullReg; n: PNode) =
  188. case n.kind
  189. of nkStrLit..nkTripleStrLit:
  190. dest.kind = rkNode
  191. createStr(dest)
  192. dest.node.strVal = n.strVal
  193. of nkCharLit..nkUInt64Lit:
  194. dest.kind = rkInt
  195. dest.intVal = n.intVal
  196. of nkFloatLit..nkFloat128Lit:
  197. dest.kind = rkFloat
  198. dest.floatVal = n.floatVal
  199. else:
  200. dest.kind = rkNode
  201. dest.node = n
  202. proc regToNode(x: TFullReg): PNode =
  203. case x.kind
  204. of rkNone: result = newNode(nkEmpty)
  205. of rkInt: result = newNode(nkIntLit); result.intVal = x.intVal
  206. of rkFloat: result = newNode(nkFloatLit); result.floatVal = x.floatVal
  207. of rkNode: result = x.node
  208. of rkRegisterAddr: result = regToNode(x.regAddr[])
  209. of rkNodeAddr: result = x.nodeAddr[]
  210. template getstr(a: untyped): untyped =
  211. (if a.kind == rkNode: a.node.strVal else: $chr(int(a.intVal)))
  212. proc pushSafePoint(f: PStackFrame; pc: int) =
  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.isNil or 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(exceptType, raisedType) <= 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. if f.safePoints.isNil: return -1
  264. for s in f.safePoints:
  265. var pc = s
  266. while c.code[pc].opcode == opcExcept:
  267. pc = pc + c.code[pc].regBx - wordExcess
  268. if c.code[pc].opcode == opcFinally:
  269. return pc
  270. return -1
  271. proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
  272. if desttyp.kind == tyString:
  273. if dest.kind != rkNode:
  274. myreset(dest)
  275. dest.kind = rkNode
  276. dest.node = newNode(nkStrLit)
  277. let styp = srctyp.skipTypes(abstractRange)
  278. case styp.kind
  279. of tyEnum:
  280. let n = styp.n
  281. let x = src.intVal.int
  282. if x <% n.len and (let f = n.sons[x].sym; f.position == x):
  283. dest.node.strVal = if f.ast.isNil: f.name.s else: f.ast.strVal
  284. else:
  285. for i in 0.. <n.len:
  286. if n.sons[i].kind != nkSym: internalError("opConv for enum")
  287. let f = n.sons[i].sym
  288. if f.position == x:
  289. dest.node.strVal = if f.ast.isNil: f.name.s else: f.ast.strVal
  290. return
  291. dest.node.strVal = styp.sym.name.s & " " & $x
  292. of tyInt..tyInt64:
  293. dest.node.strVal = $src.intVal
  294. of tyUInt..tyUInt64:
  295. dest.node.strVal = $uint64(src.intVal)
  296. of tyBool:
  297. dest.node.strVal = if src.intVal == 0: "false" else: "true"
  298. of tyFloat..tyFloat128:
  299. dest.node.strVal = $src.floatVal
  300. of tyString:
  301. dest.node.strVal = src.node.strVal
  302. of tyCString:
  303. if src.node.kind == nkBracket:
  304. # Array of chars
  305. var strVal = ""
  306. for son in src.node.sons:
  307. let c = char(son.intVal)
  308. if c == '\0': break
  309. strVal.add(c)
  310. dest.node.strVal = strVal
  311. else:
  312. dest.node.strVal = src.node.strVal
  313. of tyChar:
  314. dest.node.strVal = $chr(src.intVal)
  315. else:
  316. internalError("cannot convert to string " & desttyp.typeToString)
  317. else:
  318. case skipTypes(desttyp, abstractRange).kind
  319. of tyInt..tyInt64:
  320. if dest.kind != rkInt:
  321. myreset(dest); dest.kind = rkInt
  322. case skipTypes(srctyp, abstractRange).kind
  323. of tyFloat..tyFloat64:
  324. dest.intVal = int(src.floatVal)
  325. else:
  326. dest.intVal = src.intVal
  327. if dest.intVal < firstOrd(desttyp) or dest.intVal > lastOrd(desttyp):
  328. return true
  329. of tyUInt..tyUInt64:
  330. if dest.kind != rkInt:
  331. myreset(dest); dest.kind = rkInt
  332. case skipTypes(srctyp, abstractRange).kind
  333. of tyFloat..tyFloat64:
  334. dest.intVal = int(src.floatVal)
  335. else:
  336. let srcDist = (sizeof(src.intVal) - srctyp.size) * 8
  337. let destDist = (sizeof(dest.intVal) - desttyp.size) * 8
  338. when system.cpuEndian == bigEndian:
  339. dest.intVal = (src.intVal shr srcDist) shl srcDist
  340. dest.intVal = (dest.intVal shr destDist) shl destDist
  341. else:
  342. dest.intVal = (src.intVal shl srcDist) shr srcDist
  343. dest.intVal = (dest.intVal shl destDist) shr destDist
  344. of tyFloat..tyFloat64:
  345. if dest.kind != rkFloat:
  346. myreset(dest); dest.kind = rkFloat
  347. case skipTypes(srctyp, abstractRange).kind
  348. of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyBool, tyChar:
  349. dest.floatVal = toBiggestFloat(src.intVal)
  350. else:
  351. dest.floatVal = src.floatVal
  352. else:
  353. asgnComplex(dest, src)
  354. proc compile(c: PCtx, s: PSym): int =
  355. result = vmgen.genProc(c, s)
  356. when debugEchoCode: c.echoCode result
  357. #c.echoCode
  358. template handleJmpBack() {.dirty.} =
  359. if c.loopIterations <= 0:
  360. if allowInfiniteLoops in c.features:
  361. c.loopIterations = MaxLoopIterations
  362. else:
  363. msgWriteln("stack trace: (most recent call last)")
  364. stackTraceAux(c, tos, pc)
  365. globalError(c.debug[pc], errTooManyIterations)
  366. dec(c.loopIterations)
  367. proc recSetFlagIsRef(arg: PNode) =
  368. arg.flags.incl(nfIsRef)
  369. for i in 0 ..< arg.safeLen:
  370. arg.sons[i].recSetFlagIsRef
  371. proc setLenSeq(c: PCtx; node: PNode; newLen: int; info: TLineInfo) =
  372. # FIXME: this doesn't attempt to solve incomplete
  373. # support of tyPtr, tyRef in VM.
  374. let typ = node.typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc})
  375. let typeEntry = typ.sons[0].skipTypes(abstractInst+{tyRange}-{tyTypeDesc})
  376. let typeKind = case typeEntry.kind
  377. of tyUInt..tyUInt64: nkUIntLit
  378. of tyRange, tyEnum, tyBool, tyChar, tyInt..tyInt64: nkIntLit
  379. of tyFloat..tyFloat128: nkFloatLit
  380. of tyString: nkStrLit
  381. of tyObject: nkObjConstr
  382. of tySequence: nkNilLit
  383. of tyProc, tyTuple: nkPar
  384. else: nkEmpty
  385. let oldLen = node.len
  386. setLen(node.sons, newLen)
  387. if oldLen < newLen:
  388. # TODO: This is still not correct for tyPtr, tyRef default value
  389. for i in oldLen .. <newLen:
  390. node.sons[i] = newNodeI(typeKind, info)
  391. proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
  392. var pc = start
  393. var tos = tos
  394. var regs: seq[TFullReg] # alias to tos.slots for performance
  395. move(regs, tos.slots)
  396. #echo "NEW RUN ------------------------"
  397. while true:
  398. #{.computedGoto.}
  399. let instr = c.code[pc]
  400. let ra = instr.regA
  401. #if c.traceActive:
  402. when traceCode:
  403. echo "PC ", pc, " ", c.code[pc].opcode, " ra ", ra, " rb ", instr.regB, " rc ", instr.regC
  404. # message(c.debug[pc], warnUser, "Trace")
  405. case instr.opcode
  406. of opcEof: return regs[ra]
  407. of opcRet:
  408. # XXX perform any cleanup actions
  409. pc = tos.comesFrom
  410. tos = tos.next
  411. let retVal = regs[0]
  412. if tos.isNil:
  413. #echo "RET ", retVal.rendertree
  414. return retVal
  415. move(regs, tos.slots)
  416. assert c.code[pc].opcode in {opcIndCall, opcIndCallAsgn}
  417. if c.code[pc].opcode == opcIndCallAsgn:
  418. regs[c.code[pc].regA] = retVal
  419. #echo "RET2 ", retVal.rendertree, " ", c.code[pc].regA
  420. of opcYldYoid: assert false
  421. of opcYldVal: assert false
  422. of opcAsgnInt:
  423. decodeB(rkInt)
  424. regs[ra].intVal = regs[rb].intVal
  425. of opcAsgnStr:
  426. decodeBC(rkNode)
  427. createStrKeepNode regs[ra], rc != 0
  428. regs[ra].node.strVal = regs[rb].node.strVal
  429. of opcAsgnFloat:
  430. decodeB(rkFloat)
  431. regs[ra].floatVal = regs[rb].floatVal
  432. of opcAsgnComplex:
  433. asgnComplex(regs[ra], regs[instr.regB])
  434. of opcAsgnRef:
  435. asgnRef(regs[ra], regs[instr.regB])
  436. of opcRegToNode:
  437. decodeB(rkNode)
  438. putIntoNode(regs[ra].node, regs[rb])
  439. of opcNodeToReg:
  440. let ra = instr.regA
  441. let rb = instr.regB
  442. # opcDeref might already have loaded it into a register. XXX Let's hope
  443. # this is still correct this way:
  444. if regs[rb].kind != rkNode:
  445. regs[ra] = regs[rb]
  446. else:
  447. assert regs[rb].kind == rkNode
  448. let nb = regs[rb].node
  449. case nb.kind
  450. of nkCharLit..nkUInt64Lit:
  451. ensureKind(rkInt)
  452. regs[ra].intVal = nb.intVal
  453. of nkFloatLit..nkFloat64Lit:
  454. ensureKind(rkFloat)
  455. regs[ra].floatVal = nb.floatVal
  456. else:
  457. ensureKind(rkNode)
  458. regs[ra].node = nb
  459. of opcLdArr:
  460. # a = b[c]
  461. decodeBC(rkNode)
  462. if regs[rc].intVal > high(int):
  463. stackTrace(c, tos, pc, errIndexOutOfBounds)
  464. let idx = regs[rc].intVal.int
  465. let src = regs[rb].node
  466. if src.kind in {nkStrLit..nkTripleStrLit}:
  467. if idx <% src.strVal.len:
  468. regs[ra].node = newNodeI(nkCharLit, c.debug[pc])
  469. regs[ra].node.intVal = src.strVal[idx].ord
  470. else:
  471. stackTrace(c, tos, pc, errIndexOutOfBounds)
  472. elif src.kind notin {nkEmpty..nkFloat128Lit} and idx <% src.len:
  473. regs[ra].node = src.sons[idx]
  474. else:
  475. stackTrace(c, tos, pc, errIndexOutOfBounds)
  476. of opcLdStrIdx:
  477. decodeBC(rkInt)
  478. let idx = regs[rc].intVal.int
  479. let s = regs[rb].node.strVal
  480. if s.isNil:
  481. stackTrace(c, tos, pc, errNilAccess)
  482. elif idx <=% s.len:
  483. regs[ra].intVal = s[idx].ord
  484. else:
  485. stackTrace(c, tos, pc, errIndexOutOfBounds)
  486. of opcWrArr:
  487. # a[b] = c
  488. decodeBC(rkNode)
  489. let idx = regs[rb].intVal.int
  490. let arr = regs[ra].node
  491. if arr.kind in {nkStrLit..nkTripleStrLit}:
  492. if idx <% arr.strVal.len:
  493. arr.strVal[idx] = chr(regs[rc].intVal)
  494. else:
  495. stackTrace(c, tos, pc, errIndexOutOfBounds)
  496. elif idx <% arr.len:
  497. putIntoNode(arr.sons[idx], regs[rc])
  498. else:
  499. stackTrace(c, tos, pc, errIndexOutOfBounds)
  500. of opcLdObj:
  501. # a = b.c
  502. decodeBC(rkNode)
  503. let src = regs[rb].node
  504. if src.kind notin {nkEmpty..nkNilLit}:
  505. let n = src.sons[rc + ord(src.kind == nkObjConstr)].skipColon
  506. regs[ra].node = n
  507. else:
  508. stackTrace(c, tos, pc, errNilAccess)
  509. of opcWrObj:
  510. # a.b = c
  511. decodeBC(rkNode)
  512. let shiftedRb = rb + ord(regs[ra].node.kind == nkObjConstr)
  513. let dest = regs[ra].node
  514. if dest.kind == nkNilLit:
  515. stackTrace(c, tos, pc, errNilAccess)
  516. elif dest.sons[shiftedRb].kind == nkExprColonExpr:
  517. putIntoNode(dest.sons[shiftedRb].sons[1], regs[rc])
  518. else:
  519. putIntoNode(dest.sons[shiftedRb], regs[rc])
  520. of opcWrStrIdx:
  521. decodeBC(rkNode)
  522. let idx = regs[rb].intVal.int
  523. if idx <% regs[ra].node.strVal.len:
  524. regs[ra].node.strVal[idx] = chr(regs[rc].intVal)
  525. else:
  526. stackTrace(c, tos, pc, errIndexOutOfBounds)
  527. of opcAddrReg:
  528. decodeB(rkRegisterAddr)
  529. regs[ra].regAddr = addr(regs[rb])
  530. of opcAddrNode:
  531. decodeB(rkNodeAddr)
  532. if regs[rb].kind == rkNode:
  533. regs[ra].nodeAddr = addr(regs[rb].node)
  534. else:
  535. stackTrace(c, tos, pc, errGenerated, "limited VM support for 'addr'")
  536. of opcLdDeref:
  537. # a = b[]
  538. let ra = instr.regA
  539. let rb = instr.regB
  540. case regs[rb].kind
  541. of rkNodeAddr:
  542. ensureKind(rkNode)
  543. regs[ra].node = regs[rb].nodeAddr[]
  544. of rkRegisterAddr:
  545. ensureKind(regs[rb].regAddr.kind)
  546. regs[ra] = regs[rb].regAddr[]
  547. of rkNode:
  548. if regs[rb].node.kind == nkNilLit:
  549. stackTrace(c, tos, pc, errNilAccess)
  550. if regs[rb].node.kind == nkRefTy:
  551. regs[ra].node = regs[rb].node.sons[0]
  552. else:
  553. ensureKind(rkNode)
  554. regs[ra].node = regs[rb].node
  555. else:
  556. stackTrace(c, tos, pc, errNilAccess)
  557. of opcWrDeref:
  558. # a[] = c; b unused
  559. let ra = instr.regA
  560. let rc = instr.regC
  561. case regs[ra].kind
  562. of rkNodeAddr: putIntoNode(regs[ra].nodeAddr[], regs[rc])
  563. of rkRegisterAddr: regs[ra].regAddr[] = regs[rc]
  564. of rkNode: putIntoNode(regs[ra].node, regs[rc])
  565. else: stackTrace(c, tos, pc, errNilAccess)
  566. of opcAddInt:
  567. decodeBC(rkInt)
  568. let
  569. bVal = regs[rb].intVal
  570. cVal = regs[rc].intVal
  571. sum = bVal +% cVal
  572. if (sum xor bVal) >= 0 or (sum xor cVal) >= 0:
  573. regs[ra].intVal = sum
  574. else:
  575. stackTrace(c, tos, pc, errOverOrUnderflow)
  576. of opcAddImmInt:
  577. decodeBImm(rkInt)
  578. #message(c.debug[pc], warnUser, "came here")
  579. #debug regs[rb].node
  580. let
  581. bVal = regs[rb].intVal
  582. cVal = imm
  583. sum = bVal +% cVal
  584. if (sum xor bVal) >= 0 or (sum xor cVal) >= 0:
  585. regs[ra].intVal = sum
  586. else:
  587. stackTrace(c, tos, pc, errOverOrUnderflow)
  588. of opcSubInt:
  589. decodeBC(rkInt)
  590. let
  591. bVal = regs[rb].intVal
  592. cVal = regs[rc].intVal
  593. diff = bVal -% cVal
  594. if (diff xor bVal) >= 0 or (diff xor not cVal) >= 0:
  595. regs[ra].intVal = diff
  596. else:
  597. stackTrace(c, tos, pc, errOverOrUnderflow)
  598. of opcSubImmInt:
  599. decodeBImm(rkInt)
  600. let
  601. bVal = regs[rb].intVal
  602. cVal = imm
  603. diff = bVal -% cVal
  604. if (diff xor bVal) >= 0 or (diff xor not cVal) >= 0:
  605. regs[ra].intVal = diff
  606. else:
  607. stackTrace(c, tos, pc, errOverOrUnderflow)
  608. of opcLenSeq:
  609. decodeBImm(rkInt)
  610. #assert regs[rb].kind == nkBracket
  611. let high = (imm and 1) # discard flags
  612. if (imm and nimNodeFlag) != 0:
  613. # used by mNLen (NimNode.len)
  614. regs[ra].intVal = regs[rb].node.safeLen - high
  615. else:
  616. # safeArrLen also return string node len
  617. # used when string is passed as openArray in VM
  618. regs[ra].intVal = regs[rb].node.safeArrLen - high
  619. of opcLenStr:
  620. decodeBImm(rkInt)
  621. assert regs[rb].kind == rkNode
  622. regs[ra].intVal = regs[rb].node.strVal.len - imm
  623. of opcIncl:
  624. decodeB(rkNode)
  625. let b = regs[rb].regToNode
  626. if not inSet(regs[ra].node, b):
  627. addSon(regs[ra].node, copyTree(b))
  628. of opcInclRange:
  629. decodeBC(rkNode)
  630. var r = newNode(nkRange)
  631. r.add regs[rb].regToNode
  632. r.add regs[rc].regToNode
  633. addSon(regs[ra].node, r.copyTree)
  634. of opcExcl:
  635. decodeB(rkNode)
  636. var b = newNodeIT(nkCurly, regs[ra].node.info, regs[ra].node.typ)
  637. addSon(b, regs[rb].regToNode)
  638. var r = diffSets(regs[ra].node, b)
  639. discardSons(regs[ra].node)
  640. for i in countup(0, sonsLen(r) - 1): addSon(regs[ra].node, r.sons[i])
  641. of opcCard:
  642. decodeB(rkInt)
  643. regs[ra].intVal = nimsets.cardSet(regs[rb].node)
  644. of opcMulInt:
  645. decodeBC(rkInt)
  646. let
  647. bVal = regs[rb].intVal
  648. cVal = regs[rc].intVal
  649. product = bVal *% cVal
  650. floatProd = toBiggestFloat(bVal) * toBiggestFloat(cVal)
  651. resAsFloat = toBiggestFloat(product)
  652. if resAsFloat == floatProd:
  653. regs[ra].intVal = product
  654. elif 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
  655. regs[ra].intVal = product
  656. else:
  657. stackTrace(c, tos, pc, errOverOrUnderflow)
  658. of opcDivInt:
  659. decodeBC(rkInt)
  660. if regs[rc].intVal == 0: stackTrace(c, tos, pc, errConstantDivisionByZero)
  661. else: regs[ra].intVal = regs[rb].intVal div regs[rc].intVal
  662. of opcModInt:
  663. decodeBC(rkInt)
  664. if regs[rc].intVal == 0: stackTrace(c, tos, pc, errConstantDivisionByZero)
  665. else: regs[ra].intVal = regs[rb].intVal mod regs[rc].intVal
  666. of opcAddFloat:
  667. decodeBC(rkFloat)
  668. regs[ra].floatVal = regs[rb].floatVal + regs[rc].floatVal
  669. of opcSubFloat:
  670. decodeBC(rkFloat)
  671. regs[ra].floatVal = regs[rb].floatVal - regs[rc].floatVal
  672. of opcMulFloat:
  673. decodeBC(rkFloat)
  674. regs[ra].floatVal = regs[rb].floatVal * regs[rc].floatVal
  675. of opcDivFloat:
  676. decodeBC(rkFloat)
  677. regs[ra].floatVal = regs[rb].floatVal / regs[rc].floatVal
  678. of opcShrInt:
  679. decodeBC(rkInt)
  680. regs[ra].intVal = regs[rb].intVal shr regs[rc].intVal
  681. of opcShlInt:
  682. decodeBC(rkInt)
  683. regs[ra].intVal = regs[rb].intVal shl regs[rc].intVal
  684. of opcBitandInt:
  685. decodeBC(rkInt)
  686. regs[ra].intVal = regs[rb].intVal and regs[rc].intVal
  687. of opcBitorInt:
  688. decodeBC(rkInt)
  689. regs[ra].intVal = regs[rb].intVal or regs[rc].intVal
  690. of opcBitxorInt:
  691. decodeBC(rkInt)
  692. regs[ra].intVal = regs[rb].intVal xor regs[rc].intVal
  693. of opcAddu:
  694. decodeBC(rkInt)
  695. regs[ra].intVal = regs[rb].intVal +% regs[rc].intVal
  696. of opcSubu:
  697. decodeBC(rkInt)
  698. regs[ra].intVal = regs[rb].intVal -% regs[rc].intVal
  699. of opcMulu:
  700. decodeBC(rkInt)
  701. regs[ra].intVal = regs[rb].intVal *% regs[rc].intVal
  702. of opcDivu:
  703. decodeBC(rkInt)
  704. regs[ra].intVal = regs[rb].intVal /% regs[rc].intVal
  705. of opcModu:
  706. decodeBC(rkInt)
  707. regs[ra].intVal = regs[rb].intVal %% regs[rc].intVal
  708. of opcEqInt:
  709. decodeBC(rkInt)
  710. regs[ra].intVal = ord(regs[rb].intVal == regs[rc].intVal)
  711. of opcLeInt:
  712. decodeBC(rkInt)
  713. regs[ra].intVal = ord(regs[rb].intVal <= regs[rc].intVal)
  714. of opcLtInt:
  715. decodeBC(rkInt)
  716. regs[ra].intVal = ord(regs[rb].intVal < regs[rc].intVal)
  717. of opcEqFloat:
  718. decodeBC(rkInt)
  719. regs[ra].intVal = ord(regs[rb].floatVal == regs[rc].floatVal)
  720. of opcLeFloat:
  721. decodeBC(rkInt)
  722. regs[ra].intVal = ord(regs[rb].floatVal <= regs[rc].floatVal)
  723. of opcLtFloat:
  724. decodeBC(rkInt)
  725. regs[ra].intVal = ord(regs[rb].floatVal < regs[rc].floatVal)
  726. of opcLeu:
  727. decodeBC(rkInt)
  728. regs[ra].intVal = ord(regs[rb].intVal <=% regs[rc].intVal)
  729. of opcLtu:
  730. decodeBC(rkInt)
  731. regs[ra].intVal = ord(regs[rb].intVal <% regs[rc].intVal)
  732. of opcEqRef:
  733. decodeBC(rkInt)
  734. regs[ra].intVal = ord((regs[rb].node.kind == nkNilLit and
  735. regs[rc].node.kind == nkNilLit) or
  736. regs[rb].node == regs[rc].node)
  737. of opcEqNimrodNode:
  738. decodeBC(rkInt)
  739. regs[ra].intVal =
  740. ord(exprStructuralEquivalent(regs[rb].node, regs[rc].node,
  741. strictSymEquality=true))
  742. of opcSameNodeType:
  743. decodeBC(rkInt)
  744. regs[ra].intVal = ord(regs[rb].node.typ.sameTypeOrNil regs[rc].node.typ)
  745. of opcXor:
  746. decodeBC(rkInt)
  747. regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
  748. of opcNot:
  749. decodeB(rkInt)
  750. assert regs[rb].kind == rkInt
  751. regs[ra].intVal = 1 - regs[rb].intVal
  752. of opcUnaryMinusInt:
  753. decodeB(rkInt)
  754. assert regs[rb].kind == rkInt
  755. let val = regs[rb].intVal
  756. if val != int64.low:
  757. regs[ra].intVal = -val
  758. else:
  759. stackTrace(c, tos, pc, errOverOrUnderflow)
  760. of opcUnaryMinusFloat:
  761. decodeB(rkFloat)
  762. assert regs[rb].kind == rkFloat
  763. regs[ra].floatVal = -regs[rb].floatVal
  764. of opcBitnotInt:
  765. decodeB(rkInt)
  766. assert regs[rb].kind == rkInt
  767. regs[ra].intVal = not regs[rb].intVal
  768. of opcEqStr:
  769. decodeBC(rkInt)
  770. regs[ra].intVal = ord(regs[rb].node.strVal == regs[rc].node.strVal)
  771. of opcLeStr:
  772. decodeBC(rkInt)
  773. regs[ra].intVal = ord(regs[rb].node.strVal <= regs[rc].node.strVal)
  774. of opcLtStr:
  775. decodeBC(rkInt)
  776. regs[ra].intVal = ord(regs[rb].node.strVal < regs[rc].node.strVal)
  777. of opcLeSet:
  778. decodeBC(rkInt)
  779. regs[ra].intVal = ord(containsSets(regs[rb].node, regs[rc].node))
  780. of opcEqSet:
  781. decodeBC(rkInt)
  782. regs[ra].intVal = ord(equalSets(regs[rb].node, regs[rc].node))
  783. of opcLtSet:
  784. decodeBC(rkInt)
  785. let a = regs[rb].node
  786. let b = regs[rc].node
  787. regs[ra].intVal = ord(containsSets(a, b) and not equalSets(a, b))
  788. of opcMulSet:
  789. decodeBC(rkNode)
  790. createSet(regs[ra])
  791. move(regs[ra].node.sons,
  792. nimsets.intersectSets(regs[rb].node, regs[rc].node).sons)
  793. of opcPlusSet:
  794. decodeBC(rkNode)
  795. createSet(regs[ra])
  796. move(regs[ra].node.sons,
  797. nimsets.unionSets(regs[rb].node, regs[rc].node).sons)
  798. of opcMinusSet:
  799. decodeBC(rkNode)
  800. createSet(regs[ra])
  801. move(regs[ra].node.sons,
  802. nimsets.diffSets(regs[rb].node, regs[rc].node).sons)
  803. of opcSymdiffSet:
  804. decodeBC(rkNode)
  805. createSet(regs[ra])
  806. move(regs[ra].node.sons,
  807. nimsets.symdiffSets(regs[rb].node, regs[rc].node).sons)
  808. of opcConcatStr:
  809. decodeBC(rkNode)
  810. createStr regs[ra]
  811. regs[ra].node.strVal = getstr(regs[rb])
  812. for i in rb+1..rb+rc-1:
  813. regs[ra].node.strVal.add getstr(regs[i])
  814. of opcAddStrCh:
  815. decodeB(rkNode)
  816. #createStrKeepNode regs[ra]
  817. regs[ra].node.strVal.add(regs[rb].intVal.chr)
  818. of opcAddStrStr:
  819. decodeB(rkNode)
  820. #createStrKeepNode regs[ra]
  821. regs[ra].node.strVal.add(regs[rb].node.strVal)
  822. of opcAddSeqElem:
  823. decodeB(rkNode)
  824. if regs[ra].node.kind == nkBracket:
  825. regs[ra].node.add(copyValue(regs[rb].regToNode))
  826. else:
  827. stackTrace(c, tos, pc, errNilAccess)
  828. of opcGetImpl:
  829. decodeB(rkNode)
  830. let a = regs[rb].node
  831. if a.kind == nkSym:
  832. regs[ra].node = if a.sym.ast.isNil: newNode(nkNilLit)
  833. else: copyTree(a.sym.ast)
  834. else:
  835. stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
  836. of opcEcho:
  837. let rb = instr.regB
  838. if rb == 1:
  839. msgWriteln(regs[ra].node.strVal, {msgStdout})
  840. else:
  841. var outp = ""
  842. for i in ra..ra+rb-1:
  843. #if regs[i].kind != rkNode: debug regs[i]
  844. outp.add(regs[i].node.strVal)
  845. msgWriteln(outp, {msgStdout})
  846. of opcContainsSet:
  847. decodeBC(rkInt)
  848. regs[ra].intVal = ord(inSet(regs[rb].node, regs[rc].regToNode))
  849. of opcSubStr:
  850. decodeBC(rkNode)
  851. inc pc
  852. assert c.code[pc].opcode == opcSubStr
  853. let rd = c.code[pc].regA
  854. createStr regs[ra]
  855. regs[ra].node.strVal = substr(regs[rb].node.strVal,
  856. regs[rc].intVal.int, regs[rd].intVal.int)
  857. of opcParseFloat:
  858. decodeBC(rkInt)
  859. inc pc
  860. assert c.code[pc].opcode == opcParseFloat
  861. let rd = c.code[pc].regA
  862. var rcAddr = addr(regs[rc])
  863. if rcAddr.kind == rkRegisterAddr: rcAddr = rcAddr.regAddr
  864. elif regs[rc].kind != rkFloat:
  865. myreset(regs[rc])
  866. regs[rc].kind = rkFloat
  867. regs[ra].intVal = parseBiggestFloat(regs[rb].node.strVal,
  868. rcAddr.floatVal, regs[rd].intVal.int)
  869. of opcRangeChck:
  870. let rb = instr.regB
  871. let rc = instr.regC
  872. if not (leValueConv(regs[rb].regToNode, regs[ra].regToNode) and
  873. leValueConv(regs[ra].regToNode, regs[rc].regToNode)):
  874. stackTrace(c, tos, pc, errGenerated,
  875. msgKindToString(errIllegalConvFromXtoY) % [
  876. $regs[ra].regToNode, "[" & $regs[rb].regToNode & ".." & $regs[rc].regToNode & "]"])
  877. of opcIndCall, opcIndCallAsgn:
  878. # dest = call regStart, n; where regStart = fn, arg1, ...
  879. let rb = instr.regB
  880. let rc = instr.regC
  881. let bb = regs[rb].node
  882. let isClosure = bb.kind == nkPar
  883. let prc = if not isClosure: bb.sym else: bb.sons[0].sym
  884. if prc.offset < -1:
  885. # it's a callback:
  886. c.callbacks[-prc.offset-2].value(
  887. VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs),
  888. currentException: c.currentExceptionB,
  889. currentLineInfo: c.debug[pc]))
  890. elif sfImportc in prc.flags:
  891. if allowFFI notin c.features:
  892. globalError(c.debug[pc], errGenerated, "VM not allowed to do FFI")
  893. # we pass 'tos.slots' instead of 'regs' so that the compiler can keep
  894. # 'regs' in a register:
  895. when hasFFI:
  896. let prcValue = c.globals.sons[prc.position-1]
  897. if prcValue.kind == nkEmpty:
  898. globalError(c.debug[pc], errGenerated, "canot run " & prc.name.s)
  899. let newValue = callForeignFunction(prcValue, prc.typ, tos.slots,
  900. rb+1, rc-1, c.debug[pc])
  901. if newValue.kind != nkEmpty:
  902. assert instr.opcode == opcIndCallAsgn
  903. putIntoReg(regs[ra], newValue)
  904. else:
  905. globalError(c.debug[pc], errGenerated, "VM not built with FFI support")
  906. elif prc.kind != skTemplate:
  907. let newPc = compile(c, prc)
  908. # tricky: a recursion is also a jump back, so we use the same
  909. # logic as for loops:
  910. if newPc < pc: handleJmpBack()
  911. #echo "new pc ", newPc, " calling: ", prc.name.s
  912. var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos)
  913. newSeq(newFrame.slots, prc.offset+ord(isClosure))
  914. if not isEmptyType(prc.typ.sons[0]) or prc.kind == skMacro:
  915. putIntoReg(newFrame.slots[0], getNullValue(prc.typ.sons[0], prc.info))
  916. for i in 1 .. rc-1:
  917. newFrame.slots[i] = regs[rb+i]
  918. if isClosure:
  919. newFrame.slots[rc].kind = rkNode
  920. newFrame.slots[rc].node = regs[rb].node.sons[1]
  921. tos = newFrame
  922. move(regs, newFrame.slots)
  923. # -1 for the following 'inc pc'
  924. pc = newPc-1
  925. else:
  926. # for 'getAst' support we need to support template expansion here:
  927. let genSymOwner = if tos.next != nil and tos.next.prc != nil:
  928. tos.next.prc
  929. else:
  930. c.module
  931. var macroCall = newNodeI(nkCall, c.debug[pc])
  932. macroCall.add(newSymNode(prc))
  933. for i in 1 .. rc-1:
  934. let node = regs[rb+i].regToNode
  935. node.info = c.debug[pc]
  936. macroCall.add(node)
  937. var a = evalTemplate(macroCall, prc, genSymOwner)
  938. if a.kind == nkStmtList and a.len == 1: a = a[0]
  939. a.recSetFlagIsRef
  940. ensureKind(rkNode)
  941. regs[ra].node = a
  942. of opcTJmp:
  943. # jump Bx if A != 0
  944. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  945. if regs[ra].intVal != 0:
  946. inc pc, rbx
  947. of opcFJmp:
  948. # jump Bx if A == 0
  949. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  950. if regs[ra].intVal == 0:
  951. inc pc, rbx
  952. of opcJmp:
  953. # jump Bx
  954. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  955. inc pc, rbx
  956. of opcJmpBack:
  957. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  958. inc pc, rbx
  959. handleJmpBack()
  960. of opcBranch:
  961. # we know the next instruction is a 'fjmp':
  962. let branch = c.constants[instr.regBx-wordExcess]
  963. var cond = false
  964. for j in countup(0, sonsLen(branch) - 2):
  965. if overlap(regs[ra].regToNode, branch.sons[j]):
  966. cond = true
  967. break
  968. assert c.code[pc+1].opcode == opcFJmp
  969. inc pc
  970. # we skip this instruction so that the final 'inc(pc)' skips
  971. # the following jump
  972. if not cond:
  973. let instr2 = c.code[pc]
  974. let rbx = instr2.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  975. inc pc, rbx
  976. of opcTry:
  977. let rbx = instr.regBx - wordExcess
  978. tos.pushSafePoint(pc + rbx)
  979. assert c.code[pc+rbx].opcode in {opcExcept, opcFinally}
  980. of opcExcept:
  981. # just skip it; it's followed by a jump;
  982. # we'll execute in the 'raise' handler
  983. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  984. inc pc, rbx
  985. while c.code[pc+1].opcode == opcExcept:
  986. let rbx = c.code[pc+1].regBx - wordExcess - 1
  987. inc pc, rbx
  988. #assert c.code[pc+1].opcode in {opcExcept, opcFinally}
  989. if c.code[pc+1].opcode != opcFinally:
  990. # in an except handler there is no active safe point for the 'try':
  991. tos.popSafePoint()
  992. of opcFinally:
  993. # just skip it; it's followed by the code we need to execute anyway
  994. tos.popSafePoint()
  995. of opcFinallyEnd:
  996. if c.currentExceptionA != nil:
  997. # we are in a cleanup run:
  998. let (newPc, newTos) = cleanUpOnException(c, tos)
  999. if newPc-1 < 0:
  1000. bailOut(c, tos)
  1001. return
  1002. pc = newPc-1
  1003. if tos != newTos:
  1004. tos = newTos
  1005. move(regs, tos.slots)
  1006. of opcRaise:
  1007. let raised = regs[ra].node
  1008. c.currentExceptionA = raised
  1009. c.exceptionInstr = pc
  1010. let (newPc, newTos) = cleanUpOnException(c, tos)
  1011. # -1 because of the following 'inc'
  1012. if newPc-1 < 0:
  1013. bailOut(c, tos)
  1014. return
  1015. pc = newPc-1
  1016. if tos != newTos:
  1017. tos = newTos
  1018. move(regs, tos.slots)
  1019. of opcNew:
  1020. ensureKind(rkNode)
  1021. let typ = c.types[instr.regBx - wordExcess]
  1022. regs[ra].node = getNullValue(typ, c.debug[pc])
  1023. regs[ra].node.flags.incl nfIsRef
  1024. of opcNewSeq:
  1025. let typ = c.types[instr.regBx - wordExcess]
  1026. inc pc
  1027. ensureKind(rkNode)
  1028. let instr2 = c.code[pc]
  1029. let count = regs[instr2.regA].intVal.int
  1030. regs[ra].node = newNodeI(nkBracket, c.debug[pc])
  1031. regs[ra].node.typ = typ
  1032. newSeq(regs[ra].node.sons, count)
  1033. for i in 0 .. <count:
  1034. regs[ra].node.sons[i] = getNullValue(typ.sons[0], c.debug[pc])
  1035. of opcNewStr:
  1036. decodeB(rkNode)
  1037. regs[ra].node = newNodeI(nkStrLit, c.debug[pc])
  1038. regs[ra].node.strVal = newString(regs[rb].intVal.int)
  1039. of opcLdImmInt:
  1040. # dest = immediate value
  1041. decodeBx(rkInt)
  1042. regs[ra].intVal = rbx
  1043. of opcLdNull:
  1044. ensureKind(rkNode)
  1045. let typ = c.types[instr.regBx - wordExcess]
  1046. regs[ra].node = getNullValue(typ, c.debug[pc])
  1047. # opcLdNull really is the gist of the VM's problems: should it load
  1048. # a fresh null to regs[ra].node or to regs[ra].node[]? This really
  1049. # depends on whether regs[ra] represents the variable itself or wether
  1050. # it holds the indirection! Due to the way registers are re-used we cannot
  1051. # say for sure here! --> The codegen has to deal with it
  1052. # via 'genAsgnPatch'.
  1053. of opcLdNullReg:
  1054. let typ = c.types[instr.regBx - wordExcess]
  1055. if typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc}).kind in {
  1056. tyFloat..tyFloat128}:
  1057. ensureKind(rkFloat)
  1058. regs[ra].floatVal = 0.0
  1059. else:
  1060. ensureKind(rkInt)
  1061. regs[ra].intVal = 0
  1062. of opcLdConst:
  1063. let rb = instr.regBx - wordExcess
  1064. let cnst = c.constants.sons[rb]
  1065. if fitsRegister(cnst.typ):
  1066. myreset(regs[ra])
  1067. putIntoReg(regs[ra], cnst)
  1068. else:
  1069. ensureKind(rkNode)
  1070. regs[ra].node = cnst
  1071. of opcAsgnConst:
  1072. let rb = instr.regBx - wordExcess
  1073. let cnst = c.constants.sons[rb]
  1074. if fitsRegister(cnst.typ):
  1075. putIntoReg(regs[ra], cnst)
  1076. else:
  1077. ensureKind(rkNode)
  1078. regs[ra].node = cnst.copyTree
  1079. of opcLdGlobal:
  1080. let rb = instr.regBx - wordExcess - 1
  1081. ensureKind(rkNode)
  1082. regs[ra].node = c.globals.sons[rb]
  1083. of opcLdGlobalAddr:
  1084. let rb = instr.regBx - wordExcess - 1
  1085. ensureKind(rkNodeAddr)
  1086. regs[ra].nodeAddr = addr(c.globals.sons[rb])
  1087. of opcRepr:
  1088. decodeB(rkNode)
  1089. createStr regs[ra]
  1090. regs[ra].node.strVal = renderTree(regs[rb].regToNode, {renderNoComments, renderDocComments})
  1091. of opcQuit:
  1092. if c.mode in {emRepl, emStaticExpr, emStaticStmt}:
  1093. message(c.debug[pc], hintQuitCalled)
  1094. msgQuit(int8(getOrdValue(regs[ra].regToNode)))
  1095. else:
  1096. return TFullReg(kind: rkNone)
  1097. of opcSetLenStr:
  1098. decodeB(rkNode)
  1099. #createStrKeepNode regs[ra]
  1100. regs[ra].node.strVal.setLen(regs[rb].intVal.int)
  1101. of opcOf:
  1102. decodeBC(rkInt)
  1103. let typ = c.types[regs[rc].intVal.int]
  1104. regs[ra].intVal = ord(inheritanceDiff(regs[rb].node.typ, typ) >= 0)
  1105. of opcIs:
  1106. decodeBC(rkInt)
  1107. let t1 = regs[rb].node.typ.skipTypes({tyTypeDesc})
  1108. let t2 = c.types[regs[rc].intVal.int]
  1109. # XXX: This should use the standard isOpImpl
  1110. let match = if t2.kind == tyUserTypeClass: true
  1111. else: sameType(t1, t2)
  1112. regs[ra].intVal = ord(match)
  1113. of opcSetLenSeq:
  1114. decodeB(rkNode)
  1115. let newLen = regs[rb].intVal.int
  1116. if regs[ra].node.isNil: stackTrace(c, tos, pc, errNilAccess)
  1117. else: c.setLenSeq(regs[ra].node, newLen, c.debug[pc])
  1118. of opcReset:
  1119. internalError(c.debug[pc], "too implement")
  1120. of opcNarrowS:
  1121. decodeB(rkInt)
  1122. let min = -(1.BiggestInt shl (rb-1))
  1123. let max = (1.BiggestInt shl (rb-1))-1
  1124. if regs[ra].intVal < min or regs[ra].intVal > max:
  1125. stackTrace(c, tos, pc, errGenerated,
  1126. msgKindToString(errUnhandledExceptionX) % "value out of range")
  1127. of opcNarrowU:
  1128. decodeB(rkInt)
  1129. regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
  1130. of opcIsNil:
  1131. decodeB(rkInt)
  1132. let node = regs[rb].node
  1133. regs[ra].intVal = ord(node.kind == nkNilLit or
  1134. (node.kind in {nkStrLit..nkTripleStrLit} and node.strVal.isNil))
  1135. of opcNBindSym:
  1136. decodeBx(rkNode)
  1137. regs[ra].node = copyTree(c.constants.sons[rbx])
  1138. of opcNChild:
  1139. decodeBC(rkNode)
  1140. let idx = regs[rc].intVal.int
  1141. let src = regs[rb].node
  1142. if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len:
  1143. regs[ra].node = src.sons[idx]
  1144. else:
  1145. stackTrace(c, tos, pc, errIndexOutOfBounds)
  1146. of opcNSetChild:
  1147. decodeBC(rkNode)
  1148. let idx = regs[rb].intVal.int
  1149. var dest = regs[ra].node
  1150. if dest.kind notin {nkEmpty..nkNilLit} and idx <% dest.len:
  1151. dest.sons[idx] = regs[rc].node
  1152. else:
  1153. stackTrace(c, tos, pc, errIndexOutOfBounds)
  1154. of opcNAdd:
  1155. decodeBC(rkNode)
  1156. var u = regs[rb].node
  1157. if u.kind notin {nkEmpty..nkNilLit}:
  1158. u.add(regs[rc].node)
  1159. else:
  1160. stackTrace(c, tos, pc, errGenerated, "cannot add to node kind: " & $u.kind)
  1161. regs[ra].node = u
  1162. of opcNAddMultiple:
  1163. decodeBC(rkNode)
  1164. let x = regs[rc].node
  1165. var u = regs[rb].node
  1166. if u.kind notin {nkEmpty..nkNilLit}:
  1167. # XXX can be optimized:
  1168. for i in 0.. <x.len: u.add(x.sons[i])
  1169. else:
  1170. stackTrace(c, tos, pc, errGenerated, "cannot add to node kind: " & $u.kind)
  1171. regs[ra].node = u
  1172. of opcNKind:
  1173. decodeB(rkInt)
  1174. regs[ra].intVal = ord(regs[rb].node.kind)
  1175. c.comesFromHeuristic = regs[rb].node.info
  1176. of opcNIntVal:
  1177. decodeB(rkInt)
  1178. let a = regs[rb].node
  1179. case a.kind
  1180. of nkCharLit..nkUInt64Lit: regs[ra].intVal = a.intVal
  1181. else: stackTrace(c, tos, pc, errFieldXNotFound, "intVal")
  1182. of opcNFloatVal:
  1183. decodeB(rkFloat)
  1184. let a = regs[rb].node
  1185. case a.kind
  1186. of nkFloatLit..nkFloat64Lit: regs[ra].floatVal = a.floatVal
  1187. else: stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
  1188. of opcNSymbol:
  1189. decodeB(rkNode)
  1190. let a = regs[rb].node
  1191. if a.kind == nkSym:
  1192. regs[ra].node = copyNode(a)
  1193. else:
  1194. stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
  1195. of opcNIdent:
  1196. decodeB(rkNode)
  1197. let a = regs[rb].node
  1198. if a.kind == nkIdent:
  1199. regs[ra].node = copyNode(a)
  1200. else:
  1201. stackTrace(c, tos, pc, errFieldXNotFound, "ident")
  1202. of opcNGetType:
  1203. let rb = instr.regB
  1204. let rc = instr.regC
  1205. case rc:
  1206. of 0:
  1207. # getType opcode:
  1208. ensureKind(rkNode)
  1209. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1210. regs[ra].node = opMapTypeToAst(regs[rb].node.typ, c.debug[pc])
  1211. else:
  1212. stackTrace(c, tos, pc, errGenerated, "node has no type")
  1213. of 1:
  1214. # typeKind opcode:
  1215. ensureKind(rkInt)
  1216. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1217. regs[ra].intVal = ord(regs[rb].node.typ.kind)
  1218. #else:
  1219. # stackTrace(c, tos, pc, errGenerated, "node has no type")
  1220. of 2:
  1221. # getTypeInst opcode:
  1222. ensureKind(rkNode)
  1223. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1224. regs[ra].node = opMapTypeInstToAst(regs[rb].node.typ, c.debug[pc])
  1225. else:
  1226. stackTrace(c, tos, pc, errGenerated, "node has no type")
  1227. else:
  1228. # getTypeImpl opcode:
  1229. ensureKind(rkNode)
  1230. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1231. regs[ra].node = opMapTypeImplToAst(regs[rb].node.typ, c.debug[pc])
  1232. else:
  1233. stackTrace(c, tos, pc, errGenerated, "node has no type")
  1234. of opcNStrVal:
  1235. decodeB(rkNode)
  1236. createStr regs[ra]
  1237. let a = regs[rb].node
  1238. if a.kind in {nkStrLit..nkTripleStrLit}: regs[ra].node.strVal = a.strVal
  1239. elif a.kind == nkCommentStmt: regs[ra].node.strVal = a.comment
  1240. else: stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
  1241. of opcSlurp:
  1242. decodeB(rkNode)
  1243. createStr regs[ra]
  1244. regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc],
  1245. c.module)
  1246. of opcGorge:
  1247. decodeBC(rkNode)
  1248. inc pc
  1249. let rd = c.code[pc].regA
  1250. createStr regs[ra]
  1251. regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
  1252. regs[rc].node.strVal, regs[rd].node.strVal,
  1253. c.debug[pc])[0]
  1254. of opcNError:
  1255. decodeB(rkNode)
  1256. let a = regs[ra].node
  1257. let b = regs[rb].node
  1258. stackTrace(c, tos, pc, errUser, a.strVal, if b.kind == nkNilLit: nil else: b)
  1259. of opcNWarning:
  1260. message(c.debug[pc], warnUser, regs[ra].node.strVal)
  1261. of opcNHint:
  1262. message(c.debug[pc], hintUser, regs[ra].node.strVal)
  1263. of opcParseExprToAst:
  1264. decodeB(rkNode)
  1265. # c.debug[pc].line.int - countLines(regs[rb].strVal) ?
  1266. var error: string
  1267. let ast = parseString(regs[rb].node.strVal, c.cache, c.debug[pc].toFullPath,
  1268. c.debug[pc].line.int,
  1269. proc (info: TLineInfo; msg: TMsgKind; arg: string) =
  1270. if error.isNil and msg <= msgs.errMax:
  1271. error = formatMsg(info, msg, arg))
  1272. if not error.isNil:
  1273. c.errorFlag = error
  1274. elif sonsLen(ast) != 1:
  1275. c.errorFlag = formatMsg(c.debug[pc], errExprExpected, "multiple statements")
  1276. else:
  1277. regs[ra].node = ast.sons[0]
  1278. of opcParseStmtToAst:
  1279. decodeB(rkNode)
  1280. var error: string
  1281. let ast = parseString(regs[rb].node.strVal, c.cache, c.debug[pc].toFullPath,
  1282. c.debug[pc].line.int,
  1283. proc (info: TLineInfo; msg: TMsgKind; arg: string) =
  1284. if error.isNil and msg <= msgs.errMax:
  1285. error = formatMsg(info, msg, arg))
  1286. if not error.isNil:
  1287. c.errorFlag = error
  1288. else:
  1289. regs[ra].node = ast
  1290. of opcQueryErrorFlag:
  1291. createStr regs[ra]
  1292. regs[ra].node.strVal = c.errorFlag
  1293. c.errorFlag.setLen 0
  1294. of opcCallSite:
  1295. ensureKind(rkNode)
  1296. if c.callsite != nil: regs[ra].node = c.callsite
  1297. else: stackTrace(c, tos, pc, errFieldXNotFound, "callsite")
  1298. of opcNGetFile:
  1299. decodeB(rkNode)
  1300. let n = regs[rb].node
  1301. regs[ra].node = newStrNode(nkStrLit, n.info.toFilename)
  1302. regs[ra].node.info = n.info
  1303. regs[ra].node.typ = n.typ
  1304. of opcNGetLine:
  1305. decodeB(rkNode)
  1306. let n = regs[rb].node
  1307. regs[ra].node = newIntNode(nkIntLit, n.info.line)
  1308. regs[ra].node.info = n.info
  1309. regs[ra].node.typ = n.typ
  1310. of opcNGetColumn:
  1311. decodeB(rkNode)
  1312. let n = regs[rb].node
  1313. regs[ra].node = newIntNode(nkIntLit, n.info.col)
  1314. regs[ra].node.info = n.info
  1315. regs[ra].node.typ = n.typ
  1316. of opcEqIdent:
  1317. decodeBC(rkInt)
  1318. if regs[rb].node.kind == nkIdent and regs[rc].node.kind == nkIdent:
  1319. regs[ra].intVal = ord(regs[rb].node.ident.id == regs[rc].node.ident.id)
  1320. else:
  1321. regs[ra].intVal = 0
  1322. of opcStrToIdent:
  1323. decodeB(rkNode)
  1324. if regs[rb].node.kind notin {nkStrLit..nkTripleStrLit}:
  1325. stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
  1326. else:
  1327. regs[ra].node = newNodeI(nkIdent, c.debug[pc])
  1328. regs[ra].node.ident = getIdent(regs[rb].node.strVal)
  1329. of opcIdentToStr:
  1330. decodeB(rkNode)
  1331. let a = regs[rb].node
  1332. createStr regs[ra]
  1333. regs[ra].node.info = c.debug[pc]
  1334. if a.kind == nkSym:
  1335. regs[ra].node.strVal = a.sym.name.s
  1336. elif a.kind == nkIdent:
  1337. regs[ra].node.strVal = a.ident.s
  1338. else:
  1339. stackTrace(c, tos, pc, errFieldXNotFound, "ident")
  1340. of opcSetType:
  1341. if regs[ra].kind != rkNode:
  1342. internalError(c.debug[pc], "cannot set type")
  1343. regs[ra].node.typ = c.types[instr.regBx - wordExcess]
  1344. of opcConv:
  1345. let rb = instr.regB
  1346. inc pc
  1347. let desttyp = c.types[c.code[pc].regBx - wordExcess]
  1348. inc pc
  1349. let srctyp = c.types[c.code[pc].regBx - wordExcess]
  1350. if opConv(regs[ra], regs[rb], desttyp, srctyp):
  1351. stackTrace(c, tos, pc, errGenerated,
  1352. msgKindToString(errIllegalConvFromXtoY) % [
  1353. typeToString(srctyp), typeToString(desttyp)])
  1354. of opcCast:
  1355. let rb = instr.regB
  1356. inc pc
  1357. let desttyp = c.types[c.code[pc].regBx - wordExcess]
  1358. inc pc
  1359. let srctyp = c.types[c.code[pc].regBx - wordExcess]
  1360. when hasFFI:
  1361. let dest = fficast(regs[rb], desttyp)
  1362. asgnRef(regs[ra], dest)
  1363. else:
  1364. globalError(c.debug[pc], "cannot evaluate cast")
  1365. of opcNSetIntVal:
  1366. decodeB(rkNode)
  1367. var dest = regs[ra].node
  1368. if dest.kind in {nkCharLit..nkUInt64Lit} and
  1369. regs[rb].kind in {rkInt}:
  1370. dest.intVal = regs[rb].intVal
  1371. else:
  1372. stackTrace(c, tos, pc, errFieldXNotFound, "intVal")
  1373. of opcNSetFloatVal:
  1374. decodeB(rkNode)
  1375. var dest = regs[ra].node
  1376. if dest.kind in {nkFloatLit..nkFloat64Lit} and
  1377. regs[rb].kind in {rkFloat}:
  1378. dest.floatVal = regs[rb].floatVal
  1379. else:
  1380. stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
  1381. of opcNSetSymbol:
  1382. decodeB(rkNode)
  1383. var dest = regs[ra].node
  1384. if dest.kind == nkSym and regs[rb].node.kind == nkSym:
  1385. dest.sym = regs[rb].node.sym
  1386. else:
  1387. stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
  1388. of opcNSetIdent:
  1389. decodeB(rkNode)
  1390. var dest = regs[ra].node
  1391. if dest.kind == nkIdent and regs[rb].node.kind == nkIdent:
  1392. dest.ident = regs[rb].node.ident
  1393. else:
  1394. stackTrace(c, tos, pc, errFieldXNotFound, "ident")
  1395. of opcNSetType:
  1396. decodeB(rkNode)
  1397. let b = regs[rb].node
  1398. internalAssert b.kind == nkSym and b.sym.kind == skType
  1399. internalAssert regs[ra].node != nil
  1400. regs[ra].node.typ = b.sym.typ
  1401. of opcNSetStrVal:
  1402. decodeB(rkNode)
  1403. var dest = regs[ra].node
  1404. if dest.kind in {nkStrLit..nkTripleStrLit} and
  1405. regs[rb].kind in {rkNode}:
  1406. dest.strVal = regs[rb].node.strVal
  1407. elif dest.kind == nkCommentStmt and regs[rb].kind in {rkNode}:
  1408. dest.comment = regs[rb].node.strVal
  1409. else:
  1410. stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
  1411. of opcNNewNimNode:
  1412. decodeBC(rkNode)
  1413. var k = regs[rb].intVal
  1414. if k < 0 or k > ord(high(TNodeKind)):
  1415. internalError(c.debug[pc],
  1416. "request to create a NimNode of invalid kind")
  1417. let cc = regs[rc].node
  1418. regs[ra].node = newNodeI(TNodeKind(int(k)),
  1419. if cc.kind != nkNilLit:
  1420. cc.info
  1421. elif c.comesFromHeuristic.line > -1:
  1422. c.comesFromHeuristic
  1423. elif c.callsite != nil and c.callsite.safeLen > 1:
  1424. c.callsite[1].info
  1425. else:
  1426. c.debug[pc])
  1427. regs[ra].node.flags.incl nfIsRef
  1428. of opcNCopyNimNode:
  1429. decodeB(rkNode)
  1430. regs[ra].node = copyNode(regs[rb].node)
  1431. of opcNCopyNimTree:
  1432. decodeB(rkNode)
  1433. regs[ra].node = copyTree(regs[rb].node)
  1434. of opcNDel:
  1435. decodeBC(rkNode)
  1436. let bb = regs[rb].intVal.int
  1437. for i in countup(0, regs[rc].intVal.int-1):
  1438. delSon(regs[ra].node, bb)
  1439. of opcGenSym:
  1440. decodeBC(rkNode)
  1441. let k = regs[rb].intVal
  1442. let name = if regs[rc].node.strVal.len == 0: ":tmp"
  1443. else: regs[rc].node.strVal
  1444. if k < 0 or k > ord(high(TSymKind)):
  1445. internalError(c.debug[pc], "request to create symbol of invalid kind")
  1446. var sym = newSym(k.TSymKind, name.getIdent, c.module.owner, c.debug[pc])
  1447. incl(sym.flags, sfGenSym)
  1448. regs[ra].node = newSymNode(sym)
  1449. of opcTypeTrait:
  1450. # XXX only supports 'name' for now; we can use regC to encode the
  1451. # type trait operation
  1452. decodeB(rkNode)
  1453. var typ = regs[rb].node.typ
  1454. internalAssert typ != nil
  1455. while typ.kind == tyTypeDesc and typ.len > 0: typ = typ.sons[0]
  1456. createStr regs[ra]
  1457. regs[ra].node.strVal = typ.typeToString(preferExported)
  1458. of opcMarshalLoad:
  1459. let ra = instr.regA
  1460. let rb = instr.regB
  1461. inc pc
  1462. let typ = c.types[c.code[pc].regBx - wordExcess]
  1463. putIntoReg(regs[ra], loadAny(regs[rb].node.strVal, typ))
  1464. of opcMarshalStore:
  1465. decodeB(rkNode)
  1466. inc pc
  1467. let typ = c.types[c.code[pc].regBx - wordExcess]
  1468. createStrKeepNode(regs[ra])
  1469. if regs[ra].node.strVal.isNil: regs[ra].node.strVal = newStringOfCap(1000)
  1470. storeAny(regs[ra].node.strVal, typ, regs[rb].regToNode)
  1471. of opcToNarrowInt:
  1472. decodeBC(rkInt)
  1473. let mask = (1'i64 shl rc) - 1 # 0xFF
  1474. let signbit = 1'i64 shl (rc - 1) # 0x80
  1475. let toggle = mask - signbit # 0x7F
  1476. # algorithm: -((i8 and 0xFF) xor 0x7F) + 0x7F
  1477. # mask off higher bits.
  1478. # uses two's complement to sign-extend integer.
  1479. # reajust integer into desired range.
  1480. regs[ra].intVal = -((regs[rb].intVal and mask) xor toggle) + toggle
  1481. inc pc
  1482. proc execute(c: PCtx, start: int): PNode =
  1483. var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil)
  1484. newSeq(tos.slots, c.prc.maxSlots)
  1485. result = rawExecute(c, start, tos).regToNode
  1486. proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
  1487. if sym.kind in routineKinds:
  1488. if sym.typ.len-1 != args.len:
  1489. localError(sym.info,
  1490. "NimScript: expected $# arguments, but got $#" % [
  1491. $(sym.typ.len-1), $args.len])
  1492. else:
  1493. let start = genProc(c, sym)
  1494. var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
  1495. let maxSlots = sym.offset
  1496. newSeq(tos.slots, maxSlots)
  1497. # setup parameters:
  1498. if not isEmptyType(sym.typ.sons[0]) or sym.kind == skMacro:
  1499. putIntoReg(tos.slots[0], getNullValue(sym.typ.sons[0], sym.info))
  1500. # XXX We could perform some type checking here.
  1501. for i in 1.. <sym.typ.len:
  1502. putIntoReg(tos.slots[i], args[i-1])
  1503. result = rawExecute(c, start, tos).regToNode
  1504. else:
  1505. localError(sym.info,
  1506. "NimScript: attempt to call non-routine: " & sym.name.s)
  1507. proc evalStmt*(c: PCtx, n: PNode) =
  1508. let n = transformExpr(c.module, n)
  1509. let start = genStmt(c, n)
  1510. # execute new instructions; this redundant opcEof check saves us lots
  1511. # of allocations in 'execute':
  1512. if c.code[start].opcode != opcEof:
  1513. discard execute(c, start)
  1514. proc evalExpr*(c: PCtx, n: PNode): PNode =
  1515. let n = transformExpr(c.module, n)
  1516. let start = genExpr(c, n)
  1517. assert c.code[start].opcode != opcEof
  1518. result = execute(c, start)
  1519. proc getGlobalValue*(c: PCtx; s: PSym): PNode =
  1520. internalAssert s.kind in {skLet, skVar} and sfGlobal in s.flags
  1521. result = c.globals.sons[s.position-1]
  1522. include vmops
  1523. # for now we share the 'globals' environment. XXX Coming soon: An API for
  1524. # storing&loading the 'globals' environment to get what a component system
  1525. # requires.
  1526. var
  1527. globalCtx*: PCtx
  1528. proc setupGlobalCtx(module: PSym; cache: IdentCache) =
  1529. if globalCtx.isNil:
  1530. globalCtx = newCtx(module, cache)
  1531. registerAdditionalOps(globalCtx)
  1532. else:
  1533. refresh(globalCtx, module)
  1534. proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
  1535. #var c = newEvalContext(module, emRepl)
  1536. #c.features = {allowCast, allowFFI, allowInfiniteLoops}
  1537. #pushStackFrame(c, newStackFrame())
  1538. # XXX produce a new 'globals' environment here:
  1539. setupGlobalCtx(module, cache)
  1540. result = globalCtx
  1541. when hasFFI:
  1542. globalCtx.features = {allowFFI, allowCast}
  1543. var oldErrorCount: int
  1544. proc myProcess(c: PPassContext, n: PNode): PNode =
  1545. # don't eval errornous code:
  1546. if oldErrorCount == msgs.gErrorCounter:
  1547. evalStmt(PCtx(c), n)
  1548. result = emptyNode
  1549. else:
  1550. result = n
  1551. oldErrorCount = msgs.gErrorCounter
  1552. proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
  1553. myProcess(c, n)
  1554. const evalPass* = makePass(myOpen, nil, myProcess, myClose)
  1555. proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode,
  1556. mode: TEvalMode): PNode =
  1557. let n = transformExpr(module, n)
  1558. setupGlobalCtx(module, cache)
  1559. var c = globalCtx
  1560. let oldMode = c.mode
  1561. defer: c.mode = oldMode
  1562. c.mode = mode
  1563. let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
  1564. if c.code[start].opcode == opcEof: return emptyNode
  1565. assert c.code[start].opcode != opcEof
  1566. when debugEchoCode: c.echoCode start
  1567. var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil)
  1568. newSeq(tos.slots, c.prc.maxSlots)
  1569. #for i in 0 .. <c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty)
  1570. result = rawExecute(c, start, tos).regToNode
  1571. if result.info.line < 0: result.info = n.info
  1572. proc evalConstExpr*(module: PSym; cache: IdentCache, e: PNode): PNode =
  1573. result = evalConstExprAux(module, cache, nil, e, emConst)
  1574. proc evalStaticExpr*(module: PSym; cache: IdentCache, e: PNode, prc: PSym): PNode =
  1575. result = evalConstExprAux(module, cache, prc, e, emStaticExpr)
  1576. proc evalStaticStmt*(module: PSym; cache: IdentCache, e: PNode, prc: PSym) =
  1577. discard evalConstExprAux(module, cache, prc, e, emStaticStmt)
  1578. proc setupCompileTimeVar*(module: PSym; cache: IdentCache, n: PNode) =
  1579. discard evalConstExprAux(module, cache, nil, n, emStaticStmt)
  1580. proc setupMacroParam(x: PNode, typ: PType): TFullReg =
  1581. case typ.kind
  1582. of tyStatic:
  1583. putIntoReg(result, x)
  1584. of tyTypeDesc:
  1585. putIntoReg(result, x)
  1586. else:
  1587. result.kind = rkNode
  1588. var n = x
  1589. if n.kind in {nkHiddenSubConv, nkHiddenStdConv}: n = n.sons[1]
  1590. n = n.canonValue
  1591. n.flags.incl nfIsRef
  1592. n.typ = x.typ
  1593. result.node = n
  1594. iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
  1595. let gp = macroSym.ast[genericParamsPos]
  1596. for i in 0 .. <gp.len:
  1597. let genericParam = gp[i].sym
  1598. let posInCall = macroSym.typ.len + i
  1599. yield (genericParam, call[posInCall])
  1600. var evalMacroCounter: int
  1601. proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
  1602. sym: PSym): PNode =
  1603. # XXX globalError() is ugly here, but I don't know a better solution for now
  1604. inc(evalMacroCounter)
  1605. if evalMacroCounter > 100:
  1606. globalError(n.info, errTemplateInstantiationTooNested)
  1607. # immediate macros can bypass any type and arity checking so we check the
  1608. # arity here too:
  1609. if sym.typ.len > n.safeLen and sym.typ.len > 1:
  1610. globalError(n.info, "in call '$#' got $#, but expected $# argument(s)" % [
  1611. n.renderTree,
  1612. $ <n.safeLen, $ <sym.typ.len])
  1613. setupGlobalCtx(module, cache)
  1614. var c = globalCtx
  1615. c.comesFromHeuristic.line = -1
  1616. c.callsite = nOrig
  1617. let start = genProc(c, sym)
  1618. var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
  1619. let maxSlots = sym.offset
  1620. newSeq(tos.slots, maxSlots)
  1621. # setup arguments:
  1622. var L = n.safeLen
  1623. if L == 0: L = 1
  1624. # This is wrong for tests/reject/tind1.nim where the passed 'else' part
  1625. # doesn't end up in the parameter:
  1626. #InternalAssert tos.slots.len >= L
  1627. # return value:
  1628. tos.slots[0].kind = rkNode
  1629. tos.slots[0].node = newNodeI(nkEmpty, n.info)
  1630. # setup parameters:
  1631. for i in 1.. <sym.typ.len:
  1632. tos.slots[i] = setupMacroParam(n.sons[i], sym.typ.sons[i])
  1633. let gp = sym.ast[genericParamsPos]
  1634. for i in 0 .. <gp.len:
  1635. if sfImmediate notin sym.flags:
  1636. let idx = sym.typ.len + i
  1637. if idx < n.len:
  1638. tos.slots[idx] = setupMacroParam(n.sons[idx], gp[i].sym.typ)
  1639. else:
  1640. dec(evalMacroCounter)
  1641. c.callsite = nil
  1642. localError(n.info, "expected " & $gp.len &
  1643. " generic parameter(s)")
  1644. elif gp[i].sym.typ.kind in {tyStatic, tyTypeDesc}:
  1645. dec(evalMacroCounter)
  1646. c.callsite = nil
  1647. globalError(n.info, "static[T] or typedesc nor supported for .immediate macros")
  1648. # temporary storage:
  1649. #for i in L .. <maxSlots: tos.slots[i] = newNode(nkEmpty)
  1650. result = rawExecute(c, start, tos).regToNode
  1651. if result.info.line < 0: result.info = n.info
  1652. if cyclicTree(result): globalError(n.info, errCyclicTree)
  1653. dec(evalMacroCounter)
  1654. c.callsite = nil