vm.nim 75 KB

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