main.py 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  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.returnvalue = None
  14. self.success = True
  15. self.generators = {}
  16. self.allow_compiled = True
  17. #self.allow_compiled = False
  18. # `self.jit` handles most JIT-related functionality.
  19. self.jit = jit.ModelverseJit()
  20. if self.allow_compiled:
  21. self.jit.compiled_function_lookup = lambda func_name: \
  22. getattr(compiled_functions, func_name, None)
  23. # To disable the JIT, uncomment the line below:
  24. # self.jit.set_jit_enabled(False)
  25. self.debug_info = "(no debug information found)"
  26. def execute_yields(self, username, operation, params, reply):
  27. try:
  28. self.success = True
  29. if username not in self.generators:
  30. self.generators[username] = {}
  31. if operation not in self.generators[username]:
  32. # Create the generator for the function to execute
  33. self.generators[username][operation] = getattr(self, operation)(username, *params)
  34. if reply is not None:
  35. return self.generators[username][operation].send(reply)
  36. else:
  37. return self.generators[username][operation].next()
  38. except StopIteration:
  39. # Done, so remove the generator
  40. del self.generators[username][operation]
  41. return None
  42. except:
  43. print("Unknown error @ %s" % self.debug_info)
  44. raise
  45. def execute_rule(self, username):
  46. user_root, = yield [("RD", [self.root, username])]
  47. user_frame, = yield [("RD", [user_root, "frame"])]
  48. inst, phase = yield [("RD", [user_frame, "IP"]),
  49. ("RD", [user_frame, "phase"]),
  50. ]
  51. self.new_debug, phase_v, inst_v = \
  52. yield [("RD", [inst, "__debug"]),
  53. ("RV", [phase]),
  54. ("RV", [inst]),
  55. ]
  56. if self.new_debug is not None:
  57. self.debug_info, = yield [("RV", [self.new_debug])]
  58. if phase_v == "finish":
  59. gen = self.helper_init(user_root)
  60. elif inst is None:
  61. raise Exception("Instruction pointer could not be found!")
  62. elif isinstance(phase_v, string_types):
  63. if phase_v == "init" and self.jit.is_jittable_entry_point(inst):
  64. #print("%-30s(%s)" % ("COMPILED " + str(self.jit.jitted_entry_points[inst]), phase_v))
  65. gen = self.execute_jit(user_root, inst, username)
  66. elif inst_v is None:
  67. raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
  68. else:
  69. gen = self.get_inst_phase_generator(inst_v, phase_v, user_root)
  70. elif inst_v is None:
  71. raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
  72. elif inst_v["value"] == "call":
  73. #print("%-30s(%s)" % ("call", "param"))
  74. gen = self.call_param(user_root)
  75. else:
  76. raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
  77. try:
  78. inp = None
  79. while 1:
  80. inp = yield gen.send(inp)
  81. except StopIteration:
  82. pass
  83. except jit.JitCompilationFailedException as e:
  84. # Try again, but this time without the JIT.
  85. # print(e.message)
  86. gen = self.get_inst_phase_generator(inst_v, phase_v, user_root)
  87. try:
  88. inp = None
  89. while 1:
  90. inp = yield gen.send(inp)
  91. except StopIteration:
  92. pass
  93. def get_inst_phase_generator(self, inst_v, phase_v, user_root):
  94. """Gets a generator for the given instruction in the given phase,
  95. for the specified user root."""
  96. #print("%-30s(%s) -- %s" % (inst_v["value"], phase_v, username))
  97. return getattr(self, "%s_%s" % (inst_v["value"], phase_v))(user_root)
  98. ##########################
  99. ### Process primitives ###
  100. ##########################
  101. def load_primitives(self, username):
  102. hierarchy, = yield [("RD", [self.root, "__hierarchy"])]
  103. primitives, = yield [("RD", [hierarchy, "primitives"])]
  104. keys, = yield [("RDK", [primitives])]
  105. function_names = yield [("RV", [f]) for f in keys]
  106. signatures = yield [("RDN", [primitives, f]) for f in keys]
  107. bodies = yield [("RD", [f, "body"]) for f in signatures]
  108. for i in range(len(keys)):
  109. self.jit.register_compiled(
  110. bodies[i],
  111. getattr(primitive_functions, function_names[i]),
  112. function_names[i])
  113. def execute_jit(self, user_root, inst, username):
  114. # execute_jit
  115. user_frame, = yield [("RD", [user_root, "frame"])]
  116. symbols, = yield [("RD", [user_frame, "symbols"])]
  117. all_links, = yield [("RO", [symbols])]
  118. containers = yield [("RE", [v]) for v in all_links]
  119. outgoings = yield [("RO", [v]) for v in all_links]
  120. dict_values = yield [("RD", [v[1], "value"]) for v in containers]
  121. formals_1 = yield [("RE", [v[0]]) for v in outgoings]
  122. dict_keys_ref = yield [("RD", [v[1], "name"]) for v in formals_1]
  123. dict_keys = yield [("RV", [v]) for v in dict_keys_ref]
  124. parameters = dict(zip(dict_keys, dict_values))
  125. parameters["root"] = self.root
  126. parameters["user_root"] = user_root
  127. parameters["username"] = username
  128. parameters["mvk"] = self
  129. # Have the JIT compile the function.
  130. try:
  131. jit_gen = self.jit.jit_compile(user_root, inst)
  132. inp = None
  133. while 1:
  134. inp = yield jit_gen.send(inp)
  135. except primitive_functions.PrimitiveFinished as e:
  136. compiled_func = e.result
  137. # Run the compiled function.
  138. try:
  139. prim = compiled_func(**parameters)
  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" % (compiled_func, 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.jit.register_compiled(compiler_body, compiled_function, var_name)
  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. self.jit.mark_entry_point(body)
  649. phase_link, frame_link, prev_phase, new_phase, new_frame, new_evalstack, new_symbols, new_returnvalue = \
  650. yield [("RDE", [user_frame, "phase"]),
  651. ("RDE", [user_root, "frame"]),
  652. ("CNV", ["finish"]),
  653. ("CNV", ["init"]),
  654. ("CN", []),
  655. ("CN", []),
  656. ("CN", []),
  657. ("CN", []),
  658. ]
  659. _, _, _, _, _, _, _, _, _, _, _ = \
  660. yield [("CD", [user_root, "frame", new_frame]),
  661. ("CD", [new_frame, "evalstack", new_evalstack]),
  662. ("CD", [new_frame, "symbols", new_symbols]),
  663. ("CD", [new_frame, "returnvalue", new_returnvalue]),
  664. ("CD", [new_frame, "caller", inst]),
  665. ("CD", [new_frame, "phase", new_phase]),
  666. ("CD", [new_frame, "IP", body]),
  667. ("CD", [new_frame, "prev", user_frame]),
  668. ("CD", [user_frame, "phase", prev_phase]),
  669. ("DE", [phase_link]),
  670. ("DE", [frame_link]),
  671. ]
  672. else:
  673. newer_frames, invoking_frames = \
  674. yield [("RRD", [user_frame, "prev"]),
  675. ("RRD", [inst, "caller"]),
  676. ]
  677. new_frame = self.find_overlapping(newer_frames, invoking_frames)
  678. phase_link, frame_link, new_symbols, new_IP = \
  679. yield [("RDE", [user_frame, "phase"]),
  680. ("RDE", [user_root, "frame"]),
  681. ("RD", [new_frame, "symbols"]),
  682. ("RD", [new_frame, "IP"]),
  683. ]
  684. signature, = yield [("RRD", [new_IP, "body"])]
  685. signature = signature[0]
  686. sig_params, last_param = \
  687. yield [("RD", [signature, "params"]),
  688. ("RD", [inst, "last_param"]),
  689. ]
  690. body, = yield [("RD", [new_IP, "body"])]
  691. self.jit.mark_entry_point(body)
  692. name, = yield [("RD", [last_param, "name"])]
  693. name_value, = yield [("RV", [name])]
  694. returnvalue, formal_parameter, new_phase, variable = \
  695. yield [("RD", [user_frame, "returnvalue"]),
  696. ("RD", [sig_params, name_value]),
  697. ("CNV", ["finish"]),
  698. ("CN", []),
  699. ]
  700. _, _, _, t1 = yield [("CD", [user_root, "frame", new_frame]),
  701. ("CD", [user_frame, "phase", new_phase]),
  702. ("CD", [variable, "value", returnvalue]),
  703. ("CE", [new_symbols, variable]),
  704. ]
  705. _, _, _ = yield [("CE", [t1, formal_parameter]),
  706. ("DE", [frame_link]),
  707. ("DE", [phase_link]),
  708. ]
  709. def find_overlapping(self, a, b):
  710. newer_frames = set(a)
  711. invoking_frames = set(b)
  712. matches = list(newer_frames.intersection(invoking_frames))
  713. if len(matches) == 1:
  714. return matches[0]
  715. elif len(matches) > 1:
  716. raise Exception("%s: error: multiple overlapping elements" % self.debug_info)
  717. else:
  718. raise Exception("%s: error: could not find any overlap" % self.debug_info)
  719. def call_param(self, user_root):
  720. user_frame, = yield [("RD", [user_root, "frame"])]
  721. inst, phase = yield [("RD", [user_frame, "IP"]),
  722. ("RD", [user_frame, "phase"]),
  723. ]
  724. params, last_param = \
  725. yield [("RD", [inst, "params"]),
  726. ("RD", [inst, "last_param"]),
  727. ]
  728. next_param, = yield [("RD", [params, "next_param"])]
  729. if params == phase:
  730. phase_link, ip_link, returnvalue, param_value, evalstack, evalstack_link = \
  731. yield [("RDE", [user_frame, "phase"]),
  732. ("RDE", [user_frame, "IP"]),
  733. ("RD", [user_frame, "returnvalue"]),
  734. ("RD", [params, "value"]),
  735. ("RD", [user_frame, "evalstack"]),
  736. ("RDE", [user_frame, "evalstack"]),
  737. ]
  738. body, = yield [("RD", [returnvalue, "body"])]
  739. new_frame, prev_evalstack, new_phase, prev_phase, new_evalstack, new_symbols, new_returnvalue = \
  740. yield [("CN", []),
  741. ("CN", []),
  742. ("CNV", ["init"]),
  743. ("CNV", ["init"]),
  744. ("CN", []),
  745. ("CN", []),
  746. ("CN", []),
  747. ]
  748. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = \
  749. yield [("CD", [new_frame, "evalstack", new_evalstack]),
  750. ("CD", [new_frame, "symbols", new_symbols]),
  751. ("CD", [new_frame, "returnvalue", new_returnvalue]),
  752. ("CD", [new_frame, "caller", inst]),
  753. ("CD", [new_frame, "phase", new_phase]),
  754. ("CD", [new_frame, "IP", body]),
  755. ("CD", [new_frame, "prev", user_frame]),
  756. ("CD", [user_frame, "phase", prev_phase]),
  757. ("CD", [user_frame, "IP", param_value]),
  758. ("CD", [prev_evalstack, "prev", evalstack]),
  759. ("CD", [evalstack, "inst", inst]),
  760. ("CD", [user_frame, "evalstack", prev_evalstack]),
  761. ("DE", [evalstack_link]),
  762. ("DE", [ip_link]),
  763. ("DE", [phase_link]),
  764. ]
  765. if next_param is not None:
  766. _ = yield [("CD", [evalstack, "phase", next_param])]
  767. else:
  768. evalstack_phase, = \
  769. yield [("CNV", ["call"])]
  770. _ = yield [("CD", [evalstack, "phase", evalstack_phase])]
  771. else:
  772. frame_link, phase_link, newer_frames, invoking_frames = \
  773. yield [("RDE", [user_root, "frame"]),
  774. ("RDE", [user_frame, "phase"]),
  775. ("RRD", [user_frame, "prev"]),
  776. ("RRD", [inst, "caller"]),
  777. ]
  778. new_frame = self.find_overlapping(newer_frames, invoking_frames)
  779. ip_link, evalstack, evalstack_link, new_symbols, new_IP = \
  780. yield [("RDE", [user_frame, "IP"]),
  781. ("RD", [user_frame, "evalstack"]),
  782. ("RDE", [user_frame, "evalstack"]),
  783. ("RD", [new_frame, "symbols"]),
  784. ("RD", [new_frame, "IP"]),
  785. ]
  786. signature, = yield [("RRD", [new_IP, "body"])]
  787. signature = signature[0]
  788. sig_params, = yield [("RD", [signature, "params"])]
  789. if last_param == phase:
  790. prev_param, = \
  791. yield [("RRD", [last_param, "next_param"])]
  792. prev_param = prev_param[0]
  793. name, = yield [("RD", [prev_param, "name"])]
  794. name_value, = \
  795. yield [("RV", [name])]
  796. evalstack_phase, = \
  797. yield [("CNV", ["call"])]
  798. _ = yield [("CD", [evalstack, "phase", evalstack_phase])]
  799. formal_parameter, param_value = \
  800. yield [("RD", [sig_params, name_value]),
  801. ("RD", [last_param, "value"]),
  802. ]
  803. else:
  804. param_b, = yield [("RD", [user_frame, "phase"])]
  805. param_c, param_a = \
  806. yield [("RD", [param_b, "next_param"]),
  807. ("RRD", [param_b, "next_param"]),
  808. ]
  809. param_a = param_a[0]
  810. name, param_value = \
  811. yield [("RD", [param_a, "name"]),
  812. ("RD", [param_b, "value"]),
  813. ]
  814. name_value, = \
  815. yield [("RV", [name])]
  816. formal_parameter, _ = \
  817. yield [("RD", [sig_params, name_value]),
  818. ("CD", [evalstack, "phase", param_c]),
  819. ]
  820. new_phase, new_evalstack, variable, returnvalue = \
  821. yield [("CNV", ["init"]),
  822. ("CN", []),
  823. ("CN", []),
  824. ("RD", [user_frame, "returnvalue"]),
  825. ]
  826. _, _, _, _, _, _ = \
  827. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  828. ("CD", [new_evalstack, "prev", evalstack]),
  829. ("CD", [evalstack, "inst", inst]),
  830. ("CD", [user_frame, "phase", new_phase]),
  831. ("CD", [user_frame, "IP", param_value]),
  832. ("CD", [variable, "value", returnvalue]),
  833. ]
  834. t1, = yield [("CE", [new_symbols, variable])]
  835. _, _, _, _ = \
  836. yield [("CE", [t1, formal_parameter]),
  837. ("DE", [phase_link]),
  838. ("DE", [ip_link]),
  839. ("DE", [evalstack_link]),
  840. ]
  841. def input_init(self, user_root):
  842. user_frame, = yield [("RD", [user_root, "frame"])]
  843. returnvalue_link, _input = \
  844. yield [("RDE", [user_frame, "returnvalue"]),
  845. ("RD", [user_root, "input"]),
  846. ]
  847. value, next, phase_link = \
  848. yield [("RD", [_input, "value"]),
  849. ("RD", [_input, "next"]),
  850. ("RDE", [user_frame, "phase"]),
  851. ]
  852. if value is not None:
  853. v = yield [("RV", [value])]
  854. _, _, finish = \
  855. yield [("CD", [user_frame, "returnvalue", value]),
  856. ("CD", [user_root, "input", next]),
  857. ("CNV", ["finish"]),
  858. ]
  859. _, _, _, _ = \
  860. yield [("CD", [user_frame, "phase", finish]),
  861. ("DN", [_input]),
  862. ("DE", [returnvalue_link]),
  863. ("DE", [phase_link]),
  864. ]
  865. self.input_value = value
  866. else:
  867. # No input yet, so just wait and don't advance IP or phase
  868. self.input_value = None
  869. self.success = False
  870. def output_init(self, user_root):
  871. user_frame, = yield [("RD", [user_root, "frame"])]
  872. evalstack, evalstack_link, ip_link, inst = \
  873. yield [("RD", [user_frame, "evalstack"]),
  874. ("RDE", [user_frame, "evalstack"]),
  875. ("RDE", [user_frame, "IP"]),
  876. ("RD", [user_frame, "IP"]),
  877. ]
  878. value, new_evalstack, evalstack_phase = \
  879. yield [("RD", [inst, "value"]),
  880. ("CN", []),
  881. ("CNV", ["output"]),
  882. ]
  883. _, _, _, _, _, _, _ = \
  884. yield [("CD", [user_frame, "evalstack", new_evalstack]),
  885. ("CD", [new_evalstack, "prev", evalstack]),
  886. ("CD", [evalstack, "inst", inst]),
  887. ("CD", [evalstack, "phase", evalstack_phase]),
  888. ("CD", [user_frame, "IP", value]),
  889. ("DE", [evalstack_link]),
  890. ("DE", [ip_link]),
  891. ]
  892. def output_output(self, user_root):
  893. user_frame, = yield [("RD", [user_root, "frame"])]
  894. returnvalue_link, returnvalue, last_output, phase_link, last_output_link, new_last_output, finish = \
  895. yield [("RDE", [user_frame, "returnvalue"]),
  896. ("RD", [user_frame, "returnvalue"]),
  897. ("RD", [user_root, "last_output"]),
  898. ("RDE", [user_frame, "phase"]),
  899. ("RDE", [user_root, "last_output"]),
  900. ("CN", []),
  901. ("CNV", ["finish"]),
  902. ]
  903. _, _, _, _, _, _ = \
  904. yield [("CD", [last_output, "value", returnvalue]),
  905. ("CD", [last_output, "next", new_last_output]),
  906. ("CD", [user_root, "last_output", new_last_output]),
  907. ("CD", [user_frame, "phase", finish]),
  908. ("DE", [last_output_link]),
  909. ("DE", [phase_link]),
  910. ]
  911. def declare_init(self, user_root):
  912. user_frame, = yield [("RD", [user_root, "frame"])]
  913. inst, = yield [("RD", [user_frame, "IP"])]
  914. new_var, symbols, phase_link, empty_node, new_phase = \
  915. yield [("RD", [inst, "var"]),
  916. ("RD", [user_frame, "symbols"]),
  917. ("RDE", [user_frame, "phase"]),
  918. ("CN", []),
  919. ("CNV", ["finish"]),
  920. ]
  921. exists, = yield [("RDN", [symbols, new_var])]
  922. if exists is None:
  923. new_edge, = yield [("CE", [symbols, empty_node])]
  924. _ = yield [("CE", [new_edge, new_var])]
  925. _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  926. ("DE", [phase_link]),
  927. ]
  928. def global_init(self, user_root):
  929. user_frame, = yield [("RD", [user_root, "frame"])]
  930. inst, = yield [("RD", [user_frame, "IP"])]
  931. new_var, global_symbols, phase_link, empty_node, new_phase = \
  932. yield [("RD", [inst, "var"]),
  933. ("RD", [user_root, "globals"]),
  934. ("RDE", [user_frame, "phase"]),
  935. ("CN", []),
  936. ("CNV", ["finish"]),
  937. ]
  938. value, = yield [("RV", [new_var])]
  939. exists, = yield [("RD", [global_symbols, value])]
  940. if exists is None:
  941. yield [("CD", [global_symbols, value, empty_node])]
  942. _, _ = yield [("CD", [user_frame, "phase", new_phase]),
  943. ("DE", [phase_link])
  944. ]