wraparound directive implemented
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Wed, 6 May 2009 18:26:30 +0000 (20:26 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Wed, 6 May 2009 18:26:30 +0000 (20:26 +0200)
Cython/Compiler/Buffer.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Options.py
tests/run/bufaccess.pyx

index 7724fadef01101d4ddff098cb366f8e3d8f84833..df019beeb06a7b985d377a50e2a0e0121dbb1a11 100644 (file)
@@ -330,7 +330,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
 
     code.putln("}") # Release stack
 
-def put_buffer_lookup_code(entry, index_signeds, index_cnames, options, pos, code):
+def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos, code):
     """
     Generates code to process indices and calculate an offset into
     a buffer. Returns a C string which gives a pointer which can be
@@ -345,9 +345,9 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, options, pos, cod
     """
     bufaux = entry.buffer_aux
     bufstruct = bufaux.buffer_info_var.cname
-    negative_indices = entry.type.negative_indices
+    negative_indices = directives['wraparound'] and entry.type.negative_indices
 
-    if options['boundscheck']:
+    if directives['boundscheck']:
         # Check bounds and fix negative indices.
         # We allocate a temporary which is initialized to -1, meaning OK (!).
         # If an error occurs, the temp is set to the dimension index the
index 5b61722406b37a4c7a569ae6713e06d7b677a7dc..99c447fbf645356c50b8cad376a9447adc09f821 100644 (file)
@@ -1958,7 +1958,7 @@ class IndexNode(ExprNode):
         return Buffer.put_buffer_lookup_code(entry=self.base.entry,
                                              index_signeds=[i.type.signed for i in self.indices],
                                              index_cnames=index_temps,
-                                             options=code.globalstate.directives,
+                                             directives=code.globalstate.directives,
                                              pos=self.pos, code=code)
 
     def put_nonecheck(self, code):
index 06f7024475bf48f8450f62b372dd287435bdc8ae..faaec3cd19d4720044d7057040ead1c328f3d402 100644 (file)
@@ -54,7 +54,7 @@ c_line_in_traceback = 1
 embed = False
 
 
-# Declare pragmas
+# Declare compiler directives
 option_defaults = {
     'boundscheck' : True,
     'nonecheck' : False,
@@ -64,6 +64,7 @@ option_defaults = {
     'cdivision': True,  # Will be False in 0.12
     'cdivision_warnings': False,
     'always_allow_keywords': False,
+    'wraparound' : True
 }
 
 # Override types possibilities above, if needed
index eb4c10ba029eabb74de8dfdf7c8b1b0e0e77ae46..db65dcac1570b432e2d5cce5886808f0b3643e79 100644 (file)
@@ -478,6 +478,26 @@ def no_negative_indices(object[int, negative_indices=False] buf, int idx):
     """
     return buf[idx]
 
+@testcase
+@cython.wraparound(False)
+def wraparound_directive(object[int] buf, int pos_idx, int neg_idx):
+    """
+    Again, the most interesting thing here is to inspect the C source.
+    
+    >>> A = IntMockBuffer(None, range(4))
+    >>> wraparound_directive(A, 2, -1)
+    5
+    >>> wraparound_directive(A, -1, 2)
+    Traceback (most recent call last):
+        ...
+    IndexError: Out of bounds on buffer access (axis 0)
+    """
+    cdef int byneg
+    with cython.wraparound(True):
+        byneg = buf[neg_idx]
+    return buf[pos_idx] + byneg
+
+
 #
 # Test which flags are passed.
 #