Author: Ilya Osadchiy <osadchiy.i...@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 + +@jit.dont_look_inside @unwrap_spec(category=str) def debug_start(space, category): debug.debug_start(category) +@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)) +@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) + +@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit