ModuleNode.py 120 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)
349
        rootwriter.copyto(f)
350
        if options.gdb_debug:
Mark Florisson's avatar
Mark Florisson committed
351
            self._serialize_lineno_map(env, rootwriter)
352 353
        f.close()
        result.c_file_generated = 1
354
        if Options.annotate or options.annotate:
355 356
            self.annotate(rootwriter)
            rootwriter.save_annotation(result.main_source_file, result.c_file)
357

Mark Florisson's avatar
Mark Florisson committed
358
    def _serialize_lineno_map(self, env, ccodewriter):
359
        tb = env.context.gdb_debug_outputwriter
Mark Florisson's avatar
Mark Florisson committed
360
        markers = ccodewriter.buffer.allmarkers()
361

Mark Florisson's avatar
Mark Florisson committed
362
        d = {}
363
        for c_lineno, cython_lineno in enumerate(markers):
Mark Florisson's avatar
Mark Florisson committed
364 365
            if cython_lineno > 0:
                d.setdefault(cython_lineno, []).append(c_lineno + 1)
366

Mark Florisson's avatar
Mark Florisson committed
367 368 369 370 371 372 373 374 375 376
        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()
377

378 379 380 381 382 383
    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
384

385 386 387 388 389 390 391 392 393
    def sort_types_by_inheritance(self, type_dict, getkey):
        # copy the types into a list moving each parent type before
        # its first child
        type_items = type_dict.items()
        type_list = []
        for i, item in enumerate(type_items):
            key, new_entry = item

            # collect all base classes to check for children
394
            hierarchy = set()
395
            base = new_entry
396 397 398 399 400 401 402
            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)
403
            new_entry.base_keys = hierarchy
404

405
            # find the first (sub-)subclass and insert before that
406 407
            for j in range(i):
                entry = type_list[j]
408
                if key in entry.base_keys:
409 410 411 412 413 414 415
                    type_list.insert(j, new_entry)
                    break
            else:
                type_list.append(new_entry)
        return type_list

    def sort_type_hierarchy(self, module_list, env):
Gary Furnish's avatar
Gary Furnish committed
416
        vtab_dict = {}
417
        vtabslot_dict = {}
Gary Furnish's avatar
Gary Furnish committed
418 419 420 421 422
        for module in module_list:
            for entry in module.c_class_entries:
                if not entry.in_cinclude:
                    type = entry.type
                    if type.vtabstruct_cname:
423 424 425 426
                        vtab_dict[type.vtabstruct_cname] = entry
            all_defined_here = module is env
            for entry in module.type_entries:
                if all_defined_here or entry.defined_in_pxd:
Gary Furnish's avatar
Gary Furnish committed
427
                    type = entry.type
428 429 430
                    if type.is_extension_type and not entry.in_cinclude:
                        type = entry.type
                        vtabslot_dict[type.objstruct_cname] = entry
431

432 433
        def vtabstruct_cname(entry_type):
            return entry_type.vtabstruct_cname
434 435
        vtab_list = self.sort_types_by_inheritance(
            vtab_dict, vtabstruct_cname)
436 437 438

        def objstruct_cname(entry_type):
            return entry_type.objstruct_cname
439 440
        vtabslot_list = self.sort_types_by_inheritance(
            vtabslot_dict, objstruct_cname)
441

442
        return (vtab_list, vtabslot_list)
443

444
    def sort_cdef_classes(self, env):
445
        key_func = operator.attrgetter('objstruct_cname')
446 447
        entry_dict = {}
        for entry in env.c_class_entries:
Stefan Behnel's avatar
Stefan Behnel committed
448 449 450
            key = key_func(entry.type)
            assert key not in entry_dict
            entry_dict[key] = entry
451 452
        env.c_class_entries[:] = self.sort_types_by_inheritance(
            entry_dict, key_func)
453

Gary Furnish's avatar
Gary Furnish committed
454
    def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
455 456 457
        # TODO: Why are these separated out?
        for entry in vtabslot_list:
            self.generate_objstruct_predeclaration(entry.type, code)
458
        vtabslot_entries = set(vtabslot_list)
Gary Furnish's avatar
Gary Furnish committed
459 460 461 462 463 464 465 466 467
        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)
468
            type_entries = [t for t in type_entries if t not in vtabslot_entries]
469
            self.generate_type_header_code(type_entries, code)
Gary Furnish's avatar
Gary Furnish committed
470
        for entry in vtabslot_list:
471
            self.generate_objstruct_definition(entry.type, code)
472
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
473
        for entry in vtab_list:
474
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
475 476
            self.generate_exttype_vtable_struct(entry, code)
            self.generate_exttype_vtabptr_declaration(entry, code)
477
            self.generate_exttype_final_methods_declaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
478

479 480 481
    def generate_declarations_for_modules(self, env, modules, globalstate):
        typecode = globalstate['type_declarations']
        typecode.putln("")
482
        typecode.putln("/*--- Type declarations ---*/")
483 484 485 486 487 488 489
        # 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')
490 491
        vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
        self.generate_type_definitions(
492 493
            env, modules, vtab_list, vtabslot_list, typecode)
        modulecode = globalstate['module_declarations']
Gary Furnish's avatar
Gary Furnish committed
494
        for module in modules:
495
            defined_here = module is env
496 497 498 499 500
            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
501

502
    def generate_module_preamble(self, env, cimported_modules, code):
503
        code.putln("/* Generated by Cython %s */" % Version.watermark)
504 505
        code.putln("")
        code.putln("#define PY_SSIZE_T_CLEAN")
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526

        # 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")

527 528
        for filename in env.python_include_files:
            code.putln('#include "%s"' % filename)
529 530
        code.putln("#ifndef Py_PYTHON_H")
        code.putln("    #error Python headers needed to compile C extensions, please install development version of Python.")
Robert Bradshaw's avatar
Robert Bradshaw committed
531
        code.putln("#elif PY_VERSION_HEX < 0x02040000")
532
        code.putln("    #error Cython requires Python 2.4+.")
533 534
        code.putln("#else")
        code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
535

536
        code.put(UtilityCode.load_as_string("CModulePreamble", "ModuleSetupCode.c")[1])
537 538 539

        code.put("""
#if PY_MAJOR_VERSION >= 3
540 541 542 543
  #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
544 545
        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
546
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)")
Robert Bradshaw's avatar
Robert Bradshaw committed
547 548
        else:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
549
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)")
550
        code.putln("#endif")
551

552
        code.putln("")
553
        self.generate_extern_c_macro_definition(code)
554
        code.putln("")
555

556 557 558
        code.putln("#if defined(WIN32) || defined(MS_WINDOWS)")
        code.putln("#define _USE_MATH_DEFINES")
        code.putln("#endif")
559
        code.putln("#include <math.h>")
560

561
        code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env))
562
        code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
563
        self.generate_includes(env, cimported_modules, code)
564 565 566 567 568
        code.putln("")
        code.putln("#ifdef PYREX_WITHOUT_ASSERTIONS")
        code.putln("#define CYTHON_WITHOUT_ASSERTIONS")
        code.putln("#endif")
        code.putln("")
569

570 571 572 573
        if env.directives['ccomplex']:
            code.putln("")
            code.putln("#if !defined(CYTHON_CCOMPLEX)")
            code.putln("#define CYTHON_CCOMPLEX 1")
574
            code.putln("#endif")
575
            code.putln("")
576
        code.put(UtilityCode.load_as_string("UtilityFunctionPredeclarations", "ModuleSetupCode.c")[0])
577 578 579 580 581 582

        c_string_type = env.directives['c_string_type']
        c_string_encoding = env.directives['c_string_encoding']
        if c_string_type != 'bytes' and not c_string_encoding:
            error(self.pos, "a default encoding must be provided if c_string_type != bytes")
        code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII %s' % int(c_string_encoding == 'ascii'))
583 584 585 586 587
        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)
588 589
        code.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_type.title())
        code.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_type.title())
590
        code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0])
591
        
Robert Bradshaw's avatar
Robert Bradshaw committed
592
        code.put(Nodes.branch_prediction_macros)
593 594
        code.putln('')
        code.putln('static PyObject *%s;' % env.module_cname)
595
        code.putln('static PyObject *%s;' % env.module_dict_cname)
596
        code.putln('static PyObject *%s;' % Naming.builtins_cname)
Robert Bradshaw's avatar
Robert Bradshaw committed
597
        code.putln('static PyObject *%s;' % Naming.empty_tuple)
Robert Bradshaw's avatar
Robert Bradshaw committed
598
        code.putln('static PyObject *%s;' % Naming.empty_bytes)
599 600
        if Options.pre_import is not None:
            code.putln('static PyObject *%s;' % Naming.preimport_cname)
601
        code.putln('static int %s;' % Naming.lineno_cname)
602
        code.putln('static int %s = 0;' % Naming.clineno_cname)
603 604
        code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
        code.putln('static const char *%s;' % Naming.filename_cname)
605

606 607 608 609 610 611
        # XXX this is a mess
        for utility_code in PyrexTypes.c_int_from_py_function.specialize_list:
            env.use_utility_code(utility_code)
        for utility_code in PyrexTypes.c_long_from_py_function.specialize_list:
            env.use_utility_code(utility_code)

612 613
    def generate_extern_c_macro_definition(self, code):
        name = Naming.extern_c_macro
614 615 616 617 618 619
        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")
620 621 622
        code.putln("#endif")

    def generate_includes(self, env, cimported_modules, code):
623
        includes = []
Robert Bradshaw's avatar
Robert Bradshaw committed
624
        for filename in env.include_files:
Stefan Behnel's avatar
Stefan Behnel committed
625 626 627
            byte_decoded_filenname = str(filename)
            if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
                code.putln('#include %s' % byte_decoded_filenname)
628
            else:
Stefan Behnel's avatar
Stefan Behnel committed
629
                code.putln('#include "%s"' % byte_decoded_filenname)
630

631 632
        code.putln_openmp("#include <omp.h>")

633 634
    def generate_filename_table(self, code):
        code.putln("")
Robert Bradshaw's avatar
Robert Bradshaw committed
635
        code.putln("static const char *%s[] = {" % Naming.filetable_cname)
636 637
        if code.globalstate.filename_list:
            for source_desc in code.globalstate.filename_list:
638
                filename = os.path.basename(source_desc.get_filenametable_entry())
639
                escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
Robert Bradshaw's avatar
Robert Bradshaw committed
640
                code.putln('"%s",' % escaped_filename)
641 642 643 644
        else:
            # Some C compilers don't like an empty array
            code.putln("0")
        code.putln("};")
645 646 647 648

    def generate_type_predeclarations(self, env, code):
        pass

649
    def generate_type_header_code(self, type_entries, code):
650 651
        # Generate definitions of structs/unions/enums/typedefs/objstructs.
        #self.generate_gcc33_hack(env, code) # Is this still needed?
652
        # Forward declarations
653
        for entry in type_entries:
654
            if not entry.in_cinclude:
655
                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
656
                type = entry.type
657
                if type.is_typedef: # Must test this first!
658
                    pass
659
                elif type.is_struct_or_union or type.is_cpp_class:
660 661 662 663 664 665 666 667 668 669
                    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)
670
                elif type.is_enum:
671
                    self.generate_enum_definition(entry, code)
672 673
                elif type.is_struct_or_union:
                    self.generate_struct_union_definition(entry, code)
674 675
                elif type.is_cpp_class:
                    self.generate_cpp_class_definition(entry, code)
676
                elif type.is_extension_type:
677
                    self.generate_objstruct_definition(type, code)
678

679 680 681 682 683 684 685 686 687 688 689 690 691
    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))
692

693 694
    def generate_typedef(self, entry, code):
        base_type = entry.type.typedef_base_type
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
695
        if base_type.is_numeric:
696 697 698 699
            try:
                writer = code.globalstate['numeric_typedefs']
            except KeyError:
                writer = code
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
700 701
        else:
            writer = code
702
        writer.mark_pos(entry.pos)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
703
        writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
704

705
    def sue_predeclaration(self, type, kind, name):
706
        if type.typedef_flag:
707 708 709
            return "%s %s;\ntypedef %s %s %s;" % (
                kind, name,
                kind, name, name)
710
        else:
711 712 713 714
            return "%s %s;" % (kind, name)

    def generate_struct_union_predeclaration(self, entry, code):
        type = entry.type
715
        if type.is_cpp_class and type.templates:
716
            code.putln("template <typename %s>" % ", typename ".join([T.declaration_code("") for T in type.templates]))
717 718 719 720 721
        code.putln(self.sue_predeclaration(type, type.kind, type.cname))

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

724
    def generate_struct_union_definition(self, entry, code):
725
        code.mark_pos(entry.pos)
726 727 728
        type = entry.type
        scope = type.scope
        if scope:
729 730 731 732 733
            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)
734
            header, footer = \
735 736
                self.sue_header_footer(type, kind, type.cname)
            if packed:
737 738 739 740
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack(1)")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(push, 1)")
741
                code.putln("#endif")
742 743 744 745 746 747 748 749 750 751 752
            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)
753
            if packed:
754 755 756 757
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack()")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(pop)")
758
                code.putln("#endif")
759

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
    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(" {")
            for attr in scope.var_entries:
775
                if attr.type.is_cfunction and attr.name != "<init>":
776 777 778 779 780 781
                    code.put("virtual ")
                code.putln(
                    "%s;" %
                        attr.type.declaration_code(attr.cname))
            code.putln("};")

782
    def generate_enum_definition(self, entry, code):
783
        code.mark_pos(entry.pos)
784 785 786 787 788 789 790 791 792 793 794 795
        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]
796
            # this does not really generate code, just builds the result value
797
            for value_entry in enum_values:
798 799 800 801 802
                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:
803 804 805 806
                    value_code = value_entry.cname
                else:
                    value_code = ("%s = %s" % (
                        value_entry.cname,
807
                        value_entry.value_node.result()))
808 809 810 811
                if value_entry is not last_entry:
                    value_code += ","
                code.putln(value_code)
        code.putln(footer)
812 813 814
        if entry.type.typedef_flag:
            # Not pre-declared.
            code.putln("typedef enum %s %s;" % (name, name))
815

816
    def generate_typeobj_predeclaration(self, entry, code):
817 818 819 820
        code.putln("")
        name = entry.type.typeobj_cname
        if name:
            if entry.visibility == 'extern' and not entry.in_cinclude:
821
                code.putln("%s %s %s;" % (
822
                    Naming.extern_c_macro,
823
                    PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
824 825
                    name))
            elif entry.visibility == 'public':
826
                code.putln("%s %s %s;" % (
827
                    Naming.extern_c_macro,
828
                    PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"),
829 830 831
                    name))
            # ??? Do we really need the rest of this? ???
            #else:
832
            #    code.putln("static PyTypeObject %s;" % name)
833

834
    def generate_exttype_vtable_struct(self, entry, code):
835 836 837
        if not entry.used:
            return

838
        code.mark_pos(entry.pos)
839 840 841
        # Generate struct declaration for an extension type's vtable.
        type = entry.type
        scope = type.scope
842 843 844

        self.specialize_fused_types(scope)

845 846 847 848 849 850 851 852 853 854 855 856
        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(
857
                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname))
858 859
            code.putln(
                "};")
860

861
    def generate_exttype_vtabptr_declaration(self, entry, code):
862 863 864
        if not entry.used:
            return

865
        code.mark_pos(entry.pos)
866 867 868 869 870 871
        # 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))
872

873 874 875 876 877 878 879 880 881 882 883
    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)
884 885
                modifiers = code.build_function_modifiers(method_entry.func_modifiers)
                code.putln("static %s%s;" % (modifiers, declaration))
886

887 888 889 890
    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
891

892
    def generate_objstruct_definition(self, type, code):
893
        code.mark_pos(type.pos)
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
        # 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:
            code.putln(
                "%s%s %s;" % (
                    ("struct ", "")[base_type.typedef_flag],
                    base_type.objstruct_cname,
                    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:
917 918 919 920
            if attr.is_declared_generic:
                attr_type = py_object_type
            else:
                attr_type = attr.type
921 922
            code.putln(
                "%s;" %
923
                    attr_type.declaration_code(attr.cname))
924
        code.putln(footer)
925 926 927
        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))
928

929
    def generate_c_class_declarations(self, env, code, definition):
930
        for entry in env.c_class_entries:
931
            if definition or entry.defined_in_pxd:
932
                code.putln("static PyTypeObject *%s = 0;" %
933
                    entry.type.typeptr_cname)
934

935
    def generate_cvariable_declarations(self, env, code, definition):
936 937
        if env.is_cython_builtin:
            return
938 939 940 941
        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))):
942
                continue
943 944 945 946 947 948 949 950 951 952

            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':
953
                storage_class = Naming.extern_c_macro
954 955 956 957 958 959
                if definition:
                    dll_linkage = "DL_EXPORT"
                else:
                    dll_linkage = "DL_IMPORT"
            elif entry.visibility == 'private':
                storage_class = "static"
960 961 962 963 964
                dll_linkage = None
                if entry.init is not None:
                    init =  entry.type.literal_code(entry.init)
            type = entry.type
            cname = entry.cname
965 966 967 968

            if entry.defined_in_pxd and not definition:
                storage_class = "static"
                dll_linkage = None
969
                type = CPtrType(type)
970 971 972 973 974 975 976 977 978 979 980 981 982 983
                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):
984
        for entry in env.cfunc_entries:
985
            if entry.used or (entry.visibility == 'public' or entry.api):
986
                generate_cfunction_declaration(entry, env, code, definition)
987

988 989
    def generate_variable_definitions(self, env, code):
        for entry in env.var_entries:
Vitja Makarov's avatar
Vitja Makarov committed
990
            if (not entry.in_cinclude and
991 992 993 994 995 996 997
                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(";")

998 999 1000 1001 1002
    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
1003
            if entry.visibility != 'extern':
1004 1005 1006 1007
                type = entry.type
                scope = type.scope
                if scope: # could be None if there was an error
                    self.generate_exttype_vtable(scope, code)
1008
                    self.generate_new_function(scope, code, entry)
1009
                    self.generate_dealloc_function(scope, code)
1010
                    if scope.needs_gc():
1011 1012
                        self.generate_traverse_function(scope, code, entry)
                        self.generate_clear_function(scope, code, entry)
1013 1014 1015 1016
                    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)
1017 1018 1019 1020 1021
                    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")
1022 1023
                    if scope.defines_any(["__setslice__", "__delslice__"]):
                        self.generate_ass_slice_function(scope, code)
1024
                    if scope.defines_any(["__getattr__","__getattribute__"]):
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
                        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)
1036

1037 1038 1039 1040 1041 1042 1043
    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))
1044

1045 1046 1047 1048 1049 1050
    def generate_self_cast(self, scope, code):
        type = scope.parent_type
        code.putln(
            "%s = (%s)o;" % (
                type.declaration_code("p"),
                type.declaration_code("")))
1051

1052
    def generate_new_function(self, scope, code, cclass_entry):
1053 1054
        tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
        slot_func = scope.mangle_internal("tp_new")
1055 1056
        type = scope.parent_type
        base_type = type.base_type
1057

1058 1059
        have_entries, (py_attrs, py_buffers, memoryview_slices) = \
                        scope.get_refcounted_entries(include_weakref=True)
Robert Bradshaw's avatar
Robert Bradshaw committed
1060
        cpp_class_attrs = [entry for entry in scope.var_entries if entry.type.is_cpp_class]
1061

1062 1063 1064 1065 1066 1067 1068
        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 '

1069 1070 1071 1072 1073 1074 1075
        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)

1076 1077 1078
        decls = code.globalstate['decls']
        decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" %
                    slot_func)
1079
        code.putln("")
1080 1081 1082 1083 1084 1085
        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("")
1086
        code.putln(
1087
            "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {"
1088 1089 1090
                % (slot_func, unused_marker, unused_marker))

        need_self_cast = type.vtabslot_cname or have_entries or cpp_class_attrs
1091
        if need_self_cast:
1092
            code.putln("%s;" % scope.parent_type.declaration_code("p"))
1093
        if base_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
1094 1095
            tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
            if tp_new is None:
1096
                tp_new = "%s->tp_new" % base_type.typeptr_cname
1097
            code.putln("PyObject *o = %s(t, a, k);" % tp_new)
1098
        else:
1099 1100
            code.putln("PyObject *o;")
            if freelist_size:
1101 1102 1103
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
                obj_struct = type.declaration_code("", deref=True)
1104
                code.putln("if (likely((%s > 0) & (t->tp_basicsize == sizeof(%s)))) {" % (
1105
                    freecount_name, obj_struct))
1106 1107
                code.putln("o = (PyObject*)%s[--%s];" % (
                    freelist_name, freecount_name))
1108
                code.putln("memset(o, 0, sizeof(%s));" % obj_struct)
1109
                code.putln("PyObject_INIT(o, t);")
1110 1111 1112 1113
                if scope.needs_gc():
                    code.putln("PyObject_GC_Track(o);")
                code.putln("} else {")
            code.putln("o = (*t->tp_alloc)(t, 0);")
1114
        code.putln("if (unlikely(!o)) return 0;")
1115 1116
        if freelist_size and not base_type:
            code.putln('}')
1117
        if need_self_cast:
1118
            code.putln("p = %s;" % type.cast_code("o"))
1119
        #if need_self_cast:
Robert Bradshaw's avatar
Robert Bradshaw committed
1120
        #    self.generate_self_cast(scope, code)
1121
        if type.vtabslot_cname:
1122 1123 1124 1125 1126
            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
1127 1128 1129
            else:
                struct_type_cast = ""
            code.putln("p->%s = %s%s;" % (
1130
                type.vtabslot_cname,
1131
                struct_type_cast, type.vtabptr_cname))
1132

Robert Bradshaw's avatar
Robert Bradshaw committed
1133 1134
        for entry in cpp_class_attrs:
            code.putln("new((void*)&(p->%s)) %s();" % 
1135
                       (entry.cname, entry.type.declaration_code("")))
1136

1137
        for entry in py_attrs:
1138 1139
            if scope.is_internal or entry.name == "__weakref__":
                # internal classes do not need None inits
1140
                code.putln("p->%s = 0;" % entry.cname)
1141
            else:
1142
                code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
1143

1144
        for entry in memoryview_slices:
1145
            code.putln("p->%s.data = NULL;" % entry.cname)
1146
            code.putln("p->%s.memview = NULL;" % entry.cname)
1147 1148 1149 1150 1151 1152 1153

        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;")

1154 1155
        if new_func_entry and new_func_entry.is_special:
            if new_func_entry.trivial_signature:
1156 1157 1158
                cinit_args = "o, %s, NULL" % Naming.empty_tuple
            else:
                cinit_args = "o, a, k"
1159
            code.putln(
1160
                "if (unlikely(%s(%s) < 0)) {" %
1161
                    (new_func_entry.func_cname, cinit_args))
1162
            code.put_decref_clear("o", py_object_type, nanny=False)
1163 1164 1165 1166 1167 1168
            code.putln(
                "}")
        code.putln(
            "return o;")
        code.putln(
            "}")
1169

1170
    def generate_dealloc_function(self, scope, code):
1171 1172
        tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
        slot_func = scope.mangle_internal("tp_dealloc")
1173
        base_type = scope.parent_type.base_type
1174 1175
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1176 1177

        slot_func_cname = scope.mangle_internal("tp_dealloc")
1178 1179
        code.putln("")
        code.putln(
1180
            "static void %s(PyObject *o) {" % slot_func_cname)
1181

1182
        weakref_slot = scope.lookup_here("__weakref__")
1183
        _, (py_attrs, _, memoryview_slices) = scope.get_refcounted_entries()
Robert Bradshaw's avatar
Robert Bradshaw committed
1184
        cpp_class_attrs = [entry for entry in scope.var_entries if entry.type.is_cpp_class]
1185

Robert Bradshaw's avatar
Robert Bradshaw committed
1186 1187 1188 1189
        if (py_attrs
            or cpp_class_attrs
            or memoryview_slices
            or weakref_slot in scope.var_entries):
1190
            self.generate_self_cast(scope, code)
1191 1192 1193 1194
        
        # We must mark ths object as (gc) untracked while tearing it down, lest
        # the garbage collection is invoked while running this destructor.
        if scope.needs_gc():
1195
            code.putln("PyObject_GC_UnTrack(o);")
1196 1197

        # call the user's __dealloc__
1198
        self.generate_usr_dealloc_call(scope, code)
1199
        if weakref_slot in scope.var_entries:
1200
            code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
1201

Robert Bradshaw's avatar
Robert Bradshaw committed
1202
        for entry in cpp_class_attrs:
1203 1204 1205 1206 1207
            split_cname = entry.type.cname.split('::')
            destructor_name = split_cname.pop()
            # Make sure the namespace delimiter was not in a template arg.
            while destructor_name.count('<') != destructor_name.count('>'):
                destructor_name = split_cname.pop() + '::' + destructor_name
Olivier Parcollet's avatar
Olivier Parcollet committed
1208
            destructor_name = destructor_name.split('<',1)[0]
1209 1210
            code.putln("p->%s.%s::~%s();" %
                (entry.cname, entry.type.declaration_code(""), destructor_name))
1211

1212
        for entry in py_attrs:
1213 1214
            code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False,
                                   clear_before_decref=True)
1215 1216 1217 1218 1219

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

1220
        if base_type:
1221 1222 1223 1224 1225
            # The base class deallocator probably expects this to be tracked, so
            # undo the untracking above.
            if scope.needs_gc():
                code.putln("PyObject_GC_Track(o);")

Robert Bradshaw's avatar
Robert Bradshaw committed
1226
            tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
1227 1228
            if tp_dealloc is not None:
                code.putln("%s(o);" % tp_dealloc)
1229 1230
            elif base_type.is_builtin_type:
                code.putln("%s->tp_dealloc(o);" % base_type.typeptr_cname)
1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
            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
                code.putln("if (likely(%s)) %s->tp_dealloc(o); else __Pyx_call_next_tp_dealloc(o, %s);" % (
                    base_cname, base_cname, slot_func_cname))
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("CallNextTpDealloc", "ExtensionTypes.c"))
1241
        else:
1242 1243 1244 1245 1246 1247
            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
1248 1249
                code.putln("if ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))) {" % (
                    freecount_name, freelist_size, type.declaration_code("", deref=True)))
1250 1251 1252 1253 1254 1255
                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("}")
1256 1257
        code.putln(
            "}")
1258

1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
    def generate_usr_dealloc_call(self, scope, code):
        entry = scope.lookup_here("__dealloc__")
        if entry:
            code.putln(
                "{")
            code.putln(
                    "PyObject *etype, *eval, *etb;")
            code.putln(
                    "PyErr_Fetch(&etype, &eval, &etb);")
            code.putln(
1269
                    "++Py_REFCNT(o);")
1270
            code.putln(
1271
                    "%s(o);" %
1272 1273 1274 1275
                        entry.func_cname)
            code.putln(
                    "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
            code.putln(
1276
                    "--Py_REFCNT(o);")
1277 1278 1279 1280
            code.putln(
                    "PyErr_Restore(etype, eval, etb);")
            code.putln(
                "}")
1281

1282
    def generate_traverse_function(self, scope, code, cclass_entry):
1283 1284
        tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
        slot_func = scope.mangle_internal("tp_traverse")
1285
        base_type = scope.parent_type.base_type
1286 1287
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1288 1289 1290
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, visitproc v, void *a) {"
1291
                % slot_func)
1292

1293 1294
        have_entries, (py_attrs, py_buffers, memoryview_slices) = (
            scope.get_refcounted_entries(include_gc_simple=False))
1295

1296
        if base_type or py_attrs:
1297
            code.putln("int e;")
1298 1299

        if py_attrs or py_buffers:
1300
            self.generate_self_cast(scope, code)
1301

1302
        if base_type:
1303
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1304 1305 1306
            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)
1307 1308 1309 1310
            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))
1311
            else:
1312 1313 1314 1315 1316 1317 1318 1319 1320
                # 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"))
1321

1322 1323 1324 1325 1326 1327 1328 1329
        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(
1330
                        "e = (*v)(%s, a); if (e) return e;"
1331 1332 1333
                            % var_code)
            code.putln(
                    "}")
1334

Stefan Behnel's avatar
Stefan Behnel committed
1335 1336
        # Traverse buffer exporting objects.
        # Note: not traversing memoryview attributes of memoryview slices!
1337 1338
        # 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
1339 1340
        for entry in py_buffers:
            cname = entry.cname + ".obj"
1341 1342
            code.putln("if (p->%s) {" % cname)
            code.putln(    "e = (*v)(p->%s, a); if (e) return e;" % cname)
1343 1344
            code.putln("}")

1345 1346 1347 1348
        code.putln(
                "return 0;")
        code.putln(
            "}")
1349

1350
    def generate_clear_function(self, scope, code, cclass_entry):
1351 1352
        tp_slot = TypeSlots.GCDependentSlot("tp_clear")
        slot_func = scope.mangle_internal("tp_clear")
1353
        base_type = scope.parent_type.base_type
1354 1355
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1356

1357 1358
        have_entries, (py_attrs, py_buffers, memoryview_slices) = (
            scope.get_refcounted_entries(include_gc_simple=False))
1359

1360 1361 1362 1363 1364 1365 1366 1367
        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))

1368
        if py_attrs or py_buffers:
1369
            self.generate_self_cast(scope, code)
1370

1371
        if base_type:
1372
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1373 1374 1375
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("%s(o);" % static_call)
1376 1377 1378 1379
            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))
1380
            else:
1381 1382 1383 1384 1385 1386 1387 1388 1389
                # 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"))
1390

1391
        for entry in py_attrs:
1392
            code.putln("Py_CLEAR(p->%s);" % entry.cname)
1393 1394

        for entry in py_buffers:
1395
            # Note: shouldn't this call __Pyx_ReleaseBuffer ??
1396 1397 1398 1399 1400
            code.putln("Py_CLEAR(p->%s.obj);" % entry.cname)

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

1401 1402 1403 1404
        code.putln(
            "return 0;")
        code.putln(
            "}")
1405

1406 1407 1408 1409 1410
    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(
1411
            "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1412 1413 1414 1415
                scope.mangle_internal("sq_item"))
        code.putln(
                "PyObject *r;")
        code.putln(
1416
                "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1417
        code.putln(
1418
                "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448
        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(
1449
                    '  "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
            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(
1466
                    '  "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1467 1468 1469 1470 1471 1472
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")
1473

1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
    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(
1502
            "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515
                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(
1516
                    '  "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
            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(
1533
                    '  "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1534 1535 1536 1537 1538 1539 1540 1541
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_getattro_function(self, scope, code):
1542 1543 1544
        # First try to get the attribute using __getattribute__, if defined, or
        # PyObject_GenericGetAttr.
        #
1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
        # 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__")
1560 1561 1562 1563
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *n) {"
                % scope.mangle_internal("tp_getattro"))
1564 1565 1566 1567 1568 1569
        if getattribute_entry is not None:
            code.putln(
                "PyObject *v = %s(o, n);" %
                    getattribute_entry.func_cname)
        else:
            code.putln(
1570
                "PyObject *v = PyObject_GenericGetAttr(o, n);")
1571 1572
        if getattr_entry is not None:
            code.putln(
1573
                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1574 1575 1576 1577 1578 1579
            code.putln(
                "PyErr_Clear();")
            code.putln(
                "v = %s(o, n);" %
                    getattr_entry.func_cname)
            code.putln(
1580 1581
                "}")
        code.putln(
1582
            "return v;")
1583 1584
        code.putln(
            "}")
1585

1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
    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(
            "}")
1625

1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652
    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(
            "}")
1653

1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693
    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(
1694
                "}")
1695 1696
        code.putln(
            "}")
1697

1698 1699 1700 1701 1702 1703 1704
    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)
1705

1706 1707 1708 1709 1710 1711 1712
    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(
1713
            "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" %
1714 1715 1716 1717 1718 1719
                property_entry.getter_cname)
        code.putln(
                "return %s(o);" %
                    get_entry.func_cname)
        code.putln(
            "}")
1720

1721 1722 1723 1724 1725 1726 1727 1728
    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(
1729
            "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" %
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768
                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:
1769
            header = "static PyTypeObject %s = {"
1770 1771 1772
        #code.putln(header % scope.parent_type.typeobj_cname)
        code.putln(header % type.typeobj_cname)
        code.putln(
1773
            "PyVarObject_HEAD_INIT(0, 0)")
1774
        code.putln(
1775
            '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1776
                self.full_module_name, scope.class_name))
1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789
        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(
            "};")
1790

1791 1792 1793
    def generate_method_table(self, env, code):
        code.putln("")
        code.putln(
1794
            "static PyMethodDef %s[] = {" %
1795 1796
                env.method_table_cname)
        for entry in env.pyfunc_entries:
1797 1798
            if not entry.fused_cfunction:
                code.put_pymethoddef(entry, ",")
1799 1800 1801 1802
        code.putln(
                "{0, 0, 0, 0}")
        code.putln(
            "};")
1803

1804 1805 1806 1807 1808 1809 1810
    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:
1811 1812 1813 1814
                if entry.doc:
                    doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
                else:
                    doc_code = "0"
1815
                code.putln(
1816
                    '{(char *)"%s", %s, %s, %s, 0},' % (
1817 1818 1819
                        entry.name,
                        entry.getter_cname or "0",
                        entry.setter_cname or "0",
1820
                        doc_code))
1821 1822 1823 1824
            code.putln(
                    "{0, 0, 0, 0, 0}")
            code.putln(
                "};")
1825

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1826
    def generate_import_star(self, env, code):
1827
        env.use_utility_code(streq_utility_code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1828
        code.putln()
1829
        code.putln("static char* %s_type_names[] = {" % Naming.import_star)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1830 1831 1832 1833 1834 1835
        for name, entry in env.entries.items():
            if entry.is_type:
                code.putln('"%s",' % name)
        code.putln("0")
        code.putln("};")
        code.putln()
1836
        code.enter_cfunc_scope() # as we need labels
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1837 1838 1839
        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) {")
1840
        code.putln("if (__Pyx_StrEq(name, *type_name)) {")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1841 1842 1843 1844 1845 1846 1847 1848 1849
        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:
1850
                code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1851 1852 1853 1854 1855
                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)))
1856 1857
                    code.putln("Py_INCREF(o);")
                    code.put_decref(entry.cname, entry.type, nanny=False)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1858
                    code.putln("%s = %s;" % (
1859
                        entry.cname,
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1860 1861 1862 1863
                        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:
1864
                        rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877
                    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;")
1878 1879 1880
        if code.label_used(code.error_label):
            code.put_label(code.error_label)
            # This helps locate the offending name.
1881
            code.put_add_traceback(self.full_module_name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1882 1883 1884 1885 1886
        code.error_label = old_error_label
        code.putln("bad:")
        code.putln("return -1;")
        code.putln("}")
        code.putln(import_star_utility_code)
1887
        code.exit_cfunc_scope() # done with labels
1888 1889

    def generate_module_init_func(self, imported_modules, env, code):
1890
        code.enter_cfunc_scope()
1891
        code.putln("")
1892 1893 1894 1895 1896 1897 1898 1899 1900 1901
        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("{")
1902
        tempdecl_code = code.insertion_point()
Robert Bradshaw's avatar
Robert Bradshaw committed
1903

1904
        code.put_declare_refcount_context()
1905 1906 1907
        code.putln("#if CYTHON_REFNANNY")
        code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
        code.putln("if (!__Pyx_RefNanny) {")
1908
        code.putln("  PyErr_Clear();")
1909 1910 1911
        code.putln("  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
        code.putln("  if (!__Pyx_RefNanny)")
        code.putln("      Py_FatalError(\"failed to import 'refnanny' module\");")
1912
        code.putln("}")
1913
        code.putln("#endif")
1914
        code.put_setup_refcount_context(header3)
1915

1916
        env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c"))
1917
        code.putln("if ( __Pyx_check_binary_version() < 0) %s" % code.error_goto(self.pos))
1918

1919 1920
        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)))
1921

1922 1923
        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
1924
        code.putln("#endif")
1925

1926 1927
        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
1928
        code.putln("#endif")
1929

1930 1931 1932 1933
        code.putln("#ifdef __Pyx_Generator_USED")
        code.putln("if (__pyx_Generator_init() < 0) %s" % code.error_goto(self.pos))
        code.putln("#endif")

1934
        code.putln("/*--- Library function declarations ---*/")
1935
        env.generate_library_function_declarations(code)
1936

1937 1938
        code.putln("/*--- Threads initialization code ---*/")
        code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
1939
        code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
1940 1941 1942 1943
        code.putln("PyEval_InitThreads();")
        code.putln("#endif")
        code.putln("#endif")

1944
        code.putln("/*--- Module creation code ---*/")
1945
        self.generate_module_creation_code(env, code)
1946

1947 1948 1949
        code.putln("/*--- Initialize various global constants etc. ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))

1950
        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
1951
        code.putln("if (__Pyx_init_sys_getdefaultencoding_params() < 0) %s" % code.error_goto(self.pos))
1952 1953
        code.putln("#endif")

1954 1955
        __main__name = code.globalstate.get_py_string_const(
            EncodedString("__main__"), identifier=True)
1956 1957 1958 1959
        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,
1960
                __main__name.cname,
1961 1962
                code.error_goto(self.pos)))
        code.putln("}")
1963

1964 1965
        # set up __file__ and __path__, then add the module to sys.modules
        self.generate_module_import_setup(env, code)
1966

Robert Bradshaw's avatar
Robert Bradshaw committed
1967 1968
        if Options.cache_builtins:
            code.putln("/*--- Builtin init code ---*/")
1969 1970 1971 1972
            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))
1973

1974
        code.putln("/*--- Global init code ---*/")
1975
        self.generate_global_init_code(env, code)
Gary Furnish's avatar
Gary Furnish committed
1976

1977 1978 1979
        code.putln("/*--- Variable export code ---*/")
        self.generate_c_variable_export_code(env, code)

1980
        code.putln("/*--- Function export code ---*/")
1981 1982
        self.generate_c_function_export_code(env, code)

1983
        code.putln("/*--- Type init code ---*/")
1984
        self.generate_type_init_code(env, code)
1985

1986
        code.putln("/*--- Type import code ---*/")
1987 1988 1989
        for module in imported_modules:
            self.generate_type_import_code_for_module(module, env, code)

1990 1991 1992 1993
        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
1994 1995
        code.putln("/*--- Function import code ---*/")
        for module in imported_modules:
1996
            self.specialize_fused_types(module)
Gary Furnish's avatar
Gary Furnish committed
1997 1998
            self.generate_c_function_import_code_for_module(module, env, code)

1999
        code.putln("/*--- Execution code ---*/")
Robert Bradshaw's avatar
Robert Bradshaw committed
2000
        code.mark_pos(None)
2001

2002
        self.body.generate_execution_code(code)
2003

2004
        if Options.generate_cleanup_code:
2005 2006
            code.globalstate.use_utility_code(
                UtilityCode.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c"))
2007
            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
2008

2009
        code.put_goto(code.return_label)
2010
        code.put_label(code.error_label)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2011 2012
        for cname, type in code.funcstate.all_managed_temps():
            code.put_xdecref(cname, type)
2013
        code.putln('if (%s) {' % env.module_cname)
2014
        code.put_add_traceback("init %s" % env.qualified_name)
2015
        env.use_utility_code(Nodes.traceback_utility_code)
2016
        code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
2017 2018 2019
        code.putln('} else if (!PyErr_Occurred()) {')
        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
        code.putln('}')
2020
        code.put_label(code.return_label)
2021 2022 2023

        code.put_finish_refcount_context()

2024 2025 2026
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("return;")
        code.putln("#else")
2027
        code.putln("return %s;" % env.module_cname)
2028
        code.putln("#endif")
2029
        code.putln('}')
2030

2031
        tempdecl_code.put_temp_declarations(code.funcstate)
2032

2033
        code.exit_cfunc_scope()
2034

2035
    def generate_module_import_setup(self, env, code):
2036 2037 2038
        module_path = env.directives['set_initial_path']
        if module_path == 'SOURCEFILE':
            module_path = self.pos[0].filename
2039 2040 2041

        if module_path:
            code.putln('if (__Pyx_SetAttrString(%s, "__file__", %s) < 0) %s;' % (
2042
                env.module_cname,
2043 2044
                code.globalstate.get_py_string_const(
                    EncodedString(decode_filename(module_path))).cname,
2045
                code.error_goto(self.pos)))
2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093

            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")
2094

2095 2096 2097
    def generate_module_cleanup_func(self, env, code):
        if not Options.generate_cleanup_code:
            return
2098

2099
        code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' %
2100
                   Naming.cleanup_cname)
2101 2102
        if Options.generate_cleanup_code >= 2:
            code.putln("/*--- Global cleanup code ---*/")
2103 2104 2105
            rev_entries = list(env.var_entries)
            rev_entries.reverse()
            for entry in rev_entries:
2106
                if entry.visibility != 'extern':
2107
                    if entry.type.is_pyobject and entry.used:
2108 2109 2110 2111
                        code.put_xdecref_clear(
                            entry.cname, entry.type,
                            clear_before_decref=True,
                            nanny=False)
2112
        code.putln("__Pyx_CleanupGlobals();")
2113 2114
        if Options.generate_cleanup_code >= 3:
            code.putln("/*--- Type import cleanup code ---*/")
2115 2116 2117 2118 2119
            for type in env.types_imported:
                code.put_xdecref_clear(
                    type.typeptr_cname, type,
                    clear_before_decref=True,
                    nanny=False)
2120 2121
        if Options.cache_builtins:
            code.putln("/*--- Builtin cleanup code ---*/")
2122
            for entry in env.cached_builtins:
2123 2124 2125 2126
                code.put_xdecref_clear(
                    entry.cname, PyrexTypes.py_object_type,
                    clear_before_decref=True,
                    nanny=False)
2127
        code.putln("/*--- Intern cleanup code ---*/")
2128 2129
        code.put_decref_clear(Naming.empty_tuple,
                              PyrexTypes.py_object_type,
2130
                              clear_before_decref=True,
2131
                              nanny=False)
2132 2133
        for entry in env.c_class_entries:
            cclass_type = entry.type
2134
            if cclass_type.is_external or cclass_type.base_type:
2135 2136 2137 2138 2139 2140 2141 2142 2143 2144
                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("}")
2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157
#        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))
2158 2159 2160
        code.putln('#if CYTHON_COMPILING_IN_PYPY')
        code.putln('Py_CLEAR(%s);' % Naming.builtins_cname)
        code.putln('#endif')
2161

2162
    def generate_main_method(self, env, code):
2163
        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173
        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))
2174

2175 2176
    def generate_pymoduledef_struct(self, env, code):
        if env.doc:
2177
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2178 2179
        else:
            doc = "0"
2180
        if Options.generate_cleanup_code:
Stefan Behnel's avatar
Stefan Behnel committed
2181
            cleanup_func = "(freefunc)%s" % Naming.cleanup_cname
2182 2183
        else:
            cleanup_func = 'NULL'
2184 2185 2186

        code.putln("")
        code.putln("#if PY_MAJOR_VERSION >= 3")
2187
        code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
2188 2189 2190 2191
        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")
2192
        code.putln("  PyModuleDef_HEAD_INIT,")
2193
        code.putln("#endif")
2194
        code.putln('  __Pyx_NAMESTR("%s"),' % env.module_name)
2195 2196 2197 2198 2199 2200
        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
2201
        code.putln("  %s /* m_free */" % cleanup_func)
2202 2203 2204
        code.putln("};")
        code.putln("#endif")

2205 2206 2207 2208
    def generate_module_creation_code(self, env, code):
        # Generate code to create the module object and
        # install the builtins.
        if env.doc:
2209
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2210 2211
        else:
            doc = "0"
2212
        code.putln("#if PY_MAJOR_VERSION < 3")
2213
        code.putln(
2214
            '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % (
2215 2216 2217
                env.module_cname,
                env.module_name,
                env.method_table_cname,
2218 2219
                doc,
                env.module_cname))
2220 2221 2222 2223 2224 2225
        code.putln("#else")
        code.putln(
            "%s = PyModule_Create(&%s);" % (
                env.module_cname,
                Naming.pymoduledef_cname))
        code.putln("#endif")
2226
        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
2227 2228 2229 2230 2231
        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)
2232

2233
        code.putln(
2234
            '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); %s' % (
2235
                Naming.builtins_cname,
2236
                code.error_goto_if_null(Naming.builtins_cname, self.pos)))
2237 2238 2239
        code.putln('#if CYTHON_COMPILING_IN_PYPY')
        code.putln('Py_INCREF(%s);' % Naming.builtins_cname)
        code.putln('#endif')
2240
        code.putln(
2241
            'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
2242 2243 2244
                env.module_cname,
                Naming.builtins_cname,
                code.error_goto(self.pos)))
2245 2246
        if Options.pre_import is not None:
            code.putln(
2247
                '%s = PyImport_AddModule(__Pyx_NAMESTR("%s")); %s' % (
2248
                    Naming.preimport_cname,
2249 2250
                    Options.pre_import,
                    code.error_goto_if_null(Naming.preimport_cname, self.pos)))
2251

2252 2253 2254 2255
    def generate_global_init_code(self, env, code):
        # Generate code to initialise global PyObject *
        # variables to None.
        for entry in env.var_entries:
2256
            if entry.visibility != 'extern':
2257 2258
                if entry.used:
                    entry.type.global_init_code(entry, code)
2259

2260 2261
    def generate_c_variable_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2262
        entries = []
2263
        for entry in env.var_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2264 2265 2266
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2267 2268
                entries.append(entry)
        if entries:
2269
            env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c"))
2270
            for entry in entries:
2271
                signature = entry.type.declaration_code("")
2272 2273 2274
                name = code.intern_identifier(entry.name)
                code.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % (
                    name, entry.cname, signature,
2275 2276
                    code.error_goto(self.pos)))

2277 2278
    def generate_c_function_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2279
        entries = []
2280
        for entry in env.cfunc_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2281 2282 2283
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2284 2285
                entries.append(entry)
        if entries:
2286 2287
            env.use_utility_code(
                UtilityCode.load_cached("FunctionExport", "ImportExport.c"))
2288
            for entry in entries:
Mark Florisson's avatar
Mark Florisson committed
2289 2290 2291 2292 2293 2294
                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)))
2295

2296
    def generate_type_import_code_for_module(self, module, env, code):
2297
        # Generate type import code for all exported extension types in
2298
        # an imported module.
2299 2300 2301
        #if module.c_class_entries:
        for entry in module.c_class_entries:
            if entry.defined_in_pxd:
2302
                self.generate_type_import_code(env, entry.type, entry.pos, code)
2303

2304
    def specialize_fused_types(self, pxd_env):
2305 2306 2307 2308 2309 2310 2311 2312 2313
        """
        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
2314
                entry.type.get_all_specialized_function_types()
2315

2316 2317 2318 2319 2320 2321 2322
    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:
2323 2324 2325 2326
            env.use_utility_code(
                UtilityCode.load_cached("ModuleImport", "ImportExport.c"))
            env.use_utility_code(
                UtilityCode.load_cached("VoidPtrImport", "ImportExport.c"))
2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345
            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))

2346 2347 2348 2349
    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:
2350
            if entry.defined_in_pxd and entry.used:
2351 2352
                entries.append(entry)
        if entries:
2353 2354 2355 2356
            env.use_utility_code(
                UtilityCode.load_cached("ModuleImport", "ImportExport.c"))
            env.use_utility_code(
                UtilityCode.load_cached("FunctionImport", "ImportExport.c"))
2357
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2358 2359 2360 2361 2362 2363
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
2364
            for entry in entries:
Mark Florisson's avatar
Mark Florisson committed
2365 2366 2367 2368 2369 2370 2371
                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)))
2372
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
2373

2374 2375 2376 2377
    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:
2378
            if entry.visibility == 'extern' and not entry.utility_code_definition:
2379 2380 2381 2382 2383 2384
                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)
2385

2386 2387
    def generate_base_type_import_code(self, env, entry, code):
        base_type = entry.type.base_type
2388 2389
        if (base_type and base_type.module_name != env.qualified_name and not
               base_type.is_builtin_type and not entry.utility_code_definition):
2390
            self.generate_type_import_code(env, base_type, self.pos, code)
2391

2392 2393 2394 2395 2396 2397
    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
2398
        env.use_utility_code(UtilityCode.load_cached("TypeImport", "ImportExport.c"))
