From 68e1429c9c879eeb5f6627fea100aa3c56c7e4b9 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Fri, 18 Jul 2008 12:40:26 +0200 Subject: Introduced BufferType, start of numpy-independent testcase, GetBuffer improvements --- Cython/Compiler/ModuleNode.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 3dbdf90db..04fd9e2bc 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -2002,9 +2002,25 @@ static void numpy_releasebuffer(PyObject *obj, Py_buffer *view) { """) except KeyError: pass + + # Search all types for __getbuffer__ overloads + types = [] + def find_buffer_types(scope): + for m in scope.cimported_modules: + find_buffer_types(m) + for e in scope.type_entries: + t = e.type + if t.is_extension_type: + release = get = None + for x in t.scope.pyfunc_entries: + if x.name == u"__getbuffer__": get = x.func_cname + elif x.name == u"__releasebuffer__": release = x.func_cname + if get: + types.append((t.typeptr_cname, get, release)) + + find_buffer_types(self.scope) # For now, hard-code numpy imported as "numpy" - types = [] try: ndarrtype = env.entries[u'numpy'].as_module.entries['ndarray'].type types.append((ndarrtype.typeptr_cname, "numpy_getbuffer", "numpy_releasebuffer")) @@ -2015,7 +2031,7 @@ static void numpy_releasebuffer(PyObject *obj, Py_buffer *view) { if len(types) > 0: clause = "if" for t, get, release in types: - code.putln("%s (__Pyx_TypeTest(obj, %s)) return %s(obj, view, flags);" % (clause, t, get)) + code.putln("%s (PyObject_TypeCheck(obj, %s)) return %s(obj, view, flags);" % (clause, t, get)) clause = "else if" code.putln("else {") code.putln("PyErr_Format(PyExc_TypeError, \"'%100s' does not have the buffer interface\", Py_TYPE(obj)->tp_name);") @@ -2027,8 +2043,9 @@ static void numpy_releasebuffer(PyObject *obj, Py_buffer *view) { if len(types) > 0: clause = "if" for t, get, release in types: - code.putln("%s (__Pyx_TypeTest(obj, %s)) %s(obj, view);" % (clause, t, release)) - clause = "else if" + if release: + code.putln("%s (PyObject_TypeCheck(obj, %s)) %s(obj, view);" % (clause, t, release)) + clause = "else if" code.putln("}") code.putln("") code.putln("#endif") -- cgit v1.2.1 From 7147f66b05b012f9c00a3db328ee45e188dfd4d6 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Sat, 26 Jul 2008 10:59:36 +0200 Subject: Buffer type checking cleanup/rewrite (now uses use_utility_code) --- Cython/Compiler/ModuleNode.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Cython/Compiler/ModuleNode.py (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py old mode 100644 new mode 100755 -- cgit v1.2.1 From 724f57561327202071ed65e81a0c5ef10a9ea4ec Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Sat, 26 Jul 2008 18:39:58 +0200 Subject: Only define PyObject_GetBuffer etc. if really needed --- Cython/Compiler/ModuleNode.py | 103 ------------------------------------------ 1 file changed, 103 deletions(-) (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 8cedcd663..63a40f864 100755 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -260,7 +260,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.generate_module_cleanup_func(env, code) self.generate_filename_table(code) self.generate_utility_functions(env, code) - self.generate_buffer_compatability_functions(env, code) self.generate_declarations_for_modules(env, modules, code.h) @@ -441,8 +440,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln(" #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)") code.putln(" #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)") code.putln("") - code.putln(" static int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags);") - code.putln(" static void PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view);") code.putln("#endif") code.put(builtin_module_name_utility_code[0]) @@ -1956,106 +1953,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.put(PyrexTypes.type_conversion_functions) code.putln("") - def generate_buffer_compatability_functions(self, env, code): - # will be refactored - try: - env.entries[u'numpy'] - code.put(""" -static int numpy_getbuffer(PyObject *obj, Py_buffer *view, int flags) { - /* This function is always called after a type-check; safe to cast */ - PyArrayObject *arr = (PyArrayObject*)obj; - PyArray_Descr *type = (PyArray_Descr*)arr->descr; - - - int typenum = PyArray_TYPE(obj); - if (!PyTypeNum_ISNUMBER(typenum)) { - PyErr_Format(PyExc_TypeError, "Only numeric NumPy types currently supported."); - return -1; - } - - /* - NumPy format codes doesn't completely match buffer codes; - seems safest to retranslate. - 01234567890123456789012345*/ - const char* base_codes = "?bBhHiIlLqQfdgfdgO"; - - char* format = (char*)malloc(4); - char* fp = format; - *fp++ = type->byteorder; - if (PyTypeNum_ISCOMPLEX(typenum)) *fp++ = 'Z'; - *fp++ = base_codes[typenum]; - *fp = 0; - - view->buf = arr->data; - view->readonly = !PyArray_ISWRITEABLE(obj); - view->ndim = PyArray_NDIM(arr); - view->strides = PyArray_STRIDES(arr); - view->shape = PyArray_DIMS(arr); - view->suboffsets = NULL; - view->format = format; - view->itemsize = type->elsize; - - view->internal = 0; - return 0; -} - -static void numpy_releasebuffer(PyObject *obj, Py_buffer *view) { - free((char*)view->format); - view->format = NULL; -} - -""") - except KeyError: - pass - - # Search all types for __getbuffer__ overloads - types = [] - def find_buffer_types(scope): - for m in scope.cimported_modules: - find_buffer_types(m) - for e in scope.type_entries: - t = e.type - if t.is_extension_type: - release = get = None - for x in t.scope.pyfunc_entries: - if x.name == u"__getbuffer__": get = x.func_cname - elif x.name == u"__releasebuffer__": release = x.func_cname - if get: - types.append((t.typeptr_cname, get, release)) - - find_buffer_types(self.scope) - - # For now, hard-code numpy imported as "numpy" - try: - ndarrtype = env.entries[u'numpy'].as_module.entries['ndarray'].type - types.append((ndarrtype.typeptr_cname, "numpy_getbuffer", "numpy_releasebuffer")) - except KeyError: - pass - code.putln("#if PY_VERSION_HEX < 0x02060000") - code.putln("static int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {") - if len(types) > 0: - clause = "if" - for t, get, release in types: - code.putln("%s (PyObject_TypeCheck(obj, %s)) return %s(obj, view, flags);" % (clause, t, get)) - clause = "else if" - code.putln("else {") - code.putln("PyErr_Format(PyExc_TypeError, \"'%100s' does not have the buffer interface\", Py_TYPE(obj)->tp_name);") - code.putln("return -1;") - if len(types) > 0: code.putln("}") - code.putln("}") - code.putln("") - code.putln("static void PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view) {") - if len(types) > 0: - clause = "if" - for t, get, release in types: - if release: - code.putln("%s (PyObject_TypeCheck(obj, %s)) %s(obj, view);" % (clause, t, release)) - clause = "else if" - code.putln("}") - code.putln("") - code.putln("#endif") - - #------------------------------------------------------------------------------------ # # Runtime support code -- cgit v1.2.1 From 68ecd7c59c404f7914ef9f33ed31e0d10ab8607d Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Tue, 29 Jul 2008 14:59:06 +0200 Subject: Cleared file executable bit that was set earlier by a mistake --- Cython/Compiler/ModuleNode.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Cython/Compiler/ModuleNode.py (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py old mode 100755 new mode 100644 -- cgit v1.2.1 From 6dcb9c6e559ec59b1a9d485694e9fdd35d6903ea Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Tue, 29 Jul 2008 18:19:08 +0200 Subject: Changed fork design slightly in StringIOTree, begun on forking CCodeWriter --- Cython/Compiler/ModuleNode.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 63a40f864..a7d62cf2a 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -97,7 +97,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): h_extension_types = h_entries(env.c_class_entries) if h_types or h_vars or h_funcs or h_extension_types: result.h_file = replace_suffix(result.c_file, ".h") - h_code = Code.CCodeWriter(open_new_file(result.h_file)) + h_code = Code.CCodeWriter() if options.generate_pxi: result.i_file = replace_suffix(result.c_file, ".pxi") i_code = Code.PyrexCodeWriter(result.i_file) @@ -129,6 +129,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name) h_code.putln("") h_code.putln("#endif") + + h_code.copyto(open_new_file(result.h_file)) def generate_public_declaration(self, entry, h_code, i_code): h_code.putln("%s %s;" % ( @@ -156,7 +158,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): has_api_extension_types = 1 if api_funcs or has_api_extension_types: result.api_file = replace_suffix(result.c_file, "_api.h") - h_code = Code.CCodeWriter(open_new_file(result.api_file)) + h_code = Code.CCodeWriter() name = self.api_name(env) guard = Naming.api_guard_prefix + name h_code.put_h_guard(guard) @@ -209,6 +211,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): h_code.putln("}") h_code.putln("") h_code.putln("#endif") + + h_code.copy_to(open_new_file(result.api_file)) def generate_cclass_header_code(self, type, h_code): h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % ( @@ -232,11 +236,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): def generate_c_code(self, env, options, result): modules = self.referenced_modules if Options.annotate or options.annotate: - code = Annotate.AnnotationCCodeWriter(StringIO()) + code = Annotate.AnnotationCCodeWriter() else: - code = Code.CCodeWriter(StringIO()) - code.h = Code.CCodeWriter(StringIO()) - code.init_labels() + code = Code.CCodeWriter() + code.h = Code.CCodeWriter() self.generate_module_preamble(env, modules, code.h) code.putln("") @@ -264,9 +267,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.generate_declarations_for_modules(env, modules, code.h) f = open_new_file(result.c_file) - f.write(code.h.f.getvalue()) + code.h.copyto(f) f.write("\n") - f.write(code.f.getvalue()) + code.copyto(f) f.close() result.c_file_generated = 1 if Options.annotate or options.annotate: @@ -1479,6 +1482,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("0") code.putln("};") code.putln() + code.enter_cfunc_scope() # as we need labels code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set) code.putln("char** type_name = %s_type_names;" % Naming.import_star) code.putln("while (*type_name) {") @@ -1529,8 +1533,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("return -1;") code.putln("}") code.putln(import_star_utility_code) + code.exit_cfunc_scope() # done with labels def generate_module_init_func(self, imported_modules, env, code): + code.enter_cfunc_scope() code.putln("") header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name @@ -1584,6 +1590,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("/*--- Execution code ---*/") code.mark_pos(None) + self.body.generate_execution_code(code) if Options.generate_cleanup_code: @@ -1603,6 +1610,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("return NULL;") code.putln("#endif") code.putln('}') + code.exit_cfunc_scope() def generate_module_cleanup_func(self, env, code): if not Options.generate_cleanup_code: -- cgit v1.2.1 From ace9e7f1adf49cbd70a83e7229933d88ffc26c68 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Tue, 29 Jul 2008 19:18:33 +0200 Subject: Forking CCodeWriter done (and used for module header generation) --- Cython/Compiler/ModuleNode.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index a7d62cf2a..6e4b20ddd 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -212,7 +212,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): h_code.putln("") h_code.putln("#endif") - h_code.copy_to(open_new_file(result.api_file)) + h_code.copyto(open_new_file(result.api_file)) def generate_cclass_header_code(self, type, h_code): h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % ( @@ -239,8 +239,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code = Annotate.AnnotationCCodeWriter() else: code = Code.CCodeWriter() - code.h = Code.CCodeWriter() - self.generate_module_preamble(env, modules, code.h) + h_code = code.fork() + self.generate_module_preamble(env, modules, h_code) code.putln("") code.putln("/* Implementation of %s */" % env.qualified_name) @@ -262,13 +262,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.mark_pos(None) self.generate_module_cleanup_func(env, code) self.generate_filename_table(code) - self.generate_utility_functions(env, code) + self.generate_utility_functions(env, code, h_code) - self.generate_declarations_for_modules(env, modules, code.h) + self.generate_declarations_for_modules(env, modules, h_code) + h_code.write('\n') f = open_new_file(result.c_file) - code.h.copyto(f) - f.write("\n") code.copyto(f) f.close() result.c_file_generated = 1 @@ -1947,7 +1946,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): "%s = &%s;" % ( type.typeptr_cname, type.typeobj_cname)) - def generate_utility_functions(self, env, code): + def generate_utility_functions(self, env, code, h_code): code.putln("") code.putln("/* Runtime support code */") code.putln("") @@ -1956,7 +1955,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): (Naming.filetable_cname, Naming.filenames_cname)) code.putln("}") for utility_code in env.utility_code_used: - code.h.put(utility_code[0]) + h_code.put(utility_code[0]) code.put(utility_code[1]) code.put(PyrexTypes.type_conversion_functions) code.putln("") -- cgit v1.2.1 From b6f46a392b7d902fc96a348c427a6166714aaba5 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Wed, 30 Jul 2008 10:54:59 +0200 Subject: Changed name from "fork" to "insertion_point" (codewriter), introduced func context --- Cython/Compiler/ModuleNode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 6e4b20ddd..f2662a7ef 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -239,7 +239,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code = Annotate.AnnotationCCodeWriter() else: code = Code.CCodeWriter() - h_code = code.fork() + h_code = code.insertion_point() self.generate_module_preamble(env, modules, h_code) code.putln("") -- cgit v1.2.1 From f614efffc3ce979391abb93b56d49b23c4822503 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Wed, 30 Jul 2008 12:30:15 +0200 Subject: Module init func must also declare codewrite temps --- Cython/Compiler/ModuleNode.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Cython/Compiler/ModuleNode.py') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index f2662a7ef..26b778e31 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1547,8 +1547,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln(header3) code.putln("#endif") code.putln("{") - - code.put_var_declarations(env.temp_entries) + tempdecl_code = code.insertion_point() code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos))); code.putln("/*--- Libary function declarations ---*/") @@ -1609,6 +1608,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("return NULL;") code.putln("#endif") code.putln('}') + + tempdecl_code.put_var_declarations(env.temp_entries) + tempdecl_code.put_temp_declarations(code.func) + code.exit_cfunc_scope() def generate_module_cleanup_func(self, env, code): -- cgit v1.2.1