Alex Gaynor avatar Alex Gaynor committed c3cdcac Merge

merged upstream.

Comments (0)

Files changed (16)

pypy/rlib/rerased.py

             if hop.r_result.lowleveltype is lltype.Void:
                 return hop.inputconst(lltype.Void, None)
             [v] = hop.inputargs(hop.args_r[0])
-            return hop.genop('cast_opaque_ptr', [v], resulttype = hop.r_result)
+            return hop.args_r[0].rtype_unerase(hop, v)
 
     return erase, unerase
 
     def specialize_call(self, hop):
         [v] = hop.inputargs(hop.args_r[0])
         assert isinstance(hop.s_result, annmodel.SomeInteger)
-        return hop.gendirectcall(ll_unerase_int, v)
+        return hop.args_r[0].rtype_unerase_int(hop, v)
 
 def ll_unerase_int(gcref):
     from pypy.rpython.lltypesystem.lloperation import llop
         return False # cannot be None, but can contain a None
 
     def rtyper_makerepr(self, rtyper):
-        return ErasedRepr(rtyper)
+        if rtyper.type_system.name == 'lltypesystem':
+            return ErasedRepr(rtyper)
+        elif rtyper.type_system.name == 'ootypesystem':
+            return OOErasedRepr(rtyper)
 
     def rtyper_makekey(self):
         return self.__class__,
         return hop.genop('cast_opaque_ptr', [v_obj],
                          resulttype=self.lowleveltype)
 
+    def rtype_unerase(self, hop, s_obj):
+        [v] = hop.inputargs(hop.args_r[0])
+        return hop.genop('cast_opaque_ptr', [v], resulttype=hop.r_result)
+
+    def rtype_unerase_int(self, hop, v):
+        return hop.gendirectcall(ll_unerase_int, v)
+
     def rtype_erase_int(self, hop):
         [v_value] = hop.inputargs(lltype.Signed)
         c_one = hop.inputconst(lltype.Signed, 1)
             return lltype.nullptr(self.lowleveltype.TO)
         v = r_obj.convert_const(value._x)
         return lltype.cast_opaque_ptr(self.lowleveltype, v)
+
+from pypy.rpython.ootypesystem import ootype
+
+class OOErasedRepr(Repr):
+    lowleveltype = ootype.Object
+    def __init__(self, rtyper):
+        self.rtyper = rtyper
+
+    def rtype_erase(self, hop, s_obj):
+        hop.exception_cannot_occur()
+        r_obj = self.rtyper.getrepr(s_obj)
+        if r_obj.lowleveltype is lltype.Void:
+            return hop.inputconst(self.lowleveltype,
+                                  ootype.NULL)
+        [v_obj] = hop.inputargs(r_obj)
+        return hop.genop('cast_to_object', [v_obj],
+                         resulttype=self.lowleveltype)
+
+    def rtype_unerase(self, hop, s_obj):
+        [v] = hop.inputargs(hop.args_r[0])
+        return hop.genop('cast_from_object', [v], resulttype=hop.r_result)
+
+    def rtype_unerase_int(self, hop, v):
+        c_one = hop.inputconst(lltype.Signed, 1)
+        v2 = hop.genop('oounbox_int', [v], resulttype=hop.r_result)
+        return hop.genop('int_rshift', [v2, c_one], resulttype=lltype.Signed)
+
+    def rtype_erase_int(self, hop):
+        hop.exception_is_here()
+        [v_value] = hop.inputargs(lltype.Signed)
+        c_one = hop.inputconst(lltype.Signed, 1)
+        v2 = hop.genop('int_lshift_ovf', [v_value, c_one],
+                       resulttype = lltype.Signed)
+        v2p1 = hop.genop('int_add', [v2, c_one],
+                         resulttype = lltype.Signed)
+        return hop.genop('oobox_int', [v2p1], resulttype=hop.r_result)
+
+    def convert_const(self, value):
+        if value._identity is _identity_for_ints:
+            return value._x # FIXME: what should we do here?
+        bk = self.rtyper.annotator.bookkeeper
+        s_obj = value._identity.get_input_annotation(bk)
+        r_obj = self.rtyper.getrepr(s_obj)
+        if r_obj.lowleveltype is lltype.Void:
+            return ootype.NULL
+        v = r_obj.convert_const(value._x)
+        return ootype.cast_to_object(v)

