ModuleNode.py 125 KB
Newer Older
1
#
2
#   Module parse tree node
3 4
#

5 6 7
import cython
cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object,
               error=object, warning=object, py_object_type=object, UtilityCode=object,
Stefan Behnel's avatar
Stefan Behnel committed
8
               EncodedString=object)
9

10 11
import os
import operator
12
from PyrexTypes import CPtrType
Robert Bradshaw's avatar
Robert Bradshaw committed
13
import Future
14

15
import Annotate
16 17 18 19 20 21
import Code
import Naming
import Nodes
import Options
import TypeSlots
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
Stefan Behnel's avatar
Stefan Behnel committed
28
from StringEncoding import EncodedString
29

Gary Furnish's avatar
Gary Furnish committed
30

31

32 33 34 35
def check_c_declarations_pxd(module_node):
    module_node.scope.check_c_classes_pxd()
    return module_node

36
def check_c_declarations(module_node):
37
    module_node.scope.check_c_classes()
38
    module_node.scope.check_c_functions()
39 40
    return module_node

41 42 43
class ModuleNode(Nodes.Node, Nodes.BlockNode):
    #  doc       string or None
    #  body      StatListNode
44 45
    #
    #  referenced_modules   [ModuleScope]
46
    #  full_module_name     string
47 48 49
    #
    #  scope                The module scope.
    #  compilation_source   A CompilationSource (see Main)
50
    #  directives           Top-level compiler directives
51

52
    child_attrs = ["body"]
53
    directives = None
54

55 56 57 58 59 60 61 62 63 64 65 66 67 68
    def merge_in(self, tree, scope, merge_scope=False):
        # Merges in the contents of another tree, and possibly scope. With the
        # current implementation below, this must be done right prior
        # to code generation.
        #
        # Note: This way of doing it seems strange -- I believe the
        # right concept is to split ModuleNode into a ModuleNode and a
        # CodeGenerator, and tell that CodeGenerator to generate code
        # from multiple sources.
        assert isinstance(self.body, Nodes.StatListNode)
        if isinstance(tree, Nodes.StatListNode):
            self.body.stats.extend(tree.stats)
        else:
            self.body.stats.append(tree)
69 70 71 72 73 74 75 76 77 78 79 80 81

        self.scope.utility_code_list.extend(scope.utility_code_list)

        def extend_if_not_in(L1, L2):
            for x in L2:
                if x not in L1:
                    L1.append(x)

        extend_if_not_in(self.scope.include_files, scope.include_files)
        extend_if_not_in(self.scope.included_files, scope.included_files)
        extend_if_not_in(self.scope.python_include_files,
                         scope.python_include_files)

82
        if merge_scope:
83 84 85
            # Ensure that we don't generate import code for these entries!
            for entry in scope.c_class_entries:
                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 92 93
        if not Options.docstrings:
            env.doc = self.doc = None
        elif Options.embed_pos_in_docstring:
Robert Bradshaw's avatar
Robert Bradshaw committed
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)
Robert Bradshaw's avatar
Robert Bradshaw committed
97
                env.doc.encoding = self.doc.encoding
98 99
        else:
            env.doc = self.doc
100
        env.directives = self.directives
101
        self.body.analyse_declarations(env)
102

103 104
    def process_implementation(self, options, result):
        env = self.scope
105
        env.return_type = PyrexTypes.c_void_type
106 107
        self.referenced_modules = []
        self.find_referenced_modules(env, self.referenced_modules, {})
108
        self.sort_cdef_classes(env)
109
        self.generate_c_code(env, options, result)
110 111
        self.generate_h_code(env, options, result)
        self.generate_api_code(env, result)
Robert Bradshaw's avatar
Robert Bradshaw committed
112

113 114 115 116 117 118
    def has_imported_c_functions(self):
        for module in self.referenced_modules:
            for entry in module.cfunc_entries:
                if entry.defined_in_pxd:
                    return 1
        return 0
119

120
    def generate_h_code(self, env, options, result):
121
        def h_entries(entries, api=0, pxd=0):
Stefan Behnel's avatar
Stefan Behnel committed
122
            return [entry for entry in entries
123 124 125 126
                    if ((entry.visibility == 'public') or
                        (api and entry.api) or
                        (pxd and entry.defined_in_pxd))]
        h_types = h_entries(env.type_entries, api=1)
Stefan Behnel's avatar
Stefan Behnel committed
127 128 129
        h_vars = h_entries(env.var_entries)
        h_funcs = h_entries(env.cfunc_entries)
        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 135 136 137 138
            if options.generate_pxi:
                result.i_file = replace_suffix(result.c_file, ".pxi")
                i_code = Code.PyrexCodeWriter(result.i_file)
            else:
                i_code = None
139 140 141

            h_guard = Naming.h_guard_prefix + self.api_name(env)
            h_code.put_h_guard(h_guard)
142
            h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
143
            self.generate_type_header_code(h_types, h_code)
144 145
            if options.capi_reexport_cincludes:
                self.generate_includes(env, [], h_code)
146
            h_code.putln("")
147 148
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.putln("#ifndef %s" % api_guard)
149 150
            h_code.putln("")
            self.generate_extern_c_macro_definition(h_code)
Stefan Behnel's avatar
Stefan Behnel committed
151
            if h_extension_types:
152
                h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
153
                for entry in h_extension_types:
154 155 156
                    self.generate_cclass_header_code(entry.type, h_code)
                    if i_code:
                        self.generate_cclass_include_code(entry.type, i_code)
157 158 159 160 161 162 163 164
            if h_funcs:
                h_code.putln("")
                for entry in h_funcs:
                    self.generate_public_declaration(entry, h_code, i_code)
            if h_vars:
                h_code.putln("")
                for entry in h_vars:
                    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 171
            h_code.putln("#else")
            h_code.putln("PyMODINIT_FUNC PyInit_%s(void);" % env.module_name)
172
            h_code.putln("#endif")
173 174
            h_code.putln("")
            h_code.putln("#endif /* !%s */" % h_guard)
175

176 177 178 179 180
            f = open_new_file(result.h_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
181

182 183 184 185
    def generate_public_declaration(self, entry, h_code, i_code):
        h_code.putln("%s %s;" % (
            Naming.extern_c_macro,
            entry.type.declaration_code(
Mark Florisson's avatar
Mark Florisson committed
186
                entry.cname, dll_linkage = "DL_IMPORT")))
187
        if i_code:
188
            i_code.putln("cdef extern %s" %
Mark Florisson's avatar
Mark Florisson committed
189
                entry.type.declaration_code(entry.cname, pyrex = 1))
190

191 192
    def api_name(self, env):
        return env.qualified_name.replace(".", "__")
Robert Bradshaw's avatar
Robert Bradshaw committed
193

194
    def generate_api_code(self, env, result):
195
        def api_entries(entries, pxd=0):
196 197 198 199 200 201
            return [entry for entry in entries
                    if entry.api or (pxd and entry.defined_in_pxd)]
        api_vars = api_entries(env.var_entries)
        api_funcs = api_entries(env.cfunc_entries)
        api_extension_types = api_entries(env.c_class_entries)
        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 206
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.put_h_guard(api_guard)
207 208 209
            h_code.putln('#include "Python.h"')
            if result.h_file:
                h_code.putln('#include "%s"' % os.path.basename(result.h_file))
210
            if api_extension_types:
211
                h_code.putln("")
212 213 214 215 216
                for entry in api_extension_types:
                    type = entry.type
                    h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname)
                    h_code.putln("#define %s (*%s)" % (
                        type.typeobj_cname, type.typeptr_cname))
217 218 219 220
            if api_funcs:
                h_code.putln("")
                for entry in api_funcs:
                    type = CPtrType(entry.type)
221 222 223 224 225 226 227
                    cname = env.mangle(Naming.func_prefix, entry.name)
                    h_code.putln("static %s = 0;" % type.declaration_code(cname))
                    h_code.putln("#define %s %s" % (entry.name, cname))
            if api_vars:
                h_code.putln("")
                for entry in api_vars:
                    type = CPtrType(entry.type)
228
                    cname = env.mangle(Naming.varptr_prefix, entry.name)
229 230
                    h_code.putln("static %s = 0;" %  type.declaration_code(cname))
                    h_code.putln("#define %s (*%s)" % (entry.name, cname))
231 232
            h_code.put(UtilityCode.load_as_string("PyIdentifierFromString", "ImportExport.c")[0])
            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 244
            h_code.putln("if (!module) goto bad;")
            for entry in api_funcs:
245
                cname = env.mangle(Naming.func_prefix, entry.name)
