Cython has moved to github.

cython-devel

view Cython/Compiler/ModuleNode.py @ 1409:151d8366f329

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