pypy/rlib/test/test_rerased.py

 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.rpython.lltypesystem.rclass import OBJECTPTR
+from pypy.rpython.ootypesystem.rclass import OBJECT
 from pypy.rpython.lltypesystem import lltype, llmemory
 
+from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 
 class X(object):
     pass
     s = a.build_types(f, [])
     assert isinstance(s, annmodel.SomeInteger)
 
-def test_rtype_1():
-    def f():
-        return eraseX(X())
-    x = interpret(f, [])
-    assert lltype.typeOf(x) == llmemory.GCREF
-
-def test_rtype_2():
-    def f():
-        x1 = X()
-        e = eraseX(x1)
-        #assert not is_integer(e)
-        x2 = uneraseX(e)
-        return x2
-    x = interpret(f, [])
-    assert lltype.castable(OBJECTPTR, lltype.typeOf(x)) > 0
-
-def test_rtype_3():
-    def f():
-        e = erase_int(16)
-        #assert is_integer(e)
-        x2 = unerase_int(e)
-        return x2
-    x = interpret(f, [])
-    assert x == 16
-
-
-def test_prebuilt_erased():
-    e1 = erase_int(16)
-    x1 = X()
-    x1.foobar = 42
-    e2 = eraseX(x1)
-
-    def f():
-        #assert is_integer(e1)
-        #assert not is_integer(e2)
-        x1.foobar += 1
-        x2 = unerase_int(e1) + uneraseX(e2).foobar
-        return x2
-    x = interpret(f, [])
-    assert x == 16 + 42 + 1
-
-def test_prebuilt_erased_in_instance():
-    erase_empty, unerase_empty = new_erasing_pair("empty")
-    class FakeList(object):
-        pass
-
-    x1 = X()
-    x1.foobar = 42
-    l1 = FakeList()
-    l1.storage = eraseX(x1)
-    l2 = FakeList()
-    l2.storage = erase_empty(None)
-
-    def f():
-        #assert is_integer(e1)
-        #assert not is_integer(e2)
-        x1.foobar += 1
-        x2 = uneraseX(l1.storage).foobar + (unerase_empty(l2.storage) is None)
-        return x2
-    x = interpret(f, [])
-    assert x == 43 + True
-
-
-def test_overflow():
-    def f(i):
-        try:
-            e = erase_int(i)
-        except OverflowError:
-            return -1
-        #assert is_integer(e)
-        return unerase_int(e)
-    x = interpret(f, [16])
-    assert x == 16
-    x = interpret(f, [sys.maxint])
-    assert x == -1
-
-def test_none():
-    def foo():
-        return uneraseX(eraseX(None))
-    assert foo() is None
-    res = interpret(foo, [])
-    assert not res
-    #
-    def foo():
-        eraseX(X())
-        return uneraseX(eraseX(None))
-    assert foo() is None
-    res = interpret(foo, [])
-    assert not res
-
-def test_union():
-    s_e1 = SomeErased()
-    s_e1.const = 1
-    s_e2 = SomeErased()
-    s_e2.const = 3
-    assert not annmodel.pair(s_e1, s_e2).union().is_constant()
-
-
-def test_rtype_list():
-    prebuilt_l = [X()]
-    prebuilt_e = erase_list_X(prebuilt_l)
-    def l(flag):
-        if flag == 1:
-            l = [X()]
-            e = erase_list_X(l)
-        elif flag == 2:
-            l = prebuilt_l
-            e = erase_list_X(l)
-        else:
-            l = prebuilt_l
-            e = prebuilt_e
-        #assert is_integer(e) is False
-        assert unerase_list_X(e) is l
-    interpret(l, [0])
-    interpret(l, [1])
-    interpret(l, [2])
-
-# ____________________________________________________________
-
-def test_erasing_pair():
-    erase, unerase = new_erasing_pair("test1")
-    class X:
-        pass
-    x = X()
-    erased = erase(x)
-    assert unerase(erased) is x
-    #
-    erase2, unerase2 = new_erasing_pair("test2")
-    py.test.raises(AssertionError, unerase2, erased)
-
 def test_annotate_erasing_pair():
     erase, unerase = new_erasing_pair("test1")
     erase2, unerase2 = new_erasing_pair("test2")
     a = RPythonAnnotator()
     s = a.build_types(f, [int])
     assert isinstance(s, annmodel.SomeInteger)