246 247
                sig = entry.type.signature_string()
                h_code.putln(
248 249 250
                    'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
            for entry in api_vars:
251
                cname = env.mangle(Naming.varptr_prefix, entry.name)
252 253 254 255
                sig = entry.type.declaration_code("")
                h_code.putln(
                    'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
256
            h_code.putln("Py_DECREF(module); module = 0;")
257
            for entry in api_extension_types:
258 259 260
                self.generate_type_import_call(
                    entry.type, h_code,
                    "if (!%s) goto bad;" % entry.type.typeptr_cname)
261 262 263 264 265 266
            h_code.putln("return 0;")
            h_code.putln("bad:")
            h_code.putln("Py_XDECREF(module);")
            h_code.putln("return -1;")
            h_code.putln("}")
            h_code.putln("")
267
            h_code.putln("#endif /* !%s */" % api_guard)
268

269 270 271 272 273
            f = open_new_file(result.api_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
274

275
    def generate_cclass_header_code(self, type, h_code):
276
        h_code.putln("%s %s %s;" % (
Robert Bradshaw's avatar
Robert Bradshaw committed
277
            Naming.extern_c_macro,
278
            PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
279
            type.typeobj_cname))
280

281 282 283 284 285 286 287
    def generate_cclass_include_code(self, type, i_code):
        i_code.putln("cdef extern class %s.%s:" % (
            type.module_name, type.name))
        i_code.indent()
        var_entries = type.scope.var_entries
        if var_entries:
            for entry in var_entries:
288
                i_code.putln("cdef %s" %
289 290 291 292
                    entry.type.declaration_code(entry.cname, pyrex = 1))
        else:
            i_code.putln("pass")
        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 299
            emit_linenums = False
            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 310
        globalstate.module_pos = self.pos
        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 325
        # generate normal variable and function definitions
        self.generate_variable_definitions(env, code)
326
        self.body.generate_function_definitions(env, code)
Robert Bradshaw's avatar
Robert Bradshaw committed
327
        code.mark_pos(None)
328 329
        self.generate_typeobj_definitions(env, code)
        self.generate_method_table(env, code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
330 331
        if env.has_import_star:
            self.generate_import_star(env, code)
332
        self.generate_pymoduledef_struct(env, code)
333

334 335 336
        # init_globals is inserted before this
        self.generate_module_init_func(modules[:-1], env, globalstate['init_module'])
        self.generate_module_cleanup_func(env, globalstate['cleanup_module'])
337
        if Options.embed:
338 339
            self.generate_main_method(env, globalstate['main_method'])
        self.generate_filename_table(globalstate['filename_table'])
340

341
        self.generate_declarations_for_modules(env, modules, globalstate)
342
        h_code.write('\n')
Gary Furnish's avatar
Gary Furnish committed
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)
Stefan Behnel's avatar
Stefan Behnel committed
349 350 351 352
        try:
            rootwriter.copyto(f)
        finally:
            f.close()
353
        result.c_file_generated = 1
Stefan Behnel's avatar
Stefan Behnel committed
354 355
        if options.gdb_debug:
            self._serialize_lineno_map(env, rootwriter)
356
        if Options.annotate or options.annotate:
357 358 359 360 361 362 363
            self._generate_annotations(rootwriter, result)

    def _generate_annotations(self, rootwriter, result):
        self.annotate(rootwriter)
        rootwriter.save_annotation(result.main_source_file, result.c_file)

        # if we included files, additionally generate one annotation file for each
364 365 366
        if not self.scope.included_files:
            return

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 371 372 373 374
            target_file = os.path.abspath(os.path.join(target_dir, included_file))
            target_file_dir = os.path.dirname(target_file)
            if not target_file_dir.startswith(target_dir):
                # any other directories may not be writable => avoid trying
                continue
375 376 377 378 379 380 381 382 383 384 385
            source_file = search_include_file(included_file, "", self.pos, include=True)
            if not source_file:
                continue
            if target_file_dir != target_dir and not os.path.exists(target_file_dir):
                try:
                    os.makedirs(target_file_dir)
                except OSError, e:
                    import errno
                    if e.errno != errno.EEXIST:
                        raise
            rootwriter.save_annotation(source_file, target_file)
386

Mark Florisson's avatar
Mark Florisson committed
387
    def _serialize_lineno_map(self, env, ccodewriter):
388
        tb = env.context.gdb_debug_outputwriter
Mark Florisson's avatar
Mark Florisson committed
389
        markers = ccodewriter.buffer.allmarkers()
390

Mark Florisson's avatar
Mark Florisson committed
391
        d = {}
392
        for c_lineno, cython_lineno in enumerate(markers):
Mark Florisson's avatar
Mark Florisson committed
393 394
            if cython_lineno > 0:
                d.setdefault(cython_lineno, []).append(c_lineno + 1)
395

Mark Florisson's avatar
Mark Florisson committed
396 397 398 399 400 401 402 403 404 405
        tb.start('LineNumberMapping')
        for cython_lineno, c_linenos in sorted(d.iteritems()):
                attrs = {
                    'c_linenos': ' '.join(map(str, c_linenos)),
                    'cython_lineno': str(cython_lineno),
                }
                tb.start('LineNumber', attrs)
                tb.end('LineNumber')
        tb.end('LineNumberMapping')
        tb.serialize()
406

407 408 409 410 411 412
    def find_referenced_modules(self, env, module_list, modules_seen):
        if env not in modules_seen:
            modules_seen[env] = 1
            for imported_module in env.cimported_modules:
                self.find_referenced_modules(imported_module, module_list, modules_seen)
            module_list.append(env)
Gary Furnish's avatar
Gary Furnish committed
413

414
    def sort_types_by_inheritance(self, type_dict, type_order, getkey):
415 416 417
        # copy the types into a list moving each parent type before
        # its first child
        type_list = []
418 419
        for i, key in enumerate(type_order):
            new_entry = type_dict[key]
420 421

            # collect all base classes to check for children
422
            hierarchy = set()
423
            base = new_entry
424 425 426 427 428 429 430
            while base:
                base_type = base.type.base_type
                if not base_type:
                    break
                base_key = getkey(base_type)
                hierarchy.add(base_key)
                base = type_dict.get(base_key)
431
            new_entry.base_keys = hierarchy
432

433
            # find the first (sub-)subclass and insert before that
434 435
            for j in range(i):
                entry = type_list[j]
436
                if key in entry.base_keys:
437 438 439 440 441 442 443
                    type_list.insert(j, new_entry)
                    break
            else:
                type_list.append(new_entry)
        return type_list

    def sort_type_hierarchy(self, module_list, env):
444 445 446
        # poor developer's OrderedDict
        vtab_dict, vtab_dict_order = {}, []
        vtabslot_dict, vtabslot_dict_order = {}, []
Stefan Behnel's avatar
Stefan Behnel committed
447

Gary Furnish's avatar
Gary Furnish committed
448 449
        for module in module_list:
            for entry in module.c_class_entries:
450
                if entry.used and not entry.in_cinclude:
Gary Furnish's avatar
Gary Furnish committed
451
                    type = entry.type
452 453 454
                    key = type.vtabstruct_cname
                    if not key:
                        continue
Stefan Behnel's avatar
Stefan Behnel committed
455 456 457 458 459 460 461 462 463
                    if key in vtab_dict:
                        # FIXME: this should *never* happen, but apparently it does
                        # for Cython generated utility code
                        from Cython.Compiler.UtilityCode import NonManglingModuleScope
                        assert isinstance(entry.scope, NonManglingModuleScope), str(entry.scope)
                        assert isinstance(vtab_dict[key].scope, NonManglingModuleScope), str(vtab_dict[key].scope)
                    else:
                        vtab_dict[key] = entry
                        vtab_dict_order.append(key)
464 465
            all_defined_here = module is env
            for entry in module.type_entries:
466
                if entry.used and (all_defined_here or entry.defined_in_pxd):
Gary Furnish's avatar
Gary Furnish committed
467
                    type = entry.type
468 469
                    if type.is_extension_type and not entry.in_cinclude:
                        type = entry.type
470 471 472 473
                        key = type.objstruct_cname
                        assert key not in vtabslot_dict, key
                        vtabslot_dict[key] = entry
                        vtabslot_dict_order.append(key)
474

475 476
        def vtabstruct_cname(entry_type):
            return entry_type.vtabstruct_cname
477
        vtab_list = self.sort_types_by_inheritance(
478
            vtab_dict, vtab_dict_order, vtabstruct_cname)
479 480 481

        def objstruct_cname(entry_type):
            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:
Stefan Behnel's avatar
Stefan Behnel committed
491
            key = key_func(entry.type)
492
            assert key not in entry_dict, key
Stefan Behnel's avatar
Stefan Behnel committed
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

Gary Furnish's avatar
Gary Furnish committed
498
    def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
499 500 501
        # TODO: Why are these separated out?
        for entry in vtabslot_list:
            self.generate_objstruct_predeclaration(entry.type, code)
502
        vtabslot_entries = set(vtabslot_list)
Gary Furnish's avatar
Gary Furnish committed
503 504 505 506 507 508 509 510 511
        for module in modules:
            definition = module is env
            if definition:
                type_entries = module.type_entries
            else:
                type_entries = []
                for entry in module.type_entries:
                    if entry.defined_in_pxd:
                        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)
Gary Furnish's avatar
Gary Furnish committed
514
        for entry in vtabslot_list:
515
            self.generate_objstruct_definition(entry.type, code)
516
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
517
        for entry in vtab_list:
518
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
519 520
            self.generate_exttype_vtable_struct(entry, code)
            self.generate_exttype_vtabptr_declaration(entry, code)
521
            self.generate_exttype_final_methods_declaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
522

523 524 525
    def generate_declarations_for_modules(self, env, modules, globalstate):
        typecode = globalstate['type_declarations']
        typecode.putln("")
526
        typecode.putln("/*--- Type declarations ---*/")
527 528 529 530 531 532 533
        # This is to work around the fact that array.h isn't part of the C-API,
        # but we need to declare it earlier than utility code.
        if 'cpython.array' in [m.qualified_name for m in modules]:
            typecode.putln('#ifndef _ARRAYARRAY_H')
            typecode.putln('struct arrayobject;')
            typecode.putln('typedef struct arrayobject arrayobject;')
            typecode.putln('#endif')
534 535
        vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
        self.generate_type_definitions(
536 537
            env, modules, vtab_list, vtabslot_list, typecode)
        modulecode = globalstate['module_declarations']
Gary Furnish's avatar
Gary Furnish committed
538
        for module in modules:
539
            defined_here = module is env
540 541 542 543 544
            modulecode.putln("")
            modulecode.putln("/* Module declarations from '%s' */" % module.qualified_name)
            self.generate_c_class_declarations(module, modulecode, defined_here)
            self.generate_cvariable_declarations(module, modulecode, defined_here)
            self.generate_cfunction_declarations(module, modulecode, defined_here)
Gary Furnish's avatar
Gary Furnish committed
545

546
    def generate_module_preamble(self, env, cimported_modules, code):
547
        code.putln("/* Generated by Cython %s */" % Version.watermark)
548 549
        code.putln("")
        code.putln("#define PY_SSIZE_T_CLEAN")
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570

        # sizeof(PyLongObject.ob_digit[0]) may have been determined dynamically
        # at compile time in CPython, in which case we can't know the correct
        # storage size for an installed system.  We can rely on it only if
        # pyconfig.h defines it statically, i.e. if it was set by "configure".
        # Once we include "Python.h", it will come up with its own idea about
        # a suitable value, which may or may not match the real one.
        code.putln("#ifndef CYTHON_USE_PYLONG_INTERNALS")
        code.putln("#ifdef PYLONG_BITS_IN_DIGIT")
        # assume it's an incorrect left-over
        code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
        code.putln("#else")
        code.putln('#include "pyconfig.h"')
        code.putln("#ifdef PYLONG_BITS_IN_DIGIT")
        code.putln("#define CYTHON_USE_PYLONG_INTERNALS 1")
        code.putln("#else")
        code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
        code.putln("#endif")
        code.putln("#endif")
        code.putln("#endif")

571 572
        for filename in env.python_include_files:
            code.putln('#include "%s"' % filename)
573 574
        code.putln("#ifndef Py_PYTHON_H")
        code.putln("    #error Python headers needed to compile C extensions, please install development version of Python.")
575 576
        code.putln("#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)")
        code.putln("    #error Cython requires Python 2.6+ or Python 3.2+.")
577 578
        code.putln("#else")
        code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
Robert Bradshaw's avatar
Robert Bradshaw committed
579

Robert Bradshaw's avatar
Robert Bradshaw committed
580 581
        from Cython import __version__
        code.putln('#define CYTHON_ABI "%s"' % __version__.replace('.', '_'))
582

583
        code.put(UtilityCode.load_as_string("CModulePreamble", "ModuleSetupCode.c")[1])
584 585 586

        code.put("""
#if PY_MAJOR_VERSION >= 3
587 588 589 590
  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
#else
""")
Robert Bradshaw's avatar
Robert Bradshaw committed
591 592
        if Future.division in env.context.future_directives:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
593
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)")
Robert Bradshaw's avatar
Robert Bradshaw committed
594 595
        else:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
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 604 605
        code.putln("#if defined(WIN32) || defined(MS_WINDOWS)")
        code.putln("#define _USE_MATH_DEFINES")
        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 612 613 614 615
        code.putln("")
        code.putln("#ifdef PYREX_WITHOUT_ASSERTIONS")
        code.putln("#define CYTHON_WITHOUT_ASSERTIONS")
        code.putln("#endif")
        code.putln("")
616

617 618 619 620
        if env.directives['ccomplex']:
            code.putln("")
            code.putln("#if !defined(CYTHON_CCOMPLEX)")
            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 626

        c_string_type = env.directives['c_string_type']
        c_string_encoding = env.directives['c_string_encoding']
627 628
        if c_string_type not in ('bytes', 'bytearray') and not c_string_encoding:
            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 631 632 633 634
        if c_string_encoding == 'default':
            code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 1')
        else:
            code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0')
            code.putln('#define __PYX_DEFAULT_STRING_ENCODING "%s"' % c_string_encoding)
635 636 637 638 639 640
        if c_string_type == 'bytearray':
            c_string_func_name = 'ByteArray'
        else:
            c_string_func_name = c_string_type.title()
        code.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_func_name)
        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])
Robert Bradshaw's avatar
Robert Bradshaw committed
642

643 644 645
        # These utility functions are assumed to exist and used elsewhere.
        PyrexTypes.c_long_type.create_to_py_utility_code(env)
        PyrexTypes.c_long_type.create_from_py_utility_code(env)
Robert Bradshaw's avatar
Robert Bradshaw committed
646
        PyrexTypes.c_int_type.create_from_py_utility_code(env)
Robert Bradshaw's avatar
Robert Bradshaw committed
647

Robert Bradshaw's avatar
Robert Bradshaw committed
648
        code.put(Nodes.branch_prediction_macros)
649 650
        code.putln('')
        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)
Robert Bradshaw's avatar
Robert Bradshaw committed
653
        code.putln('static PyObject *%s;' % Naming.empty_tuple)
Robert Bradshaw's avatar
Robert Bradshaw committed
654
        code.putln('static PyObject *%s;' % Naming.empty_bytes)
655 656
        if Options.pre_import is not None:
            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 660
        code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
        code.putln('static const char *%s;' % Naming.filename_cname)
661

662 663
    def generate_extern_c_macro_definition(self, code):
        name = Naming.extern_c_macro
664 665 666 667 668 669
        code.putln("#ifndef %s" % name)
        code.putln("  #ifdef __cplusplus")
        code.putln('    #define %s extern "C"' % name)
        code.putln("  #else")
        code.putln("    #define %s extern" % name)
        code.putln("  #endif")
670 671 672
        code.putln("#endif")

    def generate_includes(self, env, cimported_modules, code):
673
        includes = []
Robert Bradshaw's avatar
Robert Bradshaw committed
674
        for filename in env.include_files:
Stefan Behnel's avatar
Stefan Behnel committed
675 676 677
            byte_decoded_filenname = str(filename)
            if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
                code.putln('#include %s' % byte_decoded_filenname)
678
            else:
Stefan Behnel's avatar
Stefan Behnel committed
679
                code.putln('#include "%s"' % byte_decoded_filenname)
680

681 682
        code.putln_openmp("#include <omp.h>")

683 684
    def generate_filename_table(self, code):
        code.putln("")
Robert Bradshaw's avatar
Robert Bradshaw committed
685
        code.putln("static const char *%s[] = {" % Naming.filetable_cname)
686 687
        if code.globalstate.filename_list:
            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'\"')
Robert Bradshaw's avatar
Robert Bradshaw committed
690
                code.putln('"%s",' % escaped_filename)
691 692 693 694
        else:
            # Some C compilers don't like an empty array
            code.putln("0")
        code.putln("};")
695 696 697 698

    def generate_type_predeclarations(self, env, code):
        pass

699
    def generate_type_header_code(self, type_entries, code):
700 701
        # Generate definitions of structs/unions/enums/typedefs/objstructs.
        #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 711 712 713 714 715 716 717 718 719
                    self.generate_struct_union_predeclaration(entry, code)
                elif type.is_extension_type:
                    self.generate_objstruct_predeclaration(type, code)
        # Actual declarations
        for entry in type_entries:
            if not entry.in_cinclude:
                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
                type = entry.type
                if type.is_typedef: # Must test this first!
                    self.generate_typedef(entry, code)
720
                elif type.is_enum:
721
                    self.generate_enum_definition(entry, code)
722 723
                elif type.is_struct_or_union:
                    self.generate_struct_union_definition(entry, code)
724 725
                elif type.is_cpp_class:
                    self.generate_cpp_class_definition(entry, code)
726
                elif type.is_extension_type:
727
                    self.generate_objstruct_definition(type, code)
728

729 730 731 732 733 734 735 736 737 738 739 740 741
    def generate_gcc33_hack(self, env, code):
        # Workaround for spurious warning generation in gcc 3.3
        code.putln("")
        for entry in env.c_class_entries:
            type = entry.type
            if not type.typedef_flag:
                name = type.objstruct_cname
                if name.startswith("__pyx_"):
                    tail = name[6:]
                else:
                    tail = name
                code.putln("typedef struct %s __pyx_gcc33_%s;" % (
                    name, tail))
