vm.nim 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956
  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 opcAsgnComplex:
  429. asgnComplex(regs[ra], regs[instr.regB])
  430. of opcAsgnRef:
  431. asgnRef(regs[ra], regs[instr.regB])
  432. of opcNodeToReg:
  433. let ra = instr.regA
  434. let rb = instr.regB
  435. # opcDeref might already have loaded it into a register. XXX Let's hope
  436. # this is still correct this way:
  437. if regs[rb].kind != rkNode:
  438. regs[ra] = regs[rb]
  439. else:
  440. assert regs[rb].kind == rkNode
  441. let nb = regs[rb].node
  442. case nb.kind
  443. of nkCharLit..nkUInt64Lit:
  444. ensureKind(rkInt)
  445. regs[ra].intVal = nb.intVal
  446. of nkFloatLit..nkFloat64Lit:
  447. ensureKind(rkFloat)
  448. regs[ra].floatVal = nb.floatVal
  449. else:
  450. ensureKind(rkNode)
  451. regs[ra].node = nb
  452. of opcLdArr:
  453. # a = b[c]
  454. decodeBC(rkNode)
  455. if regs[rc].intVal > high(int):
  456. stackTrace(c, tos, pc, errIndexOutOfBounds)
  457. let idx = regs[rc].intVal.int
  458. let src = regs[rb].node
  459. if src.kind in {nkStrLit..nkTripleStrLit}:
  460. if idx <% src.strVal.len:
  461. regs[ra].node = newNodeI(nkCharLit, c.debug[pc])
  462. regs[ra].node.intVal = src.strVal[idx].ord
  463. else:
  464. stackTrace(c, tos, pc, errIndexOutOfBounds)
  465. elif src.kind notin {nkEmpty..nkFloat128Lit} and idx <% src.len:
  466. regs[ra].node = src.sons[idx]
  467. else:
  468. stackTrace(c, tos, pc, errIndexOutOfBounds)
  469. of opcLdStrIdx:
  470. decodeBC(rkInt)
  471. let idx = regs[rc].intVal.int
  472. let s = regs[rb].node.strVal
  473. if idx <% s.len:
  474. regs[ra].intVal = s[idx].ord
  475. elif idx == s.len and optLaxStrings in c.config.options:
  476. regs[ra].intVal = 0
  477. else:
  478. stackTrace(c, tos, pc, errIndexOutOfBounds)
  479. of opcWrArr:
  480. # a[b] = c
  481. decodeBC(rkNode)
  482. let idx = regs[rb].intVal.int
  483. let arr = regs[ra].node
  484. if arr.kind in {nkStrLit..nkTripleStrLit}:
  485. if idx <% arr.strVal.len:
  486. arr.strVal[idx] = chr(regs[rc].intVal)
  487. else:
  488. stackTrace(c, tos, pc, errIndexOutOfBounds)
  489. elif idx <% arr.len:
  490. writeField(arr.sons[idx], regs[rc])
  491. else:
  492. stackTrace(c, tos, pc, errIndexOutOfBounds)
  493. of opcLdObj:
  494. # a = b.c
  495. decodeBC(rkNode)
  496. let src = regs[rb].node
  497. case src.kind
  498. of nkEmpty..nkNilLit:
  499. stackTrace(c, tos, pc, errNilAccess)
  500. of nkObjConstr:
  501. let n = src.sons[rc + 1].skipColon
  502. regs[ra].node = n
  503. else:
  504. let n = src.sons[rc]
  505. regs[ra].node = n
  506. of opcWrObj:
  507. # a.b = c
  508. decodeBC(rkNode)
  509. let shiftedRb = rb + ord(regs[ra].node.kind == nkObjConstr)
  510. let dest = regs[ra].node
  511. if dest.kind == nkNilLit:
  512. stackTrace(c, tos, pc, errNilAccess)
  513. elif dest.sons[shiftedRb].kind == nkExprColonExpr:
  514. writeField(dest.sons[shiftedRb].sons[1], regs[rc])
  515. else:
  516. writeField(dest.sons[shiftedRb], regs[rc])
  517. of opcWrStrIdx:
  518. decodeBC(rkNode)
  519. let idx = regs[rb].intVal.int
  520. if idx <% regs[ra].node.strVal.len:
  521. regs[ra].node.strVal[idx] = chr(regs[rc].intVal)
  522. else:
  523. stackTrace(c, tos, pc, errIndexOutOfBounds)
  524. of opcAddrReg:
  525. decodeB(rkRegisterAddr)
  526. regs[ra].regAddr = addr(regs[rb])
  527. of opcAddrNode:
  528. decodeB(rkNodeAddr)
  529. if regs[rb].kind == rkNode:
  530. regs[ra].nodeAddr = addr(regs[rb].node)
  531. else:
  532. stackTrace(c, tos, pc, "limited VM support for 'addr'")
  533. of opcLdDeref:
  534. # a = b[]
  535. let ra = instr.regA
  536. let rb = instr.regB
  537. case regs[rb].kind
  538. of rkNodeAddr:
  539. ensureKind(rkNode)
  540. regs[ra].node = regs[rb].nodeAddr[]
  541. of rkRegisterAddr:
  542. ensureKind(regs[rb].regAddr.kind)
  543. regs[ra] = regs[rb].regAddr[]
  544. of rkNode:
  545. if regs[rb].node.kind == nkNilLit:
  546. stackTrace(c, tos, pc, errNilAccess)
  547. if regs[rb].node.kind == nkRefTy:
  548. regs[ra].node = regs[rb].node.sons[0]
  549. else:
  550. ensureKind(rkNode)
  551. regs[ra].node = regs[rb].node
  552. else:
  553. stackTrace(c, tos, pc, errNilAccess)
  554. of opcWrDeref:
  555. # a[] = c; b unused
  556. let ra = instr.regA
  557. let rc = instr.regC
  558. case regs[ra].kind
  559. of rkNodeAddr:
  560. let n = regs[rc].regToNode
  561. # `var object` parameters are sent as rkNodeAddr. When they are mutated
  562. # vmgen generates opcWrDeref, which means that we must dereference
  563. # twice.
  564. # TODO: This should likely be handled differently in vmgen.
  565. if (nfIsRef notin regs[ra].nodeAddr[].flags and
  566. nfIsRef notin n.flags):
  567. regs[ra].nodeAddr[][] = n[]
  568. else:
  569. regs[ra].nodeAddr[] = n
  570. of rkRegisterAddr: regs[ra].regAddr[] = regs[rc]
  571. of rkNode:
  572. if regs[ra].node.kind == nkNilLit:
  573. stackTrace(c, tos, pc, errNilAccess)
  574. assert nfIsRef in regs[ra].node.flags
  575. regs[ra].node[] = regs[rc].regToNode[]
  576. regs[ra].node.flags.incl nfIsRef
  577. else: stackTrace(c, tos, pc, errNilAccess)
  578. of opcAddInt:
  579. decodeBC(rkInt)
  580. let
  581. bVal = regs[rb].intVal
  582. cVal = regs[rc].intVal
  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 opcAddImmInt:
  589. decodeBImm(rkInt)
  590. #message(c.config, c.debug[pc], warnUser, "came here")
  591. #debug regs[rb].node
  592. let
  593. bVal = regs[rb].intVal
  594. cVal = imm
  595. sum = bVal +% cVal
  596. if (sum xor bVal) >= 0 or (sum xor cVal) >= 0:
  597. regs[ra].intVal = sum
  598. else:
  599. stackTrace(c, tos, pc, errOverOrUnderflow)
  600. of opcSubInt:
  601. decodeBC(rkInt)
  602. let
  603. bVal = regs[rb].intVal
  604. cVal = regs[rc].intVal
  605. diff = bVal -% cVal
  606. if (diff xor bVal) >= 0 or (diff xor not cVal) >= 0:
  607. regs[ra].intVal = diff
  608. else:
  609. stackTrace(c, tos, pc, errOverOrUnderflow)
  610. of opcSubImmInt:
  611. decodeBImm(rkInt)
  612. let
  613. bVal = regs[rb].intVal
  614. cVal = imm
  615. diff = bVal -% cVal
  616. if (diff xor bVal) >= 0 or (diff xor not cVal) >= 0:
  617. regs[ra].intVal = diff
  618. else:
  619. stackTrace(c, tos, pc, errOverOrUnderflow)
  620. of opcLenSeq:
  621. decodeBImm(rkInt)
  622. #assert regs[rb].kind == nkBracket
  623. let high = (imm and 1) # discard flags
  624. if (imm and nimNodeFlag) != 0:
  625. # used by mNLen (NimNode.len)
  626. regs[ra].intVal = regs[rb].node.safeLen - high
  627. else:
  628. # safeArrLen also return string node len
  629. # used when string is passed as openArray in VM
  630. regs[ra].intVal = regs[rb].node.safeArrLen - high
  631. of opcLenStr:
  632. decodeBImm(rkInt)
  633. assert regs[rb].kind == rkNode
  634. regs[ra].intVal = regs[rb].node.strVal.len - imm
  635. of opcIncl:
  636. decodeB(rkNode)
  637. let b = regs[rb].regToNode
  638. if not inSet(regs[ra].node, b):
  639. addSon(regs[ra].node, copyTree(b))
  640. of opcInclRange:
  641. decodeBC(rkNode)
  642. var r = newNode(nkRange)
  643. r.add regs[rb].regToNode
  644. r.add regs[rc].regToNode
  645. addSon(regs[ra].node, r.copyTree)
  646. of opcExcl:
  647. decodeB(rkNode)
  648. var b = newNodeIT(nkCurly, regs[ra].node.info, regs[ra].node.typ)
  649. addSon(b, regs[rb].regToNode)
  650. var r = diffSets(c.config, regs[ra].node, b)
  651. discardSons(regs[ra].node)
  652. for i in countup(0, sonsLen(r) - 1): addSon(regs[ra].node, r.sons[i])
  653. of opcCard:
  654. decodeB(rkInt)
  655. regs[ra].intVal = nimsets.cardSet(c.config, regs[rb].node)
  656. of opcMulInt:
  657. decodeBC(rkInt)
  658. let
  659. bVal = regs[rb].intVal
  660. cVal = regs[rc].intVal
  661. product = bVal *% cVal
  662. floatProd = toBiggestFloat(bVal) * toBiggestFloat(cVal)
  663. resAsFloat = toBiggestFloat(product)
  664. if resAsFloat == floatProd:
  665. regs[ra].intVal = product
  666. elif 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
  667. regs[ra].intVal = product
  668. else:
  669. stackTrace(c, tos, pc, errOverOrUnderflow)
  670. of opcDivInt:
  671. decodeBC(rkInt)
  672. if regs[rc].intVal == 0: stackTrace(c, tos, pc, errConstantDivisionByZero)
  673. else: regs[ra].intVal = regs[rb].intVal div regs[rc].intVal
  674. of opcModInt:
  675. decodeBC(rkInt)
  676. if regs[rc].intVal == 0: stackTrace(c, tos, pc, errConstantDivisionByZero)
  677. else: regs[ra].intVal = regs[rb].intVal mod regs[rc].intVal
  678. of opcAddFloat:
  679. decodeBC(rkFloat)
  680. regs[ra].floatVal = regs[rb].floatVal + regs[rc].floatVal
  681. of opcSubFloat:
  682. decodeBC(rkFloat)
  683. regs[ra].floatVal = regs[rb].floatVal - regs[rc].floatVal
  684. of opcMulFloat:
  685. decodeBC(rkFloat)
  686. regs[ra].floatVal = regs[rb].floatVal * regs[rc].floatVal
  687. of opcDivFloat:
  688. decodeBC(rkFloat)
  689. regs[ra].floatVal = regs[rb].floatVal / regs[rc].floatVal
  690. of opcShrInt:
  691. decodeBC(rkInt)
  692. regs[ra].intVal = regs[rb].intVal shr regs[rc].intVal
  693. of opcShlInt:
  694. decodeBC(rkInt)
  695. regs[ra].intVal = regs[rb].intVal shl regs[rc].intVal
  696. of opcAshrInt:
  697. decodeBC(rkInt)
  698. regs[ra].intVal = ashr(regs[rb].intVal, regs[rc].intVal)
  699. of opcBitandInt:
  700. decodeBC(rkInt)
  701. regs[ra].intVal = regs[rb].intVal and regs[rc].intVal
  702. of opcBitorInt:
  703. decodeBC(rkInt)
  704. regs[ra].intVal = regs[rb].intVal or regs[rc].intVal
  705. of opcBitxorInt:
  706. decodeBC(rkInt)
  707. regs[ra].intVal = regs[rb].intVal xor regs[rc].intVal
  708. of opcAddu:
  709. decodeBC(rkInt)
  710. regs[ra].intVal = regs[rb].intVal +% regs[rc].intVal
  711. of opcSubu:
  712. decodeBC(rkInt)
  713. regs[ra].intVal = regs[rb].intVal -% regs[rc].intVal
  714. of opcMulu:
  715. decodeBC(rkInt)
  716. regs[ra].intVal = regs[rb].intVal *% regs[rc].intVal
  717. of opcDivu:
  718. decodeBC(rkInt)
  719. regs[ra].intVal = regs[rb].intVal /% regs[rc].intVal
  720. of opcModu:
  721. decodeBC(rkInt)
  722. regs[ra].intVal = regs[rb].intVal %% regs[rc].intVal
  723. of opcEqInt:
  724. decodeBC(rkInt)
  725. regs[ra].intVal = ord(regs[rb].intVal == regs[rc].intVal)
  726. of opcLeInt:
  727. decodeBC(rkInt)
  728. regs[ra].intVal = ord(regs[rb].intVal <= regs[rc].intVal)
  729. of opcLtInt:
  730. decodeBC(rkInt)
  731. regs[ra].intVal = ord(regs[rb].intVal < regs[rc].intVal)
  732. of opcEqFloat:
  733. decodeBC(rkInt)
  734. regs[ra].intVal = ord(regs[rb].floatVal == regs[rc].floatVal)
  735. of opcLeFloat:
  736. decodeBC(rkInt)
  737. regs[ra].intVal = ord(regs[rb].floatVal <= regs[rc].floatVal)
  738. of opcLtFloat:
  739. decodeBC(rkInt)
  740. regs[ra].intVal = ord(regs[rb].floatVal < regs[rc].floatVal)
  741. of opcLeu:
  742. decodeBC(rkInt)
  743. regs[ra].intVal = ord(regs[rb].intVal <=% regs[rc].intVal)
  744. of opcLtu:
  745. decodeBC(rkInt)
  746. regs[ra].intVal = ord(regs[rb].intVal <% regs[rc].intVal)
  747. of opcEqRef:
  748. decodeBC(rkInt)
  749. if regs[rb].kind == rkNodeAddr:
  750. if regs[rc].kind == rkNodeAddr:
  751. regs[ra].intVal = ord(regs[rb].nodeAddr == regs[rc].nodeAddr)
  752. else:
  753. assert regs[rc].kind == rkNode
  754. # we know these cannot be equal
  755. regs[ra].intVal = ord(false)
  756. elif regs[rc].kind == rkNodeAddr:
  757. assert regs[rb].kind == rkNode
  758. # we know these cannot be equal
  759. regs[ra].intVal = ord(false)
  760. else:
  761. regs[ra].intVal = ord((regs[rb].node.kind == nkNilLit and
  762. regs[rc].node.kind == nkNilLit) or
  763. regs[rb].node == regs[rc].node)
  764. of opcEqNimNode:
  765. decodeBC(rkInt)
  766. regs[ra].intVal =
  767. ord(exprStructuralEquivalent(regs[rb].node, regs[rc].node,
  768. strictSymEquality=true))
  769. of opcSameNodeType:
  770. decodeBC(rkInt)
  771. regs[ra].intVal = ord(regs[rb].node.typ.sameTypeOrNil regs[rc].node.typ)
  772. of opcXor:
  773. decodeBC(rkInt)
  774. regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
  775. of opcNot:
  776. decodeB(rkInt)
  777. assert regs[rb].kind == rkInt
  778. regs[ra].intVal = 1 - regs[rb].intVal
  779. of opcUnaryMinusInt:
  780. decodeB(rkInt)
  781. assert regs[rb].kind == rkInt
  782. let val = regs[rb].intVal
  783. if val != int64.low:
  784. regs[ra].intVal = -val
  785. else:
  786. stackTrace(c, tos, pc, errOverOrUnderflow)
  787. of opcUnaryMinusFloat:
  788. decodeB(rkFloat)
  789. assert regs[rb].kind == rkFloat
  790. regs[ra].floatVal = -regs[rb].floatVal
  791. of opcBitnotInt:
  792. decodeB(rkInt)
  793. assert regs[rb].kind == rkInt
  794. regs[ra].intVal = not regs[rb].intVal
  795. of opcEqStr:
  796. decodeBC(rkInt)
  797. regs[ra].intVal = ord(regs[rb].node.strVal == regs[rc].node.strVal)
  798. of opcLeStr:
  799. decodeBC(rkInt)
  800. regs[ra].intVal = ord(regs[rb].node.strVal <= regs[rc].node.strVal)
  801. of opcLtStr:
  802. decodeBC(rkInt)
  803. regs[ra].intVal = ord(regs[rb].node.strVal < regs[rc].node.strVal)
  804. of opcLeSet:
  805. decodeBC(rkInt)
  806. regs[ra].intVal = ord(containsSets(c.config, regs[rb].node, regs[rc].node))
  807. of opcEqSet:
  808. decodeBC(rkInt)
  809. regs[ra].intVal = ord(equalSets(c.config, regs[rb].node, regs[rc].node))
  810. of opcLtSet:
  811. decodeBC(rkInt)
  812. let a = regs[rb].node
  813. let b = regs[rc].node
  814. regs[ra].intVal = ord(containsSets(c.config, a, b) and not equalSets(c.config, a, b))
  815. of opcMulSet:
  816. decodeBC(rkNode)
  817. createSet(regs[ra])
  818. move(regs[ra].node.sons,
  819. nimsets.intersectSets(c.config, regs[rb].node, regs[rc].node).sons)
  820. of opcPlusSet:
  821. decodeBC(rkNode)
  822. createSet(regs[ra])
  823. move(regs[ra].node.sons,
  824. nimsets.unionSets(c.config, regs[rb].node, regs[rc].node).sons)
  825. of opcMinusSet:
  826. decodeBC(rkNode)
  827. createSet(regs[ra])
  828. move(regs[ra].node.sons,
  829. nimsets.diffSets(c.config, regs[rb].node, regs[rc].node).sons)
  830. of opcSymdiffSet:
  831. decodeBC(rkNode)
  832. createSet(regs[ra])
  833. move(regs[ra].node.sons,
  834. nimsets.symdiffSets(c.config, regs[rb].node, regs[rc].node).sons)
  835. of opcConcatStr:
  836. decodeBC(rkNode)
  837. createStr regs[ra]
  838. regs[ra].node.strVal = getstr(regs[rb])
  839. for i in rb+1..rb+rc-1:
  840. regs[ra].node.strVal.add getstr(regs[i])
  841. of opcAddStrCh:
  842. decodeB(rkNode)
  843. #createStrKeepNode regs[ra]
  844. regs[ra].node.strVal.add(regs[rb].intVal.chr)
  845. of opcAddStrStr:
  846. decodeB(rkNode)
  847. #createStrKeepNode regs[ra]
  848. regs[ra].node.strVal.add(regs[rb].node.strVal)
  849. of opcAddSeqElem:
  850. decodeB(rkNode)
  851. if regs[ra].node.kind == nkBracket:
  852. regs[ra].node.add(copyValue(regs[rb].regToNode))
  853. else:
  854. stackTrace(c, tos, pc, errNilAccess)
  855. of opcGetImpl:
  856. decodeB(rkNode)
  857. var a = regs[rb].node
  858. if a.kind == nkVarTy: a = a[0]
  859. if a.kind == nkSym:
  860. regs[ra].node = if a.sym.ast.isNil: newNode(nkNilLit)
  861. else: copyTree(a.sym.ast)
  862. regs[ra].node.flags.incl nfIsRef
  863. else:
  864. stackTrace(c, tos, pc, "node is not a symbol")
  865. of opcSymOwner:
  866. decodeB(rkNode)
  867. let a = regs[rb].node
  868. if a.kind == nkSym:
  869. regs[ra].node = if a.sym.owner.isNil: newNode(nkNilLit)
  870. else: newSymNode(a.sym.skipGenericOwner)
  871. regs[ra].node.flags.incl nfIsRef
  872. else:
  873. stackTrace(c, tos, pc, "node is not a symbol")
  874. of opcEcho:
  875. let rb = instr.regB
  876. if rb == 1:
  877. msgWriteln(c.config, regs[ra].node.strVal, {msgStdout})
  878. else:
  879. var outp = ""
  880. for i in ra..ra+rb-1:
  881. #if regs[i].kind != rkNode: debug regs[i]
  882. outp.add(regs[i].node.strVal)
  883. msgWriteln(c.config, outp, {msgStdout})
  884. of opcContainsSet:
  885. decodeBC(rkInt)
  886. regs[ra].intVal = ord(inSet(regs[rb].node, regs[rc].regToNode))
  887. of opcSubStr:
  888. decodeBC(rkNode)
  889. inc pc
  890. assert c.code[pc].opcode == opcSubStr
  891. let rd = c.code[pc].regA
  892. createStr regs[ra]
  893. regs[ra].node.strVal = substr(regs[rb].node.strVal,
  894. regs[rc].intVal.int, regs[rd].intVal.int)
  895. of opcParseFloat:
  896. decodeBC(rkInt)
  897. inc pc
  898. assert c.code[pc].opcode == opcParseFloat
  899. let rd = c.code[pc].regA
  900. var rcAddr = addr(regs[rc])
  901. if rcAddr.kind == rkRegisterAddr: rcAddr = rcAddr.regAddr
  902. elif regs[rc].kind != rkFloat:
  903. myreset(regs[rc])
  904. regs[rc].kind = rkFloat
  905. regs[ra].intVal = parseBiggestFloat(regs[rb].node.strVal,
  906. rcAddr.floatVal, regs[rd].intVal.int)
  907. of opcRangeChck:
  908. let rb = instr.regB
  909. let rc = instr.regC
  910. if not (leValueConv(regs[rb].regToNode, regs[ra].regToNode) and
  911. leValueConv(regs[ra].regToNode, regs[rc].regToNode)):
  912. stackTrace(c, tos, pc,
  913. errIllegalConvFromXtoY % [
  914. $regs[ra].regToNode, "[" & $regs[rb].regToNode & ".." & $regs[rc].regToNode & "]"])
  915. of opcIndCall, opcIndCallAsgn:
  916. # dest = call regStart, n; where regStart = fn, arg1, ...
  917. let rb = instr.regB
  918. let rc = instr.regC
  919. let bb = regs[rb].node
  920. let isClosure = bb.kind == nkTupleConstr
  921. let prc = if not isClosure: bb.sym else: bb.sons[0].sym
  922. if prc.offset < -1:
  923. # it's a callback:
  924. c.callbacks[-prc.offset-2].value(
  925. VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs),
  926. currentException: c.currentExceptionB,
  927. currentLineInfo: c.debug[pc]))
  928. elif sfImportc in prc.flags:
  929. if allowFFI notin c.features:
  930. globalError(c.config, c.debug[pc], "VM not allowed to do FFI")
  931. # we pass 'tos.slots' instead of 'regs' so that the compiler can keep
  932. # 'regs' in a register:
  933. when hasFFI:
  934. let prcValue = c.globals.sons[prc.position-1]
  935. if prcValue.kind == nkEmpty:
  936. globalError(c.config, c.debug[pc], "cannot run " & prc.name.s)
  937. let newValue = callForeignFunction(prcValue, prc.typ, tos.slots,
  938. rb+1, rc-1, c.debug[pc])
  939. if newValue.kind != nkEmpty:
  940. assert instr.opcode == opcIndCallAsgn
  941. putIntoReg(regs[ra], newValue)
  942. else:
  943. globalError(c.config, c.debug[pc], "VM not built with FFI support")
  944. elif prc.kind != skTemplate:
  945. let newPc = compile(c, prc)
  946. # tricky: a recursion is also a jump back, so we use the same
  947. # logic as for loops:
  948. if newPc < pc: handleJmpBack()
  949. #echo "new pc ", newPc, " calling: ", prc.name.s
  950. var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos)
  951. newSeq(newFrame.slots, prc.offset+ord(isClosure))
  952. if not isEmptyType(prc.typ.sons[0]) or prc.kind == skMacro:
  953. putIntoReg(newFrame.slots[0], getNullValue(prc.typ.sons[0], prc.info, c.config))
  954. for i in 1 .. rc-1:
  955. newFrame.slots[i] = regs[rb+i]
  956. if isClosure:
  957. newFrame.slots[rc].kind = rkNode
  958. newFrame.slots[rc].node = regs[rb].node.sons[1]
  959. tos = newFrame
  960. move(regs, newFrame.slots)
  961. # -1 for the following 'inc pc'
  962. pc = newPc-1
  963. else:
  964. # for 'getAst' support we need to support template expansion here:
  965. let genSymOwner = if tos.next != nil and tos.next.prc != nil:
  966. tos.next.prc
  967. else:
  968. c.module
  969. var macroCall = newNodeI(nkCall, c.debug[pc])
  970. macroCall.add(newSymNode(prc))
  971. for i in 1 .. rc-1:
  972. let node = regs[rb+i].regToNode
  973. node.info = c.debug[pc]
  974. macroCall.add(node)
  975. var a = evalTemplate(macroCall, prc, genSymOwner, c.config)
  976. if a.kind == nkStmtList and a.len == 1: a = a[0]
  977. a.recSetFlagIsRef
  978. ensureKind(rkNode)
  979. regs[ra].node = a
  980. of opcTJmp:
  981. # jump Bx if A != 0
  982. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  983. if regs[ra].intVal != 0:
  984. inc pc, rbx
  985. of opcFJmp:
  986. # jump Bx if A == 0
  987. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  988. if regs[ra].intVal == 0:
  989. inc pc, rbx
  990. of opcJmp:
  991. # jump Bx
  992. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  993. inc pc, rbx
  994. of opcJmpBack:
  995. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  996. inc pc, rbx
  997. handleJmpBack()
  998. of opcBranch:
  999. # we know the next instruction is a 'fjmp':
  1000. let branch = c.constants[instr.regBx-wordExcess]
  1001. var cond = false
  1002. for j in countup(0, sonsLen(branch) - 2):
  1003. if overlap(regs[ra].regToNode, branch.sons[j]):
  1004. cond = true
  1005. break
  1006. assert c.code[pc+1].opcode == opcFJmp
  1007. inc pc
  1008. # we skip this instruction so that the final 'inc(pc)' skips
  1009. # the following jump
  1010. if not cond:
  1011. let instr2 = c.code[pc]
  1012. let rbx = instr2.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  1013. inc pc, rbx
  1014. of opcTry:
  1015. let rbx = instr.regBx - wordExcess
  1016. tos.pushSafePoint(pc + rbx)
  1017. assert c.code[pc+rbx].opcode in {opcExcept, opcFinally}
  1018. of opcExcept:
  1019. # just skip it; it's followed by a jump;
  1020. # we'll execute in the 'raise' handler
  1021. let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
  1022. inc pc, rbx
  1023. while c.code[pc+1].opcode == opcExcept:
  1024. let rbx = c.code[pc+1].regBx - wordExcess - 1
  1025. inc pc, rbx
  1026. #assert c.code[pc+1].opcode in {opcExcept, opcFinally}
  1027. if c.code[pc+1].opcode != opcFinally:
  1028. # in an except handler there is no active safe point for the 'try':
  1029. tos.popSafePoint()
  1030. of opcFinally:
  1031. # just skip it; it's followed by the code we need to execute anyway
  1032. tos.popSafePoint()
  1033. of opcFinallyEnd:
  1034. if c.currentExceptionA != nil:
  1035. # we are in a cleanup run:
  1036. let (newPc, newTos) = cleanUpOnException(c, tos)
  1037. if newPc-1 < 0:
  1038. bailOut(c, tos)
  1039. return
  1040. pc = newPc-1
  1041. if tos != newTos:
  1042. tos = newTos
  1043. move(regs, tos.slots)
  1044. of opcRaise:
  1045. let raised = regs[ra].node
  1046. c.currentExceptionA = raised
  1047. c.exceptionInstr = pc
  1048. let (newPc, newTos) = cleanUpOnException(c, tos)
  1049. # -1 because of the following 'inc'
  1050. if newPc-1 < 0:
  1051. bailOut(c, tos)
  1052. return
  1053. pc = newPc-1
  1054. if tos != newTos:
  1055. tos = newTos
  1056. move(regs, tos.slots)
  1057. of opcNew:
  1058. ensureKind(rkNode)
  1059. let typ = c.types[instr.regBx - wordExcess]
  1060. regs[ra].node = getNullValue(typ, c.debug[pc], c.config)
  1061. regs[ra].node.flags.incl nfIsRef
  1062. of opcNewSeq:
  1063. let typ = c.types[instr.regBx - wordExcess]
  1064. inc pc
  1065. ensureKind(rkNode)
  1066. let instr2 = c.code[pc]
  1067. let count = regs[instr2.regA].intVal.int
  1068. regs[ra].node = newNodeI(nkBracket, c.debug[pc])
  1069. regs[ra].node.typ = typ
  1070. newSeq(regs[ra].node.sons, count)
  1071. for i in 0 ..< count:
  1072. regs[ra].node.sons[i] = getNullValue(typ.sons[0], c.debug[pc], c.config)
  1073. of opcNewStr:
  1074. decodeB(rkNode)
  1075. regs[ra].node = newNodeI(nkStrLit, c.debug[pc])
  1076. regs[ra].node.strVal = newString(regs[rb].intVal.int)
  1077. of opcLdImmInt:
  1078. # dest = immediate value
  1079. decodeBx(rkInt)
  1080. regs[ra].intVal = rbx
  1081. of opcLdNull:
  1082. ensureKind(rkNode)
  1083. let typ = c.types[instr.regBx - wordExcess]
  1084. regs[ra].node = getNullValue(typ, c.debug[pc], c.config)
  1085. # opcLdNull really is the gist of the VM's problems: should it load
  1086. # a fresh null to regs[ra].node or to regs[ra].node[]? This really
  1087. # depends on whether regs[ra] represents the variable itself or wether
  1088. # it holds the indirection! Due to the way registers are re-used we cannot
  1089. # say for sure here! --> The codegen has to deal with it
  1090. # via 'genAsgnPatch'.
  1091. of opcLdNullReg:
  1092. let typ = c.types[instr.regBx - wordExcess]
  1093. if typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc}).kind in {
  1094. tyFloat..tyFloat128}:
  1095. ensureKind(rkFloat)
  1096. regs[ra].floatVal = 0.0
  1097. else:
  1098. ensureKind(rkInt)
  1099. regs[ra].intVal = 0
  1100. of opcLdConst:
  1101. let rb = instr.regBx - wordExcess
  1102. let cnst = c.constants.sons[rb]
  1103. if fitsRegister(cnst.typ):
  1104. myreset(regs[ra])
  1105. putIntoReg(regs[ra], cnst)
  1106. else:
  1107. ensureKind(rkNode)
  1108. regs[ra].node = cnst
  1109. of opcAsgnConst:
  1110. let rb = instr.regBx - wordExcess
  1111. let cnst = c.constants.sons[rb]
  1112. if fitsRegister(cnst.typ):
  1113. putIntoReg(regs[ra], cnst)
  1114. else:
  1115. ensureKind(rkNode)
  1116. regs[ra].node = cnst.copyTree
  1117. of opcLdGlobal:
  1118. let rb = instr.regBx - wordExcess - 1
  1119. ensureKind(rkNode)
  1120. regs[ra].node = c.globals.sons[rb]
  1121. of opcLdGlobalAddr:
  1122. let rb = instr.regBx - wordExcess - 1
  1123. ensureKind(rkNodeAddr)
  1124. regs[ra].nodeAddr = addr(c.globals.sons[rb])
  1125. of opcRepr:
  1126. decodeB(rkNode)
  1127. createStr regs[ra]
  1128. regs[ra].node.strVal = renderTree(regs[rb].regToNode, {renderNoComments, renderDocComments})
  1129. of opcQuit:
  1130. if c.mode in {emRepl, emStaticExpr, emStaticStmt}:
  1131. message(c.config, c.debug[pc], hintQuitCalled)
  1132. msgQuit(int8(getOrdValue(regs[ra].regToNode)))
  1133. else:
  1134. return TFullReg(kind: rkNone)
  1135. of opcSetLenStr:
  1136. decodeB(rkNode)
  1137. #createStrKeepNode regs[ra]
  1138. regs[ra].node.strVal.setLen(regs[rb].intVal.int)
  1139. of opcOf:
  1140. decodeBC(rkInt)
  1141. let typ = c.types[regs[rc].intVal.int]
  1142. regs[ra].intVal = ord(inheritanceDiff(regs[rb].node.typ, typ) <= 0)
  1143. of opcIs:
  1144. decodeBC(rkInt)
  1145. let t1 = regs[rb].node.typ.skipTypes({tyTypeDesc})
  1146. let t2 = c.types[regs[rc].intVal.int]
  1147. # XXX: This should use the standard isOpImpl
  1148. let match = if t2.kind == tyUserTypeClass: true
  1149. else: sameType(t1, t2)
  1150. regs[ra].intVal = ord(match)
  1151. of opcSetLenSeq:
  1152. decodeB(rkNode)
  1153. let newLen = regs[rb].intVal.int
  1154. if regs[ra].node.isNil: stackTrace(c, tos, pc, errNilAccess)
  1155. else: c.setLenSeq(regs[ra].node, newLen, c.debug[pc])
  1156. of opcNarrowS:
  1157. decodeB(rkInt)
  1158. let min = -(1.BiggestInt shl (rb-1))
  1159. let max = (1.BiggestInt shl (rb-1))-1
  1160. if regs[ra].intVal < min or regs[ra].intVal > max:
  1161. stackTrace(c, tos, pc, "unhandled exception: value out of range")
  1162. of opcNarrowU:
  1163. decodeB(rkInt)
  1164. regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
  1165. of opcSignExtend:
  1166. # like opcNarrowS, but no out of range possible
  1167. decodeB(rkInt)
  1168. let imm = 64 - rb
  1169. regs[ra].intVal = ashr(regs[ra].intVal shl imm, imm)
  1170. of opcIsNil:
  1171. decodeB(rkInt)
  1172. let node = regs[rb].node
  1173. regs[ra].intVal = ord(
  1174. # Note that `nfIsRef` + `nkNilLit` represents an allocated
  1175. # reference with the value `nil`, so `isNil` should be false!
  1176. (node.kind == nkNilLit and nfIsRef notin node.flags) or
  1177. (not node.typ.isNil and node.typ.kind == tyProc and
  1178. node.typ.callConv == ccClosure and node.sons[0].kind == nkNilLit and
  1179. node.sons[1].kind == nkNilLit))
  1180. of opcNBindSym:
  1181. # cannot use this simple check
  1182. # if dynamicBindSym notin c.config.features:
  1183. # bindSym with static input
  1184. decodeBx(rkNode)
  1185. regs[ra].node = copyTree(c.constants.sons[rbx])
  1186. regs[ra].node.flags.incl nfIsRef
  1187. of opcNDynBindSym:
  1188. # experimental bindSym
  1189. let
  1190. rb = instr.regB
  1191. rc = instr.regC
  1192. idx = int(regs[rb+rc-1].intVal)
  1193. callback = c.callbacks[idx].value
  1194. args = VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs),
  1195. currentException: c.currentExceptionB,
  1196. currentLineInfo: c.debug[pc])
  1197. callback(args)
  1198. regs[ra].node.flags.incl nfIsRef
  1199. of opcNChild:
  1200. decodeBC(rkNode)
  1201. let idx = regs[rc].intVal.int
  1202. let src = regs[rb].node
  1203. if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len:
  1204. regs[ra].node = src.sons[idx]
  1205. else:
  1206. stackTrace(c, tos, pc, errIndexOutOfBounds)
  1207. of opcNSetChild:
  1208. decodeBC(rkNode)
  1209. let idx = regs[rb].intVal.int
  1210. var dest = regs[ra].node
  1211. if dest.kind notin {nkEmpty..nkNilLit} and idx <% dest.len:
  1212. dest.sons[idx] = regs[rc].node
  1213. else:
  1214. stackTrace(c, tos, pc, errIndexOutOfBounds)
  1215. of opcNAdd:
  1216. decodeBC(rkNode)
  1217. var u = regs[rb].node
  1218. if u.kind notin {nkEmpty..nkNilLit}:
  1219. u.add(regs[rc].node)
  1220. else:
  1221. stackTrace(c, tos, pc, "cannot add to node kind: " & $u.kind)
  1222. regs[ra].node = u
  1223. of opcNAddMultiple:
  1224. decodeBC(rkNode)
  1225. let x = regs[rc].node
  1226. var u = regs[rb].node
  1227. if u.kind notin {nkEmpty..nkNilLit}:
  1228. # XXX can be optimized:
  1229. for i in 0..<x.len: u.add(x.sons[i])
  1230. else:
  1231. stackTrace(c, tos, pc, "cannot add to node kind: " & $u.kind)
  1232. regs[ra].node = u
  1233. of opcNKind:
  1234. decodeB(rkInt)
  1235. regs[ra].intVal = ord(regs[rb].node.kind)
  1236. c.comesFromHeuristic = regs[rb].node.info
  1237. of opcNSymKind:
  1238. decodeB(rkInt)
  1239. let a = regs[rb].node
  1240. if a.kind == nkSym:
  1241. regs[ra].intVal = ord(a.sym.kind)
  1242. else:
  1243. stackTrace(c, tos, pc, "node is not a symbol")
  1244. c.comesFromHeuristic = regs[rb].node.info
  1245. of opcNIntVal:
  1246. decodeB(rkInt)
  1247. let a = regs[rb].node
  1248. case a.kind
  1249. of nkCharLit..nkUInt64Lit: regs[ra].intVal = a.intVal
  1250. else: stackTrace(c, tos, pc, errFieldXNotFound & "intVal")
  1251. of opcNFloatVal:
  1252. decodeB(rkFloat)
  1253. let a = regs[rb].node
  1254. case a.kind
  1255. of nkFloatLit..nkFloat64Lit: regs[ra].floatVal = a.floatVal
  1256. else: stackTrace(c, tos, pc, errFieldXNotFound & "floatVal")
  1257. of opcNSymbol:
  1258. decodeB(rkNode)
  1259. let a = regs[rb].node
  1260. if a.kind == nkSym:
  1261. regs[ra].node = copyNode(a)
  1262. else:
  1263. stackTrace(c, tos, pc, errFieldXNotFound & "symbol")
  1264. of opcNIdent:
  1265. decodeB(rkNode)
  1266. let a = regs[rb].node
  1267. if a.kind == nkIdent:
  1268. regs[ra].node = copyNode(a)
  1269. else:
  1270. stackTrace(c, tos, pc, errFieldXNotFound & "ident")
  1271. of opcNGetType:
  1272. let rb = instr.regB
  1273. let rc = instr.regC
  1274. case rc:
  1275. of 0:
  1276. # getType opcode:
  1277. ensureKind(rkNode)
  1278. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1279. regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.typ, c.debug[pc])
  1280. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1281. regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
  1282. else:
  1283. stackTrace(c, tos, pc, "node has no type")
  1284. of 1:
  1285. # typeKind opcode:
  1286. ensureKind(rkInt)
  1287. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1288. regs[ra].intVal = ord(regs[rb].node.typ.kind)
  1289. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1290. regs[ra].intVal = ord(regs[rb].node.sym.typ.kind)
  1291. #else:
  1292. # stackTrace(c, tos, pc, "node has no type")
  1293. of 2:
  1294. # getTypeInst opcode:
  1295. ensureKind(rkNode)
  1296. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1297. regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.typ, c.debug[pc])
  1298. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1299. regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
  1300. else:
  1301. stackTrace(c, tos, pc, "node has no type")
  1302. else:
  1303. # getTypeImpl opcode:
  1304. ensureKind(rkNode)
  1305. if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
  1306. regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.typ, c.debug[pc])
  1307. elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
  1308. regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
  1309. else:
  1310. stackTrace(c, tos, pc, "node has no type")
  1311. of opcNStrVal:
  1312. decodeB(rkNode)
  1313. createStr regs[ra]
  1314. let a = regs[rb].node
  1315. case a.kind
  1316. of {nkStrLit..nkTripleStrLit}:
  1317. regs[ra].node.strVal = a.strVal
  1318. of nkCommentStmt:
  1319. regs[ra].node.strVal = a.comment
  1320. of nkIdent:
  1321. regs[ra].node.strVal = a.ident.s
  1322. of nkSym:
  1323. regs[ra].node.strVal = a.sym.name.s
  1324. else:
  1325. stackTrace(c, tos, pc, errFieldXNotFound & "strVal")
  1326. of opcSlurp:
  1327. decodeB(rkNode)
  1328. createStr regs[ra]
  1329. regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc],
  1330. c.module, c.config)
  1331. of opcGorge:
  1332. when defined(nimcore):
  1333. decodeBC(rkNode)
  1334. inc pc
  1335. let rd = c.code[pc].regA
  1336. createStr regs[ra]
  1337. regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
  1338. regs[rc].node.strVal, regs[rd].node.strVal,
  1339. c.debug[pc], c.config)[0]
  1340. else:
  1341. globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support")
  1342. of opcNError, opcNWarning, opcNHint:
  1343. decodeB(rkNode)
  1344. let a = regs[ra].node
  1345. let b = regs[rb].node
  1346. let info = if b.kind == nkNilLit: c.debug[pc] else: b.info
  1347. if instr.opcode == opcNError:
  1348. stackTrace(c, tos, pc, a.strVal, info)
  1349. elif instr.opcode == opcNWarning:
  1350. message(c.config, info, warnUser, a.strVal)
  1351. elif instr.opcode == opcNHint:
  1352. message(c.config, info, hintUser, a.strVal)
  1353. of opcParseExprToAst:
  1354. decodeB(rkNode)
  1355. # c.debug[pc].line.int - countLines(regs[rb].strVal) ?
  1356. var error: string
  1357. let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
  1358. toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int,
  1359. proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) =
  1360. if error.len == 0 and msg <= errMax:
  1361. error = formatMsg(conf, info, msg, arg))
  1362. if error.len > 0:
  1363. c.errorFlag = error
  1364. elif sonsLen(ast) != 1:
  1365. c.errorFlag = formatMsg(c.config, c.debug[pc], errGenerated,
  1366. "expected expression, but got multiple statements")
  1367. else:
  1368. regs[ra].node = ast.sons[0]
  1369. of opcParseStmtToAst:
  1370. decodeB(rkNode)
  1371. var error: string
  1372. let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
  1373. toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int,
  1374. proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) =
  1375. if error.len == 0 and msg <= errMax:
  1376. error = formatMsg(conf, info, msg, arg))
  1377. if error.len > 0:
  1378. c.errorFlag = error
  1379. else:
  1380. regs[ra].node = ast
  1381. of opcQueryErrorFlag:
  1382. createStr regs[ra]
  1383. regs[ra].node.strVal = c.errorFlag
  1384. c.errorFlag.setLen 0
  1385. of opcCallSite:
  1386. ensureKind(rkNode)
  1387. if c.callsite != nil: regs[ra].node = c.callsite
  1388. else: stackTrace(c, tos, pc, errFieldXNotFound & "callsite")
  1389. of opcNGetLineInfo:
  1390. decodeBImm(rkNode)
  1391. let n = regs[rb].node
  1392. case imm
  1393. of 0: # getFile
  1394. regs[ra].node = newStrNode(nkStrLit, toFullPath(c.config, n.info))
  1395. of 1: # getLine
  1396. regs[ra].node = newIntNode(nkIntLit, n.info.line.int)
  1397. of 2: # getColumn
  1398. regs[ra].node = newIntNode(nkIntLit, n.info.col)
  1399. else:
  1400. internalAssert c.config, false
  1401. regs[ra].node.info = n.info
  1402. regs[ra].node.typ = n.typ
  1403. of opcNSetLineInfo:
  1404. decodeB(rkNode)
  1405. regs[ra].node.info = regs[rb].node.info
  1406. of opcEqIdent:
  1407. decodeBC(rkInt)
  1408. # aliases for shorter and easier to understand code below
  1409. let aNode = regs[rb].node
  1410. let bNode = regs[rc].node
  1411. # these are cstring to prevent string copy, and cmpIgnoreStyle from
  1412. # takes cstring arguments
  1413. var aStrVal: cstring = nil
  1414. var bStrVal: cstring = nil
  1415. # extract strVal from argument ``a``
  1416. case aNode.kind
  1417. of {nkStrLit..nkTripleStrLit}:
  1418. aStrVal = aNode.strVal.cstring
  1419. of nkIdent:
  1420. aStrVal = aNode.ident.s.cstring
  1421. of nkSym:
  1422. aStrVal = aNode.sym.name.s.cstring
  1423. of nkOpenSymChoice, nkClosedSymChoice:
  1424. aStrVal = aNode[0].sym.name.s.cstring
  1425. else:
  1426. discard
  1427. # extract strVal from argument ``b``
  1428. case bNode.kind
  1429. of {nkStrLit..nkTripleStrLit}:
  1430. bStrVal = bNode.strVal.cstring
  1431. of nkIdent:
  1432. bStrVal = bNode.ident.s.cstring
  1433. of nkSym:
  1434. bStrVal = bNode.sym.name.s.cstring
  1435. of nkOpenSymChoice, nkClosedSymChoice:
  1436. bStrVal = bNode[0].sym.name.s.cstring
  1437. else:
  1438. discard
  1439. # set result
  1440. regs[ra].intVal =
  1441. if aStrVal != nil and bStrVal != nil:
  1442. ord(idents.cmpIgnoreStyle(aStrVal,bStrVal,high(int)) == 0)
  1443. else:
  1444. 0
  1445. of opcStrToIdent:
  1446. decodeB(rkNode)
  1447. if regs[rb].node.kind notin {nkStrLit..nkTripleStrLit}:
  1448. stackTrace(c, tos, pc, errFieldXNotFound & "strVal")
  1449. else:
  1450. regs[ra].node = newNodeI(nkIdent, c.debug[pc])
  1451. regs[ra].node.ident = getIdent(c.cache, regs[rb].node.strVal)
  1452. regs[ra].node.flags.incl nfIsRef
  1453. of opcSetType:
  1454. if regs[ra].kind != rkNode:
  1455. internalError(c.config, c.debug[pc], "cannot set type")
  1456. regs[ra].node.typ = c.types[instr.regBx - wordExcess]
  1457. of opcConv:
  1458. let rb = instr.regB
  1459. inc pc
  1460. let desttyp = c.types[c.code[pc].regBx - wordExcess]
  1461. inc pc
  1462. let srctyp = c.types[c.code[pc].regBx - wordExcess]
  1463. if opConv(c, regs[ra], regs[rb], desttyp, srctyp):
  1464. stackTrace(c, tos, pc,
  1465. errIllegalConvFromXtoY % [
  1466. typeToString(srctyp), typeToString(desttyp)])
  1467. of opcCast:
  1468. let rb = instr.regB
  1469. inc pc
  1470. let desttyp = c.types[c.code[pc].regBx - wordExcess]
  1471. inc pc
  1472. let srctyp = c.types[c.code[pc].regBx - wordExcess]
  1473. when hasFFI:
  1474. let dest = fficast(regs[rb], desttyp)
  1475. asgnRef(regs[ra], dest)
  1476. else:
  1477. globalError(c.config, c.debug[pc], "cannot evaluate cast")
  1478. of opcNSetIntVal:
  1479. decodeB(rkNode)
  1480. var dest = regs[ra].node
  1481. if dest.kind in {nkCharLit..nkUInt64Lit} and
  1482. regs[rb].kind in {rkInt}:
  1483. dest.intVal = regs[rb].intVal
  1484. else:
  1485. stackTrace(c, tos, pc, errFieldXNotFound & "intVal")
  1486. of opcNSetFloatVal:
  1487. decodeB(rkNode)
  1488. var dest = regs[ra].node
  1489. if dest.kind in {nkFloatLit..nkFloat64Lit} and
  1490. regs[rb].kind in {rkFloat}:
  1491. dest.floatVal = regs[rb].floatVal
  1492. else:
  1493. stackTrace(c, tos, pc, errFieldXNotFound & "floatVal")
  1494. of opcNSetSymbol:
  1495. decodeB(rkNode)
  1496. var dest = regs[ra].node
  1497. if dest.kind == nkSym and regs[rb].node.kind == nkSym:
  1498. dest.sym = regs[rb].node.sym
  1499. else:
  1500. stackTrace(c, tos, pc, errFieldXNotFound & "symbol")
  1501. of opcNSetIdent:
  1502. decodeB(rkNode)
  1503. var dest = regs[ra].node
  1504. if dest.kind == nkIdent and regs[rb].node.kind == nkIdent:
  1505. dest.ident = regs[rb].node.ident
  1506. else:
  1507. stackTrace(c, tos, pc, errFieldXNotFound & "ident")
  1508. of opcNSetType:
  1509. decodeB(rkNode)
  1510. let b = regs[rb].node
  1511. internalAssert c.config, b.kind == nkSym and b.sym.kind == skType
  1512. internalAssert c.config, regs[ra].node != nil
  1513. regs[ra].node.typ = b.sym.typ
  1514. of opcNSetStrVal:
  1515. decodeB(rkNode)
  1516. var dest = regs[ra].node
  1517. if dest.kind in {nkStrLit..nkTripleStrLit} and
  1518. regs[rb].kind in {rkNode}:
  1519. dest.strVal = regs[rb].node.strVal
  1520. elif dest.kind == nkCommentStmt and regs[rb].kind in {rkNode}:
  1521. dest.comment = regs[rb].node.strVal
  1522. else:
  1523. stackTrace(c, tos, pc, errFieldXNotFound & "strVal")
  1524. of opcNNewNimNode:
  1525. decodeBC(rkNode)
  1526. var k = regs[rb].intVal
  1527. if k < 0 or k > ord(high(TNodeKind)):
  1528. internalError(c.config, c.debug[pc],
  1529. "request to create a NimNode of invalid kind")
  1530. let cc = regs[rc].node
  1531. let x = newNodeI(TNodeKind(int(k)),
  1532. if cc.kind != nkNilLit:
  1533. cc.info
  1534. elif c.comesFromHeuristic.line != 0'u16:
  1535. c.comesFromHeuristic
  1536. elif c.callsite != nil and c.callsite.safeLen > 1:
  1537. c.callsite[1].info
  1538. else:
  1539. c.debug[pc])
  1540. x.flags.incl nfIsRef
  1541. # prevent crashes in the compiler resulting from wrong macros:
  1542. if x.kind == nkIdent: x.ident = c.cache.emptyIdent
  1543. regs[ra].node = x
  1544. of opcNCopyNimNode:
  1545. decodeB(rkNode)
  1546. regs[ra].node = copyNode(regs[rb].node)
  1547. of opcNCopyNimTree:
  1548. decodeB(rkNode)
  1549. regs[ra].node = copyTree(regs[rb].node)
  1550. of opcNDel:
  1551. decodeBC(rkNode)
  1552. let bb = regs[rb].intVal.int
  1553. for i in countup(0, regs[rc].intVal.int-1):
  1554. delSon(regs[ra].node, bb)
  1555. of opcGenSym:
  1556. decodeBC(rkNode)
  1557. let k = regs[rb].intVal
  1558. let name = if regs[rc].node.strVal.len == 0: ":tmp"
  1559. else: regs[rc].node.strVal
  1560. if k < 0 or k > ord(high(TSymKind)):
  1561. internalError(c.config, c.debug[pc], "request to create symbol of invalid kind")
  1562. var sym = newSym(k.TSymKind, getIdent(c.cache, name), c.module.owner, c.debug[pc])
  1563. incl(sym.flags, sfGenSym)
  1564. regs[ra].node = newSymNode(sym)
  1565. regs[ra].node.flags.incl nfIsRef
  1566. of opcNccValue:
  1567. decodeB(rkInt)
  1568. let destKey = regs[rb].node.strVal
  1569. regs[ra].intVal = getOrDefault(c.graph.cacheCounters, destKey)
  1570. of opcNccInc:
  1571. let g = c.graph
  1572. let destKey = regs[ra].node.strVal
  1573. let by = regs[instr.regB].intVal
  1574. let v = getOrDefault(g.cacheCounters, destKey)
  1575. g.cacheCounters[destKey] = v+by
  1576. recordInc(c, c.debug[pc], destKey, by)
  1577. of opcNcsAdd:
  1578. let g = c.graph
  1579. let destKey = regs[ra].node.strVal
  1580. let val = regs[instr.regB].node
  1581. if not contains(g.cacheSeqs, destKey):
  1582. g.cacheSeqs[destKey] = newTree(nkStmtList, val)
  1583. # newNodeI(nkStmtList, c.debug[pc])
  1584. else:
  1585. g.cacheSeqs[destKey].add val
  1586. recordAdd(c, c.debug[pc], destKey, val)
  1587. of opcNcsIncl:
  1588. let g = c.graph
  1589. let destKey = regs[ra].node.strVal
  1590. let val = regs[instr.regB].node
  1591. if not contains(g.cacheSeqs, destKey):
  1592. g.cacheSeqs[destKey] = newTree(nkStmtList, val)
  1593. else:
  1594. block search:
  1595. for existing in g.cacheSeqs[destKey]:
  1596. if exprStructuralEquivalent(existing, val, strictSymEquality=true):
  1597. break search
  1598. g.cacheSeqs[destKey].add val
  1599. recordIncl(c, c.debug[pc], destKey, val)
  1600. of opcNcsLen:
  1601. let g = c.graph
  1602. decodeB(rkInt)
  1603. let destKey = regs[rb].node.strVal
  1604. regs[ra].intVal =
  1605. if contains(g.cacheSeqs, destKey): g.cacheSeqs[destKey].len else: 0
  1606. of opcNcsAt:
  1607. let g = c.graph
  1608. decodeBC(rkNode)
  1609. let idx = regs[rc].intVal
  1610. let destKey = regs[rb].node.strVal
  1611. if contains(g.cacheSeqs, destKey) and idx <% g.cacheSeqs[destKey].len:
  1612. regs[ra].node = g.cacheSeqs[destKey][idx.int]
  1613. else:
  1614. stackTrace(c, tos, pc, errIndexOutOfBounds)
  1615. of opcNctPut:
  1616. let g = c.graph
  1617. let destKey = regs[ra].node.strVal
  1618. let key = regs[instr.regB].node.strVal
  1619. let val = regs[instr.regC].node
  1620. if not contains(g.cacheTables, destKey):
  1621. g.cacheTables[destKey] = initBTree[string, PNode]()
  1622. if not contains(g.cacheTables[destKey], key):
  1623. g.cacheTables[destKey].add(key, val)
  1624. recordPut(c, c.debug[pc], destKey, key, val)
  1625. else:
  1626. stackTrace(c, tos, pc, "key already exists: " & key)
  1627. of opcNctLen:
  1628. let g = c.graph
  1629. decodeB(rkInt)
  1630. let destKey = regs[rb].node.strVal
  1631. regs[ra].intVal =
  1632. if contains(g.cacheTables, destKey): g.cacheTables[destKey].len else: 0
  1633. of opcNctGet:
  1634. let g = c.graph
  1635. decodeBC(rkNode)
  1636. let destKey = regs[rb].node.strVal
  1637. let key = regs[rc].node.strVal
  1638. if contains(g.cacheTables, destKey):
  1639. if contains(g.cacheTables[destKey], key):
  1640. regs[ra].node = getOrDefault(g.cacheTables[destKey], key)
  1641. else:
  1642. stackTrace(c, tos, pc, "key does not exist: " & key)
  1643. else:
  1644. stackTrace(c, tos, pc, "key does not exist: " & destKey)
  1645. of opcNctHasNext:
  1646. let g = c.graph
  1647. decodeBC(rkInt)
  1648. let destKey = regs[rb].node.strVal
  1649. regs[ra].intVal =
  1650. if g.cacheTables.contains(destKey):
  1651. ord(btrees.hasNext(g.cacheTables[destKey], regs[rc].intVal.int))
  1652. else:
  1653. 0
  1654. of opcNctNext:
  1655. let g = c.graph
  1656. decodeBC(rkNode)
  1657. let destKey = regs[rb].node.strVal
  1658. let index = regs[rc].intVal
  1659. if contains(g.cacheTables, destKey):
  1660. let (k, v, nextIndex) = btrees.next(g.cacheTables[destKey], index.int)
  1661. regs[ra].node = newTree(nkTupleConstr, newStrNode(k, c.debug[pc]), v,
  1662. newIntNode(nkIntLit, nextIndex))
  1663. else:
  1664. stackTrace(c, tos, pc, "key does not exist: " & destKey)
  1665. of opcTypeTrait:
  1666. # XXX only supports 'name' for now; we can use regC to encode the
  1667. # type trait operation
  1668. decodeB(rkNode)
  1669. var typ = regs[rb].node.typ
  1670. internalAssert c.config, typ != nil
  1671. while typ.kind == tyTypeDesc and typ.len > 0: typ = typ.sons[0]
  1672. createStr regs[ra]
  1673. regs[ra].node.strVal = typ.typeToString(preferExported)
  1674. of opcMarshalLoad:
  1675. let ra = instr.regA
  1676. let rb = instr.regB
  1677. inc pc
  1678. let typ = c.types[c.code[pc].regBx - wordExcess]
  1679. putIntoReg(regs[ra], loadAny(regs[rb].node.strVal, typ, c.cache, c.config))
  1680. of opcMarshalStore:
  1681. decodeB(rkNode)
  1682. inc pc
  1683. let typ = c.types[c.code[pc].regBx - wordExcess]
  1684. createStrKeepNode(regs[ra])
  1685. when not defined(nimNoNilSeqs):
  1686. if regs[ra].node.strVal.isNil: regs[ra].node.strVal = newStringOfCap(1000)
  1687. storeAny(regs[ra].node.strVal, typ, regs[rb].regToNode, c.config)
  1688. of opcToNarrowInt:
  1689. decodeBC(rkInt)
  1690. let mask = (1'i64 shl rc) - 1 # 0xFF
  1691. let signbit = 1'i64 shl (rc - 1) # 0x80
  1692. let toggle = mask - signbit # 0x7F
  1693. # algorithm: -((i8 and 0xFF) xor 0x7F) + 0x7F
  1694. # mask off higher bits.
  1695. # uses two's complement to sign-extend integer.
  1696. # reajust integer into desired range.
  1697. regs[ra].intVal = -((regs[rb].intVal and mask) xor toggle) + toggle
  1698. inc pc
  1699. proc execute(c: PCtx, start: int): PNode =
  1700. var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil)
  1701. newSeq(tos.slots, c.prc.maxSlots)
  1702. result = rawExecute(c, start, tos).regToNode
  1703. proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
  1704. if sym.kind in routineKinds:
  1705. if sym.typ.len-1 != args.len:
  1706. localError(c.config, sym.info,
  1707. "NimScript: expected $# arguments, but got $#" % [
  1708. $(sym.typ.len-1), $args.len])
  1709. else:
  1710. let start = genProc(c, sym)
  1711. var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
  1712. let maxSlots = sym.offset
  1713. newSeq(tos.slots, maxSlots)
  1714. # setup parameters:
  1715. if not isEmptyType(sym.typ.sons[0]) or sym.kind == skMacro:
  1716. putIntoReg(tos.slots[0], getNullValue(sym.typ.sons[0], sym.info, c.config))
  1717. # XXX We could perform some type checking here.
  1718. for i in 1..<sym.typ.len:
  1719. putIntoReg(tos.slots[i], args[i-1])
  1720. result = rawExecute(c, start, tos).regToNode
  1721. else:
  1722. localError(c.config, sym.info,
  1723. "NimScript: attempt to call non-routine: " & sym.name.s)
  1724. proc evalStmt*(c: PCtx, n: PNode) =
  1725. let n = transformExpr(c.graph, c.module, n)
  1726. let start = genStmt(c, n)
  1727. # execute new instructions; this redundant opcEof check saves us lots
  1728. # of allocations in 'execute':
  1729. if c.code[start].opcode != opcEof:
  1730. discard execute(c, start)
  1731. proc evalExpr*(c: PCtx, n: PNode): PNode =
  1732. let n = transformExpr(c.graph, c.module, n)
  1733. let start = genExpr(c, n)
  1734. assert c.code[start].opcode != opcEof
  1735. result = execute(c, start)
  1736. proc getGlobalValue*(c: PCtx; s: PSym): PNode =
  1737. internalAssert c.config, s.kind in {skLet, skVar} and sfGlobal in s.flags
  1738. result = c.globals.sons[s.position-1]
  1739. include vmops
  1740. proc setupGlobalCtx*(module: PSym; graph: ModuleGraph) =
  1741. if graph.vm.isNil:
  1742. graph.vm = newCtx(module, graph.cache, graph)
  1743. registerAdditionalOps(PCtx graph.vm)
  1744. else:
  1745. refresh(PCtx graph.vm, module)
  1746. proc myOpen(graph: ModuleGraph; module: PSym): PPassContext =
  1747. #var c = newEvalContext(module, emRepl)
  1748. #c.features = {allowCast, allowFFI, allowInfiniteLoops}
  1749. #pushStackFrame(c, newStackFrame())
  1750. # XXX produce a new 'globals' environment here:
  1751. setupGlobalCtx(module, graph)
  1752. result = PCtx graph.vm
  1753. when hasFFI:
  1754. PCtx(graph.vm).features = {allowFFI, allowCast}
  1755. proc myProcess(c: PPassContext, n: PNode): PNode =
  1756. let c = PCtx(c)
  1757. # don't eval errornous code:
  1758. if c.oldErrorCount == c.config.errorCounter:
  1759. evalStmt(c, n)
  1760. result = newNodeI(nkEmpty, n.info)
  1761. else:
  1762. result = n
  1763. c.oldErrorCount = c.config.errorCounter
  1764. proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
  1765. myProcess(c, n)
  1766. const evalPass* = makePass(myOpen, myProcess, myClose)
  1767. proc evalConstExprAux(module: PSym;
  1768. g: ModuleGraph; prc: PSym, n: PNode,
  1769. mode: TEvalMode): PNode =
  1770. let n = transformExpr(g, module, n)
  1771. setupGlobalCtx(module, g)
  1772. var c = PCtx g.vm
  1773. let oldMode = c.mode
  1774. defer: c.mode = oldMode
  1775. c.mode = mode
  1776. let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
  1777. if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
  1778. assert c.code[start].opcode != opcEof
  1779. when debugEchoCode: c.echoCode start
  1780. var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil)
  1781. newSeq(tos.slots, c.prc.maxSlots)
  1782. #for i in 0 ..< c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty)
  1783. result = rawExecute(c, start, tos).regToNode
  1784. if result.info.col < 0: result.info = n.info
  1785. proc evalConstExpr*(module: PSym; g: ModuleGraph; e: PNode): PNode =
  1786. result = evalConstExprAux(module, g, nil, e, emConst)
  1787. proc evalStaticExpr*(module: PSym; g: ModuleGraph; e: PNode, prc: PSym): PNode =
  1788. result = evalConstExprAux(module, g, prc, e, emStaticExpr)
  1789. proc evalStaticStmt*(module: PSym; g: ModuleGraph; e: PNode, prc: PSym) =
  1790. discard evalConstExprAux(module, g, prc, e, emStaticStmt)
  1791. proc setupCompileTimeVar*(module: PSym; g: ModuleGraph; n: PNode) =
  1792. discard evalConstExprAux(module, g, nil, n, emStaticStmt)
  1793. proc setupMacroParam(x: PNode, typ: PType): TFullReg =
  1794. case typ.kind
  1795. of tyStatic:
  1796. putIntoReg(result, x)
  1797. of tyTypeDesc:
  1798. putIntoReg(result, x)
  1799. else:
  1800. result.kind = rkNode
  1801. var n = x
  1802. if n.kind in {nkHiddenSubConv, nkHiddenStdConv}: n = n.sons[1]
  1803. n = n.canonValue
  1804. n.flags.incl nfIsRef
  1805. n.typ = x.typ
  1806. result.node = n
  1807. iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
  1808. let gp = macroSym.ast[genericParamsPos]
  1809. for i in 0 ..< gp.len:
  1810. let genericParam = gp[i].sym
  1811. let posInCall = macroSym.typ.len + i
  1812. yield (genericParam, call[posInCall])
  1813. # to prevent endless recursion in macro instantiation
  1814. const evalMacroLimit = 1000
  1815. proc evalMacroCall*(module: PSym; g: ModuleGraph;
  1816. n, nOrig: PNode, sym: PSym): PNode =
  1817. # XXX globalError() is ugly here, but I don't know a better solution for now
  1818. inc(g.config.evalMacroCounter)
  1819. if g.config.evalMacroCounter > evalMacroLimit:
  1820. globalError(g.config, n.info, "macro instantiation too nested")
  1821. # immediate macros can bypass any type and arity checking so we check the
  1822. # arity here too:
  1823. if sym.typ.len > n.safeLen and sym.typ.len > 1:
  1824. globalError(g.config, n.info, "in call '$#' got $#, but expected $# argument(s)" % [
  1825. n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)])
  1826. setupGlobalCtx(module, g)
  1827. var c = PCtx g.vm
  1828. c.comesFromHeuristic.line = 0'u16
  1829. c.callsite = nOrig
  1830. let start = genProc(c, sym)
  1831. var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
  1832. let maxSlots = sym.offset
  1833. newSeq(tos.slots, maxSlots)
  1834. # setup arguments:
  1835. var L = n.safeLen
  1836. if L == 0: L = 1
  1837. # This is wrong for tests/reject/tind1.nim where the passed 'else' part
  1838. # doesn't end up in the parameter:
  1839. #InternalAssert tos.slots.len >= L
  1840. # return value:
  1841. tos.slots[0].kind = rkNode
  1842. tos.slots[0].node = newNodeI(nkEmpty, n.info)
  1843. # setup parameters:
  1844. for i in 1..<sym.typ.len:
  1845. tos.slots[i] = setupMacroParam(n.sons[i], sym.typ.sons[i])
  1846. let gp = sym.ast[genericParamsPos]
  1847. for i in 0 ..< gp.len:
  1848. if sfImmediate notin sym.flags:
  1849. let idx = sym.typ.len + i
  1850. if idx < n.len:
  1851. tos.slots[idx] = setupMacroParam(n.sons[idx], gp[i].sym.typ)
  1852. else:
  1853. dec(g.config.evalMacroCounter)
  1854. c.callsite = nil
  1855. localError(c.config, n.info, "expected " & $gp.len &
  1856. " generic parameter(s)")
  1857. elif gp[i].sym.typ.kind in {tyStatic, tyTypeDesc}:
  1858. dec(g.config.evalMacroCounter)
  1859. c.callsite = nil
  1860. globalError(c.config, n.info, "static[T] or typedesc nor supported for .immediate macros")
  1861. # temporary storage:
  1862. #for i in L ..< maxSlots: tos.slots[i] = newNode(nkEmpty)
  1863. result = rawExecute(c, start, tos).regToNode
  1864. if result.info.line < 0: result.info = n.info
  1865. if cyclicTree(result): globalError(c.config, n.info, "macro produced a cyclic tree")
  1866. dec(g.config.evalMacroCounter)
  1867. c.callsite = nil