Commit bdf1058f authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Buffer bounds checking can be turned off via compilation options

--HG--
rename : tests/run/options.pyx => tests/compile/c_options.pyx
parent c19b1ad4
......@@ -235,7 +235,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
code.putln('}')
def put_access(entry, index_signeds, index_cnames, pos, code):
def put_access(entry, index_signeds, index_cnames, options, pos, code):
"""Returns a c string which can be used to access the buffer
for reading or writing.
......@@ -244,45 +244,42 @@ def put_access(entry, index_signeds, index_cnames, pos, code):
body. The lookup however is delegated to a inline function that is instantiated
once per ndim (lookup with suboffsets tend to get quite complicated).
"""
code.globalstate.use_utility_code(access_utility_code)
bufaux = entry.buffer_aux
bufstruct = bufaux.buffer_info_var.cname
# Check bounds and fix negative indices
boundscheck = True
nonegs = True
tmp_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type)
if boundscheck:
if options['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
# error is occuring at.
tmp_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type)
code.putln("%s = -1;" % tmp_cname)
for idx, (signed, cname, shape) in enumerate(zip(index_signeds, index_cnames,
for dim, (signed, cname, shape) in enumerate(zip(index_signeds, index_cnames,
bufaux.shapevars)):
if signed != 0:
nonegs = False
# not unsigned, deal with negative index
code.putln("if (%s < 0) {" % cname)
code.putln("%s += %s;" % (cname, shape.cname))
if boundscheck:
code.putln("if (%s) %s = %d;" % (
code.unlikely("%s < 0" % cname), tmp_cname, idx))
code.unlikely("%s < 0" % cname), tmp_cname, dim))
code.put("} else ")
else:
if idx > 0: code.put("else ")
if boundscheck:
# check bounds in positive direction
code.putln("if (%s) %s = %d;" % (
code.unlikely("%s >= %s" % (cname, shape.cname)),
tmp_cname, idx))
if boundscheck:
tmp_cname, dim))
code.globalstate.use_utility_code(raise_indexerror_code)
code.put("if (%s) " % code.unlikely("%s != -1" % tmp_cname))
code.begin_block()
code.putln('__Pyx_BufferIndexError(%s);' % tmp_cname)
code.putln('__Pyx_RaiseBufferIndexError(%s);' % tmp_cname)
code.putln(code.error_goto(pos))
code.end_block()
code.funcstate.release_temp(tmp_cname)
else:
# Only fix negative indices.
for signed, cname, shape in zip(index_signeds, index_cnames,
bufaux.shapevars):
if signed != 0:
code.putln("if (%s < 0) %s += %s;" % (cname, cname, shape.cname))
# Create buffer lookup and return it
params = []
......@@ -536,11 +533,11 @@ def use_py2_buffer_functions(env):
# Utility function to set the right exception
# The caller should immediately goto_error
access_utility_code = [
raise_indexerror_code = [
"""\
static void __Pyx_BufferIndexError(int axis); /*proto*/
static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/
""","""\
static void __Pyx_BufferIndexError(int axis) {
static void __Pyx_RaiseBufferIndexError(int axis) {
PyErr_Format(PyExc_IndexError,
"Out of bounds on buffer access (axis %d)", axis);
}
......
......@@ -104,7 +104,7 @@ def report_error(err):
def error(position, message):
#print "Errors.error:", repr(position), repr(message) ###
err = CompileError(position, message)
# if position is not None: raise Exception(err) # debug
#if position is not None: raise Exception(err) # debug
report_error(err)
return err
......
......@@ -1525,7 +1525,6 @@ class IndexNode(ExprNode):
self.generate_subexpr_disposal_code(code)
def buffer_access_code(self, code):
print self.options
# Assign indices to temps
index_temps = [code.funcstate.allocate_temp(i.type) for i in self.indices]
for temp, index in zip(index_temps, self.indices):
......@@ -1535,7 +1534,9 @@ class IndexNode(ExprNode):
valuecode = Buffer.put_access(entry=self.base.entry,
index_signeds=[i.type.signed for i in self.indices],
index_cnames=index_temps,
options=self.options,
pos=self.pos, code=code)
return valuecode
......
#cython: boundscheck=False
print 3
def f(object[int, 2] buf):
print buf[3, 2]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment