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): ...@@ -1478,11 +1478,8 @@ class SimpleCallNode(ExprNode):
function.obj = CloneNode(self.self) function.obj = CloneNode(self.self)
func_type = self.function_type() func_type = self.function_type()
if func_type.is_pyobject: if func_type.is_pyobject:
if self.args: self.arg_tuple = TupleNode(self.pos, args = self.args)
self.arg_tuple = TupleNode(self.pos, args = self.args) self.arg_tuple.analyse_types(env)
self.arg_tuple.analyse_types(env)
else:
self.arg_tuple = None
self.args = None self.args = None
self.type = py_object_type self.type = py_object_type
self.is_temp = 1 self.is_temp = 1
...@@ -1573,12 +1570,9 @@ class SimpleCallNode(ExprNode): ...@@ -1573,12 +1570,9 @@ class SimpleCallNode(ExprNode):
def generate_result_code(self, code): def generate_result_code(self, code):
func_type = self.function_type() func_type = self.function_type()
if func_type.is_pyobject: if func_type.is_pyobject:
if self.arg_tuple: arg_code = self.arg_tuple.py_result()
arg_code = self.arg_tuple.py_result()
else:
arg_code = "0"
code.putln( code.putln(
"%s = PyObject_CallObject(%s, %s); %s" % ( "%s = PyObject_Call(%s, %s, NULL); %s" % (
self.result_code, self.result_code,
self.function.py_result(), self.function.py_result(),
arg_code, arg_code,
...@@ -1663,7 +1657,7 @@ class GeneralCallNode(ExprNode): ...@@ -1663,7 +1657,7 @@ class GeneralCallNode(ExprNode):
else: else:
keyword_code = None keyword_code = None
if not keyword_code: if not keyword_code:
call_code = "PyObject_CallObject(%s, %s)" % ( call_code = "PyObject_Call(%s, %s, NULL)" % (
self.function.py_result(), self.function.py_result(),
self.positional_args.py_result()) self.positional_args.py_result())
else: else:
......
...@@ -568,8 +568,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -568,8 +568,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_exttype_vtable(scope, code) self.generate_exttype_vtable(scope, code)
self.generate_new_function(scope, code) self.generate_new_function(scope, code)
self.generate_dealloc_function(scope, code) self.generate_dealloc_function(scope, code)
self.generate_traverse_function(scope, code) if scope.needs_gc():
self.generate_clear_function(scope, code) self.generate_traverse_function(scope, code)
self.generate_clear_function(scope, code)
if scope.defines_any(["__getitem__"]): if scope.defines_any(["__getitem__"]):
self.generate_getitem_int_function(scope, code) self.generate_getitem_int_function(scope, code)
if scope.defines_any(["__setitem__", "__delitem__"]): if scope.defines_any(["__setitem__", "__delitem__"]):
...@@ -725,9 +726,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -725,9 +726,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if py_attrs: if py_attrs:
self.generate_self_cast(scope, code) self.generate_self_cast(scope, code)
if base_type: if base_type:
code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
code.putln( code.putln(
"e = %s->tp_traverse(o, v, a); if (e) return e;" % "e = %s->tp_traverse(o, v, a); if (e) return e;" %
base_type.typeptr_cname) base_type.typeptr_cname)
code.putln("}")
for entry in py_attrs: for entry in py_attrs:
var_code = "p->%s" % entry.cname var_code = "p->%s" % entry.cname
code.putln( code.putln(
...@@ -757,14 +760,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -757,14 +760,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
py_attrs.append(entry) py_attrs.append(entry)
if py_attrs: if py_attrs:
self.generate_self_cast(scope, code) self.generate_self_cast(scope, code)
code.putln("PyObject* tmp;")
if base_type: if base_type:
code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
code.putln( code.putln(
"%s->tp_clear(o);" % "%s->tp_clear(o);" %
base_type.typeptr_cname) base_type.typeptr_cname)
code.putln("}")
for entry in py_attrs: for entry in py_attrs:
name = "p->%s" % entry.cname name = "p->%s" % entry.cname
code.put_xdecref(name, entry.type) code.putln("tmp = %s;" % name)
code.put_init_var_to_py_none(entry, "p->%s") code.put_init_to_py_none(name, entry.type)
code.putln("Py_XDECREF(tmp);")
code.putln( code.putln(
"return 0;") "return 0;")
code.putln( code.putln(
......
...@@ -3346,7 +3346,7 @@ static int __Pyx_GetStarArgs( ...@@ -3346,7 +3346,7 @@ static int __Pyx_GetStarArgs(
PyObject **kwds2, PyObject **kwds2,
char rqd_kwds[]) char rqd_kwds[])
{ {
PyObject *x = 0, *args1 = 0, *kwds1 = 0; PyObject *s = 0, *x = 0, *args1 = 0, *kwds1 = 0;
int i; int i;
char **p; char **p;
...@@ -3375,14 +3375,9 @@ static int __Pyx_GetStarArgs( ...@@ -3375,14 +3375,9 @@ static int __Pyx_GetStarArgs(
args1 = *args; args1 = *args;
Py_INCREF(args1); Py_INCREF(args1);
} }
if (rqd_kwds && !*kwds) if (*kwds) {
for (i = 0, p = kwd_list; *p; i++, p++) if (kwds2) {
if (rqd_kwds[i])
goto missing_kwarg;
if (kwds2) {
if (*kwds) {
kwds1 = PyDict_New(); kwds1 = PyDict_New();
if (!kwds1) if (!kwds1)
goto bad; goto bad;
...@@ -3390,30 +3385,41 @@ static int __Pyx_GetStarArgs( ...@@ -3390,30 +3385,41 @@ static int __Pyx_GetStarArgs(
if (!*kwds2) if (!*kwds2)
goto bad; goto bad;
for (i = 0, p = kwd_list; *p; i++, p++) { 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 (x) {
if (PyDict_SetItemString(kwds1, *p, x) < 0) if (PyDict_SetItem(kwds1, s, x) < 0)
goto bad; goto bad;
if (PyDict_DelItemString(*kwds2, *p) < 0) if (PyDict_DelItem(*kwds2, s) < 0)
goto bad; goto bad;
} }
else if (rqd_kwds && rqd_kwds[i]) else if (rqd_kwds && rqd_kwds[i])
goto missing_kwarg; goto missing_kwarg;
Py_DECREF(s);
} }
s = 0;
} }
else { else {
*kwds2 = PyDict_New(); kwds1 = *kwds;
if (!*kwds2) Py_INCREF(kwds1);
goto bad; if (rqd_kwds) {
for (i = 0, p = kwd_list; *p; i++, p++)
if (rqd_kwds[i] && !PyDict_GetItemString(kwds1, *p))
goto missing_kwarg;
}
} }
} }
else { else {
kwds1 = *kwds; if (rqd_kwds) {
Py_XINCREF(kwds1);
if (rqd_kwds && *kwds)
for (i = 0, p = kwd_list; *p; i++, p++) for (i = 0, p = kwd_list; *p; i++, p++)
if (rqd_kwds[i] && !PyDict_GetItemString(*kwds, *p)) if (rqd_kwds[i])
goto missing_kwarg; goto missing_kwarg;
}
if (kwds2) {
*kwds2 = PyDict_New();
if (!*kwds2)
goto bad;
}
} }
*args = args1; *args = args1;
...@@ -3423,6 +3429,7 @@ missing_kwarg: ...@@ -3423,6 +3429,7 @@ missing_kwarg:
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"required keyword argument '%s' is missing", *p); "required keyword argument '%s' is missing", *p);
bad: bad:
Py_XDECREF(s);
Py_XDECREF(args1); Py_XDECREF(args1);
Py_XDECREF(kwds1); Py_XDECREF(kwds1);
if (args2) { if (args2) {
......
...@@ -1202,7 +1202,8 @@ def p_with_statement(s): ...@@ -1202,7 +1202,8 @@ def p_with_statement(s):
body = p_suite(s) body = p_suite(s)
return Nodes.GILStatNode(pos, state = state, body = body) return Nodes.GILStatNode(pos, state = state, body = body)
else: 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): def p_simple_statement(s):
#print "p_simple_statement:", s.sy, s.systring ### #print "p_simple_statement:", s.sy, s.systring ###
...@@ -2025,9 +2026,11 @@ def p_c_class_definition(s, level, pos, ...@@ -2025,9 +2026,11 @@ def p_c_class_definition(s, level, pos,
error(pos, "Object struct name specification required for 'public' C class") error(pos, "Object struct name specification required for 'public' C class")
if not typeobj_name: if not typeobj_name:
error(pos, "Type object name specification required for 'public' C class") error(pos, "Type object name specification required for 'public' C class")
else: elif visibility == 'private':
if api: if api:
error(pos, "Only 'public' C class can be declared 'api'") error(pos, "Only 'public' C class can be declared 'api'")
else:
error(pos, "Invalid class visibility '%s'" % visibility)
return Nodes.CClassDefNode(pos, return Nodes.CClassDefNode(pos,
visibility = visibility, visibility = visibility,
typedef_flag = typedef_flag, typedef_flag = typedef_flag,
......
...@@ -176,22 +176,6 @@ class EmptySlot(FixedSlot): ...@@ -176,22 +176,6 @@ class EmptySlot(FixedSlot):
FixedSlot.__init__(self, slot_name, "0") 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): class MethodSlot(SlotDescriptor):
# Type slot descriptor for a user-definable method. # Type slot descriptor for a user-definable method.
# #
...@@ -228,6 +212,26 @@ class InternalMethodSlot(SlotDescriptor): ...@@ -228,6 +212,26 @@ class InternalMethodSlot(SlotDescriptor):
return scope.mangle_internal(self.slot_name) 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): class SyntheticSlot(InternalMethodSlot):
# Type slot descriptor for a synthesized method which # Type slot descriptor for a synthesized method which
# dispatches to one or more user-defined methods depending # dispatches to one or more user-defined methods depending
...@@ -252,12 +256,11 @@ class TypeFlagsSlot(SlotDescriptor): ...@@ -252,12 +256,11 @@ class TypeFlagsSlot(SlotDescriptor):
# Descriptor for the type flags slot. # Descriptor for the type flags slot.
def slot_code(self, scope): 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"
value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC" if scope.needs_gc():
#if scope.has_pyobject_attrs: value += "|Py_TPFLAGS_HAVE_GC"
# value += "|Py_TPFLAGS_HAVE_GC"
return value return value
class DocStringSlot(SlotDescriptor): class DocStringSlot(SlotDescriptor):
# Descriptor for the docstring slot. # Descriptor for the docstring slot.
...@@ -578,8 +581,8 @@ slot_table = ( ...@@ -578,8 +581,8 @@ slot_table = (
TypeFlagsSlot("tp_flags"), TypeFlagsSlot("tp_flags"),
DocStringSlot("tp_doc"), DocStringSlot("tp_doc"),
InternalMethodSlot("tp_traverse"), GCDependentSlot("tp_traverse"),
InternalMethodSlot("tp_clear"), GCDependentSlot("tp_clear"),
# Later -- synthesize a method to split into separate ops? # Later -- synthesize a method to split into separate ops?
MethodSlot(richcmpfunc, "tp_richcompare", "__richcmp__"), MethodSlot(richcmpfunc, "tp_richcompare", "__richcmp__"),
...@@ -604,10 +607,7 @@ slot_table = ( ...@@ -604,10 +607,7 @@ slot_table = (
MethodSlot(initproc, "tp_init", "__init__"), MethodSlot(initproc, "tp_init", "__init__"),
EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"), EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
InternalMethodSlot("tp_new"), InternalMethodSlot("tp_new"),
# Some versions of Python 2.2 inherit the wrong value for tp_free when the EmptySlot("tp_free"),
# 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_is_gc"), EmptySlot("tp_is_gc"),
EmptySlot("tp_bases"), EmptySlot("tp_bases"),
......
...@@ -153,12 +153,13 @@ class build_ext(_build_ext.build_ext): ...@@ -153,12 +153,13 @@ class build_ext(_build_ext.build_ext):
or getattr(extension, 'pyrex_c_in_temp', 0)): or getattr(extension, 'pyrex_c_in_temp', 0)):
target_dir = os.path.join(self.build_temp, "pyrex") target_dir = os.path.join(self.build_temp, "pyrex")
else: else:
target_dir = "" target_dir = None
for source in sources: 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 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_sources.append(source)
pyrex_targets[source] = new_sources[-1] pyrex_targets[source] = new_sources[-1]
else: 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