742

743 744
    def generate_typedef(self, entry, code):
        base_type = entry.type.typedef_base_type
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
745
        if base_type.is_numeric:
746 747 748 749
            try:
                writer = code.globalstate['numeric_typedefs']
            except KeyError:
                writer = code
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
750 751
        else:
            writer = code
752
        writer.mark_pos(entry.pos)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
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 758 759
            return "%s %s;\ntypedef %s %s %s;" % (
                kind, name,
                kind, name, name)
760
        else:
761 762 763 764
            return "%s %s;" % (kind, name)

    def generate_struct_union_predeclaration(self, entry, code):
        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 768 769 770 771
        code.putln(self.sue_predeclaration(type, type.kind, type.cname))

    def sue_header_footer(self, type, kind, name):
        header = "%s %s {" % (kind, name)
        footer = "};"
772
        return header, footer
773

774
    def generate_struct_union_definition(self, entry, code):
775
        code.mark_pos(entry.pos)
776 777 778
        type = entry.type
        scope = type.scope
        if scope:
779 780 781 782 783
            kind = type.kind
            packed = type.is_struct and type.packed
            if packed:
                kind = "%s %s" % (type.kind, "__Pyx_PACKED")
                code.globalstate.use_utility_code(packed_struct_utility_code)
784
            header, footer = \
785 786
                self.sue_header_footer(type, kind, type.cname)
            if packed:
787 788 789 790
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack(1)")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(push, 1)")
791
                code.putln("#endif")
792 793 794 795 796 797 798 799 800 801 802
            code.putln(header)
            var_entries = scope.var_entries
            if not var_entries:
                error(entry.pos,
                    "Empty struct or union definition not allowed outside a"
                    " 'cdef extern from' block")
            for attr in var_entries:
                code.putln(
                    "%s;" %
                        attr.type.declaration_code(attr.cname))
            code.putln(footer)
803
            if packed:
804 805 806 807
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack()")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(pop)")
808
                code.putln("#endif")
809

810 811 812 813 814 815 816 817 818 819 820 821 822 823
    def generate_cpp_class_definition(self, entry, code):
        code.mark_pos(entry.pos)
        type = entry.type
        scope = type.scope
        if scope:
            if type.templates:
                code.putln("template <class %s>" % ", class ".join([T.declaration_code("") for T in type.templates]))
            # Just let everything be public.
            code.put("struct %s" % type.cname)
            if type.base_classes:
                base_class_decl = ", public ".join(
                    [base_class.declaration_code("") for base_class in type.base_classes])
                code.put(" : public %s" % base_class_decl)
            code.putln(" {")
824 825
            has_virtual_methods = False
            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 830 831
                    has_virtual_methods = True
                if attr.cname[0] == '~':
                    has_destructor = True
832 833 834
                code.putln(
                    "%s;" %
                        attr.type.declaration_code(attr.cname))
835 836
            if has_virtual_methods and not has_destructor:
                code.put("virtual ~%s() { }" % type.cname)
837 838
            code.putln("};")

839
    def generate_enum_definition(self, entry, code):
840
        code.mark_pos(entry.pos)
841 842 843 844 845 846 847 848 849 850 851 852
        type = entry.type
        name = entry.cname or entry.name or ""
        header, footer = \
            self.sue_header_footer(type, "enum", name)
        code.putln(header)
        enum_values = entry.enum_values
        if not enum_values:
            error(entry.pos,
                "Empty enum definition not allowed outside a"
                " 'cdef extern from' block")
        else:
            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 856 857 858 859
                if value_entry.value_node is not None:
                    value_entry.value_node.generate_evaluation_code(code)

            for value_entry in enum_values:
                if value_entry.value_node is None:
860 861 862 863
                    value_code = value_entry.cname
                else:
                    value_code = ("%s = %s" % (
                        value_entry.cname,
864
                        value_entry.value_node.result()))
865 866 867 868
                if value_entry is not last_entry:
                    value_code += ","
                code.putln(value_code)
        code.putln(footer)
869 870 871
        if entry.type.typedef_flag:
            # Not pre-declared.
            code.putln("typedef enum %s %s;" % (name, name))
872

873
    def generate_typeobj_predeclaration(self, entry, code):
874 875 876 877
        code.putln("")
        name = entry.type.typeobj_cname
        if name:
            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 882
                    name))
            elif entry.visibility == 'public':
883
                code.putln("%s %s %s;" % (
884
                    Naming.extern_c_macro,
885
                    PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"),
886 887 888
                    name))
            # ??? Do we really need the rest of this? ???
            #else:
889
            #    code.putln("static PyTypeObject %s;" % name)
890

891
    def generate_exttype_vtable_struct(self, entry, code):
892 893 894
        if not entry.used:
            return

895
        code.mark_pos(entry.pos)
896 897 898
        # Generate struct declaration for an extension type's vtable.
        type = entry.type
        scope = type.scope
899 900 901

        self.specialize_fused_types(scope)

902 903 904 905 906 907 908 909 910 911 912 913
        if type.vtabstruct_cname:
            code.putln("")
            code.putln(
                "struct %s {" %
                    type.vtabstruct_cname)
            if type.base_type and type.base_type.vtabstruct_cname:
                code.putln("struct %s %s;" % (
                    type.base_type.vtabstruct_cname,
                    Naming.obj_base_cname))
            for method_entry in scope.cfunc_entries:
                if not method_entry.is_inherited:
                    code.putln(
914
                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname))
915 916
            code.putln(
                "};")
917

918
    def generate_exttype_vtabptr_declaration(self, entry, code):
919 920 921
        if not entry.used:
            return

922
        code.mark_pos(entry.pos)
923 924 925 926 927 928
        # Generate declaration of pointer to an extension type's vtable.
        type = entry.type
        if type.vtabptr_cname:
            code.putln("static struct %s *%s;" % (
                type.vtabstruct_cname,
                type.vtabptr_cname))
929

930 931 932 933 934 935 936 937 938 939 940
    def generate_exttype_final_methods_declaration(self, entry, code):
        if not entry.used:
            return

        code.mark_pos(entry.pos)
        # Generate final methods prototypes
        type = entry.type
        for method_entry in entry.type.scope.cfunc_entries:
            if not method_entry.is_inherited and method_entry.final_func_cname:
                declaration = method_entry.type.declaration_code(
                    method_entry.final_func_cname)
941 942
                modifiers = code.build_function_modifiers(method_entry.func_modifiers)
                code.putln("static %s%s;" % (modifiers, declaration))
943

944 945 946 947
    def generate_objstruct_predeclaration(self, type, code):
        if not type.scope:
            return
        code.putln(self.sue_predeclaration(type, "struct", type.objstruct_cname))
Vitja Makarov's avatar
Vitja Makarov committed
948

949
    def generate_objstruct_definition(self, type, code):
950
        code.mark_pos(type.pos)
951 952 953 954 955 956 957 958 959
        # Generate object struct definition for an
        # extension type.
        if not type.scope:
            return # Forward declared but never defined
        header, footer = \
            self.sue_header_footer(type, "struct", type.objstruct_cname)
        code.putln(header)
        base_type = type.base_type
        if base_type:
960 961 962 963
            basestruct_cname = base_type.objstruct_cname
            if basestruct_cname == "PyTypeObject":
                # User-defined subclasses of type are heap allocated.
                basestruct_cname = "PyHeapTypeObject"
964 965 966
            code.putln(
                "%s%s %s;" % (
                    ("struct ", "")[base_type.typedef_flag],
967
                    basestruct_cname,
968 969 970 971 972 973 974 975 976 977
                    Naming.obj_base_cname))
        else:
            code.putln(
                "PyObject_HEAD")
        if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
            code.putln(
                "struct %s *%s;" % (
                    type.vtabstruct_cname,
                    type.vtabslot_cname))
        for attr in type.scope.var_entries:
978 979 980 981
            if attr.is_declared_generic:
                attr_type = py_object_type
            else:
                attr_type = attr.type
982 983
            code.putln(
                "%s;" %
984
                    attr_type.declaration_code(attr.cname))
985
        code.putln(footer)
986 987 988
        if type.objtypedef_cname is not None:
            # Only for exposing public typedef name.
            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 998
        if env.is_cython_builtin:
            return
999 1000 1001 1002
        for entry in env.var_entries:
            if (entry.in_cinclude or entry.in_closure or
                (entry.visibility == 'private' and
                 not (entry.defined_in_pxd or entry.used))):
1003
                continue
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013

            storage_class = None
            dll_linkage = None
            cname = None
            init = None

            if entry.visibility == 'extern':
                storage_class = Naming.extern_c_macro
                dll_linkage = "DL_IMPORT"
            elif entry.visibility == 'public':
1014
                storage_class = Naming.extern_c_macro
1015 1016 1017 1018 1019 1020
                if definition:
                    dll_linkage = "DL_EXPORT"
                else:
                    dll_linkage = "DL_IMPORT"
            elif entry.visibility == 'private':
                storage_class = "static"
1021 1022 1023 1024 1025
                dll_linkage = None
                if entry.init is not None:
                    init =  entry.type.literal_code(entry.init)
            type = entry.type
            cname = entry.cname
1026 1027 1028 1029

            if entry.defined_in_pxd and not definition:
                storage_class = "static"
                dll_linkage = None
1030
                type = CPtrType(type)
1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
                cname = env.mangle(Naming.varptr_prefix, entry.name)
                init = 0

            if storage_class:
                code.put("%s " % storage_class)
            code.put(type.declaration_code(
                cname, dll_linkage = dll_linkage))
            if init is not None:
                code.put_safe(" = %s" % init)
            code.putln(";")
            if entry.cname != cname:
                code.putln("#define %s (*%s)" % (entry.cname, cname))

    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 1050
    def generate_variable_definitions(self, env, code):
        for entry in env.var_entries:
Vitja Makarov's avatar
Vitja Makarov committed
1051
            if (not entry.in_cinclude and
1052 1053 1054 1055 1056 1057 1058
                entry.visibility == "public"):
                code.put(entry.type.declaration_code(entry.cname))
                if entry.init is not None:
                    init =  entry.type.literal_code(entry.init)
                    code.put_safe(" = %s" % init)
                code.putln(";")

1059 1060 1061 1062 1063
    def generate_typeobj_definitions(self, env, code):
        full_module_name = env.qualified_name
        for entry in env.c_class_entries:
            #print "generate_typeobj_definitions:", entry.name
            #print "...visibility =", entry.visibility
Stefan Behnel's avatar
Stefan Behnel committed
1064
            if entry.visibility != 'extern':
1065 1066 1067 1068
                type = entry.type
                scope = type.scope
                if scope: # could be None if there was an error
                    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 1074
                        if scope.needs_tp_clear():
                            self.generate_clear_function(scope, code, entry)
1075 1076 1077 1078
                    if scope.defines_any(["__getitem__"]):
                        self.generate_getitem_int_function(scope, code)
                    if scope.defines_any(["__setitem__", "__delitem__"]):
                        self.generate_ass_subscript_function(scope, code)
1079 1080 1081 1082 1083
                    if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]):
                        warning(self.pos, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1)
                        code.putln("#if PY_MAJOR_VERSION >= 3")
                        code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
                        code.putln("#endif")
1084 1085
                    if scope.defines_any(["__setslice__", "__delslice__"]):
                        self.generate_ass_slice_function(scope, code)
1086
                    if scope.defines_any(["__getattr__","__getattribute__"]):
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
                        self.generate_getattro_function(scope, code)
                    if scope.defines_any(["__setattr__", "__delattr__"]):
                        self.generate_setattro_function(scope, code)
                    if scope.defines_any(["__get__"]):
                        self.generate_descr_get_function(scope, code)
                    if scope.defines_any(["__set__", "__delete__"]):
                        self.generate_descr_set_function(scope, code)
                    self.generate_property_accessors(scope, code)
                    self.generate_method_table(scope, code)
                    self.generate_getset_table(scope, code)
                    self.generate_typeobj_definition(full_module_name, entry, code)
1098

1099 1100 1101 1102 1103 1104 1105
    def generate_exttype_vtable(self, scope, code):
        # Generate the definition of an extension type's vtable.
        type = scope.parent_type
        if type.vtable_cname:
            code.putln("static struct %s %s;" % (
                type.vtabstruct_cname,
                type.vtable_cname))
1106

