Author: Antonio Cuni <[email protected]>
Branch: jitypes2
Changeset: r44209:071205420fb5
Date: 2011-05-16 15:32 +0200
http://bitbucket.org/pypy/pypy/changeset/071205420fb5/

Log:    hg merge default

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -24,6 +24,8 @@
 ^pypy/translator/c/src/libffi_msvc/.+\.dll$
 ^pypy/translator/c/src/libffi_msvc/.+\.lib$
 ^pypy/translator/c/src/libffi_msvc/.+\.exp$
+^pypy/translator/c/src/cjkcodecs/.+\.o$
+^pypy/translator/c/src/cjkcodecs/.+\.obj$
 ^pypy/translator/jvm/\.project$
 ^pypy/translator/jvm/\.classpath$
 ^pypy/translator/jvm/eclipse-bin$
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -317,7 +317,7 @@
     RegrTest('test_multibytecodec.py'),
     RegrTest('test_multibytecodec_support.py', skip="not a test"),
     RegrTest('test_multifile.py'),
-    RegrTest('test_multiprocessing.py'),
+    RegrTest('test_multiprocessing.py', skip='FIXME leaves subprocesses'),
     RegrTest('test_mutants.py', core="possibly"),
     RegrTest('test_mutex.py'),
     RegrTest('test_netrc.py'),
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -127,8 +127,6 @@
 SQLITE_FUNCTION                 = 31
 
 # SQLite C API
-sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double]
-sqlite.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64]
 
 sqlite.sqlite3_value_int.argtypes = [c_void_p]
 sqlite.sqlite3_value_int.restype = c_int
@@ -151,7 +149,16 @@
 sqlite.sqlite3_value_type.argtypes = [c_void_p]
 sqlite.sqlite3_value_type.restype = c_int
 
+sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p]
+sqlite.sqlite3_bind_blob.restype = c_int
+sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double]
+sqlite.sqlite3_bind_double.restype = c_int
 sqlite.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int]
+sqlite.sqlite3_bind_int.restype = c_int
+sqlite.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64]
+sqlite.sqlite3_bind_int64.restype = c_int
+sqlite.sqlite3_bind_null.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_bind_null.restype = c_int
 sqlite.sqlite3_bind_parameter_count.argtypes = [c_void_p]
 sqlite.sqlite3_bind_parameter_count.restype = c_int
 sqlite.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p]
@@ -159,45 +166,69 @@
 sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_bind_parameter_name.restype = c_char_p
 sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int,c_void_p]
-sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p]
-sqlite.sqlite3_bind_blob.restype = c_int
+sqlite.sqlite3_bind_text.restype = c_int
+sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_busy_timeout.restype = c_int
 sqlite.sqlite3_changes.argtypes = [c_void_p]
 sqlite.sqlite3_changes.restype = c_int
 sqlite.sqlite3_close.argtypes = [c_void_p]
 sqlite.sqlite3_close.restype = c_int
+sqlite.sqlite3_column_blob.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_column_blob.restype = c_void_p
+sqlite.sqlite3_column_bytes.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_column_bytes.restype = c_int
+sqlite.sqlite3_column_count.argtypes = [c_void_p]
+sqlite.sqlite3_column_count.restype = c_int
+sqlite.sqlite3_column_decltype.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_column_decltype.restype = c_char_p
+sqlite.sqlite3_column_double.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_column_double.restype = c_double
+sqlite.sqlite3_column_int64.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_column_int64.restype = c_int64
+sqlite.sqlite3_column_name.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_column_name.restype = c_char_p
+sqlite.sqlite3_column_text.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_column_text.restype = c_char_p
+sqlite.sqlite3_column_type.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_column_type.restype = c_int
 sqlite.sqlite3_complete.argtypes = [c_char_p]
 sqlite.sqlite3_complete.restype = c_int
 sqlite.sqlite3_errcode.restype = c_int
+sqlite.sqlite3_errmsg.argtypes = [c_void_p]
 sqlite.sqlite3_errmsg.restype = c_char_p
+sqlite.sqlite3_finalize.argtypes = [c_void_p]
+sqlite.sqlite3_finalize.restype = c_int
 sqlite.sqlite3_get_autocommit.argtypes = [c_void_p]
 sqlite.sqlite3_get_autocommit.restype = c_int
+sqlite.sqlite3_last_insert_rowid.argtypes = [c_void_p]
+sqlite.sqlite3_last_insert_rowid.restype = c_int64
 sqlite.sqlite3_libversion.argtypes = []
 sqlite.sqlite3_libversion.restype = c_char_p
 sqlite.sqlite3_open.argtypes = [c_char_p, c_void_p]
 sqlite.sqlite3_open.restype = c_int
+sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, 
POINTER(c_char_p)]
+sqlite.sqlite3_prepare.restype = c_int
 sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, 
POINTER(c_char_p)]
 sqlite.sqlite3_prepare_v2.restype = c_int
-sqlite.sqlite3_column_decltype.argtypes = [c_void_p, c_int]
-sqlite.sqlite3_column_decltype.restype = c_char_p
 sqlite.sqlite3_step.argtypes = [c_void_p]
 sqlite.sqlite3_step.restype = c_int
 sqlite.sqlite3_reset.argtypes = [c_void_p]
 sqlite.sqlite3_reset.restype = c_int
-sqlite.sqlite3_column_count.argtypes = [c_void_p]
-sqlite.sqlite3_column_count.restype = c_int
+sqlite.sqlite3_total_changes.argtypes = [c_void_p]
+sqlite.sqlite3_total_changes.restype = c_int
 
 sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
+sqlite.sqlite3_result_blob.restype = None
 sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64]
+sqlite.sqlite3_result_int64.restype = None
 sqlite.sqlite3_result_null.argtypes = [c_void_p]
+sqlite.sqlite3_result_null.restype = None
 sqlite.sqlite3_result_double.argtypes = [c_void_p, c_double]
+sqlite.sqlite3_result_double.restype = None
 sqlite.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int]
+sqlite.sqlite3_result_error.restype = None
 sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
+sqlite.sqlite3_result_text.restype = None
 
 ##########################################
 # END Wrapped SQLite C API and constants
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -52,8 +52,6 @@
 * `Mercurial commit mailing list`_: updates to code and
   documentation. 
 
-* `Sprint mailing list`_: mailing list for organizing upcoming sprints. 
-
 * `Development bug/feature tracker`_: filing bugs and feature requests. 
 
 * **IRC channel #pypy on freenode**: Many of the core developers are hanging 
out 
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -82,7 +82,7 @@
             raise
 
     def getaddrstring(self, space):
-        # XXX slowish
+        # slowish
         w_id = space.id(self)
         w_4 = space.wrap(4)
         w_0x0F = space.wrap(0x0F)
@@ -616,7 +616,6 @@
 
     def createcompiler(self):
         "Factory function creating a compiler object."
-        # XXX simple selection logic for now
         try:
             return self.default_compiler
         except AttributeError:
@@ -821,11 +820,11 @@
 
     def call_obj_args(self, w_callable, w_obj, args):
         if not self.config.objspace.disable_call_speedhacks:
-            # XXX start of hack for performance
+            # start of hack for performance
             from pypy.interpreter.function import Function
             if isinstance(w_callable, Function):
                 return w_callable.call_obj_args(w_obj, args)
-            # XXX end of hack for performance
+            # end of hack for performance
         return self.call_args(w_callable, args.prepend(w_obj))
 
     def call(self, w_callable, w_args, w_kwds=None):
@@ -835,7 +834,7 @@
     def call_function(self, w_func, *args_w):
         nargs = len(args_w) # used for pruning funccall versions
         if not self.config.objspace.disable_call_speedhacks and nargs < 5:
-            # XXX start of hack for performance
+            # start of hack for performance
             from pypy.interpreter.function import Function, Method
             if isinstance(w_func, Method):
                 w_inst = w_func.w_instance
@@ -850,7 +849,7 @@
 
             if isinstance(w_func, Function):
                 return w_func.funccall(*args_w)
-            # XXX end of hack for performance
+            # end of hack for performance
 
         args = Arguments(self, list(args_w))
         return self.call_args(w_func, args)
@@ -864,7 +863,7 @@
             return self.call_args_and_c_profile(frame, w_func, args)
 
         if not self.config.objspace.disable_call_speedhacks:
-            # XXX start of hack for performance
+            # start of hack for performance
             if isinstance(w_func, Method):
                 w_inst = w_func.w_instance
                 if w_inst is not None:
@@ -879,7 +878,7 @@
 
             if isinstance(w_func, Function):
                 return w_func.funccall_valuestack(nargs, frame)
-            # XXX end of hack for performance
+            # end of hack for performance
 
         args = frame.make_arguments(nargs)
         return self.call_args(w_func, args)
@@ -1338,7 +1337,7 @@
         source = source.lstrip()
         assert source.startswith('('), "incorrect header in:\n%s" % (source,)
         source = py.code.Source("def anonymous%s\n" % source)
-        w_glob = space.newdict()
+        w_glob = space.newdict(module=True)
         space.exec_(str(source), w_glob, w_glob)
         return space.getitem(w_glob, space.wrap('anonymous'))
 