+
+class BaseTestRErased(BaseRtypingTest):
+    def test_rtype_1(self):
+        def f():
+            return eraseX(X())
+        x = self.interpret(f, [])
+        assert lltype.typeOf(x) == self.ERASED_TYPE
+
+    def test_rtype_2(self):
+        def f():
+            x1 = X()
+            e = eraseX(x1)
+            #assert not is_integer(e)
+            x2 = uneraseX(e)
+            return x2
+        x = self.interpret(f, [])
+        assert self.castable(self.UNERASED_TYPE, x)
+
+    def test_rtype_3(self):
+        def f():
+            e = erase_int(16)
+            #assert is_integer(e)
+            x2 = unerase_int(e)
+            return x2
+        x = self.interpret(f, [])
+        assert x == 16
+
+    def test_prebuilt_erased(self):
+        e1 = erase_int(16)
+        x1 = X()
+        x1.foobar = 42
+        e2 = eraseX(x1)
+
+        def f():
+            #assert is_integer(e1)
+            #assert not is_integer(e2)
+            x1.foobar += 1
+            x2 = unerase_int(e1) + uneraseX(e2).foobar
+            return x2
+        x = self.interpret(f, [])
+        assert x == 16 + 42 + 1
+
+    def test_prebuilt_erased_in_instance(self):
+        erase_empty, unerase_empty = new_erasing_pair("empty")
+        class FakeList(object):
+            pass
+
+        x1 = X()
+        x1.foobar = 42
+        l1 = FakeList()
+        l1.storage = eraseX(x1)
+        l2 = FakeList()
+        l2.storage = erase_empty(None)
+
+        def f():
+            #assert is_integer(e1)
+            #assert not is_integer(e2)
+            x1.foobar += 1
+            x2 = uneraseX(l1.storage).foobar + (unerase_empty(l2.storage) is None)
+            return x2
+        x = self.interpret(f, [])
+        assert x == 43 + True
+
+    def test_overflow(self):
+        def f(i):
+            try:
+                e = erase_int(i)
+            except OverflowError:
+                return -1
+            #assert is_integer(e)
+            return unerase_int(e)
+        x = self.interpret(f, [16])
+        assert x == 16
+        x = self.interpret(f, [sys.maxint])
+        assert x == -1
+
+    def test_none(self):
+        def foo():
+            return uneraseX(eraseX(None))
+        assert foo() is None
+        res = self.interpret(foo, [])
+        assert not res
+        #
+        def foo():
+            eraseX(X())
+            return uneraseX(eraseX(None))
+        assert foo() is None
+        res = self.interpret(foo, [])
+        assert not res
+
+    def test_rtype_list(self):
+        prebuilt_l = [X()]
+        prebuilt_e = erase_list_X(prebuilt_l)
+        def l(flag):
+            if flag == 1:
+                l = [X()]
+                e = erase_list_X(l)
+            elif flag == 2:
+                l = prebuilt_l
+                e = erase_list_X(l)
+            else:
+                l = prebuilt_l
+                e = prebuilt_e
+            #assert is_integer(e) is False
+            assert unerase_list_X(e) is l
+        self.interpret(l, [0])
+        self.interpret(l, [1])
+        self.interpret(l, [2])
+
+class TestLLtype(BaseTestRErased, LLRtypeMixin):
+    ERASED_TYPE = llmemory.GCREF
+    UNERASED_TYPE = OBJECTPTR
+    def castable(self, TO, var):
+        return lltype.castable(TO, lltype.typeOf(var)) > 0
+
+from pypy.rpython.ootypesystem.ootype import Object
+
+class TestOOtype(BaseTestRErased, OORtypeMixin):
+    ERASED_TYPE = Object
+    UNERASED_TYPE = OBJECT
+    def castable(self, TO, var):
+        return ootype.isSubclass(lltype.typeOf(var), TO)
+    @py.test.mark.xfail
+    def test_prebuilt_erased(self):
+        super(TestOOtype, self).test_prebuilt_erased()
+
+def test_union():
+    s_e1 = SomeErased()
+    s_e1.const = 1
+    s_e2 = SomeErased()
+    s_e2.const = 3
+    assert not annmodel.pair(s_e1, s_e2).union().is_constant()
+
+# ____________________________________________________________
+
+def test_erasing_pair():
+    erase, unerase = new_erasing_pair("test1")
+    class X:
+        pass
+    x = X()
+    erased = erase(x)
+    assert unerase(erased) is x
+    #
+    erase2, unerase2 = new_erasing_pair("test2")
+    py.test.raises(AssertionError, unerase2, erased)

pypy/rpython/llinterp.py

         except ValueError:
             self.make_llexception()
 
+    def op_oobox_int(self, i):
+        return ootype.oobox_int(i)
+
+    def op_oounbox_int(self, x):
+        return ootype.oounbox_int(x)
+
 class Tracer(object):
     Counter = 0
     file = None

pypy/rpython/lltypesystem/lloperation.py

     'classof':              LLOp(oo=True, canfold=True),
     'subclassof':           LLOp(oo=True, canfold=True),
     'oostring':             LLOp(oo=True, sideeffects=False),
+    'oobox_int':            LLOp(oo=True, sideeffects=False),
+    'oounbox_int':          LLOp(oo=True, sideeffects=False),
     'ooparse_int':          LLOp(oo=True, canraise=(ValueError,)),
     'ooparse_float':        LLOp(oo=True, canraise=(ValueError,)),
     'oounicode':            LLOp(oo=True, canraise=(UnicodeDecodeError,)),

pypy/rpython/ootypesystem/ooopimpl.py

 # ____________________________________________________________
 # Implementation of the 'canfold' oo operations
 
-
 def op_ooupcast(INST, inst):
     return ootype.ooupcast(INST, inst)
 op_ooupcast.need_result_type = True

pypy/rpython/ootypesystem/ootype.py

     assert typeOf(obj) is Object
     return obj._cast_to(EXPECTED_TYPE)
 
+class Box(_object):
+    def __init__(self, i):
+        self._TYPE = Object
+        self.i = i
+
+def oobox_int(i):
+    return Box(i)
+
+def oounbox_int(x):
+    return x.i
+
 def oostring(obj, base):
     """
     Convert char, int, float, instances and str to str.

pypy/rpython/ootypesystem/rdict.py

         methodname = None
     return fn, v_obj, methodname
 
-def rtype_r_dict(hop):
+def rtype_r_dict(hop, i_force_non_null=None):
     from pypy.rlib import jit
 
     r_dict = hop.r_result

pypy/rpython/test/test_rint.py

 from pypy.rlib import objectmodel
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.lltypesystem.lloperation import llop
 
 class TestSnippet(object):
 
     pass
 
 class TestOOtype(BaseTestRint, OORtypeMixin):
-    pass
+    def test_oobox_int(self):
+        def f():
+            x = llop.oobox_int(ootype.Object, 42)
+            return llop.oounbox_int(lltype.Signed, x)
+        assert self.interpret(f, []) == 42

pypy/translator/cli/metavm.py

 from pypy.translator.cli import oopspec
 from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.lltypesystem import rffi
+from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.translator.oosupport.metavm import Generator, InstructionList, MicroInstruction,\
      PushAllArgs, StoreResult, GetField, SetField, DownCast
 from pypy.translator.oosupport.metavm import _Call as _OOCall
         generator.load(v_obj)
         generator.ilasm.opcode('unbox.any', boxtype)
 
+class _UnboxType(MicroInstruction):
+    def __init__(self, TO):
+        self.TO = TO
+
+    def render(self, generator, op):
+        v_obj, = op.args
+        boxtype = generator.cts.lltype_to_cts(self.TO)
+        generator.load(v_obj)
+        generator.ilasm.opcode('unbox.any', boxtype)
+
 class _NewArray(MicroInstruction):
     def render(self, generator, op):
         v_type, v_length = op.args
 #CastWeakAdrToPtr = _CastWeakAdrToPtr()
 Box = _Box()
 Unbox = _Unbox()
+UnboxInt = _UnboxType(lltype.Signed)
 NewArray = _NewArray()
 GetArrayElem = _GetArrayElem()
 SetArrayElem = _SetArrayElem()

pypy/translator/cli/opcodes.py

      IndirectCall, GetField, SetField, DownCast, NewCustomDict,\
      MapException, Box, Unbox, NewArray, GetArrayElem, SetArrayElem,\
      TypeOf, CastPrimitive, EventHandler, GetStaticField, SetStaticField, \
-     DebugPrint
+     DebugPrint, UnboxInt
 from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
     New, RuntimeNew, CastTo, PushPrimitive, OOString, OOUnicode, OONewArray
 from pypy.translator.cli.cts import WEAKREF
     'cast_from_object':         [DownCast],
     'clibox':                   [Box],
     'cliunbox':                 [Unbox],
+    'oobox_int':                [Box],
+    'oounbox_int':              [UnboxInt],
     'cli_newarray':             [NewArray],
     'cli_getelem':              [GetArrayElem],
     'cli_setelem':              [SetArrayElem],
     'debug_fatalerror':         [PushAllArgs, 'call void [pypylib]pypy.runtime.Debug::DEBUG_FATALERROR(string)'],
     'keepalive':                Ignore,
     'jit_marker':               Ignore,
+    'jit_force_quasi_immutable':Ignore,
     'jit_force_virtualizable':  Ignore,
     'jit_force_virtual':        DoNothing,
     }

pypy/translator/cli/test/test_int.py

 import py
 from pypy.translator.cli.test.runtest import CliTest
-from pypy.rpython.test.test_rint import BaseTestRint
+from pypy.rpython.test.test_rint import TestOOtype as _TestOOtype # so py.test won't run the base test
 
-class TestCliInt(CliTest, BaseTestRint):
+class TestCliInt(CliTest, _TestOOtype):
     def test_char_constant(self):
         def dummyfn(i):
             return chr(i)

pypy/translator/jvm/opcodes.py

     'oosend':                   [JvmCallMethod, StoreResult],
     'ooupcast':                 DoNothing,
     'oodowncast':               [DownCast, StoreResult],
+    'oobox_int':                jvm.PYPYBOXINT,
+    'oounbox_int':              jvm.PYPYUNBOXINT,
     'cast_to_object':           DoNothing,
     'cast_from_object':         [DownCast, StoreResult],
     'instanceof':               [CastTo, StoreResult],

pypy/translator/jvm/src/pypy/PyPy.java

         return result;
     }
 
+    public static Object box_integer(int x) {
+        return new Integer(x);
+    }
+
+    public static int unbox_integer(Object o) {
+        Integer x = (Integer)o;
+        return x.intValue();
+    }
     // Used in testing the JVM backend:
     //
     //    A series of methods which serve a similar purpose to repr() in Python:

pypy/translator/jvm/test/test_int.py

 import py
 from pypy.translator.jvm.test.runtest import JvmTest
 from pypy.rpython.test.test_rint import BaseTestRint
+from pypy.rpython.test.test_rint import TestOOtype as _TestOOtype # so py.test won't run the base test
 
 # ====> ../../../rpython/test/test_rint.py
 
-class TestJvmInt(JvmTest, BaseTestRint):
+class TestJvmInt(JvmTest, _TestOOtype):
     def test_char_constant(self):
         def dummyfn(i):
             return chr(i)

pypy/translator/jvm/typesystem.py

 PYPYRUNTIMENEW =        Method.s(jPyPy, 'RuntimeNew', (jClass,), jObject)
 PYPYSTRING2BYTES =      Method.s(jPyPy, 'string2bytes', (jString,), jByteArray)
 PYPYARRAYTOLIST =       Method.s(jPyPy, 'array_to_list', (jObjectArray,), jArrayList)
+PYPYBOXINT =            Method.s(jPyPy, 'box_integer', (jInt,), jObject)
+PYPYUNBOXINT =          Method.s(jPyPy, 'unbox_integer', (jObject,), jInt)
 PYPYOOPARSEFLOAT =      Method.v(jPyPy, 'ooparse_float', (jString,), jDouble)
 OBJECTGETCLASS =        Method.v(jObject, 'getClass', (), jClass)
 CLASSGETNAME =          Method.v(jClass, 'getName', (), jString)

pypy/translator/oosupport/test_template/operations.py

+from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.ootypesystem import ootype
 from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, ovfcheck
 from pypy.rlib import rstack
 from pypy.annotation import model as annmodel
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.