Cython has moved to github.

pyrex

view Pyrex/Compiler/ModuleNode.py @ 104:955ec491fcfc

Fix hex compile-time constants
author Gregory Ewing <greg.ewing@canterbury.ac.nz>
date Wed Aug 27 19:05:46 2008 +1200 (3 years ago)
parents c3c8da7982d6
children 94d46b3c5354
line source
1 #
2 # Pyrex - Module parse tree node
3 #
5 import os, time
6 from cStringIO import StringIO
7 from PyrexTypes import CPtrType, py_object_type, typecast
8 from Pyrex.Utils import set
10 # Following is set by Testing.py to suppress filename/date comments
11 # in generated files, so as not to produce spurious changes in test
12 # reference files.
14 testing_mode = False
17 import Code
18 import Naming
19 import Nodes
20 import Options
21 import PyrexTypes
22 import TypeSlots
23 import Version
25 from Errors import error
26 from PyrexTypes import py_object_type
27 from Pyrex.Utils import open_new_file, replace_suffix
29 class ModuleNode(Nodes.Node, Nodes.BlockNode):
30 # doc string or None
31 # body StatListNode
32 #
33 # referenced_modules [ModuleScope]
34 # module_temp_cname string
36 def analyse_declarations(self, env):
37 env.doc = self.doc
38 self.body.analyse_declarations(env)
40 def process_implementation(self, env, options, result):
41 self.analyse_declarations(env)
42 env.check_c_classes()
43 self.body.analyse_expressions(env)
44 env.return_type = PyrexTypes.c_void_type
45 self.referenced_modules = self.find_referenced_modules(env)
46 if self.has_imported_c_functions():
47 self.module_temp_cname = env.allocate_temp_pyobject()
48 env.release_temp(self.module_temp_cname)
49 if options.timestamps or options.recursive:
50 self.generate_dep_file(env, result)
51 self.generate_c_code(env, result)
52 self.generate_h_code(env, options, result)
53 self.generate_api_code(env, result)
55 def has_imported_c_functions(self):
56 for module in self.referenced_modules:
57 for entry in module.cfunc_entries:
58 if entry.defined_in_pxd:
59 return 1
60 return 0
62 def generate_dep_file(self, env, result):
63 modules = self.referenced_modules
64 includes = set(env.pyrex_include_files)
65 for module in modules:
66 for include in module.pyrex_include_files:
67 includes.add(include)
68 if len(modules) > 1 or includes:
69 include_list = list(includes)
70 include_list.sort()
71 dep_file = replace_suffix(result.c_file, ".dep")
72 f = open(dep_file, "w")
73 try:
74 for module in modules[:-1]:
75 f.write("cimport %s\n" % module.qualified_name)
76 for path in include_list:
77 f.write("include %s\n" % path)
78 finally:
79 f.close()
81 def generate_h_code(self, env, options, result):
82 def pub(entries): #, pxd = 0):
83 return [entry for entry in entries
84 if entry.visibility == 'public'] # or pxd and entry.defined_in_pxd]
85 denv = env.definition_scope
86 h_types = pub(denv.type_entries) + pub(env.type_entries)
87 h_vars = pub(denv.var_entries) + pub(env.var_entries)
88 h_funcs = pub(denv.cfunc_entries) + pub(env.cfunc_entries)
89 h_extension_types = pub(denv.c_class_entries) + pub(env.c_class_entries)
90 if h_types or h_vars or h_funcs or h_extension_types:
91 result.h_file = replace_suffix(result.c_file, ".h")
92 h_code = Code.CCodeWriter(open_new_file(result.h_file))
93 if options.generate_pxi:
94 result.i_file = replace_suffix(result.c_file, ".pxi")
95 i_code = Code.PyrexCodeWriter(result.i_file)
96 else:
97 i_code = None
98 guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
99 h_code.put_h_guard(guard)
100 self.generate_extern_c_macro_definition(h_code)
101 self.generate_type_header_code(h_types, h_code)
102 h_code.putln("")
103 h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
104 if h_vars:
105 h_code.putln("")
106 for entry in h_vars:
107 self.generate_public_declaration(entry, h_code, i_code)
108 if h_funcs:
109 h_code.putln("")
110 for entry in h_funcs:
111 self.generate_public_declaration(entry, h_code, i_code)
112 if h_extension_types:
113 h_code.putln("")
114 for entry in h_extension_types:
115 self.generate_cclass_header_code(entry.type, h_code)
116 if i_code:
117 self.generate_cclass_include_code(entry.type, i_code)
118 h_code.putln("")
119 h_code.putln("#endif")
120 h_code.putln("")
121 h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
122 h_code.putln("")
123 h_code.putln("#endif")
125 def generate_public_declaration(self, entry, h_code, i_code):
126 h_code.putln("%s %s;" % (
127 Naming.extern_c_macro,
128 entry.type.declaration_code(
129 entry.cname, dll_linkage = "DL_IMPORT")))
130 if i_code:
131 i_code.putln("cdef extern %s" %
132 entry.type.declaration_code(entry.cname, pyrex = 1))
134 def api_name(self, env):
135 return env.qualified_name.replace(".", "__")
137 def generate_api_code(self, env, result):
138 denv = env.definition_scope
139 api_funcs = []
140 public_extension_types = []
141 has_api_extension_types = 0
142 for entry in denv.cfunc_entries:
143 if entry.visibility <> 'extern':
144 api_funcs.append(entry)
145 for entry in env.cfunc_entries:
146 if entry.api:
147 api_funcs.append(entry)
148 for entry in denv.c_class_entries + env.c_class_entries:
149 if entry.visibility == 'public':
150 public_extension_types.append(entry)
151 if entry.api:
152 has_api_extension_types = 1
153 if api_funcs or has_api_extension_types:
154 result.api_file = replace_suffix(result.c_file, "_api.h")
155 h_code = Code.CCodeWriter(open_new_file(result.api_file))
156 name = self.api_name(env)
157 guard = Naming.api_guard_prefix + name
158 h_code.put_h_guard(guard)
159 h_code.putln('#include "Python.h"')
160 if result.h_file:
161 h_code.putln('#include "%s"' % os.path.basename(result.h_file))
162 for entry in public_extension_types:
163 type = entry.type
164 h_code.putln("")
165 h_code.putln("static PyTypeObject *%s;" % type.typeptr_cname)
166 h_code.putln("#define %s (*%s)" % (
167 type.typeobj_cname, type.typeptr_cname))
168 if api_funcs:
169 h_code.putln("")
170 for entry in api_funcs:
171 type = CPtrType(entry.type)
172 h_code.putln("static %s;" % type.declaration_code(entry.cname))
173 h_code.putln("")
174 h_code.put_h_guard(Naming.api_func_guard + "import_module")
175 h_code.put(import_module_utility_code[1])
176 h_code.putln("")
177 h_code.putln("#endif")
178 if api_funcs:
179 h_code.putln("")
180 h_code.put(function_import_utility_code[1])
181 if public_extension_types:
182 h_code.putln("")
183 h_code.put(type_import_utility_code[1])
184 h_code.putln("")
185 h_code.putln("static int import_%s(void) {" % name)
186 h_code.putln("PyObject *module = 0;")
187 h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
188 h_code.putln("if (!module) goto bad;")
189 for entry in api_funcs:
190 sig = entry.type.signature_string()
191 h_code.putln(
192 'if (__Pyx_ImportFunction(module, "%s", (void**)&%s, "%s") < 0) goto bad;' % (
193 entry.name,
194 entry.cname,
195 sig))
196 h_code.putln("Py_DECREF(module); module = 0;")
197 for entry in public_extension_types:
198 self.generate_type_import_call(entry.type, h_code, "goto bad;")
199 h_code.putln("return 0;")
200 h_code.putln("bad:")
201 h_code.putln("Py_XDECREF(module);")
202 h_code.putln("return -1;")
203 h_code.putln("}")
204 h_code.putln("")
205 h_code.putln("#endif")
207 def generate_cclass_header_code(self, type, h_code):
208 h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
209 Naming.extern_c_macro,
210 type.typeobj_cname))
211 #self.generate_obj_struct_definition(type, h_code)
213 def generate_cclass_include_code(self, type, i_code):
214 i_code.putln("cdef extern class %s.%s:" % (
215 type.module_name, type.name))
216 i_code.indent()
217 var_entries = type.scope.var_entries
218 if var_entries:
219 for entry in var_entries:
220 i_code.putln("cdef %s" %
221 entry.type.declaration_code(entry.cname, pyrex = 1))
222 else:
223 i_code.putln("pass")
224 i_code.dedent()
226 def generate_c_code(self, env, result):
227 code = Code.MainCCodeWriter(StringIO())
228 code.h = Code.CCodeWriter(StringIO())
229 code.init_labels()
231 modules = self.referenced_modules
232 self.generate_module_preamble(env, modules, code.h)
234 code.putln("")
235 code.putln("/* Implementation of %s */" % env.qualified_name)
236 #self.generate_const_definitions(env, code)
237 #self.generate_interned_name_decls(env, code)
238 #self.generate_py_string_decls(env, code)
239 self.body.generate_function_definitions(env, code)
240 #self.generate_interned_name_table(env, code)
241 #self.generate_py_string_table(env, code)
242 self.generate_typeobj_definitions(env, code)
243 self.generate_method_table(env, code)
244 self.generate_filename_init_prototype(code)
245 self.generate_module_init_func(modules[:-1], env, code)
246 self.generate_filename_table(code)
247 self.generate_utility_functions(code)
249 denv = env.definition_scope
250 for module in modules:
251 code.h.putln("")
252 code.h.putln("/* Declarations from %s */" % module.qualified_name)
253 self.generate_declarations_for_module(module, code.h,
254 implementation = module is denv)
256 code.h.putln("")
257 code.h.putln("/* Declarations from implementation of %s */" %
258 env.qualified_name)
259 self.generate_declarations_for_module(env, code.h, implementation = 1)
260 code.global_state.generate_const_declarations(code.h)
261 #self.generate_interned_name_table(code.interned_strings, code.h)
262 #self.generate_py_string_table(code.py_strings, code.h)
263 self.generate_default_value_declarations(env, code.h)
265 f = open_new_file(result.c_file)
266 f.write(code.h.f.getvalue())
267 f.write("\n")
268 f.write(code.f.getvalue())
269 f.close()
270 result.c_file_generated = 1
272 def find_referenced_modules(self, env):
273 # Given the ImplementationScope, find the DefinitionScopes of all
274 # modules cimported, directly or indirectly. Includes this module's
275 # DefinitionScope as the last entry in the list.
276 denv = env.definition_scope
277 module_list = []
278 modules_seen = set()
279 def add_module(module):
280 if module not in modules_seen:
281 modules_seen.add(module)
282 add_modules(module.cimported_modules)
283 module_list.append(module)
284 def add_modules(modules):
285 for module in modules:
286 add_module(module)
287 modules_seen.add(denv)
288 add_modules(denv.cimported_modules)
289 add_modules(env.cimported_modules)
290 module_list.append(denv)
291 #self.print_referenced_modules(module_list) ###
292 return module_list
294 def print_referenced_modules(self, module_list):
295 print "find_referenced_modules: result =",
296 for m in module_list:
297 print m,
298 print
300 def generate_module_preamble(self, env, cimported_modules, code):
301 comment = "Generated by Pyrex"
302 if not testing_mode:
303 comment = "%s %s on %s" % (comment, Version.version, time.asctime())
304 code.putln('/* %s */' % comment)
305 code.putln('')
306 code.putln('#define PY_SSIZE_T_CLEAN')
307 for filename in env.python_include_files:
308 code.putln('#include "%s"' % filename)
309 code.putln("#ifndef PY_LONG_LONG")
310 code.putln(" #define PY_LONG_LONG LONG_LONG")
311 code.putln("#endif")
312 code.putln("#if PY_VERSION_HEX < 0x02050000")
313 code.putln(" typedef int Py_ssize_t;")
314 code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
315 code.putln(" #define PY_SSIZE_T_MIN INT_MIN")
316 code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
317 code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)")
318 code.putln("#endif")
319 code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
320 code.putln(" #ifndef __stdcall")
321 code.putln(" #define __stdcall")
322 code.putln(" #endif")
323 code.putln(" #ifndef __cdecl")
324 code.putln(" #define __cdecl")
325 code.putln(" #endif")
326 code.putln("#endif")
327 self.generate_extern_c_macro_definition(code)
328 code.putln("#include <math.h>")
329 self.generate_includes(env, cimported_modules, code)
330 code.putln('')
331 code.put(Nodes.utility_function_predeclarations)
332 code.putln('')
333 code.putln('static PyObject *%s;' % env.module_cname)
334 code.putln('static PyObject *%s;' % Naming.builtins_cname)
335 code.putln('static int %s;' % Naming.lineno_cname)
336 code.putln('static char *%s;' % Naming.filename_cname)
337 code.putln('static char **%s;' % Naming.filetable_cname)
338 doc = None
339 doc1 = env.definition_scope.doc
340 doc2 = env.doc
341 if doc1 and doc2:
342 doc = "%s\\n%s" % (doc1, doc2)
343 else:
344 doc = doc1 or doc2
345 if doc:
346 code.putln('')
347 code.putln('static char %s[] = "%s";' % (env.doc_cname, doc))
349 def generate_extern_c_macro_definition(self, code):
350 name = Naming.extern_c_macro
351 code.putln("#ifdef __cplusplus")
352 code.putln('#define %s extern "C"' % name)
353 code.putln("#else")
354 code.putln("#define %s extern" % name)
355 code.putln("#endif")
357 def generate_includes(self, env, cimported_modules, code):
358 includes = env.include_files[:]
359 for module in cimported_modules:
360 for filename in module.include_files:
361 if filename not in includes:
362 includes.append(filename)
363 for filename in includes:
364 code.putln('#include "%s"' % filename)
366 def generate_filename_table(self, code):
367 code.global_state.generate_filename_table(code)
369 def generate_declarations_for_module(self, env, code, implementation):
370 self.generate_type_predeclarations(env, code)
371 self.generate_type_definitions(env, code) #, implementation)
372 self.generate_global_declarations(env, code, implementation)
373 self.generate_cfunction_predeclarations(env, code, implementation)
375 def generate_type_predeclarations(self, env, code):
376 pass
378 def generate_type_header_code(self, type_entries, code):
379 # Generate definitions of structs/unions/enums/typedefs/objstructs.
380 #self.generate_gcc33_hack(env, code) # Is this still needed?
381 #for entry in env.type_entries:
382 for entry in type_entries:
383 if not entry.in_cinclude:
384 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
385 type = entry.type
386 if type.is_typedef: # Must test this first!
387 self.generate_typedef(entry, code)
388 elif type.is_struct_or_union:
389 self.generate_struct_union_definition(entry, code)
390 elif type.is_enum:
391 self.generate_enum_definition(entry, code)
392 elif type.is_extension_type:
393 self.generate_obj_struct_definition(type, code)
395 def generate_type_definitions(self, env, code): #, implementation):
396 #print "generate_type_definitions:", env ###
397 type_entries = env.type_entries
398 self.generate_type_header_code(type_entries, code)
399 for entry in env.c_class_entries:
400 if not entry.in_cinclude:
401 self.generate_typeobject_predeclaration(entry, code)
402 self.generate_exttype_vtable_struct(entry, code)
403 self.generate_exttype_vtabptr_declaration(entry, code)
405 # def generate_gcc33_hack(self, env, code):
406 # # Workaround for spurious warning generation in gcc 3.3
407 # if 0:
408 # code.putln("")
409 # for entry in env.c_class_entries:
410 # type = entry.type
411 # if not type.typedef_flag:
412 # name = type.objstruct_cname
413 # if name.startswith("__pyx_"):
414 # tail = name[6:]
415 # else:
416 # tail = name
417 # code.putln("typedef struct %s __pyx_gcc33_%s;" % (
418 # name, tail))
420 def generate_typedef(self, entry, code):
421 base_type = entry.type.typedef_base_type
422 code.putln("")
423 code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
425 def sue_header_footer(self, type, kind, name):
426 if type.typedef_flag:
427 header = "typedef %s {" % kind
428 footer = "} %s;" % name
429 else:
430 header = "%s %s {" % (kind, name)
431 footer = "};"
432 return header, footer
434 def generate_struct_union_definition(self, entry, code):
435 type = entry.type
436 scope = type.scope
437 if scope:
438 header, footer = \
439 self.sue_header_footer(type, type.kind, type.cname)
440 code.putln("")
441 code.putln(header)
442 var_entries = scope.var_entries
443 if not var_entries and not scope.cfunc_entries:
444 error(entry.pos,
445 "Empty struct or union definition not allowed outside a"
446 " 'cdef extern from' block")
447 for attr in var_entries:
448 code.putln(
449 "%s;" %
450 attr.type.declaration_code(attr.cname))
451 code.putln(footer)
453 def generate_enum_definition(self, entry, code):
454 type = entry.type
455 name = entry.cname or entry.name or ""
456 header, footer = \
457 self.sue_header_footer(type, "enum", name)
458 code.putln("")
459 code.putln(header)
460 enum_values = entry.enum_values
461 if not enum_values:
462 error(entry.pos,
463 "Empty enum definition not allowed outside a"
464 " 'cdef extern from' block")
465 else:
466 last_entry = enum_values[-1]
467 for value_entry in enum_values:
468 if value_entry.value == value_entry.name:
469 value_code = value_entry.cname
470 else:
471 value_code = ("%s = %s" % (
472 value_entry.cname,
473 value_entry.value))
474 if value_entry is not last_entry:
475 value_code += ","
476 code.putln(value_code)
477 code.putln(footer)
479 def generate_typeobject_predeclaration(self, entry, code):
480 code.putln("")
481 name = entry.type.typeobj_cname
482 if name:
483 if entry.visibility == 'extern' and not entry.in_cinclude:
484 code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
485 Naming.extern_c_macro,
486 name))
487 elif entry.visibility == 'public':
488 #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
489 code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
490 Naming.extern_c_macro,
491 name))
493 def generate_exttype_vtable_struct(self, entry, code):
494 # Generate struct declaration for an extension type's vtable.
495 type = entry.type
496 scope = type.scope
497 if type.vtabstruct_cname:
498 code.putln("")
499 code.putln(
500 "struct %s {" %
501 type.vtabstruct_cname)
502 if type.base_type and type.base_type.vtabstruct_cname:
503 code.putln("struct %s %s;" % (
504 type.base_type.vtabstruct_cname,
505 Naming.obj_base_cname))
506 for method_entry in scope.cfunc_entries:
507 if not method_entry.is_inherited:
508 code.putln(
509 "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
510 code.putln(
511 "};")
513 def generate_exttype_vtabptr_declaration(self, entry, code):
514 # Generate declaration of pointer to an extension type's vtable.
515 type = entry.type
516 if type.vtabptr_cname:
517 code.putln("static struct %s *%s;" % (
518 type.vtabstruct_cname,
519 type.vtabptr_cname))
521 def generate_obj_struct_definition(self, type, code):
522 # Generate object struct definition for an
523 # extension type.
524 if not type.scope:
525 return # Forward declared but never defined
526 header, footer = \
527 self.sue_header_footer(type, "struct", type.objstruct_cname)
528 code.putln("")
529 code.putln(header)
530 base_type = type.base_type
531 if base_type:
532 code.putln(
533 "%s%s %s;" % (
534 ("struct ", "")[base_type.typedef_flag],
535 base_type.objstruct_cname,
536 Naming.obj_base_cname))
537 else:
538 code.putln(
539 "PyObject_HEAD")
540 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
541 code.putln(
542 "struct %s *%s;" % (
543 type.vtabstruct_cname,
544 type.vtabslot_cname))
545 for attr in type.scope.var_entries:
546 code.putln(
547 "%s;" %
548 attr.type.declaration_code(attr.cname))
549 code.putln(footer)
551 def generate_global_declarations(self, env, code, implementation):
552 code.putln("")
553 for entry in env.c_class_entries:
554 if implementation or entry.defined_in_pxd:
555 code.putln("static PyTypeObject *%s = 0;" %
556 entry.type.typeptr_cname)
557 #code.putln("/* var_entries */") ###
558 code.put_var_declarations(env.var_entries, static = 1,
559 dll_linkage = "DL_EXPORT", definition = implementation)
561 def generate_default_value_declarations(self, env, code):
562 #code.putln("/* default_entries */") ###
563 code.putln("")
564 code.put_var_declarations(env.default_entries, static = 1)
566 def generate_cfunction_predeclarations(self, env, code, implementation):
567 for entry in env.cfunc_entries:
568 if not entry.in_cinclude:
569 # and (definition or entry.defined_in_pxd or
570 # entry.visibility == 'extern'):
571 if entry.visibility in ('public', 'extern'):
572 dll_linkage = "DL_EXPORT"
573 else:
574 dll_linkage = None
575 type = entry.type
576 if not implementation: #and entry.defined_in_pxd:
577 type = CPtrType(type)
578 header = type.declaration_code(entry.cname,
579 dll_linkage = dll_linkage)
580 if entry.visibility <> 'private':
581 storage_class = "%s " % Naming.extern_c_macro
582 else:
583 storage_class = "static "
584 code.putln("%s%s; /*proto*/" % (
585 storage_class,
586 header))
588 def generate_typeobj_definitions(self, env, code):
589 full_module_name = env.qualified_name
590 denv = env.definition_scope
591 for entry in denv.c_class_entries + env.c_class_entries:
592 #print "generate_typeobj_definitions:", entry.name
593 #print "...visibility =", entry.visibility
594 if entry.visibility <> 'extern':
595 type = entry.type
596 scope = type.scope
597 if scope: # could be None if there was an error
598 self.generate_exttype_vtable(scope, code)
599 self.generate_new_function(scope, code)
600 self.generate_dealloc_function(scope, code)
601 self.generate_traverse_function(scope, code)
602 self.generate_clear_function(scope, code)
603 if scope.defines_any(["__getitem__"]):
604 self.generate_getitem_int_function(scope, code)
605 if scope.defines_any(["__setitem__", "__delitem__"]):
606 self.generate_ass_subscript_function(scope, code)
607 if scope.defines_any(["__setslice__", "__delslice__"]):
608 self.generate_ass_slice_function(scope, code)
609 if scope.defines_any(["__getattr__"]):
610 self.generate_getattro_function(scope, code)
611 if scope.defines_any(["__setattr__", "__delattr__"]):
612 self.generate_setattro_function(scope, code)
613 if scope.defines_any(["__get__"]):
614 self.generate_descr_get_function(scope, code)
615 if scope.defines_any(["__set__", "__delete__"]):
616 self.generate_descr_set_function(scope, code)
617 self.generate_property_accessors(scope, code)
618 self.generate_method_table(scope, code)
619 self.generate_member_table(scope, code)
620 self.generate_getset_table(scope, code)
621 self.generate_typeobj_definition(full_module_name, entry, code)
623 def generate_exttype_vtable(self, scope, code):
624 # Generate the definition of an extension type's vtable.
625 type = scope.parent_type
626 if type.vtable_cname:
627 code.putln("static struct %s %s;" % (
628 type.vtabstruct_cname,
629 type.vtable_cname))
631 def generate_self_cast(self, scope, code):
632 type = scope.parent_type
633 code.putln(
634 "%s = (%s)o;" % (
635 type.declaration_code("p"),
636 type.declaration_code("")))
638 def generate_new_function(self, scope, code):
639 type = scope.parent_type
640 base_type = type.base_type
641 py_attrs = []
642 for entry in scope.var_entries:
643 if entry.type.is_pyobject:
644 py_attrs.append(entry)
645 need_self_cast = type.vtabslot_cname or py_attrs
646 code.putln("")
647 code.putln(
648 "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
649 % scope.mangle_internal("tp_new"))
650 if need_self_cast:
651 code.putln(
652 "%s;"
653 % scope.parent_type.declaration_code("p"))
654 if base_type:
655 code.putln(
656 "PyObject *o = %s->tp_new(t, a, k);" %
657 base_type.typeptr_cname)
658 else:
659 code.putln(
660 "PyObject *o = (*t->tp_alloc)(t, 0);")
661 code.putln(
662 "if (!o) return 0;")
663 if need_self_cast:
664 code.putln(
665 "p = %s;"
666 % type.cast_code("o"))
667 #if need_self_cast:
668 # self.generate_self_cast(scope, code)
669 if type.vtabslot_cname:
670 code.putln("*(struct %s **)&p->%s = %s;" % (
671 type.vtabstruct_cname,
672 type.vtabslot_cname,
673 type.vtabptr_cname))
674 for entry in py_attrs:
675 if entry.name == "__weakref__":
676 code.putln("p->%s = 0;" % entry.cname)
677 else:
678 code.put_init_var_to_py_none(entry, "p->%s")
679 entry = scope.lookup_here("__new__")
680 if entry:
681 code.putln(
682 "if (%s(o, a, k) < 0) {" %
683 entry.func_cname)
684 code.put_decref_clear("o", py_object_type);
685 code.putln(
686 "}")
687 code.putln(
688 "return o;")
689 code.putln(
690 "}")
692 def generate_dealloc_function(self, scope, code):
693 base_type = scope.parent_type.base_type
694 code.putln("")
695 code.putln(
696 "static void %s(PyObject *o) {"
697 % scope.mangle_internal("tp_dealloc"))
698 #py_attrs = []
699 #for entry in scope.var_entries:
700 # if entry.type.is_pyobject and entry.name <> "__weakref__":
701 # py_attrs.append(entry)
702 py_attrs = scope.pyattr_entries
703 if py_attrs:
704 self.generate_self_cast(scope, code)
705 self.generate_usr_dealloc_call(scope, code)
706 if scope.lookup_here("__weakref__"):
707 code.putln("PyObject_ClearWeakRefs(o);")
708 for entry in py_attrs:
709 code.put_xdecref("p->%s" % entry.cname, entry.type)
710 if base_type:
711 code.putln(
712 "%s->tp_dealloc(o);" %
713 base_type.typeptr_cname)
714 else:
715 code.putln(
716 "(*o->ob_type->tp_free)(o);")
717 code.putln(
718 "}")
720 def generate_usr_dealloc_call(self, scope, code):
721 entry = scope.lookup_here("__dealloc__")
722 if entry:
723 code.putln(
724 "{")
725 code.putln(
726 "PyObject *etype, *eval, *etb;")
727 code.putln(
728 "PyErr_Fetch(&etype, &eval, &etb);")
729 code.putln(
730 "++o->ob_refcnt;")
731 code.putln(
732 "%s(o);" %
733 entry.func_cname)
734 code.putln(
735 "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
736 code.putln(
737 "--o->ob_refcnt;")
738 code.putln(
739 "PyErr_Restore(etype, eval, etb);")
740 code.putln(
741 "}")
743 def generate_traverse_function(self, scope, code):
744 py_attrs = scope.pyattr_entries
745 if py_attrs:
746 base_type = scope.parent_type.base_type
747 code.putln("")
748 code.putln(
749 "static int %s(PyObject *o, visitproc v, void *a) {"
750 % scope.mangle_internal("tp_traverse"))
751 code.putln(
752 "int e;")
753 self.generate_self_cast(scope, code)
754 if base_type:
755 code.putln(
756 "traverseproc t;")
757 code.putln(
758 "if ((t = %s->tp_traverse)) {" %
759 base_type.typeptr_cname)
760 code.putln(
761 "e = t(o, v, a); if (e) return e;")
762 code.putln(
763 "}")
764 for entry in py_attrs:
765 var_code = "p->%s" % entry.cname
766 code.putln(
767 "if (%s) {"
768 % var_code)
769 if entry.type.is_extension_type:
770 var_code = "((PyObject*)%s)" % var_code
771 code.putln(
772 "e = (*v)(%s, a); if (e) return e;"
773 % var_code)
774 code.putln(
775 "}")
776 code.putln(
777 "return 0;")
778 code.putln(
779 "}")
781 def generate_clear_function(self, scope, code):
782 py_attrs = scope.pyattr_entries
783 if py_attrs:
784 base_type = scope.parent_type.base_type
785 code.putln("")
786 code.putln(
787 "static int %s(PyObject *o) {"
788 % scope.mangle_internal("tp_clear"))
789 self.generate_self_cast(scope, code)
790 code.putln(
791 "PyObject *t;")
792 if base_type:
793 code.putln(
794 "inquiry c;")
795 code.putln(
796 "if ((c = %s->tp_clear)) {" %
797 base_type.typeptr_cname)
798 code.putln(
799 "c(o);")
800 code.putln(
801 "}")
802 for entry in py_attrs:
803 name = "p->%s" % entry.cname
804 code.putln(
805 "t = %s; " %
806 typecast(py_object_type, entry.type, name))
807 code.put_init_var_to_py_none(entry, "p->%s")
808 #code.put_xdecref(name, entry.type)
809 code.putln(
810 "Py_XDECREF(t);")
811 code.putln(
812 "return 0;")
813 code.putln(
814 "}")
816 def generate_getitem_int_function(self, scope, code):
817 # This function is put into the sq_item slot when
818 # a __getitem__ method is present. It converts its
819 # argument to a Python integer and calls mp_subscript.
820 code.putln(
821 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
822 scope.mangle_internal("sq_item"))
823 code.putln(
824 "PyObject *r;")
825 code.putln(
826 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
827 code.putln(
828 "r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
829 code.putln(
830 "Py_DECREF(x);")
831 code.putln(
832 "return r;")
833 code.putln(
834 "}")
836 def generate_ass_subscript_function(self, scope, code):
837 # Setting and deleting an item are both done through
838 # the ass_subscript method, so we dispatch to user's __setitem__
839 # or __delitem__, or raise an exception.
840 base_type = scope.parent_type.base_type
841 set_entry = scope.lookup_here("__setitem__")
842 del_entry = scope.lookup_here("__delitem__")
843 code.putln("")
844 code.putln(
845 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
846 scope.mangle_internal("mp_ass_subscript"))
847 code.putln(
848 "if (v) {")
849 if set_entry:
850 code.putln(
851 "return %s(o, i, v);" %
852 set_entry.func_cname)
853 else:
854 self.generate_guarded_basetype_call(
855 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
856 code.putln(
857 "PyErr_Format(PyExc_NotImplementedError,")
858 code.putln(
859 ' "Subscript assignment not supported by %s", o->ob_type->tp_name);')
860 code.putln(
861 "return -1;")
862 code.putln(
863 "}")
864 code.putln(
865 "else {")
866 if del_entry:
867 code.putln(
868 "return %s(o, i);" %
869 del_entry.func_cname)
870 else:
871 self.generate_guarded_basetype_call(
872 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
873 code.putln(
874 "PyErr_Format(PyExc_NotImplementedError,")
875 code.putln(
876 ' "Subscript deletion not supported by %s", o->ob_type->tp_name);')
877 code.putln(
878 "return -1;")
879 code.putln(
880 "}")
881 code.putln(
882 "}")
884 def generate_guarded_basetype_call(
885 self, base_type, substructure, slot, args, code):
886 if base_type:
887 base_tpname = base_type.typeptr_cname
888 if substructure:
889 code.putln(
890 "if (%s->%s && %s->%s->%s)" % (
891 base_tpname, substructure, base_tpname, substructure, slot))
892 code.putln(
893 " return %s->%s->%s(%s);" % (
894 base_tpname, substructure, slot, args))
895 else:
896 code.putln(
897 "if (%s->%s)" % (
898 base_tpname, slot))
899 code.putln(
900 " return %s->%s(%s);" % (
901 base_tpname, slot, args))
903 def generate_ass_slice_function(self, scope, code):
904 # Setting and deleting a slice are both done through
905 # the ass_slice method, so we dispatch to user's __setslice__
906 # or __delslice__, or raise an exception.
907 base_type = scope.parent_type.base_type
908 set_entry = scope.lookup_here("__setslice__")
909 del_entry = scope.lookup_here("__delslice__")
910 code.putln("")
911 code.putln(
912 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
913 scope.mangle_internal("sq_ass_slice"))
914 code.putln(
915 "if (v) {")
916 if set_entry:
917 code.putln(
918 "return %s(o, i, j, v);" %
919 set_entry.func_cname)
920 else:
921 self.generate_guarded_basetype_call(
922 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
923 code.putln(
924 "PyErr_Format(PyExc_NotImplementedError,")
925 code.putln(
926 ' "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
927 code.putln(
928 "return -1;")
929 code.putln(
930 "}")
931 code.putln(
932 "else {")
933 if del_entry:
934 code.putln(
935 "return %s(o, i, j);" %
936 del_entry.func_cname)
937 else:
938 self.generate_guarded_basetype_call(
939 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
940 code.putln(
941 "PyErr_Format(PyExc_NotImplementedError,")
942 code.putln(
943 ' "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
944 code.putln(
945 "return -1;")
946 code.putln(
947 "}")
948 code.putln(
949 "}")
951 def generate_getattro_function(self, scope, code):
952 # First try to get the attribute using PyObject_GenericGetAttr.
953 # If that raises an AttributeError, call the user's __getattr__
954 # method.
955 entry = scope.lookup_here("__getattr__")
956 code.putln("")
957 code.putln(
958 "static PyObject *%s(PyObject *o, PyObject *n) {"
959 % scope.mangle_internal("tp_getattro"))
960 code.putln(
961 "PyObject *v = PyObject_GenericGetAttr(o, n);")
962 code.putln(
963 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
964 code.putln(
965 "PyErr_Clear();")
966 code.putln(
967 "v = %s(o, n);" %
968 entry.func_cname)
969 code.putln(
970 "}")
971 code.putln(
972 "return v;")
973 code.putln(
974 "}")
976 def generate_setattro_function(self, scope, code):
977 # Setting and deleting an attribute are both done through
978 # the setattro method, so we dispatch to user's __setattr__
979 # or __delattr__ or fall back on PyObject_GenericSetAttr.
980 base_type = scope.parent_type.base_type
981 set_entry = scope.lookup_here("__setattr__")
982 del_entry = scope.lookup_here("__delattr__")
983 code.putln("")
984 code.putln(
985 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
986 scope.mangle_internal("tp_setattro"))
987 code.putln(
988 "if (v) {")
989 if set_entry:
990 code.putln(
991 "return %s(o, n, v);" %
992 set_entry.func_cname)
993 else:
994 self.generate_guarded_basetype_call(
995 base_type, None, "tp_setattro", "o, n, v", code)
996 code.putln(
997 "return PyObject_GenericSetAttr(o, n, v);")
998 code.putln(
999 "}")
1000 code.putln(
1001 "else {")
1002 if del_entry:
1003 code.putln(
1004 "return %s(o, n);" %
1005 del_entry.func_cname)
1006 else:
1007 self.generate_guarded_basetype_call(
1008 base_type, None, "tp_setattro", "o, n, v", code)
1009 code.putln(
1010 "return PyObject_GenericSetAttr(o, n, 0);")
1011 code.putln(
1012 "}")
1013 code.putln(
1014 "}")
1016 def generate_descr_get_function(self, scope, code):
1017 # The __get__ function of a descriptor object can be
1018 # called with NULL for the second or third arguments
1019 # under some circumstances, so we replace them with
1020 # None in that case.
1021 user_get_entry = scope.lookup_here("__get__")
1022 code.putln("")
1023 code.putln(
1024 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1025 scope.mangle_internal("tp_descr_get"))
1026 code.putln(
1027 "PyObject *r = 0;")
1028 code.putln(
1029 "if (!i) i = Py_None;")
1030 code.putln(
1031 "if (!c) c = Py_None;")
1032 #code.put_incref("i", py_object_type)
1033 #code.put_incref("c", py_object_type)
1034 code.putln(
1035 "r = %s(o, i, c);" %
1036 user_get_entry.func_cname)
1037 #code.put_decref("i", py_object_type)
1038 #code.put_decref("c", py_object_type)
1039 code.putln(
1040 "return r;")
1041 code.putln(
1042 "}")
1044 def generate_descr_set_function(self, scope, code):
1045 # Setting and deleting are both done through the __set__
1046 # method of a descriptor, so we dispatch to user's __set__
1047 # or __delete__ or raise an exception.
1048 base_type = scope.parent_type.base_type
1049 user_set_entry = scope.lookup_here("__set__")
1050 user_del_entry = scope.lookup_here("__delete__")
1051 code.putln("")
1052 code.putln(
1053 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1054 scope.mangle_internal("tp_descr_set"))
1055 code.putln(
1056 "if (v) {")
1057 if user_set_entry:
1058 code.putln(
1059 "return %s(o, i, v);" %
1060 user_set_entry.func_cname)
1061 else:
1062 self.generate_guarded_basetype_call(
1063 base_type, None, "tp_descr_set", "o, i, v", code)
1064 code.putln(
1065 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1066 code.putln(
1067 "return -1;")
1068 code.putln(
1069 "}")
1070 code.putln(
1071 "else {")
1072 if user_del_entry:
1073 code.putln(
1074 "return %s(o, i);" %
1075 user_del_entry.func_cname)
1076 else:
1077 self.generate_guarded_basetype_call(
1078 base_type, None, "tp_descr_set", "o, i, v", code)
1079 code.putln(
1080 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1081 code.putln(
1082 "return -1;")
1083 code.putln(
1084 "}")
1085 code.putln(
1086 "}")
1088 def generate_property_accessors(self, cclass_scope, code):
1089 for entry in cclass_scope.property_entries:
1090 property_scope = entry.scope
1091 if property_scope.defines_any(["__get__"]):
1092 self.generate_property_get_function(entry, code)
1093 if property_scope.defines_any(["__set__", "__del__"]):
1094 self.generate_property_set_function(entry, code)
1096 def generate_property_get_function(self, property_entry, code):
1097 property_scope = property_entry.scope
1098 property_entry.getter_cname = property_scope.parent_scope.mangle(
1099 Naming.prop_get_prefix, property_entry.name)
1100 get_entry = property_scope.lookup_here("__get__")
1101 code.putln("")
1102 code.putln(
1103 "static PyObject *%s(PyObject *o, void *x) {" %
1104 property_entry.getter_cname)
1105 code.putln(
1106 "return %s(o);" %
1107 get_entry.func_cname)
1108 code.putln(
1109 "}")
1111 def generate_property_set_function(self, property_entry, code):
1112 property_scope = property_entry.scope
1113 property_entry.setter_cname = property_scope.parent_scope.mangle(
1114 Naming.prop_set_prefix, property_entry.name)
1115 set_entry = property_scope.lookup_here("__set__")
1116 del_entry = property_scope.lookup_here("__del__")
1117 code.putln("")
1118 code.putln(
1119 "static int %s(PyObject *o, PyObject *v, void *x) {" %
1120 property_entry.setter_cname)
1121 code.putln(
1122 "if (v) {")
1123 if set_entry:
1124 code.putln(
1125 "return %s(o, v);" %
1126 set_entry.func_cname)
1127 else:
1128 code.putln(
1129 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1130 code.putln(
1131 "return -1;")
1132 code.putln(
1133 "}")
1134 code.putln(
1135 "else {")
1136 if del_entry:
1137 code.putln(
1138 "return %s(o);" %
1139 del_entry.func_cname)
1140 else:
1141 code.putln(
1142 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1143 code.putln(
1144 "return -1;")
1145 code.putln(
1146 "}")
1147 code.putln(
1148 "}")
1150 def generate_typeobj_definition(self, modname, entry, code):
1151 type = entry.type
1152 scope = type.scope
1153 for suite in TypeSlots.substructures:
1154 suite.generate_substructure(scope, code)
1155 code.putln("")
1156 if entry.visibility == 'public':
1157 header = "DL_EXPORT(PyTypeObject) %s = {"
1158 else:
1159 header = "PyTypeObject %s = {"
1160 code.putln(header % type.typeobj_cname)
1161 code.putln(
1162 "PyObject_HEAD_INIT(0)")
1163 code.putln(
1164 "0, /*ob_size*/")
1165 code.putln(
1166 '"%s.%s", /*tp_name*/' % (
1167 modname, scope.class_name))
1168 if type.typedef_flag:
1169 objstruct = type.objstruct_cname
1170 else:
1171 #objstruct = "struct %s" % scope.parent_type.objstruct_cname
1172 objstruct = "struct %s" % type.objstruct_cname
1173 code.putln(
1174 "sizeof(%s), /*tp_basicsize*/" %
1175 objstruct)
1176 code.putln(
1177 "0, /*tp_itemsize*/")
1178 for slot in TypeSlots.slot_table:
1179 slot.generate(scope, code)
1180 code.putln(
1181 "};")
1183 def generate_method_table(self, env, code):
1184 code.putln("")
1185 code.putln(
1186 "static struct PyMethodDef %s[] = {" %
1187 env.method_table_cname)
1188 for entry in env.pyfunc_entries:
1189 code.put_pymethoddef(entry, ",")
1190 code.putln(
1191 "{0, 0, 0, 0}")
1192 code.putln(
1193 "};")
1195 def generate_member_table(self, env, code):
1196 #print "ModuleNode.generate_member_table: scope =", env ###
1197 if env.public_attr_entries:
1198 code.putln("")
1199 code.putln(
1200 "static struct PyMemberDef %s[] = {" %
1201 env.member_table_cname)
1202 type = env.parent_type
1203 if type.typedef_flag:
1204 objstruct = type.objstruct_cname
1205 else:
1206 objstruct = "struct %s" % type.objstruct_cname
1207 for entry in env.public_attr_entries:
1208 type_code = entry.type.pymemberdef_typecode
1209 if entry.visibility == 'readonly':
1210 flags = "READONLY"
1211 else:
1212 flags = "0"
1213 code.putln('{"%s", %s, %s, %s, 0},' % (
1214 entry.name,
1215 type_code,
1216 "offsetof(%s, %s)" % (objstruct, entry.name),
1217 flags))
1218 code.putln(
1219 "{0, 0, 0, 0, 0}")
1220 code.putln(
1221 "};")
1223 def generate_getset_table(self, env, code):
1224 if env.property_entries:
1225 code.putln("")
1226 code.putln(
1227 "static struct PyGetSetDef %s[] = {" %
1228 env.getset_table_cname)
1229 for entry in env.property_entries:
1230 if entry.doc:
1231 doc_code = code.get_string_const(entry.doc)
1232 else:
1233 doc_code = "0"
1234 code.putln(
1235 '{"%s", %s, %s, %s, 0},' % (
1236 entry.name,
1237 entry.getter_cname or "0",
1238 entry.setter_cname or "0",
1239 doc_code))
1240 code.putln(
1241 "{0, 0, 0, 0, 0}")
1242 code.putln(
1243 "};")
1245 def generate_interned_name_table(self, interned_strings, code):
1246 code.putln("")
1247 code.putln(
1248 "static PyObject **%s[] = {" % Naming.intern_tab_cname)
1249 for s in interned_strings:
1250 code.putln("&%s," % s.py_cname)
1251 code.putln("0")
1252 code.putln(
1253 "};")
1255 def generate_filename_init_prototype(self, code):
1256 code.putln("");
1257 code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1259 def generate_module_init_func(self, imported_modules, env, code):
1260 denv = env.definition_scope
1261 code.putln("")
1262 header = "PyMODINIT_FUNC init%s(void)" % env.module_name
1263 code.putln("%s; /*proto*/" % header)
1264 code.putln("%s {" % header)
1265 code.put_var_declarations(env.temp_entries)
1267 #code.putln("/*--- Libary function declarations ---*/")
1268 env.generate_library_function_declarations(code)
1269 self.generate_filename_init_call(code)
1271 #code.putln("/*--- Module creation code ---*/")
1272 self.generate_module_creation_code(env, code)
1274 #code.putln("/*--- String init code ---*/")
1275 self.generate_string_init_code(env, code)
1277 #code.putln("/*--- Intern code ---*/")
1278 #self.generate_intern_code(env, code)
1280 #code.putln("/*--- Global init code ---*/")
1281 self.generate_global_init_code(env, code)
1283 #code.putln("/*--- Function export code ---*/")
1284 self.generate_pxd_function_export_code(env, code)
1285 self.generate_api_function_export_code(env, code)
1287 #code.putln("/*--- Function import code ---*/")
1288 for module in imported_modules:
1289 self.generate_c_function_import_code_for_module(module, env, code)
1291 #code.putln("/*--- Type init code ---*/")
1292 self.generate_type_init_code(env, code)
1294 #code.putln("/*--- Type import code ---*/")
1295 for module in imported_modules:
1296 self.generate_type_import_code_for_module(module, env, code)
1298 #code.putln("/*--- Execution code ---*/")
1299 self.body.generate_execution_code(code)
1300 code.putln("return;")
1301 code.put_label(code.error_label)
1302 code.put_var_xdecrefs(env.temp_entries)
1303 code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
1304 code.use_utility_code(Nodes.traceback_utility_code)
1305 code.putln('}')
1307 def generate_filename_init_call(self, code):
1308 code.putln("%s();" % Naming.fileinit_cname)
1310 def generate_module_creation_code(self, env, code):
1311 # Generate code to create the module object and
1312 # install the builtins.
1313 if env.doc:
1314 doc = env.doc_cname
1315 else:
1316 doc = "0"
1317 code.putln(
1318 '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
1319 env.module_cname,
1320 env.module_name,
1321 env.method_table_cname,
1322 doc))
1323 code.putln(
1324 "if (!%s) %s;" % (
1325 env.module_cname,
1326 code.error_goto(self.pos)));
1327 code.putln(
1328 "Py_INCREF(%s);" %
1329 env.module_cname)
1330 code.putln(
1331 '%s = PyImport_AddModule("__builtin__");' %
1332 Naming.builtins_cname)
1333 code.putln(
1334 "if (!%s) %s;" % (
1335 Naming.builtins_cname,
1336 code.error_goto(self.pos)));
1337 code.putln(
1338 'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1339 env.module_cname,
1340 Naming.builtins_cname,
1341 code.error_goto(self.pos)))
1343 def generate_string_init_code(self, env, code):
1344 code.use_utility_code(Nodes.init_string_tab_utility_code)
1345 code.putln(
1346 "if (__Pyx_InitStrings(%s) < 0) %s;" % (
1347 Naming.stringtab_cname,
1348 code.error_goto(self.pos)))
1350 def generate_global_init_code(self, env, code):
1351 # Generate code to initialise global PyObject *
1352 # variables to None.
1353 for entry in env.var_entries:
1354 if entry.visibility <> 'extern':
1355 if entry.type.is_pyobject:
1356 code.put_init_var_to_py_none(entry)
1358 def generate_pxd_function_export_code(self, env, code):
1359 denv = env.definition_scope
1360 for entry in denv.cfunc_entries:
1361 if entry.visibility <> 'extern':
1362 self.generate_c_function_export_code(env, entry, code)
1364 def generate_api_function_export_code(self, env, code):
1365 for entry in env.cfunc_entries:
1366 if entry.api:
1367 self.generate_c_function_export_code(env, entry, code)
1369 def generate_c_function_export_code(self, env, entry, code):
1370 code.use_utility_code(function_export_utility_code)
1371 signature = entry.type.signature_string()
1372 code.putln('if (__Pyx_ExportFunction("%s", (void*)%s, "%s") < 0) %s' % (
1373 entry.name,
1374 entry.cname,
1375 signature,
1376 code.error_goto(self.pos)))
1378 def generate_type_import_code_for_module(self, module, env, code):
1379 # Generate type import code for all exported extension types in
1380 # an imported module.
1381 #if module.c_class_entries:
1382 #print "generate_type_import_code_for_module:", module ###
1383 for entry in module.c_class_entries:
1384 if entry.defined_in_pxd:
1385 self.generate_type_import_code(env, entry.type, entry.pos, code)
1387 def generate_c_function_import_code_for_module(self, module, env, code):
1388 # Generate import code for all exported C functions in a cimported module.
1389 entries = []
1390 for entry in module.cfunc_entries:
1391 if entry.defined_in_pxd:
1392 entries.append(entry)
1393 if entries:
1394 code.use_utility_code(import_module_utility_code)
1395 code.use_utility_code(function_import_utility_code)
1396 temp = self.module_temp_cname
1397 code.putln(
1398 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
1399 temp,
1400 module.qualified_name,
1401 temp,
1402 code.error_goto(self.pos)))
1403 for entry in entries:
1404 code.putln(
1405 'if (__Pyx_ImportFunction(%s, "%s", (void**)&%s, "%s") < 0) %s' % (
1406 temp,
1407 entry.name,
1408 entry.cname,
1409 entry.type.signature_string(),
1410 code.error_goto(self.pos)))
1411 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
1413 def generate_type_init_code(self, env, code):
1414 # Generate type import code for extern extension types
1415 # and type ready code for non-extern ones.
1416 #print "generate_type_init_code:", env ###
1417 denv = env.definition_scope
1418 for entry in denv.c_class_entries + env.c_class_entries:
1419 if entry.visibility == 'extern':
1420 self.generate_type_import_code(env, entry.type, entry.pos, code)
1421 else:
1422 self.generate_base_type_import_code(env, entry, code)
1423 self.generate_exttype_vtable_init_code(entry, code)
1424 self.generate_type_ready_code(env, entry, code)
1425 self.generate_typeptr_assignment_code(entry, code)
1427 def generate_base_type_import_code(self, env, entry, code):
1428 base_type = entry.type.base_type
1429 if base_type and base_type.module_name <> env.qualified_name:
1430 self.generate_type_import_code(env, base_type, self.pos, code)
1432 def use_type_import_utility_code(self, code):
1433 import ExprNodes
1434 code.use_utility_code(type_import_utility_code)
1435 code.use_utility_code(import_module_utility_code)
1437 def generate_type_import_code(self, env, type, pos, code):
1438 # If not already done, generate code to import the typeobject of an
1439 # extension type defined in another module, and extract its C method
1440 # table pointer if any.
1441 #print "generate_type_import_code:", type ###
1442 if type in env.types_imported:
1443 return
1444 if type.typedef_flag:
1445 objstruct = type.objstruct_cname
1446 else:
1447 objstruct = "struct %s" % type.objstruct_cname
1448 self.generate_type_import_call(type, code, code.error_goto(pos))
1449 self.use_type_import_utility_code(code)
1450 if type.vtabptr_cname:
1451 code.putln(
1452 "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1453 type.typeptr_cname,
1454 type.vtabptr_cname,
1455 code.error_goto(pos)))
1456 code.use_utility_code(Nodes.get_vtable_utility_code)
1457 env.types_imported[type] = 1
1459 def generate_type_import_call(self, type, code, error_code):
1460 if type.typedef_flag:
1461 objstruct = type.objstruct_cname
1462 else:
1463 objstruct = "struct %s" % type.objstruct_cname
1464 code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
1465 type.typeptr_cname,
1466 type.module_name,
1467 type.name,
1468 objstruct,
1469 type.typeptr_cname,
1470 error_code))
1472 def generate_type_ready_code(self, env, entry, code):
1473 # Generate a call to PyType_Ready for an extension
1474 # type defined in this module.
1475 type = entry.type
1476 typeobj_cname = type.typeobj_cname
1477 scope = type.scope
1478 if scope: # could be None if there was an error
1479 if entry.visibility <> 'extern':
1480 for slot in TypeSlots.slot_table:
1481 slot.generate_dynamic_init_code(scope, code)
1482 code.putln(
1483 "if (PyType_Ready(&%s) < 0) %s" % (
1484 typeobj_cname,
1485 code.error_goto(entry.pos)))
1486 if type.vtable_cname:
1487 code.putln(
1488 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
1489 typeobj_cname,
1490 type.vtabptr_cname,
1491 code.error_goto(entry.pos)))
1492 code.use_utility_code(Nodes.set_vtable_utility_code)
1493 code.putln(
1494 'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
1495 Naming.module_cname,
1496 scope.class_name,
1497 typeobj_cname,
1498 code.error_goto(entry.pos)))
1499 weakref_entry = scope.lookup_here("__weakref__")
1500 if weakref_entry:
1501 if weakref_entry.type is py_object_type:
1502 tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
1503 code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
1504 tp_weaklistoffset,
1505 tp_weaklistoffset,
1506 type.objstruct_cname,
1507 weakref_entry.cname))
1508 else:
1509 error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
1511 def generate_exttype_vtable_init_code(self, entry, code):
1512 # Generate code to initialise the C method table of an
1513 # extension type.
1514 type = entry.type
1515 if type.vtable_cname:
1516 code.putln(
1517 "%s = &%s;" % (
1518 type.vtabptr_cname,
1519 type.vtable_cname))
1520 if type.base_type and type.base_type.vtabptr_cname:
1521 code.putln(
1522 "%s.%s = *%s;" % (
1523 type.vtable_cname,
1524 Naming.obj_base_cname,
1525 type.base_type.vtabptr_cname))
1526 for meth_entry in type.scope.cfunc_entries:
1527 if meth_entry.func_cname:
1528 code.putln(
1529 "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
1530 type.vtable_cname,
1531 meth_entry.cname,
1532 meth_entry.func_cname))
1534 def generate_typeptr_assignment_code(self, entry, code):
1535 # Generate code to initialise the typeptr of an extension
1536 # type defined in this module to point to its type object.
1537 type = entry.type
1538 if type.typeobj_cname:
1539 code.putln(
1540 "%s = &%s;" % (
1541 type.typeptr_cname, type.typeobj_cname))
1543 def generate_utility_functions(self, code):
1544 code.global_state.generate_utility_functions(code)
1546 #------------------------------------------------------------------------------------
1548 # Runtime support code
1550 #------------------------------------------------------------------------------------
1552 import_module_utility_code = [
1553 """
1554 static PyObject *__Pyx_ImportModule(char *name); /*proto*/
1555 ""","""
1556 #ifndef __PYX_HAVE_RT_ImportModule
1557 #define __PYX_HAVE_RT_ImportModule
1558 static PyObject *__Pyx_ImportModule(char *name) {
1559 PyObject *py_name = 0;
1561 py_name = PyString_FromString(name);
1562 if (!py_name)
1563 goto bad;
1564 return PyImport_Import(py_name);
1565 bad:
1566 Py_XDECREF(py_name);
1567 return 0;
1569 #endif
1570 """]
1572 #------------------------------------------------------------------------------------
1574 type_import_utility_code = [
1575 """
1576 static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
1577 ""","""
1578 #ifndef __PYX_HAVE_RT_ImportType
1579 #define __PYX_HAVE_RT_ImportType
1580 static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
1581 long size)
1583 PyObject *py_module = 0;
1584 PyObject *result = 0;
1586 py_module = __Pyx_ImportModule(module_name);
1587 if (!py_module)
1588 goto bad;
1589 result = PyObject_GetAttrString(py_module, class_name);
1590 if (!result)
1591 goto bad;
1592 if (!PyType_Check(result)) {
1593 PyErr_Format(PyExc_TypeError,
1594 "%s.%s is not a type object",
1595 module_name, class_name);
1596 goto bad;
1598 if (((PyTypeObject *)result)->tp_basicsize != size) {
1599 PyErr_Format(PyExc_ValueError,
1600 "%s.%s does not appear to be the correct type object",
1601 module_name, class_name);
1602 goto bad;
1604 return (PyTypeObject *)result;
1605 bad:
1606 Py_XDECREF(result);
1607 return 0;
1609 #endif
1610 """]
1612 #------------------------------------------------------------------------------------
1614 function_export_utility_code = [
1615 """
1616 static int __Pyx_ExportFunction(char *n, void *f, char *s); /*proto*/
1617 """,r"""
1618 static int __Pyx_ExportFunction(char *n, void *f, char *s) {
1619 PyObject *d = 0;
1620 PyObject *p = 0;
1621 d = PyObject_GetAttrString(%(MODULE)s, "%(API)s");
1622 if (!d) {
1623 PyErr_Clear();
1624 d = PyDict_New();
1625 if (!d)
1626 goto bad;
1627 Py_INCREF(d);
1628 if (PyModule_AddObject(%(MODULE)s, "%(API)s", d) < 0)
1629 goto bad;
1631 p = PyCObject_FromVoidPtrAndDesc(f, s, 0);
1632 if (!p)
1633 goto bad;
1634 if (PyDict_SetItemString(d, n, p) < 0)
1635 goto bad;
1636 Py_DECREF(d);
1637 return 0;
1638 bad:
1639 Py_XDECREF(p);
1640 Py_XDECREF(d);
1641 return -1;
1643 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}]
1645 #------------------------------------------------------------------------------------
1647 function_import_utility_code = [
1648 """
1649 static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
1650 ""","""
1651 #ifndef __PYX_HAVE_RT_ImportFunction
1652 #define __PYX_HAVE_RT_ImportFunction
1653 static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
1654 PyObject *d = 0;
1655 PyObject *cobj = 0;
1656 char *desc;
1658 d = PyObject_GetAttrString(module, "%(API)s");
1659 if (!d)
1660 goto bad;
1661 cobj = PyDict_GetItemString(d, funcname);
1662 if (!cobj) {
1663 PyErr_Format(PyExc_ImportError,
1664 "%%s does not export expected C function %%s",
1665 PyModule_GetName(module), funcname);
1666 goto bad;
1668 desc = (char *)PyCObject_GetDesc(cobj);
1669 if (!desc)
1670 goto bad;
1671 if (strcmp(desc, sig) != 0) {
1672 PyErr_Format(PyExc_TypeError,
1673 "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
1674 PyModule_GetName(module), funcname, sig, desc);
1675 goto bad;
1677 *f = PyCObject_AsVoidPtr(cobj);
1678 Py_DECREF(d);
1679 return 0;
1680 bad:
1681 Py_XDECREF(d);
1682 return -1;
1684 #endif
1685 """ % dict(API = Naming.api_name)]