vm.nim 73 KB

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