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

arigo at codespeak.net arigo at codespeak.net
Tue Oct 18 12:32:44 CEST 2005


Author: arigo
Date: Tue Oct 18 12:32:43 2005
New Revision: 18734

Added:
   pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
Modified:
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/ootypesystem/ootype.py
   pypy/dist/pypy/rpython/ootypesystem/rclass.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
Log:
ootyper: isinstance() support (including much confusion about ootype.Class,
Instance, _class, _instance, _INSTANCE, etc.)



Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Tue Oct 18 12:32:43 2005
@@ -656,6 +656,9 @@
         assert isinstance(inst, ootype._instance)
         return bool(inst)
 
+    def op_instanceof(self, inst, INST):
+        return ootype.instanceof(inst, INST)
+
 # by default we route all logging messages to nothingness
 # e.g. tests can then switch on logging to get more help
 # for failing tests

Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py	Tue Oct 18 12:32:43 2005
@@ -255,7 +255,11 @@
     return INSTANCE._null
 
 def instanceof(inst, INSTANCE):
-    return isSubclass(inst._TYPE, INSTANCE)
+    # this version of instanceof() accepts a NULL instance and always
+    # returns False in this case.
+    assert isinstance(inst, _instance)
+    assert isinstance(INSTANCE, Instance)
+    return bool(inst) and isSubclass(inst._TYPE, INSTANCE)
 
 def classof(inst):
     return runtimeClass(inst._TYPE)

Added: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py	Tue Oct 18 12:32:43 2005
@@ -0,0 +1,28 @@
+from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.ootypesystem import rclass
+from pypy.objspace.flow.model import Constant
+
+
+def rtype_builtin_isinstance(hop):
+    if hop.s_result.is_constant():
+        return hop.inputconst(lltype.Bool, hop.s_result.const)
+
+    if hop.args_s[1].is_constant() and hop.args_s[1].const == list:
+        if hop.args_s[0].knowntype != list:
+            raise TyperError("isinstance(x, list) expects x to be known statically to be a list or None")
+        raise TyperError("XXX missing impl of isinstance(x, list)")
+
+    class_repr = rclass.get_type_repr(hop.rtyper)
+    instance_repr = hop.args_r[0]
+    assert isinstance(instance_repr, rclass.InstanceRepr)
+
+    v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
+    if isinstance(v_cls, Constant):
+        c_cls = hop.inputconst(ootype.Void, v_cls.value._INSTANCE)
+        return hop.genop('instanceof', [v_obj, c_cls], resulttype=ootype.Bool)
+    else:
+        raise TyperError("XXX missing impl of isinstance(x, variable)")
+
+
+BUILTIN_TYPER = {}
+BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance

Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py	Tue Oct 18 12:32:43 2005
@@ -1,6 +1,7 @@
+import types
 from pypy.rpython.rmodel import inputconst
 from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \
-                                getinstancerepr, getclassrepr
+                                getinstancerepr, getclassrepr, get_type_repr
 from pypy.rpython.rpbc import getsignature
 from pypy.rpython.ootypesystem import ootype
 from pypy.annotation.pairtype import pairtype
@@ -17,9 +18,19 @@
     def _setup_repr(self):
         pass # not actually needed?
 
-    def convert_const(self):
-        # FIXME
-        pass
+    def convert_const(self, value):
+        if not isinstance(value, (type, types.ClassType)):
+            raise TyperError("not a class: %r" % (value,))
+        try:
+            subclassdef = self.rtyper.annotator.getuserclasses()[value]
+        except KeyError:
+            raise TyperError("no classdef: %r" % (value,))
+        if self.classdef is not None:
+            if self.classdef.commonbase(subclassdef) != self.classdef:
+                raise TyperError("not a subclass of %r: %r" % (
+                    self.classdef.cls, value))
+        #
+        return getinstancerepr(self.rtyper, subclassdef).lowleveltype._class
 
 
 def mangle(name):
@@ -179,7 +190,7 @@
 
     def convert_const(self, value):
         if value is None:
-            return null(self.lowleveltype)
+            return ootype.null(self.lowleveltype)
         try:
             classdef = self.rtyper.annotator.getuserclasses()[value.__class__]
         except KeyError:

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py	Tue Oct 18 12:32:43 2005
@@ -212,3 +212,29 @@
     assert res is False
     res = interpret(dummyfn, [False], type_system='ootype')
     assert res is True
+
+def test_isinstance():
+    class A:
+        pass
+    class B(A):
+        pass
+    class C(B):
+        pass
+    def f(i):
+        if i == 0:
+            o = None
+        elif i == 1:
+            o = A()
+        elif i == 2:
+            o = B()
+        else:
+            o = C()
+        return 100*isinstance(o, A)+10*isinstance(o, B)+1*isinstance(o ,C)
+    res = interpret(f, [1], type_system='ootype')
+    assert res == 100
+    res = interpret(f, [2], type_system='ootype')
+    assert res == 110
+    res = interpret(f, [3], type_system='ootype')
+    assert res == 111
+    res = interpret(f, [0], type_system='ootype')
+    assert res == 0



More information about the Pypy-commit mailing list