[pypy-svn] r40985 - in pypy/dist/pypy: jit/codegen/dump/test jit/codegen/i386/test jit/hintannotator jit/timeshifter jit/timeshifter/test module/pypyjit module/pypyjit/test objspace/std

arigo at codespeak.net arigo at codespeak.net
Wed Mar 21 22:30:33 CET 2007


Author: arigo
Date: Wed Mar 21 22:30:31 2007
New Revision: 40985

Added:
   pypy/dist/pypy/module/pypyjit/newbool.py   (contents, props changed)
   pypy/dist/pypy/module/pypyjit/test/test_newbool.py   (contents, props changed)
Modified:
   pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py
   pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
   pypy/dist/pypy/jit/hintannotator/annotator.py
   pypy/dist/pypy/jit/hintannotator/bookkeeper.py
   pypy/dist/pypy/jit/timeshifter/hrtyper.py
   pypy/dist/pypy/jit/timeshifter/rcontainer.py
   pypy/dist/pypy/jit/timeshifter/rtimeshift.py
   pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
   pypy/dist/pypy/jit/timeshifter/vdict.py
   pypy/dist/pypy/objspace/std/boolobject.py
   pypy/dist/pypy/objspace/std/noneobject.py
   pypy/dist/pypy/objspace/std/objspace.py
Log:
(the jit band)

Special support for newbool(), linked from pypyjit with the timeshifter.
Returns a VirtualBool which simply stores the boolean value.
Not integrated with "translate --jit" yet.



Modified: pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py	Wed Mar 21 22:30:31 2007
@@ -1,5 +1,6 @@
 import py
 from pypy.jit.codegen.dump.rgenop import RDumpGenOp
+from pypy.jit.timeshifter.test.test_timeshift import Whatever
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests, FUNC, FUNC2
 from ctypes import cast, c_int, c_void_p, CFUNCTYPE
@@ -17,12 +18,3 @@
 
     # for the individual tests see
     # ====> ../../test/rgenop_tests.py
-
-
-class Whatever(object):
-    def __eq__(self, other):
-        return True
-    def __ne__(self, other):
-        return False
-    def __and__(self, other):
-        return Whatever()      # for test_ovfcheck_adder_direct

Modified: pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py	Wed Mar 21 22:30:31 2007
@@ -1,6 +1,7 @@
 import os, py
 from pypy.annotation import model as annmodel
 from pypy.jit.timeshifter.test import test_timeshift
+from pypy.jit.timeshifter.test.test_timeshift import Whatever
 from pypy.jit.codegen.i386.rgenop import RI386GenOp, IntConst
 from pypy.jit.codegen.i386.test.test_operation import RGenOpPacked
 from pypy.jit.codegen.i386.conftest import option
@@ -9,10 +10,6 @@
     if not option.interp:
         py.test.skip("these tests take ages and are not really useful")
 
-class Whatever(object):
-    def __eq__(self, other):
-        return True
-
 class I386LLInterpTimeshiftingTestMixin(object):
     class RGenOp(RGenOpPacked):
         from pypy.jit.codegen.i386.codebuf import LLTypeMachineCodeBlock \

Modified: pypy/dist/pypy/jit/hintannotator/annotator.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/annotator.py	(original)
+++ pypy/dist/pypy/jit/hintannotator/annotator.py	Wed Mar 21 22:30:31 2007
@@ -9,13 +9,19 @@
 
 
 class HintAnnotatorPolicy(policy.AnnotatorPolicy):
-
-    def __init__(self, novirtualcontainer     = False,
-                       oopspec                = False,
-                       entrypoint_returns_red = True):
-        self.novirtualcontainer     = novirtualcontainer
-        self.oopspec                = oopspec
-        self.entrypoint_returns_red = entrypoint_returns_red
+    novirtualcontainer     = False
+    oopspec                = False
+    entrypoint_returns_red = True
+
+    def __init__(self, novirtualcontainer     = None,
+                       oopspec                = None,
+                       entrypoint_returns_red = None):
+        if novirtualcontainer is not None:
+            self.novirtualcontainer = novirtualcontainer
+        if oopspec is not None:
+            self.oopspec = oopspec
+        if entrypoint_returns_red is not None:
+            self.entrypoint_returns_red = entrypoint_returns_red
 
     def look_inside_graph(self, graph):
         return True
@@ -23,10 +29,10 @@
 
 class StopAtXPolicy(HintAnnotatorPolicy):
     """Useful for tests."""
+    novirtualcontainer = True
+    oopspec = True
 
     def __init__(self, *funcs):
-        HintAnnotatorPolicy.__init__(self, novirtualcontainer=True,
-                                     oopspec=True)
         self.funcs = funcs
 
     def look_inside_graph(self, graph):

Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/bookkeeper.py	(original)
+++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py	Wed Mar 21 22:30:31 2007
@@ -97,13 +97,13 @@
         newstartblock.closeblock(Link([v_res], newgraph.returnblock))
         return newgraph
 
-    def build_metacall_graph(self, origgraph, metafunc):
+    def build_metacall_graph(self, origgraph, metadesccls):
         args_v = [copyvar(None, v) for v in origgraph.getargs()]
         v_res = copyvar(None, origgraph.getreturnvar())
-        v_metafunc = Constant(metafunc, lltype.Void)
+        v_metadesccls = Constant(metadesccls, lltype.Void)
         newstartblock = Block(args_v)
         newstartblock.operations.append(
-            SpaceOperation('ts_metacall', [v_metafunc] + args_v, v_res))
+            SpaceOperation('ts_metacall', [v_metadesccls] + args_v, v_res))
         newgraph = FunctionGraph('%s_ts_metacall' % (origgraph.name,),
                                  newstartblock)
         newgraph.getreturnvar().concretetype = v_res.concretetype

Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py	Wed Mar 21 22:30:31 2007
@@ -685,7 +685,9 @@
         args_r = [self.getredrepr(originalconcretetype(hs))
                   for hs in hop.args_s[1:]]
         vlist = hop.inputargs(lltype.Void, *args_r)
