[pypy-svn] r25513 - in pypy/branch/stacklesscfg/pypy/translator/c: . test
mwh at codespeak.net
mwh at codespeak.net
Fri Apr 7 18:58:24 CEST 2006
Author: mwh
Date: Fri Apr 7 18:58:23 2006
New Revision: 25513
Added:
pypy/branch/stacklesscfg/pypy/translator/c/stacklesscode.py (contents, props changed)
Modified:
pypy/branch/stacklesscfg/pypy/translator/c/stacklesstransform.py
pypy/branch/stacklesscfg/pypy/translator/c/test/test_stacklesstransform.py
Log:
(hpk, mwh)
a start at an RPython main loop for stackless.
a start at a transform to insert state saving blocks into a function
more implicit XXXs than you could possibly imagine
Added: pypy/branch/stacklesscfg/pypy/translator/c/stacklesscode.py
==============================================================================
--- (empty file)
+++ pypy/branch/stacklesscfg/pypy/translator/c/stacklesscode.py Fri Apr 7 18:58:23 2006
@@ -0,0 +1,87 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython import rarithmetic
+
+STATE_HEADER = lltype.Struct('state_header',
+ ('f_back', lltype.Ptr(lltype.ForwardReference())),
+ ('state', lltype.Signed))
+STATE_HEADER.f_back.TO.become(STATE_HEADER)
+
+null_state = lltype.nullptr(STATE_HEADER)
+
+class StacklessData:
+ def __init__(self):
+ self.top = null_state
+ self.bottom = null_state
+ self.restart_substate = 0
+ self.retval_long = 0
+ self.retval_longlong = rarithmetic.r_longlong(0)
+ self.retval_double = 0.0
+ self.retval_void_p = llmemory.fakeaddress(None)
+ self.exception = None
+
+global_state = StacklessData()
+
+class UnwindException(Exception):
+ def __init__(self):
+ self.frame = null_state
+
+void_void_func = lltype.FuncType([], lltype.Void)
+long_void_func = lltype.FuncType([], lltype.Signed)
+longlong_void_func = lltype.FuncType([], lltype.SignedLongLong)
+pointer_void_func = lltype.FuncType([], llmemory.Address)
+float_void_func = lltype.FuncType([], lltype.Float)
+
+def call_function(fn, signature):
+ pass
+## if signature == 'void':
+## fn2 = llmemory.cast_adr_to_ptr(fn, void_void_func)
+## fn2()
+## elif signature == 'long':
+## fn3 = llmemory.cast_adr_to_ptr(fn, long_void_func)
+## global_state.long_retval = fn3()
+## elif signature == 'long long':
+## fn4 = llmemory.cast_adr_to_ptr(fn, longlong_void_func)
+## global_state.longlong_retval = fn4()
+## elif signature == 'pointer':
+## fn5 = llmemory.cast_adr_to_ptr(fn, pointer_void_func)
+## global_state.pointer_retval = fn5()
+## elif signature == 'float':
+## fn6 = llmemory.cast_adr_to_ptr(fn, float_void_func)
+## global_state.float_retval = fn6()
+
+
+null_address = llmemory.fakeaddress(None)
+
+def decode_state(state):
+ return null_address, 'void', 0
+
+def slp_main_loop():
+ while 1:
+ pending = global_state.top
+ while 1:
+ back = pending.f_back
+
+ state = pending.state
+ fn, signature, global_state.restart_substate = decode_state(state)
+
+ try:
+ call_function(fn, signature)
+## except UnwindException, u:
+## pending = u.frame
+## break
+ except Exception, e:
+ global_state.exception = e
+ else:
+ global_state.exception = None
+
+ if not back:
+ if global_state.exception:
+ raise global_state.exception
+ return
+
+ pending = back
+ global_state.top = pending
+
+ if global_state.bottom:
+ assert global_state.bottom.f_back is None
+ global_state.bottom.f_back = back
Modified: pypy/branch/stacklesscfg/pypy/translator/c/stacklesstransform.py
==============================================================================
--- pypy/branch/stacklesscfg/pypy/translator/c/stacklesstransform.py (original)
+++ pypy/branch/stacklesscfg/pypy/translator/c/stacklesstransform.py Fri Apr 7 18:58:23 2006
@@ -1,5 +1,12 @@
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython import rarithmetic
+from pypy.translator.backendopt import support
+from pypy.objspace.flow import model
+from pypy.rpython.memory.gctransform import varoftype
+from pypy.translator.unsimplify import copyvar
+from pypy.annotation import model as annmodel
+from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
+from pypy.translator.c import stacklesscode
STORAGE_TYPES = [llmemory.Address,
lltype.Signed,
@@ -11,7 +18,7 @@
'longlong']
def storage_type(T):
- """Return the type used to save values of this type
+ """Return the index into STORAGE_TYPES
"""
if T is lltype.Void:
return None
@@ -26,28 +33,64 @@
else:
raise Exception("don't know about %r" % (T,))
+
+
STATE_HEADER = lltype.Struct('state_header',
('f_back', lltype.Ptr(lltype.ForwardReference())),
('state', lltype.Signed))
STATE_HEADER.f_back.TO.become(STATE_HEADER)
+null_state = lltype.nullptr(STATE_HEADER)
+
+## def func(x):
+## return g() + x + 1
+
+## STATE_func_0 = lltype.Struct('STATE_func_0',
+## ('header', STATE_HEADER),
+## ('saved_long_0', Signed))
+
+## def func(x):
+## if global_state.top:
+## if global_state.restart_substate == 0:
+## frame = cast_pointer(lltype.Ptr(STATE_func_0), global_state.top)
+## x = frame.saved_long_0
+## retval = global_state.long_retval
+## else:
+## abort()
+## else:
+## try:
+## retval = g(x)
+## except UnwindException, u:
+## state = lltype.raw_malloc(STATE_func_0)
+## state.saved_long_0 = x
+## state.header.f_back = u.frame
+## state.header.state = XXX
+## u.frame = state.header
+## raise
+
+## return retval + x + 1
+
+
class StacklessTransfomer(object):
def __init__(self, translator):
self.translator = translator
- null_frame_p = lltype.nullptr(STATE_HEADER)
-
- class StacklessData:
- def __init__(self):
- top = null_frame_p
- bottom = null_frame_p
- restart_substate = 0
- retval_long = 0
- retval_longlong = rarithmetic.r_longlong(0)
- retval_double = 0.0
- retval_void_p = llmemory.fakeaddress(None)
-
+ edata = translator.rtyper.getexceptiondata()
self.frametypes = {}
+ self.curr_graph = None
+
+ mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
+ l2a = annmodel.lltype_to_annotation
+
+ slp_main_loop_graph = mixlevelannotator.getgraph(
+ stacklesscode.slp_main_loop, [], l2a(lltype.Void))
+ SLP_MAIN_LOOP_TYPE = lltype.FuncType([], lltype.Void)
+ self.slp_main_loop_type_ptr = model.Constant(lltype.functionptr(
+ SLP_MAIN_LOOP_TYPE, "slp_main_loop",
+ graph=slp_main_loop_graph),
+ SLP_MAIN_LOOP_TYPE)
+
+ mixlevelannotator.finish()
def frame_type_for_vars(self, vars):
types = [storage_type(v.concretetype) for v in vars]
@@ -71,6 +114,105 @@
return T
def transform_graph(self, graph):
+ self.resume_points = []
+
+ assert self.curr_graph is None
+ self.curr_graph = graph
+
for block in graph.iterblocks():
- pass
+ self.transform_block(block)
+ if self.resume_points:
+ XXX
+
+ self.curr_graph = None
+
+ def transform_block(self, block):
+ i = 0
+
+ edata = self.translator.rtyper.getexceptiondata()
+ etype = edata.lltype_of_exception_type
+ evalue = edata.lltype_of_exception_value
+
+ while i < len(block.operations):
+ op = block.operations[i]
+ if op.opname in ('direct_call', 'indirect_call'):
+ after_block = support.split_block_with_keepalive(self.translator, self.curr_graph, block, i+1)
+ link = block.exits[0]
+
+ var_unwind_exception = varoftype(evalue)
+
+ save_block = self.generate_save_block(link.args, var_unwind_exception)
+
+ newlink = model.Link(link.args + [var_unwind_exception], save_block, model.Constant(SystemExit))
+ block.exitswitch = model.c_last_exception
+ block.exits.append(newlink)
+ block = after_block
+ i = 0
+ else:
+ i += 1
+
+ def generate_save_block(self, varstosave, var_unwind_exception):
+ edata = self.translator.rtyper.getexceptiondata()
+ etype = edata.lltype_of_exception_type
+ evalue = edata.lltype_of_exception_value
+ inputargs = [copyvar(self.translator, v) for v in varstosave]
+ var_unwind_exception0 = copyvar(self.translator, var_unwind_exception)
+ from pypy.rpython.rclass import getinstancerepr
+ var_unwind_exception = varoftype(getinstancerepr(self.translator.rtyper,
+ self.translator.annotator.bookkeeper.getuniqueclassdef(SystemExit)).lowleveltype)
+
+ fields = []
+ for i, v in enumerate(varstosave):
+ if v.concretetype is not lltype.Void:
+ fields.append(('field_%d'%(i,), v.concretetype))
+ frame_type = lltype.Struct("S",
+ ('header', STATE_HEADER),
+ *fields)
+
+
+ save_state_block = model.Block(inputargs + [var_unwind_exception])
+ saveops = save_state_block.operations
+ frame_state_var = varoftype(lltype.Ptr(frame_type))
+
+ saveops.append(model.SpaceOperation('malloc',
+ [model.Constant(frame_type, lltype.Void)],
+ frame_state_var))
+
+ saveops.extend(self.generate_saveops(frame_state_var, inputargs))
+
+## state.header.f_back = u.frame
+## state.header.state = XXX
+## u.frame = state.header
+ header_var = varoftype(lltype.Ptr(STATE_HEADER))
+ saveops.append(model.SpaceOperation("cast_pointer", [frame_state_var], header_var))
+ var_unwind_exception_frame = varoftype(lltype.Ptr(STATE_HEADER))
+ saveops.append(model.SpaceOperation("getfield",
+ [var_unwind_exception, model.Constant("frame", lltype.Void)],
+ var_unwind_exception_frame))
+ saveops.append(model.SpaceOperation("setfield",
+ [header_var, model.Constant("f_back", lltype.Void), var_unwind_exception_frame],
+ varoftype(lltype.Void)))
+ saveops.append(model.SpaceOperation("setfield",
+ [var_unwind_exception, model.Constant("frame", lltype.Void)],
+ varoftype(lltype.Void)))
+
+ save_state_block.closeblock(model.Link([varoftype(etype), varoftype(evalue)],
+ self.curr_graph.exceptblock))
+
+ return save_state_block
+
+
+ def generate_saveops(self, frame_state_var, varstosave):
+ frame_type = frame_state_var.concretetype.TO
+ ops = []
+ for i, var in enumerate(varstosave):
+ t = storage_type(var.concretetype)
+ fname = model.Constant(frame_type._names[i+1], lltype.Void)
+ ops.append(model.SpaceOperation('setfield',
+ [frame_state_var, fname, var],
+ varoftype(lltype.Void)))
+
+ return ops
+
+
Modified: pypy/branch/stacklesscfg/pypy/translator/c/test/test_stacklesstransform.py
==============================================================================
--- pypy/branch/stacklesscfg/pypy/translator/c/test/test_stacklesstransform.py (original)
+++ pypy/branch/stacklesscfg/pypy/translator/c/test/test_stacklesstransform.py Fri Apr 7 18:58:23 2006
@@ -1,23 +1,40 @@
from pypy.translator.c.stacklesstransform import StacklessTransfomer
from pypy.rpython.memory.gctransform import varoftype
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.translator.translator import TranslationContext, graphof
+from pypy import conftest
-def test_frame_types():
- st = StacklessTransfomer(None)
+## def test_frame_types():
+## st = StacklessTransfomer(None)
- signed = varoftype(lltype.Signed)
- ptr = varoftype(lltype.Ptr(lltype.GcStruct("S")))
- addr = varoftype(llmemory.Address)
- float = varoftype(lltype.Float)
- longlong = varoftype(lltype.SignedLongLong)
+## signed = varoftype(lltype.Signed)
+## ptr = varoftype(lltype.Ptr(lltype.GcStruct("S")))
+## addr = varoftype(llmemory.Address)
+## float = varoftype(lltype.Float)
+## longlong = varoftype(lltype.SignedLongLong)
- ft4vars = st.frame_type_for_vars
+## ft4vars = st.frame_type_for_vars
- s1 = ft4vars([signed])
- assert 'header' in s1._flds
- assert len(s1._flds) == 2
+## s1 = ft4vars([signed])
+## assert 'header' in s1._flds
+## assert len(s1._flds) == 2
- s2_1 = ft4vars([signed, ptr])
- s2_2 = ft4vars([ptr, signed])
+## s2_1 = ft4vars([signed, ptr])
+## s2_2 = ft4vars([ptr, signed])
- assert s2_1 is s2_2
+## assert s2_1 is s2_2
+
+def test_simple_transform():
+ def g():
+ return 2
+ def example(x):
+ return g() + x + 1
+ t = TranslationContext()
+ t.buildannotator().build_types(example, [int])
+ t.buildrtyper().specialize()
+ example_graph = graphof(t, example)
+ st = StacklessTransfomer(t)
+ st.transform_graph(example_graph)
+ if conftest.option.view:
+ t.view()
+
More information about the Pypy-commit
mailing list