main.py 55 KB

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