diff --git a/pypy/interpreter/executioncontext.py 
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -24,6 +24,8 @@
     # XXX [fijal] but they're not. is_being_profiled is guarded a bit all
     #     over the place as well as w_tracefunc
 
+    _immutable_fields_ = ['profilefunc?', 'w_tracefunc?']
+
     def __init__(self, space):
         self.space = space
         self.topframeref = jit.vref_None
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -768,6 +768,31 @@
             funcptr(llmemory.cast_ptr_to_adr(gcref_struct),
                     llmemory.cast_ptr_to_adr(gcref_newptr))
 
+    def replace_constptrs_with_getfield_raw(self, cpu, newops, op):
+        # xxx some performance issue here
+        newargs = [None] * op.numargs()
+        needs_copy = False
+        for i in range(op.numargs()):
+            v = op.getarg(i)
+            newargs[i] = v
+            if isinstance(v, ConstPtr) and bool(v.value):
+                addr = self.gcrefs.get_address_of_gcref(v.value)
+                # ^^^even for non-movable objects, to record their presence
+                if rgc.can_move(v.value):
+                    box = BoxPtr(v.value)
+                    addr = cpu.cast_adr_to_int(addr)
+                    newops.append(ResOperation(rop.GETFIELD_RAW,
+                                               [ConstInt(addr)], box,
+                                               self.single_gcref_descr))
+                    newargs[i] = box
+                    needs_copy = True
+        #
+        if needs_copy:
+            return op.copy_and_change(op.getopnum(), args=newargs)
+        else:
+            return op
+
+
     def rewrite_assembler(self, cpu, operations):
         # Perform two kinds of rewrites in parallel:
         #
@@ -790,19 +815,7 @@
             if op.getopnum() == rop.DEBUG_MERGE_POINT:
                 continue
             # ---------- replace ConstPtrs with GETFIELD_RAW ----------
-            # xxx some performance issue here
-            for i in range(op.numargs()):
-                v = op.getarg(i)
-                if isinstance(v, ConstPtr) and bool(v.value):
-                    addr = self.gcrefs.get_address_of_gcref(v.value)
-                    # ^^^even for non-movable objects, to record their presence
-                    if rgc.can_move(v.value):
-                        box = BoxPtr(v.value)
-                        addr = cpu.cast_adr_to_int(addr)
-                        newops.append(ResOperation(rop.GETFIELD_RAW,
-                                                   [ConstInt(addr)], box,
-                                                   self.single_gcref_descr))
-                        op.setarg(i, box)
+            op = self.replace_constptrs_with_getfield_raw(cpu, newops, op)
             if op.is_malloc():
                 last_malloc = op.result
             elif op.can_malloc():
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py 
b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -6,6 +6,7 @@
 from pypy.jit.backend.llsupport.gc import *
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.metainterp.gc import get_description
+from pypy.jit.metainterp.resoperation import get_deep_immutable_oplist
 from pypy.jit.tool.oparser import parse
 from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
 from pypy.jit.metainterp.test.test_optimizeopt import equaloplists
@@ -437,6 +438,7 @@
             ]
         gc_ll_descr = self.gc_ll_descr
         gc_ll_descr.gcrefs = MyFakeGCRefList()
+        operations = get_deep_immutable_oplist(operations)
         operations = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations)
         assert len(operations) == 2
         assert operations[0].getopnum() == rop.GETFIELD_RAW
@@ -472,6 +474,7 @@
         gc_ll_descr = self.gc_ll_descr
         gc_ll_descr.gcrefs = MyFakeGCRefList()
         old_can_move = rgc.can_move
+        operations = get_deep_immutable_oplist(operations)
         try:
             rgc.can_move = lambda s: False
             operations = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations)
@@ -496,6 +499,7 @@
                          descr=field_descr),
             ]
         gc_ll_descr = self.gc_ll_descr
+        operations = get_deep_immutable_oplist(operations)
         operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations)
         assert len(operations) == 2
         #
@@ -520,6 +524,7 @@
                          descr=array_descr),
             ]
         gc_ll_descr = self.gc_ll_descr
+        operations = get_deep_immutable_oplist(operations)
         operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations)
         assert len(operations) == 2
         #
@@ -552,7 +557,8 @@
         setfield_gc(p0, p1, descr=xdescr)
         jump()
         """, namespace=locals())
-        operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, 
ops.operations)
+        operations = get_deep_immutable_oplist(ops.operations)
+        operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, 
operations)
         equaloplists(operations, expected.operations)
 
     def test_rewrite_assembler_initialization_store_2(self):
@@ -576,7 +582,8 @@
         setfield_raw(p0, p1, descr=xdescr)
         jump()
         """, namespace=locals())