-        metafunc = vlist[0].value
+        metadesccls = vlist[0].value
+        metadesc = metadesccls(self)
+        metafunc = metadesc.metafunc
         v_jitstate = hop.llops.getjitstate()
         return hop.llops.genmixlevelhelpercall(metafunc,
                             [self.s_JITState] + [self.s_RedBox] * nb_args,

Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py	Wed Mar 21 22:30:31 2007
@@ -26,13 +26,17 @@
 
 
 class VirtualContainer(AbstractContainer):
-    _attrs_ = []
+    _attrs_ = ('ownbox',)
 
     allowed_in_virtualizable = False
 
     def setforced(self, _):
         raise NotImplementedError
 
+    def op_ptreq(self, jitstate, otherbox, reverse):
+        equal = self is otherbox.content
+        return rvalue.ll_fromvalue(jitstate, equal ^ reverse)
+
 
 class FrozenContainer(AbstractContainer):
     _attrs_ = []
@@ -465,7 +469,7 @@
         #self.fz_content_boxes initialized later
 
     def exactmatch(self, vstruct, outgoingvarboxes, memo):
-        assert isinstance(vstruct, VirtualStruct)
+        assert isinstance(vstruct, VirtualContainer)
         contmemo = memo.containers
         if self in contmemo:
             ok = vstruct is contmemo[self]
@@ -476,7 +480,8 @@
             assert contmemo[vstruct] is not self
             outgoingvarboxes.append(vstruct.ownbox)
             return False
-        if self.typedesc is not vstruct.typedesc:
+        if (not isinstance(vstruct, VirtualStruct)
+            or self.typedesc is not vstruct.typedesc):
             if not memo.force_merge:
                 raise rvalue.DontMerge
             outgoingvarboxes.append(vstruct.ownbox)
@@ -511,7 +516,7 @@
 
 
 class VirtualStruct(VirtualContainer):
-    _attrs_ = "typedesc content_boxes ownbox".split()
+    _attrs_ = "typedesc content_boxes".split()
 
     allowed_in_virtualizable = True
     
@@ -842,7 +847,17 @@
             gv_ptr = self.getgenvar(jitstate)
             fielddesc.generate_set(jitstate, gv_ptr,
                                    valuebox.getgenvar(jitstate))
-            
+
+    def op_ptreq(self, jitstate, otherbox, reverse):
+        if self is otherbox.content:
+            answer = True
+        else:
+            gv_outside = self.content_boxes[-1].genvar
+            if gv_outside is self.typedesc.gv_null:
+                answer = False
+            else:
+                return None   # fall-back
+        return rvalue.ll_fromvalue(jitstate, answer ^ reverse)
 
 # patching VirtualStructCls
 StructTypeDesc.VirtualStructCls = VirtualStruct

Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py	Wed Mar 21 22:30:31 2007
@@ -228,15 +228,18 @@
 
 def ll_genptreq(jitstate, argbox0, argbox1, reverse):
     builder = jitstate.curbuilder
-    # XXX this assumption is not completely valid in the presence
-    # of virtualizable
-    if argbox0.content is not None or argbox1.content is not None:
-        equal = argbox0.content is argbox1.content
-        return rvalue.ll_fromvalue(jitstate, equal ^ reverse)
-    elif argbox0.is_constant() and argbox1.is_constant():
+    if argbox0.is_constant() and argbox1.is_constant():
         addr0 = rvalue.ll_getvalue(argbox0, llmemory.Address)
         addr1 = rvalue.ll_getvalue(argbox1, llmemory.Address)
         return rvalue.ll_fromvalue(jitstate, (addr0 == addr1) ^ reverse)
+    if argbox0.content is not None:
+        resultbox = argbox0.content.op_ptreq(jitstate, argbox1, reverse)
+        if resultbox is not None:
+            return resultbox
+    if argbox1.content is not None:
+        resultbox = argbox1.content.op_ptreq(jitstate, argbox0, reverse)
+        if resultbox is not None:
+            return resultbox
     gv_addr0 = argbox0.getgenvar(jitstate)
     gv_addr1 = argbox1.getgenvar(jitstate)
     if reverse:

Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	Wed Mar 21 22:30:31 2007
@@ -12,7 +12,7 @@
 from pypy.rlib.objectmodel import hint, keepalive_until_here, debug_assert
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.rarithmetic import ovfcheck
-from pypy.rpython.annlowlevel import PseudoHighLevelCallable
+from pypy.rpython.annlowlevel import PseudoHighLevelCallable, cachedtype
 from pypy.rpython.module.support import LLSupport
 from pypy.annotation import model as annmodel
 from pypy.rpython.llinterp import LLInterpreter, LLException
@@ -23,6 +23,17 @@
 
 P_NOVIRTUAL = HintAnnotatorPolicy(novirtualcontainer=True)
 
+
+class Whatever(object):
+    """To cheat in the tests that have no way to do the right thing."""
+    def __eq__(self, other):
+        return True
+    def __ne__(self, other):
+        return False
+    def __and__(self, other):
+        return Whatever()     # for test_ovfcheck_adder_direct in codegen.dump
+
+
 def getargtypes(annotator, values):
     return [annotation(annotator, x) for x in values]
 
@@ -1640,11 +1651,20 @@
 
     def test_substitute_graph(self):
 
-        def h(jitstate, mbox):
-            from pypy.jit.timeshifter.rvalue import IntRedBox
-            builder = jitstate.curbuilder
-            gv_result = builder.genop1("int_neg", mbox.getgenvar(jitstate))
-            return IntRedBox(mbox.kind, gv_result)
+        class MetaG:
+            __metaclass__ = cachedtype
+
+            def __init__(self, hrtyper):
+                pass
+
+            def _freeze_(self):
+                return True
+
+            def metafunc(self, jitstate, mbox):
+                from pypy.jit.timeshifter.rvalue import IntRedBox
+                builder = jitstate.curbuilder
+                gv_result = builder.genop1("int_neg", mbox.getgenvar(jitstate))
+                return IntRedBox(mbox.kind, gv_result)
 
         def g(m):
             return m + 17
@@ -1655,7 +1675,7 @@
         class MyPolicy(HintAnnotatorPolicy):
             def look_inside_graph(self, graph):
                 if graph.func is g:
-                    return h     # replaces g with a meta-call to h...
+                    return MetaG   # replaces g with a meta-call to metafunc()
                 else:
                     return True
 

Modified: pypy/dist/pypy/jit/timeshifter/vdict.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vdict.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/vdict.py	Wed Mar 21 22:30:31 2007
@@ -183,7 +183,7 @@
 
 
 class AbstractVirtualDict(VirtualContainer):
-    _attrs_ = ('typedesc', 'ownbox')     # and no item_boxes
+    _attrs_ = ('typedesc',)     # and no item_boxes
 
     FrozenVirtualDict = AbstractFrozenVirtualDict    # overridden in subclasses
 

Added: pypy/dist/pypy/module/pypyjit/newbool.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/pypyjit/newbool.py	Wed Mar 21 22:30:31 2007
@@ -0,0 +1,204 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.annlowlevel import cachedtype
+from pypy.annotation import model as annmodel
+from pypy.jit.timeshifter import rvalue, rcontainer
+from pypy.objspace.std.boolobject import W_BoolObject
+
+
+class NewBoolDesc:
+    __metaclass__ = cachedtype
+
+    def __init__(self, hrtyper):
+        self.hrtyper = hrtyper
+        RGenOp = hrtyper.RGenOp
+        rtyper = hrtyper.rtyper
+        bk = rtyper.annotator.bookkeeper
+        s_w_bool = annmodel.unionof(bk.immutablevalue(W_BoolObject.w_False),
+                                    bk.immutablevalue(W_BoolObject.w_True))
+        r_w_bool = rtyper.getrepr(s_w_bool)
+        self.ll_False = r_w_bool.convert_const(W_BoolObject.w_False)
+        self.ll_True  = r_w_bool.convert_const(W_BoolObject.w_True)
+
+        A = lltype.FixedSizeArray(lltype.typeOf(self.ll_False), 2)
+        self.ll_bools = lltype.malloc(A, immortal=True)
+        self.ll_bools[0] = self.ll_False
+        self.ll_bools[1] = self.ll_True
+        self.gv_bools = RGenOp.constPrebuiltGlobal(self.ll_bools)
+        self.boolsToken = RGenOp.arrayToken(A)
+
+        self.bools_gv = [RGenOp.constPrebuiltGlobal(self.ll_False),
+                         RGenOp.constPrebuiltGlobal(self.ll_True)]
+
+        self.ptrkind = RGenOp.kindToken(r_w_bool.lowleveltype)
+        self.boolkind = RGenOp.kindToken(lltype.Bool)
+
+        ll_BoolObject = r_w_bool.rclass.getvtable()
+        self.BoolObjectBox = rvalue.redbox_from_prebuilt_value(RGenOp,
+                                                               ll_BoolObject)
+
+        self.Falsebox = rvalue.redbox_from_prebuilt_value(RGenOp, False)
+        self.Truebox = rvalue.redbox_from_prebuilt_value(RGenOp, True)
+        self.boolboxes = [self.Falsebox, self.Truebox]
+
+    def _freeze_(self):
+        return True
+
+    def vboolfactory(self):
+        vbool = VirtualBool(self)
+        box = rvalue.PtrRedBox(self.ptrkind, known_nonzero=True)
+        box.content = vbool
+        vbool.ownbox = box
+        return vbool
+
+    def metafunc(self, jitstate, valuebox):
+        vbool = self.vboolfactory()
+        vbool.valuebox = valuebox
+        return vbool.ownbox
+
+    def getboolbox(self, jitstate, gv_bool, reverse=False):
+        if gv_bool.is_const:
+            flag = gv_bool.revealconst(lltype.Bool)
+            return self.boolboxes[flag ^ reverse]
+        else:
+            if reverse:
+                gv_bool = jitstate.curbuilder.genop1("bool_not", gv_bool)
+            return rvalue.IntRedBox(self.boolkind, gv_bool)
+
+    def genbooleq(self, jitstate, gv_bool1, gv_bool2, reverse=False):
+        if gv_bool1.is_const:
+            reverse ^= not gv_bool1.revealconst(lltype.Bool)
+            return self.getboolbox(jitstate, gv_bool2, reverse)
+        elif gv_bool2.is_const:
+            reverse ^= not gv_bool2.revealconst(lltype.Bool)
+            return self.getboolbox(jitstate, gv_bool1, reverse)
+        else:
+            # XXX maybe gv_bool1 == gv_bool2 :-)
+            curbuilder = jitstate.curbuilder
+            gv_int1 = curbuilder.genop1("cast_bool_to_int", gv_bool1)
+            gv_int2 = curbuilder.genop1("cast_bool_to_int", gv_bool2)
+            if reverse:
+                gv_res = curbuilder.genop2("int_ne", gv_int1, gv_int2)
+            else:
+                gv_res = curbuilder.genop2("int_eq", gv_int1, gv_int2)
+            return rvalue.IntRedBox(self.boolkind, gv_res)
+
+
+class VirtualBool(rcontainer.VirtualContainer):
+
+    def __init__(self, newbooldesc):
+        self.newbooldesc = newbooldesc
+        #self.valuebox = ... set independently
+
+    def enter_block(self, incoming, memo):
+        contmemo = memo.containers
+        if self not in contmemo:
+            contmemo[self] = None
+            self.valuebox.enter_block(incoming, memo)
+
+    def force_runtime_container(self, jitstate):
+        desc = self.newbooldesc
+        valuebox = self.valuebox
+        if valuebox.is_constant():
+            value = valuebox.genvar.revealconst(lltype.Bool)
+            genvar = desc.bools_gv[value]
+        else:
+            gv_index = valuebox.getgenvar(jitstate)
+            gv_index = jitstate.curbuilder.genop1("cast_bool_to_int", gv_index)
+            genvar = jitstate.curbuilder.genop_getarrayitem(
+                desc.boolsToken,
+                desc.gv_bools,
+                gv_index)
+        self.ownbox.setgenvar_hint(genvar, known_nonzero=True)
+        self.ownbox.content = None
+
+    def freeze(self, memo):
+        contmemo = memo.containers
+        assert self not in contmemo     # contmemo no longer used
+        result = contmemo[self] = FrozenBool(self.newbooldesc)
+        frozenbox = self.valuebox.freeze(memo)
+        result.fz_valuebox = frozenbox
+        return result
+
+    def copy(self, memo):
+        contmemo = memo.containers
+        assert self not in contmemo     # contmemo no longer used
+        result = contmemo[self] = VirtualBool(self.newbooldesc)
+        result.valuebox = self.valuebox.copy(memo)
+        result.ownbox = self.ownbox.copy(memo)
+        return result
+
+    def replace(self, memo):
+        contmemo = memo.containers
+        assert self not in contmemo     # contmemo no longer used
+        contmemo[self] = None
+        self.valuebox = self.valuebox.replace(memo)
+        self.ownbox = self.ownbox.replace(memo)
+
+    def op_getfield(self, jitstate, fielddesc):
+        if fielddesc.fieldindex == 0:     # the __class__ field
+            return self.newbooldesc.BoolObjectBox
+        else:
+            # assume it is the 'boolval' field
+            return self.valuebox
+
+    def op_ptreq(self, jitstate, otherbox, reverse):
+        desc = self.newbooldesc
+        if otherbox.is_constant():
+            addr = otherbox.genvar.revealconst(llmemory.Address)
+            if addr == llmemory.cast_ptr_to_adr(desc.ll_False):
+                return desc.getboolbox(jitstate, self.valuebox.genvar,
+                                       not reverse)
+            elif addr == llmemory.cast_ptr_to_adr(desc.ll_True):
+                return desc.getboolbox(jitstate, self.valuebox.genvar,
+                                       reverse)
+            else:
+                return desc.boolboxes[False ^ reverse]
+
+        othercontent = otherbox.content
+        if not isinstance(othercontent, VirtualBool):
+            return None     # no clue
+
+        return desc.genbooleq(jitstate,
+                              self.valuebox.genvar,
+                              othercontent.valuebox.genvar,
+                              reverse)
+
+
+class FrozenBool(rcontainer.FrozenContainer):
+
+    def __init__(self, newbooldesc):
+        self.newbooldesc = newbooldesc
+        #self.fz_valuebox initialized later
+
+    def exactmatch(self, vstruct, outgoingvarboxes, memo):
+        # XXX code duplication with rcontainer...
+        contmemo = memo.containers
+        if self in contmemo:
+            ok = vstruct is contmemo[self]
+            if not ok:
+                outgoingvarboxes.append(vstruct.ownbox)
+            return ok
+        if vstruct in contmemo:
+            assert contmemo[vstruct] is not self
+            outgoingvarboxes.append(vstruct.ownbox)
+            return False
+        if not isinstance(vstruct, VirtualBool):
+            if not memo.force_merge:
+                raise rvalue.DontMerge
+            outgoingvarboxes.append(vstruct.ownbox)
+            return False
+        contmemo[self] = vstruct
+        contmemo[vstruct] = self
+        return self.fz_valuebox.exactmatch(vstruct.valuebox,
+                                           outgoingvarboxes,
+                                           memo)
+
+    def unfreeze(self, incomingvarboxes, memo):
+        contmemo = memo.containers
+        if self in contmemo:
+            return contmemo[self]
+        vbool = self.newbooldesc.vboolfactory()
+        ownbox = vbool.ownbox
+        contmemo[self] = ownbox
+        vbool.valuebox = self.fz_valuebox.unfreeze(incomingvarboxes, memo)
+        return ownbox

Added: pypy/dist/pypy/module/pypyjit/test/test_newbool.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/pypyjit/test/test_newbool.py	Wed Mar 21 22:30:31 2007
@@ -0,0 +1,214 @@
+from pypy.rpython.lltypesystem import lltype
+from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy
+from pypy.jit.timeshifter import rvalue
+from pypy.jit.timeshifter.test.test_timeshift import Whatever
+from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
+from pypy.jit.codegen.model import GenVar
+from pypy.jit.codegen.llgraph.rgenop import rgenop
+from pypy.module.pypyjit.newbool import NewBoolDesc
+
+
+class DummyDesc(NewBoolDesc):
+    def __init__(self):
+        self.boolkind = rgenop.kindToken(lltype.Bool)
+        self.boolboxes = [rvalue.redbox_from_prebuilt_value(rgenop, False),
+                          rvalue.redbox_from_prebuilt_value(rgenop, True)]
+
+desc = DummyDesc()
+
+
+class DummyJITState:
+    def __init__(self):
+        self.curbuilder = DummyBuilder()
+
+
+class DummyBuilder:
+    def __init__(self):
+        self.operations = []
+
+    def genop1(self, opname, gv_arg):
+        gv_res = GenVar()
+        self.operations.append((opname, gv_arg, gv_res))
+        return gv_res
+
+    def genop2(self, opname, gv_arg1, gv_arg2):
+        gv_res = GenVar()
+        self.operations.append((opname, gv_arg1, gv_arg2, gv_res))
+        return gv_res
+
+
+def test_getboolbox():
+    for b1 in [False, True]:
+        for b2 in [False, True]:
+            jitstate = DummyJITState()
+            box = desc.getboolbox(jitstate, rgenop.genconst(b1), b2)
+            assert box.genvar.revealconst(lltype.Bool) == b1 ^ b2
+            assert not jitstate.curbuilder.operations
+
+    gv1 = GenVar()
+    jitstate = DummyJITState()
+    box = desc.getboolbox(jitstate, gv1, False)
+    assert box.genvar == gv1
+    assert not jitstate.curbuilder.operations
+
+    jitstate = DummyJITState()
+    box = desc.getboolbox(jitstate, gv1, True)
+    assert jitstate.curbuilder.operations == [
+        ("bool_not", gv1, box.genvar),
+        ]
+
+def test_genbooleq():
+    gv1 = GenVar()
+    gv2 = GenVar()
+    gf = rgenop.genconst(False)
+    gt = rgenop.genconst(True)
+
+    for b1 in [False, True]:
+        for b2 in [False, True]:
+            for rev in [False, True]:
+                jitstate = DummyJITState()
+                box = desc.genbooleq(jitstate,
+                                     rgenop.genconst(b1),
+                                     rgenop.genconst(b2),
+                                     rev)
+                assert box.genvar.revealconst(lltype.Bool) == (b1 == b2) ^ rev
+                assert not jitstate.curbuilder.operations
+
+    for b2 in [False, True]:
+        for rev in [False, True]:
+            for flip in [False, True]:
+                jitstate = DummyJITState()
+                args = [gv1, rgenop.genconst(b2), rev]
+                if flip:
+                    args[0], args[1] = args[1], args[0]
+                box = desc.genbooleq(jitstate, *args)
+
+                should_neg = (b2 == rev)
+                if should_neg:
+                    assert jitstate.curbuilder.operations == [
+                        ("bool_not", gv1, box.genvar),
+                        ]
+                else:
+                    assert box.genvar == gv1
+                    assert not jitstate.curbuilder.operations
+
+    for rev in [False, True]:
+        jitstate = DummyJITState()
+        box = desc.genbooleq(jitstate, gv1, gv2, rev)
+        ops = jitstate.curbuilder.operations
+        _, _, gvi1 = ops[0]
+        _, _, gvi2 = ops[1]
+        assert ops == [
+            ("cast_bool_to_int", gv1, gvi1),
+            ("cast_bool_to_int", gv2, gvi2),
+            (["int_eq", "int_ne"][rev], gvi1, gvi2, box.genvar),
+            ]
+
+# ____________________________________________________________
+
+from pypy.objspace.std.boolobject import W_BoolObject
+from pypy.interpreter.baseobjspace import W_Root
+
+def newbool(flag):
+    if flag:
+        return W_BoolObject.w_True
+    else:
+        return W_BoolObject.w_False
+
+class MyPolicy(HintAnnotatorPolicy):
+    novirtualcontainer = True
+    def look_inside_graph(self, graph):
+        if graph.func is newbool:
+            return NewBoolDesc
+        else:
+            return True
+
+
+class TestNewBool(TimeshiftingTests):
+
+    def test_simple(self):
+        def f(n):
+            w_res = newbool(n > 5)
+            return int(w_res.boolval)
+
+        res = self.timeshift(f, [7], policy=MyPolicy())
+        assert res == 1
+        self.check_insns({'int_gt': 1, 'cast_bool_to_int': 1})
+
+    def test_ptreq1(self):
+        def f(n):
+            w_res = newbool(n > 5)
+            return int(w_res is W_BoolObject.w_True)
+
+        res = self.timeshift(f, [3], policy=MyPolicy())
+        assert res == 0
+        self.check_insns({'int_gt': 1, 'cast_bool_to_int': 1})
+
+    def test_ptreq2(self):
+        def f(n):
+            w_res = newbool(n > 5)
+            return int(w_res is W_BoolObject.w_False)
+
+        res = self.timeshift(f, [3], policy=MyPolicy())
+        assert res == 1
+        self.check_insns({'int_gt': 1, 'bool_not': 1, 'cast_bool_to_int': 1})
+
+    def test_force(self):
+        def f(n):
+            w_res = newbool(n > 5)
+            return w_res
+        f.convert_result = lambda res: 'foo'
+
+        res = self.timeshift(f, [3], policy=MyPolicy())
+        self.check_insns({'int_gt': 1,
+                          'cast_bool_to_int': 1, 'getarrayitem': 1,
+                          'cast_pointer': Whatever()})
+
+    def test_merge_bools(self):
+        def f(n):
+            if n > 5:
+                w_res = newbool(n >= 10)
+            else:
+                w_res = newbool(n < -10)
+            return int(w_res.boolval)
+
+        res = self.timeshift(f, [-3], policy=MyPolicy())
+        assert res == 0
+        self.check_insns({'int_gt': 1, 'int_ge': 1, 'int_lt': 1,
+                          'cast_bool_to_int': 1})
+
+    def test_merge_with_virtual_root(self):
+        def f(n):
+            if n > 5:
+                w_res = newbool(n >= 10)
+            else:
+                w_res = W_Root()
+            return w_res
+        f.convert_result = lambda res: 'foo'
+
+        res = self.timeshift(f, [-3], policy=MyPolicy())
+        self.check_insns({'int_gt': 1, 'int_ge': 1,
+                          'cast_bool_to_int': 1, 'getarrayitem': 1,
+                          'malloc': 1, 'setfield': 1,
+                          'cast_pointer': Whatever()})
+
+    def test_ptreq3(self):
+        def f(n):
+            w1 = newbool(n >= 10)
+            w2 = W_Root()
+            return int(w1 is w2) + int(w2 is w1)
+
+        res = self.timeshift(f, [123], policy=MyPolicy())
+        assert res == 0
+        self.check_insns({'int_ge': 1})
+
+    def test_ptreq4(self):
+        w2 = W_Root()
+
+        def f(n):
+            w1 = newbool(n >= 10)
+            return int(w1 is w2) + int(w2 is w1)
+
+        res = self.timeshift(f, [123], policy=MyPolicy())
+        assert res == 0
+        self.check_insns({'int_ge': 1})

Modified: pypy/dist/pypy/objspace/std/boolobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/boolobject.py	(original)
+++ pypy/dist/pypy/objspace/std/boolobject.py	Wed Mar 21 22:30:31 2007
@@ -20,6 +20,9 @@
 
 registerimplementation(W_BoolObject)
 
+W_BoolObject.w_False = W_BoolObject(False)
+W_BoolObject.w_True  = W_BoolObject(True)
+
 # bool-to-int delegation requires translating the .boolvar attribute
 # to an .intval one
 def delegate_Bool2IntObject(space, w_bool):

Modified: pypy/dist/pypy/objspace/std/noneobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/noneobject.py	(original)
+++ pypy/dist/pypy/objspace/std/noneobject.py	Wed Mar 21 22:30:31 2007
@@ -14,6 +14,8 @@
 
 registerimplementation(W_NoneObject)
 
+W_NoneObject.w_None = W_NoneObject()
+
 def nonzero__None(space, w_none):
     return space.w_False
 

Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py	(original)
+++ pypy/dist/pypy/objspace/std/objspace.py	Wed Mar 21 22:30:31 2007
@@ -166,9 +166,9 @@
             globals()[cls.__name__] = cls
 
         # singletons
-        self.w_None  = W_NoneObject()
-        self.w_False = W_BoolObject(False)
-        self.w_True  = W_BoolObject(True)
+        self.w_None  = W_NoneObject.w_None
+        self.w_False = W_BoolObject.w_False
+        self.w_True  = W_BoolObject.w_True
         from pypy.interpreter.special import NotImplemented, Ellipsis
         self.w_NotImplemented = self.wrap(NotImplemented(self))  
         self.w_Ellipsis = self.wrap(Ellipsis(self))  



More information about the Pypy-commit mailing list