1 # 2 # Module parse tree node 3 # 4 5 import cython 6 cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object, 7 error=object, warning=object, py_object_type=object, UtilityCode=object, 8 EncodedString=object) 9 10 import os 11 import operator 12 from PyrexTypes import CPtrType 13 import Future 14 15 import Annotate 16 import Code 17 import Naming 18 import Nodes 19 import Options 20 import TypeSlots 21 import Version 22 import PyrexTypes 23 24 from Errors import error, warning 25 from PyrexTypes import py_object_type 26 from Cython.Utils import open_new_file, replace_suffix, decode_filename 27 from Code import UtilityCode 28 from StringEncoding import EncodedString 29 30 31 32 def check_c_declarations_pxd(module_node): 33 module_node.scope.check_c_classes_pxd() 34 return module_node 35 36 def check_c_declarations(module_node): 37 module_node.scope.check_c_classes() 38 module_node.scope.check_c_functions() 39 return module_node 40 41 class ModuleNode(Nodes.Node, Nodes.BlockNode): 42 # doc string or None 43 # body StatListNode 44 # 45 # referenced_modules [ModuleScope] 46 # full_module_name string 47 # 48 # scope The module scope. 49 # compilation_source A CompilationSource (see Main) 50 # directives Top-level compiler directives 51 52 child_attrs = ["body"] 53 directives = None 54 55 def merge_in(self, tree, scope, merge_scope=False): 56 # Merges in the contents of another tree, and possibly scope. With the 57 # current implementation below, this must be done right prior 58 # to code generation. 59 # 60 # Note: This way of doing it seems strange -- I believe the 61 # right concept is to split ModuleNode into a ModuleNode and a 62 # CodeGenerator, and tell that CodeGenerator to generate code 63 # from multiple sources. 64 assert isinstance(self.body, Nodes.StatListNode) 65 if isinstance(tree, Nodes.StatListNode): 66 self.body.stats.extend(tree.stats) 67 else: 68 self.body.stats.append(tree) 69 70 self.scope.utility_code_list.extend(scope.utility_code_list) 71 72 def extend_if_not_in(L1, L2): 73 for x in L2: 74 if x not in L1: 75 L1.append(x) 76 77 extend_if_not_in(self.scope.include_files, scope.include_files) 78 extend_if_not_in(self.scope.included_files, scope.included_files) 79 extend_if_not_in(self.scope.python_include_files, 80 scope.python_include_files) 81 82 if merge_scope: 83 # Ensure that we don't generate import code for these entries! 84 for entry in scope.c_class_entries: 85 entry.type.module_name = self.full_module_name 86 entry.type.scope.directives["internal"] = True 87 88 self.scope.merge_in(scope) 89 90 def analyse_declarations(self, env): 91 if not Options.docstrings: 92 env.doc = self.doc = None 93 elif Options.embed_pos_in_docstring: 94 env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos)) 95 if not self.doc is None: 96 env.doc = EncodedString(env.doc + u'\n' + self.doc) 97 env.doc.encoding = self.doc.encoding 98 else: 99 env.doc = self.doc 100 env.directives = self.directives 101 self.body.analyse_declarations(env) 102 103 def process_implementation(self, options, result): 104 env = self.scope 105 env.return_type = PyrexTypes.c_void_type 106 self.referenced_modules = [] 107 self.find_referenced_modules(env, self.referenced_modules, {}) 108 self.sort_cdef_classes(env) 109 self.generate_c_code(env, options, result) 110 self.generate_h_code(env, options, result) 111 self.generate_api_code(env, result) 112 113 def has_imported_c_functions(self): 114 for module in self.referenced_modules: 115 for entry in module.cfunc_entries: 116 if entry.defined_in_pxd: 117 return 1 118 return 0 119 120 def generate_h_code(self, env, options, result): 121 def h_entries(entries, api=0, pxd=0): 122 return [entry for entry in entries 123 if ((entry.visibility == 'public') or 124 (api and entry.api) or 125 (pxd and entry.defined_in_pxd))] 126 h_types = h_entries(env.type_entries, api=1) 127 h_vars = h_entries(env.var_entries) 128 h_funcs = h_entries(env.cfunc_entries) 129 h_extension_types = h_entries(env.c_class_entries) 130 if (h_types or h_vars or h_funcs or h_extension_types): 131 result.h_file = replace_suffix(result.c_file, ".h") 132 h_code = Code.CCodeWriter() 133 Code.GlobalState(h_code, self) 134 if options.generate_pxi: 135 result.i_file = replace_suffix(result.c_file, ".pxi") 136 i_code = Code.PyrexCodeWriter(result.i_file) 137 else: 138 i_code = None 139 140 h_guard = Naming.h_guard_prefix + self.api_name(env) 141 h_code.put_h_guard(h_guard) 142 h_code.putln("") 143 self.generate_type_header_code(h_types, h_code) 144 if options.capi_reexport_cincludes: 145 self.generate_includes(env, [], h_code) 146 h_code.putln("") 147 api_guard = Naming.api_guard_prefix + self.api_name(env) 148 h_code.putln("#ifndef %s" % api_guard) 149 h_code.putln("") 150 self.generate_extern_c_macro_definition(h_code) 151 if h_extension_types: 152 h_code.putln("") 153 for entry in h_extension_types: 154 self.generate_cclass_header_code(entry.type, h_code) 155 if i_code: 156 self.generate_cclass_include_code(entry.type, i_code) 157 if h_funcs: 158 h_code.putln("") 159 for entry in h_funcs: 160 self.generate_public_declaration(entry, h_code, i_code) 161 if h_vars: 162 h_code.putln("") 163 for entry in h_vars: 164 self.generate_public_declaration(entry, h_code, i_code) 165 h_code.putln("") 166 h_code.putln("#endif /* !%s */" % api_guard) 167 h_code.putln("") 168 h_code.putln("#if PY_MAJOR_VERSION < 3") 169 h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name) 170 h_code.putln("#else") 171 h_code.putln("PyMODINIT_FUNC PyInit_%s(void);" % env.module_name) 172 h_code.putln("#endif") 173 h_code.putln("") 174 h_code.putln("#endif /* !%s */" % h_guard) 175 176 f = open_new_file(result.h_file) 177 try: 178 h_code.copyto(f) 179 finally: 180 f.close() 181 182 def generate_public_declaration(self, entry, h_code, i_code): 183 h_code.putln("%s %s;" % ( 184 Naming.extern_c_macro, 185 entry.type.declaration_code( 186 entry.cname, dll_linkage = "DL_IMPORT"))) 187 if i_code: 188 i_code.putln("cdef extern %s" % 189 entry.type.declaration_code(entry.cname, pyrex = 1)) 190 191 def api_name(self, env): 192 return env.qualified_name.replace(".", "__") 193 194 def generate_api_code(self, env, result): 195 def api_entries(entries, pxd=0): 196 return [entry for entry in entries 197 if entry.api or (pxd and entry.defined_in_pxd)] 198 api_vars = api_entries(env.var_entries) 199 api_funcs = api_entries(env.cfunc_entries) 200 api_extension_types = api_entries(env.c_class_entries) 201 if api_vars or api_funcs or api_extension_types: 202 result.api_file = replace_suffix(result.c_file, "_api.h") 203 h_code = Code.CCodeWriter() 204 Code.GlobalState(h_code, self) 205 api_guard = Naming.api_guard_prefix + self.api_name(env) 206 h_code.put_h_guard(api_guard) 207 h_code.putln('#include "Python.h"') 208 if result.h_file: 209 h_code.putln('#include "%s"' % os.path.basename(result.h_file)) 210 if api_extension_types: 211 h_code.putln("") 212 for entry in api_extension_types: 213 type = entry.type 214 h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname) 215 h_code.putln("#define %s (*%s)" % ( 216 type.typeobj_cname, type.typeptr_cname)) 217 if api_funcs: 218 h_code.putln("") 219 for entry in api_funcs: 220 type = CPtrType(entry.type) 221 cname = env.mangle(Naming.func_prefix, entry.name) 222 h_code.putln("static %s = 0;" % type.declaration_code(cname)) 223 h_code.putln("#define %s %s" % (entry.name, cname)) 224 if api_vars: 225 h_code.putln("") 226 for entry in api_vars: 227 type = CPtrType(entry.type) 228 cname = env.mangle(Naming.varptr_prefix, entry.name) 229 h_code.putln("static %s = 0;" % type.declaration_code(cname)) 230 h_code.putln("#define %s (*%s)" % (entry.name, cname)) 231 h_code.put(UtilityCode.load_as_string("PyIdentifierFromString", "ImportExport.c")[0]) 232 h_code.put(UtilityCode.load_as_string("ModuleImport", "ImportExport.c")[1]) 233 if api_vars: 234 h_code.put(UtilityCode.load_as_string("VoidPtrImport", "ImportExport.c")[1]) 235 if api_funcs: 236 h_code.put(UtilityCode.load_as_string("FunctionImport", "ImportExport.c")[1]) 237 if api_extension_types: 238 h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[1]) 239 h_code.putln("") 240 h_code.putln("static int import_%s(void) {" % self.api_name(env)) 241 h_code.putln("PyObject *module = 0;") 242 h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name) 243 h_code.putln("if (!module) goto bad;") 244 for entry in api_funcs: 245 cname = env.mangle(Naming.func_prefix, entry.name) 246 sig = entry.type.signature_string() 247 h_code.putln( 248 'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;' 249 % (entry.name, cname, sig)) 250 for entry in api_vars: 251 cname = env.mangle(Naming.varptr_prefix, entry.name) 252 sig = entry.type.declaration_code("") 253 h_code.putln( 254 'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;' 255 % (entry.name, cname, sig)) 256 h_code.putln("Py_DECREF(module); module = 0;") 257 for entry in api_extension_types: 258 self.generate_type_import_call( 259 entry.type, h_code, 260 "if (!%s) goto bad;" % entry.type.typeptr_cname) 261 h_code.putln("return 0;") 262 h_code.putln("bad:") 263 h_code.putln("Py_XDECREF(module);") 264 h_code.putln("return -1;") 265 h_code.putln("}") 266 h_code.putln("") 267 h_code.putln("#endif /* !%s */" % api_guard) 268 269 f = open_new_file(result.api_file) 270 try: 271 h_code.copyto(f) 272 finally: 273 f.close() 274 275 def generate_cclass_header_code(self, type, h_code): 276 h_code.putln("%s %s %s;" % ( 277 Naming.extern_c_macro, 278 PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"), 279 type.typeobj_cname)) 280 281 def generate_cclass_include_code(self, type, i_code): 282 i_code.putln("cdef extern class %s.%s:" % ( 283 type.module_name, type.name)) 284 i_code.indent() 285 var_entries = type.scope.var_entries 286 if var_entries: 287 for entry in var_entries: 288 i_code.putln("cdef %s" % 289 entry.type.declaration_code(entry.cname, pyrex = 1)) 290 else: 291 i_code.putln("pass") 292 i_code.dedent() 293 294 def generate_c_code(self, env, options, result): 295 modules = self.referenced_modules 296 297 if Options.annotate or options.annotate: 298 emit_linenums = False 299 rootwriter = Annotate.AnnotationCCodeWriter() 300 else: 301 emit_linenums = options.emit_linenums 302 rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback) 303 globalstate = Code.GlobalState(rootwriter, self, emit_linenums, options.common_utility_include_dir) 304 globalstate.initialize_main_c_code() 305 h_code = globalstate['h_code'] 306 307 self.generate_module_preamble(env, modules, h_code) 308 309 globalstate.module_pos = self.pos 310 globalstate.directives = self.directives 311 312 globalstate.use_utility_code(refnanny_utility_code) 313 314 code = globalstate['before_global_var'] 315 code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name) 316 code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))) 317 code.putln("") 318 code.putln("/* Implementation of '%s' */" % env.qualified_name) 319 320 code = globalstate['all_the_rest'] 321 322 self.generate_cached_builtins_decls(env, code) 323 self.generate_lambda_definitions(env, code) 324 # generate normal variable and function definitions 325 self.generate_variable_definitions(env, code) 326 self.body.generate_function_definitions(env, code) 327 code.mark_pos(None) 328 self.generate_typeobj_definitions(env, code) 329 self.generate_method_table(env, code) 330 if env.has_import_star: 331 self.generate_import_star(env, code) 332 self.generate_pymoduledef_struct(env, code) 333 334 # init_globals is inserted before this 335 self.generate_module_init_func(modules[:-1], env, globalstate['init_module']) 336 self.generate_module_cleanup_func(env, globalstate['cleanup_module']) 337 if Options.embed: 338 self.generate_main_method(env, globalstate['main_method']) 339 self.generate_filename_table(globalstate['filename_table']) 340 341 self.generate_declarations_for_modules(env, modules, globalstate) 342 h_code.write('\n') 343 344 for utilcode in env.utility_code_list[:]: 345 globalstate.use_utility_code(utilcode) 346 globalstate.finalize_main_c_code() 347 348 f = open_new_file(result.c_file) 349 try: 350 rootwriter.copyto(f) 351 finally: 352 f.close() 353 result.c_file_generated = 1 354 if options.gdb_debug: 355 self._serialize_lineno_map(env, rootwriter) 356 if Options.annotate or options.annotate: 357 self._generate_annotations(rootwriter, result) 358 359 def _generate_annotations(self, rootwriter, result): 360 self.annotate(rootwriter) 361 rootwriter.save_annotation(result.main_source_file, result.c_file) 362 363 # if we included files, additionally generate one annotation file for each 364 if not self.scope.included_files: 365 return 366 367 search_include_file = self.scope.context.search_include_directories 368 target_dir = os.path.abspath(os.path.dirname(result.c_file)) 369 for included_file in self.scope.included_files: 370 target_file = os.path.abspath(os.path.join(target_dir, included_file)) 371 target_file_dir = os.path.dirname(target_file) 372 if not target_file_dir.startswith(target_dir): 373 # any other directories may not be writable => avoid trying 374 continue 375 source_file = search_include_file(included_file, "", self.pos, include=True) 376 if not source_file: 377 continue 378 if target_file_dir != target_dir and not os.path.exists(target_file_dir): 379 try: 380 os.makedirs(target_file_dir) 381 except OSError, e: 382 import errno 383 if e.errno != errno.EEXIST: 384 raise 385 rootwriter.save_annotation(source_file, target_file) 386 387 def _serialize_lineno_map(self, env, ccodewriter): 388 tb = env.context.gdb_debug_outputwriter 389 markers = ccodewriter.buffer.allmarkers() 390 391 d = {} 392 for c_lineno, cython_lineno in enumerate(markers): 393 if cython_lineno > 0: 394 d.setdefault(cython_lineno, []).append(c_lineno + 1) 395 396 tb.start('LineNumberMapping') 397 for cython_lineno, c_linenos in sorted(d.iteritems()): 398 attrs = { 399 'c_linenos': ' '.join(map(str, c_linenos)), 400 'cython_lineno': str(cython_lineno), 401 } 402 tb.start('LineNumber', attrs) 403 tb.end('LineNumber') 404 tb.end('LineNumberMapping') 405 tb.serialize() 406 407 def find_referenced_modules(self, env, module_list, modules_seen): 408 if env not in modules_seen: 409 modules_seen[env] = 1 410 for imported_module in env.cimported_modules: 411 self.find_referenced_modules(imported_module, module_list, modules_seen) 412 module_list.append(env) 413 414 def sort_types_by_inheritance(self, type_dict, type_order, getkey): 415 # copy the types into a list moving each parent type before 416 # its first child 417 type_list = [] 418 for i, key in enumerate(type_order): 419 new_entry = type_dict[key] 420 421 # collect all base classes to check for children 422 hierarchy = set() 423 base = new_entry 424 while base: 425 base_type = base.type.base_type 426 if not base_type: 427 break 428 base_key = getkey(base_type) 429 hierarchy.add(base_key) 430 base = type_dict.get(base_key) 431 new_entry.base_keys = hierarchy 432 433 # find the first (sub-)subclass and insert before that 434 for j in range(i): 435 entry = type_list[j] 436 if key in entry.base_keys: 437 type_list.insert(j, new_entry) 438 break 439 else: 440 type_list.append(new_entry) 441 return type_list 442 443 def sort_type_hierarchy(self, module_list, env): 444 # poor developer's OrderedDict 445 vtab_dict, vtab_dict_order = {}, [] 446 vtabslot_dict, vtabslot_dict_order = {}, [] 447 448 for module in module_list: 449 for entry in module.c_class_entries: 450 if entry.used and not entry.in_cinclude: 451 type = entry.type 452 key = type.vtabstruct_cname 453 if not key: 454 continue 455 if key in vtab_dict: 456 # FIXME: this should *never* happen, but apparently it does 457 # for Cython generated utility code 458 from Cython.Compiler.UtilityCode import NonManglingModuleScope 459 assert isinstance(entry.scope, NonManglingModuleScope), str(entry.scope) 460 assert isinstance(vtab_dict[key].scope, NonManglingModuleScope), str(vtab_dict[key].scope) 461 else: 462 vtab_dict[key] = entry 463 vtab_dict_order.append(key) 464 all_defined_here = module is env 465 for entry in module.type_entries: 466 if entry.used and (all_defined_here or entry.defined_in_pxd): 467 type = entry.type 468 if type.is_extension_type and not entry.in_cinclude: 469 type = entry.type 470 key = type.objstruct_cname 471 assert key not in vtabslot_dict, key 472 vtabslot_dict[key] = entry 473 vtabslot_dict_order.append(key) 474 475 def vtabstruct_cname(entry_type): 476 return entry_type.vtabstruct_cname 477 vtab_list = self.sort_types_by_inheritance( 478 vtab_dict, vtab_dict_order, vtabstruct_cname) 479 480 def objstruct_cname(entry_type): 481 return entry_type.objstruct_cname 482 vtabslot_list = self.sort_types_by_inheritance( 483 vtabslot_dict, vtabslot_dict_order, objstruct_cname) 484 485 return (vtab_list, vtabslot_list) 486 487 def sort_cdef_classes(self, env): 488 key_func = operator.attrgetter('objstruct_cname') 489 entry_dict, entry_order = {}, [] 490 for entry in env.c_class_entries: 491 key = key_func(entry.type) 492 assert key not in entry_dict, key 493 entry_dict[key] = entry 494 entry_order.append(key) 495 env.c_class_entries[:] = self.sort_types_by_inheritance( 496 entry_dict, entry_order, key_func) 497 498 def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code): 499 # TODO: Why are these separated out? 500 for entry in vtabslot_list: 501 self.generate_objstruct_predeclaration(entry.type, code) 502 vtabslot_entries = set(vtabslot_list) 503 for module in modules: 504 definition = module is env 505 if definition: 506 type_entries = module.type_entries 507 else: 508 type_entries = [] 509 for entry in module.type_entries: 510 if entry.defined_in_pxd: 511 type_entries.append(entry) 512 type_entries = [t for t in type_entries if t not in vtabslot_entries] 513 self.generate_type_header_code(type_entries, code) 514 for entry in vtabslot_list: 515 self.generate_objstruct_definition(entry.type, code) 516 self.generate_typeobj_predeclaration(entry, code) 517 for entry in vtab_list: 518 self.generate_typeobj_predeclaration(entry, code) 519 self.generate_exttype_vtable_struct(entry, code) 520 self.generate_exttype_vtabptr_declaration(entry, code) 521 self.generate_exttype_final_methods_declaration(entry, code) 522 523 def generate_declarations_for_modules(self, env, modules, globalstate): 524 typecode = globalstate['type_declarations'] 525 typecode.putln("") 526 typecode.putln("/*--- Type declarations ---*/") 527 # This is to work around the fact that array.h isn't part of the C-API, 528 # but we need to declare it earlier than utility code. 529 if 'cpython.array' in [m.qualified_name for m in modules]: 530 typecode.putln('#ifndef _ARRAYARRAY_H') 531 typecode.putln('struct arrayobject;') 532 typecode.putln('typedef struct arrayobject arrayobject;') 533 typecode.putln('#endif') 534 vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env) 535 self.generate_type_definitions( 536 env, modules, vtab_list, vtabslot_list, typecode) 537 modulecode = globalstate['module_declarations'] 538 for module in modules: 539 defined_here = module is env 540 modulecode.putln("") 541 modulecode.putln("/* Module declarations from '%s' */" % module.qualified_name) 542 self.generate_c_class_declarations(module, modulecode, defined_here) 543 self.generate_cvariable_declarations(module, modulecode, defined_here) 544 self.generate_cfunction_declarations(module, modulecode, defined_here) 545 546 def generate_module_preamble(self, env, cimported_modules, code): 547 code.putln("/* Generated by Cython %s */" % Version.watermark) 548 code.putln("") 549 code.putln("#define PY_SSIZE_T_CLEAN") 550 551 # sizeof(PyLongObject.ob_digit[0]) may have been determined dynamically 552 # at compile time in CPython, in which case we can't know the correct 553 # storage size for an installed system. We can rely on it only if 554 # pyconfig.h defines it statically, i.e. if it was set by "configure". 555 # Once we include "Python.h", it will come up with its own idea about 556 # a suitable value, which may or may not match the real one. 557 code.putln("#ifndef CYTHON_USE_PYLONG_INTERNALS") 558 code.putln("#ifdef PYLONG_BITS_IN_DIGIT") 559 # assume it's an incorrect left-over 560 code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0") 561 code.putln("#else") 562 code.putln('#include "pyconfig.h"') 563 code.putln("#ifdef PYLONG_BITS_IN_DIGIT") 564 code.putln("#define CYTHON_USE_PYLONG_INTERNALS 1") 565 code.putln("#else") 566 code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0") 567 code.putln("#endif") 568 code.putln("#endif") 569 code.putln("#endif") 570 571 for filename in env.python_include_files: 572 code.putln('#include "%s"' % filename) 573 code.putln("#ifndef Py_PYTHON_H") 574 code.putln(" #error Python headers needed to compile C extensions, please install development version of Python.") 575 code.putln("#elif PY_VERSION_HEX < 0x02040000") 576 code.putln(" #error Cython requires Python 2.4+.") 577 code.putln("#else") 578 code.globalstate["end"].putln("#endif /* Py_PYTHON_H */") 579 580 from Cython import __version__ 581 code.putln('#define CYTHON_ABI "%s"' % __version__.replace('.', '_')) 582 583 code.put(UtilityCode.load_as_string("CModulePreamble", "ModuleSetupCode.c")[1]) 584 585 code.put(""" 586 #if PY_MAJOR_VERSION >= 3 587 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) 588 #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) 589 #else 590 """) 591 if Future.division in env.context.future_directives: 592 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)") 593 code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)") 594 else: 595 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)") 596 code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)") 597 code.putln("#endif") 598 599 code.putln("") 600 self.generate_extern_c_macro_definition(code) 601 code.putln("") 602 603 code.putln("#if defined(WIN32) || defined(MS_WINDOWS)") 604 code.putln("#define _USE_MATH_DEFINES") 605 code.putln("#endif") 606 code.putln("#include <math.h>") 607 608 code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env)) 609 code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env)) 610 self.generate_includes(env, cimported_modules, code) 611 code.putln("") 612 code.putln("#ifdef PYREX_WITHOUT_ASSERTIONS") 613 code.putln("#define CYTHON_WITHOUT_ASSERTIONS") 614 code.putln("#endif") 615 code.putln("") 616 617 if env.directives['ccomplex']: 618 code.putln("") 619 code.putln("#if !defined(CYTHON_CCOMPLEX)") 620 code.putln("#define CYTHON_CCOMPLEX 1") 621 code.putln("#endif") 622 code.putln("") 623 code.put(UtilityCode.load_as_string("UtilityFunctionPredeclarations", "ModuleSetupCode.c")[0]) 624 625 c_string_type = env.directives['c_string_type'] 626 c_string_encoding = env.directives['c_string_encoding'] 627 if c_string_type not in ('bytes', 'bytearray') and not c_string_encoding: 628 error(self.pos, "a default encoding must be provided if c_string_type is not a byte type") 629 code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII %s' % int(c_string_encoding == 'ascii')) 630 if c_string_encoding == 'default': 631 code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 1') 632 else: 633 code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0') 634 code.putln('#define __PYX_DEFAULT_STRING_ENCODING "%s"' % c_string_encoding) 635 if c_string_type == 'bytearray': 636 c_string_func_name = 'ByteArray' 637 else: 638 c_string_func_name = c_string_type.title() 639 code.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_func_name) 640 code.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_func_name) 641 code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0]) 642 643 # These utility functions are assumed to exist and used elsewhere. 644 PyrexTypes.c_long_type.create_to_py_utility_code(env) 645 PyrexTypes.c_long_type.create_from_py_utility_code(env) 646 PyrexTypes.c_int_type.create_from_py_utility_code(env) 647 648 code.put(Nodes.branch_prediction_macros) 649 code.putln('') 650 code.putln('static PyObject *%s;' % env.module_cname) 651 code.putln('static PyObject *%s;' % env.module_dict_cname) 652 code.putln('static PyObject *%s;' % Naming.builtins_cname) 653 code.putln('static PyObject *%s;' % Naming.empty_tuple) 654 code.putln('static PyObject *%s;' % Naming.empty_bytes) 655 if Options.pre_import is not None: 656 code.putln('static PyObject *%s;' % Naming.preimport_cname) 657 code.putln('static int %s;' % Naming.lineno_cname) 658 code.putln('static int %s = 0;' % Naming.clineno_cname) 659 code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro)) 660 code.putln('static const char *%s;' % Naming.filename_cname) 661 662 def generate_extern_c_macro_definition(self, code): 663 name = Naming.extern_c_macro 664 code.putln("#ifndef %s" % name) 665 code.putln(" #ifdef __cplusplus") 666 code.putln(' #define %s extern "C"' % name) 667 code.putln(" #else") 668 code.putln(" #define %s extern" % name) 669 code.putln(" #endif") 670 code.putln("#endif") 671 672 def generate_includes(self, env, cimported_modules, code): 673 includes = [] 674 for filename in env.include_files: 675 byte_decoded_filenname = str(filename) 676 if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>': 677 code.putln('#include %s' % byte_decoded_filenname) 678 else: 679 code.putln('#include "%s"' % byte_decoded_filenname) 680 681 code.putln_openmp("#include <omp.h>") 682 683 def generate_filename_table(self, code): 684 code.putln("") 685 code.putln("static const char *%s[] = {" % Naming.filetable_cname) 686 if code.globalstate.filename_list: 687 for source_desc in code.globalstate.filename_list: 688 filename = os.path.basename(source_desc.get_filenametable_entry()) 689 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"') 690 code.putln('"%s",' % escaped_filename) 691 else: 692 # Some C compilers don't like an empty array 693 code.putln("0") 694 code.putln("};") 695 696 def generate_type_predeclarations(self, env, code): 697 pass 698 699 def generate_type_header_code(self, type_entries, code): 700 # Generate definitions of structs/unions/enums/typedefs/objstructs. 701 #self.generate_gcc33_hack(env, code) # Is this still needed? 702 # Forward declarations 703 for entry in type_entries: 704 if not entry.in_cinclude: 705 #print "generate_type_header_code:", entry.name, repr(entry.type) ### 706 type = entry.type 707 if type.is_typedef: # Must test this first! 708 pass 709 elif type.is_struct_or_union or type.is_cpp_class: 710 self.generate_struct_union_predeclaration(entry, code) 711 elif type.is_extension_type: 712 self.generate_objstruct_predeclaration(type, code) 713 # Actual declarations 714 for entry in type_entries: 715 if not entry.in_cinclude: 716 #print "generate_type_header_code:", entry.name, repr(entry.type) ### 717 type = entry.type 718 if type.is_typedef: # Must test this first! 719 self.generate_typedef(entry, code) 720 elif type.is_enum: 721 self.generate_enum_definition(entry, code) 722 elif type.is_struct_or_union: 723 self.generate_struct_union_definition(entry, code) 724 elif type.is_cpp_class: 725 self.generate_cpp_class_definition(entry, code) 726 elif type.is_extension_type: 727 self.generate_objstruct_definition(type, code) 728 729 def generate_gcc33_hack(self, env, code): 730 # Workaround for spurious warning generation in gcc 3.3 731 code.putln("") 732 for entry in env.c_class_entries: 733 type = entry.type 734 if not type.typedef_flag: 735 name = type.objstruct_cname 736 if name.startswith("__pyx_"): 737 tail = name[6:] 738 else: 739 tail = name 740 code.putln("typedef struct %s __pyx_gcc33_%s;" % ( 741 name, tail)) 742 743 def generate_typedef(self, entry, code): 744 base_type = entry.type.typedef_base_type 745 if base_type.is_numeric: 746 try: 747 writer = code.globalstate['numeric_typedefs'] 748 except KeyError: 749 writer = code 750 else: 751 writer = code 752 writer.mark_pos(entry.pos) 753 writer.putln("typedef %s;" % base_type.declaration_code(entry.cname)) 754 755 def sue_predeclaration(self, type, kind, name): 756 if type.typedef_flag: 757 return "%s %s;\ntypedef %s %s %s;" % ( 758 kind, name, 759 kind, name, name) 760 else: 761 return "%s %s;" % (kind, name) 762 763 def generate_struct_union_predeclaration(self, entry, code): 764 type = entry.type 765 if type.is_cpp_class and type.templates: 766 code.putln("template <typename %s>" % ", typename ".join([T.declaration_code("") for T in type.templates])) 767 code.putln(self.sue_predeclaration(type, type.kind, type.cname)) 768 769 def sue_header_footer(self, type, kind, name): 770 header = "%s %s {" % (kind, name) 771 footer = "};" 772 return header, footer 773 774 def generate_struct_union_definition(self, entry, code): 775 code.mark_pos(entry.pos) 776 type = entry.type 777 scope = type.scope 778 if scope: 779 kind = type.kind 780 packed = type.is_struct and type.packed 781 if packed: 782 kind = "%s %s" % (type.kind, "__Pyx_PACKED") 783 code.globalstate.use_utility_code(packed_struct_utility_code) 784 header, footer = \ 785 self.sue_header_footer(type, kind, type.cname) 786 if packed: 787 code.putln("#if defined(__SUNPRO_C)") 788 code.putln(" #pragma pack(1)") 789 code.putln("#elif !defined(__GNUC__)") 790 code.putln(" #pragma pack(push, 1)") 791 code.putln("#endif") 792 code.putln(header) 793 var_entries = scope.var_entries 794 if not var_entries: 795 error(entry.pos, 796 "Empty struct or union definition not allowed outside a" 797 " 'cdef extern from' block") 798 for attr in var_entries: 799 code.putln( 800 "%s;" % 801 attr.type.declaration_code(attr.cname)) 802 code.putln(footer) 803 if packed: 804 code.putln("#if defined(__SUNPRO_C)") 805 code.putln(" #pragma pack()") 806 code.putln("#elif !defined(__GNUC__)") 807 code.putln(" #pragma pack(pop)") 808 code.putln("#endif") 809 810 def generate_cpp_class_definition(self, entry, code): 811 code.mark_pos(entry.pos) 812 type = entry.type 813 scope = type.scope 814 if scope: 815 if type.templates: 816 code.putln("template <class %s>" % ", class ".join([T.declaration_code("") for T in type.templates])) 817 # Just let everything be public. 818 code.put("struct %s" % type.cname) 819 if type.base_classes: 820 base_class_decl = ", public ".join( 821 [base_class.declaration_code("") for base_class in type.base_classes]) 822 code.put(" : public %s" % base_class_decl) 823 code.putln(" {") 824 has_virtual_methods = False 825 has_destructor = False 826 for attr in scope.var_entries: 827 if attr.type.is_cfunction and attr.name != "<init>": 828 code.put("virtual ") 829 has_virtual_methods = True 830 if attr.cname[0] == '~': 831 has_destructor = True 832 code.putln( 833 "%s;" % 834 attr.type.declaration_code(attr.cname)) 835 if has_virtual_methods and not has_destructor: 836 code.put("virtual ~%s() { }" % type.cname) 837 code.putln("};") 838 839 def generate_enum_definition(self, entry, code): 840 code.mark_pos(entry.pos) 841 type = entry.type 842 name = entry.cname or entry.name or "" 843 header, footer = \ 844 self.sue_header_footer(type, "enum", name) 845 code.putln(header) 846 enum_values = entry.enum_values 847 if not enum_values: 848 error(entry.pos, 849 "Empty enum definition not allowed outside a" 850 " 'cdef extern from' block") 851 else: 852 last_entry = enum_values[-1] 853 # this does not really generate code, just builds the result value 854 for value_entry in enum_values: 855 if value_entry.value_node is not None: 856 value_entry.value_node.generate_evaluation_code(code) 857 858 for value_entry in enum_values: 859 if value_entry.value_node is None: 860 value_code = value_entry.cname 861 else: 862 value_code = ("%s = %s" % ( 863 value_entry.cname, 864 value_entry.value_node.result())) 865 if value_entry is not last_entry: 866 value_code += "," 867 code.putln(value_code) 868 code.putln(footer) 869 if entry.type.typedef_flag: 870 # Not pre-declared. 871 code.putln("typedef enum %s %s;" % (name, name)) 872 873 def generate_typeobj_predeclaration(self, entry, code): 874 code.putln("") 875 name = entry.type.typeobj_cname 876 if name: 877 if entry.visibility == 'extern' and not entry.in_cinclude: 878 code.putln("%s %s %s;" % ( 879 Naming.extern_c_macro, 880 PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"), 881 name)) 882 elif entry.visibility == 'public': 883 code.putln("%s %s %s;" % ( 884 Naming.extern_c_macro, 885 PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"), 886 name)) 887 # ??? Do we really need the rest of this? ??? 888 #else: 889 # code.putln("static PyTypeObject %s;" % name) 890 891 def generate_exttype_vtable_struct(self, entry, code): 892 if not entry.used: 893 return 894 895 code.mark_pos(entry.pos) 896 # Generate struct declaration for an extension type's vtable. 897 type = entry.type 898 scope = type.scope 899 900 self.specialize_fused_types(scope) 901 902 if type.vtabstruct_cname: 903 code.putln("") 904 code.putln( 905 "struct %s {" % 906 type.vtabstruct_cname) 907 if type.base_type and type.base_type.vtabstruct_cname: 908 code.putln("struct %s %s;" % ( 909 type.base_type.vtabstruct_cname, 910 Naming.obj_base_cname)) 911 for method_entry in scope.cfunc_entries: 912 if not method_entry.is_inherited: 913 code.putln( 914 "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname)) 915 code.putln( 916 "};") 917 918 def generate_exttype_vtabptr_declaration(self, entry, code): 919 if not entry.used: 920 return 921 922 code.mark_pos(entry.pos) 923 # Generate declaration of pointer to an extension type's vtable. 924 type = entry.type 925 if type.vtabptr_cname: 926 code.putln("static struct %s *%s;" % ( 927 type.vtabstruct_cname, 928 type.vtabptr_cname)) 929 930 def generate_exttype_final_methods_declaration(self, entry, code): 931 if not entry.used: 932 return 933 934 code.mark_pos(entry.pos) 935 # Generate final methods prototypes 936 type = entry.type 937 for method_entry in entry.type.scope.cfunc_entries: 938 if not method_entry.is_inherited and method_entry.final_func_cname: 939 declaration = method_entry.type.declaration_code( 940 method_entry.final_func_cname) 941 modifiers = code.build_function_modifiers(method_entry.func_modifiers) 942 code.putln("static %s%s;" % (modifiers, declaration)) 943 944 def generate_objstruct_predeclaration(self, type, code): 945 if not type.scope: 946 return 947 code.putln(self.sue_predeclaration(type, "struct", type.objstruct_cname)) 948 949 def generate_objstruct_definition(self, type, code): 950 code.mark_pos(type.pos) 951 # Generate object struct definition for an 952 # extension type. 953 if not type.scope: 954 return # Forward declared but never defined 955 header, footer = \ 956 self.sue_header_footer(type, "struct", type.objstruct_cname) 957 code.putln(header) 958 base_type = type.base_type 959 if base_type: 960 basestruct_cname = base_type.objstruct_cname 961 if basestruct_cname == "PyTypeObject": 962 # User-defined subclasses of type are heap allocated. 963 basestruct_cname = "PyHeapTypeObject" 964 code.putln( 965 "%s%s %s;" % ( 966 ("struct ", "")[base_type.typedef_flag], 967 basestruct_cname, 968 Naming.obj_base_cname)) 969 else: 970 code.putln( 971 "PyObject_HEAD") 972 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname): 973 code.putln( 974 "struct %s *%s;" % ( 975 type.vtabstruct_cname, 976 type.vtabslot_cname)) 977 for attr in type.scope.var_entries: 978 if attr.is_declared_generic: 979 attr_type = py_object_type 980 else: 981 attr_type = attr.type 982 code.putln( 983 "%s;" % 984 attr_type.declaration_code(attr.cname)) 985 code.putln(footer) 986 if type.objtypedef_cname is not None: 987 # Only for exposing public typedef name. 988 code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname)) 989 990 def generate_c_class_declarations(self, env, code, definition): 991 for entry in env.c_class_entries: 992 if definition or entry.defined_in_pxd: 993 code.putln("static PyTypeObject *%s = 0;" % 994 entry.type.typeptr_cname) 995 996 def generate_cvariable_declarations(self, env, code, definition): 997 if env.is_cython_builtin: 998 return 999 for entry in env.var_entries: 1000 if (entry.in_cinclude or entry.in_closure or 1001 (entry.visibility == 'private' and 1002 not (entry.defined_in_pxd or entry.used))): 1003 continue 1004 1005 storage_class = None 1006 dll_linkage = None 1007 cname = None 1008 init = None 1009 1010 if entry.visibility == 'extern': 1011 storage_class = Naming.extern_c_macro 1012 dll_linkage = "DL_IMPORT" 1013 elif entry.visibility == 'public': 1014 storage_class = Naming.extern_c_macro 1015 if definition: 1016 dll_linkage = "DL_EXPORT" 1017 else: 1018 dll_linkage = "DL_IMPORT" 1019 elif entry.visibility == 'private': 1020 storage_class = "static" 1021 dll_linkage = None 1022 if entry.init is not None: 1023 init = entry.type.literal_code(entry.init) 1024 type = entry.type 1025 cname = entry.cname 1026 1027 if entry.defined_in_pxd and not definition: 1028 storage_class = "static" 1029 dll_linkage = None 1030 type = CPtrType(type) 1031 cname = env.mangle(Naming.varptr_prefix, entry.name) 1032 init = 0 1033 1034 if storage_class: 1035 code.put("%s " % storage_class) 1036 code.put(type.declaration_code( 1037 cname, dll_linkage = dll_linkage)) 1038 if init is not None: 1039 code.put_safe(" = %s" % init) 1040 code.putln(";") 1041 if entry.cname != cname: 1042 code.putln("#define %s (*%s)" % (entry.cname, cname)) 1043 1044 def generate_cfunction_declarations(self, env, code, definition): 1045 for entry in env.cfunc_entries: 1046 if entry.used or (entry.visibility == 'public' or entry.api): 1047 generate_cfunction_declaration(entry, env, code, definition) 1048 1049 def generate_variable_definitions(self, env, code): 1050 for entry in env.var_entries: 1051 if (not entry.in_cinclude and 1052 entry.visibility == "public"): 1053 code.put(entry.type.declaration_code(entry.cname)) 1054 if entry.init is not None: 1055 init = entry.type.literal_code(entry.init) 1056 code.put_safe(" = %s" % init) 1057 code.putln(";") 1058 1059 def generate_typeobj_definitions(self, env, code): 1060 full_module_name = env.qualified_name 1061 for entry in env.c_class_entries: 1062 #print "generate_typeobj_definitions:", entry.name 1063 #print "...visibility =", entry.visibility 1064 if entry.visibility != 'extern': 1065 type = entry.type 1066 scope = type.scope 1067 if scope: # could be None if there was an error 1068 self.generate_exttype_vtable(scope, code) 1069 self.generate_new_function(scope, code, entry) 1070 self.generate_dealloc_function(scope, code) 1071 if scope.needs_gc(): 1072 self.generate_traverse_function(scope, code, entry) 1073 if scope.needs_tp_clear(): 1074 self.generate_clear_function(scope, code, entry) 1075 if scope.defines_any(["__getitem__"]): 1076 self.generate_getitem_int_function(scope, code) 1077 if scope.defines_any(["__setitem__", "__delitem__"]): 1078 self.generate_ass_subscript_function(scope, code) 1079 if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]): 1080 warning(self.pos, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1) 1081 code.putln("#if PY_MAJOR_VERSION >= 3") 1082 code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") 1083 code.putln("#endif") 1084 if scope.defines_any(["__setslice__", "__delslice__"]): 1085 self.generate_ass_slice_function(scope, code) 1086 if scope.defines_any(["__getattr__","__getattribute__"]): 1087 self.generate_getattro_function(scope, code) 1088 if scope.defines_any(["__setattr__", "__delattr__"]): 1089 self.generate_setattro_function(scope, code) 1090 if scope.defines_any(["__get__"]): 1091 self.generate_descr_get_function(scope, code) 1092 if scope.defines_any(["__set__", "__delete__"]): 1093 self.generate_descr_set_function(scope, code) 1094 self.generate_property_accessors(scope, code) 1095 self.generate_method_table(scope, code) 1096 self.generate_getset_table(scope, code) 1097 self.generate_typeobj_definition(full_module_name, entry, code) 1098 1099 def generate_exttype_vtable(self, scope, code): 1100 # Generate the definition of an extension type's vtable. 1101 type = scope.parent_type 1102 if type.vtable_cname: 1103 code.putln("static struct %s %s;" % ( 1104 type.vtabstruct_cname, 1105 type.vtable_cname)) 1106 1107 def generate_self_cast(self, scope, code): 1108 type = scope.parent_type 1109 code.putln( 1110 "%s = (%s)o;" % ( 1111 type.declaration_code("p"), 1112 type.declaration_code(""))) 1113 1114 def generate_new_function(self, scope, code, cclass_entry): 1115 tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__') 1116 slot_func = scope.mangle_internal("tp_new") 1117 type = scope.parent_type 1118 base_type = type.base_type 1119 1120 have_entries, (py_attrs, py_buffers, memoryview_slices) = \ 1121 scope.get_refcounted_entries() 1122 is_final_type = scope.parent_type.is_final_type 1123 if scope.is_internal: 1124 # internal classes (should) never need None inits, normal zeroing will do 1125 py_attrs = [] 1126 cpp_class_attrs = [entry for entry in scope.var_entries 1127 if entry.type.is_cpp_class] 1128 1129 new_func_entry = scope.lookup_here("__new__") 1130 if base_type or (new_func_entry and new_func_entry.is_special 1131 and not new_func_entry.trivial_signature): 1132 unused_marker = '' 1133 else: 1134 unused_marker = 'CYTHON_UNUSED ' 1135 1136 if base_type: 1137 freelist_size = 0 # not currently supported 1138 else: 1139 freelist_size = scope.directives.get('freelist', 0) 1140 freelist_name = scope.mangle_internal(Naming.freelist_name) 1141 freecount_name = scope.mangle_internal(Naming.freecount_name) 1142 1143 decls = code.globalstate['decls'] 1144 decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" % 1145 slot_func) 1146 code.putln("") 1147 if freelist_size: 1148 code.putln("static %s[%d];" % ( 1149 scope.parent_type.declaration_code(freelist_name), 1150 freelist_size)) 1151 code.putln("static int %s = 0;" % freecount_name) 1152 code.putln("") 1153 code.putln( 1154 "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {" 1155 % (slot_func, unused_marker, unused_marker)) 1156 1157 need_self_cast = (type.vtabslot_cname or 1158 (py_buffers or memoryview_slices or py_attrs) or 1159 cpp_class_attrs) 1160 if need_self_cast: 1161 code.putln("%s;" % scope.parent_type.declaration_code("p")) 1162 if base_type: 1163 tp_new = TypeSlots.get_base_slot_function(scope, tp_slot) 1164 if tp_new is None: 1165 tp_new = "%s->tp_new" % base_type.typeptr_cname 1166 code.putln("PyObject *o = %s(t, a, k);" % tp_new) 1167 else: 1168 code.putln("PyObject *o;") 1169 if freelist_size: 1170 code.globalstate.use_utility_code( 1171 UtilityCode.load_cached("IncludeStringH", "StringTools.c")) 1172 if is_final_type: 1173 type_safety_check = '' 1174 else: 1175 type_safety_check = ' & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)' 1176 obj_struct = type.declaration_code("", deref=True) 1177 code.putln("if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % ( 1178 freecount_name, obj_struct, type_safety_check)) 1179 code.putln("o = (PyObject*)%s[--%s];" % ( 1180 freelist_name, freecount_name)) 1181 code.putln("memset(o, 0, sizeof(%s));" % obj_struct) 1182 code.putln("(void) PyObject_INIT(o, t);") 1183 if scope.needs_gc(): 1184 code.putln("PyObject_GC_Track(o);") 1185 code.putln("} else {") 1186 if not is_final_type: 1187 code.putln("if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {") 1188 code.putln("o = (*t->tp_alloc)(t, 0);") 1189 if not is_final_type: 1190 code.putln("} else {") 1191 code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple) 1192 code.putln("}") 1193 code.putln("if (unlikely(!o)) return 0;") 1194 if freelist_size and not base_type: 1195 code.putln('}') 1196 if need_self_cast: 1197 code.putln("p = %s;" % type.cast_code("o")) 1198 #if need_self_cast: 1199 # self.generate_self_cast(scope, code) 1200 if type.vtabslot_cname: 1201 vtab_base_type = type 1202 while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname: 1203 vtab_base_type = vtab_base_type.base_type 1204 if vtab_base_type is not type: 1205 struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname 1206 else: 1207 struct_type_cast = "" 1208 code.putln("p->%s = %s%s;" % ( 1209 type.vtabslot_cname, 1210 struct_type_cast, type.vtabptr_cname)) 1211 1212 for entry in cpp_class_attrs: 1213 code.putln("new((void*)&(p->%s)) %s();" % 1214 (entry.cname, entry.type.declaration_code(""))) 1215 1216 for entry in py_attrs: 1217 code.put_init_var_to_py_none(entry, "p->%s", nanny=False) 1218 1219 for entry in memoryview_slices: 1220 code.putln("p->%s.data = NULL;" % entry.cname) 1221 code.putln("p->%s.memview = NULL;" % entry.cname) 1222 1223 for entry in py_buffers: 1224 code.putln("p->%s.obj = NULL;" % entry.cname) 1225 1226 if cclass_entry.cname == '__pyx_memoryviewslice': 1227 code.putln("p->from_slice.memview = NULL;") 1228 1229 if new_func_entry and new_func_entry.is_special: 1230 if new_func_entry.trivial_signature: 1231 cinit_args = "o, %s, NULL" % Naming.empty_tuple 1232 else: 1233 cinit_args = "o, a, k" 1234 code.putln( 1235 "if (unlikely(%s(%s) < 0)) {" % 1236 (new_func_entry.func_cname, cinit_args)) 1237 code.put_decref_clear("o", py_object_type, nanny=False) 1238 code.putln( 1239 "}") 1240 code.putln( 1241 "return o;") 1242 code.putln( 1243 "}") 1244 1245 def generate_dealloc_function(self, scope, code): 1246 tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__') 1247 slot_func = scope.mangle_internal("tp_dealloc") 1248 base_type = scope.parent_type.base_type 1249 if tp_slot.slot_code(scope) != slot_func: 1250 return # never used 1251 1252 slot_func_cname = scope.mangle_internal("tp_dealloc") 1253 code.putln("") 1254 code.putln( 1255 "static void %s(PyObject *o) {" % slot_func_cname) 1256 1257 is_final_type = scope.parent_type.is_final_type 1258 needs_gc = scope.needs_gc() 1259 1260 weakref_slot = scope.lookup_here("__weakref__") 1261 if weakref_slot not in scope.var_entries: 1262 weakref_slot = None 1263 1264 _, (py_attrs, _, memoryview_slices) = scope.get_refcounted_entries() 1265 cpp_class_attrs = [entry for entry in scope.var_entries 1266 if entry.type.is_cpp_class] 1267 1268 if py_attrs or cpp_class_attrs or memoryview_slices or weakref_slot: 1269 self.generate_self_cast(scope, code) 1270 1271 if not is_final_type: 1272 # in Py3.4+, call tp_finalize() as early as possible 1273 code.putln("#if PY_VERSION_HEX >= 0x030400a1") 1274 if needs_gc: 1275 finalised_check = '!_PyGC_FINALIZED(o)' 1276 else: 1277 finalised_check = ( 1278 '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))') 1279 code.putln("if (unlikely(Py_TYPE(o)->tp_finalize) && %s) {" % 1280 finalised_check) 1281 # if instance was resurrected by finaliser, return 1282 code.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;") 1283 code.putln("}") 1284 code.putln("#endif") 1285 1286 if needs_gc: 1287 # We must mark this object as (gc) untracked while tearing 1288 # it down, lest the garbage collection is invoked while 1289 # running this destructor. 1290 code.putln("PyObject_GC_UnTrack(o);") 1291 1292 # call the user's __dealloc__ 1293 self.generate_usr_dealloc_call(scope, code) 1294 1295 if weakref_slot: 1296 code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);") 1297 1298 for entry in cpp_class_attrs: 1299 code.putln("__Pyx_call_destructor(&p->%s);" % entry.cname) 1300 1301 for entry in py_attrs: 1302 code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False, 1303 clear_before_decref=True) 1304 1305 for entry in memoryview_slices: 1306 code.put_xdecref_memoryviewslice("p->%s" % entry.cname, 1307 have_gil=True) 1308 1309 if base_type: 1310 if needs_gc: 1311 # The base class deallocator probably expects this to be tracked, 1312 # so undo the untracking above. 1313 if base_type.scope and base_type.scope.needs_gc(): 1314 code.putln("PyObject_GC_Track(o);") 1315 else: 1316 code.putln("#if CYTHON_COMPILING_IN_CPYTHON") 1317 code.putln("if (PyType_IS_GC(Py_TYPE(o)->tp_base))") 1318 code.putln("#endif") 1319 code.putln("PyObject_GC_Track(o);") 1320 1321 tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot) 1322 if tp_dealloc is not None: 1323 code.putln("%s(o);" % tp_dealloc) 1324 elif base_type.is_builtin_type: 1325 code.putln("%s->tp_dealloc(o);" % base_type.typeptr_cname) 1326 else: 1327 # This is an externally defined type. Calling through the 1328 # cimported base type pointer directly interacts badly with 1329 # the module cleanup, which may already have cleared it. 1330 # In that case, fall back to traversing the type hierarchy. 1331 base_cname = base_type.typeptr_cname 1332 code.putln("if (likely(%s)) %s->tp_dealloc(o); " 1333 "else __Pyx_call_next_tp_dealloc(o, %s);" % ( 1334 base_cname, base_cname, slot_func_cname)) 1335 code.globalstate.use_utility_code( 1336 UtilityCode.load_cached("CallNextTpDealloc", "ExtensionTypes.c")) 1337 else: 1338 freelist_size = scope.directives.get('freelist', 0) 1339 if freelist_size: 1340 freelist_name = scope.mangle_internal(Naming.freelist_name) 1341 freecount_name = scope.mangle_internal(Naming.freecount_name) 1342 1343 if is_final_type: 1344 type_safety_check = '' 1345 else: 1346 type_safety_check = ( 1347 ' & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)') 1348 1349 type = scope.parent_type 1350 code.putln("if (CYTHON_COMPILING_IN_CPYTHON && ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))%s)) {" % ( 1351 freecount_name, freelist_size, type.declaration_code("", deref=True), 1352 type_safety_check)) 1353 code.putln("%s[%s++] = %s;" % ( 1354 freelist_name, freecount_name, type.cast_code("o"))) 1355 code.putln("} else {") 1356 code.putln("(*Py_TYPE(o)->tp_free)(o);") 1357 if freelist_size: 1358 code.putln("}") 1359 code.putln( 1360 "}") 1361 1362 def generate_usr_dealloc_call(self, scope, code): 1363 entry = scope.lookup_here("__dealloc__") 1364 if not entry: 1365 return 1366 1367 code.putln("{") 1368 code.putln("PyObject *etype, *eval, *etb;") 1369 code.putln("PyErr_Fetch(&etype, &eval, &etb);") 1370 code.putln("++Py_REFCNT(o);") 1371 code.putln("%s(o);" % entry.func_cname) 1372 code.putln("--Py_REFCNT(o);") 1373 code.putln("PyErr_Restore(etype, eval, etb);") 1374 code.putln("}") 1375 1376 def generate_traverse_function(self, scope, code, cclass_entry): 1377 tp_slot = TypeSlots.GCDependentSlot("tp_traverse") 1378 slot_func = scope.mangle_internal("tp_traverse") 1379 base_type = scope.parent_type.base_type 1380 if tp_slot.slot_code(scope) != slot_func: 1381 return # never used 1382 code.putln("") 1383 code.putln( 1384 "static int %s(PyObject *o, visitproc v, void *a) {" 1385 % slot_func) 1386 1387 have_entries, (py_attrs, py_buffers, memoryview_slices) = ( 1388 scope.get_refcounted_entries(include_gc_simple=False)) 1389 1390 if base_type or py_attrs: 1391 code.putln("int e;") 1392 1393 if py_attrs or py_buffers: 1394 self.generate_self_cast(scope, code) 1395 1396 if base_type: 1397 # want to call it explicitly if possible so inlining can be performed 1398 static_call = TypeSlots.get_base_slot_function(scope, tp_slot) 1399 if static_call: 1400 code.putln("e = %s(o, v, a); if (e) return e;" % static_call) 1401 elif base_type.is_builtin_type: 1402 base_cname = base_type.typeptr_cname 1403 code.putln("if (!%s->tp_traverse); else { e = %s->tp_traverse(o,v,a); if (e) return e; }" % ( 1404 base_cname, base_cname)) 1405 else: 1406 # This is an externally defined type. Calling through the 1407 # cimported base type pointer directly interacts badly with 1408 # the module cleanup, which may already have cleared it. 1409 # In that case, fall back to traversing the type hierarchy. 1410 base_cname = base_type.typeptr_cname 1411 code.putln("e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % ( 1412 base_cname, base_cname, base_cname, slot_func)) 1413 code.globalstate.use_utility_code( 1414 UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c")) 1415 1416 for entry in py_attrs: 1417 var_code = "p->%s" % entry.cname 1418 code.putln( 1419 "if (%s) {" 1420 % var_code) 1421 if entry.type.is_extension_type: 1422 var_code = "((PyObject*)%s)" % var_code 1423 code.putln( 1424 "e = (*v)(%s, a); if (e) return e;" 1425 % var_code) 1426 code.putln( 1427 "}") 1428 1429 # Traverse buffer exporting objects. 1430 # Note: not traversing memoryview attributes of memoryview slices! 1431 # When triggered by the GC, it would cause multiple visits (gc_refs 1432 # subtractions which is not matched by its reference count!) 1433 for entry in py_buffers: 1434 cname = entry.cname + ".obj" 1435 code.putln("if (p->%s) {" % cname) 1436 code.putln( "e = (*v)(p->%s, a); if (e) return e;" % cname) 1437 code.putln("}") 1438 1439 code.putln( 1440 "return 0;") 1441 code.putln( 1442 "}") 1443 1444 def generate_clear_function(self, scope, code, cclass_entry): 1445 tp_slot = TypeSlots.GCDependentSlot("tp_clear") 1446 slot_func = scope.mangle_internal("tp_clear") 1447 base_type = scope.parent_type.base_type 1448 if tp_slot.slot_code(scope) != slot_func: 1449 return # never used 1450 1451 have_entries, (py_attrs, py_buffers, memoryview_slices) = ( 1452 scope.get_refcounted_entries(include_gc_simple=False)) 1453 1454 if py_attrs or py_buffers or base_type: 1455 unused = '' 1456 else: 1457 unused = 'CYTHON_UNUSED ' 1458 1459 code.putln("") 1460 code.putln("static int %s(%sPyObject *o) {" % (slot_func, unused)) 1461 1462 if py_attrs and Options.clear_to_none: 1463 code.putln("PyObject* tmp;") 1464 1465 if py_attrs or py_buffers: 1466 self.generate_self_cast(scope, code) 1467 1468 if base_type: 1469 # want to call it explicitly if possible so inlining can be performed 1470 static_call = TypeSlots.get_base_slot_function(scope, tp_slot) 1471 if static_call: 1472 code.putln("%s(o);" % static_call) 1473 elif base_type.is_builtin_type: 1474 base_cname = base_type.typeptr_cname 1475 code.putln("if (!%s->tp_clear); else %s->tp_clear(o);" % ( 1476 base_cname, base_cname)) 1477 else: 1478 # This is an externally defined type. Calling through the 1479 # cimported base type pointer directly interacts badly with 1480 # the module cleanup, which may already have cleared it. 1481 # In that case, fall back to traversing the type hierarchy. 1482 base_cname = base_type.typeptr_cname 1483 code.putln("if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % ( 1484 base_cname, base_cname, base_cname, slot_func)) 1485 code.globalstate.use_utility_code( 1486 UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c")) 1487 1488 if Options.clear_to_none: 1489 for entry in py_attrs: 1490 name = "p->%s" % entry.cname 1491 code.putln("tmp = ((PyObject*)%s);" % name) 1492 if entry.is_declared_generic: 1493 code.put_init_to_py_none(name, py_object_type, nanny=False) 1494 else: 1495 code.put_init_to_py_none(name, entry.type, nanny=False) 1496 code.putln("Py_XDECREF(tmp);") 1497 else: 1498 for entry in py_attrs: 1499 code.putln("Py_CLEAR(p->%s);" % entry.cname) 1500 1501 for entry in py_buffers: 1502 # Note: shouldn't this call __Pyx_ReleaseBuffer ?? 1503 code.putln("Py_CLEAR(p->%s.obj);" % entry.cname) 1504 1505 if cclass_entry.cname == '__pyx_memoryviewslice': 1506 code.putln("__PYX_XDEC_MEMVIEW(&p->from_slice, 1);") 1507 1508 code.putln( 1509 "return 0;") 1510 code.putln( 1511 "}") 1512 1513 def generate_getitem_int_function(self, scope, code): 1514 # This function is put into the sq_item slot when 1515 # a __getitem__ method is present. It converts its 1516 # argument to a Python integer and calls mp_subscript. 1517 code.putln( 1518 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" % 1519 scope.mangle_internal("sq_item")) 1520 code.putln( 1521 "PyObject *r;") 1522 code.putln( 1523 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;") 1524 code.putln( 1525 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);") 1526 code.putln( 1527 "Py_DECREF(x);") 1528 code.putln( 1529 "return r;") 1530 code.putln( 1531 "}") 1532 1533 def generate_ass_subscript_function(self, scope, code): 1534 # Setting and deleting an item are both done through 1535 # the ass_subscript method, so we dispatch to user's __setitem__ 1536 # or __delitem__, or raise an exception. 1537 base_type = scope.parent_type.base_type 1538 set_entry = scope.lookup_here("__setitem__") 1539 del_entry = scope.lookup_here("__delitem__") 1540 code.putln("") 1541 code.putln( 1542 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % 1543 scope.mangle_internal("mp_ass_subscript")) 1544 code.putln( 1545 "if (v) {") 1546 if set_entry: 1547 code.putln( 1548 "return %s(o, i, v);" % 1549 set_entry.func_cname) 1550 else: 1551 self.generate_guarded_basetype_call( 1552 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) 1553 code.putln( 1554 "PyErr_Format(PyExc_NotImplementedError,") 1555 code.putln( 1556 ' "Subscript assignment not supported by %.200s", Py_TYPE(o)->tp_name);') 1557 code.putln( 1558 "return -1;") 1559 code.putln( 1560 "}") 1561 code.putln( 1562 "else {") 1563 if del_entry: 1564 code.putln( 1565 "return %s(o, i);" % 1566 del_entry.func_cname) 1567 else: 1568 self.generate_guarded_basetype_call( 1569 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) 1570 code.putln( 1571 "PyErr_Format(PyExc_NotImplementedError,") 1572 code.putln( 1573 ' "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);') 1574 code.putln( 1575 "return -1;") 1576 code.putln( 1577 "}") 1578 code.putln( 1579 "}") 1580 1581 def generate_guarded_basetype_call( 1582 self, base_type, substructure, slot, args, code): 1583 if base_type: 1584 base_tpname = base_type.typeptr_cname 1585 if substructure: 1586 code.putln( 1587 "if (%s->%s && %s->%s->%s)" % ( 1588 base_tpname, substructure, base_tpname, substructure, slot)) 1589 code.putln( 1590 " return %s->%s->%s(%s);" % ( 1591 base_tpname, substructure, slot, args)) 1592 else: 1593 code.putln( 1594 "if (%s->%s)" % ( 1595 base_tpname, slot)) 1596 code.putln( 1597 " return %s->%s(%s);" % ( 1598 base_tpname, slot, args)) 1599 1600 def generate_ass_slice_function(self, scope, code): 1601 # Setting and deleting a slice are both done through 1602 # the ass_slice method, so we dispatch to user's __setslice__ 1603 # or __delslice__, or raise an exception. 1604 base_type = scope.parent_type.base_type 1605 set_entry = scope.lookup_here("__setslice__") 1606 del_entry = scope.lookup_here("__delslice__") 1607 code.putln("") 1608 code.putln( 1609 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" % 1610 scope.mangle_internal("sq_ass_slice")) 1611 code.putln( 1612 "if (v) {") 1613 if set_entry: 1614 code.putln( 1615 "return %s(o, i, j, v);" % 1616 set_entry.func_cname) 1617 else: 1618 self.generate_guarded_basetype_call( 1619 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) 1620 code.putln( 1621 "PyErr_Format(PyExc_NotImplementedError,") 1622 code.putln( 1623 ' "2-element slice assignment not supported by %.200s", Py_TYPE(o)->tp_name);') 1624 code.putln( 1625 "return -1;") 1626 code.putln( 1627 "}") 1628 code.putln( 1629 "else {") 1630 if del_entry: 1631 code.putln( 1632 "return %s(o, i, j);" % 1633 del_entry.func_cname) 1634 else: 1635 self.generate_guarded_basetype_call( 1636 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) 1637 code.putln( 1638 "PyErr_Format(PyExc_NotImplementedError,") 1639 code.putln( 1640 ' "2-element slice deletion not supported by %.200s", Py_TYPE(o)->tp_name);') 1641 code.putln( 1642 "return -1;") 1643 code.putln( 1644 "}") 1645 code.putln( 1646 "}") 1647 1648 def generate_getattro_function(self, scope, code): 1649 # First try to get the attribute using __getattribute__, if defined, or 1650 # PyObject_GenericGetAttr. 1651 # 1652 # If that raises an AttributeError, call the __getattr__ if defined. 1653 # 1654 # In both cases, defined can be in this class, or any base class. 1655 def lookup_here_or_base(n,type=None): 1656 # Recursive lookup 1657 if type is None: 1658 type = scope.parent_type 1659 r = type.scope.lookup_here(n) 1660 if r is None and \ 1661 type.base_type is not None: 1662 return lookup_here_or_base(n,type.base_type) 1663 else: 1664 return r 1665 getattr_entry = lookup_here_or_base("__getattr__") 1666 getattribute_entry = lookup_here_or_base("__getattribute__") 1667 code.putln("") 1668 code.putln( 1669 "static PyObject *%s(PyObject *o, PyObject *n) {" 1670 % scope.mangle_internal("tp_getattro")) 1671 if getattribute_entry is not None: 1672 code.putln( 1673 "PyObject *v = %s(o, n);" % 1674 getattribute_entry.func_cname) 1675 else: 1676 code.putln( 1677 "PyObject *v = PyObject_GenericGetAttr(o, n);") 1678 if getattr_entry is not None: 1679 code.putln( 1680 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {") 1681 code.putln( 1682 "PyErr_Clear();") 1683 code.putln( 1684 "v = %s(o, n);" % 1685 getattr_entry.func_cname) 1686 code.putln( 1687 "}") 1688 code.putln( 1689 "return v;") 1690 code.putln( 1691 "}") 1692 1693 def generate_setattro_function(self, scope, code): 1694 # Setting and deleting an attribute are both done through 1695 # the setattro method, so we dispatch to user's __setattr__ 1696 # or __delattr__ or fall back on PyObject_GenericSetAttr. 1697 base_type = scope.parent_type.base_type 1698 set_entry = scope.lookup_here("__setattr__") 1699 del_entry = scope.lookup_here("__delattr__") 1700 code.putln("") 1701 code.putln( 1702 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" % 1703 scope.mangle_internal("tp_setattro")) 1704 code.putln( 1705 "if (v) {") 1706 if set_entry: 1707 code.putln( 1708 "return %s(o, n, v);" % 1709 set_entry.func_cname) 1710 else: 1711 self.generate_guarded_basetype_call( 1712 base_type, None, "tp_setattro", "o, n, v", code) 1713 code.putln( 1714 "return PyObject_GenericSetAttr(o, n, v);") 1715 code.putln( 1716 "}") 1717 code.putln( 1718 "else {") 1719 if del_entry: 1720 code.putln( 1721 "return %s(o, n);" % 1722 del_entry.func_cname) 1723 else: 1724 self.generate_guarded_basetype_call( 1725 base_type, None, "tp_setattro", "o, n, v", code) 1726 code.putln( 1727 "return PyObject_GenericSetAttr(o, n, 0);") 1728 code.putln( 1729 "}") 1730 code.putln( 1731 "}") 1732 1733 def generate_descr_get_function(self, scope, code): 1734 # The __get__ function of a descriptor object can be 1735 # called with NULL for the second or third arguments 1736 # under some circumstances, so we replace them with 1737 # None in that case. 1738 user_get_entry = scope.lookup_here("__get__") 1739 code.putln("") 1740 code.putln( 1741 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" % 1742 scope.mangle_internal("tp_descr_get")) 1743 code.putln( 1744 "PyObject *r = 0;") 1745 code.putln( 1746 "if (!i) i = Py_None;") 1747 code.putln( 1748 "if (!c) c = Py_None;") 1749 #code.put_incref("i", py_object_type) 1750 #code.put_incref("c", py_object_type) 1751 code.putln( 1752 "r = %s(o, i, c);" % 1753 user_get_entry.func_cname) 1754 #code.put_decref("i", py_object_type) 1755 #code.put_decref("c", py_object_type) 1756 code.putln( 1757 "return r;") 1758 code.putln( 1759 "}") 1760 1761 def generate_descr_set_function(self, scope, code): 1762 # Setting and deleting are both done through the __set__ 1763 # method of a descriptor, so we dispatch to user's __set__ 1764 # or __delete__ or raise an exception. 1765 base_type = scope.parent_type.base_type 1766 user_set_entry = scope.lookup_here("__set__") 1767 user_del_entry = scope.lookup_here("__delete__") 1768 code.putln("") 1769 code.putln( 1770 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % 1771 scope.mangle_internal("tp_descr_set")) 1772 code.putln( 1773 "if (v) {") 1774 if user_set_entry: 1775 code.putln( 1776 "return %s(o, i, v);" % 1777 user_set_entry.func_cname) 1778 else: 1779 self.generate_guarded_basetype_call( 1780 base_type, None, "tp_descr_set", "o, i, v", code) 1781 code.putln( 1782 'PyErr_SetString(PyExc_NotImplementedError, "__set__");') 1783 code.putln( 1784 "return -1;") 1785 code.putln( 1786 "}") 1787 code.putln( 1788 "else {") 1789 if user_del_entry: 1790 code.putln( 1791 "return %s(o, i);" % 1792 user_del_entry.func_cname) 1793 else: 1794 self.generate_guarded_basetype_call( 1795 base_type, None, "tp_descr_set", "o, i, v", code) 1796 code.putln( 1797 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");') 1798 code.putln( 1799 "return -1;") 1800 code.putln( 1801 "}") 1802 code.putln( 1803 "}") 1804 1805 def generate_property_accessors(self, cclass_scope, code): 1806 for entry in cclass_scope.property_entries: 1807 property_scope = entry.scope 1808 if property_scope.defines_any(["__get__"]): 1809 self.generate_property_get_function(entry, code) 1810 if property_scope.defines_any(["__set__", "__del__"]): 1811 self.generate_property_set_function(entry, code) 1812 1813 def generate_property_get_function(self, property_entry, code): 1814 property_scope = property_entry.scope 1815 property_entry.getter_cname = property_scope.parent_scope.mangle( 1816 Naming.prop_get_prefix, property_entry.name) 1817 get_entry = property_scope.lookup_here("__get__") 1818 code.putln("") 1819 code.putln( 1820 "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % 1821 property_entry.getter_cname) 1822 code.putln( 1823 "return %s(o);" % 1824 get_entry.func_cname) 1825 code.putln( 1826 "}") 1827 1828 def generate_property_set_function(self, property_entry, code): 1829 property_scope = property_entry.scope 1830 property_entry.setter_cname = property_scope.parent_scope.mangle( 1831 Naming.prop_set_prefix, property_entry.name) 1832 set_entry = property_scope.lookup_here("__set__") 1833 del_entry = property_scope.lookup_here("__del__") 1834 code.putln("") 1835 code.putln( 1836 "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" % 1837 property_entry.setter_cname) 1838 code.putln( 1839 "if (v) {") 1840 if set_entry: 1841 code.putln( 1842 "return %s(o, v);" % 1843 set_entry.func_cname) 1844 else: 1845 code.putln( 1846 'PyErr_SetString(PyExc_NotImplementedError, "__set__");') 1847 code.putln( 1848 "return -1;") 1849 code.putln( 1850 "}") 1851 code.putln( 1852 "else {") 1853 if del_entry: 1854 code.putln( 1855 "return %s(o);" % 1856 del_entry.func_cname) 1857 else: 1858 code.putln( 1859 'PyErr_SetString(PyExc_NotImplementedError, "__del__");') 1860 code.putln( 1861 "return -1;") 1862 code.putln( 1863 "}") 1864 code.putln( 1865 "}") 1866 1867 def generate_typeobj_definition(self, modname, entry, code): 1868 type = entry.type 1869 scope = type.scope 1870 for suite in TypeSlots.substructures: 1871 suite.generate_substructure(scope, code) 1872 code.putln("") 1873 if entry.visibility == 'public': 1874 header = "DL_EXPORT(PyTypeObject) %s = {" 1875 else: 1876 header = "static PyTypeObject %s = {" 1877 #code.putln(header % scope.parent_type.typeobj_cname) 1878 code.putln(header % type.typeobj_cname) 1879 code.putln( 1880 "PyVarObject_HEAD_INIT(0, 0)") 1881 code.putln( 1882 '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % ( 1883 self.full_module_name, scope.class_name)) 1884 if type.typedef_flag: 1885 objstruct = type.objstruct_cname 1886 else: 1887 objstruct = "struct %s" % type.objstruct_cname 1888 code.putln( 1889 "sizeof(%s), /*tp_basicsize*/" % 1890 objstruct) 1891 code.putln( 1892 "0, /*tp_itemsize*/") 1893 for slot in TypeSlots.slot_table: 1894 slot.generate(scope, code) 1895 code.putln( 1896 "};") 1897 1898 def generate_method_table(self, env, code): 1899 if env.is_c_class_scope and not env.pyfunc_entries: 1900 return 1901 code.putln("") 1902 code.putln( 1903 "static PyMethodDef %s[] = {" % 1904 env.method_table_cname) 1905 for entry in env.pyfunc_entries: 1906 if not entry.fused_cfunction: 1907 code.put_pymethoddef(entry, ",") 1908 code.putln( 1909 "{0, 0, 0, 0}") 1910 code.putln( 1911 "};") 1912 1913 def generate_getset_table(self, env, code): 1914 if env.property_entries: 1915 code.putln("") 1916 code.putln( 1917 "static struct PyGetSetDef %s[] = {" % 1918 env.getset_table_cname) 1919 for entry in env.property_entries: 1920 if entry.doc: 1921 doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc) 1922 else: 1923 doc_code = "0" 1924 code.putln( 1925 '{(char *)"%s", %s, %s, %s, 0},' % ( 1926 entry.name, 1927 entry.getter_cname or "0", 1928 entry.setter_cname or "0", 1929 doc_code)) 1930 code.putln( 1931 "{0, 0, 0, 0, 0}") 1932 code.putln( 1933 "};") 1934 1935 def generate_import_star(self, env, code): 1936 env.use_utility_code(streq_utility_code) 1937 code.putln() 1938 code.putln("static char* %s_type_names[] = {" % Naming.import_star) 1939 for name, entry in sorted(env.entries.items()): 1940 if entry.is_type: 1941 code.putln('"%s",' % name) 1942 code.putln("0") 1943 code.putln("};") 1944 code.putln() 1945 code.enter_cfunc_scope() # as we need labels 1946 code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set) 1947 code.putln("char** type_name = %s_type_names;" % Naming.import_star) 1948 code.putln("while (*type_name) {") 1949 code.putln("if (__Pyx_StrEq(name, *type_name)) {") 1950 code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);') 1951 code.putln('goto bad;') 1952 code.putln("}") 1953 code.putln("type_name++;") 1954 code.putln("}") 1955 old_error_label = code.new_error_label() 1956 code.putln("if (0);") # so the first one can be "else if" 1957 for name, entry in env.entries.items(): 1958 if entry.is_cglobal and entry.used: 1959 code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name) 1960 if entry.type.is_pyobject: 1961 if entry.type.is_extension_type or entry.type.is_builtin_type: 1962 code.putln("if (!(%s)) %s;" % ( 1963 entry.type.type_test_code("o"), 1964 code.error_goto(entry.pos))) 1965 code.putln("Py_INCREF(o);") 1966 code.put_decref(entry.cname, entry.type, nanny=False) 1967 code.putln("%s = %s;" % ( 1968 entry.cname, 1969 PyrexTypes.typecast(entry.type, py_object_type, "o"))) 1970 elif entry.type.from_py_function: 1971 rhs = "%s(o)" % entry.type.from_py_function 1972 if entry.type.is_enum: 1973 rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs) 1974 code.putln("%s = %s; if (%s) %s;" % ( 1975 entry.cname, 1976 rhs, 1977 entry.type.error_condition(entry.cname), 1978 code.error_goto(entry.pos))) 1979 else: 1980 code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type)) 1981 code.putln(code.error_goto(entry.pos)) 1982 code.putln("}") 1983 code.putln("else {") 1984 code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname) 1985 code.putln("}") 1986 code.putln("return 0;") 1987 if code.label_used(code.error_label): 1988 code.put_label(code.error_label) 1989 # This helps locate the offending name. 1990 code.put_add_traceback(self.full_module_name) 1991 code.error_label = old_error_label 1992 code.putln("bad:") 1993 code.putln("return -1;") 1994 code.putln("}") 1995 code.putln(import_star_utility_code) 1996 code.exit_cfunc_scope() # done with labels 1997 1998 def generate_module_init_func(self, imported_modules, env, code): 1999 code.enter_cfunc_scope() 2000 code.putln("") 2001 header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name 2002 header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name 2003 code.putln("#if PY_MAJOR_VERSION < 3") 2004 code.putln("%s; /*proto*/" % header2) 2005 code.putln(header2) 2006 code.putln("#else") 2007 code.putln("%s; /*proto*/" % header3) 2008 code.putln(header3) 2009 code.putln("#endif") 2010 code.putln("{") 2011 tempdecl_code = code.insertion_point() 2012 2013 code.put_declare_refcount_context() 2014 code.putln("#if CYTHON_REFNANNY") 2015 code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");") 2016 code.putln("if (!__Pyx_RefNanny) {") 2017 code.putln(" PyErr_Clear();") 2018 code.putln(" __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");") 2019 code.putln(" if (!__Pyx_RefNanny)") 2020 code.putln(" Py_FatalError(\"failed to import 'refnanny' module\");") 2021 code.putln("}") 2022 code.putln("#endif") 2023 code.put_setup_refcount_context(header3) 2024 2025 env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c")) 2026 code.putln("if ( __Pyx_check_binary_version() < 0) %s" % code.error_goto(self.pos)) 2027 2028 code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos))) 2029 code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos))) 2030 2031 code.putln("#ifdef __Pyx_CyFunction_USED") 2032 code.putln("if (__Pyx_CyFunction_init() < 0) %s" % code.error_goto(self.pos)) 2033 code.putln("#endif") 2034 2035 code.putln("#ifdef __Pyx_FusedFunction_USED") 2036 code.putln("if (__pyx_FusedFunction_init() < 0) %s" % code.error_goto(self.pos)) 2037 code.putln("#endif") 2038 2039 code.putln("#ifdef __Pyx_Generator_USED") 2040 code.putln("if (__pyx_Generator_init() < 0) %s" % code.error_goto(self.pos)) 2041 code.putln("#endif") 2042 2043 code.putln("/*--- Library function declarations ---*/") 2044 env.generate_library_function_declarations(code) 2045 2046 code.putln("/*--- Threads initialization code ---*/") 2047 code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS") 2048 code.putln("#ifdef WITH_THREAD /* Python build with threading support? */") 2049 code.putln("PyEval_InitThreads();") 2050 code.putln("#endif") 2051 code.putln("#endif") 2052 2053 code.putln("/*--- Module creation code ---*/") 2054 self.generate_module_creation_code(env, code) 2055 2056 code.putln("/*--- Initialize various global constants etc. ---*/") 2057 code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos)) 2058 2059 code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)") 2060 code.putln("if (__Pyx_init_sys_getdefaultencoding_params() < 0) %s" % code.error_goto(self.pos)) 2061 code.putln("#endif") 2062 2063 __main__name = code.globalstate.get_py_string_const( 2064 EncodedString("__main__"), identifier=True) 2065 code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))) 2066 code.putln( 2067 'if (__Pyx_SetAttrString(%s, "__name__", %s) < 0) %s;' % ( 2068 env.module_cname, 2069 __main__name.cname, 2070 code.error_goto(self.pos))) 2071 code.putln("}") 2072 2073 # set up __file__ and __path__, then add the module to sys.modules 2074 self.generate_module_import_setup(env, code) 2075 2076 if Options.cache_builtins: 2077 code.putln("/*--- Builtin init code ---*/") 2078 code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()", self.pos)) 2079 2080 code.putln("/*--- Constants init code ---*/") 2081 code.putln(code.error_goto_if_neg("__Pyx_InitCachedConstants()", self.pos)) 2082 2083 code.putln("/*--- Global init code ---*/") 2084 self.generate_global_init_code(env, code) 2085 2086 code.putln("/*--- Variable export code ---*/") 2087 self.generate_c_variable_export_code(env, code) 2088 2089 code.putln("/*--- Function export code ---*/") 2090 self.generate_c_function_export_code(env, code) 2091 2092 code.putln("/*--- Type init code ---*/") 2093 self.generate_type_init_code(env, code) 2094 2095 code.putln("/*--- Type import code ---*/") 2096 for module in imported_modules: 2097 self.generate_type_import_code_for_module(module, env, code) 2098 2099 code.putln("/*--- Variable import code ---*/") 2100 for module in imported_modules: 2101 self.generate_c_variable_import_code_for_module(module, env, code) 2102 2103 code.putln("/*--- Function import code ---*/") 2104 for module in imported_modules: 2105 self.specialize_fused_types(module) 2106 self.generate_c_function_import_code_for_module(module, env, code) 2107 2108 code.putln("/*--- Execution code ---*/") 2109 code.mark_pos(None) 2110 2111 self.body.generate_execution_code(code) 2112 2113 if Options.generate_cleanup_code: 2114 code.globalstate.use_utility_code( 2115 UtilityCode.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c")) 2116 code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos)) 2117 2118 code.put_goto(code.return_label) 2119 code.put_label(code.error_label) 2120 for cname, type in code.funcstate.all_managed_temps(): 2121 code.put_xdecref(cname, type) 2122 code.putln('if (%s) {' % env.module_cname) 2123 code.put_add_traceback("init %s" % env.qualified_name) 2124 env.use_utility_code(Nodes.traceback_utility_code) 2125 code.put_decref_clear(env.module_cname, py_object_type, nanny=False) 2126 code.putln('} else if (!PyErr_Occurred()) {') 2127 code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name) 2128 code.putln('}') 2129 code.put_label(code.return_label) 2130 2131 code.put_finish_refcount_context() 2132 2133 code.putln("#if PY_MAJOR_VERSION < 3") 2134 code.putln("return;") 2135 code.putln("#else") 2136 code.putln("return %s;" % env.module_cname) 2137 code.putln("#endif") 2138 code.putln('}') 2139 2140 tempdecl_code.put_temp_declarations(code.funcstate) 2141 2142 code.exit_cfunc_scope() 2143 2144 def generate_module_import_setup(self, env, code): 2145 module_path = env.directives['set_initial_path'] 2146 if module_path == 'SOURCEFILE': 2147 module_path = self.pos[0].filename 2148 2149 if module_path: 2150 code.putln('if (__Pyx_SetAttrString(%s, "__file__", %s) < 0) %s;' % ( 2151 env.module_cname, 2152 code.globalstate.get_py_string_const( 2153 EncodedString(decode_filename(module_path))).cname, 2154 code.error_goto(self.pos))) 2155 2156 if env.is_package: 2157 # set __path__ to mark the module as package 2158 temp = code.funcstate.allocate_temp(py_object_type, True) 2159 code.putln('%s = Py_BuildValue("[O]", %s); %s' % ( 2160 temp, 2161 code.globalstate.get_py_string_const( 2162 EncodedString(decode_filename( 2163 os.path.dirname(module_path)))).cname, 2164 code.error_goto_if_null(temp, self.pos))) 2165 code.put_gotref(temp) 2166 code.putln( 2167 'if (__Pyx_SetAttrString(%s, "__path__", %s) < 0) %s;' % ( 2168 env.module_cname, temp, code.error_goto(self.pos))) 2169 code.put_decref_clear(temp, py_object_type) 2170 code.funcstate.release_temp(temp) 2171 2172 elif env.is_package: 2173 # packages require __path__, so all we can do is try to figure 2174 # out the module path at runtime by rerunning the import lookup 2175 package_name, _ = self.full_module_name.rsplit('.', 1) 2176 if '.' in package_name: 2177 parent_name = '"%s"' % (package_name.rsplit('.', 1)[0],) 2178 else: 2179 parent_name = 'NULL' 2180 code.globalstate.use_utility_code(UtilityCode.load( 2181 "SetPackagePathFromImportLib", "ImportExport.c")) 2182 code.putln(code.error_goto_if_neg( 2183 '__Pyx_SetPackagePathFromImportLib(%s, %s)' % ( 2184 parent_name, 2185 code.globalstate.get_py_string_const( 2186 EncodedString(env.module_name)).cname), 2187 self.pos)) 2188 2189 # CPython may not have put us into sys.modules yet, but relative imports and reimports require it 2190 fq_module_name = self.full_module_name 2191 if fq_module_name.endswith('.__init__'): 2192 fq_module_name = fq_module_name[:-len('.__init__')] 2193 code.putln("#if PY_MAJOR_VERSION >= 3") 2194 code.putln("{") 2195 code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" % 2196 code.error_goto_if_null("modules", self.pos)) 2197 code.putln('if (!PyDict_GetItemString(modules, "%s")) {' % fq_module_name) 2198 code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, "%s", %s)' % ( 2199 fq_module_name, env.module_cname), self.pos)) 2200 code.putln("}") 2201 code.putln("}") 2202 code.putln("#endif") 2203 2204 def generate_module_cleanup_func(self, env, code): 2205 if not Options.generate_cleanup_code: 2206 return 2207 2208 code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' % 2209 Naming.cleanup_cname) 2210 if Options.generate_cleanup_code >= 2: 2211 code.putln("/*--- Global cleanup code ---*/") 2212 rev_entries = list(env.var_entries) 2213 rev_entries.reverse() 2214 for entry in rev_entries: 2215 if entry.visibility != 'extern': 2216 if entry.type.is_pyobject and entry.used: 2217 code.put_xdecref_clear( 2218 entry.cname, entry.type, 2219 clear_before_decref=True, 2220 nanny=False) 2221 code.putln("__Pyx_CleanupGlobals();") 2222 if Options.generate_cleanup_code >= 3: 2223 code.putln("/*--- Type import cleanup code ---*/") 2224 for ext_type in sorted(env.types_imported, key=operator.attrgetter('typeptr_cname')): 2225 code.put_xdecref_clear( 2226 ext_type.typeptr_cname, ext_type, 2227 clear_before_decref=True, 2228 nanny=False) 2229 if Options.cache_builtins: 2230 code.putln("/*--- Builtin cleanup code ---*/") 2231 for entry in env.cached_builtins: 2232 code.put_xdecref_clear( 2233 entry.cname, PyrexTypes.py_object_type, 2234 clear_before_decref=True, 2235 nanny=False) 2236 code.putln("/*--- Intern cleanup code ---*/") 2237 code.put_decref_clear(Naming.empty_tuple, 2238 PyrexTypes.py_object_type, 2239 clear_before_decref=True, 2240 nanny=False) 2241 for entry in env.c_class_entries: 2242 cclass_type = entry.type 2243 if cclass_type.is_external or cclass_type.base_type: 2244 continue 2245 if cclass_type.scope.directives.get('freelist', 0): 2246 scope = cclass_type.scope 2247 freelist_name = scope.mangle_internal(Naming.freelist_name) 2248 freecount_name = scope.mangle_internal(Naming.freecount_name) 2249 code.putln("while (%s > 0) {" % freecount_name) 2250 code.putln("PyObject* o = (PyObject*)%s[--%s];" % ( 2251 freelist_name, freecount_name)) 2252 code.putln("(*Py_TYPE(o)->tp_free)(o);") 2253 code.putln("}") 2254 # for entry in env.pynum_entries: 2255 # code.put_decref_clear(entry.cname, 2256 # PyrexTypes.py_object_type, 2257 # nanny=False) 2258 # for entry in env.all_pystring_entries: 2259 # if entry.is_interned: 2260 # code.put_decref_clear(entry.pystring_cname, 2261 # PyrexTypes.py_object_type, 2262 # nanny=False) 2263 # for entry in env.default_entries: 2264 # if entry.type.is_pyobject and entry.used: 2265 # code.putln("Py_DECREF(%s); %s = 0;" % ( 2266 # code.entry_as_pyobject(entry), entry.cname)) 2267 code.putln('#if CYTHON_COMPILING_IN_PYPY') 2268 code.putln('Py_CLEAR(%s);' % Naming.builtins_cname) 2269 code.putln('#endif') 2270 code.put_decref_clear(env.module_dict_cname, py_object_type, 2271 nanny=False, clear_before_decref=True) 2272 2273 def generate_main_method(self, env, code): 2274 module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__')) 2275 if Options.embed == "main": 2276 wmain = "wmain" 2277 else: 2278 wmain = Options.embed 2279 code.globalstate.use_utility_code( 2280 main_method.specialize( 2281 module_name = env.module_name, 2282 module_is_main = module_is_main, 2283 main_method = Options.embed, 2284 wmain_method = wmain)) 2285 2286 def generate_pymoduledef_struct(self, env, code): 2287 if env.doc: 2288 doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc) 2289 else: 2290 doc = "0" 2291 if Options.generate_cleanup_code: 2292 cleanup_func = "(freefunc)%s" % Naming.cleanup_cname 2293 else: 2294 cleanup_func = 'NULL' 2295 2296 code.putln("") 2297 code.putln("#if PY_MAJOR_VERSION >= 3") 2298 code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname) 2299 code.putln("#if PY_VERSION_HEX < 0x03020000") 2300 # fix C compiler warnings due to missing initialisers 2301 code.putln(" { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },") 2302 code.putln("#else") 2303 code.putln(" PyModuleDef_HEAD_INIT,") 2304 code.putln("#endif") 2305 code.putln(' __Pyx_NAMESTR("%s"),' % env.module_name) 2306 code.putln(" %s, /* m_doc */" % doc) 2307 code.putln(" -1, /* m_size */") 2308 code.putln(" %s /* m_methods */," % env.method_table_cname) 2309 code.putln(" NULL, /* m_reload */") 2310 code.putln(" NULL, /* m_traverse */") 2311 code.putln(" NULL, /* m_clear */") 2312 code.putln(" %s /* m_free */" % cleanup_func) 2313 code.putln("};") 2314 code.putln("#endif") 2315 2316 def generate_module_creation_code(self, env, code): 2317 # Generate code to create the module object and 2318 # install the builtins. 2319 if env.doc: 2320 doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc) 2321 else: 2322 doc = "0" 2323 code.putln("#if PY_MAJOR_VERSION < 3") 2324 code.putln( 2325 '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % ( 2326 env.module_cname, 2327 env.module_name, 2328 env.method_table_cname, 2329 doc, 2330 env.module_cname)) 2331 code.putln("#else") 2332 code.putln( 2333 "%s = PyModule_Create(&%s);" % ( 2334 env.module_cname, 2335 Naming.pymoduledef_cname)) 2336 code.putln("#endif") 2337 code.putln(code.error_goto_if_null(env.module_cname, self.pos)) 2338 code.putln( 2339 "%s = PyModule_GetDict(%s); %s" % ( 2340 env.module_dict_cname, env.module_cname, 2341 code.error_goto_if_null(env.module_dict_cname, self.pos))) 2342 code.put_incref(env.module_dict_cname, py_object_type, nanny=False) 2343 2344 code.putln( 2345 '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); %s' % ( 2346 Naming.builtins_cname, 2347 code.error_goto_if_null(Naming.builtins_cname, self.pos))) 2348 code.putln('#if CYTHON_COMPILING_IN_PYPY') 2349 code.putln('Py_INCREF(%s);' % Naming.builtins_cname) 2350 code.putln('#endif') 2351 code.putln( 2352 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % ( 2353 env.module_cname, 2354 Naming.builtins_cname, 2355 code.error_goto(self.pos))) 2356 if Options.pre_import is not None: 2357 code.putln( 2358 '%s = PyImport_AddModule(__Pyx_NAMESTR("%s")); %s' % ( 2359 Naming.preimport_cname, 2360 Options.pre_import, 2361 code.error_goto_if_null(Naming.preimport_cname, self.pos))) 2362 2363 def generate_global_init_code(self, env, code): 2364 # Generate code to initialise global PyObject * 2365 # variables to None. 2366 for entry in env.var_entries: 2367 if entry.visibility != 'extern': 2368 if entry.used: 2369 entry.type.global_init_code(entry, code) 2370 2371 def generate_c_variable_export_code(self, env, code): 2372 # Generate code to create PyCFunction wrappers for exported C functions. 2373 entries = [] 2374 for entry in env.var_entries: 2375 if (entry.api 2376 or entry.defined_in_pxd 2377 or (Options.cimport_from_pyx and not entry.visibility == 'extern')): 2378 entries.append(entry) 2379 if entries: 2380 env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c")) 2381 for entry in entries: 2382 signature = entry.type.declaration_code("") 2383 name = code.intern_identifier(entry.name) 2384 code.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % ( 2385 name, entry.cname, signature, 2386 code.error_goto(self.pos))) 2387 2388 def generate_c_function_export_code(self, env, code): 2389 # Generate code to create PyCFunction wrappers for exported C functions. 2390 entries = [] 2391 for entry in env.cfunc_entries: 2392 if (entry.api 2393 or entry.defined_in_pxd 2394 or (Options.cimport_from_pyx and not entry.visibility == 'extern')): 2395 entries.append(entry) 2396 if entries: 2397 env.use_utility_code( 2398 UtilityCode.load_cached("FunctionExport", "ImportExport.c")) 2399 for entry in entries: 2400 signature = entry.type.signature_string() 2401 code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % ( 2402 entry.name, 2403 entry.cname, 2404 signature, 2405 code.error_goto(self.pos))) 2406 2407 def generate_type_import_code_for_module(self, module, env, code): 2408 # Generate type import code for all exported extension types in 2409 # an imported module. 2410 #if module.c_class_entries: 2411 for entry in module.c_class_entries: 2412 if entry.defined_in_pxd: 2413 self.generate_type_import_code(env, entry.type, entry.pos, code) 2414 2415 def specialize_fused_types(self, pxd_env): 2416 """ 2417 If fused c(p)def functions are defined in an imported pxd, but not 2418 used in this implementation file, we still have fused entries and 2419 not specialized ones. This method replaces any fused entries with their 2420 specialized ones. 2421 """ 2422 for entry in pxd_env.cfunc_entries[:]: 2423 if entry.type.is_fused: 2424 # This call modifies the cfunc_entries in-place 2425 entry.type.get_all_specialized_function_types() 2426 2427 def generate_c_variable_import_code_for_module(self, module, env, code): 2428 # Generate import code for all exported C functions in a cimported module. 2429 entries = [] 2430 for entry in module.var_entries: 2431 if entry.defined_in_pxd: 2432 entries.append(entry) 2433 if entries: 2434 env.use_utility_code( 2435 UtilityCode.load_cached("ModuleImport", "ImportExport.c")) 2436 env.use_utility_code( 2437 UtilityCode.load_cached("VoidPtrImport", "ImportExport.c")) 2438 temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 2439 code.putln( 2440 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % ( 2441 temp, 2442 module.qualified_name, 2443 temp, 2444 code.error_goto(self.pos))) 2445 for entry in entries: 2446 if env is module: 2447 cname = entry.cname 2448 else: 2449 cname = module.mangle(Naming.varptr_prefix, entry.name) 2450 signature = entry.type.declaration_code("") 2451 code.putln( 2452 'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % ( 2453 temp, entry.name, cname, signature, 2454 code.error_goto(self.pos))) 2455 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp)) 2456 2457 def generate_c_function_import_code_for_module(self, module, env, code): 2458 # Generate import code for all exported C functions in a cimported module. 2459 entries = [] 2460 for entry in module.cfunc_entries: 2461 if entry.defined_in_pxd and entry.used: 2462 entries.append(entry) 2463 if entries: 2464 env.use_utility_code( 2465 UtilityCode.load_cached("ModuleImport", "ImportExport.c")) 2466 env.use_utility_code( 2467 UtilityCode.load_cached("FunctionImport", "ImportExport.c")) 2468 temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 2469 code.putln( 2470 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % ( 2471 temp, 2472 module.qualified_name, 2473 temp, 2474 code.error_goto(self.pos))) 2475 for entry in entries: 2476 code.putln( 2477 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % ( 2478 temp, 2479 entry.name, 2480 entry.cname, 2481 entry.type.signature_string(), 2482 code.error_goto(self.pos))) 2483 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp)) 2484 2485 def generate_type_init_code(self, env, code): 2486 # Generate type import code for extern extension types 2487 # and type ready code for non-extern ones. 2488 for entry in env.c_class_entries: 2489 if entry.visibility == 'extern' and not entry.utility_code_definition: 2490 self.generate_type_import_code(env, entry.type, entry.pos, code) 2491 else: 2492 self.generate_base_type_import_code(env, entry, code) 2493 self.generate_exttype_vtable_init_code(entry, code) 2494 self.generate_type_ready_code(env, entry, code) 2495 self.generate_typeptr_assignment_code(entry, code) 2496 2497 def generate_base_type_import_code(self, env, entry, code): 2498 base_type = entry.type.base_type 2499 if (base_type and base_type.module_name != env.qualified_name and not 2500 base_type.is_builtin_type and not entry.utility_code_definition): 2501 self.generate_type_import_code(env, base_type, self.pos, code) 2502 2503 def generate_type_import_code(self, env, type, pos, code): 2504 # If not already done, generate code to import the typeobject of an 2505 # extension type defined in another module, and extract its C method 2506 # table pointer if any. 2507 if type in env.types_imported: 2508 return 2509 env.use_utility_code(UtilityCode.load_cached("TypeImport", "ImportExport.c")) 2510 self.generate_type_import_call(type, code, 2511 code.error_goto_if_null(type.typeptr_cname, pos)) 2512 if type.vtabptr_cname: 2513 code.globalstate.use_utility_code( 2514 UtilityCode.load_cached('GetVTable', 'ImportExport.c')) 2515 code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % ( 2516 type.vtabptr_cname, 2517 type.vtabstruct_cname, 2518 type.typeptr_cname, 2519 code.error_goto_if_null(type.vtabptr_cname, pos))) 2520 env.types_imported.add(type) 2521 2522 py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'} 2523 2524 def generate_type_import_call(self, type, code, error_code): 2525 if type.typedef_flag: 2526 objstruct = type.objstruct_cname 2527 else: 2528 objstruct = "struct %s" % type.objstruct_cname 2529 sizeof_objstruct = objstruct 2530 module_name = type.module_name 2531 condition = replacement = None 2532 if module_name not in ('__builtin__', 'builtins'): 2533 module_name = '"%s"' % module_name 2534 else: 2535 module_name = '__Pyx_BUILTIN_MODULE_NAME' 2536 if type.name in Code.non_portable_builtins_map: 2537 condition, replacement = Code.non_portable_builtins_map[type.name] 2538 if objstruct in Code.basicsize_builtins_map: 2539 # Some builtin types have a tp_basicsize which differs from sizeof(...): 2540 sizeof_objstruct = Code.basicsize_builtins_map[objstruct] 2541 2542 code.put('%s = __Pyx_ImportType(%s,' % ( 2543 type.typeptr_cname, 2544 module_name)) 2545 2546 if condition and replacement: 2547 code.putln("") # start in new line 2548 code.putln("#if %s" % condition) 2549 code.putln('"%s",' % replacement) 2550 code.putln("#else") 2551 code.putln('"%s",' % type.name) 2552 code.putln("#endif") 2553 else: 2554 code.put(' "%s", ' % type.name) 2555 2556 if sizeof_objstruct != objstruct: 2557 if not condition: 2558 code.putln("") # start in new line 2559 code.putln("#if CYTHON_COMPILING_IN_PYPY") 2560 code.putln('sizeof(%s),' % objstruct) 2561 code.putln("#else") 2562 code.putln('sizeof(%s),' % sizeof_objstruct) 2563 code.putln("#endif") 2564 else: 2565 code.put('sizeof(%s), ' % objstruct) 2566 2567 code.putln('%i); %s' % ( 2568 not type.is_external or type.is_subclassed, 2569 error_code)) 2570 2571 def generate_type_ready_code(self, env, entry, code): 2572 # Generate a call to PyType_Ready for an extension 2573 # type defined in this module. 2574 type = entry.type 2575 typeobj_cname = type.typeobj_cname 2576 scope = type.scope 2577 if scope: # could be None if there was an error 2578 if entry.visibility != 'extern': 2579 for slot in TypeSlots.slot_table: 2580 slot.generate_dynamic_init_code(scope, code) 2581 code.putln( 2582 "if (PyType_Ready(&%s) < 0) %s" % ( 2583 typeobj_cname, 2584 code.error_goto(entry.pos))) 2585 # Don't inherit tp_print from builtin types, restoring the 2586 # behavior of using tp_repr or tp_str instead. 2587 code.putln("%s.tp_print = 0;" % typeobj_cname) 2588 # Fix special method docstrings. This is a bit of a hack, but 2589 # unless we let PyType_Ready create the slot wrappers we have 2590 # a significant performance hit. (See trac #561.) 2591 for func in entry.type.scope.pyfunc_entries: 2592 is_buffer = func.name in ('__getbuffer__', 2593 '__releasebuffer__') 2594 if (func.is_special and Options.docstrings and 2595 func.wrapperbase_cname and not is_buffer): 2596 slot = TypeSlots.method_name_to_slot[func.name] 2597 preprocessor_guard = slot.preprocessor_guard_code() 2598 if preprocessor_guard: 2599 code.putln(preprocessor_guard) 2600 code.putln('#if CYTHON_COMPILING_IN_CPYTHON') 2601 code.putln("{") 2602 code.putln( 2603 'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % ( 2604 typeobj_cname, 2605 func.name, 2606 code.error_goto_if_null('wrapper', entry.pos))) 2607 code.putln( 2608 "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {") 2609 code.putln( 2610 "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % ( 2611 func.wrapperbase_cname)) 2612 code.putln( 2613 "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname)) 2614 code.putln( 2615 "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % ( 2616 func.wrapperbase_cname)) 2617 code.putln("}") 2618 code.putln("}") 2619 code.putln('#endif') 2620 if preprocessor_guard: 2621 code.putln('#endif') 2622 if type.vtable_cname: 2623 code.putln( 2624 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % ( 2625 typeobj_cname, 2626 type.vtabptr_cname, 2627 code.error_goto(entry.pos))) 2628 code.globalstate.use_utility_code( 2629 UtilityCode.load_cached('SetVTable', 'ImportExport.c')) 2630 if not type.scope.is_internal and not type.scope.directives['internal']: 2631 # scope.is_internal is set for types defined by 2632 # Cython (such as closures), the 'internal' 2633 # directive is set by users 2634 code.putln( 2635 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % ( 2636 Naming.module_cname, 2637 scope.class_name, 2638 typeobj_cname, 2639 code.error_goto(entry.pos))) 2640 weakref_entry = scope.lookup_here("__weakref__") 2641 if weakref_entry: 2642 if weakref_entry.type is py_object_type: 2643 tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname 2644 if type.typedef_flag: 2645 objstruct = type.objstruct_cname 2646 else: 2647 objstruct = "struct %s" % type.objstruct_cname 2648 code.putln("if (%s == 0) %s = offsetof(%s, %s);" % ( 2649 tp_weaklistoffset, 2650 tp_weaklistoffset, 2651 objstruct, 2652 weakref_entry.cname)) 2653 else: 2654 error(weakref_entry.pos, "__weakref__ slot must be of type 'object'") 2655 2656 def generate_exttype_vtable_init_code(self, entry, code): 2657 # Generate code to initialise the C method table of an 2658 # extension type. 2659 type = entry.type 2660 if type.vtable_cname: 2661 code.putln( 2662 "%s = &%s;" % ( 2663 type.vtabptr_cname, 2664 type.vtable_cname)) 2665 if type.base_type and type.base_type.vtabptr_cname: 2666 code.putln( 2667 "%s.%s = *%s;" % ( 2668 type.vtable_cname, 2669 Naming.obj_base_cname, 2670 type.base_type.vtabptr_cname)) 2671 2672 c_method_entries = [ 2673 entry for entry in type.scope.cfunc_entries 2674 if entry.func_cname ] 2675 if c_method_entries: 2676 for meth_entry in c_method_entries: 2677 cast = meth_entry.type.signature_cast_string() 2678 code.putln( 2679 "%s.%s = %s%s;" % ( 2680 type.vtable_cname, 2681 meth_entry.cname, 2682 cast, 2683 meth_entry.func_cname)) 2684 2685 def generate_typeptr_assignment_code(self, entry, code): 2686 # Generate code to initialise the typeptr of an extension 2687 # type defined in this module to point to its type object. 2688 type = entry.type 2689 if type.typeobj_cname: 2690 code.putln( 2691 "%s = &%s;" % ( 2692 type.typeptr_cname, type.typeobj_cname)) 2693 2694 def generate_cfunction_declaration(entry, env, code, definition): 2695 from_cy_utility = entry.used and entry.utility_code_definition 2696 if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (definition 2697 or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)): 2698 if entry.visibility == 'extern': 2699 storage_class = Naming.extern_c_macro 2700 dll_linkage = "DL_IMPORT" 2701 elif entry.visibility == 'public': 2702 storage_class = Naming.extern_c_macro 2703 dll_linkage = "DL_EXPORT" 2704 elif entry.visibility == 'private': 2705 storage_class = "static" 2706 dll_linkage = None 2707 else: 2708 storage_class = "static" 2709 dll_linkage = None 2710 type = entry.type 2711 2712 if entry.defined_in_pxd and not definition: 2713 storage_class = "static" 2714 dll_linkage = None 2715 type = CPtrType(type) 2716 2717 header = type.declaration_code( 2718 entry.cname, dll_linkage = dll_linkage) 2719 modifiers = code.build_function_modifiers(entry.func_modifiers) 2720 code.putln("%s %s%s; /*proto*/" % ( 2721 storage_class, 2722 modifiers, 2723 header)) 2724 2725 #------------------------------------------------------------------------------------ 2726 # 2727 # Runtime support code 2728 # 2729 #------------------------------------------------------------------------------------ 2730 2731 streq_utility_code = UtilityCode( 2732 proto = """ 2733 static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/ 2734 """, 2735 impl = """ 2736 static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) { 2737 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; } 2738 return *s1 == *s2; 2739 } 2740 """) 2741 2742 #------------------------------------------------------------------------------------ 2743 2744 import_star_utility_code = """ 2745 2746 /* import_all_from is an unexposed function from ceval.c */ 2747 2748 static int 2749 __Pyx_import_all_from(PyObject *locals, PyObject *v) 2750 { 2751 PyObject *all = __Pyx_GetAttrString(v, "__all__"); 2752 PyObject *dict, *name, *value; 2753 int skip_leading_underscores = 0; 2754 int pos, err; 2755 2756 if (all == NULL) { 2757 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) 2758 return -1; /* Unexpected error */ 2759 PyErr_Clear(); 2760 dict = __Pyx_GetAttrString(v, "__dict__"); 2761 if (dict == NULL) { 2762 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) 2763 return -1; 2764 PyErr_SetString(PyExc_ImportError, 2765 "from-import-* object has no __dict__ and no __all__"); 2766 return -1; 2767 } 2768 #if PY_MAJOR_VERSION < 3 2769 all = PyObject_CallMethod(dict, (char *)"keys", NULL); 2770 #else 2771 all = PyMapping_Keys(dict); 2772 #endif 2773 Py_DECREF(dict); 2774 if (all == NULL) 2775 return -1; 2776 skip_leading_underscores = 1; 2777 } 2778 2779 for (pos = 0, err = 0; ; pos++) { 2780 name = PySequence_GetItem(all, pos); 2781 if (name == NULL) { 2782 if (!PyErr_ExceptionMatches(PyExc_IndexError)) 2783 err = -1; 2784 else 2785 PyErr_Clear(); 2786 break; 2787 } 2788 if (skip_leading_underscores && 2789 #if PY_MAJOR_VERSION < 3 2790 PyString_Check(name) && 2791 PyString_AS_STRING(name)[0] == '_') 2792 #else 2793 PyUnicode_Check(name) && 2794 PyUnicode_AS_UNICODE(name)[0] == '_') 2795 #endif 2796 { 2797 Py_DECREF(name); 2798 continue; 2799 } 2800 value = PyObject_GetAttr(v, name); 2801 if (value == NULL) 2802 err = -1; 2803 else if (PyDict_CheckExact(locals)) 2804 err = PyDict_SetItem(locals, name, value); 2805 else 2806 err = PyObject_SetItem(locals, name, value); 2807 Py_DECREF(name); 2808 Py_XDECREF(value); 2809 if (err != 0) 2810 break; 2811 } 2812 Py_DECREF(all); 2813 return err; 2814 } 2815 2816 2817 static int %(IMPORT_STAR)s(PyObject* m) { 2818 2819 int i; 2820 int ret = -1; 2821 char* s; 2822 PyObject *locals = 0; 2823 PyObject *list = 0; 2824 #if PY_MAJOR_VERSION >= 3 2825 PyObject *utf8_name = 0; 2826 #endif 2827 PyObject *name; 2828 PyObject *item; 2829 2830 locals = PyDict_New(); if (!locals) goto bad; 2831 if (__Pyx_import_all_from(locals, m) < 0) goto bad; 2832 list = PyDict_Items(locals); if (!list) goto bad; 2833 2834 for(i=0; i<PyList_GET_SIZE(list); i++) { 2835 name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0); 2836 item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1); 2837 #if PY_MAJOR_VERSION >= 3 2838 utf8_name = PyUnicode_AsUTF8String(name); 2839 if (!utf8_name) goto bad; 2840 s = PyBytes_AS_STRING(utf8_name); 2841 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad; 2842 Py_DECREF(utf8_name); utf8_name = 0; 2843 #else 2844 s = PyString_AsString(name); 2845 if (!s) goto bad; 2846 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad; 2847 #endif 2848 } 2849 ret = 0; 2850 2851 bad: 2852 Py_XDECREF(locals); 2853 Py_XDECREF(list); 2854 #if PY_MAJOR_VERSION >= 3 2855 Py_XDECREF(utf8_name); 2856 #endif 2857 return ret; 2858 } 2859 """ % {'IMPORT_STAR' : Naming.import_star, 2860 'IMPORT_STAR_SET' : Naming.import_star_set } 2861 2862 refnanny_utility_code = UtilityCode.load_cached("Refnanny", "ModuleSetupCode.c") 2863 2864 main_method = UtilityCode.load("MainFunction", "Embed.c") 2865 2866 packed_struct_utility_code = UtilityCode(proto=""" 2867 #if defined(__GNUC__) 2868 #define __Pyx_PACKED __attribute__((__packed__)) 2869 #else 2870 #define __Pyx_PACKED 2871 #endif 2872 """, impl="", proto_block='utility_code_proto_before_types') 2873 2874 capsule_utility_code = UtilityCode.load("Capsule") 2875