-        operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, 
ops.operations)
+        operations = get_deep_immutable_oplist(ops.operations)
+        operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, 
operations)
         equaloplists(operations, expected.operations)
 
     def test_rewrite_assembler_initialization_store_3(self):
@@ -594,7 +601,8 @@
         setarrayitem_gc(p0, 0, p1, descr=arraydescr)
         jump()
         """, namespace=locals())
-        operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, 
ops.operations)
+        operations = get_deep_immutable_oplist(ops.operations)
+        operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, 
operations)
         equaloplists(operations, expected.operations)
 
 class TestFrameworkMiniMark(TestFramework):
diff --git a/pypy/jit/backend/x86/test/test_gc_integration.py 
b/pypy/jit/backend/x86/test/test_gc_integration.py
--- a/pypy/jit/backend/x86/test/test_gc_integration.py
+++ b/pypy/jit/backend/x86/test/test_gc_integration.py
@@ -54,7 +54,8 @@
         self.gcrefs = GcRefList()
         self.gcrefs.initialize()
         self.single_gcref_descr = GcPtrFieldDescr('', 0)
-        
+
+    replace_constptrs_with_getfield_raw = 
GcLLDescr_framework.replace_constptrs_with_getfield_raw.im_func
     rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func
 
 class TestRegallocDirectGcIntegration(object):
diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py
--- a/pypy/jit/codewriter/call.py
+++ b/pypy/jit/codewriter/call.py
@@ -219,11 +219,10 @@
                 assert not NON_VOID_ARGS, ("arguments not supported for "
                                            "loop-invariant function!")
         # build the extraeffect
+        can_invalidate = self.quasiimmut_analyzer.analyze(op)
         if extraeffect is None:
             if self.virtualizable_analyzer.analyze(op):
                 extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
-            elif self.quasiimmut_analyzer.analyze(op):
-                extraeffect = EffectInfo.EF_CAN_INVALIDATE
             elif loopinvariant:
                 extraeffect = EffectInfo.EF_LOOPINVARIANT
             elif pure:
@@ -236,14 +235,16 @@
         #
         effectinfo = effectinfo_from_writeanalyze(
             self.readwrite_analyzer.analyze(op), self.cpu, extraeffect,
-            oopspecindex)
+            oopspecindex, can_invalidate)
         #
         if oopspecindex != EffectInfo.OS_NONE:
             assert effectinfo is not None
         if pure or loopinvariant:
             assert effectinfo is not None
             assert extraeffect != EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
-            assert extraeffect != EffectInfo.EF_CAN_INVALIDATE
+            # XXX this should also say assert not can_invalidate, but
+            #     it can't because our analyzer is not good enough for now
+            #     (and getexecutioncontext() can't really invalidate)
         #
         return self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT,
                                     effectinfo)
diff --git a/pypy/jit/codewriter/effectinfo.py 
b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -13,7 +13,6 @@
     EF_LOOPINVARIANT                   = 1 #special: call it only once per loop
     EF_CANNOT_RAISE                    = 2 #a function which cannot raise
     EF_CAN_RAISE                       = 3 #normal function (can raise)
-    EF_CAN_INVALIDATE                  = 4 #can force all GUARD_NOT_INVALIDATED
     EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 5 #can raise and force virtualizables
 
     # the 'oopspecindex' field is one of the following values:
@@ -79,7 +78,8 @@
     def __new__(cls, readonly_descrs_fields,
                 write_descrs_fields, write_descrs_arrays,
                 extraeffect=EF_CAN_RAISE,
-                oopspecindex=OS_NONE):
+                oopspecindex=OS_NONE,
+                can_invalidate=False):
         key = (frozenset(readonly_descrs_fields),
                frozenset(write_descrs_fields),
                frozenset(write_descrs_arrays),
@@ -97,12 +97,13 @@
             result.write_descrs_fields = write_descrs_fields
             result.write_descrs_arrays = write_descrs_arrays
         result.extraeffect = extraeffect
+        result.can_invalidate = can_invalidate
         result.oopspecindex = oopspecindex
         cls._cache[key] = result
         return result
 
     def check_can_invalidate(self):
-        return self.extraeffect >= self.EF_CAN_INVALIDATE
+        return self.can_invalidate
 
     def check_forces_virtual_or_virtualizable(self):
         return self.extraeffect >= self.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
@@ -112,7 +113,8 @@
 
 def effectinfo_from_writeanalyze(effects, cpu,
                                  extraeffect=EffectInfo.EF_CAN_RAISE,
-                                 oopspecindex=EffectInfo.OS_NONE):
+                                 oopspecindex=EffectInfo.OS_NONE,
+                                 can_invalidate=False):
     from pypy.translator.backendopt.writeanalyze import top_set
     if effects is top_set:
         return None
@@ -150,7 +152,8 @@
                       write_descrs_fields,
                       write_descrs_arrays,
                       extraeffect,
-                      oopspecindex)
+                      oopspecindex,
+                      can_invalidate)
 
 def consider_struct(TYPE, fieldname):
     if fieldType(TYPE, fieldname) is lltype.Void:
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -7,7 +7,7 @@
 from pypy.conftest import option
 from pypy.tool.sourcetools import func_with_new_name
 
-from pypy.jit.metainterp.resoperation import ResOperation, rop
+from pypy.jit.metainterp.resoperation import ResOperation, rop, 
get_deep_immutable_oplist
 from pypy.jit.metainterp.history import TreeLoop, Box, History, LoopToken
 from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt
 from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const
@@ -73,7 +73,7 @@
             # test_memgr.py)
             if descr is not looptoken:
                 looptoken.record_jump_to(descr)
-            op.setdescr(None)    # clear reference, mostly for tests
+            op._descr = None    # clear reference, mostly for tests
             if not we_are_translated():
                 op._jumptarget_number = descr.number
     # record this looptoken on the QuasiImmut used in the code
@@ -159,10 +159,12 @@
     if not we_are_translated():
         show_loop(metainterp_sd, loop)
         loop.check_consistency()
+
+    operations = get_deep_immutable_oplist(loop.operations)
     metainterp_sd.profiler.start_backend()
     debug_start("jit-backend")
     try:
-        ops_offset = metainterp_sd.cpu.compile_loop(loop.inputargs, 
loop.operations,
+        ops_offset = metainterp_sd.cpu.compile_loop(loop.inputargs, operations,
                                                     loop.token)
     finally:
         debug_stop("jit-backend")
@@ -190,6 +192,7 @@
         show_loop(metainterp_sd)
         TreeLoop.check_consistency_of(inputargs, operations)
     metainterp_sd.profiler.start_backend()
+    operations = get_deep_immutable_oplist(operations)
     debug_start("jit-backend")
     try:
         ops_offset = metainterp_sd.cpu.compile_bridge(faildescr, inputargs, 
operations,
@@ -688,6 +691,7 @@
         ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken)
         ]
     operations[1].setfailargs([])
+    operations = get_deep_immutable_oplist(operations)
     cpu.compile_loop(inputargs, operations, loop_token, log=False)
     if memory_manager is not None:    # for tests
         memory_manager.keep_loop_alive(loop_token)
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py 
b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -15,7 +15,7 @@
 
     def reconstruct_for_next_iteration(self, optimizer, valuemap):
         return self
-    
+
     def propagate_forward(self, op):
         args = self.optimizer.make_args_key(op)
         if self.find_rewritable_bool(op, args):
@@ -40,7 +40,7 @@
                     return False
         return self.is_emittable(op)
 
-        
+
     def try_boolinvers(self, op, targs):
         oldop = self.optimizer.pure_operations.get(targs, None)
         if oldop is not None and oldop.getdescr() is op.getdescr():
@@ -69,7 +69,7 @@
         try:
             oldopnum = opboolreflex[op.getopnum()] # FIXME: add INT_ADD, 
INT_MUL
             targs = self.optimizer.make_args_key(ResOperation(oldopnum, 
[args[1], args[0]],
-                                                              None))           
 
+                                                              None))
             oldop = self.optimizer.pure_operations.get(targs, None)
             if oldop is not None and oldop.getdescr() is op.getdescr():
                 self.make_equal_to(op.result, self.getvalue(oldop.result))
@@ -80,7 +80,7 @@
         try:
             oldopnum = opboolinvers[opboolreflex[op.getopnum()]]
             targs = self.optimizer.make_args_key(ResOperation(oldopnum, 
[args[1], args[0]],
-                                                              None))           
 
+                                                              None))
             if self.try_boolinvers(op, targs):
                 return True
         except KeyError:
@@ -157,6 +157,15 @@
 
             self.emit_operation(op)
 
+    def optimize_UINT_FLOORDIV(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        v2 = self.getvalue(op.getarg(1))
+
+        if v2.is_constant() and v2.box.getint() == 1:
+            self.make_equal_to(op.result, v1)
+        else:
+            self.emit_operation(op)
+
     def optimize_INT_LSHIFT(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
@@ -322,7 +331,7 @@
         self.emit_operation(op)
         resvalue = self.getvalue(op.result)
         self.optimizer.loop_invariant_results[key] = resvalue
-    
+
     def _optimize_nullness(self, op, box, expect_nonnull):
         value = self.getvalue(box)
         if value.is_nonnull():
@@ -381,7 +390,7 @@
 ##        if realclassbox is not None:
 ##            checkclassbox = self.optimizer.cpu.typedescr2classbox(op.descr)
 ##            result = self.optimizer.cpu.ts.subclassOf(self.optimizer.cpu,
-##                                                      realclassbox, 
+##                                                      realclassbox,
 ##                                                      checkclassbox)
 ##            self.make_constant_int(op.result, result)
 ##            return
diff --git a/pypy/jit/metainterp/resoperation.py 
b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -627,3 +627,25 @@
     rop.PTR_EQ: rop.PTR_EQ,
     rop.PTR_NE: rop.PTR_NE,
     }
+
+
+def get_deep_immutable_oplist(operations):
+    """
+    When not we_are_translated(), turns ``operations`` into a frozenlist and
+    monkey-patch its items to make sure they are not mutated.
+
+    When we_are_translated(), do nothing and just return the old list.
+    """
+    from pypy.tool.frozenlist import frozenlist
+    if we_are_translated():
+        return operations
+    #
+    def setarg(*args):
+        assert False, "operations cannot change at this point"
+    def setdescr(*args):
+        assert False, "operations cannot change at this point"
+    newops = frozenlist(operations)
+    for op in newops:
+        op.setarg = setarg
+        op.setdescr = setdescr
+    return newops
diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py 
b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -2843,6 +2843,18 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_fold_partially_constant_uint_floordiv(self):
+        ops = """
+        [i0]
+        i1 = uint_floordiv(i0, 1)
+        jump(i1)
+        """
+        expected = """
+        [i0]
+        jump(i0)
+        """
+        self.optimize_loop(ops, expected)
+
     # ----------
 
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
@@ -5746,7 +5758,7 @@
         """
         expected = """
         []
-        guard_not_invalidated() []        
+        guard_not_invalidated() []
         escape(-4247)
         jump()
         """
diff --git a/pypy/jit/metainterp/test/test_resoperation.py 
b/pypy/jit/metainterp/test/test_resoperation.py
--- a/pypy/jit/metainterp/test/test_resoperation.py
+++ b/pypy/jit/metainterp/test/test_resoperation.py
@@ -68,3 +68,11 @@
     call = rop.ResOperation(rop.rop.CALL, ['a', 'b'], 'c', descr=mydescr)
     assert call.can_malloc()
     assert not rop.ResOperation(rop.rop.INT_ADD, ['a', 'b'], 'c').can_malloc()
+
+def test_get_deep_immutable_oplist():
+    ops = [rop.ResOperation(rop.rop.INT_ADD, ['a', 'b'], 'c')]
+    newops = rop.get_deep_immutable_oplist(ops)
+    py.test.raises(AttributeError, "newops.append('foobar')")
+    py.test.raises(TypeError, "newops[0] = 'foobar'")
+    py.test.raises(AssertionError, "newops[0].setarg(0, 'd')")
+    py.test.raises(AssertionError, "newops[0].setdescr('foobar')")
diff --git a/pypy/module/_socket/test/test_sock_app.py 
b/pypy/module/_socket/test/test_sock_app.py
--- a/pypy/module/_socket/test/test_sock_app.py
+++ b/pypy/module/_socket/test/test_sock_app.py
@@ -372,11 +372,12 @@
     def test_socket_connect(self):
         import _socket, os
         s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
