[pypy-svn] r28103 - in pypy/dist/pypy/translator/stackless: . test
mwh at codespeak.net
mwh at codespeak.net
Fri Jun 2 15:47:28 CEST 2006
Author: mwh
Date: Fri Jun 2 15:47:26 2006
New Revision: 28103
Modified:
pypy/dist/pypy/translator/stackless/test/test_resume_point.py
pypy/dist/pypy/translator/stackless/transform.py
Log:
(pedronis, mwh)
a little code, and another test passes.
Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original)
+++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Fri Jun 2 15:47:26 2006
@@ -68,7 +68,6 @@
def example():
f(one(),one()+one())
return 0
- py.test.skip("in-progress")
e = py.test.raises(Exception, transform_stackless_function, example)
assert e.value.args == ('not covered needed value at resume_point',)
Modified: pypy/dist/pypy/translator/stackless/transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/transform.py (original)
+++ pypy/dist/pypy/translator/stackless/transform.py Fri Jun 2 15:47:26 2006
@@ -100,6 +100,10 @@
def operation_is_true(self, op):
if op.opname == 'yield_current_frame_to_caller':
return True
+ elif op.opname == 'resume_point':
+ return True
+ elif op.opname == 'resume_point_invoke':
+ return True
return self.stackless_gc and LL_OPERATIONS[op.opname].canunwindgc
def analyze_external_call(self, op):
@@ -108,7 +112,18 @@
return callable in [ll_stack.ll_stack_unwind, ll_stack.ll_stack_capture,
ll_stackless.ll_stackless_stack_frames_depth,
ll_stackless.ll_stackless_switch]
-
+
+def vars_to_save(block):
+ lastresult = block.operations[-1].result
+ args = []
+ for l in block.exits:
+ for arg in l.args:
+ if isinstance(arg, model.Variable) \
+ and arg is not lastresult \
+ and arg not in args \
+ and arg not in [l.last_exception, l.last_exc_value]:
+ args.append(arg)
+ return args
class StacklessTransformer(object):
@@ -228,6 +243,9 @@
self.c_gc_nocollect = model.Constant("gc_nocollect", lltype.Void)
self.is_finished = False
+
+ self.explicit_resume_points = {}
+
# register the prebuilt restartinfos
for restartinfo in frame.RestartInfo.prebuilt:
self.register_restart_info(restartinfo)
@@ -405,9 +423,54 @@
if op.opname == 'yield_current_frame_to_caller':
op = replace_with_call(self.yield_current_frame_to_caller_ptr)
stackless_op = True
-
+
if (op.opname in ('direct_call', 'indirect_call')
or self.analyzer.operation_is_true(op)):
+ if op.opname == 'resume_point':
+ # in some circumstances we might be able to reuse
+ # an already inserted resume point
+ if i == len(block.operations) - 1:
+ link = block.exits[0]
+ else:
+ link = support.split_block_with_keepalive(block, i+1)
+ parms = op.args[1:]
+ if not isinstance(parms[0], model.Variable):
+ assert parms[0].value is None
+ parms[0] = None
+ args = vars_to_save(block)
+ for a in args:
+ if a not in parms:
+ raise Exception, "not covered needed value at resume_point"
+ if parms[0] is not None: # returns= case
+ res = parms[0]
+ args = [arg for arg in args if arg is not res]
+ else:
+ args = args
+ res = op.result
+
+ (frame_type,
+ fieldnames) = self.frametyper.frame_type_for_vars(args)
+
+ self.resume_points.append(
+ ResumePoint(res, args, tuple(block.exits),
+ frame_type, fieldnames))
+
+ field2parm = {}
+ for arg, fieldname in zip(args, fieldnames):
+ p = parms.index(arg)
+ field2parm[fieldname] = p-1 # ignore parm[0]
+
+ label = op.args[0].value
+ self.explicit_resume_points[label] = {
+ 'restart': len(self.masterarray1) + len(self.resume_points)-1,
+ 'frame_type': frame_type,
+ 'restype': res.concretetype,
+ 'field2parm': field2parm,
+ }
+ block = link.target
+ i = 0
+ continue
+
# trap calls to stackless-related suggested primitives
if op.opname == 'direct_call':
func = getattr(op.args[0].value._obj, '_callable', None)
@@ -467,14 +530,7 @@
# function be called right at the end of the resuming
# block, and that it is called even if the return
# value is not again used.
- args = []
- for l in block.exits:
- for arg in l.args:
- if isinstance(arg, model.Variable) \
- and arg is not op.result \
- and arg not in args \
- and arg not in [l.last_exception, l.last_exc_value]:
- args.append(arg)
+ args = vars_to_save(block)
save_block, frame_state_type, fieldnames = \
self.generate_save_block(args, var_unwind_exception)
More information about the Pypy-commit
mailing list