main.py 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. import modelverse_kernel.primitives as primitive_functions
  2. import modelverse_kernel.compiled as compiled_functions
  3. import modelverse_jit.jit as jit
  4. import sys
  5. import time
  6. if sys.version > '3': # pragma: no cover
  7. string_types = (str,)
  8. else:
  9. string_types = (str, unicode)
  10. class ModelverseKernel(object):
  11. def __init__(self, root):
  12. self.root = root
  13. self.primitives = {}
  14. self.compiled = {}
  15. self.returnvalue = None
  16. self.success = True
  17. self.generators = {}
  18. self.allow_compiled = True
  19. #self.allow_compiled = False
  20. # `self.jit` is handles most JIT-related functionality.
  21. # Set it to `None` to disable the JIT.
  22. self.jit = jit.ModelverseJit()
  23. self.debug_info = "(no debug information found)"
  24. def execute_yields(self, username, operation, params, reply):
  25. try:
  26. self.success = True
  27. if username not in self.generators:
  28. self.generators[username] = {}
  29. if operation not in self.generators[username]:
  30. # Create the generator for the function to execute
  31. self.generators[username][operation] = getattr(self, operation)(username, *params)
  32. if reply is not None:
  33. return self.generators[username][operation].send(reply)
  34. else:
  35. return self.generators[username][operation].next()
  36. except StopIteration:
  37. # Done, so remove the generator
  38. del self.generators[username][operation]
  39. return None
  40. except:
  41. print("Unknown error @ %s" % self.debug_info)
  42. raise
  43. def execute_rule(self, username):
  44. user_root, = yield [("RD", [self.root, username])]
  45. user_frame, = yield [("RD", [user_root, "frame"])]
  46. inst, phase = yield [("RD", [user_frame, "IP"]),
  47. ("RD", [user_frame, "phase"]),
  48. ]
  49. self.new_debug, phase_v, inst_v = \
  50. yield [("RD", [inst, "__debug"]),
  51. ("RV", [phase]),
  52. ("RV", [inst]),
  53. ]
  54. if self.new_debug is not None:
  55. self.debug_info, = yield [("RV", [self.new_debug])]
  56. if phase_v == "finish":
  57. gen = self.helper_init(user_root)
  58. elif inst is None:
  59. raise Exception("Instruction pointer could not be found!")
  60. elif isinstance(phase_v, string_types):
  61. if phase_v == "init" and (inst in self.compiled or \
  62. self.jit.is_jittable_entry_point(inst)):
  63. #print("%-30s(%s)" % ("COMPILED " + str(self.compiled[inst]), phase_v))
  64. gen = self.execute_primitive_or_jit(user_root, inst, username)
  65. elif inst_v is None:
  66. raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
  67. else:
  68. gen = self.get_inst_phase_generator(inst_v, phase_v, user_root)
  69. elif inst_v is None:
  70. raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
  71. elif inst_v["value"] == "call":
  72. #print("%-30s(%s)" % ("call", "param"))
  73. gen = self.call_param(user_root)
  74. else:
  75. raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
  76. try:
  77. inp = None
  78. while 1:
  79. inp = yield gen.send(inp)
  80. except StopIteration:
  81. pass
  82. except jit.JitCompilationFailedException:
  83. # Try again, but this time without the JIT.
  84. gen = self.get_inst_phase_generator(inst_v, phase_v, user_root)
  85. try:
  86. inp = None
  87. while 1:
  88. inp = yield gen.send(inp)
  89. except StopIteration:
  90. pass
  91. def get_inst_phase_generator(self, inst_v, phase_v, user_root):
  92. """Gets a generator for the given instruction in the given phase,
  93. for the specified user root."""
  94. #print("%-30s(%s) -- %s" % (inst_v["value"], phase_v, username))
  95. return getattr(self, "%s_%s" % (inst_v["value"], phase_v))(user_root)
  96. ##########################
  97. ### Process primitives ###
  98. ##########################
  99. def load_primitives(self, username):
  100. hierarchy, = yield [("RD", [self.root, "__hierarchy"])]
  101. primitives, = yield [("RD", [hierarchy, "primitives"])]
  102. keys, = yield [("RDK", [primitives])]
  103. function_names = yield [("RV", [f]) for f in keys]
  104. signatures = yield [("RDN", [primitives, f]) for f in keys]
  105. bodies = yield [("RD", [f, "body"]) for f in signatures]
  106. for i in range(len(keys)):
  107. self.primitives[bodies[i]] = getattr(primitive_functions, function_names[i])
  108. self.compiled.update(self.primitives)
  109. def execute_primitive_or_jit(self, user_root, inst, username):
  110. # execute_primitive_or_jit
  111. user_frame, = yield [("RD", [user_root, "frame"])]
  112. symbols, = yield [("RD", [user_frame, "symbols"])]
  113. all_links, = yield [("RO", [symbols])]
  114. containers = yield [("RE", [v]) for v in all_links]
  115. outgoings = yield [("RO", [v]) for v in all_links]
  116. dict_values = yield [("RD", [v[1], "value"]) for v in containers]
  117. formals_1 = yield [("RE", [v[0]]) for v in outgoings]
  118. dict_keys_ref = yield [("RD", [v[1], "name"]) for v in formals_1]
  119. dict_keys = yield [("RV", [v]) for v in dict_keys_ref]
  120. parameters = dict(zip(dict_keys, dict_values))
  121. parameters["root"] = self.root
  122. parameters["user_root"] = user_root
  123. parameters["username"] = username
  124. parameters["mvk"] = self
  125. # prim is a generator itself!
  126. try:
  127. # Forward the message we get to this generator
  128. # Sometimes it might not even be a generator, in which case this should already be in the except block (i.e., for the Read Root operation)
  129. if inst in self.compiled:
  130. prim = self.compiled[inst](**parameters)
  131. else:
  132. try:
  133. jit_gen = self.jit.try_jit(inst, dict_keys)
  134. inp = None
  135. while 1:
  136. inp = yield jit_gen.send(inp)
  137. except primitive_functions.PrimitiveFinished as e:
  138. # Execution has ended with a returnvalue, so read it out from the exception being thrown
  139. prim = e.result
  140. inp = None
  141. while 1:
  142. inp = yield prim.send(inp)
  143. except StopIteration:
  144. # Execution has ended without return value, so we have no idea what to do
  145. raise Exception("%s: primitive finished without returning a value!" % (self.debug_info))
  146. except primitive_functions.PrimitiveFinished as e:
  147. # Execution has ended with a returnvalue, so read it out from the exception being thrown
  148. result = e.result
  149. #if result is None:
  150. # raise Exception("Primitive raised exception: value of None for operation %s with parameters %s" % (self.compiled[inst], str(parameters)))
  151. # Clean up the current stack, as if a return happened
  152. old_frame, = yield [("RD", [user_frame, "prev"])]
  153. lnk, = yield [("RDE", [old_frame, "returnvalue"])]
  154. _, _, _, _ = yield [("CD", [old_frame, "returnvalue", result]),
  155. ("CD", [user_root, "frame", old_frame]),
  156. ("DE", [lnk]),
  157. ("DN", [user_frame]),
  158. ]
  159. ########################################
  160. ### Execute input and output methods ###
  161. ########################################
  162. def get_output(self, username):
  163. user_root, = yield [("RD", [self.root, username])]
  164. first_output, = yield [("RD", [user_root, "output"])]
  165. next_output, rv = yield [("RD", [first_output, "next"]),
  166. ("RD", [first_output, "value"]),
  167. ]
  168. if next_output is None:
  169. self.success = False
  170. self.returnvalue = None
  171. else:
  172. rv_value, = yield [("RV", [rv])]
  173. _, _ = yield [("CD", [user_root, "output", next_output]),
  174. ("DN", [first_output]),
  175. ]
  176. self.returnvalue = rv_value
  177. def set_input(self, username, value):
  178. user_root, = yield [("RD", [self.root, username])]
  179. old_input, link = yield [("RD", [user_root, "last_input"]),
  180. ("RDE", [user_root, "last_input"]),
  181. ]
  182. new_input, = yield [("CN", [])]
  183. _, _ = yield [("CD", [user_root, "last_input", new_input]),
  184. ("CD", [old_input, "next", new_input]),
  185. ]
  186. new_value, = yield [("CNV", [value])]
  187. _, _ = yield [("CD", [old_input, "value", new_value]),
  188. ("DE", [link])
  189. ]
  190. self.returnvalue = {"id": 100, "value": "success"}
  191. #############################################
  192. ### Transformation rules for instructions ###
  193. #############################################
  194. def break_init(self, user_root):
  195. user_frame, = yield [("RD", [user_root, "frame"])]
  196. phase_link, ip_link = \
  197. yield [("RDE", [user_frame, "phase"]),
  198. ("RDE", [user_frame, "IP"])
  199. ]
  200. inst, = yield [("RD", [user_frame, "IP"])]
  201. while_inst, new_phase = \
  202. yield [("RD", [inst, "while"]),
  203. ("CNV", ["finish"]),
  204. ]
  205. _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  206. ("CD", [user_frame, "IP", while_inst]),
  207. ("DE", [phase_link]),
  208. ("DE", [ip_link]),
  209. ]
  210. def continue_init(self, user_root):
  211. user_frame, = yield [("RD", [user_root, "frame"])]
  212. ip_link, inst = yield [("RDE", [user_frame, "IP"]),
  213. ("RD", [user_frame, "IP"]),
  214. ]
  215. while_inst, = yield [("RD", [inst, "while"])]
  216. _, _ = yield [("CD", [user_frame, "IP", while_inst]),
  217. ("DE", [ip_link]),
  218. ]
  219. def if_init(self, user_root):
  220. user_frame, = yield [("RD", [user_root, "frame"])]
  221. evalstack, evalstack_link = \
  222. yield [("RD", [user_frame, "evalstack"]),
  223. ("RDE", [user_frame, "evalstack"]),
  224. ]
  225. inst, ip_link = yield [("RD", [user_frame, "IP"]),
  226. ("RDE", [user_frame, "IP"]),
  227. ]
  228. cond, = yield [("RD", [inst, "cond"])]
  229. new_evalstack, new_phase = \
  230. yield [("CN", []),
  231. ("CNV", ["cond"]),
  232. ]
  233. _, _, _, _, _, _, _ = \
  234. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  235. ("CD", [new_evalstack, "prev", evalstack]),
  236. ("CD", [user_frame, "IP", cond]),
  237. ("CD", [evalstack, "inst", inst]),
  238. ("CD", [evalstack, "phase", new_phase]),
  239. ("DE", [evalstack_link]),
  240. ("DE", [ip_link]),
  241. ]
  242. def if_cond(self, user_root):
  243. user_frame, = yield [("RD", [user_root, "frame"])]
  244. returnvalue, inst = yield [("RD", [user_frame, "returnvalue"]),
  245. ("RD", [user_frame, "IP"]),
  246. ]
  247. returnvalue_v, = yield [("RV", [returnvalue])]
  248. _else, = yield [("RD", [inst, "else"])]
  249. if returnvalue_v:
  250. phase_link, evalstack, evalstack_link, ip_link, _then, new_evalstack, evalstack_phase, new_phase = \
  251. yield [("RDE", [user_frame, "phase"]),
  252. ("RD", [user_frame, "evalstack"]),
  253. ("RDE", [user_frame, "evalstack"]),
  254. ("RDE", [user_frame, "IP"]),
  255. ("RD", [inst, "then"]),
  256. ("CN", []),
  257. ("CNV", ["finish"]),
  258. ("CNV", ["init"]),
  259. ]
  260. _, _, _, _, _, _, _, _, _ = \
  261. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  262. ("CD", [user_frame, "IP", _then]),
  263. ("CD", [new_evalstack, "prev", evalstack]),
  264. ("CD", [evalstack, "inst", inst]),
  265. ("CD", [evalstack, "phase", evalstack_phase]),
  266. ("CD", [user_frame, "phase", new_phase]),
  267. ("DE", [evalstack_link]),
  268. ("DE", [ip_link]),
  269. ("DE", [phase_link]),
  270. ]
  271. elif _else is None:
  272. phase_link, new_phase = \
  273. yield [("RDE", [user_frame, "phase"]),
  274. ("CNV", ["finish"]),
  275. ]
  276. _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  277. ("DE", [phase_link]),
  278. ]
  279. else:
  280. phase_link, evalstack, evalstack_link, ip_link = \
  281. yield [("RDE", [user_frame, "phase"]),
  282. ("RD", [user_frame, "evalstack"]),
  283. ("RDE", [user_frame, "evalstack"]),
  284. ("RDE", [user_frame, "IP"]),
  285. ]
  286. new_evalstack, new_phase, evalstack_phase = \
  287. yield [("CN", []),
  288. ("CNV", ["init"]),
  289. ("CNV", ["finish"]),
  290. ]
  291. _, _, _, _, _, _, _, _, _ = \
  292. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  293. ("CD", [user_frame, "IP", _else]),
  294. ("CD", [new_evalstack, "prev", evalstack]),
  295. ("CD", [evalstack, "inst", inst]),
  296. ("CD", [evalstack, "phase", evalstack_phase]),
  297. ("CD", [user_frame, "phase", new_phase]),
  298. ("DE", [evalstack_link]),
  299. ("DE", [ip_link]),
  300. ("DE", [phase_link]),
  301. ]
  302. def while_init(self, user_root):
  303. user_frame, = yield [("RD", [user_root, "frame"])]
  304. evalstack, evalstack_link, ip_link, inst = \
  305. yield [("RD", [user_frame, "evalstack"]),
  306. ("RDE", [user_frame, "evalstack"]),
  307. ("RDE", [user_frame, "IP"]),
  308. ("RD", [user_frame, "IP"]),
  309. ]
  310. cond, new_evalstack, new_phase = \
  311. yield [("RD", [inst, "cond"]),
  312. ("CN", []),
  313. ("CNV", ["cond"]),
  314. ]
  315. _, _, _, _, _, _, _ = \
  316. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  317. ("CD", [new_evalstack, "prev", evalstack]),
  318. ("CD", [user_frame, "IP", cond]),
  319. ("CD", [evalstack, "phase", new_phase]),
  320. ("CD", [evalstack, "inst", inst]),
  321. ("DE", [evalstack_link]),
  322. ("DE", [ip_link]),
  323. ]
  324. def while_cond(self, user_root):
  325. user_frame, = yield [("RD", [user_root, "frame"])]
  326. returnvalue, = yield [("RD", [user_frame, "returnvalue"])]
  327. returnvalue_v, = yield [("RV", [returnvalue])]
  328. if returnvalue_v:
  329. phase_link, evalstack, evalstack_link, ip_link, inst = \
  330. yield [("RDE", [user_frame, "phase"]),
  331. ("RD", [user_frame, "evalstack"]),
  332. ("RDE", [user_frame, "evalstack"]),
  333. ("RDE", [user_frame, "IP"]),
  334. ("RD", [user_frame, "IP"]),
  335. ]
  336. body, = yield [("RD", [inst, "body"])]
  337. new_evalstack, new_phase, evalstack_phase = \
  338. yield [("CN", []),
  339. ("CNV", ["init"]),
  340. ("CNV", ["init"]),
  341. ]
  342. _, _, _, _, _, _, _, _, _ = \
  343. yield [("CD", [user_frame, "IP", body]),
  344. ("CD", [user_frame, "phase", new_phase]),
  345. ("CD", [user_frame, "evalstack", new_evalstack]),
  346. ("CD", [new_evalstack, "prev", evalstack]),
  347. ("CD", [evalstack, "inst", inst]),
  348. ("CD", [evalstack, "phase", evalstack_phase]),
  349. ("DE", [evalstack_link]),
  350. ("DE", [ip_link]),
  351. ("DE", [phase_link]),
  352. ]
  353. else:
  354. phase_link, new_phase = \
  355. yield [("RDE", [user_frame, "phase"]),
  356. ("CNV", ["finish"]),
  357. ]
  358. _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  359. ("DE", [phase_link])
  360. ]
  361. def access_init(self, user_root):
  362. user_frame, = yield [("RD", [user_root, "frame"])]
  363. evalstack, evalstack_link, inst, ip_link = \
  364. yield [("RD", [user_frame, "evalstack"]),
  365. ("RDE", [user_frame, "evalstack"]),
  366. ("RD", [user_frame, "IP"]),
  367. ("RDE", [user_frame, "IP"]),
  368. ]
  369. var, new_evalstack, new_phase = \
  370. yield [("RD", [inst, "var"]),
  371. ("CN", []),
  372. ("CNV", ["eval"]),
  373. ]
  374. _, _, _, _, _, _, _ = \
  375. yield [("CD", [user_frame, "IP", var]),
  376. ("CD", [user_frame, "evalstack", new_evalstack]),
  377. ("CD", [new_evalstack, "prev", evalstack]),
  378. ("CD", [evalstack, "inst", inst]),
  379. ("CD", [evalstack, "phase", new_phase]),
  380. ("DE", [evalstack_link]),
  381. ("DE", [ip_link]),
  382. ]
  383. def access_eval(self, user_root):
  384. user_frame, = yield [("RD", [user_root, "frame"])]
  385. phase_link, returnvalue_link, returnvalue = \
  386. yield [("RDE", [user_frame, "phase"]),
  387. ("RDE", [user_frame, "returnvalue"]),
  388. ("RD", [user_frame, "returnvalue"]),
  389. ]
  390. value, new_phase = yield [("RD", [returnvalue, "value"]),
  391. ("CNV", ["finish"]),
  392. ]
  393. _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  394. ("CD", [user_frame, "returnvalue", value]),
  395. ("DE", [phase_link]),
  396. ("DE", [returnvalue_link]),
  397. ]
  398. def resolve_init(self, user_root):
  399. user_frame, = yield [("RD", [user_root, "frame"])]
  400. symbols, evalstack, evalstack_link, ip_link, inst = \
  401. yield [("RD", [user_frame, "symbols"]),
  402. ("RD", [user_frame, "evalstack"]),
  403. ("RDE", [user_frame, "evalstack"]),
  404. ("RDE", [user_frame, "IP"]),
  405. ("RD", [user_frame, "IP"]),
  406. ]
  407. var, = yield [("RD", [inst, "var"])]
  408. variable, = yield [("RDN", [symbols, var])]
  409. if variable is None:
  410. phase_link, returnvalue_link, _globals, var_name = \
  411. yield [("RDE", [user_frame, "phase"]),
  412. ("RDE", [user_frame, "returnvalue"]),
  413. ("RD", [user_root, "globals"]),
  414. ("RV", [var]),
  415. ]
  416. variable, new_phase = \
  417. yield [("RD", [_globals, var_name]),
  418. ("CNV", ["finish"]),
  419. ]
  420. if variable is None:
  421. raise Exception("%s: not found as global: %s" % (self.debug_info, var_name))
  422. # Resolved a global, so this is a string
  423. # Potentially, this might even be a function that we have precompiled already!
  424. # So check whether this is the case or not
  425. if self.allow_compiled:
  426. compiled_function = getattr(compiled_functions, var_name, None)
  427. if compiled_function is not None:
  428. # We have a compiled function ready!
  429. # Now we have to bind the ID to the compiled functions
  430. # For this, we read out the body of the resolved data
  431. compiler_val, = yield [("RD", [variable, "value"])]
  432. compiler_body, = yield [("RD", [compiler_val, "body"])]
  433. self.compiled[compiler_body] = compiled_function
  434. else:
  435. phase_link, returnvalue_link, new_phase = \
  436. yield [("RDE", [user_frame, "phase"]),
  437. ("RDE", [user_frame, "returnvalue"]),
  438. ("CNV", ["finish"]),
  439. ]
  440. _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  441. ("CD", [user_frame, "returnvalue", variable]),
  442. ("DE", [phase_link]),
  443. ("DE", [returnvalue_link]),
  444. ]
  445. def assign_init(self, user_root):
  446. user_frame, = yield [("RD", [user_root, "frame"])]
  447. evalstack, evalstack_link, ip_link, inst = \
  448. yield [("RD", [user_frame, "evalstack"]),
  449. ("RDE", [user_frame, "evalstack"]),
  450. ("RDE", [user_frame, "IP"]),
  451. ("RD", [user_frame, "IP"]),
  452. ]
  453. var, new_evalstack, new_phase = \
  454. yield [("RD", [inst, "var"]),
  455. ("CN", []),
  456. ("CNV", ["value"]),
  457. ]
  458. _, _, _, _, _, _, _ = \
  459. yield [("CD", [user_frame, "IP", var]),
  460. ("CD", [user_frame, "evalstack", new_evalstack]),
  461. ("CD", [new_evalstack, "prev", evalstack]),
  462. ("CD", [evalstack, "inst", inst]),
  463. ("CD", [evalstack, "phase", new_phase]),
  464. ("DE", [evalstack_link]),
  465. ("DE", [ip_link]),
  466. ]
  467. def assign_value(self, user_root):
  468. user_frame, = yield [("RD", [user_root, "frame"])]
  469. phase_link, evalstack, returnvalue, evalstack_link, ip_link, inst = \
  470. yield [("RDE", [user_frame, "phase"]),
  471. ("RD", [user_frame, "evalstack"]),
  472. ("RD", [user_frame, "returnvalue"]),
  473. ("RDE", [user_frame, "evalstack"]),
  474. ("RDE", [user_frame, "IP"]),
  475. ("RD", [user_frame, "IP"]),
  476. ]
  477. value, new_evalstack, new_phase, evalstack_phase = \
  478. yield [("RD", [inst, "value"]),
  479. ("CN", []),
  480. ("CNV", ["init"]),
  481. ("CNV", ["assign"]),
  482. ]
  483. _, _, _, _, _, _, _, _, _, _ = \
  484. yield [("CD", [user_frame, "variable", returnvalue]),
  485. ("CD", [user_frame, "phase", new_phase]),
  486. ("CD", [user_frame, "evalstack", new_evalstack]),
  487. ("CD", [new_evalstack, "prev", evalstack]),
  488. ("CD", [evalstack, "inst", inst]),
  489. ("CD", [evalstack, "phase", evalstack_phase]),
  490. ("CD", [user_frame, "IP", value]),
  491. ("DE", [evalstack_link]),
  492. ("DE", [phase_link]),
  493. ("DE", [ip_link]),
  494. ]
  495. def assign_assign(self, user_root):
  496. user_frame, = yield [("RD", [user_root, "frame"])]
  497. phase_link, returnvalue, variable_link, variable = \
  498. yield [("RDE", [user_frame, "phase"]),
  499. ("RD", [user_frame, "returnvalue"]),
  500. ("RDE", [user_frame, "variable"]),
  501. ("RD", [user_frame, "variable"]),
  502. ]
  503. value_link, new_phase = \
  504. yield [("RDE", [variable, "value"]),
  505. ("CNV", ["finish"]),
  506. ]
  507. _, _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  508. ("CD", [variable, "value", returnvalue]),
  509. ("DE", [variable_link]),
  510. ("DE", [value_link]),
  511. ("DE", [phase_link]),
  512. ]
  513. def return_init(self, user_root):
  514. user_frame, = yield [("RD", [user_root, "frame"])]
  515. inst, = yield [("RD", [user_frame, "IP"])]
  516. value, = yield [("RD", [inst, "value"])]
  517. if value is None:
  518. prev_frame, = yield [("RD", [user_frame, "prev"])]
  519. _, _ = yield [("CD", [user_root, "frame", prev_frame]),
  520. ("DN", [user_frame]),
  521. ]
  522. else:
  523. evalstack, evalstack_link, ip_link, new_evalstack, evalstack_phase = \
  524. yield [("RD", [user_frame, "evalstack"]),
  525. ("RDE", [user_frame, "evalstack"]),
  526. ("RDE", [user_frame, "IP"]),
  527. ("CN", []),
  528. ("CNV", ["eval"]),
  529. ]
  530. _, _, _, _, _, _, _ = \
  531. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  532. ("CD", [new_evalstack, "prev", evalstack]),
  533. ("CD", [evalstack, "inst", inst]),
  534. ("CD", [evalstack, "phase", evalstack_phase]),
  535. ("CD", [user_frame, "IP", value]),
  536. ("DE", [evalstack_link]),
  537. ("DE", [ip_link]),
  538. ]
  539. def return_eval(self, user_root):
  540. user_frame, = yield [("RD", [user_root, "frame"])]
  541. prev_frame, = yield [("RD", [user_frame, "prev"])]
  542. returnvalue, old_returnvalue_link = \
  543. yield [("RD", [user_frame, "returnvalue"]),
  544. ("RDE", [prev_frame, "returnvalue"]),
  545. ]
  546. _, _, _, _ = yield [("CD", [user_root, "frame", prev_frame]),
  547. ("CD", [prev_frame, "returnvalue", returnvalue]),
  548. ("DE", [old_returnvalue_link]),
  549. ("DN", [user_frame]),
  550. ]
  551. def constant_init(self, user_root):
  552. user_frame, = yield [("RD", [user_root, "frame"])]
  553. phase_link, returnvalue_link, inst = \
  554. yield [("RDE", [user_frame, "phase"]),
  555. ("RDE", [user_frame, "returnvalue"]),
  556. ("RD", [user_frame, "IP"]),
  557. ]
  558. node, new_phase = yield [("RD", [inst, "node"]),
  559. ("CNV", ["finish"]),
  560. ]
  561. _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  562. ("CD", [user_frame, "returnvalue", node]),
  563. ("DE", [returnvalue_link]),
  564. ("DE", [phase_link]),
  565. ]
  566. def helper_init(self, user_root):
  567. user_frame, = yield [("RD", [user_root, "frame"])]
  568. inst, = yield [("RD", [user_frame, "IP"])]
  569. next, = yield [("RD", [inst, "next"])]
  570. if next is None:
  571. ip_link, phase_link, evalstack_top = \
  572. yield [("RDE", [user_frame, "IP"]),
  573. ("RDE", [user_frame, "phase"]),
  574. ("RD", [user_frame, "evalstack"]),
  575. ]
  576. evalstack, = yield [("RD", [evalstack_top, "prev"])]
  577. evalstack_inst, evalstack_phase, evalstack_inst_link, evalstack_phase_link = \
  578. yield [("RD", [evalstack, "inst"]),
  579. ("RD", [evalstack, "phase"]),
  580. ("RDE", [evalstack, "inst"]),
  581. ("RDE", [evalstack, "phase"]),
  582. ]
  583. _, _, _, _, _, _, _, _ = \
  584. yield [("CD", [user_frame, "evalstack", evalstack]),
  585. ("CD", [user_frame, "IP", evalstack_inst]),
  586. ("CD", [user_frame, "phase", evalstack_phase]),
  587. ("DE", [ip_link]),
  588. ("DE", [phase_link]),
  589. ("DE", [evalstack_inst_link]),
  590. ("DE", [evalstack_phase_link]),
  591. ("DN", [evalstack_top]),
  592. ]
  593. else:
  594. ip_link, phase_link, new_phase = \
  595. yield [("RDE", [user_frame, "IP"]),
  596. ("RDE", [user_frame, "phase"]),
  597. ("CNV", ["init"]),
  598. ]
  599. _, _, _, _ = yield [("CD", [user_frame, "IP", next]),
  600. ("CD", [user_frame, "phase", new_phase]),
  601. ("DE", [ip_link]),
  602. ("DE", [phase_link]),
  603. ]
  604. def call_init(self, user_root):
  605. user_frame, = yield [("RD", [user_root, "frame"])]
  606. symbols, evalstack, evalstack_link, ip_link, inst = \
  607. yield [("RD", [user_frame, "symbols"]),
  608. ("RD", [user_frame, "evalstack"]),
  609. ("RDE", [user_frame, "evalstack"]),
  610. ("RDE", [user_frame, "IP"]),
  611. ("RD", [user_frame, "IP"]),
  612. ]
  613. func, params = yield [("RD", [inst, "func"]),
  614. ("RD", [inst, "params"]),
  615. ]
  616. if params is None:
  617. new_evalstack, evalstack_phase = \
  618. yield [("CN", []),
  619. ("CNV", ["call"]),
  620. ]
  621. _, _, _, _, _, _, _ = \
  622. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  623. ("CD", [new_evalstack, "prev", evalstack]),
  624. ("CD", [evalstack, "inst", inst]),
  625. ("CD", [evalstack, "phase", evalstack_phase]),
  626. ("CD", [user_frame, "IP", func]),
  627. ("DE", [evalstack_link]),
  628. ("DE", [ip_link]),
  629. ]
  630. else:
  631. new_evalstack,= yield [("CN", [])]
  632. _, _, _, _, _, _, _ = \
  633. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  634. ("CD", [new_evalstack, "prev", evalstack]),
  635. ("CD", [evalstack, "inst", inst]),
  636. ("CD", [evalstack, "phase", params]),
  637. ("CD", [user_frame, "IP", func]),
  638. ("DE", [evalstack_link]),
  639. ("DE", [ip_link]),
  640. ]
  641. def call_call(self, user_root):
  642. user_frame, = yield [("RD", [user_root, "frame"])]
  643. inst, = yield [("RD", [user_frame, "IP"])]
  644. param, = yield [("RD", [inst, "last_param"])]
  645. if param is None:
  646. returnvalue, = yield [("RD", [user_frame, "returnvalue"])]
  647. body, = yield [("RD", [returnvalue, "body"])]
  648. if self.jit is not None:
  649. self.jit.mark_entry_point(body)
  650. phase_link, frame_link, prev_phase, new_phase, new_frame, new_evalstack, new_symbols, new_returnvalue = \
  651. yield [("RDE", [user_frame, "phase"]),
  652. ("RDE", [user_root, "frame"]),
  653. ("CNV", ["finish"]),
  654. ("CNV", ["init"]),
  655. ("CN", []),
  656. ("CN", []),
  657. ("CN", []),
  658. ("CN", []),
  659. ]
  660. _, _, _, _, _, _, _, _, _, _, _ = \
  661. yield [("CD", [user_root, "frame", new_frame]),
  662. ("CD", [new_frame, "evalstack", new_evalstack]),
  663. ("CD", [new_frame, "symbols", new_symbols]),
  664. ("CD", [new_frame, "returnvalue", new_returnvalue]),
  665. ("CD", [new_frame, "caller", inst]),
  666. ("CD", [new_frame, "phase", new_phase]),
  667. ("CD", [new_frame, "IP", body]),
  668. ("CD", [new_frame, "prev", user_frame]),
  669. ("CD", [user_frame, "phase", prev_phase]),
  670. ("DE", [phase_link]),
  671. ("DE", [frame_link]),
  672. ]
  673. else:
  674. newer_frames, invoking_frames = \
  675. yield [("RRD", [user_frame, "prev"]),
  676. ("RRD", [inst, "caller"]),
  677. ]
  678. new_frame = self.find_overlapping(newer_frames, invoking_frames)
  679. phase_link, frame_link, new_symbols, new_IP = \
  680. yield [("RDE", [user_frame, "phase"]),
  681. ("RDE", [user_root, "frame"]),
  682. ("RD", [new_frame, "symbols"]),
  683. ("RD", [new_frame, "IP"]),
  684. ]
  685. signature, = yield [("RRD", [new_IP, "body"])]
  686. signature = signature[0]
  687. sig_params, last_param = \
  688. yield [("RD", [signature, "params"]),
  689. ("RD", [inst, "last_param"]),
  690. ]
  691. body, = yield [("RD", [new_IP, "body"])]
  692. if self.jit is not None:
  693. self.jit.mark_entry_point(body)
  694. name, = yield [("RD", [last_param, "name"])]
  695. name_value, = yield [("RV", [name])]
  696. returnvalue, formal_parameter, new_phase, variable = \
  697. yield [("RD", [user_frame, "returnvalue"]),
  698. ("RD", [sig_params, name_value]),
  699. ("CNV", ["finish"]),
  700. ("CN", []),
  701. ]
  702. _, _, _, t1 = yield [("CD", [user_root, "frame", new_frame]),
  703. ("CD", [user_frame, "phase", new_phase]),
  704. ("CD", [variable, "value", returnvalue]),
  705. ("CE", [new_symbols, variable]),
  706. ]
  707. _, _, _ = yield [("CE", [t1, formal_parameter]),
  708. ("DE", [frame_link]),
  709. ("DE", [phase_link]),
  710. ]
  711. def find_overlapping(self, a, b):
  712. newer_frames = set(a)
  713. invoking_frames = set(b)
  714. matches = list(newer_frames.intersection(invoking_frames))
  715. if len(matches) == 1:
  716. return matches[0]
  717. elif len(matches) > 1:
  718. raise Exception("%s: error: multiple overlapping elements" % self.debug_info)
  719. else:
  720. raise Exception("%s: error: could not find any overlap" % self.debug_info)
  721. def call_param(self, user_root):
  722. user_frame, = yield [("RD", [user_root, "frame"])]
  723. inst, phase = yield [("RD", [user_frame, "IP"]),
  724. ("RD", [user_frame, "phase"]),
  725. ]
  726. params, last_param = \
  727. yield [("RD", [inst, "params"]),
  728. ("RD", [inst, "last_param"]),
  729. ]
  730. next_param, = yield [("RD", [params, "next_param"])]
  731. if params == phase:
  732. phase_link, ip_link, returnvalue, param_value, evalstack, evalstack_link = \
  733. yield [("RDE", [user_frame, "phase"]),
  734. ("RDE", [user_frame, "IP"]),
  735. ("RD", [user_frame, "returnvalue"]),
  736. ("RD", [params, "value"]),
  737. ("RD", [user_frame, "evalstack"]),
  738. ("RDE", [user_frame, "evalstack"]),
  739. ]
  740. body, = yield [("RD", [returnvalue, "body"])]
  741. new_frame, prev_evalstack, new_phase, prev_phase, new_evalstack, new_symbols, new_returnvalue = \
  742. yield [("CN", []),
  743. ("CN", []),
  744. ("CNV", ["init"]),
  745. ("CNV", ["init"]),
  746. ("CN", []),
  747. ("CN", []),
  748. ("CN", []),
  749. ]
  750. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = \
  751. yield [("CD", [new_frame, "evalstack", new_evalstack]),
  752. ("CD", [new_frame, "symbols", new_symbols]),
  753. ("CD", [new_frame, "returnvalue", new_returnvalue]),
  754. ("CD", [new_frame, "caller", inst]),
  755. ("CD", [new_frame, "phase", new_phase]),
  756. ("CD", [new_frame, "IP", body]),
  757. ("CD", [new_frame, "prev", user_frame]),
  758. ("CD", [user_frame, "phase", prev_phase]),
  759. ("CD", [user_frame, "IP", param_value]),
  760. ("CD", [prev_evalstack, "prev", evalstack]),
  761. ("CD", [evalstack, "inst", inst]),
  762. ("CD", [user_frame, "evalstack", prev_evalstack]),
  763. ("DE", [evalstack_link]),
  764. ("DE", [ip_link]),
  765. ("DE", [phase_link]),
  766. ]
  767. if next_param is not None:
  768. _ = yield [("CD", [evalstack, "phase", next_param])]
  769. else:
  770. evalstack_phase, = \
  771. yield [("CNV", ["call"])]
  772. _ = yield [("CD", [evalstack, "phase", evalstack_phase])]
  773. else:
  774. frame_link, phase_link, newer_frames, invoking_frames = \
  775. yield [("RDE", [user_root, "frame"]),
  776. ("RDE", [user_frame, "phase"]),
  777. ("RRD", [user_frame, "prev"]),
  778. ("RRD", [inst, "caller"]),
  779. ]
  780. new_frame = self.find_overlapping(newer_frames, invoking_frames)
  781. ip_link, evalstack, evalstack_link, new_symbols, new_IP = \
  782. yield [("RDE", [user_frame, "IP"]),
  783. ("RD", [user_frame, "evalstack"]),
  784. ("RDE", [user_frame, "evalstack"]),
  785. ("RD", [new_frame, "symbols"]),
  786. ("RD", [new_frame, "IP"]),
  787. ]
  788. signature, = yield [("RRD", [new_IP, "body"])]
  789. signature = signature[0]
  790. sig_params, = yield [("RD", [signature, "params"])]
  791. if last_param == phase:
  792. prev_param, = \
  793. yield [("RRD", [last_param, "next_param"])]
  794. prev_param = prev_param[0]
  795. name, = yield [("RD", [prev_param, "name"])]
  796. name_value, = \
  797. yield [("RV", [name])]
  798. evalstack_phase, = \
  799. yield [("CNV", ["call"])]
  800. _ = yield [("CD", [evalstack, "phase", evalstack_phase])]
  801. formal_parameter, param_value = \
  802. yield [("RD", [sig_params, name_value]),
  803. ("RD", [last_param, "value"]),
  804. ]
  805. else:
  806. param_b, = yield [("RD", [user_frame, "phase"])]
  807. param_c, param_a = \
  808. yield [("RD", [param_b, "next_param"]),
  809. ("RRD", [param_b, "next_param"]),
  810. ]
  811. param_a = param_a[0]
  812. name, param_value = \
  813. yield [("RD", [param_a, "name"]),
  814. ("RD", [param_b, "value"]),
  815. ]
  816. name_value, = \
  817. yield [("RV", [name])]
  818. formal_parameter, _ = \
  819. yield [("RD", [sig_params, name_value]),
  820. ("CD", [evalstack, "phase", param_c]),
  821. ]
  822. new_phase, new_evalstack, variable, returnvalue = \
  823. yield [("CNV", ["init"]),
  824. ("CN", []),
  825. ("CN", []),
  826. ("RD", [user_frame, "returnvalue"]),
  827. ]
  828. _, _, _, _, _, _ = \
  829. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  830. ("CD", [new_evalstack, "prev", evalstack]),
  831. ("CD", [evalstack, "inst", inst]),
  832. ("CD", [user_frame, "phase", new_phase]),
  833. ("CD", [user_frame, "IP", param_value]),
  834. ("CD", [variable, "value", returnvalue]),
  835. ]
  836. t1, = yield [("CE", [new_symbols, variable])]
  837. _, _, _, _ = \
  838. yield [("CE", [t1, formal_parameter]),
  839. ("DE", [phase_link]),
  840. ("DE", [ip_link]),
  841. ("DE", [evalstack_link]),
  842. ]
  843. def input_init(self, user_root):
  844. user_frame, = yield [("RD", [user_root, "frame"])]
  845. returnvalue_link, _input = \
  846. yield [("RDE", [user_frame, "returnvalue"]),
  847. ("RD", [user_root, "input"]),
  848. ]
  849. value, next, phase_link = \
  850. yield [("RD", [_input, "value"]),
  851. ("RD", [_input, "next"]),
  852. ("RDE", [user_frame, "phase"]),
  853. ]
  854. if value is not None:
  855. v = yield [("RV", [value])]
  856. _, _, finish = \
  857. yield [("CD", [user_frame, "returnvalue", value]),
  858. ("CD", [user_root, "input", next]),
  859. ("CNV", ["finish"]),
  860. ]
  861. _, _, _, _ = \
  862. yield [("CD", [user_frame, "phase", finish]),
  863. ("DN", [_input]),
  864. ("DE", [returnvalue_link]),
  865. ("DE", [phase_link]),
  866. ]
  867. self.input_value = value
  868. else:
  869. # No input yet, so just wait and don't advance IP or phase
  870. self.input_value = None
  871. self.success = False
  872. def output_init(self, user_root):
  873. user_frame, = yield [("RD", [user_root, "frame"])]
  874. evalstack, evalstack_link, ip_link, inst = \
  875. yield [("RD", [user_frame, "evalstack"]),
  876. ("RDE", [user_frame, "evalstack"]),
  877. ("RDE", [user_frame, "IP"]),
  878. ("RD", [user_frame, "IP"]),
  879. ]
  880. value, new_evalstack, evalstack_phase = \
  881. yield [("RD", [inst, "value"]),
  882. ("CN", []),
  883. ("CNV", ["output"]),
  884. ]
  885. _, _, _, _, _, _, _ = \
  886. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  887. ("CD", [new_evalstack, "prev", evalstack]),
  888. ("CD", [evalstack, "inst", inst]),
  889. ("CD", [evalstack, "phase", evalstack_phase]),
  890. ("CD", [user_frame, "IP", value]),
  891. ("DE", [evalstack_link]),
  892. ("DE", [ip_link]),
  893. ]
  894. def output_output(self, user_root):
  895. user_frame, = yield [("RD", [user_root, "frame"])]
  896. returnvalue_link, returnvalue, last_output, phase_link, last_output_link, new_last_output, finish = \
  897. yield [("RDE", [user_frame, "returnvalue"]),
  898. ("RD", [user_frame, "returnvalue"]),
  899. ("RD", [user_root, "last_output"]),
  900. ("RDE", [user_frame, "phase"]),
  901. ("RDE", [user_root, "last_output"]),
  902. ("CN", []),
  903. ("CNV", ["finish"]),
  904. ]
  905. _, _, _, _, _, _ = \
  906. yield [("CD", [last_output, "value", returnvalue]),
  907. ("CD", [last_output, "next", new_last_output]),
  908. ("CD", [user_root, "last_output", new_last_output]),
  909. ("CD", [user_frame, "phase", finish]),
  910. ("DE", [last_output_link]),
  911. ("DE", [phase_link]),
  912. ]
  913. def declare_init(self, user_root):
  914. user_frame, = yield [("RD", [user_root, "frame"])]
  915. inst, = yield [("RD", [user_frame, "IP"])]
  916. new_var, symbols, phase_link, empty_node, new_phase = \
  917. yield [("RD", [inst, "var"]),
  918. ("RD", [user_frame, "symbols"]),
  919. ("RDE", [user_frame, "phase"]),
  920. ("CN", []),
  921. ("CNV", ["finish"]),
  922. ]
  923. exists, = yield [("RDN", [symbols, new_var])]
  924. if exists is None:
  925. new_edge, = yield [("CE", [symbols, empty_node])]
  926. _ = yield [("CE", [new_edge, new_var])]
  927. _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  928. ("DE", [phase_link]),
  929. ]
  930. def global_init(self, user_root):
  931. user_frame, = yield [("RD", [user_root, "frame"])]
  932. inst, = yield [("RD", [user_frame, "IP"])]
  933. new_var, global_symbols, phase_link, empty_node, new_phase = \
  934. yield [("RD", [inst, "var"]),
  935. ("RD", [user_root, "globals"]),
  936. ("RDE", [user_frame, "phase"]),
  937. ("CN", []),
  938. ("CNV", ["finish"]),
  939. ]
  940. value, = yield [("RV", [new_var])]
  941. exists, = yield [("RD", [global_symbols, value])]
  942. if exists is None:
  943. yield [("CD", [global_symbols, value, empty_node])]
  944. _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  945. ("DE", [phase_link])
  946. ]