-        # XXX temporarily we use codespeak to test, will have more robust 
tests in
-        # the absence of a network connection later when more parts of the 
socket
-        # API are implemented. currently skip the test if there is no 
connection.
+        # XXX temporarily we use python.org to test, will have more robust 
tests
+        # in the absence of a network connection later when more parts of the
+        # socket API are implemented.  Currently skip the test if there is no
+        # connection.
         try:
-            s.connect(("codespeak.net", 80))
+            s.connect(("www.python.org", 80))
         except _socket.gaierror, ex:
             skip("GAIError - probably no connection: %s" % str(ex.args))
         name = s.getpeername() # Will raise socket.error if not connected
@@ -506,11 +507,12 @@
         # Test that send/sendall/sendto accept a buffer or a unicode as arg
         import _socket, os
         s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
-        # XXX temporarily we use codespeak to test, will have more robust 
tests in
-        # the absence of a network connection later when more parts of the 
socket
-        # API are implemented. currently skip the test if there is no 
connection.
+        # XXX temporarily we use python.org to test, will have more robust 
tests
+        # in the absence of a network connection later when more parts of the
+        # socket API are implemented.  Currently skip the test if there is no
+        # connection.
         try:
-            s.connect(("codespeak.net", 80))
+            s.connect(("www.python.org", 80))
         except _socket.gaierror, ex:
             skip("GAIError - probably no connection: %s" % str(ex.args))
         s.send(buffer(''))
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -899,7 +899,7 @@
 
 def _ssl_thread_id_function():
     from pypy.module.thread import ll_thread
-    return ll_thread.get_ident()
+    return rffi.cast(rffi.INT, ll_thread.get_ident())
 
 def setup_ssl_threads():
     from pypy.module.thread import ll_thread
diff --git a/pypy/module/_ssl/test/test_ssl.py 
b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -81,7 +81,7 @@
         ss = _ssl.sslwrap(s, 0)
         s.close()
         exc = raises(_ssl.SSLError, ss.write, "data")
-        assert exc.value.message == "Underlying socket has been closed."
+        assert exc.value.strerror == "Underlying socket has been closed."
 
 
 class AppTestConnectedSSL:
@@ -90,8 +90,8 @@
         cls.space = space
 
     def setup_method(self, method):
-        # https://codespeak.net/
-        ADDR = "codespeak.net", 443
+        # https://www.verisign.net/
+        ADDR = "www.verisign.net", 443
 
         self.w_s = self.space.appexec([self.space.wrap(ADDR)], """(ADDR):
             import socket
diff --git a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py 
b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
--- a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
@@ -1031,7 +1031,6 @@
         """)
 
     def test_func_defaults(self):
-        py.test.skip("until we fix defaults")
         def main(n):
             i = 1
             while i < n:
@@ -1044,20 +1043,10 @@
         assert loop.match("""
             i10 = int_lt(i5, i6)
             guard_true(i10, descr=<Guard3>)
-            # This can be improved if the JIT realized the lookup of i5 
produces
-            # a constant and thus can be removed entirely
             i120 = int_add(i5, 1)
-            i140 = int_lt(0, i120)
-            guard_true(i140, descr=<Guard4>)
-            i13 = uint_floordiv(i5, i7)
-            i15 = int_add(i13, 1)
-            i17 = int_lt(i15, 0)
-            guard_false(i17, descr=<Guard5>)
-            i20 = int_sub(i15, i5)
-            i21 = int_add_ovf(i5, i20)
-            guard_no_overflow(descr=<Guard6>)
+            guard_not_invalidated(descr=<Guard4>)
             --TICK--
-            jump(p0, p1, p2, p3, p4, i21, i6, i7, p8, p9, descr=<Loop0>)
+            jump(..., descr=<Loop0>)
         """)
 
     def test__ffi_call_releases_gil(self):
@@ -1121,7 +1110,7 @@
             --TICK--
             jump(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, i28, i25, i19, i13, 
p14, p15, descr=<Loop0>)
         """)
-        
+
     def test_mutate_class(self):
         def fn(n):
             class A(object):
@@ -1526,7 +1515,7 @@
         def main():
             i=0
             sa=0
-            while i < 300: 
+            while i < 300:
                 sa+=min(max(i, 3000), 4000)
                 i+=1
             return sa
@@ -1563,7 +1552,7 @@
             p76 = call_may_force(ConstClass(min_max_loop__max), _, _, 
descr=...)
             ...
         """)
-        
+
     def test_iter_max(self):
         def main():
             i = 2
@@ -1581,7 +1570,7 @@
         assert len(guards) < 20
         assert loop.match_by_id('max',"""
             ...
-            p76 = call_may_force(ConstClass(min_max_loop__max), _, _, 
descr=...)            
+            p76 = call_may_force(ConstClass(min_max_loop__max), _, _, 
descr=...)
             ...
         """)
 
diff --git a/pypy/module/thread/ll_thread.py b/pypy/module/thread/ll_thread.py
--- a/pypy/module/thread/ll_thread.py
+++ b/pypy/module/thread/ll_thread.py
@@ -114,6 +114,8 @@
             c_thread_releaselock(self._lock)
 
     def __del__(self):
+        if free_ll_lock is None:  # happens when tests are shutting down
+            return
         free_ll_lock(self._lock)
 
     def __enter__(self):
diff --git a/pypy/objspace/std/stringobject.py 
b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -52,12 +52,16 @@
         c = v[0]
         return space.newbool(fun(c))
     else:
-        for idx in range(len(v)):
-            if not fun(v[idx]):
-                return space.w_False
-        return space.w_True
+        return _is_generic_loop(space, v, fun)
 _is_generic._annspecialcase_ = "specialize:arg(2)"
 
+def _is_generic_loop(space, v, fun):
+    for idx in range(len(v)):
+        if not fun(v[idx]):
+            return space.w_False
+    return space.w_True
+_is_generic_loop._annspecialcase_ = "specialize:arg(2)"
+
 def _upper(ch):
     if ch.islower():
         o = ord(ch) - 32
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -265,7 +265,7 @@
 
 PARAMETERS = {'threshold': 1000,
               'trace_eagerness': 200,
-              'trace_limit': 10000,
+              'trace_limit': 12000,
               'inlining': 0,
               'loop_longevity': 1000,
               'retrace_limit': 5,
diff --git a/pypy/rlib/test/test_rsocket.py b/pypy/rlib/test/test_rsocket.py
--- a/pypy/rlib/test/test_rsocket.py
+++ b/pypy/rlib/test/test_rsocket.py
@@ -297,24 +297,25 @@
     e = py.test.raises(GAIError, getaddrinfo, 'www.very-invalidaddress.com', 
None)
     assert isinstance(e.value.get_msg(), str)
 
-def test_getaddrinfo_codespeak():
-    lst = getaddrinfo('codespeak.net', None)
+def test_getaddrinfo_pydotorg():
+    lst = getaddrinfo('python.org', None)
     assert isinstance(lst, list)
     found = False
     for family, socktype, protocol, canonname, addr in lst:
-        if addr.get_host() == '88.198.193.90':
+        if addr.get_host() == '82.94.164.162':
             found = True
     assert found, lst
 
 def test_getaddrinfo_no_reverse_lookup():
     # It seems that getaddrinfo never runs a reverse lookup on Linux.
     # Python2.3 on Windows returns the hostname.
-    lst = getaddrinfo('213.239.226.252', None, flags=AI_NUMERICHOST)
+    lst = getaddrinfo('82.94.164.162', None, flags=AI_NUMERICHOST)
     assert isinstance(lst, list)
     found = False
+    print lst
     for family, socktype, protocol, canonname, addr in lst:
-        assert canonname != 'codespeak.net'
-        if addr.get_host() == '213.239.226.252':
+        assert 'python.org' not in canonname
+        if addr.get_host() == '82.94.164.162':
             found = True
     assert found, lst
 
diff --git a/pypy/tool/frozenlist.py b/pypy/tool/frozenlist.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/frozenlist.py
@@ -0,0 +1,19 @@
+from pypy.tool.sourcetools import func_with_new_name
+
+def forbid(*args):
+    raise TypeError, "cannot mutate a frozenlist"
+
+class frozenlist(list):
+    __setitem__  = func_with_new_name(forbid, '__setitem__')
+    __delitem__  = func_with_new_name(forbid, '__delitem__')
+    __setslice__ = func_with_new_name(forbid, '__setslice__')
+    __delslice__ = func_with_new_name(forbid, '__delslice__')
+    __iadd__     = func_with_new_name(forbid, '__iadd__')
+    __imul__     = func_with_new_name(forbid, '__imul__')
+    append       = func_with_new_name(forbid, 'append')
+    insert       = func_with_new_name(forbid, 'insert')
+    pop          = func_with_new_name(forbid, 'pop')
+    remove       = func_with_new_name(forbid, 'remove')
+    reverse      = func_with_new_name(forbid, 'reverse')
+    sort         = func_with_new_name(forbid, 'sort')
+    extend       = func_with_new_name(forbid, 'extend')
diff --git a/pypy/tool/test/test_frozenlist.py 
b/pypy/tool/test/test_frozenlist.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/test/test_frozenlist.py
@@ -0,0 +1,21 @@
+import py
+from pypy.tool.frozenlist import frozenlist
+
+def test_frozenlist():
+    l = frozenlist([1, 2, 3])
+    assert l[0] == 1
+    assert l[:2] == [1, 2]
+    assert l.index(2) == 1
+    py.test.raises(TypeError, "l[0] = 1")
+    py.test.raises(TypeError, "del l[0]")
+    py.test.raises(TypeError, "l[:] = []")
+    py.test.raises(TypeError, "del l[:]")
+    py.test.raises(TypeError, "l += []")
+    py.test.raises(TypeError, "l *= 2")
+    py.test.raises(TypeError, "l.append(1)")
+    py.test.raises(TypeError, "l.insert(0, 0)")
+    py.test.raises(TypeError, "l.pop()")
+    py.test.raises(TypeError, "l.remove(1)")
+    py.test.raises(TypeError, "l.reverse()")
+    py.test.raises(TypeError, "l.sort()")
+    py.test.raises(TypeError, "l.extend([])")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to