1107 1108 1109 1110 1111 1112
    def generate_self_cast(self, scope, code):
        type = scope.parent_type
        code.putln(
            "%s = (%s)o;" % (
                type.declaration_code("p"),
                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 1118
        type = scope.parent_type
        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 1124 1125 1126 1127
        if scope.is_internal:
            # internal classes (should) never need None inits, normal zeroing will do
            py_attrs = []
        cpp_class_attrs = [entry for entry in scope.var_entries
                           if entry.type.is_cpp_class]
1128

1129 1130 1131 1132 1133 1134 1135
        new_func_entry = scope.lookup_here("__new__")
        if base_type or (new_func_entry and new_func_entry.is_special
                         and not new_func_entry.trivial_signature):
            unused_marker = ''
        else:
            unused_marker = 'CYTHON_UNUSED '

1136 1137 1138 1139 1140 1141 1142
        if base_type:
            freelist_size = 0  # not currently supported
        else:
            freelist_size = scope.directives.get('freelist', 0)
        freelist_name = scope.mangle_internal(Naming.freelist_name)
        freecount_name = scope.mangle_internal(Naming.freecount_name)

1143 1144 1145
        decls = code.globalstate['decls']
        decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" %
                    slot_func)
1146
        code.putln("")
1147 1148 1149 1150 1151 1152
        if freelist_size:
            code.putln("static %s[%d];" % (
                scope.parent_type.declaration_code(freelist_name),
                freelist_size))
            code.putln("static int %s = 0;" % freecount_name)
            code.putln("")
1153
        code.putln(
1154
            "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {"
1155 1156
                % (slot_func, unused_marker, unused_marker))

1157 1158 1159
        need_self_cast = (type.vtabslot_cname or
                          (py_buffers or memoryview_slices or py_attrs) or
                          cpp_class_attrs)
1160
        if need_self_cast:
1161
            code.putln("%s;" % scope.parent_type.declaration_code("p"))
1162
        if base_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
1163 1164
            tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
            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 1169
            code.putln("PyObject *o;")
            if freelist_size:
1170 1171
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
1172 1173 1174 1175
                if is_final_type:
                    abstract_check = ''
                else:
                    abstract_check = ' & ((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)'
1176
                obj_struct = type.declaration_code("", deref=True)
1177 1178
                code.putln("if (likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % (
                    freecount_name, obj_struct, abstract_check))
1179 1180
                code.putln("o = (PyObject*)%s[--%s];" % (
                    freelist_name, freecount_name))
1181
                code.putln("memset(o, 0, sizeof(%s));" % obj_struct)
1182
                code.putln("(void) PyObject_INIT(o, t);")
1183 1184 1185
                if scope.needs_gc():
                    code.putln("PyObject_GC_Track(o);")
                code.putln("} else {")
1186 1187 1188 1189 1190 1191 1192
            if not is_final_type:
                code.putln("if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {")
            code.putln("o = (*t->tp_alloc)(t, 0);")
            if not is_final_type:
                code.putln("} else {")
                code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple)
                code.putln("}")
1193
        code.putln("if (unlikely(!o)) return 0;")
1194 1195
        if freelist_size and not base_type:
            code.putln('}')
1196
        if need_self_cast:
1197
            code.putln("p = %s;" % type.cast_code("o"))
1198
        #if need_self_cast:
Robert Bradshaw's avatar
Robert Bradshaw committed
1199
        #    self.generate_self_cast(scope, code)
1200
        if type.vtabslot_cname:
1201 1202 1203 1204 1205
            vtab_base_type = type
            while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
                vtab_base_type = vtab_base_type.base_type
            if vtab_base_type is not type:
                struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
1206 1207 1208
            else:
                struct_type_cast = ""
            code.putln("p->%s = %s%s;" % (
1209
                type.vtabslot_cname,
1210
                struct_type_cast, type.vtabptr_cname))
1211

Robert Bradshaw's avatar
Robert Bradshaw committed
1212
        for entry in cpp_class_attrs:
Robert Bradshaw's avatar
Robert Bradshaw committed
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 1224 1225 1226 1227 1228

        for entry in py_buffers:
            code.putln("p->%s.obj = NULL;" % entry.cname)

        if cclass_entry.cname == '__pyx_memoryviewslice':
            code.putln("p->from_slice.memview = NULL;")

1229 1230
        if new_func_entry and new_func_entry.is_special:
            if new_func_entry.trivial_signature:
1231 1232 1233
                cinit_args = "o, %s, NULL" % Naming.empty_tuple
            else:
                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 1239 1240 1241 1242 1243
            code.putln(
                "}")
        code.putln(
            "return o;")
        code.putln(
            "}")
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 1254
        code.putln("")
        code.putln(
1255
            "static void %s(PyObject *o) {" % slot_func_cname)
1256

1257 1258 1259
        is_final_type = scope.parent_type.is_final_type
        needs_gc = scope.needs_gc()

1260
        weakref_slot = scope.lookup_here("__weakref__")
1261 1262 1263
        if weakref_slot not in scope.var_entries:
            weakref_slot = None

1264
        _, (py_attrs, _, memoryview_slices) = scope.get_refcounted_entries()
1265 1266
        cpp_class_attrs = [entry for entry in scope.var_entries
                           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 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289

        if not is_final_type:
            # in Py3.4+, call tp_finalize() as early as possible
            code.putln("#if PY_VERSION_HEX >= 0x030400a1")
            if needs_gc:
                finalised_check = '!_PyGC_FINALIZED(o)'
            else:
                finalised_check = (
                    '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))')
            code.putln("if (unlikely(Py_TYPE(o)->tp_finalize) && %s) {" %
                       finalised_check)
            # if instance was resurrected by finaliser, return
            code.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;")
            code.putln("}")
            code.putln("#endif")

        if needs_gc:
            # We must mark this object as (gc) untracked while tearing
            # it down, lest the garbage collection is invoked while
            # 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

Robert Bradshaw's avatar
Robert Bradshaw committed
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 1303
            code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False,
                                   clear_before_decref=True)
1304 1305 1306 1307 1308

        for entry in memoryview_slices:
            code.put_xdecref_memoryviewslice("p->%s" % entry.cname,
                                             have_gil=True)

1309
        if base_type:
1310 1311 1312
            if needs_gc:
                # The base class deallocator probably expects this to be tracked,
                # so undo the untracking above.
1313 1314 1315
                if base_type.scope and base_type.scope.needs_gc():
                    code.putln("PyObject_GC_Track(o);")
                else:
1316 1317 1318 1319
                    code.putln("#if CYTHON_COMPILING_IN_CPYTHON")
                    code.putln("if (PyType_IS_GC(Py_TYPE(o)->tp_base))")
                    code.putln("#endif")
                    code.putln("PyObject_GC_Track(o);")
1320

Robert Bradshaw's avatar
Robert Bradshaw committed
1321
            tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
1322 1323
            if tp_dealloc is not None:
                code.putln("%s(o);" % tp_dealloc)
1324 1325
            elif base_type.is_builtin_type:
                code.putln("%s->tp_dealloc(o);" % base_type.typeptr_cname)
1326 1327 1328 1329 1330 1331
            else:
                # This is an externally defined type.  Calling through the
                # cimported base type pointer directly interacts badly with
                # the module cleanup, which may already have cleared it.
                # In that case, fall back to traversing the type hierarchy.
                base_cname = base_type.typeptr_cname
1332 1333 1334
                code.putln("if (likely(%s)) %s->tp_dealloc(o); "
                           "else __Pyx_call_next_tp_dealloc(o, %s);" % (
                               base_cname, base_cname, slot_func_cname))
1335 1336
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("CallNextTpDealloc", "ExtensionTypes.c"))
1337
        else:
1338 1339 1340 1341 1342 1343
            freelist_size = scope.directives.get('freelist', 0)
            if freelist_size:
                freelist_name = scope.mangle_internal(Naming.freelist_name)
                freecount_name = scope.mangle_internal(Naming.freecount_name)

                type = scope.parent_type
1344 1345
                code.putln("if ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))) {" % (
                    freecount_name, freelist_size, type.declaration_code("", deref=True)))
1346 1347 1348 1349 1350 1351
                code.putln("%s[%s++] = %s;" % (
                    freelist_name, freecount_name, type.cast_code("o")))
                code.putln("} else {")
            code.putln("(*Py_TYPE(o)->tp_free)(o);")
            if freelist_size:
                code.putln("}")
1352 1353
        code.putln(
            "}")
1354

1355 1356
    def generate_usr_dealloc_call(self, scope, code):
        entry = scope.lookup_here("__dealloc__")
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
        if not entry:
            return

        code.putln("{")
        code.putln("PyObject *etype, *eval, *etb;")
        code.putln("PyErr_Fetch(&etype, &eval, &etb);")
        code.putln("++Py_REFCNT(o);")
        code.putln("%s(o);" % entry.func_cname)
        code.putln("--Py_REFCNT(o);")
        code.putln("PyErr_Restore(etype, eval, etb);")
        code.putln("}")
1368

1369
    def generate_traverse_function(self, scope, code, cclass_entry):
1370 1371
        tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
        slot_func = scope.mangle_internal("tp_traverse")
1372
        base_type = scope.parent_type.base_type
1373 1374
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1375 1376 1377
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, visitproc v, void *a) {"
1378
                % slot_func)
1379

1380 1381
        have_entries, (py_attrs, py_buffers, memoryview_slices) = (
            scope.get_refcounted_entries(include_gc_simple=False))
1382

1383
        if base_type or py_attrs:
1384
            code.putln("int e;")
1385 1386

        if py_attrs or py_buffers:
1387
            self.generate_self_cast(scope, code)
1388

1389
        if base_type:
1390
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1391 1392 1393
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1394 1395 1396 1397
            elif base_type.is_builtin_type:
                base_cname = base_type.typeptr_cname
                code.putln("if (!%s->tp_traverse); else { e = %s->tp_traverse(o,v,a); if (e) return e; }" % (
                    base_cname, base_cname))
1398
            else:
1399 1400 1401 1402 1403 1404 1405 1406 1407
                # This is an externally defined type.  Calling through the
                # cimported base type pointer directly interacts badly with
                # the module cleanup, which may already have cleared it.
                # In that case, fall back to traversing the type hierarchy.
                base_cname = base_type.typeptr_cname
                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;" % (
                    base_cname, base_cname, base_cname, slot_func))
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c"))
1408

1409 1410 1411 1412 1413 1414 1415 1416
        for entry in py_attrs:
            var_code = "p->%s" % entry.cname
            code.putln(
                    "if (%s) {"
                        % var_code)
            if entry.type.is_extension_type:
                var_code = "((PyObject*)%s)" % var_code
            code.putln(
1417
                        "e = (*v)(%s, a); if (e) return e;"
1418 1419 1420
                            % var_code)
            code.putln(
                    "}")
1421

Stefan Behnel's avatar
Stefan Behnel committed
1422 1423
        # Traverse buffer exporting objects.
        # Note: not traversing memoryview attributes of memoryview slices!
1424 1425
        # When triggered by the GC, it would cause multiple visits (gc_refs
        # subtractions which is not matched by its reference count!)
Stefan Behnel's avatar
Stefan Behnel committed
1426 1427
        for entry in py_buffers:
            cname = entry.cname + ".obj"
1428 1429
            code.putln("if (p->%s) {" % cname)
            code.putln(    "e = (*v)(p->%s, a); if (e) return e;" % cname)
1430 1431
            code.putln("}")

1432 1433 1434 1435
        code.putln(
                "return 0;")
        code.putln(
            "}")
1436

1437
    def generate_clear_function(self, scope, code, cclass_entry):
1438 1439
        tp_slot = TypeSlots.GCDependentSlot("tp_clear")
        slot_func = scope.mangle_internal("tp_clear")
1440
        base_type = scope.parent_type.base_type
1441 1442
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1443

1444 1445
        have_entries, (py_attrs, py_buffers, memoryview_slices) = (
            scope.get_refcounted_entries(include_gc_simple=False))
1446

1447 1448 1449 1450 1451 1452 1453 1454
        if py_attrs or py_buffers or base_type:
            unused = ''
        else:
            unused = 'CYTHON_UNUSED '

        code.putln("")
        code.putln("static int %s(%sPyObject *o) {" % (slot_func, unused))

1455 1456 1457
        if py_attrs and Options.clear_to_none:
            code.putln("PyObject* tmp;")

1458
        if py_attrs or py_buffers:
1459
            self.generate_self_cast(scope, code)
1460

1461
        if base_type:
1462
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1463 1464 1465
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("%s(o);" % static_call)
1466 1467 1468 1469
            elif base_type.is_builtin_type:
                base_cname = base_type.typeptr_cname
                code.putln("if (!%s->tp_clear); else %s->tp_clear(o);" % (
                    base_cname, base_cname))
1470
            else:
1471 1472 1473 1474 1475 1476 1477 1478 1479
                # This is an externally defined type.  Calling through the
                # cimported base type pointer directly interacts badly with
                # the module cleanup, which may already have cleared it.
                # In that case, fall back to traversing the type hierarchy.
                base_cname = base_type.typeptr_cname
                code.putln("if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % (
                    base_cname, base_cname, base_cname, slot_func))
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c"))
1480

1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492
        if Options.clear_to_none:
            for entry in py_attrs:
                name = "p->%s" % entry.cname
                code.putln("tmp = ((PyObject*)%s);" % name)
                if entry.is_declared_generic:
                    code.put_init_to_py_none(name, py_object_type, nanny=False)
                else:
                    code.put_init_to_py_none(name, entry.type, nanny=False)
                code.putln("Py_XDECREF(tmp);")
        else:
            for entry in py_attrs:
                code.putln("Py_CLEAR(p->%s);" % entry.cname)
1493 1494

        for entry in py_buffers:
1495
            # Note: shouldn't this call __Pyx_ReleaseBuffer ??
1496 1497 1498 1499 1500
            code.putln("Py_CLEAR(p->%s.obj);" % entry.cname)

        if cclass_entry.cname == '__pyx_memoryviewslice':
            code.putln("__PYX_XDEC_MEMVIEW(&p->from_slice, 1);")

1501 1502 1503 1504
        code.putln(
            "return 0;")
        code.putln(
            "}")
1505

1506 1507 1508 1509 1510
    def generate_getitem_int_function(self, scope, code):
        # This function is put into the sq_item slot when
        # a __getitem__ method is present. It converts its
        # argument to a Python integer and calls mp_subscript.
        code.putln(
1511
            "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1512 1513 1514 1515
                scope.mangle_internal("sq_item"))
        code.putln(
                "PyObject *r;")
        code.putln(
1516
                "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1517
        code.putln(
1518
                "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548
        code.putln(
                "Py_DECREF(x);")
        code.putln(
                "return r;")
        code.putln(
            "}")

    def generate_ass_subscript_function(self, scope, code):
        # Setting and deleting an item are both done through
        # the ass_subscript method, so we dispatch to user's __setitem__
        # or __delitem__, or raise an exception.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setitem__")
        del_entry = scope.lookup_here("__delitem__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
                scope.mangle_internal("mp_ass_subscript"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, i, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1549
                    '  "Subscript assignment not supported by %.200s", Py_TYPE(o)->tp_name);')
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, i);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1566
                    '  "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);')
1567 1568 1569 1570 1571 1572
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")
1573

1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
    def generate_guarded_basetype_call(
            self, base_type, substructure, slot, args, code):
        if base_type:
            base_tpname = base_type.typeptr_cname
            if substructure:
                code.putln(
                    "if (%s->%s && %s->%s->%s)" % (
                        base_tpname, substructure, base_tpname, substructure, slot))
                code.putln(
                    "  return %s->%s->%s(%s);" % (
                        base_tpname, substructure, slot, args))
            else:
                code.putln(
                    "if (%s->%s)" % (
                        base_tpname, slot))
                code.putln(
                    "  return %s->%s(%s);" % (
                        base_tpname, slot, args))

    def generate_ass_slice_function(self, scope, code):
        # Setting and deleting a slice are both done through
        # the ass_slice method, so we dispatch to user's __setslice__
        # or __delslice__, or raise an exception.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setslice__")
        del_entry = scope.lookup_here("__delslice__")
        code.putln("")
        code.putln(
1602
            "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615
                scope.mangle_internal("sq_ass_slice"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, i, j, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1616
                    '  "2-element slice assignment not supported by %.200s", Py_TYPE(o)->tp_name);')
1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, i, j);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1633
                    '  "2-element slice deletion not supported by %.200s", Py_TYPE(o)->tp_name);')
1634 1635 1636 1637 1638 1639 1640 1641
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_getattro_function(self, scope, code):
1642 1643 1644
        # First try to get the attribute using __getattribute__, if defined, or
        # PyObject_GenericGetAttr.
        #
1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
        # If that raises an AttributeError, call the __getattr__ if defined.
        #
        # In both cases, defined can be in this class, or any base class.
        def lookup_here_or_base(n,type=None):
            # Recursive lookup
            if type is None:
                type = scope.parent_type
            r = type.scope.lookup_here(n)
            if r is None and \
               type.base_type is not None:
                return lookup_here_or_base(n,type.base_type)
            else:
                return r
        getattr_entry = lookup_here_or_base("__getattr__")
        getattribute_entry = lookup_here_or_base("__getattribute__")
1660 1661 1662 1663
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *n) {"
                % scope.mangle_internal("tp_getattro"))
1664 1665 1666 1667 1668 1669
        if getattribute_entry is not None:
            code.putln(
                "PyObject *v = %s(o, n);" %
                    getattribute_entry.func_cname)
        else:
            code.putln(
1670
                "PyObject *v = PyObject_GenericGetAttr(o, n);")
1671 1672
        if getattr_entry is not None:
            code.putln(
1673
                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1674 1675 1676 1677 1678 1679
            code.putln(
                "PyErr_Clear();")
            code.putln(
                "v = %s(o, n);" %
                    getattr_entry.func_cname)
            code.putln(
1680 1681
                "}")
        code.putln(
1682
            "return v;")
1683 1684
        code.putln(
            "}")
1685

1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724
    def generate_setattro_function(self, scope, code):
        # Setting and deleting an attribute are both done through
        # the setattro method, so we dispatch to user's __setattr__
        # or __delattr__ or fall back on PyObject_GenericSetAttr.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setattr__")
        del_entry = scope.lookup_here("__delattr__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
                scope.mangle_internal("tp_setattro"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, n, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_setattro", "o, n, v", code)
            code.putln(
                    "return PyObject_GenericSetAttr(o, n, v);")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, n);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_setattro", "o, n, v", code)
            code.putln(
                    "return PyObject_GenericSetAttr(o, n, 0);")
        code.putln(
                "}")
        code.putln(
            "}")
1725

1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
    def generate_descr_get_function(self, scope, code):
        # The __get__ function of a descriptor object can be
        # called with NULL for the second or third arguments
        # under some circumstances, so we replace them with
        # None in that case.
        user_get_entry = scope.lookup_here("__get__")
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
                scope.mangle_internal("tp_descr_get"))
        code.putln(
            "PyObject *r = 0;")
        code.putln(
            "if (!i) i = Py_None;")
        code.putln(
            "if (!c) c = Py_None;")
        #code.put_incref("i", py_object_type)
        #code.put_incref("c", py_object_type)
        code.putln(
            "r = %s(o, i, c);" %
                user_get_entry.func_cname)
        #code.put_decref("i", py_object_type)
        #code.put_decref("c", py_object_type)
        code.putln(
            "return r;")
        code.putln(
            "}")
1753

1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793
    def generate_descr_set_function(self, scope, code):
        # Setting and deleting are both done through the __set__
        # method of a descriptor, so we dispatch to user's __set__
        # or __delete__ or raise an exception.
        base_type = scope.parent_type.base_type
        user_set_entry = scope.lookup_here("__set__")
        user_del_entry = scope.lookup_here("__delete__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
                scope.mangle_internal("tp_descr_set"))
        code.putln(
                "if (v) {")
        if user_set_entry:
            code.putln(
                    "return %s(o, i, v);" %
                        user_set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_descr_set", "o, i, v", code)
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if user_del_entry:
            code.putln(
                    "return %s(o, i);" %
                        user_del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_descr_set", "o, i, v", code)
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
            code.putln(
                    "return -1;")
        code.putln(
1794
                "}")
1795 1796
        code.putln(
            "}")
1797

1798 1799 1800 1801 1802 1803 1804
    def generate_property_accessors(self, cclass_scope, code):
        for entry in cclass_scope.property_entries:
            property_scope = entry.scope
            if property_scope.defines_any(["__get__"]):
                self.generate_property_get_function(entry, code)
            if property_scope.defines_any(["__set__", "__del__"]):
                self.generate_property_set_function(entry, code)
1805

1806 1807 1808 1809 1810 1811 1812
    def generate_property_get_function(self, property_entry, code):
        property_scope = property_entry.scope
        property_entry.getter_cname = property_scope.parent_scope.mangle(
            Naming.prop_get_prefix, property_entry.name)
        get_entry = property_scope.lookup_here("__get__")
        code.putln("")
        code.putln(
1813
            "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" %
1814 1815 1816 1817 1818 1819
                property_entry.getter_cname)
        code.putln(
                "return %s(o);" %
                    get_entry.func_cname)
        code.putln(
            "}")
1820

1821 1822 1823 1824 1825 1826 1827 1828
    def generate_property_set_function(self, property_entry, code):
        property_scope = property_entry.scope
        property_entry.setter_cname = property_scope.parent_scope.mangle(
            Naming.prop_set_prefix, property_entry.name)
        set_entry = property_scope.lookup_here("__set__")
        del_entry = property_scope.lookup_here("__del__")
        code.putln("")
        code.putln(
1829
            "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" %
1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868
                property_entry.setter_cname)
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, v);" %
                        set_entry.func_cname)
        else:
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o);" %
                        del_entry.func_cname)
        else:
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_typeobj_definition(self, modname, entry, code):
        type = entry.type
        scope = type.scope
        for suite in TypeSlots.substructures:
            suite.generate_substructure(scope, code)
        code.putln("")
        if entry.visibility == 'public':
            header = "DL_EXPORT(PyTypeObject) %s = {"
        else:
1869
            header = "static PyTypeObject %s = {"
1870 1871 1872
        #code.putln(header % scope.parent_type.typeobj_cname)
        code.putln(header % type.typeobj_cname)
        code.putln(
1873
            "PyVarObject_HEAD_INIT(0, 0)")
1874
        code.putln(
1875
            '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1876
                self.full_module_name, scope.class_name))
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889
        if type.typedef_flag:
            objstruct = type.objstruct_cname
        else:
            objstruct = "struct %s" % type.objstruct_cname
        code.putln(
            "sizeof(%s), /*tp_basicsize*/" %
                objstruct)
        code.putln(
            "0, /*tp_itemsize*/")
        for slot in TypeSlots.slot_table:
            slot.generate(scope, code)
        code.putln(
            "};")
1890

1891
    def generate_method_table(self, env, code):
1892 1893
        if env.is_c_class_scope and not env.pyfunc_entries:
            return
1894 1895
        code.putln("")
        code.putln(
1896
            "static PyMethodDef %s[] = {" %
1897 1898
                env.method_table_cname)
        for entry in env.pyfunc_entries:
1899 1900
            if not entry.fused_cfunction:
                code.put_pymethoddef(entry, ",")
1901 1902 1903 1904
        code.putln(
                "{0, 0, 0, 0}")
        code.putln(
            "};")
1905

1906 1907 1908 1909 1910 1911 1912
    def generate_getset_table(self, env, code):
        if env.property_entries:
            code.putln("")
            code.putln(
                "static struct PyGetSetDef %s[] = {" %
                    env.getset_table_cname)
            for entry in env.property_entries:
1913 1914 1915 1916
                if entry.doc:
                    doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
                else:
                    doc_code = "0"
1917
                code.putln(
1918
                    '{(char *)"%s", %s, %s, %s, 0},' % (
1919 1920 1921
                        entry.name,
                        entry.getter_cname or "0",
                        entry.setter_cname or "0",
1922
                        doc_code))
1923 1924 1925 1926
            code.putln(
                    "{0, 0, 0, 0, 0}")
            code.putln(
                "};")
1927

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1928
    def generate_import_star(self, env, code):
1929
        env.use_utility_code(streq_utility_code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1930
        code.putln()
1931
        code.putln("static char* %s_type_names[] = {" % Naming.import_star)
1932
        for name, entry in sorted(env.entries.items()):
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1933 1934 1935 1936 1937
            if entry.is_type:
                code.putln('"%s",' % name)
        code.putln("0")
        code.putln("};")
        code.putln()
1938
        code.enter_cfunc_scope() # as we need labels
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1939 1940 1941
        code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
        code.putln("char** type_name = %s_type_names;" % Naming.import_star)
        code.putln("while (*type_name) {")
1942
        code.putln("if (__Pyx_StrEq(name, *type_name)) {")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1943 1944 1945 1946 1947 1948 1949 1950 1951
        code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
        code.putln('goto bad;')
        code.putln("}")
        code.putln("type_name++;")
        code.putln("}")
        old_error_label = code.new_error_label()
        code.putln("if (0);") # so the first one can be "else if"
        for name, entry in env.entries.items():
            if entry.is_cglobal and entry.used:
1952
                code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1953 1954 1955 1956 1957
                if entry.type.is_pyobject:
                    if entry.type.is_extension_type or entry.type.is_builtin_type:
                        code.putln("if (!(%s)) %s;" % (
                            entry.type.type_test_code("o"),
                            code.error_goto(entry.pos)))
1958 1959
                    code.putln("Py_INCREF(o);")
                    code.put_decref(entry.cname, entry.type, nanny=False)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1960
                    code.putln("%s = %s;" % (
1961
                        entry.cname,
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1962 1963 1964 1965
                        PyrexTypes.typecast(entry.type, py_object_type, "o")))
                elif entry.type.from_py_function:
                    rhs = "%s(o)" % entry.type.from_py_function
                    if entry.type.is_enum:
1966
                        rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
                    code.putln("%s = %s; if (%s) %s;" % (
                        entry.cname,
                        rhs,
                        entry.type.error_condition(entry.cname),
                        code.error_goto(entry.pos)))
                else:
                    code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
                    code.putln(code.error_goto(entry.pos))
                code.putln("}")
        code.putln("else {")
        code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
        code.putln("}")
        code.putln("return 0;")
1980 1981 1982
        if code.label_used(code.error_label):
            code.put_label(code.error_label)
            # This helps locate the offending name.
1983
            code.put_add_traceback(self.full_module_name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1984 1985 1986 1987 1988
        code.error_label = old_error_label
        code.putln("bad:")
        code.putln("return -1;")
        code.putln("}")
        code.putln(import_star_utility_code)
1989
        code.exit_cfunc_scope() # done with labels
1990 1991

    def generate_module_init_func(self, imported_modules, env, code):
1992
        code.enter_cfunc_scope()
1993
        code.putln("")
1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
        header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
        header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("%s; /*proto*/" % header2)
        code.putln(header2)
        code.putln("#else")
        code.putln("%s; /*proto*/" % header3)
        code.putln(header3)
        code.putln("#endif")
        code.putln("{")
2004
        tempdecl_code = code.insertion_point()
Robert Bradshaw's avatar
Robert Bradshaw committed
2005

2006
        code.put_declare_refcount_context()
2007 2008 2009
        code.putln("#if CYTHON_REFNANNY")
        code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
        code.putln("if (!__Pyx_RefNanny) {")
2010
        code.putln("  PyErr_Clear();")
2011 2012 2013
        code.putln("  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
        code.putln("  if (!__Pyx_RefNanny)")
        code.putln("      Py_FatalError(\"failed to import 'refnanny' module\");")
2014
        code.putln("}")
2015
        code.putln("#endif")
2016
        code.put_setup_refcount_context(header3)
2017

2018
        env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c"))
2019
        code.putln("if ( __Pyx_check_binary_version() < 0) %s" % code.error_goto(self.pos))
2020

2021 2022
        code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)))
        code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)))
2023

2024 2025
        code.putln("#ifdef __Pyx_CyFunction_USED")
        code.putln("if (__Pyx_CyFunction_init() < 0) %s" % code.error_goto(self.pos))
Robert Bradshaw's avatar
Robert Bradshaw committed
2026
        code.putln("#endif")
2027

2028 2029
        code.putln("#ifdef __Pyx_FusedFunction_USED")
        code.putln("if (__pyx_FusedFunction_init() < 0) %s" % code.error_goto(self.pos))
Robert Bradshaw's avatar
Robert Bradshaw committed
2030
        code.putln("#endif")
2031

2032 2033 2034 2035
        code.putln("#ifdef __Pyx_Generator_USED")
        code.putln("if (__pyx_Generator_init() < 0) %s" % code.error_goto(self.pos))
        code.putln("#endif")

2036
        code.putln("/*--- Library function declarations ---*/")
2037
        env.generate_library_function_declarations(code)
2038

2039 2040
        code.putln("/*--- Threads initialization code ---*/")
        code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
2041
        code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
2042 2043 2044 2045
        code.putln("PyEval_InitThreads();")
        code.putln("#endif")
        code.putln("#endif")

2046
        code.putln("/*--- Module creation code ---*/")
2047
        self.generate_module_creation_code(env, code)
2048

2049 2050 2051
        code.putln("/*--- Initialize various global constants etc. ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))

2052
        code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)")
Robert Bradshaw's avatar
Robert Bradshaw committed
2053
        code.putln("if (__Pyx_init_sys_getdefaultencoding_params() < 0) %s" % code.error_goto(self.pos))
2054 2055
        code.putln("#endif")

2056 2057
        __main__name = code.globalstate.get_py_string_const(
            EncodedString("__main__"), identifier=True)
2058 2059 2060 2061
        code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
        code.putln(
            'if (__Pyx_SetAttrString(%s, "__name__", %s) < 0) %s;' % (
                env.module_cname,
2062
                __main__name.cname,
2063 2064
                code.error_goto(self.pos)))
        code.putln("}")
2065

2066 2067
        # set up __file__ and __path__, then add the module to sys.modules
        self.generate_module_import_setup(env, code)
2068

Robert Bradshaw's avatar
Robert Bradshaw committed
2069 2070
        if Options.cache_builtins:
            code.putln("/*--- Builtin init code ---*/")
2071 2072 2073 2074
            code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()", self.pos))

        code.putln("/*--- Constants init code ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitCachedConstants()", self.pos))
2075

2076
        code.putln("/*--- Global init code ---*/")
2077
        self.generate_global_init_code(env, code)
Gary Furnish's avatar
Gary Furnish committed
2078

2079 2080 2081
        code.putln("/*--- Variable export code ---*/")
        self.generate_c_variable_export_code(env, code)

2082
        code.putln("/*--- Function export code ---*/")
2083 2084
        self.generate_c_function_export_code(env, code)

2085
        code.putln("/*--- Type init code ---*/")
2086
        self.generate_type_init_code(env, code)
2087

2088
        code.putln("/*--- Type import code ---*/")
2089 2090 2091
        for module in imported_modules:
            self.generate_type_import_code_for_module(module, env, code)

2092 2093 2094 2095
        code.putln("/*--- Variable import code ---*/")
        for module in imported_modules:
            self.generate_c_variable_import_code_for_module(module, env, code)

Gary Furnish's avatar
Gary Furnish committed
2096 2097
        code.putln("/*--- Function import code ---*/")
        for module in imported_modules:
2098
            self.specialize_fused_types(module)
Gary Furnish's avatar
Gary Furnish committed
2099 2100
            self.generate_c_function_import_code_for_module(module, env, code)

2101
        code.putln("/*--- Execution code ---*/")
Robert Bradshaw's avatar
Robert Bradshaw committed
2102
        code.mark_pos(None)
2103

2104
        self.body.generate_execution_code(code)
2105

2106
        if Options.generate_cleanup_code:
2107 2108
            code.globalstate.use_utility_code(
                UtilityCode.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c"))
2109
            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
2110

2111
        code.put_goto(code.return_label)
2112
        code.put_label(code.error_label)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2113 2114
        for cname, type in code.funcstate.all_managed_temps():
            code.put_xdecref(cname, type)
2115
        code.putln('if (%s) {' % env.module_cname)
2116
        code.put_add_traceback("init %s" % env.qualified_name)
2117
        env.use_utility_code(Nodes.traceback_utility_code)
2118
        code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
2119 2120 2121
        code.putln('} else if (!PyErr_Occurred()) {')
        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
        code.putln('}')
2122
        code.put_label(code.return_label)
2123 2124 2125

        code.put_finish_refcount_context()

2126 2127 2128
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("return;")
        code.putln("#else")
2129
        code.putln("return %s;" % env.module_cname)
2130
        code.putln("#endif")
2131
        code.putln('}')
2132

2133
        tempdecl_code.put_temp_declarations(code.funcstate)
2134

2135
        code.exit_cfunc_scope()
2136

2137
    def generate_module_import_setup(self, env, code):
2138 2139 2140
        module_path = env.directives['set_initial_path']
        if module_path == 'SOURCEFILE':
            module_path = self.pos[0].filename
2141 2142 2143

        if module_path:
            code.putln('if (__Pyx_SetAttrString(%s, "__file__", %s) < 0) %s;' % (
2144
                env.module_cname,
2145 2146
                code.globalstate.get_py_string_const(
                    EncodedString(decode_filename(module_path))).cname,
2147
                code.error_goto(self.pos)))
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195

            if env.is_package:
                # set __path__ to mark the module as package
                temp = code.funcstate.allocate_temp(py_object_type, True)
                code.putln('%s = Py_BuildValue("[O]", %s); %s' % (
                    temp,
                    code.globalstate.get_py_string_const(
                        EncodedString(decode_filename(
                            os.path.dirname(module_path)))).cname,
                    code.error_goto_if_null(temp, self.pos)))
                code.put_gotref(temp)
                code.putln(
                    'if (__Pyx_SetAttrString(%s, "__path__", %s) < 0) %s;' % (
                        env.module_cname, temp, code.error_goto(self.pos)))
                code.put_decref_clear(temp, py_object_type)
                code.funcstate.release_temp(temp)

        elif env.is_package:
            # packages require __path__, so all we can do is try to figure
            # out the module path at runtime by rerunning the import lookup
            package_name, _ = self.full_module_name.rsplit('.', 1)
            if '.' in package_name:
                parent_name = '"%s"' % (package_name.rsplit('.', 1)[0],)
            else:
                parent_name = 'NULL'
            code.globalstate.use_utility_code(UtilityCode.load(
                "SetPackagePathFromImportLib", "ImportExport.c"))
            code.putln(code.error_goto_if_neg(
                '__Pyx_SetPackagePathFromImportLib(%s, %s)' % (
                    parent_name,
                    code.globalstate.get_py_string_const(
                        EncodedString(env.module_name)).cname),
                self.pos))

        # CPython may not have put us into sys.modules yet, but relative imports and reimports require it
        fq_module_name = self.full_module_name
        if fq_module_name.endswith('.__init__'):
            fq_module_name = fq_module_name[:-len('.__init__')]
        code.putln("#if PY_MAJOR_VERSION >= 3")
        code.putln("{")
        code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" %
                   code.error_goto_if_null("modules", self.pos))
        code.putln('if (!PyDict_GetItemString(modules, "%s")) {' % fq_module_name)
        code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, "%s", %s)' % (
            fq_module_name, env.module_cname), self.pos))
        code.putln("}")
        code.putln("}")
        code.putln("#endif")
2196

2197 2198 2199
    def generate_module_cleanup_func(self, env, code):
        if not Options.generate_cleanup_code:
            return
2200

2201
        code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' %
2202
                   Naming.cleanup_cname)
2203 2204
        if Options.generate_cleanup_code >= 2:
            code.putln("/*--- Global cleanup code ---*/")
2205 2206 2207
            rev_entries = list(env.var_entries)
            rev_entries.reverse()
            for entry in rev_entries:
2208
                if entry.visibility != 'extern':
2209
                    if entry.type.is_pyobject and entry.used:
2210 2211 2212 2213
                        code.put_xdecref_clear(
                            entry.cname, entry.type,
                            clear_before_decref=True,
                            nanny=False)
2214
        code.putln("__Pyx_CleanupGlobals();")
2215 2216
        if Options.generate_cleanup_code >= 3:
            code.putln("/*--- Type import cleanup code ---*/")
2217 2218 2219 2220 2221
            for type in env.types_imported:
                code.put_xdecref_clear(
                    type.typeptr_cname, type,
                    clear_before_decref=True,
                    nanny=False)
2222 2223
        if Options.cache_builtins:
            code.putln("/*--- Builtin cleanup code ---*/")
2224
            for entry in env.cached_builtins:
2225 2226 2227 2228
                code.put_xdecref_clear(
                    entry.cname, PyrexTypes.py_object_type,
                    clear_before_decref=True,
                    nanny=False)
2229
        code.putln("/*--- Intern cleanup code ---*/")
2230 2231
        code.put_decref_clear(Naming.empty_tuple,
                              PyrexTypes.py_object_type,
2232
                              clear_before_decref=True,
2233
                              nanny=False)
2234 2235
        for entry in env.c_class_entries:
            cclass_type = entry.type
2236
            if cclass_type.is_external or cclass_type.base_type:
2237 2238 2239 2240 2241 2242 2243 2244 2245 2246
                continue
            if cclass_type.scope.directives.get('freelist', 0):
                scope = cclass_type.scope
                freelist_name = scope.mangle_internal(Naming.freelist_name)
                freecount_name = scope.mangle_internal(Naming.freecount_name)
                code.putln("while (%s > 0) {" % freecount_name)
                code.putln("PyObject* o = (PyObject*)%s[--%s];" % (
                    freelist_name, freecount_name))
                code.putln("(*Py_TYPE(o)->tp_free)(o);")
                code.putln("}")
2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259
#        for entry in env.pynum_entries:
#            code.put_decref_clear(entry.cname,
#                                  PyrexTypes.py_object_type,
#                                  nanny=False)
#        for entry in env.all_pystring_entries:
#            if entry.is_interned:
#                code.put_decref_clear(entry.pystring_cname,
#                                      PyrexTypes.py_object_type,
#                                      nanny=False)
#        for entry in env.default_entries:
#            if entry.type.is_pyobject and entry.used:
#                code.putln("Py_DECREF(%s); %s = 0;" % (
#                    code.entry_as_pyobject(entry), entry.cname))
2260 2261 2262
        code.putln('#if CYTHON_COMPILING_IN_PYPY')
        code.putln('Py_CLEAR(%s);' % Naming.builtins_cname)
        code.putln('#endif')
2263 2264
        code.put_decref_clear(env.module_dict_cname, py_object_type,
                              nanny=False, clear_before_decref=True)
2265

2266
    def generate_main_method(self, env, code):
2267
        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
2268 2269 2270 2271 2272 2273 2274 2275 2276 2277
        if Options.embed == "main":
            wmain = "wmain"
        else:
            wmain = Options.embed
        code.globalstate.use_utility_code(
            main_method.specialize(
                module_name = env.module_name,
                module_is_main = module_is_main,
                main_method = Options.embed,
                wmain_method = wmain))
2278

2279 2280
    def generate_pymoduledef_struct(self, env, code):
        if env.doc:
2281
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2282 2283
        else:
            doc = "0"
2284
        if Options.generate_cleanup_code:
Stefan Behnel's avatar
Stefan Behnel committed
2285
            cleanup_func = "(freefunc)%s" % Naming.cleanup_cname
2286 2287
        else:
            cleanup_func = 'NULL'
2288 2289 2290

        code.putln("")
        code.putln("#if PY_MAJOR_VERSION >= 3")
2291
        code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
2292 2293 2294 2295
        code.putln("#if PY_VERSION_HEX < 0x03020000")
        # fix C compiler warnings due to missing initialisers
        code.putln("  { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },")
        code.putln("#else")
2296
        code.putln("  PyModuleDef_HEAD_INIT,")
2297
        code.putln("#endif")
2298
        code.putln('  __Pyx_NAMESTR("%s"),' % env.module_name)
2299 2300 2301 2302 2303 2304
        code.putln("  %s, /* m_doc */" % doc)
        code.putln("  -1, /* m_size */")
        code.putln("  %s /* m_methods */," % env.method_table_cname)
        code.putln("  NULL, /* m_reload */")
        code.putln("  NULL, /* m_traverse */")
        code.putln("  NULL, /* m_clear */")
Stefan Behnel's avatar
Stefan Behnel committed
2305
        code.putln("  %s /* m_free */" % cleanup_func)
2306 2307 2308
        code.putln("};")
        code.putln("#endif")

2309 2310 2311 2312
    def generate_module_creation_code(self, env, code):
        # Generate code to create the module object and
        # install the builtins.
        if env.doc:
2313
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2314 2315
        else:
            doc = "0"
2316
        code.putln("#if PY_MAJOR_VERSION < 3")
