Cython has moved to github.

cython-devel

view Cython/Compiler/ModuleNode.py @ 2158:50307880f9c1

almost complete refactoring of constant allocation to move it into the code generation phase
author Stefan Behnel <scoder@users.berlios.de>
date Wed Mar 18 21:44:34 2009 +0100 (3 years ago)
parents 838a6b7cae62
children 8195340e572c
line source
1 #
2 # Pyrex - Module parse tree node
3 #
5 import os, time
6 from PyrexTypes import CPtrType
7 import Future
9 try:
10 set
11 except NameError: # Python 2.3
12 from sets import Set as set
14 import Annotate
15 import Code
16 import Naming
17 import Nodes
18 import Options
19 import PyrexTypes
20 import TypeSlots
21 import Version
22 import DebugFlags
24 from Errors import error, warning
25 from PyrexTypes import py_object_type
26 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
27 from StringEncoding import escape_byte_string, EncodedString
30 def check_c_declarations(module_node):
31 module_node.scope.check_c_classes()
32 module_node.scope.check_c_functions()
33 return module_node
35 class ModuleNode(Nodes.Node, Nodes.BlockNode):
36 # doc string or None
37 # body StatListNode
38 #
39 # referenced_modules [ModuleScope]
40 # module_temp_cname string
41 # full_module_name string
42 #
43 # scope The module scope.
44 # compilation_source A CompilationSource (see Main)
45 # directives Top-level compiler directives
47 child_attrs = ["body"]
48 directives = None
50 def analyse_declarations(self, env):
51 if Options.embed_pos_in_docstring:
52 env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos))
53 if not self.doc is None:
54 env.doc = EncodedString(env.doc + u'\n' + self.doc)
55 env.doc.encoding = self.doc.encoding
56 else:
57 env.doc = self.doc
58 env.directives = self.directives
59 self.body.analyse_declarations(env)
61 def process_implementation(self, options, result):
62 env = self.scope
63 env.return_type = PyrexTypes.c_void_type
64 self.referenced_modules = []
65 self.find_referenced_modules(env, self.referenced_modules, {})
66 if self.has_imported_c_functions():
67 self.module_temp_cname = env.allocate_temp_pyobject()
68 env.release_temp(self.module_temp_cname)
69 if options.recursive:
70 self.generate_dep_file(env, result)
71 self.generate_c_code(env, options, result)
72 self.generate_h_code(env, options, result)
73 self.generate_api_code(env, result)
75 def has_imported_c_functions(self):
76 for module in self.referenced_modules:
77 for entry in module.cfunc_entries:
78 if entry.defined_in_pxd:
79 return 1
80 return 0
82 def generate_dep_file(self, env, result):
83 modules = self.referenced_modules
84 if len(modules) > 1 or env.included_files:
85 dep_file = replace_suffix(result.c_file, ".dep")
86 f = open(dep_file, "w")
87 try:
88 for module in modules:
89 if module is not env:
90 f.write("cimport %s\n" % module.qualified_name)
91 for path in module.included_files:
92 f.write("include %s\n" % path)
93 finally:
94 f.close()
96 def generate_h_code(self, env, options, result):
97 def h_entries(entries, pxd = 0):
98 return [entry for entry in entries
99 if entry.visibility == 'public' or pxd and entry.defined_in_pxd]
100 h_types = h_entries(env.type_entries)
101 h_vars = h_entries(env.var_entries)
102 h_funcs = h_entries(env.cfunc_entries)
103 h_extension_types = h_entries(env.c_class_entries)
104 if h_types or h_vars or h_funcs or h_extension_types:
105 result.h_file = replace_suffix(result.c_file, ".h")
106 h_code = Code.CCodeWriter()
107 if options.generate_pxi:
108 result.i_file = replace_suffix(result.c_file, ".pxi")
109 i_code = Code.PyrexCodeWriter(result.i_file)
110 else:
111 i_code = None
112 guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
113 h_code.put_h_guard(guard)
114 self.generate_extern_c_macro_definition(h_code)
115 self.generate_type_header_code(h_types, h_code)
116 h_code.putln("")
117 h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
118 if h_vars:
119 h_code.putln("")
120 for entry in h_vars:
121 self.generate_public_declaration(entry, h_code, i_code)
122 if h_funcs:
123 h_code.putln("")
124 for entry in h_funcs:
125 self.generate_public_declaration(entry, h_code, i_code)
126 if h_extension_types:
127 h_code.putln("")
128 for entry in h_extension_types:
129 self.generate_cclass_header_code(entry.type, h_code)
130 if i_code:
131 self.generate_cclass_include_code(entry.type, i_code)
132 h_code.putln("")
133 h_code.putln("#endif")
134 h_code.putln("")
135 h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
136 h_code.putln("")
137 h_code.putln("#endif")
139 h_code.copyto(open_new_file(result.h_file))
141 def generate_public_declaration(self, entry, h_code, i_code):
142 h_code.putln("%s %s;" % (
143 Naming.extern_c_macro,
144 entry.type.declaration_code(
145 entry.cname, dll_linkage = "DL_IMPORT")))
146 if i_code:
147 i_code.putln("cdef extern %s" %
148 entry.type.declaration_code(entry.cname, pyrex = 1))
150 def api_name(self, env):
151 return env.qualified_name.replace(".", "__")
153 def generate_api_code(self, env, result):
154 api_funcs = []
155 public_extension_types = []
156 has_api_extension_types = 0
157 for entry in env.cfunc_entries:
158 if entry.api:
159 api_funcs.append(entry)
160 for entry in env.c_class_entries:
161 if entry.visibility == 'public':
162 public_extension_types.append(entry)
163 if entry.api:
164 has_api_extension_types = 1
165 if api_funcs or has_api_extension_types:
166 result.api_file = replace_suffix(result.c_file, "_api.h")
167 h_code = Code.CCodeWriter()
168 name = self.api_name(env)
169 guard = Naming.api_guard_prefix + name
170 h_code.put_h_guard(guard)
171 h_code.putln('#include "Python.h"')
172 if result.h_file:
173 h_code.putln('#include "%s"' % os.path.basename(result.h_file))
174 for entry in public_extension_types:
175 type = entry.type
176 h_code.putln("")
177 h_code.putln("static PyTypeObject *%s;" % type.typeptr_cname)
178 h_code.putln("#define %s (*%s)" % (
179 type.typeobj_cname, type.typeptr_cname))
180 if api_funcs:
181 h_code.putln("")
182 for entry in api_funcs:
183 type = CPtrType(entry.type)
184 h_code.putln("static %s;" % type.declaration_code(entry.cname))
185 h_code.putln("")
186 h_code.put_h_guard(Naming.api_func_guard + "import_module")
187 h_code.put(import_module_utility_code.impl)
188 h_code.putln("")
189 h_code.putln("#endif")
190 if api_funcs:
191 h_code.putln("")
192 h_code.put(function_import_utility_code.impl)
193 if public_extension_types:
194 h_code.putln("")
195 h_code.put(type_import_utility_code.impl)
196 h_code.putln("")
197 h_code.putln("static int import_%s(void) {" % name)
198 h_code.putln("PyObject *module = 0;")
199 h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
200 h_code.putln("if (!module) goto bad;")
201 for entry in api_funcs:
202 sig = entry.type.signature_string()
203 h_code.putln(
204 'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;' % (
205 entry.name,
206 entry.cname,
207 sig))
208 h_code.putln("Py_DECREF(module); module = 0;")
209 for entry in public_extension_types:
210 self.generate_type_import_call(
211 entry.type, h_code,
212 "if (!%s) goto bad;" % entry.type.typeptr_cname)
213 h_code.putln("return 0;")
214 h_code.putln("bad:")
215 h_code.putln("Py_XDECREF(module);")
216 h_code.putln("return -1;")
217 h_code.putln("}")
218 h_code.putln("")
219 h_code.putln("#endif")
221 h_code.copyto(open_new_file(result.api_file))
223 def generate_cclass_header_code(self, type, h_code):
224 h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
225 Naming.extern_c_macro,
226 type.typeobj_cname))
227 #self.generate_obj_struct_definition(type, h_code)
229 def generate_cclass_include_code(self, type, i_code):
230 i_code.putln("cdef extern class %s.%s:" % (
231 type.module_name, type.name))
232 i_code.indent()
233 var_entries = type.scope.var_entries
234 if var_entries:
235 for entry in var_entries:
236 i_code.putln("cdef %s" %
237 entry.type.declaration_code(entry.cname, pyrex = 1))
238 else:
239 i_code.putln("pass")
240 i_code.dedent()
242 def generate_c_code(self, env, options, result):
243 modules = self.referenced_modules
244 if Options.annotate or options.annotate:
245 code = Annotate.AnnotationCCodeWriter()
246 else:
247 code = Code.CCodeWriter(emit_linenums=options.emit_linenums)
248 h_code = code.insertion_point()
249 self.generate_module_preamble(env, modules, h_code)
251 code.globalstate.module_pos = self.pos
252 code.globalstate.directives = self.directives
254 code.globalstate.use_utility_code(refcount_utility_code)
256 code.putln("")
257 code.putln("/* Implementation of %s */" % env.qualified_name)
258 self.generate_const_definitions(env, code)
259 self.generate_interned_num_decls(env, code)
260 self.generate_interned_string_decls(env, code)
261 self.generate_py_string_decls(env, code)
263 code.globalstate.insert_global_var_declarations_into(code)
265 self.generate_cached_builtins_decls(env, code)
266 self.body.generate_function_definitions(env, code)
267 code.mark_pos(None)
268 self.generate_typeobj_definitions(env, code)
269 self.generate_method_table(env, code)
270 self.generate_filename_init_prototype(code)
271 if env.has_import_star:
272 self.generate_import_star(env, code)
273 self.generate_pymoduledef_struct(env, code)
274 self.generate_module_init_func(modules[:-1], env, code)
275 code.mark_pos(None)
276 self.generate_module_cleanup_func(env, code)
277 self.generate_filename_table(code)
278 self.generate_utility_functions(env, code, h_code)
280 self.generate_declarations_for_modules(env, modules, h_code)
281 h_code.write('\n')
283 code.globalstate.close_global_decls()
285 f = open_new_file(result.c_file)
286 code.copyto(f)
287 f.close()
288 result.c_file_generated = 1
289 if Options.annotate or options.annotate:
290 self.annotate(code)
291 code.save_annotation(result.main_source_file, result.c_file)
293 def find_referenced_modules(self, env, module_list, modules_seen):
294 if env not in modules_seen:
295 modules_seen[env] = 1
296 for imported_module in env.cimported_modules:
297 self.find_referenced_modules(imported_module, module_list, modules_seen)
298 module_list.append(env)
300 def sort_types_by_inheritance(self, type_dict, getkey):
301 # copy the types into a list moving each parent type before
302 # its first child
303 type_items = type_dict.items()
304 type_list = []
305 for i, item in enumerate(type_items):
306 key, new_entry = item
308 # collect all base classes to check for children
309 hierarchy = set()
310 base = new_entry
311 while base:
312 base_type = base.type.base_type
313 if not base_type:
314 break
315 base_key = getkey(base_type)
316 hierarchy.add(base_key)
317 base = type_dict.get(base_key)
318 new_entry.base_keys = hierarchy
320 # find the first (sub-)subclass and insert before that
321 for j in range(i):
322 entry = type_list[j]
323 if key in entry.base_keys:
324 type_list.insert(j, new_entry)
325 break
326 else:
327 type_list.append(new_entry)
328 return type_list
330 def sort_type_hierarchy(self, module_list, env):
331 vtab_dict = {}
332 vtabslot_dict = {}
333 for module in module_list:
334 for entry in module.c_class_entries:
335 if not entry.in_cinclude:
336 type = entry.type
337 if type.vtabstruct_cname:
338 vtab_dict[type.vtabstruct_cname] = entry
339 all_defined_here = module is env
340 for entry in module.type_entries:
341 if all_defined_here or entry.defined_in_pxd:
342 type = entry.type
343 if type.is_extension_type and not entry.in_cinclude:
344 type = entry.type
345 vtabslot_dict[type.objstruct_cname] = entry
347 def vtabstruct_cname(entry_type):
348 return entry_type.vtabstruct_cname
349 vtab_list = self.sort_types_by_inheritance(
350 vtab_dict, vtabstruct_cname)
352 def objstruct_cname(entry_type):
353 return entry_type.objstruct_cname
354 vtabslot_list = self.sort_types_by_inheritance(
355 vtabslot_dict, objstruct_cname)
357 return (vtab_list, vtabslot_list)
359 def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
360 vtabslot_entries = set(vtabslot_list)
361 for module in modules:
362 definition = module is env
363 if definition:
364 type_entries = module.type_entries
365 else:
366 type_entries = []
367 for entry in module.type_entries:
368 if entry.defined_in_pxd:
369 type_entries.append(entry)
370 for entry in type_entries:
371 if not entry.in_cinclude:
372 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
373 type = entry.type
374 if type.is_typedef: # Must test this first!
375 self.generate_typedef(entry, code)
376 elif type.is_struct_or_union:
377 self.generate_struct_union_definition(entry, code)
378 elif type.is_enum:
379 self.generate_enum_definition(entry, code)
380 elif type.is_extension_type and entry not in vtabslot_entries:
381 self.generate_obj_struct_definition(type, code)
382 for entry in vtabslot_list:
383 self.generate_obj_struct_definition(entry.type, code)
384 for entry in vtab_list:
385 self.generate_typeobject_predeclaration(entry, code)
386 self.generate_exttype_vtable_struct(entry, code)
387 self.generate_exttype_vtabptr_declaration(entry, code)
389 def generate_declarations_for_modules(self, env, modules, code):
390 code.putln("")
391 code.putln("/* Type declarations */")
392 vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
393 self.generate_type_definitions(
394 env, modules, vtab_list, vtabslot_list, code)
395 for module in modules:
396 defined_here = module is env
397 code.putln("/* Module declarations from %s */" %
398 module.qualified_name.encode("ASCII", "ignore"))
399 self.generate_global_declarations(module, code, defined_here)
400 self.generate_cfunction_predeclarations(module, code, defined_here)
402 def generate_module_preamble(self, env, cimported_modules, code):
403 code.putln('/* Generated by Cython %s on %s */' % (
404 Version.version, time.asctime()))
405 code.putln('')
406 code.putln('#define PY_SSIZE_T_CLEAN')
407 for filename in env.python_include_files:
408 code.putln('#include "%s"' % filename)
409 code.putln("#ifndef PY_LONG_LONG")
410 code.putln(" #define PY_LONG_LONG LONG_LONG")
411 code.putln("#endif")
412 code.putln("#ifndef DL_EXPORT")
413 code.putln(" #define DL_EXPORT(t) t")
414 code.putln("#endif")
415 code.putln("#if PY_VERSION_HEX < 0x02040000")
416 code.putln(" #define METH_COEXIST 0")
417 code.putln(" #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)")
418 code.putln("#endif")
420 code.putln("#if PY_VERSION_HEX < 0x02050000")
421 code.putln(" typedef int Py_ssize_t;")
422 code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
423 code.putln(" #define PY_SSIZE_T_MIN INT_MIN")
424 code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
425 code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)")
426 code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)")
427 code.putln(" #define PyIndex_Check(o) PyNumber_Check(o)")
428 code.putln("#endif")
430 code.putln("#if PY_VERSION_HEX < 0x02060000")
431 code.putln(" #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)")
432 code.putln(" #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)")
433 code.putln(" #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)")
434 code.putln(" #define PyVarObject_HEAD_INIT(type, size) \\")
435 code.putln(" PyObject_HEAD_INIT(type) size,")
436 code.putln(" #define PyType_Modified(t)")
437 code.putln("")
438 code.putln(" typedef struct {")
439 code.putln(" void *buf;")
440 code.putln(" PyObject *obj;")
441 code.putln(" Py_ssize_t len;")
442 code.putln(" Py_ssize_t itemsize;")
443 code.putln(" int readonly;")
444 code.putln(" int ndim;")
445 code.putln(" char *format;")
446 code.putln(" Py_ssize_t *shape;")
447 code.putln(" Py_ssize_t *strides;")
448 code.putln(" Py_ssize_t *suboffsets;")
449 code.putln(" void *internal;")
450 code.putln(" } Py_buffer;")
451 code.putln("")
452 code.putln(" #define PyBUF_SIMPLE 0")
453 code.putln(" #define PyBUF_WRITABLE 0x0001")
454 code.putln(" #define PyBUF_FORMAT 0x0004")
455 code.putln(" #define PyBUF_ND 0x0008")
456 code.putln(" #define PyBUF_STRIDES (0x0010 | PyBUF_ND)")
457 code.putln(" #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)")
458 code.putln(" #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)")
459 code.putln(" #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)")
460 code.putln(" #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)")
461 code.putln("")
462 code.putln("#endif")
464 code.put(builtin_module_name_utility_code.proto)
466 code.putln("#if PY_MAJOR_VERSION >= 3")
467 code.putln(" #define Py_TPFLAGS_CHECKTYPES 0")
468 code.putln(" #define Py_TPFLAGS_HAVE_INDEX 0")
469 code.putln("#endif")
471 code.putln("#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)")
472 code.putln(" #define Py_TPFLAGS_HAVE_NEWBUFFER 0")
473 code.putln("#endif")
475 code.putln("#if PY_MAJOR_VERSION >= 3")
476 code.putln(" #define PyBaseString_Type PyUnicode_Type")
477 code.putln(" #define PyString_Type PyBytes_Type")
478 code.putln(" #define PyString_CheckExact PyBytes_CheckExact")
479 code.putln(" #define PyInt_Type PyLong_Type")
480 code.putln(" #define PyInt_Check(op) PyLong_Check(op)")
481 code.putln(" #define PyInt_CheckExact(op) PyLong_CheckExact(op)")
482 code.putln(" #define PyInt_FromString PyLong_FromString")
483 code.putln(" #define PyInt_FromUnicode PyLong_FromUnicode")
484 code.putln(" #define PyInt_FromLong PyLong_FromLong")
485 code.putln(" #define PyInt_FromSize_t PyLong_FromSize_t")
486 code.putln(" #define PyInt_FromSsize_t PyLong_FromSsize_t")
487 code.putln(" #define PyInt_AsLong PyLong_AsLong")
488 code.putln(" #define PyInt_AS_LONG PyLong_AS_LONG")
489 code.putln(" #define PyInt_AsSsize_t PyLong_AsSsize_t")
490 code.putln(" #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask")
491 code.putln(" #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask")
492 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
493 code.putln("#else")
494 if Future.division in env.context.future_directives:
495 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
496 else:
497 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)")
498 code.putln(" #define PyBytes_Type PyString_Type")
499 code.putln("#endif")
501 code.putln("#if PY_MAJOR_VERSION >= 3")
502 code.putln(" #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)")
503 code.putln("#endif")
505 code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
506 code.putln(" #ifndef __stdcall")
507 code.putln(" #define __stdcall")
508 code.putln(" #endif")
509 code.putln(" #ifndef __cdecl")
510 code.putln(" #define __cdecl")
511 code.putln(" #endif")
512 code.putln("#else")
513 code.putln(" #define _USE_MATH_DEFINES")
514 code.putln("#endif")
516 code.putln("#if PY_VERSION_HEX < 0x02050000")
517 code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))")
518 code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))")
519 code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))")
520 code.putln("#else")
521 code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))")
522 code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))")
523 code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))")
524 code.putln("#endif")
526 code.putln("#if PY_VERSION_HEX < 0x02050000")
527 code.putln(" #define __Pyx_NAMESTR(n) ((char *)(n))")
528 code.putln(" #define __Pyx_DOCSTR(n) ((char *)(n))")
529 code.putln("#else")
530 code.putln(" #define __Pyx_NAMESTR(n) (n)")
531 code.putln(" #define __Pyx_DOCSTR(n) (n)")
532 code.putln("#endif")
534 self.generate_extern_c_macro_definition(code)
535 code.putln("#include <math.h>")
536 code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
537 self.generate_includes(env, cimported_modules, code)
538 code.putln('')
539 code.put(Nodes.utility_function_predeclarations)
540 code.put(PyrexTypes.type_conversion_predeclarations)
541 code.put(Nodes.branch_prediction_macros)
542 code.putln('')
543 code.putln('static PyObject *%s;' % env.module_cname)
544 code.putln('static PyObject *%s;' % Naming.builtins_cname)
545 code.putln('static PyObject *%s;' % Naming.empty_tuple)
546 if Options.pre_import is not None:
547 code.putln('static PyObject *%s;' % Naming.preimport_cname)
548 code.putln('static int %s;' % Naming.lineno_cname)
549 code.putln('static int %s = 0;' % Naming.clineno_cname)
550 code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
551 code.putln('static const char *%s;' % Naming.filename_cname)
552 code.putln('static const char **%s;' % Naming.filetable_cname)
554 env.use_utility_code(streq_utility_code)
556 def generate_extern_c_macro_definition(self, code):
557 name = Naming.extern_c_macro
558 code.putln("#ifdef __cplusplus")
559 code.putln('#define %s extern "C"' % name)
560 code.putln("#else")
561 code.putln("#define %s extern" % name)
562 code.putln("#endif")
564 def generate_includes(self, env, cimported_modules, code):
565 includes = []
566 for filename in env.include_files:
567 code.putln('#include "%s"' % filename)
569 def generate_filename_table(self, code):
570 code.putln("")
571 code.putln("static const char *%s[] = {" % Naming.filenames_cname)
572 if code.globalstate.filename_list:
573 for source_desc in code.globalstate.filename_list:
574 filename = os.path.basename(source_desc.get_filenametable_entry())
575 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
576 code.putln('"%s",' %
577 escaped_filename)
578 else:
579 # Some C compilers don't like an empty array
580 code.putln("0")
581 code.putln("};")
583 def generate_type_predeclarations(self, env, code):
584 pass
586 def generate_type_header_code(self, type_entries, code):
587 # Generate definitions of structs/unions/enums/typedefs/objstructs.
588 #self.generate_gcc33_hack(env, code) # Is this still needed?
589 #for entry in env.type_entries:
590 for entry in type_entries:
591 if not entry.in_cinclude:
592 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
593 type = entry.type
594 if type.is_typedef: # Must test this first!
595 self.generate_typedef(entry, code)
596 elif type.is_struct_or_union:
597 self.generate_struct_union_definition(entry, code)
598 elif type.is_enum:
599 self.generate_enum_definition(entry, code)
600 elif type.is_extension_type:
601 self.generate_obj_struct_definition(type, code)
603 def generate_gcc33_hack(self, env, code):
604 # Workaround for spurious warning generation in gcc 3.3
605 code.putln("")
606 for entry in env.c_class_entries:
607 type = entry.type
608 if not type.typedef_flag:
609 name = type.objstruct_cname
610 if name.startswith("__pyx_"):
611 tail = name[6:]
612 else:
613 tail = name
614 code.putln("typedef struct %s __pyx_gcc33_%s;" % (
615 name, tail))
617 def generate_typedef(self, entry, code):
618 base_type = entry.type.typedef_base_type
619 code.putln("")
620 code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
622 def sue_header_footer(self, type, kind, name):
623 if type.typedef_flag:
624 header = "typedef %s {" % kind
625 footer = "} %s;" % name
626 else:
627 header = "%s %s {" % (kind, name)
628 footer = "};"
629 return header, footer
631 def generate_struct_union_definition(self, entry, code):
632 code.mark_pos(entry.pos)
633 type = entry.type
634 scope = type.scope
635 if scope:
636 header, footer = \
637 self.sue_header_footer(type, type.kind, type.cname)
638 code.putln("")
639 code.putln(header)
640 var_entries = scope.var_entries
641 if not var_entries:
642 error(entry.pos,
643 "Empty struct or union definition not allowed outside a"
644 " 'cdef extern from' block")
645 for attr in var_entries:
646 code.putln(
647 "%s;" %
648 attr.type.declaration_code(attr.cname))
649 code.putln(footer)
651 def generate_enum_definition(self, entry, code):
652 code.mark_pos(entry.pos)
653 type = entry.type
654 name = entry.cname or entry.name or ""
655 header, footer = \
656 self.sue_header_footer(type, "enum", name)
657 code.putln("")
658 code.putln(header)
659 enum_values = entry.enum_values
660 if not enum_values:
661 error(entry.pos,
662 "Empty enum definition not allowed outside a"
663 " 'cdef extern from' block")
664 else:
665 last_entry = enum_values[-1]
666 for value_entry in enum_values:
667 if value_entry.value == value_entry.name:
668 value_code = value_entry.cname
669 else:
670 value_code = ("%s = %s" % (
671 value_entry.cname,
672 value_entry.value))
673 if value_entry is not last_entry:
674 value_code += ","
675 code.putln(value_code)
676 code.putln(footer)
678 def generate_typeobject_predeclaration(self, entry, code):
679 code.putln("")
680 name = entry.type.typeobj_cname
681 if name:
682 if entry.visibility == 'extern' and not entry.in_cinclude:
683 code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
684 Naming.extern_c_macro,
685 name))
686 elif entry.visibility == 'public':
687 #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
688 code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
689 Naming.extern_c_macro,
690 name))
691 # ??? Do we really need the rest of this? ???
692 #else:
693 # code.putln("staticforward PyTypeObject %s;" % name)
695 def generate_exttype_vtable_struct(self, entry, code):
696 code.mark_pos(entry.pos)
697 # Generate struct declaration for an extension type's vtable.
698 type = entry.type
699 scope = type.scope
700 if type.vtabstruct_cname:
701 code.putln("")
702 code.putln(
703 "struct %s {" %
704 type.vtabstruct_cname)
705 if type.base_type and type.base_type.vtabstruct_cname:
706 code.putln("struct %s %s;" % (
707 type.base_type.vtabstruct_cname,
708 Naming.obj_base_cname))
709 for method_entry in scope.cfunc_entries:
710 if not method_entry.is_inherited:
711 code.putln(
712 "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
713 code.putln(
714 "};")
716 def generate_exttype_vtabptr_declaration(self, entry, code):
717 code.mark_pos(entry.pos)
718 # Generate declaration of pointer to an extension type's vtable.
719 type = entry.type
720 if type.vtabptr_cname:
721 code.putln("static struct %s *%s;" % (
722 type.vtabstruct_cname,
723 type.vtabptr_cname))
725 def generate_obj_struct_definition(self, type, code):
726 code.mark_pos(type.pos)
727 # Generate object struct definition for an
728 # extension type.
729 if not type.scope:
730 return # Forward declared but never defined
731 header, footer = \
732 self.sue_header_footer(type, "struct", type.objstruct_cname)
733 code.putln("")
734 code.putln(header)
735 base_type = type.base_type
736 if base_type:
737 code.putln(
738 "%s%s %s;" % (
739 ("struct ", "")[base_type.typedef_flag],
740 base_type.objstruct_cname,
741 Naming.obj_base_cname))
742 else:
743 code.putln(
744 "PyObject_HEAD")
745 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
746 code.putln(
747 "struct %s *%s;" % (
748 type.vtabstruct_cname,
749 type.vtabslot_cname))
750 for attr in type.scope.var_entries:
751 code.putln(
752 "%s;" %
753 attr.type.declaration_code(attr.cname))
754 code.putln(footer)
756 def generate_global_declarations(self, env, code, definition):
757 code.putln("")
758 for entry in env.c_class_entries:
759 if definition or entry.defined_in_pxd:
760 code.putln("static PyTypeObject *%s = 0;" %
761 entry.type.typeptr_cname)
762 code.put_var_declarations(env.var_entries, static = 1,
763 dll_linkage = "DL_EXPORT", definition = definition)
764 if definition:
765 code.put_var_declarations(env.default_entries, static = 1,
766 definition = definition)
768 def generate_cfunction_predeclarations(self, env, code, definition):
769 for entry in env.cfunc_entries:
770 if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
771 or entry.defined_in_pxd or entry.visibility == 'extern')):
772 if entry.visibility in ('public', 'extern'):
773 dll_linkage = "DL_EXPORT"
774 else:
775 dll_linkage = None
776 type = entry.type
777 if not definition and entry.defined_in_pxd:
778 type = CPtrType(type)
779 header = type.declaration_code(entry.cname,
780 dll_linkage = dll_linkage)
781 if entry.visibility == 'private':
782 storage_class = "static "
783 elif entry.visibility == 'public':
784 storage_class = ""
785 else:
786 storage_class = "%s " % Naming.extern_c_macro
787 if entry.func_modifiers:
788 modifiers = '%s ' % ' '.join([
789 modifier.upper() for modifier in entry.func_modifiers])
790 else:
791 modifiers = ''
792 code.putln("%s%s%s; /*proto*/" % (
793 storage_class,
794 modifiers,
795 header))
797 def generate_typeobj_definitions(self, env, code):
798 full_module_name = env.qualified_name
799 for entry in env.c_class_entries:
800 #print "generate_typeobj_definitions:", entry.name
801 #print "...visibility =", entry.visibility
802 if entry.visibility != 'extern':
803 type = entry.type
804 scope = type.scope
805 if scope: # could be None if there was an error
806 self.generate_exttype_vtable(scope, code)
807 self.generate_new_function(scope, code)
808 self.generate_dealloc_function(scope, code)
809 if scope.needs_gc():
810 self.generate_traverse_function(scope, code)
811 self.generate_clear_function(scope, code)
812 if scope.defines_any(["__getitem__"]):
813 self.generate_getitem_int_function(scope, code)
814 if scope.defines_any(["__setitem__", "__delitem__"]):
815 self.generate_ass_subscript_function(scope, code)
816 if scope.defines_any(["__setslice__", "__delslice__"]):
817 warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3", 1)
818 self.generate_ass_slice_function(scope, code)
819 if scope.defines_any(["__getattr__","__getattribute__"]):
820 self.generate_getattro_function(scope, code)
821 if scope.defines_any(["__setattr__", "__delattr__"]):
822 self.generate_setattro_function(scope, code)
823 if scope.defines_any(["__get__"]):
824 self.generate_descr_get_function(scope, code)
825 if scope.defines_any(["__set__", "__delete__"]):
826 self.generate_descr_set_function(scope, code)
827 self.generate_property_accessors(scope, code)
828 self.generate_method_table(scope, code)
829 self.generate_member_table(scope, code)
830 self.generate_getset_table(scope, code)
831 self.generate_typeobj_definition(full_module_name, entry, code)
833 def generate_exttype_vtable(self, scope, code):
834 # Generate the definition of an extension type's vtable.
835 type = scope.parent_type
836 if type.vtable_cname:
837 code.putln("static struct %s %s;" % (
838 type.vtabstruct_cname,
839 type.vtable_cname))
841 def generate_self_cast(self, scope, code):
842 type = scope.parent_type
843 code.putln(
844 "%s = (%s)o;" % (
845 type.declaration_code("p"),
846 type.declaration_code("")))
848 def generate_new_function(self, scope, code):
849 tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
850 slot_func = scope.mangle_internal("tp_new")
851 type = scope.parent_type
852 base_type = type.base_type
853 py_attrs = []
854 for entry in scope.var_entries:
855 if entry.type.is_pyobject:
856 py_attrs.append(entry)
857 need_self_cast = type.vtabslot_cname or py_attrs
858 code.putln("")
859 code.putln(
860 "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
861 % scope.mangle_internal("tp_new"))
862 if need_self_cast:
863 code.putln(
864 "%s;"
865 % scope.parent_type.declaration_code("p"))
866 if base_type:
867 tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
868 if tp_new is None:
869 tp_new = "%s->tp_new" % base_type.typeptr_cname
870 code.putln(
871 "PyObject *o = %s(t, a, k);" % tp_new)
872 else:
873 code.putln(
874 "PyObject *o = (*t->tp_alloc)(t, 0);")
875 code.putln(
876 "if (!o) return 0;")
877 if need_self_cast:
878 code.putln(
879 "p = %s;"
880 % type.cast_code("o"))
881 #if need_self_cast:
882 # self.generate_self_cast(scope, code)
883 if type.vtabslot_cname:
884 vtab_base_type = type
885 while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
886 vtab_base_type = vtab_base_type.base_type
887 if vtab_base_type is not type:
888 struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
889 else:
890 struct_type_cast = ""
891 code.putln("p->%s = %s%s;" % (
892 type.vtabslot_cname,
893 struct_type_cast, type.vtabptr_cname))
894 for entry in py_attrs:
895 if entry.name == "__weakref__":
896 code.putln("p->%s = 0;" % entry.cname)
897 else:
898 code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
899 entry = scope.lookup_here("__new__")
900 if entry and entry.is_special:
901 if entry.trivial_signature:
902 cinit_args = "o, %s, NULL" % Naming.empty_tuple
903 else:
904 cinit_args = "o, a, k"
905 code.putln(
906 "if (%s(%s) < 0) {" %
907 (entry.func_cname, cinit_args))
908 code.put_decref_clear("o", py_object_type, nanny=False);
909 code.putln(
910 "}")
911 code.putln(
912 "return o;")
913 code.putln(
914 "}")
916 def generate_dealloc_function(self, scope, code):
917 tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
918 slot_func = scope.mangle_internal("tp_dealloc")
919 base_type = scope.parent_type.base_type
920 if tp_slot.slot_code(scope) != slot_func:
921 return # never used
922 code.putln("")
923 code.putln(
924 "static void %s(PyObject *o) {"
925 % scope.mangle_internal("tp_dealloc"))
926 py_attrs = []
927 weakref_slot = scope.lookup_here("__weakref__")
928 for entry in scope.var_entries:
929 if entry.type.is_pyobject and entry is not weakref_slot:
930 py_attrs.append(entry)
931 if py_attrs or weakref_slot in scope.var_entries:
932 self.generate_self_cast(scope, code)
933 self.generate_usr_dealloc_call(scope, code)
934 if weakref_slot in scope.var_entries:
935 code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
936 for entry in py_attrs:
937 code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
938 if base_type:
939 tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
940 if tp_dealloc is None:
941 tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
942 code.putln(
943 "%s(o);" % tp_dealloc)
944 else:
945 code.putln(
946 "(*Py_TYPE(o)->tp_free)(o);")
947 code.putln(
948 "}")
950 def generate_usr_dealloc_call(self, scope, code):
951 entry = scope.lookup_here("__dealloc__")
952 if entry:
953 code.putln(
954 "{")
955 code.putln(
956 "PyObject *etype, *eval, *etb;")
957 code.putln(
958 "PyErr_Fetch(&etype, &eval, &etb);")
959 code.putln(
960 "++Py_REFCNT(o);")
961 code.putln(
962 "%s(o);" %
963 entry.func_cname)
964 code.putln(
965 "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
966 code.putln(
967 "--Py_REFCNT(o);")
968 code.putln(
969 "PyErr_Restore(etype, eval, etb);")
970 code.putln(
971 "}")
973 def generate_traverse_function(self, scope, code):
974 tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
975 slot_func = scope.mangle_internal("tp_traverse")
976 base_type = scope.parent_type.base_type
977 if tp_slot.slot_code(scope) != slot_func:
978 return # never used
979 code.putln("")
980 code.putln(
981 "static int %s(PyObject *o, visitproc v, void *a) {"
982 % slot_func)
983 py_attrs = []
984 for entry in scope.var_entries:
985 if entry.type.is_pyobject and entry.name != "__weakref__":
986 py_attrs.append(entry)
987 if base_type or py_attrs:
988 code.putln("int e;")
989 if py_attrs:
990 self.generate_self_cast(scope, code)
991 if base_type:
992 # want to call it explicitly if possible so inlining can be performed
993 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
994 if static_call:
995 code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
996 else:
997 code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
998 code.putln(
999 "e = %s->tp_traverse(o, v, a); if (e) return e;" %
1000 base_type.typeptr_cname)
1001 code.putln("}")
1002 for entry in py_attrs:
1003 var_code = "p->%s" % entry.cname
1004 code.putln(
1005 "if (%s) {"
1006 % var_code)
1007 if entry.type.is_extension_type:
1008 var_code = "((PyObject*)%s)" % var_code
1009 code.putln(
1010 "e = (*v)(%s, a); if (e) return e;"
1011 % var_code)
1012 code.putln(
1013 "}")
1014 code.putln(
1015 "return 0;")
1016 code.putln(
1017 "}")
1019 def generate_clear_function(self, scope, code):
1020 tp_slot = TypeSlots.GCDependentSlot("tp_clear")
1021 slot_func = scope.mangle_internal("tp_clear")
1022 base_type = scope.parent_type.base_type
1023 if tp_slot.slot_code(scope) != slot_func:
1024 return # never used
1025 code.putln("")
1026 code.putln("static int %s(PyObject *o) {" % slot_func)
1027 py_attrs = []
1028 for entry in scope.var_entries:
1029 if entry.type.is_pyobject and entry.name != "__weakref__":
1030 py_attrs.append(entry)
1031 if py_attrs:
1032 self.generate_self_cast(scope, code)
1033 code.putln("PyObject* tmp;")
1034 if base_type:
1035 # want to call it explicitly if possible so inlining can be performed
1036 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1037 if static_call:
1038 code.putln("%s(o);" % static_call)
1039 else:
1040 code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
1041 code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
1042 code.putln("}")
1043 for entry in py_attrs:
1044 name = "p->%s" % entry.cname
1045 code.putln("tmp = ((PyObject*)%s);" % name)
1046 code.put_init_to_py_none(name, entry.type, nanny=False)
1047 code.putln("Py_XDECREF(tmp);")
1048 code.putln(
1049 "return 0;")
1050 code.putln(
1051 "}")
1053 def generate_getitem_int_function(self, scope, code):
1054 # This function is put into the sq_item slot when
1055 # a __getitem__ method is present. It converts its
1056 # argument to a Python integer and calls mp_subscript.
1057 code.putln(
1058 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1059 scope.mangle_internal("sq_item"))
1060 code.putln(
1061 "PyObject *r;")
1062 code.putln(
1063 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1064 code.putln(
1065 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1066 code.putln(
1067 "Py_DECREF(x);")
1068 code.putln(
1069 "return r;")
1070 code.putln(
1071 "}")
1073 def generate_ass_subscript_function(self, scope, code):
1074 # Setting and deleting an item are both done through
1075 # the ass_subscript method, so we dispatch to user's __setitem__
1076 # or __delitem__, or raise an exception.
1077 base_type = scope.parent_type.base_type
1078 set_entry = scope.lookup_here("__setitem__")
1079 del_entry = scope.lookup_here("__delitem__")
1080 code.putln("")
1081 code.putln(
1082 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1083 scope.mangle_internal("mp_ass_subscript"))
1084 code.putln(
1085 "if (v) {")
1086 if set_entry:
1087 code.putln(
1088 "return %s(o, i, v);" %
1089 set_entry.func_cname)
1090 else:
1091 self.generate_guarded_basetype_call(
1092 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1093 code.putln(
1094 "PyErr_Format(PyExc_NotImplementedError,")
1095 code.putln(
1096 ' "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1097 code.putln(
1098 "return -1;")
1099 code.putln(
1100 "}")
1101 code.putln(
1102 "else {")
1103 if del_entry:
1104 code.putln(
1105 "return %s(o, i);" %
1106 del_entry.func_cname)
1107 else:
1108 self.generate_guarded_basetype_call(
1109 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1110 code.putln(
1111 "PyErr_Format(PyExc_NotImplementedError,")
1112 code.putln(
1113 ' "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1114 code.putln(
1115 "return -1;")
1116 code.putln(
1117 "}")
1118 code.putln(
1119 "}")
1121 def generate_guarded_basetype_call(
1122 self, base_type, substructure, slot, args, code):
1123 if base_type:
1124 base_tpname = base_type.typeptr_cname
1125 if substructure:
1126 code.putln(
1127 "if (%s->%s && %s->%s->%s)" % (
1128 base_tpname, substructure, base_tpname, substructure, slot))
1129 code.putln(
1130 " return %s->%s->%s(%s);" % (
1131 base_tpname, substructure, slot, args))
1132 else:
1133 code.putln(
1134 "if (%s->%s)" % (
1135 base_tpname, slot))
1136 code.putln(
1137 " return %s->%s(%s);" % (
1138 base_tpname, slot, args))
1140 def generate_ass_slice_function(self, scope, code):
1141 # Setting and deleting a slice are both done through
1142 # the ass_slice method, so we dispatch to user's __setslice__
1143 # or __delslice__, or raise an exception.
1144 base_type = scope.parent_type.base_type
1145 set_entry = scope.lookup_here("__setslice__")
1146 del_entry = scope.lookup_here("__delslice__")
1147 code.putln("")
1148 code.putln(
1149 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1150 scope.mangle_internal("sq_ass_slice"))
1151 code.putln(
1152 "if (v) {")
1153 if set_entry:
1154 code.putln(
1155 "return %s(o, i, j, v);" %
1156 set_entry.func_cname)
1157 else:
1158 self.generate_guarded_basetype_call(
1159 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1160 code.putln(
1161 "PyErr_Format(PyExc_NotImplementedError,")
1162 code.putln(
1163 ' "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1164 code.putln(
1165 "return -1;")
1166 code.putln(
1167 "}")
1168 code.putln(
1169 "else {")
1170 if del_entry:
1171 code.putln(
1172 "return %s(o, i, j);" %
1173 del_entry.func_cname)
1174 else:
1175 self.generate_guarded_basetype_call(
1176 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1177 code.putln(
1178 "PyErr_Format(PyExc_NotImplementedError,")
1179 code.putln(
1180 ' "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1181 code.putln(
1182 "return -1;")
1183 code.putln(
1184 "}")
1185 code.putln(
1186 "}")
1188 def generate_getattro_function(self, scope, code):
1189 # First try to get the attribute using __getattribute__, if defined, or
1190 # PyObject_GenericGetAttr.
1192 # If that raises an AttributeError, call the __getattr__ if defined.
1194 # In both cases, defined can be in this class, or any base class.
1195 def lookup_here_or_base(n,type=None):
1196 # Recursive lookup
1197 if type is None:
1198 type = scope.parent_type
1199 r = type.scope.lookup_here(n)
1200 if r is None and \
1201 type.base_type is not None:
1202 return lookup_here_or_base(n,type.base_type)
1203 else:
1204 return r
1205 getattr_entry = lookup_here_or_base("__getattr__")
1206 getattribute_entry = lookup_here_or_base("__getattribute__")
1207 code.putln("")
1208 code.putln(
1209 "static PyObject *%s(PyObject *o, PyObject *n) {"
1210 % scope.mangle_internal("tp_getattro"))
1211 if getattribute_entry is not None:
1212 code.putln(
1213 "PyObject *v = %s(o, n);" %
1214 getattribute_entry.func_cname)
1215 else:
1216 code.putln(
1217 "PyObject *v = PyObject_GenericGetAttr(o, n);")
1218 if getattr_entry is not None:
1219 code.putln(
1220 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1221 code.putln(
1222 "PyErr_Clear();")
1223 code.putln(
1224 "v = %s(o, n);" %
1225 getattr_entry.func_cname)
1226 code.putln(
1227 "}")
1228 code.putln(
1229 "return v;")
1230 code.putln(
1231 "}")
1233 def generate_setattro_function(self, scope, code):
1234 # Setting and deleting an attribute are both done through
1235 # the setattro method, so we dispatch to user's __setattr__
1236 # or __delattr__ or fall back on PyObject_GenericSetAttr.
1237 base_type = scope.parent_type.base_type
1238 set_entry = scope.lookup_here("__setattr__")
1239 del_entry = scope.lookup_here("__delattr__")
1240 code.putln("")
1241 code.putln(
1242 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
1243 scope.mangle_internal("tp_setattro"))
1244 code.putln(
1245 "if (v) {")
1246 if set_entry:
1247 code.putln(
1248 "return %s(o, n, v);" %
1249 set_entry.func_cname)
1250 else:
1251 self.generate_guarded_basetype_call(
1252 base_type, None, "tp_setattro", "o, n, v", code)
1253 code.putln(
1254 "return PyObject_GenericSetAttr(o, n, v);")
1255 code.putln(
1256 "}")
1257 code.putln(
1258 "else {")
1259 if del_entry:
1260 code.putln(
1261 "return %s(o, n);" %
1262 del_entry.func_cname)
1263 else:
1264 self.generate_guarded_basetype_call(
1265 base_type, None, "tp_setattro", "o, n, v", code)
1266 code.putln(
1267 "return PyObject_GenericSetAttr(o, n, 0);")
1268 code.putln(
1269 "}")
1270 code.putln(
1271 "}")
1273 def generate_descr_get_function(self, scope, code):
1274 # The __get__ function of a descriptor object can be
1275 # called with NULL for the second or third arguments
1276 # under some circumstances, so we replace them with
1277 # None in that case.
1278 user_get_entry = scope.lookup_here("__get__")
1279 code.putln("")
1280 code.putln(
1281 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1282 scope.mangle_internal("tp_descr_get"))
1283 code.putln(
1284 "PyObject *r = 0;")
1285 code.putln(
1286 "if (!i) i = Py_None;")
1287 code.putln(
1288 "if (!c) c = Py_None;")
1289 #code.put_incref("i", py_object_type)
1290 #code.put_incref("c", py_object_type)
1291 code.putln(
1292 "r = %s(o, i, c);" %
1293 user_get_entry.func_cname)
1294 #code.put_decref("i", py_object_type)
1295 #code.put_decref("c", py_object_type)
1296 code.putln(
1297 "return r;")
1298 code.putln(
1299 "}")
1301 def generate_descr_set_function(self, scope, code):
1302 # Setting and deleting are both done through the __set__
1303 # method of a descriptor, so we dispatch to user's __set__
1304 # or __delete__ or raise an exception.
1305 base_type = scope.parent_type.base_type
1306 user_set_entry = scope.lookup_here("__set__")
1307 user_del_entry = scope.lookup_here("__delete__")
1308 code.putln("")
1309 code.putln(
1310 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1311 scope.mangle_internal("tp_descr_set"))
1312 code.putln(
1313 "if (v) {")
1314 if user_set_entry:
1315 code.putln(
1316 "return %s(o, i, v);" %
1317 user_set_entry.func_cname)
1318 else:
1319 self.generate_guarded_basetype_call(
1320 base_type, None, "tp_descr_set", "o, i, v", code)
1321 code.putln(
1322 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1323 code.putln(
1324 "return -1;")
1325 code.putln(
1326 "}")
1327 code.putln(
1328 "else {")
1329 if user_del_entry:
1330 code.putln(
1331 "return %s(o, i);" %
1332 user_del_entry.func_cname)
1333 else:
1334 self.generate_guarded_basetype_call(
1335 base_type, None, "tp_descr_set", "o, i, v", code)
1336 code.putln(
1337 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1338 code.putln(
1339 "return -1;")
1340 code.putln(
1341 "}")
1342 code.putln(
1343 "}")
1345 def generate_property_accessors(self, cclass_scope, code):
1346 for entry in cclass_scope.property_entries:
1347 property_scope = entry.scope
1348 if property_scope.defines_any(["__get__"]):
1349 self.generate_property_get_function(entry, code)
1350 if property_scope.defines_any(["__set__", "__del__"]):
1351 self.generate_property_set_function(entry, code)
1353 def generate_property_get_function(self, property_entry, code):
1354 property_scope = property_entry.scope
1355 property_entry.getter_cname = property_scope.parent_scope.mangle(
1356 Naming.prop_get_prefix, property_entry.name)
1357 get_entry = property_scope.lookup_here("__get__")
1358 code.putln("")
1359 code.putln(
1360 "static PyObject *%s(PyObject *o, void *x) {" %
1361 property_entry.getter_cname)
1362 code.putln(
1363 "return %s(o);" %
1364 get_entry.func_cname)
1365 code.putln(
1366 "}")
1368 def generate_property_set_function(self, property_entry, code):
1369 property_scope = property_entry.scope
1370 property_entry.setter_cname = property_scope.parent_scope.mangle(
1371 Naming.prop_set_prefix, property_entry.name)
1372 set_entry = property_scope.lookup_here("__set__")
1373 del_entry = property_scope.lookup_here("__del__")
1374 code.putln("")
1375 code.putln(
1376 "static int %s(PyObject *o, PyObject *v, void *x) {" %
1377 property_entry.setter_cname)
1378 code.putln(
1379 "if (v) {")
1380 if set_entry:
1381 code.putln(
1382 "return %s(o, v);" %
1383 set_entry.func_cname)
1384 else:
1385 code.putln(
1386 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1387 code.putln(
1388 "return -1;")
1389 code.putln(
1390 "}")
1391 code.putln(
1392 "else {")
1393 if del_entry:
1394 code.putln(
1395 "return %s(o);" %
1396 del_entry.func_cname)
1397 else:
1398 code.putln(
1399 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1400 code.putln(
1401 "return -1;")
1402 code.putln(
1403 "}")
1404 code.putln(
1405 "}")
1407 def generate_typeobj_definition(self, modname, entry, code):
1408 type = entry.type
1409 scope = type.scope
1410 for suite in TypeSlots.substructures:
1411 suite.generate_substructure(scope, code)
1412 code.putln("")
1413 if entry.visibility == 'public':
1414 header = "DL_EXPORT(PyTypeObject) %s = {"
1415 else:
1416 #header = "statichere PyTypeObject %s = {"
1417 header = "PyTypeObject %s = {"
1418 #code.putln(header % scope.parent_type.typeobj_cname)
1419 code.putln(header % type.typeobj_cname)
1420 code.putln(
1421 "PyVarObject_HEAD_INIT(0, 0)")
1422 code.putln(
1423 '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1424 self.full_module_name, scope.class_name))
1425 if type.typedef_flag:
1426 objstruct = type.objstruct_cname
1427 else:
1428 #objstruct = "struct %s" % scope.parent_type.objstruct_cname
1429 objstruct = "struct %s" % type.objstruct_cname
1430 code.putln(
1431 "sizeof(%s), /*tp_basicsize*/" %
1432 objstruct)
1433 code.putln(
1434 "0, /*tp_itemsize*/")
1435 for slot in TypeSlots.slot_table:
1436 slot.generate(scope, code)
1437 code.putln(
1438 "};")
1440 def generate_method_table(self, env, code):
1441 code.putln("")
1442 code.putln(
1443 "static struct PyMethodDef %s[] = {" %
1444 env.method_table_cname)
1445 for entry in env.pyfunc_entries:
1446 code.put_pymethoddef(entry, ",")
1447 code.putln(
1448 "{0, 0, 0, 0}")
1449 code.putln(
1450 "};")
1452 def generate_member_table(self, env, code):
1453 #print "ModuleNode.generate_member_table: scope =", env ###
1454 if env.public_attr_entries:
1455 code.putln("")
1456 code.putln(
1457 "static struct PyMemberDef %s[] = {" %
1458 env.member_table_cname)
1459 type = env.parent_type
1460 if type.typedef_flag:
1461 objstruct = type.objstruct_cname
1462 else:
1463 objstruct = "struct %s" % type.objstruct_cname
1464 for entry in env.public_attr_entries:
1465 type_code = entry.type.pymemberdef_typecode
1466 if entry.visibility == 'readonly':
1467 flags = "READONLY"
1468 else:
1469 flags = "0"
1470 code.putln('{(char *)"%s", %s, %s, %s, 0},' % (
1471 entry.name,
1472 type_code,
1473 "offsetof(%s, %s)" % (objstruct, entry.cname),
1474 flags))
1475 code.putln(
1476 "{0, 0, 0, 0, 0}")
1477 code.putln(
1478 "};")
1480 def generate_getset_table(self, env, code):
1481 if env.property_entries:
1482 code.putln("")
1483 code.putln(
1484 "static struct PyGetSetDef %s[] = {" %
1485 env.getset_table_cname)
1486 for entry in env.property_entries:
1487 if entry.doc:
1488 doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
1489 else:
1490 doc_code = "0"
1491 code.putln(
1492 '{(char *)"%s", %s, %s, %s, 0},' % (
1493 entry.name,
1494 entry.getter_cname or "0",
1495 entry.setter_cname or "0",
1496 doc_code))
1497 code.putln(
1498 "{0, 0, 0, 0, 0}")
1499 code.putln(
1500 "};")
1502 def generate_filename_init_prototype(self, code):
1503 code.putln("");
1504 code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1506 def generate_import_star(self, env, code):
1507 code.putln()
1508 code.putln("char* %s_type_names[] = {" % Naming.import_star)
1509 for name, entry in env.entries.items():
1510 if entry.is_type:
1511 code.putln('"%s",' % name)
1512 code.putln("0")
1513 code.putln("};")
1514 code.putln()
1515 code.enter_cfunc_scope() # as we need labels
1516 code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
1517 code.putln("char** type_name = %s_type_names;" % Naming.import_star)
1518 code.putln("while (*type_name) {")
1519 code.putln("if (__Pyx_StrEq(name, *type_name)) {")
1520 code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
1521 code.putln('goto bad;')
1522 code.putln("}")
1523 code.putln("type_name++;")
1524 code.putln("}")
1525 old_error_label = code.new_error_label()
1526 code.putln("if (0);") # so the first one can be "else if"
1527 for name, entry in env.entries.items():
1528 if entry.is_cglobal and entry.used:
1529 code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
1530 if entry.type.is_pyobject:
1531 if entry.type.is_extension_type or entry.type.is_builtin_type:
1532 code.putln("if (!(%s)) %s;" % (
1533 entry.type.type_test_code("o"),
1534 code.error_goto(entry.pos)))
1535 code.put_var_decref(entry)
1536 code.putln("%s = %s;" % (
1537 entry.cname,
1538 PyrexTypes.typecast(entry.type, py_object_type, "o")))
1539 elif entry.type.from_py_function:
1540 rhs = "%s(o)" % entry.type.from_py_function
1541 if entry.type.is_enum:
1542 rhs = typecast(entry.type, c_long_type, rhs)
1543 code.putln("%s = %s; if (%s) %s;" % (
1544 entry.cname,
1545 rhs,
1546 entry.type.error_condition(entry.cname),
1547 code.error_goto(entry.pos)))
1548 code.putln("Py_DECREF(o);")
1549 else:
1550 code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
1551 code.putln(code.error_goto(entry.pos))
1552 code.putln("}")
1553 code.putln("else {")
1554 code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
1555 code.putln("}")
1556 code.putln("return 0;")
1557 code.put_label(code.error_label)
1558 # This helps locate the offending name.
1559 code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
1560 code.error_label = old_error_label
1561 code.putln("bad:")
1562 code.putln("Py_DECREF(o);")
1563 code.putln("return -1;")
1564 code.putln("}")
1565 code.putln(import_star_utility_code)
1566 code.exit_cfunc_scope() # done with labels
1568 def generate_module_init_func(self, imported_modules, env, code):
1569 # Insert code stream of __Pyx_InitGlobals()
1570 code.globalstate.insert_initcode_into(code)
1572 code.enter_cfunc_scope()
1573 code.putln("")
1574 header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
1575 header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
1576 code.putln("#if PY_MAJOR_VERSION < 3")
1577 code.putln("%s; /*proto*/" % header2)
1578 code.putln(header2)
1579 code.putln("#else")
1580 code.putln("%s; /*proto*/" % header3)
1581 code.putln(header3)
1582 code.putln("#endif")
1583 code.putln("{")
1584 tempdecl_code = code.insertion_point()
1586 code.putln("#ifdef CYTHON_REFNANNY")
1587 code.putln("void* __pyx_refchk = NULL;")
1588 code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");")
1589 code.putln("if (!__Pyx_Refnanny) {")
1590 code.putln(" PyErr_Clear();")
1591 code.putln(" __Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"Cython.Runtime.refnanny\");")
1592 code.putln(" if (!__Pyx_Refnanny)")
1593 code.putln(" Py_FatalError(\"failed to import refnanny module\");")
1594 code.putln("}")
1595 code.putln("__pyx_refchk = __Pyx_Refnanny->NewContext(\"%s\", __LINE__, __FILE__);"% header3)
1596 code.putln("#endif")
1598 code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1600 code.putln("/*--- Library function declarations ---*/")
1601 env.generate_library_function_declarations(code)
1602 self.generate_filename_init_call(code)
1604 code.putln("/*--- Initialize various global constants etc. ---*/")
1605 code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
1607 code.putln("/*--- Module creation code ---*/")
1608 self.generate_module_creation_code(env, code)
1610 if Options.cache_builtins:
1611 code.putln("/*--- Builtin init code ---*/")
1612 code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()",
1613 self.pos))
1615 code.putln("%s = 0;" % Naming.skip_dispatch_cname);
1617 code.putln("/*--- Global init code ---*/")
1618 self.generate_global_init_code(env, code)
1620 code.putln("/*--- Function export code ---*/")
1621 self.generate_c_function_export_code(env, code)
1623 code.putln("/*--- Type init code ---*/")
1624 self.generate_type_init_code(env, code)
1626 code.putln("/*--- Type import code ---*/")
1627 for module in imported_modules:
1628 self.generate_type_import_code_for_module(module, env, code)
1630 code.putln("/*--- Function import code ---*/")
1631 for module in imported_modules:
1632 self.generate_c_function_import_code_for_module(module, env, code)
1634 code.putln("/*--- Execution code ---*/")
1635 code.mark_pos(None)
1637 self.body.generate_execution_code(code)
1639 if Options.generate_cleanup_code:
1640 # this should be replaced by the module's tp_clear in Py3
1641 env.use_utility_code(import_module_utility_code)
1642 code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1644 code.put_goto(code.return_label)
1645 code.put_label(code.error_label)
1646 code.put_var_xdecrefs(env.temp_entries)
1647 code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name)
1648 env.use_utility_code(Nodes.traceback_utility_code)
1649 code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
1650 code.put_label(code.return_label)
1652 code.put_finish_refcount_context()
1654 code.putln("#if PY_MAJOR_VERSION < 3")
1655 code.putln("return;")
1656 code.putln("#else")
1657 code.putln("return %s;" % env.module_cname)
1658 code.putln("#endif")
1659 code.putln('}')
1661 tempdecl_code.put_var_declarations(env.temp_entries)
1662 tempdecl_code.put_temp_declarations(code.funcstate)
1664 code.exit_cfunc_scope()
1666 def generate_module_cleanup_func(self, env, code):
1667 if not Options.generate_cleanup_code:
1668 return
1669 env.use_utility_code(register_cleanup_utility_code)
1670 # Insert code stream of __Pyx_CleanupGlobals()
1671 code.globalstate.insert_cleanupcode_into(code)
1672 code.putln()
1673 code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
1674 if Options.generate_cleanup_code >= 2:
1675 code.putln("/*--- Global cleanup code ---*/")
1676 rev_entries = list(env.var_entries)
1677 rev_entries.reverse()
1678 for entry in rev_entries:
1679 if entry.visibility != 'extern':
1680 if entry.type.is_pyobject and entry.used:
1681 code.putln("Py_DECREF(%s); %s = 0;" % (
1682 code.entry_as_pyobject(entry), entry.cname))
1683 code.putln("__Pyx_CleanupGlobals();")
1684 if Options.generate_cleanup_code >= 3:
1685 code.putln("/*--- Type import cleanup code ---*/")
1686 for type, _ in env.types_imported.items():
1687 code.putln("Py_DECREF((PyObject *)%s);" % type.typeptr_cname)
1688 if Options.cache_builtins:
1689 code.putln("/*--- Builtin cleanup code ---*/")
1690 for entry in env.cached_builtins:
1691 code.put_decref_clear(entry.cname,
1692 PyrexTypes.py_object_type,
1693 nanny=False)
1694 code.putln("/*--- Intern cleanup code ---*/")
1695 code.put_decref_clear(Naming.empty_tuple,
1696 PyrexTypes.py_object_type,
1697 nanny=False)
1698 for entry in env.pynum_entries:
1699 code.put_decref_clear(entry.cname,
1700 PyrexTypes.py_object_type,
1701 nanny=False)
1702 for entry in env.all_pystring_entries:
1703 if entry.is_interned:
1704 code.put_decref_clear(entry.pystring_cname,
1705 PyrexTypes.py_object_type,
1706 nanny=False)
1707 for entry in env.default_entries:
1708 if entry.type.is_pyobject and entry.used:
1709 code.putln("Py_DECREF(%s); %s = 0;" % (
1710 code.entry_as_pyobject(entry), entry.cname))
1711 code.putln("Py_INCREF(Py_None); return Py_None;")
1712 code.putln('}')
1714 def generate_filename_init_call(self, code):
1715 code.putln("%s();" % Naming.fileinit_cname)
1717 def generate_pymoduledef_struct(self, env, code):
1718 if env.doc:
1719 doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
1720 else:
1721 doc = "0"
1722 code.putln("")
1723 code.putln("#if PY_MAJOR_VERSION >= 3")
1724 code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
1725 code.putln(" PyModuleDef_HEAD_INIT,")
1726 code.putln(' __Pyx_NAMESTR("%s"),' % env.module_name)
1727 code.putln(" %s, /* m_doc */" % doc)
1728 code.putln(" -1, /* m_size */")
1729 code.putln(" %s /* m_methods */," % env.method_table_cname)
1730 code.putln(" NULL, /* m_reload */")
1731 code.putln(" NULL, /* m_traverse */")
1732 code.putln(" NULL, /* m_clear */")
1733 code.putln(" NULL /* m_free */")
1734 code.putln("};")
1735 code.putln("#endif")
1737 def generate_module_creation_code(self, env, code):
1738 # Generate code to create the module object and
1739 # install the builtins.
1740 if env.doc:
1741 doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
1742 else:
1743 doc = "0"
1744 code.putln("#if PY_MAJOR_VERSION < 3")
1745 code.putln(
1746 '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % (
1747 env.module_cname,
1748 env.module_name,
1749 env.method_table_cname,
1750 doc))
1751 code.putln("#else")
1752 code.putln(
1753 "%s = PyModule_Create(&%s);" % (
1754 env.module_cname,
1755 Naming.pymoduledef_cname))
1756 code.putln("#endif")
1757 code.putln(
1758 "if (!%s) %s;" % (
1759 env.module_cname,
1760 code.error_goto(self.pos)));
1761 code.putln("#if PY_MAJOR_VERSION < 3")
1762 code.putln(
1763 "Py_INCREF(%s);" %
1764 env.module_cname)
1765 code.putln("#endif")
1766 code.putln(
1767 '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' %
1768 Naming.builtins_cname)
1769 code.putln(
1770 "if (!%s) %s;" % (
1771 Naming.builtins_cname,
1772 code.error_goto(self.pos)));
1773 code.putln(
1774 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1775 env.module_cname,
1776 Naming.builtins_cname,
1777 code.error_goto(self.pos)))
1778 if Options.pre_import is not None:
1779 code.putln(
1780 '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % (
1781 Naming.preimport_cname,
1782 Options.pre_import))
1783 code.putln(
1784 "if (!%s) %s;" % (
1785 Naming.preimport_cname,
1786 code.error_goto(self.pos)));
1788 def generate_global_init_code(self, env, code):
1789 # Generate code to initialise global PyObject *
1790 # variables to None.
1791 for entry in env.var_entries:
1792 if entry.visibility != 'extern':
1793 if entry.type.is_pyobject and entry.used:
1794 code.put_init_var_to_py_none(entry, nanny=False)
1796 def generate_c_function_export_code(self, env, code):
1797 # Generate code to create PyCFunction wrappers for exported C functions.
1798 for entry in env.cfunc_entries:
1799 if entry.api or entry.defined_in_pxd:
1800 env.use_utility_code(function_export_utility_code)
1801 signature = entry.type.signature_string()
1802 code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
1803 entry.name,
1804 entry.cname,
1805 signature,
1806 code.error_goto(self.pos)))
1808 def generate_type_import_code_for_module(self, module, env, code):
1809 # Generate type import code for all exported extension types in
1810 # an imported module.
1811 #if module.c_class_entries:
1812 for entry in module.c_class_entries:
1813 if entry.defined_in_pxd:
1814 self.generate_type_import_code(env, entry.type, entry.pos, code)
1816 def generate_c_function_import_code_for_module(self, module, env, code):
1817 # Generate import code for all exported C functions in a cimported module.
1818 entries = []
1819 for entry in module.cfunc_entries:
1820 if entry.defined_in_pxd:
1821 entries.append(entry)
1822 if entries:
1823 env.use_utility_code(import_module_utility_code)
1824 env.use_utility_code(function_import_utility_code)
1825 temp = self.module_temp_cname
1826 code.putln(
1827 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
1828 temp,
1829 module.qualified_name,
1830 temp,
1831 code.error_goto(self.pos)))
1832 for entry in entries:
1833 code.putln(
1834 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
1835 temp,
1836 entry.name,
1837 entry.cname,
1838 entry.type.signature_string(),
1839 code.error_goto(self.pos)))
1840 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
1842 def generate_type_init_code(self, env, code):
1843 # Generate type import code for extern extension types
1844 # and type ready code for non-extern ones.
1845 for entry in env.c_class_entries:
1846 if entry.visibility == 'extern':
1847 self.generate_type_import_code(env, entry.type, entry.pos, code)
1848 else:
1849 self.generate_base_type_import_code(env, entry, code)
1850 self.generate_exttype_vtable_init_code(entry, code)
1851 self.generate_type_ready_code(env, entry, code)
1852 self.generate_typeptr_assignment_code(entry, code)
1854 def generate_base_type_import_code(self, env, entry, code):
1855 base_type = entry.type.base_type
1856 if base_type and base_type.module_name != env.qualified_name:
1857 self.generate_type_import_code(env, base_type, self.pos, code)
1859 def use_type_import_utility_code(self, env):
1860 env.use_utility_code(type_import_utility_code)
1861 env.use_utility_code(import_module_utility_code)
1863 def generate_type_import_code(self, env, type, pos, code):
1864 # If not already done, generate code to import the typeobject of an
1865 # extension type defined in another module, and extract its C method
1866 # table pointer if any.
1867 if type in env.types_imported:
1868 return
1869 if type.typedef_flag:
1870 objstruct = type.objstruct_cname
1871 else:
1872 objstruct = "struct %s" % type.objstruct_cname
1873 self.generate_type_import_call(type, code,
1874 code.error_goto_if_null(type.typeptr_cname, pos))
1875 self.use_type_import_utility_code(env)
1876 if type.vtabptr_cname:
1877 code.putln(
1878 "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1879 type.typeptr_cname,
1880 type.vtabptr_cname,
1881 code.error_goto(pos)))
1882 env.use_utility_code(Nodes.get_vtable_utility_code)
1883 env.types_imported[type] = 1
1885 py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}
1887 def generate_type_import_call(self, type, code, error_code):
1888 if type.typedef_flag:
1889 objstruct = type.objstruct_cname
1890 else:
1891 objstruct = "struct %s" % type.objstruct_cname
1892 module_name = type.module_name
1893 if module_name not in ('__builtin__', 'builtins'):
1894 module_name = '"%s"' % module_name
1895 else:
1896 module_name = '__Pyx_BUILTIN_MODULE_NAME'
1897 if type.name in self.py3_type_name_map:
1898 code.putln("#if PY_MAJOR_VERSION >= 3")
1899 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1900 type.typeptr_cname,
1901 module_name,
1902 self.py3_type_name_map[type.name],
1903 objstruct,
1904 error_code))
1905 code.putln("#else")
1906 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1907 type.typeptr_cname,
1908 module_name,
1909 type.name,
1910 objstruct,
1911 error_code))
1912 if type.name in self.py3_type_name_map:
1913 code.putln("#endif")
1915 def generate_type_ready_code(self, env, entry, code):
1916 # Generate a call to PyType_Ready for an extension
1917 # type defined in this module.
1918 type = entry.type
1919 typeobj_cname = type.typeobj_cname
1920 scope = type.scope
1921 if scope: # could be None if there was an error
1922 if entry.visibility != 'extern':
1923 for slot in TypeSlots.slot_table:
1924 slot.generate_dynamic_init_code(scope, code)
1925 code.putln(
1926 "if (PyType_Ready(&%s) < 0) %s" % (
1927 typeobj_cname,
1928 code.error_goto(entry.pos)))
1929 if type.vtable_cname:
1930 code.putln(
1931 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
1932 typeobj_cname,
1933 type.vtabptr_cname,
1934 code.error_goto(entry.pos)))
1935 env.use_utility_code(Nodes.set_vtable_utility_code)
1936 code.putln(
1937 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
1938 Naming.module_cname,
1939 scope.class_name,
1940 typeobj_cname,
1941 code.error_goto(entry.pos)))
1942 weakref_entry = scope.lookup_here("__weakref__")
1943 if weakref_entry:
1944 if weakref_entry.type is py_object_type:
1945 tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
1946 code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
1947 tp_weaklistoffset,
1948 tp_weaklistoffset,
1949 type.objstruct_cname,
1950 weakref_entry.cname))
1951 else:
1952 error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
1954 def generate_exttype_vtable_init_code(self, entry, code):
1955 # Generate code to initialise the C method table of an
1956 # extension type.
1957 type = entry.type
1958 if type.vtable_cname:
1959 code.putln(
1960 "%s = &%s;" % (
1961 type.vtabptr_cname,
1962 type.vtable_cname))
1963 if type.base_type and type.base_type.vtabptr_cname:
1964 code.putln(
1965 "%s.%s = *%s;" % (
1966 type.vtable_cname,
1967 Naming.obj_base_cname,
1968 type.base_type.vtabptr_cname))
1970 c_method_entries = [
1971 entry for entry in type.scope.cfunc_entries
1972 if entry.func_cname ]
1973 if c_method_entries:
1974 code.putln('#if PY_MAJOR_VERSION >= 3')
1975 for meth_entry in c_method_entries:
1976 cast = meth_entry.type.signature_cast_string()
1977 code.putln(
1978 "%s.%s = %s%s;" % (
1979 type.vtable_cname,
1980 meth_entry.cname,
1981 cast,
1982 meth_entry.func_cname))
1983 code.putln('#else')
1984 for meth_entry in c_method_entries:
1985 code.putln(
1986 "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
1987 type.vtable_cname,
1988 meth_entry.cname,
1989 meth_entry.func_cname))
1990 code.putln('#endif')
1992 def generate_typeptr_assignment_code(self, entry, code):
1993 # Generate code to initialise the typeptr of an extension
1994 # type defined in this module to point to its type object.
1995 type = entry.type
1996 if type.typeobj_cname:
1997 code.putln(
1998 "%s = &%s;" % (
1999 type.typeptr_cname, type.typeobj_cname))
2001 def generate_utility_functions(self, env, code, h_code):
2002 for codetup, name in env.utility_code_list:
2003 code.globalstate.use_utility_code(codetup, name)
2005 code.globalstate.put_utility_code_protos(h_code)
2006 code.putln("")
2007 code.putln("/* Runtime support code */")
2008 code.putln("")
2009 code.putln("static void %s(void) {" % Naming.fileinit_cname)
2010 code.putln("%s = %s;" %
2011 (Naming.filetable_cname, Naming.filenames_cname))
2012 code.putln("}")
2013 code.globalstate.put_utility_code_defs(code)
2014 code.put(PyrexTypes.type_conversion_functions)
2015 code.putln("")
2017 #------------------------------------------------------------------------------------
2019 # Runtime support code
2021 #------------------------------------------------------------------------------------
2023 builtin_module_name_utility_code = UtilityCode(
2024 proto = """\
2025 #if PY_MAJOR_VERSION < 3
2026 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
2027 #else
2028 #define __Pyx_BUILTIN_MODULE_NAME "builtins"
2029 #endif
2030 """)
2032 #------------------------------------------------------------------------------------
2034 streq_utility_code = UtilityCode(
2035 proto = """
2036 static INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2037 """,
2038 impl = """
2039 static INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2040 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2041 return *s1 == *s2;
2043 """)
2045 #------------------------------------------------------------------------------------
2047 import_module_utility_code = UtilityCode(
2048 proto = """
2049 static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
2050 """,
2051 impl = """
2052 #ifndef __PYX_HAVE_RT_ImportModule
2053 #define __PYX_HAVE_RT_ImportModule
2054 static PyObject *__Pyx_ImportModule(const char *name) {
2055 PyObject *py_name = 0;
2056 PyObject *py_module = 0;
2058 #if PY_MAJOR_VERSION < 3
2059 py_name = PyString_FromString(name);
2060 #else
2061 py_name = PyUnicode_FromString(name);
2062 #endif
2063 if (!py_name)
2064 goto bad;
2065 py_module = PyImport_Import(py_name);
2066 Py_DECREF(py_name);
2067 return py_module;
2068 bad:
2069 Py_XDECREF(py_name);
2070 return 0;
2072 #endif
2073 """)
2075 #------------------------------------------------------------------------------------
2077 type_import_utility_code = UtilityCode(
2078 proto = """
2079 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/
2080 """,
2081 impl = """
2082 #ifndef __PYX_HAVE_RT_ImportType
2083 #define __PYX_HAVE_RT_ImportType
2084 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
2085 long size)
2087 PyObject *py_module = 0;
2088 PyObject *result = 0;
2089 PyObject *py_name = 0;
2091 py_module = __Pyx_ImportModule(module_name);
2092 if (!py_module)
2093 goto bad;
2094 #if PY_MAJOR_VERSION < 3
2095 py_name = PyString_FromString(class_name);
2096 #else
2097 py_name = PyUnicode_FromString(class_name);
2098 #endif
2099 if (!py_name)
2100 goto bad;
2101 result = PyObject_GetAttr(py_module, py_name);
2102 Py_DECREF(py_name);
2103 py_name = 0;
2104 Py_DECREF(py_module);
2105 py_module = 0;
2106 if (!result)
2107 goto bad;
2108 if (!PyType_Check(result)) {
2109 PyErr_Format(PyExc_TypeError,
2110 "%s.%s is not a type object",
2111 module_name, class_name);
2112 goto bad;
2114 if (((PyTypeObject *)result)->tp_basicsize != size) {
2115 PyErr_Format(PyExc_ValueError,
2116 "%s.%s does not appear to be the correct type object",
2117 module_name, class_name);
2118 goto bad;
2120 return (PyTypeObject *)result;
2121 bad:
2122 Py_XDECREF(py_module);
2123 Py_XDECREF(result);
2124 return 0;
2126 #endif
2127 """)
2129 #------------------------------------------------------------------------------------
2131 function_export_utility_code = UtilityCode(
2132 proto = """
2133 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
2134 """,
2135 impl = r"""
2136 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) {
2137 #if PY_VERSION_HEX < 0x02050000
2138 char *api = (char *)"%(API)s";
2139 #else
2140 const char *api = "%(API)s";
2141 #endif
2142 PyObject *d = 0;
2143 PyObject *cobj = 0;
2144 union {
2145 void (*fp)(void);
2146 void *p;
2147 } tmp;
2150 d = PyObject_GetAttrString(%(MODULE)s, api);
2151 if (!d) {
2152 PyErr_Clear();
2153 d = PyDict_New();
2154 if (!d)
2155 goto bad;
2156 Py_INCREF(d);
2157 if (PyModule_AddObject(%(MODULE)s, api, d) < 0)
2158 goto bad;
2160 tmp.fp = f;
2161 cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
2162 if (!cobj)
2163 goto bad;
2164 if (PyDict_SetItemString(d, name, cobj) < 0)
2165 goto bad;
2166 Py_DECREF(cobj);
2167 Py_DECREF(d);
2168 return 0;
2169 bad:
2170 Py_XDECREF(cobj);
2171 Py_XDECREF(d);
2172 return -1;
2174 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
2177 #------------------------------------------------------------------------------------
2179 function_import_utility_code = UtilityCode(
2180 proto = """
2181 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
2182 """,
2183 impl = """
2184 #ifndef __PYX_HAVE_RT_ImportFunction
2185 #define __PYX_HAVE_RT_ImportFunction
2186 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
2187 #if PY_VERSION_HEX < 0x02050000
2188 char *api = (char *)"%(API)s";
2189 #else
2190 const char *api = "%(API)s";
2191 #endif
2192 PyObject *d = 0;
2193 PyObject *cobj = 0;
2194 const char *desc;
2195 const char *s1, *s2;
2196 union {
2197 void (*fp)(void);
2198 void *p;
2199 } tmp;
2201 d = PyObject_GetAttrString(module, api);
2202 if (!d)
2203 goto bad;
2204 cobj = PyDict_GetItemString(d, funcname);
2205 if (!cobj) {
2206 PyErr_Format(PyExc_ImportError,
2207 "%%s does not export expected C function %%s",
2208 PyModule_GetName(module), funcname);
2209 goto bad;
2211 desc = (const char *)PyCObject_GetDesc(cobj);
2212 if (!desc)
2213 goto bad;
2214 s1 = desc; s2 = sig;
2215 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2216 if (*s1 != *s2) {
2217 PyErr_Format(PyExc_TypeError,
2218 "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2219 PyModule_GetName(module), funcname, sig, desc);
2220 goto bad;
2222 tmp.p = PyCObject_AsVoidPtr(cobj);
2223 *f = tmp.fp;
2224 Py_DECREF(d);
2225 return 0;
2226 bad:
2227 Py_XDECREF(d);
2228 return -1;
2230 #endif
2231 """ % dict(API = Naming.api_name)
2234 register_cleanup_utility_code = UtilityCode(
2235 proto = """
2236 static int __Pyx_RegisterCleanup(void); /*proto*/
2237 static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
2238 static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
2239 """,
2240 impl = """
2241 static int __Pyx_RegisterCleanup(void) {
2242 /* Don't use Py_AtExit because that has a 32-call limit
2243 * and is called after python finalization.
2244 */
2246 PyObject *cleanup_func = 0;
2247 PyObject *atexit = 0;
2248 PyObject *reg = 0;
2249 PyObject *args = 0;
2250 PyObject *res = 0;
2251 int ret = -1;
2253 cleanup_func = PyCFunction_New(&cleanup_def, 0);
2254 args = PyTuple_New(1);
2255 if (!cleanup_func || !args)
2256 goto bad;
2257 PyTuple_SET_ITEM(args, 0, cleanup_func);
2258 cleanup_func = 0;
2260 atexit = __Pyx_ImportModule("atexit");
2261 if (!atexit)
2262 goto bad;
2263 reg = __Pyx_GetAttrString(atexit, "register");
2264 if (!reg)
2265 goto bad;
2266 res = PyObject_CallObject(reg, args);
2267 if (!res)
2268 goto bad;
2269 ret = 0;
2270 bad:
2271 Py_XDECREF(cleanup_func);
2272 Py_XDECREF(atexit);
2273 Py_XDECREF(reg);
2274 Py_XDECREF(args);
2275 Py_XDECREF(res);
2276 return ret;
2278 """)
2280 import_star_utility_code = """
2282 /* import_all_from is an unexposed function from ceval.c */
2284 static int
2285 __Pyx_import_all_from(PyObject *locals, PyObject *v)
2287 PyObject *all = __Pyx_GetAttrString(v, "__all__");
2288 PyObject *dict, *name, *value;
2289 int skip_leading_underscores = 0;
2290 int pos, err;
2292 if (all == NULL) {
2293 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2294 return -1; /* Unexpected error */
2295 PyErr_Clear();
2296 dict = __Pyx_GetAttrString(v, "__dict__");
2297 if (dict == NULL) {
2298 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2299 return -1;
2300 PyErr_SetString(PyExc_ImportError,
2301 "from-import-* object has no __dict__ and no __all__");
2302 return -1;
2304 all = PyMapping_Keys(dict);
2305 Py_DECREF(dict);
2306 if (all == NULL)
2307 return -1;
2308 skip_leading_underscores = 1;
2311 for (pos = 0, err = 0; ; pos++) {
2312 name = PySequence_GetItem(all, pos);
2313 if (name == NULL) {
2314 if (!PyErr_ExceptionMatches(PyExc_IndexError))
2315 err = -1;
2316 else
2317 PyErr_Clear();
2318 break;
2320 if (skip_leading_underscores &&
2321 #if PY_MAJOR_VERSION < 3
2322 PyString_Check(name) &&
2323 PyString_AS_STRING(name)[0] == '_')
2324 #else
2325 PyUnicode_Check(name) &&
2326 PyUnicode_AS_UNICODE(name)[0] == '_')
2327 #endif
2329 Py_DECREF(name);
2330 continue;
2332 value = PyObject_GetAttr(v, name);
2333 if (value == NULL)
2334 err = -1;
2335 else if (PyDict_CheckExact(locals))
2336 err = PyDict_SetItem(locals, name, value);
2337 else
2338 err = PyObject_SetItem(locals, name, value);
2339 Py_DECREF(name);
2340 Py_XDECREF(value);
2341 if (err != 0)
2342 break;
2344 Py_DECREF(all);
2345 return err;
2349 static int %(IMPORT_STAR)s(PyObject* m) {
2351 int i;
2352 int ret = -1;
2353 char* s;
2354 PyObject *locals = 0;
2355 PyObject *list = 0;
2356 PyObject *name;
2357 PyObject *item;
2359 locals = PyDict_New(); if (!locals) goto bad;
2360 if (__Pyx_import_all_from(locals, m) < 0) goto bad;
2361 list = PyDict_Items(locals); if (!list) goto bad;
2363 for(i=0; i<PyList_GET_SIZE(list); i++) {
2364 name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
2365 item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2366 #if PY_MAJOR_VERSION < 3
2367 s = PyString_AsString(name);
2368 #else
2369 s = PyUnicode_AsString(name);
2370 #endif
2371 if (!s) goto bad;
2372 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2374 ret = 0;
2376 bad:
2377 Py_XDECREF(locals);
2378 Py_XDECREF(list);
2379 return ret;
2381 """ % {'IMPORT_STAR' : Naming.import_star,
2382 'IMPORT_STAR_SET' : Naming.import_star_set }
2384 refcount_utility_code = UtilityCode(proto="""
2385 #ifdef CYTHON_REFNANNY
2386 typedef struct {
2387 void (*INCREF)(void*, PyObject*, int);
2388 void (*DECREF)(void*, PyObject*, int);
2389 void (*GOTREF)(void*, PyObject*, int);
2390 void (*GIVEREF)(void*, PyObject*, int);
2391 void* (*NewContext)(const char*, int, const char*);
2392 void (*FinishContext)(void**);
2393 } __Pyx_RefnannyAPIStruct;
2394 static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
2395 #define __Pyx_ImportRefcountAPI(name) \
2396 (__Pyx_RefnannyAPIStruct *) PyCObject_Import((char *)name, (char *)\"RefnannyAPI\")
2397 #define __Pyx_INCREF(r) __Pyx_Refnanny->INCREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2398 #define __Pyx_DECREF(r) __Pyx_Refnanny->DECREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2399 #define __Pyx_GOTREF(r) __Pyx_Refnanny->GOTREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2400 #define __Pyx_GIVEREF(r) __Pyx_Refnanny->GIVEREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2401 #define __Pyx_XDECREF(r) if((r) == NULL) ; else __Pyx_DECREF(r)
2402 #define __Pyx_SetupRefcountContext(name) \
2403 void* __pyx_refchk = __Pyx_Refnanny->NewContext((name), __LINE__, __FILE__)
2404 #define __Pyx_FinishRefcountContext() \
2405 __Pyx_Refnanny->FinishContext(&__pyx_refchk)
2406 #else
2407 #define __Pyx_INCREF(r) Py_INCREF(r)
2408 #define __Pyx_DECREF(r) Py_DECREF(r)
2409 #define __Pyx_GOTREF(r)
2410 #define __Pyx_GIVEREF(r)
2411 #define __Pyx_XDECREF(r) Py_XDECREF(r)
2412 #define __Pyx_SetupRefcountContext(name)
2413 #define __Pyx_FinishRefcountContext()
2414 #endif /* CYTHON_REFNANNY */
2415 #define __Pyx_XGIVEREF(r) if((r) == NULL) ; else __Pyx_GIVEREF(r)
2416 #define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
2417 """)