[pypy-svn] r22075 - in pypy/dist/pypy/rpython: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Jan 12 21:20:52 CET 2006


Author: cfbolz
Date: Thu Jan 12 21:20:51 2006
New Revision: 22075

Modified:
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/test/test_llinterp.py
Log:
make alloca (flavored_malloc(stack, ...)) work in llinterp. also invalidify the
object when leaving the stack as a safety check.


Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Thu Jan 12 21:20:51 2006
@@ -3,6 +3,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.memory import lladdress
 from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.objectmodel import FREED_OBJECT
 
 import sys
 import math
@@ -100,6 +101,7 @@
         self.f_back = f_back
         self.curr_block = None
         self.curr_operation_index = 0
+        self.alloca_objects = []
 
     # _______________________________________________________
     # variable setters/getters helpers
@@ -156,6 +158,9 @@
             nextblock, args = self.eval_block(nextblock)
             if nextblock is None:
                 self.llinterpreter.active_frame = self.f_back
+                for obj in self.alloca_objects:
+                    #XXX slighly unclean
+                    obj._setobj(None)
                 return args
 
     def eval_block(self, block):
@@ -353,6 +358,13 @@
 
     def op_flavored_malloc(self, flavor, obj):
         assert isinstance(flavor, str)
+        if flavor == "stack":
+            if isinstance(obj, self.llt.Struct) and obj._arrayfld is None:
+                result = self.llt.malloc(obj)
+                self.alloca_objects.append(result)
+                return result
+            else:
+                raise ValueError("cannot allocate variable-sized things on the stack")
         return self.llt.malloc(obj, flavor=flavor)
 
     def op_flavored_free(self, flavor, obj):

Modified: pypy/dist/pypy/rpython/test/test_llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_llinterp.py	(original)
+++ pypy/dist/pypy/rpython/test/test_llinterp.py	Thu Jan 12 21:20:51 2006
@@ -1,8 +1,9 @@
 
 import py
-from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr, PyObject
+from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr, PyObject, Void
 from pypy.rpython.rtyper import RPythonTyper
 from pypy.rpython.llinterp import LLInterpreter, LLException,log
+from pypy.rpython.rmodel import inputconst
 from pypy.translator.translator import TranslationContext
 from pypy.rpython.rlist import *
 from pypy.rpython.rint import signed_repr
@@ -384,6 +385,40 @@
         for j in [0, 1]:
             result = interpret(getids, [i, j])
             assert result
+
+def test_stack_malloc():
+    class A(object):
+        pass
+    def f():
+        a = A()
+        a.i = 1
+        return a.i
+    interp, graph = get_interpreter(f, [])
+    graph.startblock.operations[0].opname = "flavored_malloc"
+    graph.startblock.operations[0].args.insert(0, inputconst(Void, "stack"))
+    result = interp.eval_graph(graph, [])
+    assert result == 1
+
+def test_invalid_stack_access():
+    class A(object):
+        pass
+    globala = A()
+    globala.next = None
+    globala.i = 1
+    def g(a):
+        globala.next = a
+    def f():
+        a = A()
+        a.i = 2
+        g(a)
+    def h():
+        f()
+        return globala.next.i
+    interp, graph = get_interpreter(h, [])
+    fgraph = graph.startblock.operations[0].args[0].value._obj.graph
+    fgraph.startblock.operations[0].opname = "flavored_malloc"
+    fgraph.startblock.operations[0].args.insert(0, inputconst(Void, "stack"))
+    py.test.raises(AttributeError, "interp.eval_graph(graph, [])")
 #__________________________________________________________________
 # example functions for testing the LLInterpreter
 _snap = globals().copy()



More information about the Pypy-commit mailing list