main.py 53 KB

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