[pypy-svn] r78013 - in pypy/branch/leak-finder/pypy/rlib/rsre: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Oct 16 16:38:29 CEST 2010
Author: arigo
Date: Sat Oct 16 16:38:26 2010
New Revision: 78013
Added:
pypy/branch/leak-finder/pypy/rlib/rsre/test/conftest.py
pypy/branch/leak-finder/pypy/rlib/rsre/test/test_zjit.py
Modified:
pypy/branch/leak-finder/pypy/rlib/rsre/rsre_core.py
Log:
In-progress. Start with some tests.
Modified: pypy/branch/leak-finder/pypy/rlib/rsre/rsre_core.py
==============================================================================
--- pypy/branch/leak-finder/pypy/rlib/rsre/rsre_core.py (original)
+++ pypy/branch/leak-finder/pypy/rlib/rsre/rsre_core.py Sat Oct 16 16:38:26 2010
@@ -4,6 +4,7 @@
from pypy.rlib.rsre import rsre_char
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib import jit
OPCODE_FAILURE = 0
@@ -56,15 +57,18 @@
_seen_specname[specname] = True
# Install a copy of the function under the name '_spec_funcname' in each
# concrete subclass
+ specialized_methods = []
for prefix, concreteclass in [('str', StrMatchContext),
('uni', UnicodeMatchContext)]:
newfunc = func_with_new_name(func, prefix + specname)
assert not hasattr(concreteclass, specname)
setattr(concreteclass, specname, newfunc)
+ specialized_methods.append(newfunc)
# Return a dispatcher function, specialized on the exact type of 'ctx'
def dispatch(ctx, *args):
return getattr(ctx, specname)(*args)
dispatch._annspecialcase_ = 'specialize:argtype(0)'
+ dispatch._specialized_methods_ = specialized_methods
return dispatch
# ____________________________________________________________
@@ -75,6 +79,7 @@
class AbstractMatchContext(object):
"""Abstract base class"""
+ _immutable_fields_ = ['pattern[*]', 'flags']
match_start = 0
match_end = 0
match_marks = None
@@ -238,6 +243,7 @@
self.start_ptr = ptr
self.start_marks = marks
+ @jit.unroll_safe
def find_first_result(self, ctx):
ppos = self.ppos
while ctx.pat(ppos):
@@ -250,6 +256,8 @@
find_next_result = find_first_result
class RepeatOneMatchResult(MatchResult):
+ jitdriver = jit.JitDriver(greens=['nextppos', 'pattern'],
+ reds=['ptr', 'self', 'ctx'])
def __init__(self, nextppos, minptr, ptr, marks):
self.nextppos = nextppos
@@ -259,8 +267,18 @@
def find_first_result(self, ctx):
ptr = self.start_ptr
+ nextppos = self.nextppos
while ptr >= self.minptr:
- result = sre_match(ctx, self.nextppos, ptr, self.start_marks)
+ #
+ pattern = ctx.pattern
+ self.jitdriver.can_enter_jit(self=self, ptr=ptr, ctx=ctx,
+ nextppos=nextppos, pattern=pattern)
+ self.jitdriver.jit_merge_point(self=self, ptr=ptr, ctx=ctx,
+ nextppos=nextppos, pattern=pattern)
+ if jit.we_are_jitted():
+ ctx.pattern = pattern
+ #
+ result = sre_match(ctx, nextppos, ptr, self.start_marks)
ptr -= 1
if result is not None:
self.subresult = result
@@ -270,6 +288,8 @@
class MinRepeatOneMatchResult(MatchResult):
+ jitdriver = jit.JitDriver(greens=['nextppos', 'ppos3', 'pattern'],
+ reds=['ptr', 'self', 'ctx'])
def __init__(self, nextppos, ppos3, maxptr, ptr, marks):
self.nextppos = nextppos
@@ -280,27 +300,39 @@
def find_first_result(self, ctx):
ptr = self.start_ptr
+ nextppos = self.nextppos
+ ppos3 = self.ppos3
while ptr <= self.maxptr:
- result = sre_match(ctx, self.nextppos, ptr, self.start_marks)
+ #
+ pattern = ctx.pattern
+ self.jitdriver.can_enter_jit(self=self, ptr=ptr, ctx=ctx,
+ nextppos=nextppos, pattern=pattern,
+ ppos3=ppos3)
+ self.jitdriver.jit_merge_point(self=self, ptr=ptr, ctx=ctx,
+ nextppos=nextppos, pattern=pattern,
+ ppos3=ppos3)
+ if jit.we_are_jitted():
+ ctx.pattern = pattern
+ #
+ result = sre_match(ctx, nextppos, ptr, self.start_marks)
if result is not None:
self.subresult = result
self.start_ptr = ptr
return self
- if not self.next_char_ok(ctx, ptr):
+ if not self.next_char_ok(ctx, ptr, ppos3):
break
ptr += 1
def find_next_result(self, ctx):
ptr = self.start_ptr
- if not self.next_char_ok(ctx, ptr):
+ if not self.next_char_ok(ctx, ptr, self.ppos3):
return
self.start_ptr = ptr + 1
return self.find_first_result(ctx)
- def next_char_ok(self, ctx, ptr):
+ def next_char_ok(self, ctx, ptr, ppos):
if ptr == ctx.end:
return False
- ppos = self.ppos3
op = ctx.pat(ppos)
for op1, (checkerfn, _) in unroll_char_checker:
if op1 == op:
@@ -429,6 +461,7 @@
# ____________________________________________________________
@specializectx
+ at jit.unroll_safe
def sre_match(ctx, ppos, ptr, marks):
"""Returns either None or a MatchResult object. Usually we only need
the first result, but there is the case of REPEAT...UNTIL where we
Added: pypy/branch/leak-finder/pypy/rlib/rsre/test/conftest.py
==============================================================================
--- (empty file)
+++ pypy/branch/leak-finder/pypy/rlib/rsre/test/conftest.py Sat Oct 16 16:38:26 2010
@@ -0,0 +1,5 @@
+# import the option --viewloops from the JIT
+
+def pytest_addoption(parser):
+ from pypy.jit.conftest import pytest_addoption
+ pytest_addoption(parser)
Added: pypy/branch/leak-finder/pypy/rlib/rsre/test/test_zjit.py
==============================================================================
--- (empty file)
+++ pypy/branch/leak-finder/pypy/rlib/rsre/test/test_zjit.py Sat Oct 16 16:38:26 2010
@@ -0,0 +1,69 @@
+from pypy.jit.metainterp.test import test_basic
+from pypy.rlib.nonconst import NonConstant
+from pypy.rlib.debug import make_sure_not_modified
+from pypy.rlib.rsre.test.test_match import get_code
+from pypy.rlib.rsre import rsre_core
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.annlowlevel import llstr, hlstr
+
+def entrypoint1(r, string):
+ r = array2list(r)
+ string = hlstr(string)
+ make_sure_not_modified(r)
+ match = rsre_core.match(r, string)
+ if match is None:
+ return -1
+ else:
+ return match.match_end
+
+def list2array(lst):
+ a = lltype.malloc(lltype.GcArray(lltype.Signed), len(lst))
+ for i, x in enumerate(lst):
+ a[i] = x
+ return a
+
+def array2list(a):
+ return [a[i] for i in range(len(a))]
+
+
+def test_jit_unroll_safe():
+ # test that the decorators are applied in the right order
+ assert not hasattr(rsre_core.sre_match, '_jit_unroll_safe_')
+ for m in rsre_core.sre_match._specialized_methods_:
+ assert m._jit_unroll_safe_
+
+
+class TestJitRSre(test_basic.LLJitMixin):
+
+ def meta_interp_match(self, pattern, string):
+ r = get_code(pattern)
+ return self.meta_interp(entrypoint1, [list2array(r), llstr(string)],
+ listcomp=True, backendopt=True)
+
+ def test_simple_match_1(self):
+ res = self.meta_interp_match(r"ab*bbbbbbbc", "abbbbbbbbbcdef")
+ assert res == 11
+
+ def test_simple_match_2(self):
+ res = self.meta_interp_match(r".*abc", "xxabcyyyyyyyyyyyyy")
+ assert res == 5
+
+ def test_match_minrepeat_1(self):
+ res = self.meta_interp_match(r".*?abc", "xxxxxxxxxxxxxxabc")
+ assert res == 17
+
+ #def test_match_maxuntil_1(self):
+ # res = self.meta_interp_match(r"(ab)*c", "ababababababababc")
+ # assert res == 17
+
+ def test_branch_1(self):
+ res = self.meta_interp_match(r".*?(ab|x)c", "xxxxxxxxxxxxxxabc")
+ assert res == 17
+
+ def test_match_minrepeat_2(self):
+ s = ("xxxxxxxxxxabbbbbbbbbb" +
+ "xxxxxxxxxxabbbbbbbbbb" +
+ "xxxxxxxxxxabbbbbbbbbb" +
+ "xxxxxxxxxxabbbbbbbbbbc")
+ res = self.meta_interp_match(r".*?ab+?c", s)
+ assert res == len(s)
More information about the Pypy-commit
mailing list