2317
        code.putln(
2318
            '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % (
2319 2320 2321
                env.module_cname,
                env.module_name,
                env.method_table_cname,
2322 2323
                doc,
                env.module_cname))
2324 2325 2326 2327 2328 2329
        code.putln("#else")
        code.putln(
            "%s = PyModule_Create(&%s);" % (
                env.module_cname,
                Naming.pymoduledef_cname))
        code.putln("#endif")
2330
        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
2331 2332 2333 2334 2335
        code.putln(
            "%s = PyModule_GetDict(%s); %s" % (
                env.module_dict_cname, env.module_cname,
                code.error_goto_if_null(env.module_dict_cname, self.pos)))
        code.put_incref(env.module_dict_cname, py_object_type, nanny=False)
2336

2337
        code.putln(
2338
            '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); %s' % (
2339
                Naming.builtins_cname,
2340
                code.error_goto_if_null(Naming.builtins_cname, self.pos)))
2341 2342 2343
        code.putln('#if CYTHON_COMPILING_IN_PYPY')
        code.putln('Py_INCREF(%s);' % Naming.builtins_cname)
        code.putln('#endif')
2344
        code.putln(
2345
            'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
2346 2347 2348
                env.module_cname,
                Naming.builtins_cname,
                code.error_goto(self.pos)))
2349 2350
        if Options.pre_import is not None:
            code.putln(
2351
                '%s = PyImport_AddModule(__Pyx_NAMESTR("%s")); %s' % (
2352
                    Naming.preimport_cname,
2353 2354
                    Options.pre_import,
                    code.error_goto_if_null(Naming.preimport_cname, self.pos)))
2355

2356 2357 2358 2359
    def generate_global_init_code(self, env, code):
        # Generate code to initialise global PyObject *
        # variables to None.
        for entry in env.var_entries:
2360
            if entry.visibility != 'extern':
2361 2362
                if entry.used:
                    entry.type.global_init_code(entry, code)
2363

2364 2365
    def generate_c_variable_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2366
        entries = []
2367
        for entry in env.var_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2368 2369 2370
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2371 2372
                entries.append(entry)
        if entries:
2373
            env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c"))
2374
            for entry in entries:
2375
                signature = entry.type.declaration_code("")
2376 2377 2378
                name = code.intern_identifier(entry.name)
                code.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % (
                    name, entry.cname, signature,
2379 2380
                    code.error_goto(self.pos)))

2381 2382
    def generate_c_function_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2383
        entries = []
2384
        for entry in env.cfunc_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2385 2386 2387
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2388 2389
                entries.append(entry)
        if entries:
2390 2391
            env.use_utility_code(
                UtilityCode.load_cached("FunctionExport", "ImportExport.c"))
2392
            for entry in entries:
Mark Florisson's avatar
Mark Florisson committed
2393 2394 2395 2396 2397 2398
                signature = entry.type.signature_string()
                code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
                    entry.name,
                    entry.cname,
                    signature,
                    code.error_goto(self.pos)))
2399

2400
    def generate_type_import_code_for_module(self, module, env, code):
2401
        # Generate type import code for all exported extension types in
2402
        # an imported module.
2403 2404 2405
        #if module.c_class_entries:
        for entry in module.c_class_entries:
            if entry.defined_in_pxd:
2406
                self.generate_type_import_code(env, entry.type, entry.pos, code)
2407

2408
    def specialize_fused_types(self, pxd_env):
2409 2410 2411 2412 2413 2414 2415 2416 2417
        """
        If fused c(p)def functions are defined in an imported pxd, but not
        used in this implementation file, we still have fused entries and
        not specialized ones. This method replaces any fused entries with their
        specialized ones.
        """
        for entry in pxd_env.cfunc_entries[:]:
            if entry.type.is_fused:
                # This call modifies the cfunc_entries in-place
2418
                entry.type.get_all_specialized_function_types()
2419

2420 2421 2422 2423 2424 2425 2426
    def generate_c_variable_import_code_for_module(self, module, env, code):
        # Generate import code for all exported C functions in a cimported module.
        entries = []
        for entry in module.var_entries:
            if entry.defined_in_pxd:
                entries.append(entry)
        if entries:
2427 2428 2429 2430
            env.use_utility_code(
                UtilityCode.load_cached("ModuleImport", "ImportExport.c"))
            env.use_utility_code(
                UtilityCode.load_cached("VoidPtrImport", "ImportExport.c"))
2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
            for entry in entries:
                if env is module:
                    cname = entry.cname
                else:
                    cname = module.mangle(Naming.varptr_prefix, entry.name)
                signature = entry.type.declaration_code("")
                code.putln(
                    'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % (
                        temp, entry.name, cname, signature,
                        code.error_goto(self.pos)))
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))

2450 2451 2452 2453
    def generate_c_function_import_code_for_module(self, module, env, code):
        # Generate import code for all exported C functions in a cimported module.
        entries = []
        for entry in module.cfunc_entries:
2454
            if entry.defined_in_pxd and entry.used:
2455 2456
                entries.append(entry)
        if entries:
2457 2458 2459 2460
            env.use_utility_code(
                UtilityCode.load_cached("ModuleImport", "ImportExport.c"))
            env.use_utility_code(
                UtilityCode.load_cached("FunctionImport", "ImportExport.c"))
2461
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2462 2463 2464 2465 2466 2467
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
2468
            for entry in entries:
Mark Florisson's avatar
Mark Florisson committed
2469 2470 2471 2472 2473 2474 2475
                code.putln(
                    'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
                        temp,
                        entry.name,
                        entry.cname,
                        entry.type.signature_string(),
                        code.error_goto(self.pos)))
2476
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
2477

2478 2479 2480 2481
    def generate_type_init_code(self, env, code):
        # Generate type import code for extern extension types
        # and type ready code for non-extern ones.
        for entry in env.c_class_entries:
2482
            if entry.visibility == 'extern' and not entry.utility_code_definition:
2483 2484 2485 2486 2487 2488
                self.generate_type_import_code(env, entry.type, entry.pos, code)
            else:
                self.generate_base_type_import_code(env, entry, code)
                self.generate_exttype_vtable_init_code(entry, code)
                self.generate_type_ready_code(env, entry, code)
                self.generate_typeptr_assignment_code(entry, code)
2489

2490 2491
    def generate_base_type_import_code(self, env, entry, code):
        base_type = entry.type.base_type
2492 2493
        if (base_type and base_type.module_name != env.qualified_name and not
               base_type.is_builtin_type and not entry.utility_code_definition):
2494
            self.generate_type_import_code(env, base_type, self.pos, code)
2495

2496 2497 2498 2499 2500 2501
    def generate_type_import_code(self, env, type, pos, code):
        # If not already done, generate code to import the typeobject of an
        # extension type defined in another module, and extract its C method
        # table pointer if any.
        if type in env.types_imported:
            return
2502
        env.use_utility_code(UtilityCode.load_cached("TypeImport", "ImportExport.c"))
2503 2504
        self.generate_type_import_call(type, code,
                                       code.error_goto_if_null(type.typeptr_cname, pos))
2505
        if type.vtabptr_cname:
2506
            code.globalstate.use_utility_code(
2507
                UtilityCode.load_cached('GetVTable', 'ImportExport.c'))
2508 2509 2510 2511 2512
            code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % (
                type.vtabptr_cname,
                type.vtabstruct_cname,
                type.typeptr_cname,
                code.error_goto_if_null(type.vtabptr_cname, pos)))
2513
        env.types_imported[type] = 1
2514

2515 2516
    py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}

2517 2518 2519 2520 2521
    def generate_type_import_call(self, type, code, error_code):
        if type.typedef_flag:
            objstruct = type.objstruct_cname
        else:
            objstruct = "struct %s" % type.objstruct_cname
2522
        sizeof_objstruct = objstruct
2523
        module_name = type.module_name
2524
        condition = replacement = None
2525 2526 2527 2528
        if module_name not in ('__builtin__', 'builtins'):
            module_name = '"%s"' % module_name
        else:
            module_name = '__Pyx_BUILTIN_MODULE_NAME'
2529
            if type.name in Code.non_portable_builtins_map:
Stefan Behnel's avatar
Stefan Behnel committed
2530
                condition, replacement = Code.non_portable_builtins_map[type.name]
2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555
            if objstruct in Code.basicsize_builtins_map:
                # Some builtin types have a tp_basicsize which differs from sizeof(...):
                sizeof_objstruct = Code.basicsize_builtins_map[objstruct]

        code.put('%s = __Pyx_ImportType(%s,' % (
            type.typeptr_cname,
            module_name))

        if condition and replacement:
            code.putln("")  # start in new line
            code.putln("#if %s" % condition)
            code.putln('"%s",' % replacement)
            code.putln("#else")
            code.putln('"%s",' % type.name)
            code.putln("#endif")
        else:
            code.put(' "%s", ' % type.name)

        if sizeof_objstruct != objstruct:
            if not condition:
                code.putln("")  # start in new line
            code.putln("#if CYTHON_COMPILING_IN_PYPY")
            code.putln('sizeof(%s),' % objstruct)
            code.putln("#else")
            code.putln('sizeof(%s),' % sizeof_objstruct)
2556
            code.putln("#endif")
2557 2558 2559 2560 2561 2562
        else:
            code.put('sizeof(%s), ' % objstruct)

        code.putln('%i); %s' % (
            not type.is_external or type.is_subclassed,
            error_code))
2563

2564 2565 2566 2567 2568 2569 2570
    def generate_type_ready_code(self, env, entry, code):
        # Generate a call to PyType_Ready for an extension
        # type defined in this module.
        type = entry.type
        typeobj_cname = type.typeobj_cname
        scope = type.scope
        if scope: # could be None if there was an error
Stefan Behnel's avatar
Stefan Behnel committed
2571
            if entry.visibility != 'extern':
2572 2573 2574 2575 2576 2577
                for slot in TypeSlots.slot_table:
                    slot.generate_dynamic_init_code(scope, code)
                code.putln(
                    "if (PyType_Ready(&%s) < 0) %s" % (
                        typeobj_cname,
                        code.error_goto(entry.pos)))
Stefan Behnel's avatar
Stefan Behnel committed
2578
                # Don't inherit tp_print from builtin types, restoring the
2579 2580
                # behavior of using tp_repr or tp_str instead.
                code.putln("%s.tp_print = 0;" % typeobj_cname)
2581
                # Fix special method docstrings. This is a bit of a hack, but
2582
                # unless we let PyType_Ready create the slot wrappers we have
2583
                # a significant performance hit. (See trac #561.)
2584
                for func in entry.type.scope.pyfunc_entries:
2585 2586 2587 2588
                    is_buffer = func.name in ('__getbuffer__',
                                               '__releasebuffer__')
                    if (func.is_special and Options.docstrings and
                            func.wrapperbase_cname and not is_buffer):
2589 2590 2591 2592
                        slot = TypeSlots.method_name_to_slot[func.name]
                        preprocessor_guard = slot.preprocessor_guard_code()
                        if preprocessor_guard:
                            code.putln(preprocessor_guard)
2593
                        code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
Stefan Behnel's avatar
Stefan Behnel committed
2594
                        code.putln("{")
2595
                        code.putln(
2596
                            'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
2597 2598
                                typeobj_cname,
                                func.name,
Stefan Behnel's avatar
Stefan Behnel committed
2599
                                code.error_goto_if_null('wrapper', entry.pos)))
2600
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2601
                            "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
2602 2603
                        code.putln(
                            "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2604
                                func.wrapperbase_cname))
2605
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2606
                            "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname))
2607 2608
                        code.putln(
                            "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2609 2610 2611
                                func.wrapperbase_cname))
                        code.putln("}")
                        code.putln("}")
2612
                        code.putln('#endif')
2613 2614
                        if preprocessor_guard:
                            code.putln('#endif')
2615 2616 2617 2618 2619 2620
                if type.vtable_cname:
                    code.putln(
                        "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
                            typeobj_cname,
                            type.vtabptr_cname,
                            code.error_goto(entry.pos)))
2621
                    code.globalstate.use_utility_code(
2622
                        UtilityCode.load_cached('SetVTable', 'ImportExport.c'))
2623 2624 2625 2626 2627 2628 2629 2630 2631 2632
                if not type.scope.is_internal and not type.scope.directives['internal']:
                    # scope.is_internal is set for types defined by
                    # Cython (such as closures), the 'internal'
                    # directive is set by users
                    code.putln(
                        'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
                            Naming.module_cname,
                            scope.class_name,
                            typeobj_cname,
                            code.error_goto(entry.pos)))
2633 2634 2635 2636
                weakref_entry = scope.lookup_here("__weakref__")
                if weakref_entry:
                    if weakref_entry.type is py_object_type:
                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
2637 2638 2639 2640 2641
                        if type.typedef_flag:
                            objstruct = type.objstruct_cname
                        else:
                            objstruct = "struct %s" % type.objstruct_cname
                        code.putln("if (%s == 0) %s = offsetof(%s, %s);" % (
2642 2643
                            tp_weaklistoffset,
                            tp_weaklistoffset,
2644
                            objstruct,
2645 2646 2647
                            weakref_entry.cname))
                    else:
                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
2648

