|
@@ -2,6 +2,7 @@ import modelverse_kernel.primitives as primitive_functions
|
|
|
import modelverse_kernel.compiled as compiled_functions
|
|
|
import modelverse_jit.jit as jit
|
|
|
import modelverse_jit.intrinsics as jit_intrinsics
|
|
|
+from collections import defaultdict
|
|
|
import sys
|
|
|
import time
|
|
|
|
|
@@ -34,11 +35,12 @@ class ModelverseKernel(object):
|
|
|
|
|
|
# To disable the JIT, uncomment the line below:
|
|
|
# self.jit.set_jit_enabled(False)
|
|
|
- self.debug_info = "(no debug information found)"
|
|
|
+ self.debug_info = defaultdict(list)
|
|
|
|
|
|
def execute_yields(self, username, operation, params, reply):
|
|
|
try:
|
|
|
self.success = True
|
|
|
+ self.username = username
|
|
|
if username not in self.generators:
|
|
|
self.generators[username] = {}
|
|
|
if operation not in self.generators[username]:
|
|
@@ -54,42 +56,49 @@ class ModelverseKernel(object):
|
|
|
del self.generators[username][operation]
|
|
|
return None
|
|
|
except:
|
|
|
- print("Unknown error @ %s" % self.debug_info)
|
|
|
+ print("Unknown error @ %s" % self.debug_info[username])
|
|
|
raise
|
|
|
|
|
|
def execute_rule(self, username):
|
|
|
user_root, = yield [("RD", [self.root, username])]
|
|
|
- user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
- inst, phase = yield [("RD", [user_frame, "IP"]),
|
|
|
- ("RD", [user_frame, "phase"]),
|
|
|
- ]
|
|
|
- self.new_debug, phase_v, inst_v = \
|
|
|
- yield [("RD", [inst, "__debug"]),
|
|
|
- ("RV", [phase]),
|
|
|
- ("RV", [inst]),
|
|
|
- ]
|
|
|
- if self.new_debug is not None:
|
|
|
- self.debug_info, = yield [("RV", [self.new_debug])]
|
|
|
-
|
|
|
- if phase_v == "finish":
|
|
|
- gen = self.helper_init(user_root)
|
|
|
- elif inst is None:
|
|
|
- raise Exception("Instruction pointer could not be found!")
|
|
|
- elif isinstance(phase_v, string_types):
|
|
|
- if phase_v == "init" and self.jit.is_jittable_entry_point(inst):
|
|
|
- #print("%-30s(%s)" % ("COMPILED " + str(self.jit.jitted_entry_points[inst]), phase_v))
|
|
|
- gen = self.execute_jit(user_root, inst, username)
|
|
|
+ if user_root is None:
|
|
|
+ self.success = False
|
|
|
+ self.returnvalue = None
|
|
|
+ yield None
|
|
|
+ else:
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ self.inst, phase = yield [("RD", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "phase"]),
|
|
|
+ ]
|
|
|
+ self.new_debug, self.phase_v, inst_v = \
|
|
|
+ yield [("RD", [self.inst, "__debug"]),
|
|
|
+ ("RV", [phase]),
|
|
|
+ ("RV", [self.inst]),
|
|
|
+ ]
|
|
|
+ if self.new_debug is not None:
|
|
|
+ if self.debug_info[username]:
|
|
|
+ self.debug_info[username][-1], = yield [("RV", [self.new_debug])]
|
|
|
+
|
|
|
+ if self.phase_v == "finish":
|
|
|
+ gen = self.helper_init(user_root)
|
|
|
+ elif self.inst is None:
|
|
|
+ raise Exception("Instruction pointer could not be found!")
|
|
|
+ elif isinstance(self.phase_v, string_types):
|
|
|
+ if self.phase_v == "init" and self.jit.is_jittable_entry_point(self.inst):
|
|
|
+ #print("%-30s(%s)" % ("COMPILED " + str(self.jit.jitted_entry_points[self.inst]), phase_v))
|
|
|
+ gen = self.execute_jit(user_root, self.inst, username)
|
|
|
+ elif inst_v is None:
|
|
|
+ raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info[username], inst_v, self.phase_v))
|
|
|
+ else:
|
|
|
+ #print("%-30s(%s) -- %s" % (inst_v["value"], self.phase_v, username))
|
|
|
+ gen = self.get_inst_phase_generator(inst_v, self.phase_v, user_root)
|
|
|
elif inst_v is None:
|
|
|
- raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
|
|
|
+ raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info[username], inst_v, self.phase_v))
|
|
|
+ elif inst_v["value"] == "call":
|
|
|
+ #print("%-30s(%s)" % ("call", "param"))
|
|
|
+ gen = self.call_param(user_root)
|
|
|
else:
|
|
|
- gen = self.get_inst_phase_generator(inst_v, phase_v, user_root)
|
|
|
- elif inst_v is None:
|
|
|
- raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
|
|
|
- elif inst_v["value"] == "call":
|
|
|
- #print("%-30s(%s)" % ("call", "param"))
|
|
|
- gen = self.call_param(user_root)
|
|
|
- else:
|
|
|
- raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
|
|
|
+ raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info[username], inst_v, self.phase_v))
|
|
|
|
|
|
try:
|
|
|
inp = None
|
|
@@ -100,7 +109,7 @@ class ModelverseKernel(object):
|
|
|
except jit.JitCompilationFailedException as e:
|
|
|
# Try again, but this time without the JIT.
|
|
|
# print(e.message)
|
|
|
- gen = self.get_inst_phase_generator(inst_v, phase_v, user_root)
|
|
|
+ gen = self.get_inst_phase_generator(inst_v, self.phase_v, user_root)
|
|
|
try:
|
|
|
inp = None
|
|
|
while 1:
|
|
@@ -171,7 +180,7 @@ class ModelverseKernel(object):
|
|
|
inp = yield prim.send(inp)
|
|
|
except StopIteration:
|
|
|
# Execution has ended without return value, so we have no idea what to do
|
|
|
- raise Exception("%s: primitive finished without returning a value!" % (self.debug_info))
|
|
|
+ raise Exception("%s: primitive finished without returning a value!" % (self.debug_info[username]))
|
|
|
except primitive_functions.PrimitiveFinished as e:
|
|
|
# Execution has ended with a returnvalue, so read it out from the exception being thrown
|
|
|
result = e.result
|
|
@@ -187,6 +196,8 @@ class ModelverseKernel(object):
|
|
|
("DE", [lnk]),
|
|
|
("DN", [user_frame]),
|
|
|
]
|
|
|
+ if self.debug_info[self.username]:
|
|
|
+ self.debug_info[self.username].pop()
|
|
|
|
|
|
########################################
|
|
|
### Execute input and output methods ###
|
|
@@ -464,7 +475,7 @@ class ModelverseKernel(object):
|
|
|
("CNV", ["finish"]),
|
|
|
]
|
|
|
if variable is None:
|
|
|
- raise Exception("%s: not found as global: %s" % (self.debug_info, var_name))
|
|
|
+ raise Exception("Not found as global: %s" % var_name)
|
|
|
|
|
|
# Resolved a global, so this is a string
|
|
|
# Potentially, this might even be a function that we have precompiled already!
|
|
@@ -579,14 +590,20 @@ class ModelverseKernel(object):
|
|
|
|
|
|
if value is None:
|
|
|
prev_frame, = yield [("RD", [user_frame, "prev"])]
|
|
|
- _, _ = yield [("CD", [user_root, "frame", prev_frame]),
|
|
|
- ("DN", [user_frame]),
|
|
|
- ]
|
|
|
-
|
|
|
# If the callee's frame is marked with the '__primitive_return' key, then
|
|
|
# we need to throw an exception instead of just finishing here. This design
|
|
|
# gives us O(1) state reads per jit-interpreter transition.
|
|
|
exception_return, = yield [("RD", [user_frame, primitive_functions.PRIMITIVE_RETURN_KEY])]
|
|
|
+ if prev_frame is None:
|
|
|
+ _, = yield [("DN", [user_root])]
|
|
|
+ del self.debug_info[self.username]
|
|
|
+ else:
|
|
|
+ if self.debug_info[self.username]:
|
|
|
+ self.debug_info[self.username].pop()
|
|
|
+ _, _ = yield [("CD", [user_root, "frame", prev_frame]),
|
|
|
+ ("DN", [user_frame]),
|
|
|
+ ]
|
|
|
+
|
|
|
if exception_return is not None:
|
|
|
raise primitive_functions.PrimitiveFinished(None)
|
|
|
else:
|
|
@@ -608,6 +625,9 @@ class ModelverseKernel(object):
|
|
|
]
|
|
|
|
|
|
def return_eval(self, user_root):
|
|
|
+ if self.debug_info[self.username]:
|
|
|
+ self.debug_info[self.username].pop()
|
|
|
+
|
|
|
user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
prev_frame, exception_return, returnvalue = yield [
|
|
|
("RD", [user_frame, "prev"]),
|
|
@@ -726,6 +746,7 @@ class ModelverseKernel(object):
|
|
|
]
|
|
|
|
|
|
def call_call(self, user_root):
|
|
|
+ self.debug_info[self.username].append("None")
|
|
|
user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
inst, = yield [("RD", [user_frame, "IP"])]
|
|
|
param, = yield [("RD", [inst, "last_param"])]
|
|
@@ -805,9 +826,9 @@ class ModelverseKernel(object):
|
|
|
if len(matches) == 1:
|
|
|
return matches[0]
|
|
|
elif len(matches) > 1:
|
|
|
- raise Exception("%s: error: multiple overlapping elements" % self.debug_info)
|
|
|
+ raise Exception("Error: multiple overlapping elements")
|
|
|
else:
|
|
|
- raise Exception("%s: error: could not find any overlap" % self.debug_info)
|
|
|
+ raise Exception("Error: could not find any overlap")
|
|
|
|
|
|
def call_param(self, user_root):
|
|
|
user_frame, = yield [("RD", [user_root, "frame"])]
|