2399 2400
        self.generate_type_import_call(type, code,
                                       code.error_goto_if_null(type.typeptr_cname, pos))
2401
        if type.vtabptr_cname:
2402
            code.globalstate.use_utility_code(
2403
                UtilityCode.load_cached('GetVTable', 'ImportExport.c'))
2404 2405 2406 2407 2408
            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)))
2409
        env.types_imported[type] = 1
2410

2411 2412
    py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}

2413 2414 2415 2416 2417
    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
2418
        sizeof_objstruct = objstruct
2419
        module_name = type.module_name
2420
        condition = replacement = None
2421 2422 2423 2424
        if module_name not in ('__builtin__', 'builtins'):
            module_name = '"%s"' % module_name
        else:
            module_name = '__Pyx_BUILTIN_MODULE_NAME'
2425
            if type.name in Code.non_portable_builtins_map:
Stefan Behnel's avatar
Stefan Behnel committed
2426
                condition, replacement = Code.non_portable_builtins_map[type.name]
2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451
            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)
2452
            code.putln("#endif")
2453 2454 2455 2456 2457 2458
        else:
            code.put('sizeof(%s), ' % objstruct)

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

2460 2461 2462 2463 2464 2465 2466
    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
2467
            if entry.visibility != 'extern':
2468 2469 2470 2471 2472 2473
                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)))
2474
                # Fix special method docstrings. This is a bit of a hack, but
2475
                # unless we let PyType_Ready create the slot wrappers we have
2476
                # a significant performance hit. (See trac #561.)
2477
                for func in entry.type.scope.pyfunc_entries:
2478 2479 2480 2481
                    is_buffer = func.name in ('__getbuffer__',
                                               '__releasebuffer__')
                    if (func.is_special and Options.docstrings and
                            func.wrapperbase_cname and not is_buffer):
2482
                        code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
Stefan Behnel's avatar
Stefan Behnel committed
2483
                        code.putln("{")
2484
                        code.putln(
2485
                            'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
2486 2487
                                typeobj_cname,
                                func.name,
Stefan Behnel's avatar
Stefan Behnel committed
2488
                                code.error_goto_if_null('wrapper', entry.pos)))
2489
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2490
                            "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
2491 2492
                        code.putln(
                            "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2493
                                func.wrapperbase_cname))
2494
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2495
                            "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname))
2496 2497
                        code.putln(
                            "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2498 2499 2500
                                func.wrapperbase_cname))
                        code.putln("}")
                        code.putln("}")
2501
                        code.putln('#endif')
2502 2503 2504 2505 2506 2507
                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)))
2508
                    code.globalstate.use_utility_code(
2509
                        UtilityCode.load_cached('SetVTable', 'ImportExport.c'))
2510 2511 2512 2513 2514 2515 2516 2517 2518 2519
                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)))
2520 2521 2522 2523
                weakref_entry = scope.lookup_here("__weakref__")
                if weakref_entry:
                    if weakref_entry.type is py_object_type:
                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
2524 2525 2526 2527 2528
                        if type.typedef_flag:
                            objstruct = type.objstruct_cname
                        else:
                            objstruct = "struct %s" % type.objstruct_cname
                        code.putln("if (%s == 0) %s = offsetof(%s, %s);" % (
2529 2530
                            tp_weaklistoffset,
                            tp_weaklistoffset,
2531
                            objstruct,
2532 2533 2534
                            weakref_entry.cname))
                    else:
                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
2535

2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550
    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))
2551 2552 2553 2554

            c_method_entries = [
                entry for entry in type.scope.cfunc_entries
                if entry.func_cname ]
2555 2556 2557 2558 2559 2560 2561 2562 2563
            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))
2564

2565 2566 2567 2568 2569 2570 2571 2572
    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))
2573

2574
def generate_cfunction_declaration(entry, env, code, definition):
2575
    from_cy_utility = entry.used and entry.utility_code_definition
2576
    if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
2577
            or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)):
2578
        if entry.visibility == 'extern':
2579
            storage_class = Naming.extern_c_macro
2580 2581
            dll_linkage = "DL_IMPORT"
        elif entry.visibility == 'public':
2582
            storage_class = Naming.extern_c_macro
2583 2584
            dll_linkage = "DL_EXPORT"
        elif entry.visibility == 'private':
2585
            storage_class = "static"
2586 2587
            dll_linkage = None
        else:
2588
            storage_class = "static"
2589 2590 2591 2592
            dll_linkage = None
        type = entry.type

        if entry.defined_in_pxd and not definition:
2593
            storage_class = "static"
2594 2595 2596
            dll_linkage = None
            type = CPtrType(type)

2597 2598 2599 2600
        header = type.declaration_code(
            entry.cname, dll_linkage = dll_linkage)
        modifiers = code.build_function_modifiers(entry.func_modifiers)
        code.putln("%s %s%s; /*proto*/" % (
2601 2602 2603 2604
            storage_class,
            modifiers,
            header))

2605
#------------------------------------------------------------------------------------
Stefan Behnel's avatar
Stefan Behnel committed
2606 2607 2608
#
#  Runtime support code
#
2609 2610
#------------------------------------------------------------------------------------

2611 2612
streq_utility_code = UtilityCode(
proto = """
2613
static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2614 2615
""",
impl = """
2616
static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2617 2618 2619 2620 2621 2622 2623
     while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
     return *s1 == *s2;
}
""")

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

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2624 2625 2626 2627 2628 2629 2630
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
2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
    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;
        }
