Commit c5cc0c48 authored by Robert Bradshaw's avatar Robert Bradshaw

Merge Stefan Behnel's work.

parents da1d48ae f669064a
......@@ -1478,11 +1478,8 @@ class SimpleCallNode(ExprNode):
function.obj = CloneNode(self.self)
func_type = self.function_type()
if func_type.is_pyobject:
if self.args:
self.arg_tuple = TupleNode(self.pos, args = self.args)
self.arg_tuple.analyse_types(env)
else:
self.arg_tuple = None
self.args = None
self.type = py_object_type
self.is_temp = 1
......@@ -1573,12 +1570,9 @@ class SimpleCallNode(ExprNode):
def generate_result_code(self, code):
func_type = self.function_type()
if func_type.is_pyobject:
if self.arg_tuple:
arg_code = self.arg_tuple.py_result()
else:
arg_code = "0"
code.putln(
"%s = PyObject_CallObject(%s, %s); %s" % (
"%s = PyObject_Call(%s, %s, NULL); %s" % (
self.result_code,
self.function.py_result(),
arg_code,
......@@ -1663,7 +1657,7 @@ class GeneralCallNode(ExprNode):
else:
keyword_code = None
if not keyword_code:
call_code = "PyObject_CallObject(%s, %s)" % (
call_code = "PyObject_Call(%s, %s, NULL)" % (
self.function.py_result(),
self.positional_args.py_result())
else:
......
......@@ -568,6 +568,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_exttype_vtable(scope, code)
self.generate_new_function(scope, code)
self.generate_dealloc_function(scope, code)
if scope.needs_gc():
self.generate_traverse_function(scope, code)
self.generate_clear_function(scope, code)
if scope.defines_any(["__getitem__"]):
......@@ -725,9 +726,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if py_attrs:
self.generate_self_cast(scope, code)
if base_type:
code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
code.putln(
"e = %s->tp_traverse(o, v, a); if (e) return e;" %
base_type.typeptr_cname)
code.putln("}")
for entry in py_attrs:
var_code = "p->%s" % entry.cname
code.putln(
......@@ -757,14 +760,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
py_attrs.append(entry)
if py_attrs:
self.generate_self_cast(scope, code)
code.putln("PyObject* tmp;")
if base_type:
code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
code.putln(
"%s->tp_clear(o);" %
base_type.typeptr_cname)
code.putln("}")
for entry in py_attrs:
name = "p->%s" % entry.cname
code.put_xdecref(name, entry.type)
code.put_init_var_to_py_none(entry, "p->%s")
code.putln("tmp = %s;" % name)
code.put_init_to_py_none(name, entry.type)
code.putln("Py_XDECREF(tmp);")
code.putln(
"return 0;")
code.putln(
......
......@@ -3346,7 +3346,7 @@ static int __Pyx_GetStarArgs(
PyObject **kwds2,
char rqd_kwds[])
{
PyObject *x = 0, *args1 = 0, *kwds1 = 0;
PyObject *s = 0, *x = 0, *args1 = 0, *kwds1 = 0;
int i;
char **p;
......@@ -3376,13 +3376,8 @@ static int __Pyx_GetStarArgs(
Py_INCREF(args1);
}
if (rqd_kwds && !*kwds)
for (i = 0, p = kwd_list; *p; i++, p++)
if (rqd_kwds[i])
goto missing_kwarg;
if (kwds2) {
if (*kwds) {
if (kwds2) {
kwds1 = PyDict_New();
if (!kwds1)
goto bad;
......@@ -3390,31 +3385,42 @@ static int __Pyx_GetStarArgs(
if (!*kwds2)
goto bad;
for (i = 0, p = kwd_list; *p; i++, p++) {
x = PyDict_GetItemString(*kwds, *p);
s = PyString_FromString(*p);
x = PyDict_GetItem(*kwds, s);
if (x) {
if (PyDict_SetItemString(kwds1, *p, x) < 0)
if (PyDict_SetItem(kwds1, s, x) < 0)
goto bad;
if (PyDict_DelItemString(*kwds2, *p) < 0)
if (PyDict_DelItem(*kwds2, s) < 0)
goto bad;
}
else if (rqd_kwds && rqd_kwds[i])
goto missing_kwarg;
Py_DECREF(s);
}
s = 0;
}
else {
*kwds2 = PyDict_New();
if (!*kwds2)
goto bad;
kwds1 = *kwds;
Py_INCREF(kwds1);
if (rqd_kwds) {
for (i = 0, p = kwd_list; *p; i++, p++)
if (rqd_kwds[i] && !PyDict_GetItemString(kwds1, *p))
goto missing_kwarg;
}
}
}
else {
kwds1 = *kwds;
Py_XINCREF(kwds1);
if (rqd_kwds && *kwds)
if (rqd_kwds) {
for (i = 0, p = kwd_list; *p; i++, p++)
if (rqd_kwds[i] && !PyDict_GetItemString(*kwds, *p))
if (rqd_kwds[i])
goto missing_kwarg;
}
if (kwds2) {
*kwds2 = PyDict_New();
if (!*kwds2)
goto bad;
}
}
*args = args1;
*kwds = kwds1;
......@@ -3423,6 +3429,7 @@ missing_kwarg:
PyErr_Format(PyExc_TypeError,
"required keyword argument '%s' is missing", *p);
bad:
Py_XDECREF(s);
Py_XDECREF(args1);
Py_XDECREF(kwds1);
if (args2) {
......
......@@ -1202,7 +1202,8 @@ def p_with_statement(s):
body = p_suite(s)
return Nodes.GILStatNode(pos, state = state, body = body)
else:
s.error(pos, "Only 'with gil' and 'with nogil' implemented")
s.error("Only 'with gil' and 'with nogil' implemented",
pos = pos)
def p_simple_statement(s):
#print "p_simple_statement:", s.sy, s.systring ###
......@@ -2025,9 +2026,11 @@ def p_c_class_definition(s, level, pos,
error(pos, "Object struct name specification required for 'public' C class")
if not typeobj_name:
error(pos, "Type object name specification required for 'public' C class")
else:
elif visibility == 'private':
if api:
error(pos, "Only 'public' C class can be declared 'api'")
else:
error(pos, "Invalid class visibility '%s'" % visibility)
return Nodes.CClassDefNode(pos,
visibility = visibility,
typedef_flag = typedef_flag,
......
......@@ -176,22 +176,6 @@ class EmptySlot(FixedSlot):
FixedSlot.__init__(self, slot_name, "0")
class GCDependentSlot(SlotDescriptor):
# Descriptor for a slot whose value depends on whether
# the type participates in GC.
def __init__(self, slot_name, no_gc_value, gc_value, dynamic = 0):
SlotDescriptor.__init__(self, slot_name, dynamic = dynamic)
self.no_gc_value = no_gc_value
self.gc_value = gc_value
def slot_code(self, scope):
if scope.has_pyobject_attrs:
return self.gc_value
else:
return self.no_gc_value
class MethodSlot(SlotDescriptor):
# Type slot descriptor for a user-definable method.
#
......@@ -228,6 +212,26 @@ class InternalMethodSlot(SlotDescriptor):
return scope.mangle_internal(self.slot_name)
class GCDependentSlot(InternalMethodSlot):
# Descriptor for a slot whose value depends on whether
# the type participates in GC.
def __init__(self, slot_name):
InternalMethodSlot.__init__(self, slot_name)
def slot_code(self, scope):
if not scope.needs_gc():
return "0"
if not scope.has_pyobject_attrs:
# if the type does not have object attributes, it can
# delegate GC methods to its parent - iff the parent
# functions are defined in the same module
parent_type_scope = scope.parent_type.base_type.scope
if scope.parent_scope is parent_type_scope.parent_scope:
return self.slot_code(parent_type_scope)
return InternalMethodSlot.slot_code(self, scope)
class SyntheticSlot(InternalMethodSlot):
# Type slot descriptor for a synthesized method which
# dispatches to one or more user-defined methods depending
......@@ -252,10 +256,9 @@ class TypeFlagsSlot(SlotDescriptor):
# Descriptor for the type flags slot.
def slot_code(self, scope):
# Always add Py_TPFLAGS_HAVE_GC -- PyType_Ready doesn't seem to inherit it
value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC"
#if scope.has_pyobject_attrs:
# value += "|Py_TPFLAGS_HAVE_GC"
value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE"
if scope.needs_gc():
value += "|Py_TPFLAGS_HAVE_GC"
return value
......@@ -578,8 +581,8 @@ slot_table = (
TypeFlagsSlot("tp_flags"),
DocStringSlot("tp_doc"),
InternalMethodSlot("tp_traverse"),
InternalMethodSlot("tp_clear"),
GCDependentSlot("tp_traverse"),
GCDependentSlot("tp_clear"),
# Later -- synthesize a method to split into separate ops?
MethodSlot(richcmpfunc, "tp_richcompare", "__richcmp__"),
......@@ -604,10 +607,7 @@ slot_table = (
MethodSlot(initproc, "tp_init", "__init__"),
EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
InternalMethodSlot("tp_new"),
# Some versions of Python 2.2 inherit the wrong value for tp_free when the
# type has GC but the base type doesn't, so we explicitly set it ourselves
# in that case.
GCDependentSlot("tp_free", "0", "_PyObject_GC_Del", dynamic = 1),
EmptySlot("tp_free"),
EmptySlot("tp_is_gc"),
EmptySlot("tp_bases"),
......
......@@ -153,12 +153,13 @@ class build_ext(_build_ext.build_ext):
or getattr(extension, 'pyrex_c_in_temp', 0)):
target_dir = os.path.join(self.build_temp, "pyrex")
else:
target_dir = ""
target_dir = None
for source in sources:
(base, ext) = os.path.splitext(source)
(base, ext) = os.path.splitext(os.path.basename(source))
if ext == ".pyx": # Cython source file
new_sources.append(os.path.join(target_dir, base + target_ext))
output_dir = target_dir or os.path.dirname(source)
new_sources.append(os.path.join(output_dir, base + target_ext))
pyrex_sources.append(source)
pyrex_targets[source] = new_sources[-1]
else:
......
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