[pypy-commit] pypy numpy-impicit-convert: Merge default
snus_mumrik
noreply at buildbot.pypy.org
Thu Jun 23 21:14:12 CEST 2011
Author: Ilya Osadchiy <osadchiy.ilya at gmail.com>
Branch: numpy-impicit-convert
Changeset: r45092:226e890618d3
Date: 2011-06-23 22:17 +0300
http://bitbucket.org/pypy/pypy/changeset/226e890618d3/
Log: Merge default
diff --git a/pypy/interpreter/astcompiler/misc.py b/pypy/interpreter/astcompiler/misc.py
--- a/pypy/interpreter/astcompiler/misc.py
+++ b/pypy/interpreter/astcompiler/misc.py
@@ -92,7 +92,10 @@
return name
if len(name) + 2 >= MANGLE_LEN:
return name
- if name.endswith('__'):
+ # Don't mangle __id__ or names with dots. The only time a name with a dot
+ # can occur is when we are compiling an import statement that has a package
+ # name.
+ if name.endswith('__') or '.' in name:
return name
try:
i = 0
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -308,6 +308,15 @@
"p.__name__", os.path.__name__)
yield (self.st, 'from os import *',
"path.__name__, sep", (os.path.__name__, os.sep))
+ yield (self.st, '''
+ class A(object):
+ def m(self):
+ from __foo__.bar import x
+ try:
+ A().m()
+ except ImportError, e:
+ msg = str(e)
+ ''', "msg", "No module named __foo__")
def test_if_stmts(self):
yield self.st, "a = 42\nif a > 10: a += 2", "a", 44
diff --git a/pypy/jit/codewriter/policy.py b/pypy/jit/codewriter/policy.py
--- a/pypy/jit/codewriter/policy.py
+++ b/pypy/jit/codewriter/policy.py
@@ -44,10 +44,6 @@
return True
if mod.startswith('pypy.translator.'): # XXX wtf?
return True
- # string builder interface
- if mod == 'pypy.rpython.lltypesystem.rbuilder':
- return True
-
return False
def look_inside_graph(self, graph):
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -4,7 +4,7 @@
from pypy.rpython.ootypesystem import ootype
from pypy.rlib.objectmodel import we_are_translated, r_dict, Symbolic
from pypy.rlib.objectmodel import compute_unique_id
-from pypy.rlib.rarithmetic import intmask, r_int64
+from pypy.rlib.rarithmetic import r_int64
from pypy.conftest import option
from pypy.jit.metainterp.resoperation import ResOperation, rop
diff --git a/pypy/jit/metainterp/optimize.py b/pypy/jit/metainterp/optimize.py
--- a/pypy/jit/metainterp/optimize.py
+++ b/pypy/jit/metainterp/optimize.py
@@ -25,7 +25,6 @@
def _optimize_loop(metainterp_sd, old_loop_tokens, loop, enable_opts):
from pypy.jit.metainterp.optimizeopt import optimize_loop_1
- cpu = metainterp_sd.cpu
loop.logops = metainterp_sd.logger_noopt.log_loop(loop.inputargs,
loop.operations)
# XXX do we really still need a list?
@@ -49,7 +48,6 @@
def _optimize_bridge(metainterp_sd, old_loop_tokens, bridge, enable_opts,
inline_short_preamble, retraced=False):
from pypy.jit.metainterp.optimizeopt import optimize_bridge_1
- cpu = metainterp_sd.cpu
bridge.logops = metainterp_sd.logger_noopt.log_loop(bridge.inputargs,
bridge.operations)
if old_loop_tokens:
diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -112,7 +112,7 @@
class OptHeap(Optimization):
"""Cache repeated heap accesses"""
-
+
def __init__(self):
# cached fields: {descr: CachedField}
self.cached_fields = {}
@@ -129,7 +129,7 @@
self.force_all_lazy_setfields()
else:
assert 0 # was: new.lazy_setfields = self.lazy_setfields
-
+
for descr, d in self.cached_fields.items():
new.cached_fields[descr] = d.get_reconstructed(optimizer, valuemap)
diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py
--- a/pypy/jit/metainterp/optimizeopt/intbounds.py
+++ b/pypy/jit/metainterp/optimizeopt/intbounds.py
@@ -23,7 +23,7 @@
def reconstruct_for_next_iteration(self, optimizer, valuemap):
assert self.posponedop is None
- return self
+ return self
def propagate_forward(self, op):
if op.is_ovf():
@@ -194,7 +194,7 @@
# Synthesize the reverse ops for optimize_default to reuse
self.pure(rop.INT_ADD, [op.result, op.getarg(1)], op.getarg(0))
self.pure(rop.INT_SUB, [op.getarg(0), op.result], op.getarg(1))
-
+
def optimize_INT_MUL_OVF(self, op):
v1 = self.getvalue(op.getarg(0))
@@ -292,6 +292,11 @@
v1.intbound.make_ge(IntLowerBound(0))
v1.intbound.make_lt(IntUpperBound(256))
+ def optimize_UNICODEGETITEM(self, op):
+ self.emit_operation(op)
+ v1 = self.getvalue(op.result)
+ v1.intbound.make_ge(IntLowerBound(0))
+
def make_int_lt(self, box1, box2):
v1 = self.getvalue(box1)
v2 = self.getvalue(box2)
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -141,6 +141,9 @@
# meaning it has been forced.
return self.box is None
+ def is_forced_virtual(self):
+ return False
+
def getfield(self, ofs, default):
raise NotImplementedError
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
@@ -219,7 +219,7 @@
break
arg_consts.append(const)
else:
- # all constant arguments: check if we already know the reslut
+ # all constant arguments: check if we already know the result
try:
result = self.optimizer.call_pure_results[arg_consts]
except KeyError:
diff --git a/pypy/jit/metainterp/optimizeopt/string.py b/pypy/jit/metainterp/optimizeopt/string.py
--- a/pypy/jit/metainterp/optimizeopt/string.py
+++ b/pypy/jit/metainterp/optimizeopt/string.py
@@ -348,7 +348,7 @@
optimizer.emit_operation(ResOperation(rop.INT_SUB, [box1, box2], resbox))
return resbox
-def _strgetitem(optimizer, strbox, indexbox, mode):
+def _strgetitem(optimization, strbox, indexbox, mode):
if isinstance(strbox, ConstPtr) and isinstance(indexbox, ConstInt):
if mode is mode_string:
s = strbox.getref(lltype.Ptr(rstr.STR))
@@ -357,7 +357,7 @@
s = strbox.getref(lltype.Ptr(rstr.UNICODE))
return ConstInt(ord(s.chars[indexbox.getint()]))
resbox = BoxInt()
- optimizer.emit_operation(ResOperation(mode.STRGETITEM, [strbox, indexbox],
+ optimization.emit_operation(ResOperation(mode.STRGETITEM, [strbox, indexbox],
resbox))
return resbox
@@ -440,8 +440,7 @@
if vindex.is_constant():
return value.getitem(vindex.box.getint())
#
- resbox = _strgetitem(self.optimizer,
- value.force_box(),vindex.force_box(), mode)
+ resbox = _strgetitem(self, value.force_box(), vindex.force_box(), mode)
return self.getvalue(resbox)
def optimize_STRLEN(self, op):
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -4480,6 +4480,24 @@
# not obvious, because of the exception UnicodeDecodeError that
# can be raised by ll_str2unicode()
+ def test_strgetitem_repeated(self):
+ ops = """
+ [p0, i0]
+ i1 = strgetitem(p0, i0)
+ i2 = strgetitem(p0, i0)
+ i3 = int_eq(i1, i2)
+ guard_true(i3) []
+ escape(i2)
+ jump(p0, i0)
+ """
+ expected = """
+ [p0, i0]
+ i1 = strgetitem(p0, i0)
+ escape(i1)
+ jump(p0, i0)
+ """
+ self.optimize_loop(ops, expected)
+
##class TestOOtype(BaseTestOptimizeBasic, OOtypeMixin):
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -5311,7 +5311,7 @@
"""
self.optimize_strunicode_loop(ops, expected)
- def test_strgetitem_small(self):
+ def test_strgetitem_bounds(self):
ops = """
[p0, i0]
i1 = strgetitem(p0, i0)
@@ -5323,7 +5323,20 @@
"""
expected = """
[p0, i0]
- i1 = strgetitem(p0, i0)
+ jump(p0, i0)
+ """
+ self.optimize_loop(ops, expected)
+
+ def test_unicodegetitem_bounds(self):
+ ops = """
+ [p0, i0]
+ i1 = unicodegetitem(p0, i0)
+ i2 = int_lt(i1, 0)
+ guard_false(i2) []
+ jump(p0, i0)
+ """
+ expected = """
+ [p0, i0]
jump(p0, i0)
"""
self.optimize_loop(ops, expected)
@@ -5837,3 +5850,30 @@
jump(i3, i4)
"""
self.optimize_loop(ops, expected)
+
+ def test_forced_virtual_pure_getfield(self):
+ ops = """
+ [p0]
+ p1 = getfield_gc_pure(p0, descr=valuedescr)
+ jump(p1)
+ """
+ self.optimize_loop(ops, ops)
+
+ ops = """
+ [p0]
+ p1 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p1, p0, descr=valuedescr)
+ escape(p1)
+ p2 = getfield_gc_pure(p1, descr=valuedescr)
+ escape(p2)
+ jump(p0)
+ """
+ expected = """
+ [p0]
+ p1 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p1, p0, descr=valuedescr)
+ escape(p1)
+ escape(p0)
+ jump(p0)
+ """
+ self.optimize_loop(ops, expected)
\ No newline at end of file
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -20,6 +20,9 @@
self.source_op = source_op # the NEW_WITH_VTABLE/NEW_ARRAY operation
# that builds this box
+ def is_forced_virtual(self):
+ return self.box is not None
+
def get_key_box(self):
if self.box is None:
return self.keybox
@@ -120,7 +123,6 @@
op = ResOperation(rop.SETFIELD_GC, [box, subbox], None,
descr=ofs)
newoperations.append(op)
- self._fields = None
def _get_field_descr_list(self):
_cached_sorted_fields = self._cached_sorted_fields
@@ -351,7 +353,7 @@
if not self.optimizer.cpu.ts.CONST_NULL.same_constant(objbox):
seo(ResOperation(rop.SETFIELD_GC, op.getarglist(), None,
descr = vrefinfo.descr_forced))
-
+
# - set 'virtual_token' to TOKEN_NONE
args = [op.getarg(0), ConstInt(vrefinfo.TOKEN_NONE)]
seo(ResOperation(rop.SETFIELD_GC, args, None,
@@ -365,6 +367,14 @@
def optimize_GETFIELD_GC(self, op):
value = self.getvalue(op.getarg(0))
+ # If this is an immutable field (as indicated by op.is_always_pure())
+ # then it's safe to reuse the virtual's field, even if it has been
+ # forced, because it should never be written to again.
+ if value.is_forced_virtual() and op.is_always_pure():
+ fieldvalue = value.getfield(op.getdescr(), None)
+ if fieldvalue is not None:
+ self.make_equal_to(op.result, fieldvalue)
+ return
if value.is_virtual():
assert isinstance(value, AbstractVirtualValue)
fieldvalue = value.getfield(op.getdescr(), None)
@@ -382,6 +392,7 @@
def optimize_SETFIELD_GC(self, op):
value = self.getvalue(op.getarg(0))
+
if value.is_virtual():
fieldvalue = self.getvalue(op.getarg(1))
value.setfield(op.getdescr(), fieldvalue)
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1,5 +1,5 @@
-import py, os, sys
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+import py, sys
+from pypy.rpython.lltypesystem import lltype, rclass
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.debug import debug_start, debug_stop, debug_print
@@ -15,13 +15,12 @@
from pypy.jit.metainterp.jitprof import EmptyProfiler
from pypy.jit.metainterp.jitprof import GUARDS, RECORDED_OPS, ABORT_ESCAPE
from pypy.jit.metainterp.jitprof import ABORT_TOO_LONG, ABORT_BRIDGE, \
- ABORT_BAD_LOOP, ABORT_FORCE_QUASIIMMUT
+ ABORT_FORCE_QUASIIMMUT
from pypy.jit.metainterp.jitexc import JitException, get_llexception
-from pypy.rlib.rarithmetic import intmask
from pypy.rlib.objectmodel import specialize
-from pypy.jit.codewriter.jitcode import JitCode, SwitchDictDescr, MissingLiveness
-from pypy.jit.codewriter import heaptracker, longlong
-from pypy.jit.metainterp.optimizeopt.util import args_dict_box, args_dict
+from pypy.jit.codewriter.jitcode import JitCode, SwitchDictDescr
+from pypy.jit.codewriter import heaptracker
+from pypy.jit.metainterp.optimizeopt.util import args_dict_box
from pypy.jit.metainterp.optimize import RetraceLoop
# ____________________________________________________________
@@ -2119,7 +2118,6 @@
def vrefs_after_residual_call(self):
vrefinfo = self.staticdata.virtualref_info
for i in range(0, len(self.virtualref_boxes), 2):
- virtualbox = self.virtualref_boxes[i]
vrefbox = self.virtualref_boxes[i+1]
vref = vrefbox.getref_base()
if vrefinfo.tracing_after_residual_call(vref):
diff --git a/pypy/jit/metainterp/test/test_dict.py b/pypy/jit/metainterp/test/test_dict.py
--- a/pypy/jit/metainterp/test/test_dict.py
+++ b/pypy/jit/metainterp/test/test_dict.py
@@ -130,6 +130,38 @@
assert res == 50
self.check_loops(int_mod=1)
+ def test_repeated_lookup(self):
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'd'])
+ class Wrapper(object):
+ _immutable_fields_ = ["value"]
+ def __init__(self, value):
+ self.value = value
+ def eq_func(a, b):
+ return a.value == b.value
+ def hash_func(x):
+ return objectmodel.compute_hash(x.value)
+
+ def f(n):
+ d = None
+ while n > 0:
+ myjitdriver.jit_merge_point(n=n, d=d)
+ d = objectmodel.r_dict(eq_func, hash_func)
+ y = Wrapper(str(n))
+ d[y] = n - 1
+ n = d[y]
+ return d[Wrapper(str(n + 1))]
+
+ res = self.meta_interp(f, [100], listops=True)
+ assert res == f(50)
+ # XXX: ideally there would be 7 calls here, but repeated CALL_PURE with
+ # the same arguments are not folded, because we have conflicting
+ # definitions of pure, once strhash can be appropriately folded
+ # this should be decreased to seven.
+ self.check_loops({"call": 8, "guard_false": 1, "guard_no_exception": 5,
+ "guard_true": 1, "int_and": 1, "int_gt": 1,
+ "int_is_true": 1, "int_sub": 1, "jump": 1,
+ "new_with_vtable": 1, "setfield_gc": 1})
+
class TestOOtype(DictTests, OOJitMixin):
pass
diff --git a/pypy/jit/metainterp/virtualref.py b/pypy/jit/metainterp/virtualref.py
--- a/pypy/jit/metainterp/virtualref.py
+++ b/pypy/jit/metainterp/virtualref.py
@@ -1,5 +1,5 @@
from pypy.rpython.rmodel import inputconst, log
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass
from pypy.jit.metainterp import history
from pypy.jit.codewriter import heaptracker
from pypy.rlib.jit import InvalidVirtualRef
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -1,6 +1,5 @@
import sys, py
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
-from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.annlowlevel import llhelper, MixLevelHelperAnnotator,\
cast_base_ptr_to_instance, hlstr
from pypy.annotation import model as annmodel
@@ -10,16 +9,12 @@
from pypy.objspace.flow.model import checkgraph, Link, copygraph
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.rarithmetic import r_uint, intmask
-from pypy.rlib.debug import debug_print, fatalerror
-from pypy.rlib.debug import debug_start, debug_stop
-from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.translator.simplify import get_funcobj, get_functype
+from pypy.rlib.debug import fatalerror
+from pypy.translator.simplify import get_functype
from pypy.translator.unsimplify import call_final_function
from pypy.jit.metainterp import history, pyjitpl, gc, memmgr
-from pypy.jit.metainterp.pyjitpl import MetaInterpStaticData, MetaInterp
-from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper
+from pypy.jit.metainterp.pyjitpl import MetaInterpStaticData
from pypy.jit.metainterp.jitprof import Profiler, EmptyProfiler
from pypy.jit.metainterp.jitexc import JitException
from pypy.jit.metainterp.jitdriver import JitDriverStaticData
@@ -297,9 +292,6 @@
self.stats = stats
if translate_support_code:
self.annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
- annhelper = self.annhelper
- else:
- annhelper = None
cpu = CPUClass(self.translator.rtyper, self.stats, self.opt,
translate_support_code, gcdescr=self.gcdescr)
self.cpu = cpu
@@ -440,7 +432,6 @@
maybe_enter_jit._always_inline_ = True
jd._maybe_enter_jit_fn = maybe_enter_jit
- num_green_args = jd.num_green_args
def maybe_enter_from_start(*args):
maybe_compile_and_run(state.increment_function_threshold, *args)
maybe_enter_from_start._always_inline_ = True
@@ -553,7 +544,6 @@
self.rewrite_can_enter_jit(jd, sublist)
def rewrite_can_enter_jit(self, jd, can_enter_jits):
- FUNC = jd._JIT_ENTER_FUNCTYPE
FUNCPTR = jd._PTR_JIT_ENTER_FUNCTYPE
jit_enter_fnptr = self.helper_func(FUNCPTR, jd._maybe_enter_jit_fn)
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -1,7 +1,7 @@
import sys, weakref
from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi
from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.annlowlevel import hlstr, llstr, cast_base_ptr_to_instance
+from pypy.rpython.annlowlevel import hlstr, cast_base_ptr_to_instance
from pypy.rpython.annlowlevel import cast_object_to_ptr
from pypy.rlib.objectmodel import specialize, we_are_translated, r_dict
from pypy.rlib.rarithmetic import intmask
@@ -502,7 +502,6 @@
if hasattr(self, 'set_future_values'):
return self.set_future_values
- warmrunnerdesc = self.warmrunnerdesc
jitdriver_sd = self.jitdriver_sd
cpu = self.cpu
vinfo = jitdriver_sd.virtualizable_info
@@ -518,7 +517,6 @@
#
if vinfo is not None:
i0 = len(jitdriver_sd._red_args_types)
- num_green_args = jitdriver_sd.num_green_args
index_of_virtualizable = jitdriver_sd.index_of_virtualizable
vable_static_fields = unrolling_iterable(
zip(vinfo.static_extra_types, vinfo.static_fields))
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -3,6 +3,14 @@
from pypy.interpreter.mixedmodule import MixedModule
from pypy.module.imp.importing import get_pyc_magic
+
+class BuildersModule(MixedModule):
+ appleveldefs = {}
+
+ interpleveldefs = {
+ "UnicodeBuilder": "interp_builders.W_UnicodeBuilder",
+ }
+
class Module(MixedModule):
appleveldefs = {
}
@@ -19,6 +27,10 @@
'lookup_special' : 'interp_magic.lookup_special',
}
+ submodules = {
+ "builders": BuildersModule,
+ }
+
def setup_after_space_initialization(self):
"""NOT_RPYTHON"""
if not self.space.config.translating:
diff --git a/pypy/module/__pypy__/interp_builders.py b/pypy/module/__pypy__/interp_builders.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_builders.py
@@ -0,0 +1,50 @@
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.typedef import TypeDef
+from pypy.rlib.rstring import UnicodeBuilder
+
+
+class W_UnicodeBuilder(Wrappable):
+ def __init__(self, space, size):
+ if size == -1:
+ self.builder = UnicodeBuilder()
+ else:
+ self.builder = UnicodeBuilder(size)
+ self.done = False
+
+ def _check_done(self, space):
+ if self.done:
+ raise OperationError(space.w_ValueError, space.wrap("Can't operate on a done builder"))
+
+ @unwrap_spec(size=int)
+ def descr__new__(space, w_subtype, size=-1):
+ return W_UnicodeBuilder(space, size)
+
+ @unwrap_spec(s=unicode)
+ def descr_append(self, space, s):
+ self._check_done(space)
+ self.builder.append(s)
+
+ @unwrap_spec(s=unicode, start=int, end=int)
+ def descr_append_slice(self, space, s, start, end):
+ self._check_done(space)
+ if not 0 <= start <= end <= len(s):
+ raise OperationError(space.w_ValueError, space.wrap("bad start/stop"))
+ self.builder.append_slice(s, start, end)
+
+ def descr_build(self, space):
+ self._check_done(space)
+ w_s = space.wrap(self.builder.build())
+ self.done = True
+ return w_s
+
+
+W_UnicodeBuilder.typedef = TypeDef("UnicodeBuilder",
+ __new__ = interp2app(W_UnicodeBuilder.descr__new__.im_func),
+
+ append = interp2app(W_UnicodeBuilder.descr_append),
+ append_slice = interp2app(W_UnicodeBuilder.descr_append_slice),
+ build = interp2app(W_UnicodeBuilder.descr_build),
+)
+W_UnicodeBuilder.typedef.acceptable_as_base_class = False
\ No newline at end of file
diff --git a/pypy/module/__pypy__/interp_debug.py b/pypy/module/__pypy__/interp_debug.py
--- a/pypy/module/__pypy__/interp_debug.py
+++ b/pypy/module/__pypy__/interp_debug.py
@@ -1,15 +1,19 @@
from pypy.interpreter.gateway import interp2app, NoneNotWrapped, unwrap_spec
from pypy.interpreter.error import OperationError
-from pypy.rlib import debug
+from pypy.rlib import debug, jit
+
+ at jit.dont_look_inside
@unwrap_spec(category=str)
def debug_start(space, category):
debug.debug_start(category)
+ at jit.dont_look_inside
def debug_print(space, args_w):
parts = [space.str_w(space.str(w_item)) for w_item in args_w]
debug.debug_print(' '.join(parts))
+ at jit.dont_look_inside
@unwrap_spec(category=str)
def debug_stop(space, category):
debug.debug_stop(category)
diff --git a/pypy/module/__pypy__/test/test_builders.py b/pypy/module/__pypy__/test/test_builders.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_builders.py
@@ -0,0 +1,34 @@
+from pypy.conftest import gettestobjspace
+
+
+class AppTestBuilders(object):
+ def setup_class(cls):
+ cls.space = gettestobjspace(usemodules=['__pypy__'])
+
+ def test_simple(self):
+ from __pypy__.builders import UnicodeBuilder
+ b = UnicodeBuilder()
+ b.append(u"abc")
+ b.append(u"123")
+ b.append(u"1")
+ s = b.build()
+ assert s == u"abc1231"
+ raises(ValueError, b.build)
+ raises(ValueError, b.append, u"123")
+
+ def test_preallocate(self):
+ from __pypy__.builders import UnicodeBuilder
+ b = UnicodeBuilder(10)
+ b.append(u"abc")
+ b.append(u"123")
+ s = b.build()
+ assert s == u"abc123"
+
+ def test_append_slice(self):
+ from __pypy__.builders import UnicodeBuilder
+ b = UnicodeBuilder()
+ b.append_slice(u"abcdefgh", 2, 5)
+ raises(ValueError, b.append_slice, u"1", 2, 1)
+ s = b.build()
+ assert s == "cde"
+ raises(ValueError, b.append_slice, u"abc", 1, 2)
\ No newline at end of file
diff --git a/pypy/module/_stackless/test/test_greenlet.py b/pypy/module/_stackless/test/test_greenlet.py
--- a/pypy/module/_stackless/test/test_greenlet.py
+++ b/pypy/module/_stackless/test/test_greenlet.py
@@ -72,6 +72,23 @@
g1 = greenlet(f)
raises(ValueError, g2.switch)
+
+ def test_exc_info_save_restore(self):
+ from _stackless import greenlet
+ import sys
+ def f():
+ try:
+ raise ValueError('fun')
+ except:
+ exc_info = sys.exc_info()
+ greenlet(h).switch()
+ assert exc_info == sys.exc_info()
+
+ def h():
+ assert sys.exc_info() == (None, None, None)
+
+ greenlet(f).switch()
+
def test_exception(self):
from _stackless import greenlet
import sys
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -16,6 +16,7 @@
'absolute': 'interp_ufuncs.absolute',
'copysign': 'interp_ufuncs.copysign',
'exp': 'interp_ufuncs.exp',
+ 'floor': 'interp_ufuncs.floor',
'maximum': 'interp_ufuncs.maximum',
'minimum': 'interp_ufuncs.minimum',
'negative': 'interp_ufuncs.negative',
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -93,6 +93,10 @@
return 1.0 / value
@ufunc
+def floor(value):
+ return math.floor(value)
+
+ at ufunc
def sign(value):
if value == 0.0:
return 0.0
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -89,6 +89,15 @@
for i in range(4):
assert b[i] == reference[i]
+ def test_floor(self):
+ from numpy import array, floor
+
+ reference = [-2.0, -1.0, 0.0, 1.0, 1.0]
+ a = array([-1.4, -1.0, 0.0, 1.0, 1.4])
+ b = floor(a)
+ for i in range(5):
+ assert b[i] == reference[i]
+
def test_copysign(self):
from numpy import array, copysign
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -14,7 +14,8 @@
modname, _ = modname.split('.', 1)
if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions',
'imp', 'sys', 'array', '_ffi', 'itertools', 'operator',
- 'posix', '_socket', '_sre', '_lsprof', '_weakref']:
+ 'posix', '_socket', '_sre', '_lsprof', '_weakref',
+ '__pypy__']:
return True
return False
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -11,21 +11,14 @@
return 1 + rec(n-1)
#
# this loop is traced and then aborted, because the trace is too
- # long. But then "rec" is marked as "don't inline"
- i = 0
- j = 0
- while i < 20:
- i += 1
- j += rec(100)
- #
- # next time we try to trace "rec", instead of inlining we compile
- # it separately and generate a call_assembler
+ # long. But then "rec" is marked as "don't inline". Since we
+ # already traced function from the start (because of number),
+ # now we can inline it as call assembler
i = 0
j = 0
while i < 20:
i += 1
j += rec(100) # ID: call_rec
- a = 0
return j
#
log = self.run(fn, [], threshold=18)
@@ -38,6 +31,20 @@
...
""")
+ def test_fib(self):
+ def fib(n):
+ if n == 0 or n == 1:
+ return 1
+ return fib(n - 1) + fib(n - 2) # ID: call_rec
+
+ log = self.run(fib, [7], function_threshold=15)
+ loop, = log.loops_by_filename(self.filepath, is_entry_bridge='*')
+ #assert loop.match_by_id('call_rec', '''
+ #...
+ #p1 = call_assembler(..., descr=...)
+ #...
+ #''')
+
def test_simple_call(self):
src = """
OFFSET = 0
diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py
--- a/pypy/module/pypyjit/test_pypy_c/test_instance.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py
@@ -115,7 +115,6 @@
# ----------------------
loop, = log.loops_by_filename(self.filepath)
assert loop.match("""
- i8 = getfield_gc_pure(p5, descr=<SignedFieldDescr .*W_IntObject.inst_intval.*>)
i9 = int_lt(i8, i7)
guard_true(i9, descr=.*)
guard_not_invalidated(descr=.*)
@@ -125,7 +124,7 @@
p20 = new_with_vtable(ConstClass(W_IntObject))
setfield_gc(p20, i11, descr=<SignedFieldDescr.*W_IntObject.inst_intval .*>)
setfield_gc(ConstPtr(ptr21), p20, descr=<GcPtrFieldDescr .*TypeCell.inst_w_value .*>)
- jump(p0, p1, p2, p3, p4, p20, p6, i7, descr=<Loop.>)
+ jump(p0, p1, p2, p3, p4, p20, p6, i11, i7, descr=<Loop.>)
""")
def test_oldstyle_newstyle_mix(self):
diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py
--- a/pypy/rpython/lltypesystem/rdict.py
+++ b/pypy/rpython/lltypesystem/rdict.py
@@ -206,7 +206,7 @@
if dictobj is None:
return lltype.nullptr(self.DICT)
if not isinstance(dictobj, (dict, objectmodel.r_dict)):
- raise TyperError("expected a dict: %r" % (dictobj,))
+ raise TypeError("expected a dict: %r" % (dictobj,))
try:
key = Constant(dictobj)
return self.dict_cache[key]
diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py
--- a/pypy/rpython/lltypesystem/rstr.py
+++ b/pypy/rpython/lltypesystem/rstr.py
@@ -4,7 +4,7 @@
from pypy.rlib.objectmodel import malloc_zero_filled, we_are_translated
from pypy.rlib.objectmodel import _hash_string, enforceargs
from pypy.rlib.debug import ll_assert
-from pypy.rlib.jit import purefunction, we_are_jitted
+from pypy.rlib.jit import purefunction, we_are_jitted, dont_look_inside
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.robject import PyObjRepr, pyobj_repr
from pypy.rpython.rmodel import inputconst, IntegerRepr
@@ -57,6 +57,8 @@
llmemory.itemoffsetof(TP.chars, 0) +
llmemory.sizeof(CHAR_TP) * item)
+ # It'd be nice to be able to look inside this function.
+ @dont_look_inside
@enforceargs(None, None, int, int, int)
def copy_string_contents(src, dst, srcstart, dststart, length):
assert srcstart >= 0
@@ -323,6 +325,8 @@
return s
ll_str2unicode.oopspec = 'str.str2unicode(str)'
+ # it's pure but it does not look like it
+ @purefunction
def ll_strhash(s):
# unlike CPython, there is no reason to avoid to return -1
# but our malloc initializes the memory to zero, so we use zero as the
@@ -334,7 +338,6 @@
x = 29872897
s.hash = x
return x
- ll_strhash._pure_function_ = True # it's pure but it does not look like it
def ll_strfasthash(s):
return s.hash # assumes that the hash is already computed
More information about the pypy-commit
mailing list