2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663
    def generate_exttype_vtable_init_code(self, entry, code):
        # Generate code to initialise the C method table of an
        # extension type.
        type = entry.type
        if type.vtable_cname:
            code.putln(
                "%s = &%s;" % (
                    type.vtabptr_cname,
                    type.vtable_cname))
            if type.base_type and type.base_type.vtabptr_cname:
                code.putln(
                    "%s.%s = *%s;" % (
                        type.vtable_cname,
                        Naming.obj_base_cname,
                        type.base_type.vtabptr_cname))
2664 2665 2666 2667

            c_method_entries = [
                entry for entry in type.scope.cfunc_entries
                if entry.func_cname ]
2668 2669 2670 2671 2672 2673 2674 2675 2676
            if c_method_entries:
                for meth_entry in c_method_entries:
                    cast = meth_entry.type.signature_cast_string()
                    code.putln(
                        "%s.%s = %s%s;" % (
                            type.vtable_cname,
                            meth_entry.cname,
                            cast,
                            meth_entry.func_cname))
2677

2678 2679 2680 2681 2682 2683 2684 2685
    def generate_typeptr_assignment_code(self, entry, code):
        # Generate code to initialise the typeptr of an extension
        # type defined in this module to point to its type object.
        type = entry.type
        if type.typeobj_cname:
            code.putln(
                "%s = &%s;" % (
                    type.typeptr_cname, type.typeobj_cname))
2686

2687
def generate_cfunction_declaration(entry, env, code, definition):
2688
    from_cy_utility = entry.used and entry.utility_code_definition
2689
    if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
2690
            or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)):
2691
        if entry.visibility == 'extern':
2692
            storage_class = Naming.extern_c_macro
2693 2694
            dll_linkage = "DL_IMPORT"
        elif entry.visibility == 'public':
2695
            storage_class = Naming.extern_c_macro
2696 2697
            dll_linkage = "DL_EXPORT"
        elif entry.visibility == 'private':
2698
            storage_class = "static"
2699 2700
            dll_linkage = None
        else:
2701
            storage_class = "static"
2702 2703 2704 2705
            dll_linkage = None
        type = entry.type

        if entry.defined_in_pxd and not definition:
2706
            storage_class = "static"
2707 2708 2709
            dll_linkage = None
            type = CPtrType(type)

2710 2711 2712 2713
        header = type.declaration_code(
            entry.cname, dll_linkage = dll_linkage)
        modifiers = code.build_function_modifiers(entry.func_modifiers)
        code.putln("%s %s%s; /*proto*/" % (
2714 2715 2716 2717
            storage_class,
            modifiers,
            header))

2718
#------------------------------------------------------------------------------------
Stefan Behnel's avatar
Stefan Behnel committed
2719 2720 2721
#
#  Runtime support code
#
2722 2723
#------------------------------------------------------------------------------------

2724 2725
streq_utility_code = UtilityCode(
proto = """
2726
static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2727 2728
""",
impl = """
2729
static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2730 2731 2732 2733 2734 2735 2736
     while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
     return *s1 == *s2;
}
""")

#------------------------------------------------------------------------------------

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2737 2738 2739 2740 2741 2742 2743
import_star_utility_code = """

/* import_all_from is an unexposed function from ceval.c */

static int
__Pyx_import_all_from(PyObject *locals, PyObject *v)
{
Robert Bradshaw's avatar
Robert Bradshaw committed
2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760
    PyObject *all = __Pyx_GetAttrString(v, "__all__");
    PyObject *dict, *name, *value;
    int skip_leading_underscores = 0;
    int pos, err;

    if (all == NULL) {
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
            return -1; /* Unexpected error */
        PyErr_Clear();
        dict = __Pyx_GetAttrString(v, "__dict__");
        if (dict == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
                return -1;
            PyErr_SetString(PyExc_ImportError,
            "from-import-* object has no __dict__ and no __all__");
            return -1;
        }
2761 2762 2763
#if PY_MAJOR_VERSION < 3
        all = PyObject_CallMethod(dict, (char *)"keys", NULL);
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2764
        all = PyMapping_Keys(dict);
2765
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781
        Py_DECREF(dict);
        if (all == NULL)
            return -1;
        skip_leading_underscores = 1;
    }

    for (pos = 0, err = 0; ; pos++) {
        name = PySequence_GetItem(all, pos);
        if (name == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_IndexError))
                err = -1;
            else
                PyErr_Clear();
            break;
        }
        if (skip_leading_underscores &&
2782
#if PY_MAJOR_VERSION < 3
Robert Bradshaw's avatar
Robert Bradshaw committed
2783 2784
            PyString_Check(name) &&
            PyString_AS_STRING(name)[0] == '_')
2785
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2786 2787
            PyUnicode_Check(name) &&
            PyUnicode_AS_UNICODE(name)[0] == '_')
2788
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806
        {
            Py_DECREF(name);
            continue;
        }
        value = PyObject_GetAttr(v, name);
        if (value == NULL)
            err = -1;
        else if (PyDict_CheckExact(locals))
            err = PyDict_SetItem(locals, name, value);
        else
            err = PyObject_SetItem(locals, name, value);
        Py_DECREF(name);
        Py_XDECREF(value);
        if (err != 0)
            break;
    }
    Py_DECREF(all);
    return err;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2807 2808 2809
}


2810
static int %(IMPORT_STAR)s(PyObject* m) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2811 2812 2813

    int i;
    int ret = -1;
2814
    char* s;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2815 2816
    PyObject *locals = 0;
    PyObject *list = 0;
2817 2818 2819
#if PY_MAJOR_VERSION >= 3
    PyObject *utf8_name = 0;
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2820 2821
    PyObject *name;
    PyObject *item;
2822

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2823 2824 2825
    locals = PyDict_New();              if (!locals) goto bad;
    if (__Pyx_import_all_from(locals, m) < 0) goto bad;
    list = PyDict_Items(locals);        if (!list) goto bad;
2826

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2827 2828 2829
    for(i=0; i<PyList_GET_SIZE(list); i++) {
        name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
        item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2830 2831 2832 2833 2834 2835
#if PY_MAJOR_VERSION >= 3
        utf8_name = PyUnicode_AsUTF8String(name);
        if (!utf8_name) goto bad;
        s = PyBytes_AS_STRING(utf8_name);
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
        Py_DECREF(utf8_name); utf8_name = 0;
2836
#else
2837
        s = PyString_AsString(name);
2838 2839
        if (!s) goto bad;
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2840
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2841 2842
    }
    ret = 0;
2843

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2844 2845 2846
bad:
    Py_XDECREF(locals);
    Py_XDECREF(list);
2847 2848 2849
#if PY_MAJOR_VERSION >= 3
    Py_XDECREF(utf8_name);
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2850 2851
    return ret;
}
2852 2853
""" % {'IMPORT_STAR'     : Naming.import_star,
       'IMPORT_STAR_SET' : Naming.import_star_set }
2854

2855
refnanny_utility_code = UtilityCode.load_cached("Refnanny", "ModuleSetupCode.c")
Robert Bradshaw's avatar
Robert Bradshaw committed
2856

2857 2858
main_method = UtilityCode(
impl = """
2859 2860 2861 2862 2863
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif

#if PY_MAJOR_VERSION < 3
2864
int %(main_method)s(int argc, char** argv) {
2865
#elif defined(WIN32) || defined(MS_WINDOWS)
2866
int %(wmain_method)s(int argc, wchar_t **argv) {
2867 2868
#else
static int __Pyx_main(int argc, wchar_t **argv) {
2869
#endif
2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880
    /* 754 requires that FP exceptions run in "no stop" mode by default,
     * and until C vendors implement C99's ways to control FP exceptions,
     * Python requires non-stop mode.  Alas, some platforms enable FP
     * exceptions by default.  Here we disable them.
     */
#ifdef __FreeBSD__
    fp_except_t m;

    m = fpgetmask();
    fpsetmask(m & ~FP_X_OFL);
#endif
2881
    if (argc && argv)
2882
        Py_SetProgramName(argv[0]);
2883
    Py_Initialize();
2884
    if (argc && argv)
2885
        PySys_SetArgv(argc, argv);
2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901
    { /* init module '%(module_name)s' as '__main__' */
      PyObject* m = NULL;
      %(module_is_main)s = 1;
      #if PY_MAJOR_VERSION < 3
          init%(module_name)s();
      #else
          m = PyInit_%(module_name)s();
      #endif
      if (PyErr_Occurred()) {
          PyErr_Print(); /* This exits with the right code if SystemExit. */
          #if PY_MAJOR_VERSION < 3
          if (Py_FlushLine()) PyErr_Clear();
          #endif
          return 1;
      }
      Py_XDECREF(m);
2902
    }
2903
    Py_Finalize();
2904
    return 0;
2905
}
2906 2907 2908 2909 2910 2911 2912 2913


#if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
#include <locale.h>

static wchar_t*
__Pyx_char2wchar(char* arg)
{
Vitja Makarov's avatar
Vitja Makarov committed
2914
    wchar_t *res;
2915
#ifdef HAVE_BROKEN_MBSTOWCS
Vitja Makarov's avatar
Vitja Makarov committed
2916 2917 2918 2919 2920
    /* Some platforms have a broken implementation of
     * mbstowcs which does not count the characters that
     * would result from conversion.  Use an upper bound.
     */
    size_t argsize = strlen(arg);
2921
#else
Vitja Makarov's avatar
Vitja Makarov committed
2922
    size_t argsize = mbstowcs(NULL, arg, 0);
2923
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2924 2925 2926
    size_t count;
    unsigned char *in;
    wchar_t *out;
2927
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
2928
    mbstate_t mbs;
2929
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947
    if (argsize != (size_t)-1) {
        res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
        if (!res)
            goto oom;
        count = mbstowcs(res, arg, argsize+1);
        if (count != (size_t)-1) {
            wchar_t *tmp;
            /* Only use the result if it contains no
               surrogate characters. */
            for (tmp = res; *tmp != 0 &&
                     (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
                ;
            if (*tmp == 0)
                return res;
        }
        free(res);
    }
    /* Conversion failed. Fall back to escaping with surrogateescape. */
2948
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992
    /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */

    /* Overallocate; as multi-byte characters are in the argument, the
       actual output could use less memory. */
    argsize = strlen(arg) + 1;
    res = malloc(argsize*sizeof(wchar_t));
    if (!res) goto oom;
    in = (unsigned char*)arg;
    out = res;
    memset(&mbs, 0, sizeof mbs);
    while (argsize) {
        size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
        if (converted == 0)
            /* Reached end of string; null char stored. */
            break;
        if (converted == (size_t)-2) {
            /* Incomplete character. This should never happen,
               since we provide everything that we have -
               unless there is a bug in the C library, or I
               misunderstood how mbrtowc works. */
            fprintf(stderr, "unexpected mbrtowc result -2\\n");
            return NULL;
        }
        if (converted == (size_t)-1) {
            /* Conversion error. Escape as UTF-8b, and start over
               in the initial shift state. */
            *out++ = 0xdc00 + *in++;
            argsize--;
            memset(&mbs, 0, sizeof mbs);
            continue;
        }
        if (*out >= 0xd800 && *out <= 0xdfff) {
            /* Surrogate character.  Escape the original
               byte sequence with surrogateescape. */
            argsize -= converted;
            while (converted--)
                *out++ = 0xdc00 + *in++;
            continue;
        }
        /* successfully converted some bytes */
        in += converted;
        argsize -= converted;
        out++;
    }
2993
#else
Vitja Makarov's avatar
Vitja Makarov committed
2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006
    /* Cannot use C locale for escaping; manually escape as if charset
       is ASCII (i.e. escape all bytes > 128. This will still roundtrip
       correctly in the locale's charset, which must be an ASCII superset. */
    res = malloc((strlen(arg)+1)*sizeof(wchar_t));
    if (!res) goto oom;
    in = (unsigned char*)arg;
    out = res;
    while(*in)
        if(*in < 128)
            *out++ = *in++;
        else
            *out++ = 0xdc00 + *in++;
    *out = 0;
3007
#endif
Vitja Makarov's avatar
Vitja Makarov committed
3008
    return res;
3009
oom:
Vitja Makarov's avatar
Vitja Makarov committed
3010 3011
    fprintf(stderr, "out of memory\\n");
    return NULL;
3012 3013 3014
}

int
3015
%(main_method)s(int argc, char **argv)
3016
{
3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046
    if (!argc) {
        return __Pyx_main(0, NULL);
    }
    else {
        wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
        /* We need a second copies, as Python might modify the first one. */
        wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
        int i, res;
        char *oldloc;
        if (!argv_copy || !argv_copy2) {
            fprintf(stderr, "out of memory\\n");
            return 1;
        }
        oldloc = strdup(setlocale(LC_ALL, NULL));
        setlocale(LC_ALL, "");
        for (i = 0; i < argc; i++) {
            argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]);
            if (!argv_copy[i])
                return 1;
        }
        setlocale(LC_ALL, oldloc);
        free(oldloc);
        res = __Pyx_main(argc, argv_copy);
        for (i = 0; i < argc; i++) {
            free(argv_copy2[i]);
        }
        free(argv_copy);
        free(argv_copy2);
        return res;
    }
3047 3048
}
#endif
3049
""")
3050 3051 3052 3053 3054 3055 3056

packed_struct_utility_code = UtilityCode(proto="""
#if defined(__GNUC__)
#define __Pyx_PACKED __attribute__((__packed__))
#else
#define __Pyx_PACKED
#endif
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
3057
""", impl="", proto_block='utility_code_proto_before_types')
3058

3059
capsule_utility_code = UtilityCode.load("Capsule")