Commit 837aa28c authored by Stefan Behnel's avatar Stefan Behnel

merge of 0.9.6.8

parents 7acd5674 483a99c3
......@@ -20,7 +20,7 @@ builtin_function_table = [
('getattr', "OO", "O", "PyObject_GetAttr"),
('getattr3', "OOO", "O", "__Pyx_GetAttr3", "getattr"),
('hasattr', "OO", "b", "PyObject_HasAttr"),
('hash', "O", "i", "PyObject_Hash"),
('hash', "O", "l", "PyObject_Hash"),
#('hex', "", "", ""),
#('id', "", "", ""),
#('input', "", "", ""),
......
......@@ -742,7 +742,7 @@ class NameNode(AtomicExprNode):
#print "NameNode.coerce_to:", self.name, dst_type ###
if dst_type is py_object_type:
entry = self.entry
if entry.is_cfunction:
if entry and entry.is_cfunction:
var_entry = entry.as_variable
if var_entry:
node = NameNode(self.pos, name = self.name)
......@@ -779,6 +779,9 @@ class NameNode(AtomicExprNode):
self.entry = env.lookup(self.name)
if not self.entry:
self.entry = env.declare_builtin(self.name, self.pos)
if not self.entry:
self.type = PyrexTypes.error_type
return
self.analyse_rvalue_entry(env)
def analyse_target_types(self, env):
......@@ -1431,12 +1434,14 @@ class SimpleCallNode(ExprNode):
# arg_tuple ExprNode or None used internally
# self ExprNode or None used internally
# coerced_self ExprNode or None used internally
# wrapper_call bool used internally
subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
self = None
coerced_self = None
arg_tuple = None
wrapper_call = False
def compile_time_value(self, denv):
function = self.function.compile_time_value(denv)
......@@ -1544,6 +1549,9 @@ class SimpleCallNode(ExprNode):
arg_list_code.append(actual_arg.result_code)
result = "%s(%s)" % (self.function.result_code,
join(arg_list_code, ","))
if self.wrapper_call or \
self.function.entry.is_unbound_cmethod and self.function.entry.type.is_overridable:
result = "(%s = 1, %s)" % (Naming.skip_dispatch_cname, result)
return result
def generate_result_code(self, code):
......@@ -1761,6 +1769,7 @@ class AttributeNode(ExprNode):
entry.type)
ubcm_entry.is_cfunction = 1
ubcm_entry.func_cname = entry.func_cname
ubcm_entry.is_unbound_cmethod = 1
self.mutate_into_name_node(env, ubcm_entry, None)
return 1
return 0
......
......@@ -1598,11 +1598,14 @@ static PyObject *__Pyx_ImportModule(char *name); /*proto*/
#define __PYX_HAVE_RT_ImportModule
static PyObject *__Pyx_ImportModule(char *name) {
PyObject *py_name = 0;
PyObject *py_module = 0;
py_name = PyString_FromString(name);
if (!py_name)
goto bad;
return PyImport_Import(py_name);
py_module = PyImport_Import(py_name);
Py_DECREF(py_name);
return py_module;
bad:
Py_XDECREF(py_name);
return 0;
......
......@@ -13,6 +13,7 @@ arg_prefix = pyrex_prefix + "arg_"
funcdoc_prefix = pyrex_prefix + "doc_"
enum_prefix = pyrex_prefix + "e_"
func_prefix = pyrex_prefix + "f_"
pyfunc_prefix = pyrex_prefix + "pf_"
gstab_prefix = pyrex_prefix + "getsets_"
prop_get_prefix = pyrex_prefix + "getprop_"
const_prefix = pyrex_prefix + "k"
......@@ -56,6 +57,7 @@ stringtab_cname = pyrex_prefix + "string_tab"
vtabslot_cname = pyrex_prefix + "vtab"
c_api_tab_cname = pyrex_prefix + "c_api_tab"
gilstate_cname = pyrex_prefix + "state"
skip_dispatch_cname = pyrex_prefix + "skip_dispatch"
extern_c_macro = pyrex_prefix.upper() + "EXTERN_C"
......
......@@ -761,6 +761,7 @@ class CFuncDefNode(FuncDefNode):
# may be different if we're overriding a C method inherited
# from the base type of an extension type.
self.type = type
type.is_overridable = self.overridable
name = name_declarator.name
cname = name_declarator.cname
self.entry = env.declare_cfunction(
......@@ -775,7 +776,7 @@ class CFuncDefNode(FuncDefNode):
arg_names = [arg.name for arg in self.type.args]
self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.declarator.base.name)
c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1:]])
c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1:]], wrapper_call=True)
py_func_body = ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
self.py_func = DefNode(pos = self.pos,
name = self.declarator.base.name,
......@@ -790,7 +791,7 @@ class CFuncDefNode(FuncDefNode):
if Options.intern_names:
self.py_func.interned_attr_cname = env.intern(self.py_func.entry.name)
self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
self.body.stats.insert(0, self.override)
self.body = StatListNode(self.pos, stats=[self.override, self.body])
def declare_arguments(self, env):
......@@ -1020,7 +1021,7 @@ class DefNode(FuncDefNode):
self.entry = entry
prefix = env.scope_prefix
entry.func_cname = \
Naming.func_prefix + prefix + name
Naming.pyfunc_prefix + prefix + name
entry.pymethdef_cname = \
Naming.pymethdef_prefix + prefix + name
if not entry.is_special:
......@@ -1389,8 +1390,10 @@ class OverrideCheckNode(StatNode):
def generate_execution_code(self, code):
# Check to see if we are an extension type
self_arg = "((PyObject *)%s)" % self.args[0].cname
code.putln("/* Check if called by wrapper */")
code.putln("if (unlikely(%s)) %s = 0;" % (Naming.skip_dispatch_cname, Naming.skip_dispatch_cname))
code.putln("/* Check if overriden in Python */")
code.putln("if (unlikely(%s->ob_type->tp_dictoffset != 0)) {" % self_arg)
code.putln("else if (unlikely(%s->ob_type->tp_dictoffset != 0)) {" % self_arg)
err = code.error_goto_if_null(self_arg, self.pos)
# need to get attribute manually--scope would return cdef method
if Options.intern_names:
......@@ -2934,7 +2937,14 @@ utility_function_predeclarations = \
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n; int is_unicode;} __Pyx_StringTabEntry; /*proto*/
#define __pyx_PyIndex_AsSsize_t(b) PyInt_AsSsize_t(PyNumber_Index(b))
static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_ssize_t ival;
PyObject* x = PyNumber_Index(b);
if (!x) return -1;
ival = PyInt_AsSsize_t(x);
Py_DECREF(x);
return ival;
}
#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
......@@ -2943,7 +2953,11 @@ static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
else return PyObject_IsTrue(x);
}
"""
""" + """
static int %(skip_dispatch_cname)s = 0;
""" % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
if Options.gcc_branch_hints:
branch_prediction_macros = \
......
......@@ -1311,7 +1311,7 @@ def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0):
if s.sy == 'cdef':
cdef_flag = 1
s.next()
if s.sy == 'rdef':
if s.sy == 'cpdef':
cdef_flag = 1
overridable = 1
s.next()
......@@ -1320,7 +1320,7 @@ def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0):
s.error('cdef statement not allowed here')
return p_cdef_statement(s, level, visibility = visibility,
api = api, overridable = overridable)
# elif s.sy == 'rdef':
# elif s.sy == 'cpdef':
# s.next()
# return p_c_func_or_var_declaration(s, level, s.position(), visibility = visibility, api = api, overridable = True)
else:
......
......@@ -417,7 +417,7 @@ class CULongLongType(CUIntType):
class CPySSizeTType(CIntType):
to_py_function = "PyInt_FromSsize_t"
from_py_function = "PyInt_AsSsize_t"
from_py_function = "__pyx_PyIndex_AsSsize_t"
class CFloatType(CNumericType):
......@@ -535,7 +535,7 @@ class CFuncType(CType):
def __init__(self, return_type, args, has_varargs = 0,
exception_value = None, exception_check = 0, calling_convention = "",
nogil = 0, with_gil = 0):
nogil = 0, with_gil = 0, is_overridable = 0):
self.return_type = return_type
self.args = args
self.has_varargs = has_varargs
......@@ -544,6 +544,7 @@ class CFuncType(CType):
self.calling_convention = calling_convention
self.nogil = nogil
self.with_gil = with_gil
self.is_overridable = is_overridable
def __repr__(self):
arg_reprs = map(repr, self.args)
......@@ -572,6 +573,8 @@ class CFuncType(CType):
return 1
if not other_type.is_cfunction:
return 0
if self.is_overridable != other_type.is_overridable:
return 0
nargs = len(self.args)
if nargs <> len(other_type.args):
return 0
......
......@@ -139,7 +139,7 @@ reserved_words = [
"raise", "import", "exec", "try", "except", "finally",
"while", "if", "elif", "else", "for", "in", "assert",
"and", "or", "not", "is", "in", "lambda", "from",
"NULL", "cimport", "by", "with", "rdef", "DEF", "IF", "ELIF", "ELSE"
"NULL", "cimport", "by", "with", "cpdef", "DEF", "IF", "ELIF", "ELSE"
]
class Method:
......
......@@ -34,6 +34,7 @@ class Entry:
# is_variable boolean Is a variable
# is_cfunction boolean Is a C function
# is_cmethod boolean Is a C method of an extension type
# is_unbound_cmethod boolean Is an unbound C method of an extension type
# is_type boolean Is a type definition
# is_const boolean Is a constant
# is_property boolean Is a property of an extension type:
......@@ -81,6 +82,7 @@ class Entry:
is_variable = 0
is_cfunction = 0
is_cmethod = 0
is_unbound_cmethod = 0
is_type = 0
is_const = 0
is_property = 0
......@@ -107,6 +109,7 @@ class Entry:
defined_in_pxd = 0
api = 0
utility_code = None
is_overridable = 0
def __init__(self, name, cname, type, pos = None, init = None):
self.name = name
......
version = '0.9.6.7'
version = '0.9.6.8'
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