Author: Brian Kearns <bdkea...@gmail.com> Branch: Changeset: r73856:256a62fffbed Date: 2014-10-08 23:59 -0400 http://bitbucket.org/pypy/pypy/changeset/256a62fffbed/
Log: merge heads diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -12,3 +12,6 @@ Allocate by 4-byte chunks in rffi_platform, Skip testing objdump if it does not exist, and other small adjustments in own tests + +.. branch: rtyper-stuff +Small internal refactorings in the rtyper. diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py --- a/pypy/module/pypyjit/__init__.py +++ b/pypy/module/pypyjit/__init__.py @@ -7,6 +7,7 @@ interpleveldefs = { 'set_param': 'interp_jit.set_param', 'residual_call': 'interp_jit.residual_call', + 'not_from_assembler': 'interp_jit.W_NotFromAssembler', 'set_compile_hook': 'interp_resop.set_compile_hook', 'set_optimize_hook': 'interp_resop.set_optimize_hook', 'set_abort_hook': 'interp_resop.set_abort_hook', diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py --- a/pypy/module/pypyjit/interp_jit.py +++ b/pypy/module/pypyjit/interp_jit.py @@ -12,6 +12,9 @@ from pypy.interpreter.pycode import CO_GENERATOR from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import ExitFrame, Yield +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.gateway import interp2app from opcode import opmap @@ -144,3 +147,40 @@ '''For testing. Invokes callable(...), but without letting the JIT follow the call.''' return space.call_args(w_callable, __args__) + + +class W_NotFromAssembler(W_Root): + def __init__(self, space, w_callable): + self.space = space + self.w_callable = w_callable + def descr_call(self, __args__): + _call_not_in_trace(self.space, self.w_callable, __args__) + return self + +@jit.not_in_trace +def _call_not_in_trace(space, w_callable, __args__): + # this _call_not_in_trace() must return None + space.call_args(w_callable, __args__) + +def not_from_assembler_new(space, w_subtype, w_callable): + return W_NotFromAssembler(space, w_callable) + +W_NotFromAssembler.typedef = TypeDef("not_from_assembler", + __doc__ = """\ +A decorator that returns a callable that invokes the original +callable, but not from the JIT-produced assembler. It is called +from the interpreted mode, and from the JIT creation (pyjitpl) or +exiting (blackhole) steps, but just not from the final assembler. + +Note that the return value of the callable is ignored, because +there is no reasonable way to guess what it sound be in case the +function is not called. + +This is meant to be used notably in sys.settrace() for coverage- +like tools. For that purpose, if g = not_from_assembler(f), then +'g(*args)' may call 'f(*args)' but it always return g itself. +""", + __new__ = interp2app(not_from_assembler_new), + __call__ = interp2app(W_NotFromAssembler.descr_call), +) +W_NotFromAssembler.typedef.acceptable_as_base_class = False diff --git a/pypy/module/pypyjit/test/test_jit_not_in_trace.py b/pypy/module/pypyjit/test/test_jit_not_in_trace.py new file mode 100644 --- /dev/null +++ b/pypy/module/pypyjit/test/test_jit_not_in_trace.py @@ -0,0 +1,19 @@ + +class AppTestJitNotInTrace(object): + spaceconfig = dict(usemodules=('pypyjit',)) + + def test_not_from_assembler(self): + import pypyjit + @pypyjit.not_from_assembler + def f(x, y): + return 42 + r = f(3, 4) + assert r is f + + def test_not_from_assembler_exception(self): + import pypyjit + @pypyjit.not_from_assembler + def f(x, y): + raise ValueError(y, x) + e = raises(ValueError, f, 3, 4) + assert e.value.args == (4, 3) diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py --- a/rpython/jit/codewriter/effectinfo.py +++ b/rpython/jit/codewriter/effectinfo.py @@ -25,6 +25,7 @@ OS_THREADLOCALREF_GET = 5 # llop.threadlocalref_get OS_GET_ERRNO = 6 # rposix.get_errno OS_SET_ERRNO = 7 # rposix.set_errno + OS_NOT_IN_TRACE = 8 # for calls not recorded in the jit trace # OS_STR_CONCAT = 22 # "stroruni.concat" OS_STR_SLICE = 23 # "stroruni.slice" @@ -96,6 +97,7 @@ _OS_CANRAISE = set([ OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL, OS_RAW_MALLOC_VARSIZE_CHAR, OS_JIT_FORCE_VIRTUAL, OS_SHRINK_ARRAY, OS_DICT_LOOKUP, + OS_NOT_IN_TRACE, ]) def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays, diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -1562,7 +1562,17 @@ kind = getkind(args[0].concretetype) return SpaceOperation('%s_isvirtual' % kind, args, op.result) elif oopspec_name == 'jit.force_virtual': - return self._handle_oopspec_call(op, args, EffectInfo.OS_JIT_FORCE_VIRTUAL, EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE) + return self._handle_oopspec_call(op, args, + EffectInfo.OS_JIT_FORCE_VIRTUAL, + EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE) + elif oopspec_name == 'jit.not_in_trace': + # ignore 'args' and use the original 'op.args' + if op.result.concretetype is not lltype.Void: + raise Exception( + "%r: jit.not_in_trace() function must return None" + % (op.args[0],)) + return self._handle_oopspec_call(op, op.args[1:], + EffectInfo.OS_NOT_IN_TRACE) else: raise AssertionError("missing support for %r" % oopspec_name) diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1393,6 +1393,9 @@ # allboxes = self._build_allboxes(funcbox, argboxes, descr) effectinfo = descr.get_extra_info() + if effectinfo.oopspecindex == effectinfo.OS_NOT_IN_TRACE: + return self.metainterp.do_not_in_trace_call(allboxes, descr) + if (assembler_call or effectinfo.check_forces_virtual_or_virtualizable()): # residual calls require attention to keep virtualizables in-sync @@ -2830,6 +2833,19 @@ if not we_are_translated(): # for llgraph descr._original_func_ = op.getarg(0).value + def do_not_in_trace_call(self, allboxes, descr): + self.clear_exception() + resbox = executor.execute_varargs(self.cpu, self, rop.CALL, + allboxes, descr) + assert resbox is None + if self.last_exc_value_box is not None: + # cannot trace this! it raises, so we have to follow the + # exception-catching path, but the trace doesn't contain + # the call at all + raise SwitchToBlackhole(Counters.ABORT_ESCAPE, + raising_exception=True) + return None + # ____________________________________________________________ class ChangeFrame(jitexc.JitException): diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -4044,3 +4044,70 @@ res = self.interp_operations(f, [17]) assert res == 42 self.check_operations_history(guard_true=1, guard_false=0) + + def test_not_in_trace(self): + class X: + n = 0 + def g(x): + if we_are_jitted(): + raise NotImplementedError + x.n += 1 + g.oopspec = 'jit.not_in_trace()' + + jitdriver = JitDriver(greens=[], reds=['n', 'token', 'x']) + def f(n): + token = 0 + x = X() + while n >= 0: + jitdriver.jit_merge_point(n=n, x=x, token=token) + if not we_are_jitted(): + token += 1 + g(x) + n -= 1 + return x.n + token * 1000 + + res = self.meta_interp(f, [10]) + assert res == 2003 # two runs before jitting; then one tracing run + self.check_resops(int_add=0, call=0, call_may_force=0) + + def test_not_in_trace_exception(self): + def g(): + if we_are_jitted(): + raise NotImplementedError + raise ValueError + g.oopspec = 'jit.not_in_trace()' + + jitdriver = JitDriver(greens=[], reds=['n']) + def f(n): + while n >= 0: + jitdriver.jit_merge_point(n=n) + try: + g() + except ValueError: + n -= 1 + return 42 + + res = self.meta_interp(f, [10]) + assert res == 42 + self.check_aborted_count(3) + + def test_not_in_trace_blackhole(self): + class X: + seen = 0 + def g(x): + if we_are_jitted(): + raise NotImplementedError + x.seen = 42 + g.oopspec = 'jit.not_in_trace()' + + jitdriver = JitDriver(greens=[], reds=['n']) + def f(n): + while n >= 0: + jitdriver.jit_merge_point(n=n) + n -= 1 + x = X() + g(x) + return x.seen + + res = self.meta_interp(f, [10]) + assert res == 42 diff --git a/rpython/rlib/_stacklet_n_a.py b/rpython/rlib/_stacklet_n_a.py --- a/rpython/rlib/_stacklet_n_a.py +++ b/rpython/rlib/_stacklet_n_a.py @@ -1,33 +1,35 @@ from rpython.rlib import _rffi_stacklet as _c -from rpython.rlib import objectmodel, debug +from rpython.rlib import debug +from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.rtyper.annlowlevel import llhelper -from rpython.tool.staticmethods import StaticMethods -class StackletGcRootFinder: - __metaclass__ = StaticMethods - +class StackletGcRootFinder(object): + @staticmethod + @specialize.arg(1) def new(thrd, callback, arg): h = _c.new(thrd._thrd, llhelper(_c.run_fn, callback), arg) if not h: raise MemoryError return h - new._annspecialcase_ = 'specialize:arg(1)' + @staticmethod def switch(h): h = _c.switch(h) if not h: raise MemoryError return h + @staticmethod def destroy(thrd, h): _c.destroy(thrd._thrd, h) - if objectmodel.we_are_translated(): + if we_are_translated(): debug.debug_print("not using a framework GC: " "stacklet_destroy() may leak") - is_empty_handle = _c.is_empty_handle + is_empty_handle = staticmethod(_c.is_empty_handle) + @staticmethod def get_null_handle(): return _c.null_handle diff --git a/rpython/rlib/_stacklet_shadowstack.py b/rpython/rlib/_stacklet_shadowstack.py --- a/rpython/rlib/_stacklet_shadowstack.py +++ b/rpython/rlib/_stacklet_shadowstack.py @@ -3,7 +3,6 @@ from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.tool.staticmethods import StaticMethods NULL_SUSPSTACK = lltype.nullptr(llmemory.GCREF.TO) @@ -68,9 +67,7 @@ return oldsuspstack -class StackletGcRootFinder: - __metaclass__ = StaticMethods - +class StackletGcRootFinder(object): def new(thrd, callback, arg): gcrootfinder.callback = callback thread_handle = thrd._thrd @@ -78,6 +75,7 @@ h = _c.new(thread_handle, llhelper(_c.run_fn, _new_callback), arg) return get_result_suspstack(h) new._dont_inline_ = True + new = staticmethod(new) def switch(suspstack): # suspstack has a handle to target, i.e. where to switch to @@ -90,10 +88,13 @@ h = _c.switch(h) return get_result_suspstack(h) switch._dont_inline_ = True + switch = staticmethod(switch) + @staticmethod def is_empty_handle(suspstack): return not suspstack + @staticmethod def get_null_handle(): return NULL_SUSPSTACK diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -194,6 +194,14 @@ return func return decorator +def not_in_trace(func): + """A decorator for a function with no return value. It makes the + function call disappear from the jit traces. It is still called in + interpreted mode, and by the jit tracing and blackholing, but not + by the final assembler.""" + func.oopspec = "jit.not_in_trace()" # note that 'func' may take arguments + return func + @oopspec("jit.isconstant(value)") def isconstant(value): """ diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -191,6 +191,11 @@ def _is_varsize(self): return False + def _contains_value(self, value): + if self is Void: + return True + return isCompatibleType(typeOf(value), self) + NFOUND = object() class ContainerType(LowLevelType): diff --git a/rpython/rtyper/lltypesystem/rbytearray.py b/rpython/rtyper/lltypesystem/rbytearray.py --- a/rpython/rtyper/lltypesystem/rbytearray.py +++ b/rpython/rtyper/lltypesystem/rbytearray.py @@ -38,12 +38,14 @@ i += s.length() cls.ll_strsetitem_nonneg(s, i, item) + @staticmethod def ll_strsetitem_nonneg(s, i, item): chars = s.chars ll_assert(i >= 0, "negative str getitem index") ll_assert(i < len(chars), "str getitem index out of bound") chars[i] = chr(item) + @staticmethod def ll_stritem_nonneg(s, i): return ord(rstr.LLHelpers.ll_stritem_nonneg(s, i)) diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -270,6 +270,7 @@ class LLHelpers(AbstractLLHelpers): from rpython.rtyper.annlowlevel import llstr, llunicode + @staticmethod @jit.elidable def ll_str_mul(s, times): if times < 0: @@ -292,6 +293,7 @@ i += j return newstr + @staticmethod @jit.elidable def ll_char_mul(ch, times): if typeOf(ch) is Char: @@ -308,9 +310,11 @@ j += 1 return newstr + @staticmethod def ll_strlen(s): return len(s.chars) + @staticmethod @signature(types.any(), types.int(), returns=types.any()) def ll_stritem_nonneg(s, i): chars = s.chars @@ -318,6 +322,7 @@ ll_assert(i < len(chars), "str getitem index out of bound") return chars[i] + @staticmethod def ll_chr2str(ch): if typeOf(ch) is Char: malloc = mallocstr @@ -328,6 +333,7 @@ return s # @jit.look_inside_iff(lambda str: jit.isconstant(len(str.chars)) and len(str.chars) == 1) + @staticmethod @jit.oopspec("str.str2unicode(str)") def ll_str2unicode(str): lgt = len(str.chars) @@ -338,6 +344,7 @@ s.chars[i] = cast_primitive(UniChar, str.chars[i]) return s + @staticmethod def ll_str2bytearray(str): from rpython.rtyper.lltypesystem.rbytearray import BYTEARRAY @@ -347,6 +354,7 @@ b.chars[i] = str.chars[i] return b + @staticmethod @jit.elidable def ll_strhash(s): # unlike CPython, there is no reason to avoid to return -1 @@ -362,13 +370,17 @@ s.hash = x return x + @staticmethod def ll_length(s): return len(s.chars) + @staticmethod def ll_strfasthash(s): return s.hash # assumes that the hash is already computed + @staticmethod @jit.elidable + @jit.oopspec('stroruni.concat(s1, s2)') def ll_strconcat(s1, s2): len1 = s1.length() len2 = s2.length() @@ -386,8 +398,8 @@ else: newstr.copy_contents(s2, newstr, 0, len1, len2) return newstr - ll_strconcat.oopspec = 'stroruni.concat(s1, s2)' + @staticmethod @jit.elidable def ll_strip(s, ch, left, right): s_len = len(s.chars) @@ -408,6 +420,7 @@ s.copy_contents(s, result, lpos, 0, r_len) return result + @staticmethod @jit.elidable def ll_strip_default(s, left, right): s_len = len(s.chars) @@ -428,6 +441,7 @@ s.copy_contents(s, result, lpos, 0, r_len) return result + @staticmethod @jit.elidable def ll_strip_multiple(s, s2, left, right): s_len = len(s.chars) @@ -448,6 +462,7 @@ s.copy_contents(s, result, lpos, 0, r_len) return result + @staticmethod @jit.elidable def ll_upper(s): s_chars = s.chars @@ -462,6 +477,7 @@ i += 1 return result + @staticmethod @jit.elidable def ll_lower(s): s_chars = s.chars @@ -476,6 +492,7 @@ i += 1 return result + @staticmethod def ll_join(s, length, items): s_chars = s.chars s_len = len(s_chars) @@ -509,7 +526,9 @@ i += 1 return result + @staticmethod @jit.elidable + @jit.oopspec('stroruni.cmp(s1, s2)') def ll_strcmp(s1, s2): if not s1 and not s2: return True @@ -531,9 +550,10 @@ return diff i += 1 return len1 - len2 - ll_strcmp.oopspec = 'stroruni.cmp(s1, s2)' + @staticmethod @jit.elidable + @jit.oopspec('stroruni.equal(s1, s2)') def ll_streq(s1, s2): if s1 == s2: # also if both are NULLs return True @@ -551,8 +571,8 @@ return False j += 1 return True - ll_streq.oopspec = 'stroruni.equal(s1, s2)' + @staticmethod @jit.elidable def ll_startswith(s1, s2): len1 = len(s1.chars) @@ -569,11 +589,13 @@ return True + @staticmethod def ll_startswith_char(s, ch): if not len(s.chars): return False return s.chars[0] == ch + @staticmethod @jit.elidable def ll_endswith(s1, s2): len1 = len(s1.chars) @@ -591,11 +613,13 @@ return True + @staticmethod def ll_endswith_char(s, ch): if not len(s.chars): return False return s.chars[len(s.chars) - 1] == ch + @staticmethod @jit.elidable @signature(types.any(), types.any(), types.int(), types.int(), returns=types.int()) def ll_find_char(s, ch, start, end): @@ -608,6 +632,7 @@ i += 1 return -1 + @staticmethod @jit.elidable def ll_rfind_char(s, ch, start, end): if end > len(s.chars): @@ -619,6 +644,7 @@ return i return -1 + @staticmethod @jit.elidable def ll_count_char(s, ch, start, end): count = 0 @@ -631,6 +657,7 @@ i += 1 return count + @staticmethod @signature(types.any(), types.any(), types.int(), types.int(), returns=types.int()) def ll_find(s1, s2, start, end): if start < 0: @@ -646,6 +673,7 @@ return LLHelpers.ll_search(s1, s2, start, end, FAST_FIND) + @staticmethod @signature(types.any(), types.any(), types.int(), types.int(), returns=types.int()) def ll_rfind(s1, s2, start, end): if start < 0: @@ -681,6 +709,7 @@ res = 0 return res + @staticmethod @jit.elidable def ll_search(s1, s2, start, end, mode): count = 0 @@ -768,6 +797,7 @@ return -1 return count + @staticmethod @signature(types.int(), types.any(), returns=types.any()) @jit.look_inside_iff(lambda length, items: jit.loop_unrolling_heuristic( items, length)) @@ -802,6 +832,7 @@ i += 1 return result + @staticmethod @jit.look_inside_iff(lambda length, chars, RES: jit.isconstant(length) and jit.isvirtual(chars)) def ll_join_chars(length, chars, RES): # no need to optimize this, will be replaced by string builder @@ -821,6 +852,7 @@ i += 1 return result + @staticmethod @jit.oopspec('stroruni.slice(s1, start, stop)') @signature(types.any(), types.int(), types.int(), returns=types.any()) @jit.elidable @@ -836,9 +868,11 @@ s1.copy_contents(s1, newstr, start, 0, lgt) return newstr + @staticmethod def ll_stringslice_startonly(s1, start): return LLHelpers._ll_stringslice(s1, start, len(s1.chars)) + @staticmethod @signature(types.any(), types.int(), types.int(), returns=types.any()) def ll_stringslice_startstop(s1, start, stop): if jit.we_are_jitted(): @@ -851,10 +885,12 @@ stop = len(s1.chars) return LLHelpers._ll_stringslice(s1, start, stop) + @staticmethod def ll_stringslice_minusone(s1): newlen = len(s1.chars) - 1 return LLHelpers._ll_stringslice(s1, 0, newlen) + @staticmethod def ll_split_chr(LIST, s, c, max): chars = s.chars strlen = len(chars) @@ -889,6 +925,7 @@ item.copy_contents(s, item, i, 0, j - i) return res + @staticmethod def ll_split(LIST, s, c, max): count = 1 if max == -1: @@ -920,6 +957,7 @@ item.copy_contents(s, item, prev_pos, 0, last - prev_pos) return res + @staticmethod def ll_rsplit_chr(LIST, s, c, max): chars = s.chars strlen = len(chars) @@ -955,6 +993,7 @@ item.copy_contents(s, item, j, 0, i - j) return res + @staticmethod def ll_rsplit(LIST, s, c, max): count = 1 if max == -1: @@ -986,6 +1025,7 @@ item.copy_contents(s, item, 0, 0, prev_pos) return res + @staticmethod @jit.elidable def ll_replace_chr_chr(s, c1, c2): length = len(s.chars) @@ -1001,6 +1041,7 @@ j += 1 return newstr + @staticmethod @jit.elidable def ll_contains(s, c): chars = s.chars @@ -1012,6 +1053,7 @@ i += 1 return False + @staticmethod @jit.elidable def ll_int(s, base): if not 2 <= base <= 36: @@ -1068,23 +1110,29 @@ # ll_build_push(x, next_string, n-1) # s = ll_build_finish(x) + @staticmethod def ll_build_start(parts_count): return malloc(TEMP, parts_count) + @staticmethod def ll_build_push(builder, next_string, index): builder[index] = next_string + @staticmethod def ll_build_finish(builder): return LLHelpers.ll_join_strs(len(builder), builder) + @staticmethod @specialize.memo() def ll_constant(s): return string_repr.convert_const(s) + @staticmethod @specialize.memo() def ll_constant_unicode(s): return unicode_repr.convert_const(s) + @classmethod def do_stringformat(cls, hop, sourcevarsrepr): s_str = hop.args_s[0] assert s_str.is_constant() @@ -1150,8 +1198,8 @@ hop.exception_cannot_occur() # to ignore the ZeroDivisionError of '%' return hop.gendirectcall(cls.ll_join_strs, size, vtemp) - do_stringformat = classmethod(do_stringformat) + @staticmethod @jit.dont_look_inside def ll_string2list(RESLIST, src): length = len(src.chars) diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py --- a/rpython/rtyper/rmodel.py +++ b/rpython/rtyper/rmodel.py @@ -2,8 +2,7 @@ from rpython.flowspace.model import Constant from rpython.rtyper.error import TyperError, MissingRTypeOperation from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.lltypesystem.lltype import (Void, Bool, typeOf, - LowLevelType, isCompatibleType) +from rpython.rtyper.lltypesystem.lltype import Void, Bool, LowLevelType from rpython.tool.pairtype import pairtype, extendabletype, pair @@ -120,14 +119,9 @@ def convert_const(self, value): "Convert the given constant value to the low-level repr of 'self'." - if self.lowleveltype is not Void: - try: - realtype = typeOf(value) - except (AssertionError, AttributeError, TypeError): - realtype = '???' - if realtype != self.lowleveltype: - raise TyperError("convert_const(self = %r, value = %r)" % ( - self, value)) + if not self.lowleveltype._contains_value(value): + raise TyperError("convert_const(self = %r, value = %r)" % ( + self, value)) return value def get_ll_eq_function(self): @@ -356,18 +350,9 @@ lltype = reqtype else: raise TypeError(repr(reqtype)) - # Void Constants can hold any value; - # non-Void Constants must hold a correctly ll-typed value - if lltype is not Void: - try: - realtype = typeOf(value) - except (AssertionError, AttributeError): - realtype = '???' - if not isCompatibleType(realtype, lltype): - raise TyperError("inputconst(reqtype = %s, value = %s):\n" - "expected a %r,\n" - " got a %r" % (reqtype, value, - lltype, realtype)) + if not lltype._contains_value(value): + raise TyperError("inputconst(): expected a %r, got %r" % + (lltype, value)) c = Constant(value) c.concretetype = lltype return c @@ -422,7 +407,8 @@ def __ne__(self, other): return not (self == other) - def build_ll_dummy_value(self): + @property + def ll_dummy_value(self): TYPE = self.TYPE try: return self.rtyper.cache_dummy_values[TYPE] @@ -435,8 +421,6 @@ self.rtyper.cache_dummy_values[TYPE] = p return p - ll_dummy_value = property(build_ll_dummy_value) - # logging/warning diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py --- a/rpython/rtyper/rstr.py +++ b/rpython/rtyper/rstr.py @@ -9,7 +9,6 @@ from rpython.rtyper.rfloat import FloatRepr from rpython.tool.pairtype import pairtype, pair from rpython.tool.sourcetools import func_with_new_name -from rpython.tool.staticmethods import StaticMethods from rpython.rlib.rstring import UnicodeBuilder @@ -800,10 +799,8 @@ # get flowed and annotated, mostly with SomePtr. # -# this class contains low level helpers used both by lltypesystem -class AbstractLLHelpers: - __metaclass__ = StaticMethods - +class AbstractLLHelpers(object): + @staticmethod def ll_isdigit(s): from rpython.rtyper.annlowlevel import hlstr @@ -815,6 +812,7 @@ return False return True + @staticmethod def ll_isalpha(s): from rpython.rtyper.annlowlevel import hlstr @@ -826,6 +824,7 @@ return False return True + @staticmethod def ll_isalnum(s): from rpython.rtyper.annlowlevel import hlstr @@ -837,14 +836,17 @@ return False return True + @staticmethod def ll_char_isspace(ch): c = ord(ch) return c == 32 or (9 <= c <= 13) # c in (9, 10, 11, 12, 13, 32) + @staticmethod def ll_char_isdigit(ch): c = ord(ch) return c <= 57 and c >= 48 + @staticmethod def ll_char_isalpha(ch): c = ord(ch) if c >= 97: @@ -852,6 +854,7 @@ else: return 65 <= c <= 90 + @staticmethod def ll_char_isalnum(ch): c = ord(ch) if c >= 65: @@ -862,47 +865,54 @@ else: return 48 <= c <= 57 + @staticmethod def ll_char_isupper(ch): c = ord(ch) return 65 <= c <= 90 + @staticmethod def ll_char_islower(ch): c = ord(ch) return 97 <= c <= 122 + @staticmethod def ll_upper_char(ch): if 'a' <= ch <= 'z': ch = chr(ord(ch) - 32) return ch + @staticmethod def ll_lower_char(ch): if 'A' <= ch <= 'Z': ch = chr(ord(ch) + 32) return ch + @staticmethod def ll_char_hash(ch): return ord(ch) + @staticmethod def ll_unichar_hash(ch): return ord(ch) + @classmethod def ll_str_is_true(cls, s): # check if a string is True, allowing for None return bool(s) and cls.ll_strlen(s) != 0 - ll_str_is_true = classmethod(ll_str_is_true) + @classmethod def ll_stritem_nonneg_checked(cls, s, i): if i >= cls.ll_strlen(s): raise IndexError return cls.ll_stritem_nonneg(s, i) - ll_stritem_nonneg_checked = classmethod(ll_stritem_nonneg_checked) + @classmethod def ll_stritem(cls, s, i): if i < 0: i += cls.ll_strlen(s) return cls.ll_stritem_nonneg(s, i) - ll_stritem = classmethod(ll_stritem) + @classmethod def ll_stritem_checked(cls, s, i): length = cls.ll_strlen(s) if i < 0: @@ -910,8 +920,8 @@ if i >= length or i < 0: raise IndexError return cls.ll_stritem_nonneg(s, i) - ll_stritem_checked = classmethod(ll_stritem_checked) + @staticmethod def parse_fmt_string(fmt): # we support x, d, s, f, [r] it = iter(fmt) @@ -937,6 +947,7 @@ r.append(curstr) return r + @staticmethod def ll_float(ll_str): from rpython.rtyper.annlowlevel import hlstr from rpython.rlib.rfloat import rstring_to_float @@ -961,6 +972,7 @@ assert end >= 0 return rstring_to_float(s[beg:end + 1]) + @classmethod def ll_splitlines(cls, LIST, ll_str, keep_newlines): from rpython.rtyper.annlowlevel import hlstr s = hlstr(ll_str) @@ -991,4 +1003,3 @@ item = cls.ll_stringslice_startstop(ll_str, j, strlen) res.ll_setitem_fast(list_length, item) return res - ll_splitlines = classmethod(ll_splitlines) diff --git a/rpython/tool/staticmethods.py b/rpython/tool/staticmethods.py deleted file mode 100644 --- a/rpython/tool/staticmethods.py +++ /dev/null @@ -1,14 +0,0 @@ -import types -class AbstractMethods(type): - def __new__(cls, cls_name, bases, cls_dict): - for key, value in cls_dict.iteritems(): - if isinstance(value, types.FunctionType): - cls_dict[key] = cls.decorator(value) - return type.__new__(cls, cls_name, bases, cls_dict) - - -class StaticMethods(AbstractMethods): - """ - Metaclass that turns plain methods into staticmethods. - """ - decorator = staticmethod _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit