Commit 974520e5 authored by Stefan Behnel's avatar Stefan Behnel

merge from 0.9.6.6

parents 523ba29c a1e80790
......@@ -22,6 +22,8 @@ Options:
-z, --pre-import <module> If specified, assume undeclared names in this
module. Emulates the behavior of putting
"from <module> import *" at the top of the file.
--incref-local-binop Force local an extra incref on local variables before
performing any binary operations.
"""
#The following experimental options are supported only on MacOSX:
# -C, --compile Compile generated .c file to .o file
......@@ -76,6 +78,8 @@ def parse_command_line(args):
Options.embed_pos_in_docstring = 1
elif option in ("-z", "--pre-import"):
Options.pre_import = pop_arg()
elif option == "--incref-local-binop":
Options.incref_local_binop = 1
else:
bad_usage()
else:
......
......@@ -1626,7 +1626,8 @@ class AttributeNode(ExprNode):
self.obj.analyse_types(env)
self.analyse_attribute(env)
if self.entry and self.entry.is_cmethod and not self.is_called:
error(self.pos, "C method can only be called")
# error(self.pos, "C method can only be called")
pass
## Reference to C array turns into pointer to first element.
#while self.type.is_array:
# self.type = self.type.element_ptr_type()
......@@ -2430,6 +2431,8 @@ class BinopNode(ExprNode):
self.coerce_operands_to_pyobjects(env)
self.type = py_object_type
self.is_temp = 1
if Options.incref_local_binop and self.operand1.type.is_pyobject:
self.operand1 = self.operand1.coerce_to_temp(env)
else:
self.analyse_c_operation(env)
......@@ -2610,6 +2613,15 @@ class PowNode(NumBinopNode):
def c_types_okay(self, type1, type2):
return type1.is_float or type2.is_float
def type_error(self):
if not (self.operand1.type.is_error or self.operand2.type.is_error):
if self.operand1.type.is_int and self.operand2.type.is_int:
error(self.pos, "C has no integer powering, use python ints or floats instead '%s' (%s; %s)" %
(self.operator, self.operand1.type, self.operand2.type))
else:
NumBinopNode.type_error(self)
self.type = PyrexTypes.error_type
def calculate_result_code(self):
return "pow(%s, %s)" % (
self.operand1.result_code, self.operand2.result_code)
......@@ -2826,7 +2838,7 @@ class CmpNode:
and op not in ('is', 'is_not')):
return 1
else:
return 0
return type1.is_cfunction and type1.is_cfunction and type1 == type2
def generate_operation_code(self, code, result_code,
operand1, op , operand2):
......@@ -3166,7 +3178,18 @@ class CoerceFromPyTypeNode(CoercionNode):
code.putln('%s = %s; %s' % (
self.result_code,
rhs,
code.error_goto_if_PyErr(self.pos)))
code.error_goto_if(self.error_cond(), self.pos)))
def error_cond(self):
conds = []
if self.type.exception_value is not None:
conds.append("(%s == %s)" % (self.result_code, self.type.exception_value))
if self.type.exception_check:
conds.append("PyErr_Occurred()")
if len(conds) > 0:
return " && ".join(conds)
else:
return 0
class CoerceToBooleanNode(CoercionNode):
......
......@@ -158,7 +158,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
module_list.append(env)
def generate_module_preamble(self, env, cimported_modules, code):
code.putln('/* Generated by Pyrex %s on %s */' % (
code.putln('/* Generated by Cython %s on %s */' % (
Version.version, time.asctime()))
code.putln('')
code.putln('#define PY_SSIZE_T_CLEAN')
......
......@@ -1649,13 +1649,17 @@ class InPlaceAssignmentNode(AssignmentNode):
self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
self.rhs.analyse_types(env)
self.lhs.analyse_target_types(env)
if Options.incref_local_binop and self.dup.type.is_pyobject:
self.dup = self.dup.coerce_to_temp(env)
def allocate_rhs_temps(self, env):
import ExprNodes
if self.lhs.type.is_pyobject or self.rhs.type.is_pyobject:
if self.lhs.type.is_pyobject:
self.rhs = self.rhs.coerce_to_pyobject(env)
elif self.rhs.type.is_pyobject:
self.rhs = self.rhs.coerce_to(self.lhs.type, env)
if self.lhs.type.is_pyobject:
self.result = ExprNodes.PyTempNode(self.pos, env)
self.result = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
self.result.allocate_temps(env)
# if use_temp:
# self.rhs = self.rhs.coerce_to_temp(env)
......@@ -1685,6 +1689,7 @@ class InPlaceAssignmentNode(AssignmentNode):
self.dup.py_result(),
self.rhs.py_result(),
code.error_goto_if_null(self.result.py_result(), self.pos)))
self.result.generate_evaluation_code(code) # May be a type check...
self.rhs.generate_disposal_code(code)
self.dup.generate_disposal_code(code)
self.lhs.generate_assignment_code(self.result, code)
......
......@@ -9,3 +9,10 @@ embed_pos_in_docstring = 0
gcc_branch_hints = 1
pre_import = None
# This is a SAGE-specific option that will
# cause Cython to incref local variables before
# performing a binary operation on them, for
# safe detection of inplace operators.
incref_local_binop = 0
......@@ -260,6 +260,8 @@ class CType(PyrexType):
to_py_function = None
from_py_function = None
exception_value = None
exception_check = 1
#class CSimpleType(CType):
......@@ -332,6 +334,7 @@ class CIntType(CNumericType):
typedef_flag = 0
to_py_function = "PyInt_FromLong"
from_py_function = "PyInt_AsLong"
exception_value = -1
def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
......@@ -347,33 +350,35 @@ class CBIntType(CIntType):
# and no error checking should be needed (just an incref).
to_py_function = "__Pyx_PyBool_FromLong"
from_py_function = "__Pyx_PyObject_IsTrue"
exception_check = 0
class CPySSizeTType(CIntType):
to_py_function = "PyInt_FromSsize_t"
from_py_function = "__pyx_PyIndex_AsSsize_t"
exception_value = None
class CUIntType(CIntType):
to_py_function = "PyLong_FromUnsignedLong"
from_py_function = "PyInt_AsUnsignedLongMask"
exception_value = None
class CULongType(CIntType):
class CULongType(CUIntType):
to_py_function = "PyLong_FromUnsignedLong"
from_py_function = "PyInt_AsUnsignedLongMask"
class CLongLongType(CIntType):
class CLongLongType(CUIntType):
to_py_function = "PyLong_FromLongLong"
from_py_function = "PyInt_AsUnsignedLongLongMask"
class CULongLongType(CIntType):
class CULongLongType(CUIntType):
to_py_function = "PyLong_FromUnsignedLongLong"
from_py_function = "PyInt_AsUnsignedLongLongMask"
......@@ -709,6 +714,7 @@ class CStringType:
to_py_function = "PyString_FromString"
from_py_function = "PyString_AsString"
exception_value = "NULL"
def literal_code(self, value):
if isinstance(value, unicode):
......
......@@ -40,6 +40,7 @@ class Entry:
# getter_cname string C func for getting property
# setter_cname string C func for setting or deleting property
# is_self_arg boolean Is the "self" arg of an exttype method
# is_arg boolean Is the arg of a method
# is_readonly boolean Can't be assigned to
# func_cname string C func implementing Python func
# pos position Source position where declared
......@@ -81,6 +82,7 @@ class Entry:
getter_cname = None
setter_cname = None
is_self_arg = 0
is_arg = 0
is_declared_generic = 0
is_readonly = 0
func_cname = None
......@@ -910,6 +912,7 @@ class LocalScope(Scope):
entry.is_variable = 1
if type.is_pyobject:
entry.init = "0"
entry.is_arg = 1
#entry.borrowed = 1 # Not using borrowed arg refs for now
self.arg_entries.append(entry)
return entry
......
version = '0.9.6.5'
version = '0.9.6.6'
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