[pypy-svn] r43561 - in pypy/dist/pypy/translator: cli/test jvm jvm/test oosupport/test_template

niko at codespeak.net niko at codespeak.net
Tue May 22 14:41:10 CEST 2007


Author: niko
Date: Tue May 22 14:41:08 2007
New Revision: 43561

Added:
   pypy/dist/pypy/translator/oosupport/test_template/objectmodel.py
Modified:
   pypy/dist/pypy/translator/cli/test/test_objectmodel.py
   pypy/dist/pypy/translator/jvm/constant.py
   pypy/dist/pypy/translator/jvm/database.py
   pypy/dist/pypy/translator/jvm/generator.py
   pypy/dist/pypy/translator/jvm/genjvm.py
   pypy/dist/pypy/translator/jvm/metavm.py
   pypy/dist/pypy/translator/jvm/opcodes.py
   pypy/dist/pypy/translator/jvm/test/test_objectmodel.py
   pypy/dist/pypy/translator/jvm/typesystem.py
Log:
implement weak refs for genjvm; refactor test_objectmodel from cli into oosupport

Modified: pypy/dist/pypy/translator/cli/test/test_objectmodel.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_objectmodel.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_objectmodel.py	Tue May 22 14:41:08 2007
@@ -1,63 +1,10 @@
 import py
 from pypy.translator.cli.test.runtest import CliTest
-from pypy.rlib.test.test_objectmodel import BaseTestObjectModel
-
-from pypy.rlib.objectmodel import cast_object_to_weakgcaddress,\
-     cast_weakgcaddress_to_object
+from pypy.translator.oosupport.test_template.objectmodel import \
+     BaseTestObjectModel
 
 def skip_r_dict(self):
     py.test.skip('r_dict support is still incomplete')
 
 class TestCliObjectModel(CliTest, BaseTestObjectModel):
     test_rtype_r_dict_bm = skip_r_dict
-
-    def test_rdict_of_void_copy(self):
-        from pypy.rlib.test.test_objectmodel import r_dict, strange_key_eq, strange_key_hash
-        def fn():
-            d = r_dict(strange_key_eq, strange_key_hash)
-            d['hello'] = None
-            d['world'] = None
-            d1 = d.copy()
-            return len(d1)
-        assert self.interpret(fn, []) == 2
-
-    # this test is copied from TestLLtype in
-    # rlib/test_objectmodel.py. It is not in TestOOtype because at
-    # the moment llinterpret can't handle cast_*weakadr*
-    def test_cast_to_and_from_weakaddress(self):
-        class A(object):
-            pass
-        class B(object):
-            pass
-        def f():
-            a = A()
-            addr = cast_object_to_weakgcaddress(a)
-            return a is cast_weakgcaddress_to_object(addr, A)
-        res = self.interpret(f, [])
-        assert res
-##        def g():
-##            a = A()
-##            addr = cast_object_to_weakgcaddress(a)
-##            return cast_weakgcaddress_to_int(addr)
-##        assert isinstance(self.interpret(f, []), int)
-
-    def test_weakref_const(self):
-        class A(object):
-            def __init__(self):
-                self.x = 42
-        a = A()
-        weak = cast_object_to_weakgcaddress(a)
-        def f():
-            a.x = 10
-            b = cast_weakgcaddress_to_object(weak, A)
-            return b.x
-        assert self.interpret(f, []) == 10
-
-    def test_weakref_const_null(self):
-        class A(object):
-            pass
-        weak = cast_object_to_weakgcaddress(None)
-        def f():
-            b = cast_weakgcaddress_to_object(weak, A)
-            return b
-        assert self.interpret(f, []) is None

Modified: pypy/dist/pypy/translator/jvm/constant.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/constant.py	(original)
+++ pypy/dist/pypy/translator/jvm/constant.py	Tue May 22 14:41:08 2007
@@ -1,25 +1,31 @@
 from pypy.rpython.ootypesystem import ootype
+from pypy.objspace.flow import model as flowmodel
 from pypy.translator.jvm.generator import \
      Field, Method, CUSTOMDICTMAKE
 from pypy.translator.oosupport.constant import \
      BaseConstantGenerator, RecordConst, InstanceConst, ClassConst, \
-     StaticMethodConst, CustomDictConst
+     StaticMethodConst, CustomDictConst, WeakRefConst, push_constant
 from pypy.translator.jvm.typesystem import \
-     jPyPyConst, jObject, jVoid
+     jPyPyConst, jObject, jVoid, jWeakRef
 
 # ___________________________________________________________________________
 # Constant Generator
 
 class JVMConstantGenerator(BaseConstantGenerator):
-
+    
     # _________________________________________________________________
     # Constant Operations
     #
     # We store constants in static fields of the jPyPyConst class.
     
     def _init_constant(self, const):
-        fieldty = self.db.lltype_to_cts(const.OOTYPE())
-        const.fieldobj = Field(jPyPyConst.name, const.name, fieldty, True)
+        # Determine the Java type of the constant: some constants
+        # (weakrefs) do not have an OOTYPE, so if it returns None use
+        # jtype()
+        JFIELDOOTY = const.OOTYPE()
+        if not JFIELDOOTY: jfieldty = const.jtype()
+        else: jfieldty = self.db.lltype_to_cts(JFIELDOOTY)
+        const.fieldobj = Field(jPyPyConst.name, const.name, jfieldty, True)
 
     def push_constant(self, gen, const):
         const.fieldobj.load(gen)
@@ -92,3 +98,27 @@
         gen.new_with_jtype(self.hash_jcls)
         gen.emit(CUSTOMDICTMAKE)
         
+class JVMWeakRefConst(WeakRefConst):
+
+    # Ensure that weak refs are initialized last:
+    PRIORITY = 200
+
+    def jtype(self):
+        return jWeakRef
+
+    def create_pointer(self, gen):
+        gen.prepare_cast_ptr_to_weak_address()
+        if not self.value:
+            TYPE = ootype.ROOT
+            gen.push_null(TYPE)
+        else:
+            TYPE = self.value._TYPE
+            push_constant(self.db, self.value._TYPE, self.value, gen)
+        gen.finalize_cast_ptr_to_weak_address(TYPE)
+
+    def initialize_data(self, gen):
+        gen.pop(ootype.ROOT)
+        return True
+    
+    
+    

Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py	(original)
+++ pypy/dist/pypy/translator/jvm/database.py	Tue May 22 14:41:08 2007
@@ -16,6 +16,7 @@
      jStringBuilder, jInt, jVoid, jString, jChar, jPyPyConst, jObject, \
      jThrowable
 from pypy.translator.jvm.builtin import JvmBuiltInType
+from pypy.rpython.lltypesystem.llmemory import WeakGcAddress
 
 from pypy.translator.oosupport.database import Database as OODatabase
 
@@ -452,7 +453,8 @@
         ootype.Char:             jvmtype.jChar,    # byte would be sufficient, but harder
         ootype.UniChar:          jvmtype.jChar,
         ootype.Class:            jvmtype.jClass,
-        ootype.ROOT:             jvmtype.jObject   # treat like a scalar
+        ootype.ROOT:             jvmtype.jObject,  # treat like a scalar
+        WeakGcAddress:           jvmtype.jWeakRef
         }
 
     # Dictionary for non-scalar types; in this case, if we see the key, we

Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py	(original)
+++ pypy/dist/pypy/translator/jvm/generator.py	Tue May 22 14:41:08 2007
@@ -11,7 +11,7 @@
      jObject, jByteArray, jPyPyExcWrap, jIntegerClass, jLongClass, \
      jDoubleClass, jCharClass, jStringBuilder, JvmScalarType, jArrayList, \
      jObjectArray, jPyPyInterlink, jPyPyCustomDict, jPyPyEquals, \
-     jPyPyHashCode, jMap
+     jPyPyHashCode, jMap, jWeakRef
 
 # ___________________________________________________________________________
 # Miscellaneous helper functions
@@ -238,6 +238,7 @@
 NEW =       IntClassNameOpcode('new')
 DUP =       Opcode('dup')
 DUP2 =      Opcode('dup2')
+DUP_X1 =    Opcode('dup_x1')
 POP =       Opcode('pop')
 POP2 =      Opcode('pop2')
 SWAP =      Opcode('swap')
@@ -1084,7 +1085,37 @@
             self.emit(DCONST_1)
         else:
             # Big hack to avoid exponential notation:
-            self.emit(LDC2, "%22.22f" % value)        
+            self.emit(LDC2, "%22.22f" % value)
+
+    def prepare_cast_ptr_to_weak_address(self):
+        """
+        To cast a pointer to a weak ref is a 2-step process.
+        First, invoke this routine.  Then, invoke what is needed
+        to push the value, then invoke finalize_cast_ptr_to_weak_address 
+        """
+        self.emit(NEW, jWeakRef)
+        self.emit(DUP)
+        
+    def finalize_cast_ptr_to_weak_address(self, OOTYPE):
+        """
+        After prepare_cast_ptr_to_weak_address has been called, and the
+        ptr to cast has been pushed, you can invoke this routine.
+        OOTYPE should be the type of value which was pushed.
+        The result will be that at the top of the stack is a weak reference.
+        """
+        self.prepare_generic_argument(OOTYPE) 
+        ctor = Method.c(jWeakRef, (jObject,))
+        self.emit(ctor)
+
+    def cast_weak_address_to_ptr(self, OOTYPE):
+        """
+        If a weak ref is at the top of the stack, yields the object
+        that this weak ref is a pointer to.  OOTYPE is the kind of object
+        you had a weak reference to.
+        """
+        get_mthd = Method.v(jWeakRef, 'get', (), jObject)
+        self.emit(get_mthd)
+        self.prepare_generic_result(OOTYPE)
 
     # __________________________________________________________________
     # Methods invoked directly by strings in jvm/opcode.py

Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py	(original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py	Tue May 22 14:41:08 2007
@@ -18,7 +18,8 @@
 from pypy.translator.jvm.opcodes import opcodes
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.jvm.constant import \
-     JVMConstantGenerator, JVMStaticMethodConst, JVMCustomDictConst
+     JVMConstantGenerator, JVMStaticMethodConst, JVMCustomDictConst, \
+     JVMWeakRefConst
 from pypy.translator.jvm.prebuiltnodes import create_interlink_node
 
 class JvmError(Exception):
@@ -208,6 +209,7 @@
     ConstantGenerator = JVMConstantGenerator
     CustomDictConst   = JVMCustomDictConst
     StaticMethodConst = JVMStaticMethodConst
+    WeakRefConst = JVMWeakRefConst
     
     def __init__(self, tmpdir, translator, entrypoint):
         """

Modified: pypy/dist/pypy/translator/jvm/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/metavm.py	(original)
+++ pypy/dist/pypy/translator/jvm/metavm.py	Tue May 22 14:41:08 2007
@@ -114,3 +114,19 @@
         self._load_func(generator, *op.args[4:7])
         generator.emit(jvmgen.CUSTOMDICTMAKE)
 NewCustomDict = _NewCustomDict()
+
+class _CastPtrToWeakAddress(MicroInstruction):
+    def render(self, generator, op):
+        arg = op.args[0]
+        generator.prepare_cast_ptr_to_weak_address()
+        generator.load(arg)
+        generator.finalize_cast_ptr_to_weak_address(arg.concretetype)
+        generator.store(op.result)
+CastPtrToWeakAddress = _CastPtrToWeakAddress()
+        
+class _CastWeakAddressToPtr(MicroInstruction):
+    def render(self, generator, op):
+        RESULTTYPE = op.result.concretetype
+        generator.cast_weak_address_to_ptr(RESULTTYPE)
+CastWeakAddressToPtr = _CastWeakAddressToPtr()
+

Modified: pypy/dist/pypy/translator/jvm/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/opcodes.py	(original)
+++ pypy/dist/pypy/translator/jvm/opcodes.py	Tue May 22 14:41:08 2007
@@ -9,7 +9,8 @@
      PushArg, PushAllArgs, StoreResult, InstructionList, New, DoNothing, Call,\
      SetField, GetField, DownCast, RuntimeNew, OOString, CastTo
 from pypy.translator.jvm.metavm import \
-     IndirectCall, JvmCallMethod, TranslateException, NewCustomDict
+     IndirectCall, JvmCallMethod, TranslateException, NewCustomDict, \
+     CastPtrToWeakAddress, CastWeakAddressToPtr
 
 import pypy.translator.jvm.generator as jvmgen
 import pypy.translator.jvm.typesystem as jvmtype
@@ -59,9 +60,9 @@
     'hint':                     [PushArg(0), StoreResult],
     'direct_call':              [Call, StoreResult],
     'indirect_call':            [PushAllArgs, IndirectCall, StoreResult],
-    #
-    #'cast_ptr_to_weakadr':      [PushAllArgs, 'newobj instance void class %s::.ctor(object)' % WEAKREF],
-    #'cast_weakadr_to_ptr':      [CastWeakAdrToPtr],
+
+    'cast_ptr_to_weakadr':      [CastPtrToWeakAddress],
+    'cast_weakadr_to_ptr':      CastWeakAddressToPtr,
     #'gc__collect':              'call void class [mscorlib]System.GC::Collect()',
     #'resume_point':             Ignore,
 

Modified: pypy/dist/pypy/translator/jvm/test/test_objectmodel.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/test_objectmodel.py	(original)
+++ pypy/dist/pypy/translator/jvm/test/test_objectmodel.py	Tue May 22 14:41:08 2007
@@ -1,9 +1,7 @@
 import py
 from pypy.translator.jvm.test.runtest import JvmTest
-from pypy.rlib.test.test_objectmodel import BaseTestObjectModel
-
-from pypy.rlib.objectmodel import cast_object_to_weakgcaddress,\
-     cast_weakgcaddress_to_object
+from pypy.translator.oosupport.test_template.objectmodel import \
+     BaseTestObjectModel
 
 class TestJvmObjectModel(JvmTest, BaseTestObjectModel):
     pass

Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py	(original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py	Tue May 22 14:41:08 2007
@@ -168,6 +168,7 @@
 jMath = JvmClassType('java.lang.Math')
 jList = JvmInterfaceType('java.util.List')
 jArrayList = JvmClassType('java.util.ArrayList')
+jWeakRef = JvmClassType('java.lang.ref.WeakReference')
 jPyPy = JvmClassType('pypy.PyPy')
 jPyPyExcWrap = JvmClassType('pypy.ExceptionWrapper')
 jPyPyConst = JvmClassType('pypy.Constant')

Added: pypy/dist/pypy/translator/oosupport/test_template/objectmodel.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/oosupport/test_template/objectmodel.py	Tue May 22 14:41:08 2007
@@ -0,0 +1,57 @@
+import py
+from pypy.rlib.test.test_objectmodel import BaseTestObjectModel as RLibBase
+
+from pypy.rlib.objectmodel import cast_object_to_weakgcaddress,\
+     cast_weakgcaddress_to_object
+
+class BaseTestObjectModel(RLibBase):
+    def test_rdict_of_void_copy(self):
+        from pypy.rlib.test.test_objectmodel import r_dict, strange_key_eq, strange_key_hash
+        def fn():
+            d = r_dict(strange_key_eq, strange_key_hash)
+            d['hello'] = None
+            d['world'] = None
+            d1 = d.copy()
+            return len(d1)
+        assert self.interpret(fn, []) == 2
+
+    # this test is copied from TestLLtype in
+    # rlib/test_objectmodel.py. It is not in TestOOtype because at
+    # the moment llinterpret can't handle cast_*weakadr*
+    def test_cast_to_and_from_weakaddress(self):
+        class A(object):
+            pass
+        class B(object):
+            pass
+        def f():
+            a = A()
+            addr = cast_object_to_weakgcaddress(a)
+            return a is cast_weakgcaddress_to_object(addr, A)
+        res = self.interpret(f, [])
+        assert res
+##        def g():
+##            a = A()
+##            addr = cast_object_to_weakgcaddress(a)
+##            return cast_weakgcaddress_to_int(addr)
+##        assert isinstance(self.interpret(f, []), int)
+
+    def test_weakref_const(self):
+        class A(object):
+            def __init__(self):
+                self.x = 42
+        a = A()
+        weak = cast_object_to_weakgcaddress(a)
+        def f():
+            a.x = 10
+            b = cast_weakgcaddress_to_object(weak, A)
+            return b.x
+        assert self.interpret(f, []) == 10
+
+    def test_weakref_const_null(self):
+        class A(object):
+            pass
+        weak = cast_object_to_weakgcaddress(None)
+        def f():
+            b = cast_weakgcaddress_to_object(weak, A)
+            return b
+        assert self.interpret(f, []) is None



More information about the Pypy-commit mailing list