2648 2649 2650
#if PY_MAJOR_VERSION < 3
        all = PyObject_CallMethod(dict, (char *)"keys", NULL);
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2651
        all = PyMapping_Keys(dict);
2652
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668
        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 &&
2669
#if PY_MAJOR_VERSION < 3
Robert Bradshaw's avatar
Robert Bradshaw committed
2670 2671
            PyString_Check(name) &&
            PyString_AS_STRING(name)[0] == '_')
2672
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2673 2674
            PyUnicode_Check(name) &&
            PyUnicode_AS_UNICODE(name)[0] == '_')
2675
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693
        {
            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
2694 2695 2696
}


2697
static int %(IMPORT_STAR)s(PyObject* m) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2698 2699 2700

    int i;
    int ret = -1;
2701
    char* s;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2702 2703
    PyObject *locals = 0;
    PyObject *list = 0;
2704 2705 2706
#if PY_MAJOR_VERSION >= 3
    PyObject *utf8_name = 0;
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2707 2708
    PyObject *name;
    PyObject *item;
2709

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2710 2711 2712
    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;
2713

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2714 2715 2716
    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);
2717 2718 2719 2720 2721 2722
#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;
2723
#else
2724
        s = PyString_AsString(name);
2725 2726
        if (!s) goto bad;
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2727
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2728 2729
    }
    ret = 0;
2730

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2731 2732 2733
bad:
    Py_XDECREF(locals);
    Py_XDECREF(list);
2734 2735 2736
#if PY_MAJOR_VERSION >= 3
    Py_XDECREF(utf8_name);
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2737 2738
    return ret;
}
2739 2740
""" % {'IMPORT_STAR'     : Naming.import_star,
       'IMPORT_STAR_SET' : Naming.import_star_set }
2741

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

2744 2745
main_method = UtilityCode(
impl = """
2746 2747 2748 2749 2750
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif

#if PY_MAJOR_VERSION < 3
2751
int %(main_method)s(int argc, char** argv) {
2752
#elif defined(WIN32) || defined(MS_WINDOWS)
2753
int %(wmain_method)s(int argc, wchar_t **argv) {
2754 2755
#else
static int __Pyx_main(int argc, wchar_t **argv) {
2756
#endif
2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767
    /* 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
2768
    if (argc && argv)
2769
        Py_SetProgramName(argv[0]);
2770
    Py_Initialize();
2771
    if (argc && argv)
2772
        PySys_SetArgv(argc, argv);
2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788
    { /* 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);
2789
    }
2790
    Py_Finalize();
2791
    return 0;
2792
}
2793 2794 2795 2796 2797 2798 2799 2800


#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
2801
    wchar_t *res;
2802
#ifdef HAVE_BROKEN_MBSTOWCS
Vitja Makarov's avatar
Vitja Makarov committed
2803 2804 2805 2806 2807
    /* 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);
2808
#else
Vitja Makarov's avatar
Vitja Makarov committed
2809
    size_t argsize = mbstowcs(NULL, arg, 0);
2810
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2811 2812 2813
    size_t count;
    unsigned char *in;
    wchar_t *out;
2814
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
2815
    mbstate_t mbs;
2816
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834
    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. */
2835
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879
    /* 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++;
    }
2880
#else
Vitja Makarov's avatar
Vitja Makarov committed
2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893
    /* 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;
2894
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2895
    return res;
2896
oom:
Vitja Makarov's avatar
Vitja Makarov committed
2897 2898
    fprintf(stderr, "out of memory\\n");
    return NULL;
2899 2900 2901
}

int
2902
%(main_method)s(int argc, char **argv)
2903
{
2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933
    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;
    }
2934 2935
}
#endif
2936
""")
2937 2938 2939 2940 2941 2942 2943

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
2944
""", impl="", proto_block='utility_code_proto_before_types')
2945

2946
capsule_utility_code = UtilityCode.load("Capsule")