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