~lifeless/ubuntu/maverick/pyrex/fixdepends

« back to all changes in this revision

Viewing changes to Pyrex/Compiler/Nodes.py

  • Committer: Bazaar Package Importer
  • Author(s): Paul Brossier
  • Date: 2007-04-21 15:16:07 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070421151607-7u3ovhn5lmitwk8h
Tags: 0.9.5.1a-1
* New upstream release (closes: #411004)
* Provide only ${python:Provides} (closes: #399937)
* Drop Conflicts and Replaces against oldstable packages
* Bumpep Build-depends on debhelper to 5.0.37.2
* Added debian/pycompat, set to 2
* Moved DH_COMPAT=5 to debian/compat

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
#   Pyrex - Parse tree nodes
3
3
#
4
4
 
5
 
import os, string, sys, time
 
5
import string, sys
6
6
 
7
7
import Code
8
8
from Errors import error, InternalError
11
11
from PyrexTypes import py_object_type, error_type, CTypedefType
12
12
from Symtab import ModuleScope, LocalScope, \
13
13
    StructOrUnionScope, PyClassScope, CClassScope
14
 
import TypeSlots
15
 
import Version
16
14
from Pyrex.Utils import open_new_file, replace_suffix
17
15
import Options
18
16
 
95
93
            for entry in entries:
96
94
                code.putln(
97
95
                    "static PyObject *%s;" % entry.pystring_cname)
98
 
        
99
 
 
100
 
class ModuleNode(Node, BlockNode):
101
 
    #  doc       string or None
102
 
    #  body      StatListNode
103
 
    
104
 
    def analyse_declarations(self, env):
105
 
        env.doc = self.doc
106
 
        self.body.analyse_declarations(env)
107
 
    
108
 
    def process_implementation(self, env, result):
109
 
        self.analyse_declarations(env)
110
 
        env.check_c_classes()
111
 
        self.body.analyse_expressions(env)
112
 
        env.return_type = PyrexTypes.c_void_type
113
 
        self.generate_c_code(env, result)
114
 
        self.generate_h_code(env, result)
115
 
    
116
 
    def generate_h_code(self, env, result):
117
 
        public_vars_and_funcs = []
118
 
        public_extension_types = []
119
 
        for entry in env.var_entries:
120
 
            if entry.visibility == 'public':
121
 
                public_vars_and_funcs.append(entry)
122
 
        for entry in env.cfunc_entries:
123
 
            if entry.visibility == 'public':
124
 
                public_vars_and_funcs.append(entry)
125
 
        for entry in env.c_class_entries:
126
 
            if entry.visibility == 'public':
127
 
                public_extension_types.append(entry)
128
 
        if public_vars_and_funcs or public_extension_types:
129
 
            result.h_file = replace_suffix(result.c_file, ".h")
130
 
            result.i_file = replace_suffix(result.c_file, ".pxi")
131
 
            h_code = Code.CCodeWriter(result.h_file)
132
 
            i_code = Code.PyrexCodeWriter(result.i_file)
133
 
            self.generate_extern_c_macro_definition(h_code)
134
 
            for entry in public_vars_and_funcs:
135
 
                h_code.putln("%s %s;" % (
136
 
                    Naming.extern_c_macro,
137
 
                    entry.type.declaration_code(
138
 
                        entry.cname, dll_linkage = "DL_IMPORT")))
139
 
                i_code.putln("cdef extern %s" % 
140
 
                    entry.type.declaration_code(entry.cname, pyrex = 1))
141
 
            for entry in public_extension_types:
142
 
                self.generate_cclass_header_code(entry.type, h_code)
143
 
                self.generate_cclass_include_code(entry.type, i_code)
144
 
            h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
145
 
    
146
 
    def generate_cclass_header_code(self, type, h_code):
147
 
        #h_code.putln("extern DL_IMPORT(PyTypeObject) %s;" % type.typeobj_cname)
148
 
        h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
149
 
            Naming.extern_c_macro,
150
 
            type.typeobj_cname))
151
 
        self.generate_obj_struct_definition(type, h_code)
152
 
    
153
 
    def generate_cclass_include_code(self, type, i_code):
154
 
        i_code.putln("cdef extern class %s.%s:" % (
155
 
            type.module_name, type.name))
156
 
        i_code.indent()
157
 
        var_entries = type.scope.var_entries
158
 
        if var_entries:
159
 
            for entry in var_entries:
160
 
                i_code.putln("cdef %s" % 
161
 
                    entry.type.declaration_code(entry.cname, pyrex = 1))
162
 
        else:
163
 
            i_code.putln("pass")
164
 
        i_code.dedent()
165
 
    
166
 
    def generate_c_code(self, env, result):
167
 
        modules = []
168
 
        self.find_referenced_modules(env, modules, {})
169
 
        code = Code.CCodeWriter(result.c_file)
170
 
        code.init_labels()
171
 
        self.generate_module_preamble(env, modules, code)
172
 
        for module in modules:
173
 
            self.generate_declarations_for_module(module, code,
174
 
                definition = module is env)
175
 
        code.putln("")
176
 
        code.putln("/* Implementation of %s */" % env.qualified_name)
177
 
        self.generate_const_definitions(env, code)
178
 
        self.generate_interned_name_decls(env, code)
179
 
        self.generate_py_string_decls(env, code)
180
 
        self.body.generate_function_definitions(env, code)
181
 
        self.generate_interned_name_table(env, code)
182
 
        self.generate_py_string_table(env, code)
183
 
        self.generate_typeobj_definitions(env, code)
184
 
        self.generate_method_table(env, code)
185
 
        self.generate_filename_init_prototype(code)
186
 
        self.generate_module_init_func(modules[:-1], env, code)
187
 
        self.generate_filename_table(code)
188
 
        self.generate_utility_functions(env, code)
189
 
        result.c_file_generated = 1
190
 
    
191
 
    def find_referenced_modules(self, env, module_list, modules_seen):
192
 
        if env not in modules_seen:
193
 
            modules_seen[env] = 1
194
 
            for imported_module in env.cimported_modules:
195
 
                self.find_referenced_modules(imported_module, module_list, modules_seen)
196
 
            module_list.append(env)
197
 
        
198
 
    def generate_module_preamble(self, env, cimported_modules, code):
199
 
        code.putln('/* Generated by Pyrex %s on %s */' % (
200
 
            Version.version, time.asctime()))
201
 
        code.putln('')
202
 
        code.putln('#define PY_SSIZE_T_CLEAN')
203
 
        for filename in env.python_include_files:
204
 
            code.putln('#include "%s"' % filename)
205
 
        code.putln("#ifndef PY_LONG_LONG")
206
 
        code.putln("  #define PY_LONG_LONG LONG_LONG")
207
 
        code.putln("#endif")
208
 
        code.putln("#if PY_VERSION_HEX < 0x02050000")
209
 
        code.putln("  typedef int Py_ssize_t;")
210
 
        code.putln("  #define PY_SSIZE_T_MAX INT_MAX")
211
 
        code.putln("  #define PY_SSIZE_T_MIN INT_MIN")
212
 
        code.putln("  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
213
 
        code.putln("  #define PyInt_AsSsize_t(o)   PyInt_AsLong(o)")
214
 
        code.putln("#endif")
215
 
        self.generate_extern_c_macro_definition(code)
216
 
        code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
217
 
        self.generate_includes(env, cimported_modules, code)
218
 
        #for filename in env.include_files:
219
 
        #       code.putln('#include "%s"' % filename)
220
 
        code.putln('')
221
 
        code.put(utility_function_predeclarations)
222
 
        if Options.intern_names:
223
 
            code.putln(get_name_interned_predeclaration)
224
 
        else:
225
 
            code.putln(get_name_predeclaration)
226
 
        code.putln('')
227
 
        code.putln('static PyObject *%s;' % env.module_cname)
228
 
        code.putln('static PyObject *%s;' % Naming.builtins_cname)
229
 
        code.putln('static int %s;' % Naming.lineno_cname)
230
 
        code.putln('static char *%s;' % Naming.filename_cname)
231
 
        code.putln('static char **%s;' % Naming.filetable_cname)
232
 
        if env.doc:
233
 
            code.putln('')
234
 
            code.putln('static char %s[] = "%s";' % (env.doc_cname, env.doc))
235
 
    
236
 
    def generate_extern_c_macro_definition(self, code):
237
 
        name = Naming.extern_c_macro
238
 
        code.putln("#ifdef __cplusplus")
239
 
        code.putln('#define %s extern "C"' % name)
240
 
        code.putln("#else")
241
 
        code.putln("#define %s extern" % name)
242
 
        code.putln("#endif")
243
 
 
244
 
    def generate_includes(self, env, cimported_modules, code):
245
 
        includes = env.include_files[:]
246
 
        for module in cimported_modules:
247
 
            for filename in module.include_files:
248
 
                if filename not in includes:
249
 
                    includes.append(filename)
250
 
        for filename in includes:
251
 
            code.putln('#include "%s"' % filename)
252
 
    
253
 
    def generate_filename_table(self, code):
254
 
        code.putln("")
255
 
        code.putln("static char *%s[] = {" % Naming.filenames_cname)
256
 
        if code.filename_list:
257
 
            for filename in code.filename_list:
258
 
                filename = os.path.basename(filename)
259
 
                escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
260
 
                code.putln('"%s",' % 
261
 
                    escaped_filename)
262
 
        else:
263
 
            # Some C compilers don't like an empty array
264
 
            code.putln("0")
265
 
        code.putln("};")
266
 
    
267
 
    def generate_declarations_for_module(self, env, code, definition):
268
 
        code.putln("")
269
 
        code.putln("/* Declarations from %s */" % env.qualified_name)
270
 
        self.generate_type_predeclarations(env, code)
271
 
        self.generate_type_definitions(env, code)
272
 
        self.generate_global_declarations(env, code, definition)
273
 
        self.generate_cfunction_predeclarations(env, code)
274
 
 
275
 
    def generate_type_predeclarations(self, env, code):
276
 
        pass
277
 
    
278
 
    def generate_type_definitions(self, env, code):
279
 
        # Generate definitions of structs/unions/enums.
280
 
        for entry in env.sue_entries:
281
 
            if not entry.in_cinclude:
282
 
                type = entry.type
283
 
                if type.is_struct_or_union:
284
 
                    self.generate_struct_union_definition(entry, code)
285
 
                else:
286
 
                    self.generate_enum_definition(entry, code)
287
 
        # Generate extension type object struct definitions.
288
 
        for entry in env.c_class_entries:
289
 
            if not entry.in_cinclude:
290
 
                self.generate_typeobject_predeclaration(entry, code)
291
 
                self.generate_obj_struct_definition(entry.type, code)
292
 
                self.generate_exttype_vtable_struct(entry, code)
293
 
                self.generate_exttype_vtabptr_declaration(entry, code)
294
 
    
295
 
    def sue_header_footer(self, type, kind, name):
296
 
        if type.typedef_flag:
297
 
            header = "typedef %s {" % kind
298
 
            footer = "} %s;" % name
299
 
        else:
300
 
            header = "%s %s {" % (kind, name)
301
 
            footer = "};"
302
 
        return header, footer
303
 
    
304
 
    def generate_struct_union_definition(self, entry, code):
305
 
        type = entry.type
306
 
        scope = type.scope
307
 
        if scope:
308
 
            header, footer = \
309
 
                self.sue_header_footer(type, type.kind, type.cname)
310
 
            code.putln("")
311
 
            code.putln(header)
312
 
            var_entries = scope.var_entries
313
 
            if not var_entries:
314
 
                error(entry.pos,
315
 
                    "Empty struct or union definition not allowed outside a"
316
 
                    " 'cdef extern from' block")
317
 
            for attr in var_entries:
318
 
                code.putln(
319
 
                    "%s;" %
320
 
                        attr.type.declaration_code(attr.cname))
321
 
            code.putln(footer)
322
 
 
323
 
    def generate_enum_definition(self, entry, code):
324
 
        type = entry.type
325
 
        name = entry.cname or entry.name or ""
326
 
        header, footer = \
327
 
            self.sue_header_footer(type, "enum", name)
328
 
        code.putln("")
329
 
        code.putln(header)
330
 
        enum_values = entry.enum_values
331
 
        if not enum_values:
332
 
            error(entry.pos,
333
 
                "Empty enum definition not allowed outside a"
334
 
                " 'cdef extern from' block")
335
 
        for value_entry in enum_values:
336
 
            if value_entry.value == value_entry.name:
337
 
                code.putln(
338
 
                    "%s," % 
339
 
                        value_entry.cname)
340
 
            else:
341
 
                code.putln(
342
 
                    "%s = %s," % (
343
 
                        value_entry.cname,
344
 
                        value_entry.value))
345
 
        code.putln(footer)
346
 
    
347
 
    def generate_typeobject_predeclaration(self, entry, code):
348
 
        code.putln("")
349
 
        name = entry.type.typeobj_cname
350
 
        if name:
351
 
            if entry.visibility == 'extern' and not entry.in_cinclude:
352
 
                code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
353
 
                    Naming.extern_c_macro,
354
 
                    name))
355
 
            elif entry.visibility == 'public':
356
 
                #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
357
 
                code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
358
 
                    Naming.extern_c_macro,
359
 
                    name))
360
 
            # ??? Do we really need the rest of this? ???
361
 
            #else:
362
 
            #   code.putln("staticforward PyTypeObject %s;" % name)
363
 
    
364
 
    def generate_exttype_vtable_struct(self, entry, code):
365
 
        # Generate struct declaration for an extension type's vtable.
366
 
        type = entry.type
367
 
        scope = type.scope
368
 
        if type.vtabstruct_cname:
369
 
            code.putln("")
370
 
            code.putln(
371
 
                "struct %s {" %
372
 
                    type.vtabstruct_cname)
373
 
            if type.base_type and type.base_type.vtabstruct_cname:
374
 
                code.putln("struct %s %s;" % (
375
 
                    type.base_type.vtabstruct_cname,
376
 
                    Naming.obj_base_cname))
377
 
            for method_entry in scope.cfunc_entries:
378
 
                if not method_entry.is_inherited:
379
 
                    code.putln(
380
 
                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
381
 
            code.putln(
382
 
                "};")
383
 
    
384
 
    def generate_exttype_vtabptr_declaration(self, entry, code):
385
 
        # Generate declaration of pointer to an extension type's vtable.
386
 
        type = entry.type
387
 
        if type.vtabptr_cname:
388
 
            code.putln("static struct %s *%s;" % (
389
 
                type.vtabstruct_cname,
390
 
                type.vtabptr_cname))
391
 
    
392
 
    def generate_obj_struct_definition(self, type, code):
393
 
        # Generate object struct definition for an
394
 
        # extension type.
395
 
        if not type.scope:
396
 
            return # Forward declared but never defined
397
 
        header, footer = \
398
 
            self.sue_header_footer(type, "struct", type.objstruct_cname)
399
 
        code.putln("")
400
 
        code.putln(header)
401
 
        base_type = type.base_type
402
 
        if base_type:
403
 
            code.putln(
404
 
                "%s%s %s;" % (
405
 
                    ("struct ", "")[base_type.typedef_flag],
406
 
                    base_type.objstruct_cname,
407
 
                    Naming.obj_base_cname))
408
 
        else:
409
 
            code.putln(
410
 
                "PyObject_HEAD")
411
 
        if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
412
 
            code.putln(
413
 
                "struct %s *%s;" % (
414
 
                    type.vtabstruct_cname,
415
 
                    type.vtabslot_cname))
416
 
        for attr in type.scope.var_entries:
417
 
            code.putln(
418
 
                "%s;" %
419
 
                    attr.type.declaration_code(attr.cname))
420
 
        code.putln(footer)
421
 
 
422
 
    def generate_global_declarations(self, env, code, definition):
423
 
        code.putln("")
424
 
        for entry in env.c_class_entries:
425
 
            code.putln("static PyTypeObject *%s = 0;" % 
426
 
                entry.type.typeptr_cname)
427
 
        code.put_var_declarations(env.var_entries, static = 1, 
428
 
            dll_linkage = "DL_EXPORT", definition = definition)
429
 
        code.put_var_declarations(env.default_entries, static = 1)
430
 
    
431
 
    def generate_cfunction_predeclarations(self, env, code):
432
 
        for entry in env.cfunc_entries:
433
 
            if not entry.in_cinclude:
434
 
                if entry.visibility == 'public':
435
 
                    dll_linkage = "DL_EXPORT"
436
 
                else:
437
 
                    dll_linkage = None
438
 
                header = entry.type.declaration_code(entry.cname, 
439
 
                    dll_linkage = dll_linkage)
440
 
                if entry.visibility <> 'private':
441
 
                    storage_class = "%s " % Naming.extern_c_macro
442
 
                else:
443
 
                    storage_class = "static "
444
 
                code.putln("%s%s; /*proto*/" % (
445
 
                    storage_class,
446
 
                    header))
447
 
    
448
 
    def generate_typeobj_definitions(self, env, code):
449
 
        full_module_name = env.qualified_name
450
 
        for entry in env.c_class_entries:
451
 
            #print "generate_typeobj_definitions:", entry.name
452
 
            #print "...visibility =", entry.visibility
453
 
            if entry.visibility <> 'extern':
454
 
                type = entry.type
455
 
                scope = type.scope
456
 
                if scope: # could be None if there was an error
457
 
                    self.generate_exttype_vtable(scope, code)
458
 
                    self.generate_new_function(scope, code)
459
 
                    self.generate_dealloc_function(scope, code)
460
 
                    self.generate_traverse_function(scope, code)
461
 
                    self.generate_clear_function(scope, code)
462
 
                    if scope.defines_any(["__getitem__"]):
463
 
                        self.generate_getitem_int_function(scope, code)
464
 
                    if scope.defines_any(["__setitem__", "__delitem__"]):
465
 
                        self.generate_ass_subscript_function(scope, code)
466
 
                    if scope.defines_any(["__setslice__", "__delslice__"]):
467
 
                        self.generate_ass_slice_function(scope, code)
468
 
                    if scope.defines_any(["__getattr__"]):
469
 
                        self.generate_getattro_function(scope, code)
470
 
                    if scope.defines_any(["__setattr__", "__delattr__"]):
471
 
                        self.generate_setattro_function(scope, code)
472
 
                    if scope.defines_any(["__get__"]):
473
 
                        self.generate_descr_get_function(scope, code)
474
 
                    if scope.defines_any(["__set__", "__delete__"]):
475
 
                        self.generate_descr_set_function(scope, code)
476
 
                    self.generate_property_accessors(scope, code)
477
 
                    self.generate_method_table(scope, code)
478
 
                    self.generate_member_table(scope, code)
479
 
                    self.generate_getset_table(scope, code)
480
 
                    self.generate_typeobj_definition(full_module_name, entry, code)
481
 
    
482
 
    def generate_exttype_vtable(self, scope, code):
483
 
        # Generate the definition of an extension type's vtable.
484
 
        type = scope.parent_type
485
 
        if type.vtable_cname:
486
 
            code.putln("static struct %s %s;" % (
487
 
                type.vtabstruct_cname,
488
 
                type.vtable_cname))
489
 
        
490
 
    def generate_self_cast(self, scope, code):
491
 
        type = scope.parent_type
492
 
        code.putln(
493
 
            "%s = (%s)o;" % (
494
 
                type.declaration_code("p"),
495
 
                type.declaration_code("")))
496
 
    
497
 
    def generate_new_function(self, scope, code):
498
 
        base_type = scope.parent_type.base_type
499
 
        code.putln("")
500
 
        code.putln(
501
 
            "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
502
 
                % scope.mangle_internal("tp_new"))
503
 
        if base_type:
504
 
            code.putln(
505
 
                "PyObject *o = %s->tp_new(t, a, k);" %
506
 
                    base_type.typeptr_cname)
507
 
        else:
508
 
            code.putln(
509
 
                "PyObject *o = (*t->tp_alloc)(t, 0);")
510
 
        self.generate_self_cast(scope, code)
511
 
        type = scope.parent_type
512
 
        if type.vtabslot_cname:
513
 
            code.putln("*(struct %s **)&p->%s = %s;" % (
514
 
                type.vtabstruct_cname,
515
 
                type.vtabslot_cname,
516
 
                type.vtabptr_cname))
517
 
        for entry in scope.var_entries:
518
 
            if entry.type.is_pyobject:
519
 
                code.put_init_var_to_py_none(entry, "p->%s")
520
 
        entry = scope.lookup_here("__new__")
521
 
        if entry:
522
 
            code.putln(
523
 
                "if (%s(o, a, k) < 0) {" % 
524
 
                    entry.func_cname)
525
 
            code.put_decref_clear("o", py_object_type);
526
 
            code.putln(
527
 
                "}")
528
 
        code.putln(
529
 
            "return o;")
530
 
        code.putln(
531
 
            "}")
532
 
    
533
 
    def generate_dealloc_function(self, scope, code):
534
 
        base_type = scope.parent_type.base_type
535
 
        code.putln("")
536
 
        code.putln(
537
 
            "static void %s(PyObject *o) {"
538
 
                % scope.mangle_internal("tp_dealloc"))
539
 
        self.generate_self_cast(scope, code)
540
 
        self.generate_usr_dealloc_call(scope, code)
541
 
        for entry in scope.var_entries:
542
 
            if entry.type.is_pyobject:
543
 
                code.put_xdecref("p->%s" % entry.cname, entry.type)
544
 
        if base_type:
545
 
            code.putln(
546
 
                "%s->tp_dealloc(o);" %
547
 
                    base_type.typeptr_cname)
548
 
        else:
549
 
            code.putln(
550
 
                "(*o->ob_type->tp_free)(o);")
551
 
        code.putln(
552
 
            "}")
553
 
    
554
 
    def generate_usr_dealloc_call(self, scope, code):
555
 
        entry = scope.lookup_here("__dealloc__")
556
 
        if entry:
557
 
            code.putln(
558
 
                "{")
559
 
            code.putln(
560
 
                    "PyObject *etype, *eval, *etb;")
561
 
            code.putln(
562
 
                    "PyErr_Fetch(&etype, &eval, &etb);")
563
 
            code.putln(
564
 
                    "++o->ob_refcnt;")
565
 
            code.putln(
566
 
                    "%s(o);" % 
567
 
                        entry.func_cname)
568
 
            code.putln(
569
 
                    "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
570
 
            code.putln(
571
 
                    "--o->ob_refcnt;")
572
 
            code.putln(
573
 
                    "PyErr_Restore(etype, eval, etb);")
574
 
            code.putln(
575
 
                "}")
576
 
    
577
 
    def generate_traverse_function(self, scope, code):
578
 
        base_type = scope.parent_type.base_type
579
 
        code.putln("")
580
 
        code.putln(
581
 
            "static int %s(PyObject *o, visitproc v, void *a) {"
582
 
                % scope.mangle_internal("tp_traverse"))
583
 
        code.putln(
584
 
                "int e;")
585
 
        self.generate_self_cast(scope, code)
586
 
        if base_type:
587
 
            code.putln(
588
 
                    "e = %s->tp_traverse(o, v, a); if (e) return e;" %
589
 
                        base_type.typeptr_cname)
590
 
        for entry in scope.var_entries:
591
 
            if entry.type.is_pyobject:
592
 
                var_code = "p->%s" % entry.cname
593
 
                code.putln(
594
 
                        "if (%s) {"
595
 
                            % var_code)
596
 
                if entry.type.is_extension_type:
597
 
                    var_code = "((PyObject*)%s)" % var_code
598
 
                code.putln(
599
 
                            "e = (*v)(%s, a); if (e) return e;" 
600
 
                                % var_code)
601
 
                code.putln(
602
 
                        "}")
603
 
        code.putln(
604
 
                "return 0;")
605
 
        code.putln(
606
 
            "}")
607
 
    
608
 
    def generate_clear_function(self, scope, code):
609
 
        base_type = scope.parent_type.base_type
610
 
        code.putln("")
611
 
        code.putln(
612
 
            "static int %s(PyObject *o) {"
613
 
                % scope.mangle_internal("tp_clear"))
614
 
        self.generate_self_cast(scope, code)
615
 
        if base_type:
616
 
            code.putln(
617
 
                "%s->tp_clear(o);" %
618
 
                    base_type.typeptr_cname)
619
 
        for entry in scope.var_entries:
620
 
            if entry.type.is_pyobject:
621
 
                name = "p->%s" % entry.cname
622
 
                code.put_xdecref(name, entry.type)
623
 
                #code.put_init_to_py_none(name)
624
 
                code.put_init_var_to_py_none(entry, "p->%s")
625
 
        code.putln(
626
 
            "return 0;")
627
 
        code.putln(
628
 
            "}")
629
 
        
630
 
    def generate_getitem_int_function(self, scope, code):
631
 
        # This function is put into the sq_item slot when
632
 
        # a __getitem__ method is present. It converts its
633
 
        # argument to a Python integer and calls mp_subscript.
634
 
        code.putln(
635
 
            "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
636
 
                scope.mangle_internal("sq_item"))
637
 
        code.putln(
638
 
                "PyObject *r;")
639
 
        code.putln(
640
 
                "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
641
 
        code.putln(
642
 
                "r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
643
 
        code.putln(
644
 
                "Py_DECREF(x);")
645
 
        code.putln(
646
 
                "return r;")
647
 
        code.putln(
648
 
            "}")
649
 
 
650
 
    def generate_ass_subscript_function(self, scope, code):
651
 
        # Setting and deleting an item are both done through
652
 
        # the ass_subscript method, so we dispatch to user's __setitem__
653
 
        # or __delitem__, or raise an exception.
654
 
        base_type = scope.parent_type.base_type
655
 
        set_entry = scope.lookup_here("__setitem__")
656
 
        del_entry = scope.lookup_here("__delitem__")
657
 
        code.putln("")
658
 
        code.putln(
659
 
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
660
 
                scope.mangle_internal("mp_ass_subscript"))
661
 
        code.putln(
662
 
                "if (v) {")
663
 
        if set_entry:
664
 
            code.putln(
665
 
                    "return %s(o, i, v);" %
666
 
                        set_entry.func_cname)
667
 
        else:
668
 
            self.generate_guarded_basetype_call(
669
 
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
670
 
            code.putln(
671
 
                    "PyErr_Format(PyExc_NotImplementedError,")
672
 
            code.putln(
673
 
                    '  "Subscript assignment not supported by %s", o->ob_type->tp_name);')
674
 
            code.putln(
675
 
                    "return -1;")
676
 
        code.putln(
677
 
                "}")
678
 
        code.putln(
679
 
                "else {")
680
 
        if del_entry:
681
 
            code.putln(
682
 
                    "return %s(o, i);" %
683
 
                        del_entry.func_cname)
684
 
        else:
685
 
            self.generate_guarded_basetype_call(
686
 
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
687
 
            code.putln(
688
 
                    "PyErr_Format(PyExc_NotImplementedError,")
689
 
            code.putln(
690
 
                    '  "Subscript deletion not supported by %s", o->ob_type->tp_name);')
691
 
            code.putln(
692
 
                    "return -1;")
693
 
        code.putln(
694
 
                "}")
695
 
        code.putln(
696
 
            "}")
697
 
    
698
 
    def generate_guarded_basetype_call(
699
 
            self, base_type, substructure, slot, args, code):
700
 
        if base_type:
701
 
            base_tpname = base_type.typeptr_cname
702
 
            if substructure:
703
 
                code.putln(
704
 
                    "if (%s->%s && %s->%s->%s)" % (
705
 
                        base_tpname, substructure, base_tpname, substructure, slot))
706
 
                code.putln(
707
 
                    "  return %s->%s->%s(%s);" % (
708
 
                        base_tpname, substructure, slot, args))
709
 
            else:
710
 
                code.putln(
711
 
                    "if (%s->%s)" % (
712
 
                        base_tpname, slot))
713
 
                code.putln(
714
 
                    "  return %s->%s(%s);" % (
715
 
                        base_tpname, slot, args))
716
 
 
717
 
    def generate_ass_slice_function(self, scope, code):
718
 
        # Setting and deleting a slice are both done through
719
 
        # the ass_slice method, so we dispatch to user's __setslice__
720
 
        # or __delslice__, or raise an exception.
721
 
        base_type = scope.parent_type.base_type
722
 
        set_entry = scope.lookup_here("__setslice__")
723
 
        del_entry = scope.lookup_here("__delslice__")
724
 
        code.putln("")
725
 
        code.putln(
726
 
            "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
727
 
                scope.mangle_internal("sq_ass_slice"))
728
 
        code.putln(
729
 
                "if (v) {")
730
 
        if set_entry:
731
 
            code.putln(
732
 
                    "return %s(o, i, j, v);" %
733
 
                        set_entry.func_cname)
734
 
        else:
735
 
            self.generate_guarded_basetype_call(
736
 
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
737
 
            code.putln(
738
 
                    "PyErr_Format(PyExc_NotImplementedError,")
739
 
            code.putln(
740
 
                    '  "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
741
 
            code.putln(
742
 
                    "return -1;")
743
 
        code.putln(
744
 
                "}")
745
 
        code.putln(
746
 
                "else {")
747
 
        if del_entry:
748
 
            code.putln(
749
 
                    "return %s(o, i, j);" %
750
 
                        del_entry.func_cname)
751
 
        else:
752
 
            self.generate_guarded_basetype_call(
753
 
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
754
 
            code.putln(
755
 
                    "PyErr_Format(PyExc_NotImplementedError,")
756
 
            code.putln(
757
 
                    '  "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
758
 
            code.putln(
759
 
                    "return -1;")
760
 
        code.putln(
761
 
                "}")
762
 
        code.putln(
763
 
            "}")
764
 
 
765
 
    def generate_getattro_function(self, scope, code):
766
 
        # First try to get the attribute using PyObject_GenericGetAttr.
767
 
        # If that raises an AttributeError, call the user's __getattr__
768
 
        # method.
769
 
        entry = scope.lookup_here("__getattr__")
770
 
        code.putln("")
771
 
        code.putln(
772
 
            "static PyObject *%s(PyObject *o, PyObject *n) {"
773
 
                % scope.mangle_internal("tp_getattro"))
774
 
        code.putln(
775
 
                "PyObject *v = PyObject_GenericGetAttr(o, n);")
776
 
        code.putln(
777
 
                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
778
 
        code.putln(
779
 
                    "PyErr_Clear();")
780
 
        code.putln(
781
 
                    "v = %s(o, n);" %
782
 
                        entry.func_cname)
783
 
        code.putln(
784
 
                "}")
785
 
        code.putln(
786
 
                "return v;")
787
 
        code.putln(
788
 
            "}")
789
 
    
790
 
    def generate_setattro_function(self, scope, code):
791
 
        # Setting and deleting an attribute are both done through
792
 
        # the setattro method, so we dispatch to user's __setattr__
793
 
        # or __delattr__ or fall back on PyObject_GenericSetAttr.
794
 
        base_type = scope.parent_type.base_type
795
 
        set_entry = scope.lookup_here("__setattr__")
796
 
        del_entry = scope.lookup_here("__delattr__")
797
 
        code.putln("")
798
 
        code.putln(
799
 
            "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
800
 
                scope.mangle_internal("tp_setattro"))
801
 
        code.putln(
802
 
                "if (v) {")
803
 
        if set_entry:
804
 
            code.putln(
805
 
                    "return %s(o, n, v);" %
806
 
                        set_entry.func_cname)
807
 
        else:
808
 
            self.generate_guarded_basetype_call(
809
 
                base_type, None, "tp_setattro", "o, n, v", code)
810
 
            code.putln(
811
 
                    "return PyObject_GenericSetAttr(o, n, v);")
812
 
        code.putln(
813
 
                "}")
814
 
        code.putln(
815
 
                "else {")
816
 
        if del_entry:
817
 
            code.putln(
818
 
                    "return %s(o, n);" %
819
 
                        del_entry.func_cname)
820
 
        else:
821
 
            self.generate_guarded_basetype_call(
822
 
                base_type, None, "tp_setattro", "o, n, v", code)
823
 
            code.putln(
824
 
                    "return PyObject_GenericSetAttr(o, n, 0);")
825
 
        code.putln(
826
 
                "}")
827
 
        code.putln(
828
 
            "}")
829
 
    
830
 
    def generate_descr_get_function(self, scope, code):
831
 
        # The __get__ function of a descriptor object can be
832
 
        # called with NULL for the second or third arguments
833
 
        # under some circumstances, so we replace them with
834
 
        # None in that case.
835
 
        user_get_entry = scope.lookup_here("__get__")
836
 
        code.putln("")
837
 
        code.putln(
838
 
            "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
839
 
                scope.mangle_internal("tp_descr_get"))
840
 
        code.putln(
841
 
            "PyObject *r = 0;")
842
 
        code.putln(
843
 
            "if (!i) i = Py_None;")
844
 
        code.putln(
845
 
            "if (!c) c = Py_None;")
846
 
        #code.put_incref("i", py_object_type)
847
 
        #code.put_incref("c", py_object_type)
848
 
        code.putln(
849
 
            "r = %s(o, i, c);" %
850
 
                user_get_entry.func_cname)
851
 
        #code.put_decref("i", py_object_type)
852
 
        #code.put_decref("c", py_object_type)
853
 
        code.putln(
854
 
            "return r;")
855
 
        code.putln(
856
 
            "}")
857
 
    
858
 
    def generate_descr_set_function(self, scope, code):
859
 
        # Setting and deleting are both done through the __set__
860
 
        # method of a descriptor, so we dispatch to user's __set__
861
 
        # or __delete__ or raise an exception.
862
 
        base_type = scope.parent_type.base_type
863
 
        user_set_entry = scope.lookup_here("__set__")
864
 
        user_del_entry = scope.lookup_here("__delete__")
865
 
        code.putln("")
866
 
        code.putln(
867
 
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
868
 
                scope.mangle_internal("tp_descr_set"))
869
 
        code.putln(
870
 
                "if (v) {")
871
 
        if user_set_entry:
872
 
            code.putln(
873
 
                    "return %s(o, i, v);" %
874
 
                        user_set_entry.func_cname)
875
 
        else:
876
 
            self.generate_guarded_basetype_call(
877
 
                base_type, None, "tp_descr_set", "o, i, v", code)
878
 
            code.putln(
879
 
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
880
 
            code.putln(
881
 
                    "return -1;")
882
 
        code.putln(
883
 
                "}")
884
 
        code.putln(
885
 
                "else {")
886
 
        if user_del_entry:
887
 
            code.putln(
888
 
                    "return %s(o, i);" %
889
 
                        user_del_entry.func_cname)
890
 
        else:
891
 
            self.generate_guarded_basetype_call(
892
 
                base_type, None, "tp_descr_set", "o, i, v", code)
893
 
            code.putln(
894
 
                    'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
895
 
            code.putln(
896
 
                    "return -1;")
897
 
        code.putln(
898
 
                "}")            
899
 
        code.putln(
900
 
            "}")
901
 
    
902
 
    def generate_property_accessors(self, cclass_scope, code):
903
 
        for entry in cclass_scope.property_entries:
904
 
            property_scope = entry.scope
905
 
            if property_scope.defines_any(["__get__"]):
906
 
                self.generate_property_get_function(entry, code)
907
 
            if property_scope.defines_any(["__set__", "__del__"]):
908
 
                self.generate_property_set_function(entry, code)
909
 
    
910
 
    def generate_property_get_function(self, property_entry, code):
911
 
        property_scope = property_entry.scope
912
 
        property_entry.getter_cname = property_scope.parent_scope.mangle(
913
 
            Naming.prop_get_prefix, property_entry.name)
914
 
        get_entry = property_scope.lookup_here("__get__")
915
 
        code.putln("")
916
 
        code.putln(
917
 
            "static PyObject *%s(PyObject *o, void *x) {" %
918
 
                property_entry.getter_cname)
919
 
        code.putln(
920
 
                "return %s(o);" %
921
 
                    get_entry.func_cname)
922
 
        code.putln(
923
 
            "}")
924
 
    
925
 
    def generate_property_set_function(self, property_entry, code):
926
 
        property_scope = property_entry.scope
927
 
        property_entry.setter_cname = property_scope.parent_scope.mangle(
928
 
            Naming.prop_set_prefix, property_entry.name)
929
 
        set_entry = property_scope.lookup_here("__set__")
930
 
        del_entry = property_scope.lookup_here("__del__")
931
 
        code.putln("")
932
 
        code.putln(
933
 
            "static int %s(PyObject *o, PyObject *v, void *x) {" %
934
 
                property_entry.setter_cname)
935
 
        code.putln(
936
 
                "if (v) {")
937
 
        if set_entry:
938
 
            code.putln(
939
 
                    "return %s(o, v);" %
940
 
                        set_entry.func_cname)
941
 
        else:
942
 
            code.putln(
943
 
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
944
 
            code.putln(
945
 
                    "return -1;")
946
 
        code.putln(
947
 
                "}")
948
 
        code.putln(
949
 
                "else {")
950
 
        if del_entry:
951
 
            code.putln(
952
 
                    "return %s(o);" %
953
 
                        del_entry.func_cname)
954
 
        else:
955
 
            code.putln(
956
 
                    'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
957
 
            code.putln(
958
 
                    "return -1;")
959
 
        code.putln(
960
 
                "}")
961
 
        code.putln(
962
 
            "}")
963
 
 
964
 
    def generate_typeobj_definition(self, modname, entry, code):
965
 
        type = entry.type
966
 
        scope = type.scope
967
 
        for suite in TypeSlots.substructures:
968
 
            suite.generate_substructure(scope, code)
969
 
        code.putln("")
970
 
        if entry.visibility == 'public':
971
 
            header = "DL_EXPORT(PyTypeObject) %s = {"
972
 
        else:
973
 
            #header = "statichere PyTypeObject %s = {"
974
 
            header = "PyTypeObject %s = {"
975
 
        #code.putln(header % scope.parent_type.typeobj_cname)
976
 
        code.putln(header % type.typeobj_cname)
977
 
        code.putln(
978
 
            "PyObject_HEAD_INIT(0)")
979
 
        code.putln(
980
 
            "0, /*ob_size*/")
981
 
        code.putln(
982
 
            '"%s.%s", /*tp_name*/' % (
983
 
                modname, scope.class_name))
984
 
        if type.typedef_flag:
985
 
            objstruct = type.objstruct_cname
986
 
        else:
987
 
            #objstruct = "struct %s" % scope.parent_type.objstruct_cname
988
 
            objstruct = "struct %s" % type.objstruct_cname
989
 
        code.putln(
990
 
            "sizeof(%s), /*tp_basicsize*/" %
991
 
                objstruct)
992
 
        code.putln(
993
 
            "0, /*tp_itemsize*/")
994
 
        for slot in TypeSlots.slot_table:
995
 
            slot.generate(scope, code)
996
 
        code.putln(
997
 
            "};")
998
 
    
999
 
    def generate_method_table(self, env, code):
1000
 
        code.putln("")
1001
 
        code.putln(
1002
 
            "static struct PyMethodDef %s[] = {" % 
1003
 
                env.method_table_cname)
1004
 
        for entry in env.pyfunc_entries:
1005
 
                code.put_pymethoddef(entry, ",")
1006
 
        code.putln(
1007
 
                "{0, 0, 0, 0}")
1008
 
        code.putln(
1009
 
            "};")
1010
 
    
1011
 
    def generate_member_table(self, env, code):
1012
 
        #print "ModuleNode.generate_member_table: scope =", env ###
1013
 
        if env.public_attr_entries:
1014
 
            code.putln("")
1015
 
            code.putln(
1016
 
                "static struct PyMemberDef %s[] = {" %
1017
 
                    env.member_table_cname)
1018
 
            type = env.parent_type
1019
 
            if type.typedef_flag:
1020
 
                objstruct = type.objstruct_cname
1021
 
            else:
1022
 
                objstruct = "struct %s" % type.objstruct_cname
1023
 
            for entry in env.public_attr_entries:
1024
 
                type_code = entry.type.pymemberdef_typecode
1025
 
                if entry.visibility == 'readonly':
1026
 
                    flags = "READONLY"
1027
 
                else:
1028
 
                    flags = "0"
1029
 
                code.putln('{"%s", %s, %s, %s, 0},' % (
1030
 
                    entry.name,
1031
 
                    type_code,
1032
 
                    "offsetof(%s, %s)" % (objstruct, entry.name),
1033
 
                    flags))
1034
 
            code.putln(
1035
 
                    "{0, 0, 0, 0, 0}")
1036
 
            code.putln(
1037
 
                "};")
1038
 
    
1039
 
    def generate_getset_table(self, env, code):
1040
 
        if env.property_entries:
1041
 
            code.putln("")
1042
 
            code.putln(
1043
 
                "static struct PyGetSetDef %s[] = {" %
1044
 
                    env.getset_table_cname)
1045
 
            for entry in env.property_entries:
1046
 
                code.putln(
1047
 
                    '{"%s", %s, %s, %s, 0},' % (
1048
 
                        entry.name,
1049
 
                        entry.getter_cname or "0",
1050
 
                        entry.setter_cname or "0",
1051
 
                        entry.doc_cname or "0"))
1052
 
            code.putln(
1053
 
                    "{0, 0, 0, 0, 0}")
1054
 
            code.putln(
1055
 
                "};")
1056
 
    
1057
 
    def generate_interned_name_table(self, env, code):
1058
 
        items = env.intern_map.items()
1059
 
        if items:
1060
 
            items.sort()
1061
 
            code.putln("")
1062
 
            code.putln(
1063
 
                "static __Pyx_InternTabEntry %s[] = {" %
1064
 
                    Naming.intern_tab_cname)
1065
 
            for (name, cname) in items:
1066
 
                code.putln(
1067
 
                    '{&%s, "%s"},' % (
1068
 
                        cname,
1069
 
                        name))
1070
 
            code.putln(
1071
 
                "{0, 0}")
1072
 
            code.putln(
1073
 
                "};")
1074
 
    
1075
 
    def generate_py_string_table(self, env, code):
1076
 
        entries = env.all_pystring_entries
1077
 
        if entries:
1078
 
            code.putln("")
1079
 
            code.putln(
1080
 
                "static __Pyx_StringTabEntry %s[] = {" %
1081
 
                    Naming.stringtab_cname)
1082
 
            for entry in entries:
1083
 
                code.putln(
1084
 
                    "{&%s, %s, sizeof(%s)}," % (
1085
 
                        entry.pystring_cname,
1086
 
                        entry.cname,
1087
 
                        entry.cname))
1088
 
            code.putln(
1089
 
                "{0, 0, 0}")
1090
 
            code.putln(
1091
 
                "};")
1092
 
    
1093
 
    def generate_filename_init_prototype(self, code):
1094
 
        code.putln("");
1095
 
        code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1096
 
 
1097
 
    def generate_module_init_func(self, imported_modules, env, code):
1098
 
        code.putln("")
1099
 
        header = "PyMODINIT_FUNC init%s(void)" % env.module_name
1100
 
        code.putln("%s; /*proto*/" % header)
1101
 
        code.putln("%s {" % header)
1102
 
        code.put_var_declarations(env.temp_entries)
1103
 
        #code.putln("/*--- Libary function declarations ---*/")
1104
 
        env.generate_library_function_declarations(code)
1105
 
        self.generate_filename_init_call(code)
1106
 
        #code.putln("/*--- Module creation code ---*/")
1107
 
        self.generate_module_creation_code(env, code)
1108
 
        #code.putln("/*--- Intern code ---*/")
1109
 
        self.generate_intern_code(env, code)
1110
 
        #code.putln("/*--- String init code ---*/")
1111
 
        self.generate_string_init_code(env, code)
1112
 
        #code.putln("/*--- Global init code ---*/")
1113
 
        self.generate_global_init_code(env, code)
1114
 
        #code.putln("/*--- Type import code ---*/")
1115
 
        for module in imported_modules:
1116
 
            self.generate_type_import_code_for_module(module, env, code)
1117
 
        #code.putln("/*--- Type init code ---*/")
1118
 
        self.generate_type_init_code(env, code)
1119
 
        #code.putln("/*--- Execution code ---*/")
1120
 
        self.body.generate_execution_code(code)
1121
 
        code.putln("return;")
1122
 
        code.put_label(code.error_label)
1123
 
        code.put_var_xdecrefs(env.temp_entries)
1124
 
        code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
1125
 
        env.use_utility_code(traceback_utility_code)
1126
 
        code.putln('}')
1127
 
    
1128
 
    def generate_filename_init_call(self, code):
1129
 
        code.putln("%s();" % Naming.fileinit_cname)
1130
 
    
1131
 
    def generate_module_creation_code(self, env, code):
1132
 
        # Generate code to create the module object and
1133
 
        # install the builtins.
1134
 
        if env.doc:
1135
 
            doc = env.doc_cname
1136
 
        else:
1137
 
            doc = "0"
1138
 
        code.putln(
1139
 
            '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
1140
 
                env.module_cname, 
1141
 
                env.module_name, 
1142
 
                env.method_table_cname, 
1143
 
                doc))
1144
 
        code.putln(
1145
 
            "if (!%s) %s;" % (
1146
 
                env.module_cname,
1147
 
                code.error_goto(self.pos)));
1148
 
        code.putln(
1149
 
            '%s = PyImport_AddModule("__builtin__");' %
1150
 
                Naming.builtins_cname)
1151
 
        code.putln(
1152
 
            "if (!%s) %s;" % (
1153
 
                Naming.builtins_cname,
1154
 
                code.error_goto(self.pos)));
1155
 
        code.putln(
1156
 
            'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1157
 
                env.module_cname,
1158
 
                Naming.builtins_cname,
1159
 
                code.error_goto(self.pos)))
1160
 
    
1161
 
    def generate_intern_code(self, env, code):
1162
 
        if env.intern_map:
1163
 
            env.use_utility_code(init_intern_tab_utility_code);
1164
 
            code.putln(
1165
 
                "if (__Pyx_InternStrings(%s) < 0) %s;" % (
1166
 
                    Naming.intern_tab_cname,
1167
 
                    code.error_goto(self.pos)))
1168
 
    
1169
 
    def generate_string_init_code(self, env, code):
1170
 
        if env.all_pystring_entries:
1171
 
            env.use_utility_code(init_string_tab_utility_code)
1172
 
            code.putln(
1173
 
                "if (__Pyx_InitStrings(%s) < 0) %s;" % (
1174
 
                    Naming.stringtab_cname,
1175
 
                    code.error_goto(self.pos)))
1176
 
    
1177
 
    def generate_global_init_code(self, env, code):
1178
 
        # Generate code to initialise global PyObject *
1179
 
        # variables to None.
1180
 
        for entry in env.var_entries:
1181
 
            if entry.visibility <> 'extern':
1182
 
                if entry.type.is_pyobject:
1183
 
                    code.put_init_var_to_py_none(entry)
1184
 
    
1185
 
    def generate_type_import_code_for_module(self, module, env, code):
1186
 
        # Generate type import code for all extension types in
1187
 
        # an imported module.
1188
 
        if module.c_class_entries:
1189
 
            for entry in module.c_class_entries:
1190
 
                self.generate_type_import_code(env, entry, code)
1191
 
    
1192
 
    def generate_type_init_code(self, env, code):
1193
 
        # Generate type import code for extern extension types
1194
 
        # and type ready code for non-extern ones.
1195
 
        for entry in env.c_class_entries:
1196
 
            if entry.visibility == 'extern':
1197
 
                self.generate_type_import_code(env, entry, code)
1198
 
            else:
1199
 
                self.generate_exttype_vtable_init_code(entry, code)
1200
 
                self.generate_type_ready_code(env, entry, code)
1201
 
                self.generate_typeptr_assignment_code(entry, code)
1202
 
    
1203
 
    def use_type_import_utility_code(self, env):
1204
 
        import ExprNodes
1205
 
        env.use_utility_code(type_import_utility_code)
1206
 
        env.use_utility_code(ExprNodes.import_utility_code)
1207
 
    
1208
 
    def generate_type_import_code(self, env, entry, code):
1209
 
        # Generate code to import the typeobject of an
1210
 
        # extension type defined in another module, and
1211
 
        # extract its C method table pointer if any.
1212
 
        type = entry.type
1213
 
        if type.typedef_flag:
1214
 
            objstruct = type.objstruct_cname
1215
 
        else:
1216
 
            objstruct = "struct %s" % type.objstruct_cname
1217
 
        code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
1218
 
            type.typeptr_cname,
1219
 
            type.module_name, 
1220
 
            type.name,
1221
 
            objstruct,
1222
 
            type.typeptr_cname,
1223
 
            code.error_goto(entry.pos)))
1224
 
        self.use_type_import_utility_code(env)
1225
 
        if type.vtabptr_cname:
1226
 
            code.putln(
1227
 
                "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1228
 
                    type.typeptr_cname,
1229
 
                    type.vtabptr_cname,
1230
 
                    code.error_goto(entry.pos)))
1231
 
            env.use_utility_code(get_vtable_utility_code)
1232
 
    
1233
 
    def generate_type_ready_code(self, env, entry, code):
1234
 
        # Generate a call to PyType_Ready for an extension
1235
 
        # type defined in this module.
1236
 
        type = entry.type
1237
 
        typeobj_cname = type.typeobj_cname
1238
 
        scope = type.scope
1239
 
        if scope: # could be None if there was an error
1240
 
            if entry.visibility <> 'extern':
1241
 
                for slot in TypeSlots.slot_table:
1242
 
                    slot.generate_dynamic_init_code(scope, code)
1243
 
                code.putln(
1244
 
                    "if (PyType_Ready(&%s) < 0) %s" % (
1245
 
                        typeobj_cname,
1246
 
                        code.error_goto(entry.pos)))
1247
 
                if type.vtable_cname:
1248
 
                    code.putln(
1249
 
                        "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
1250
 
                            typeobj_cname,
1251
 
                            type.vtabptr_cname,
1252
 
                            code.error_goto(entry.pos)))
1253
 
                    env.use_utility_code(set_vtable_utility_code)
1254
 
                code.putln(
1255
 
                    'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
1256
 
                        Naming.module_cname,
1257
 
                        scope.class_name,
1258
 
                        typeobj_cname,
1259
 
                        code.error_goto(entry.pos)))
1260
 
                weakref_entry = scope.lookup_here("__weakref__")
1261
 
                if weakref_entry:
1262
 
                    if weakref_entry.type is py_object_type:
1263
 
                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
1264
 
                        code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
1265
 
                            tp_weaklistoffset,
1266
 
                            tp_weaklistoffset,
1267
 
                            type.objstruct_cname,
1268
 
                            weakref_entry.cname))
1269
 
                    else:
1270
 
                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
1271
 
    
1272
 
    def generate_exttype_vtable_init_code(self, entry, code):
1273
 
        # Generate code to initialise the C method table of an
1274
 
        # extension type.
1275
 
        type = entry.type
1276
 
        if type.vtable_cname:
1277
 
            code.putln(
1278
 
                "%s = &%s;" % (
1279
 
                    type.vtabptr_cname,
1280
 
                    type.vtable_cname))
1281
 
            if type.base_type and type.base_type.vtabptr_cname:
1282
 
                code.putln(
1283
 
                    "%s.%s = *%s;" % (
1284
 
                        type.vtable_cname,
1285
 
                        Naming.obj_base_cname,
1286
 
                        type.base_type.vtabptr_cname))
1287
 
            for meth_entry in type.scope.cfunc_entries:
1288
 
                if meth_entry.func_cname:
1289
 
                    code.putln(
1290
 
                        "*(void **)&%s.%s = (void *)%s;" % (
1291
 
                            type.vtable_cname,
1292
 
                            meth_entry.cname,
1293
 
                            meth_entry.func_cname))
1294
 
    
1295
 
    def generate_typeptr_assignment_code(self, entry, code):
1296
 
        # Generate code to initialise the typeptr of an extension
1297
 
        # type defined in this module to point to its type object.
1298
 
        type = entry.type
1299
 
        if type.typeobj_cname:
1300
 
            code.putln(
1301
 
                "%s = &%s;" % (
1302
 
                    type.typeptr_cname, type.typeobj_cname))
1303
 
    
1304
 
    def generate_utility_functions(self, env, code):
1305
 
        code.putln("")
1306
 
        code.putln("/* Runtime support code */")
1307
 
        code.putln("")
1308
 
        code.putln("static void %s(void) {" % Naming.fileinit_cname)
1309
 
        code.putln("%s = %s;" % 
1310
 
            (Naming.filetable_cname, Naming.filenames_cname))
1311
 
        code.putln("}")
1312
 
        for utility_code in env.utility_code_used:
1313
 
            code.put(utility_code)
1314
96
 
1315
97
 
1316
98
class StatListNode(Node):
1705
487
        # ----- Top-level constants used by this function
1706
488
        self.generate_interned_name_decls(lenv, code)
1707
489
        self.generate_py_string_decls(lenv, code)
1708
 
        #code.putln("")
1709
 
        #code.put_var_declarations(lenv.const_entries, static = 1)
1710
490
        self.generate_const_definitions(lenv, code)
1711
491
        # ----- Function header
1712
492
        code.putln("")
1729
509
        # ----- Fetch arguments
1730
510
        self.generate_argument_parsing_code(code)
1731
511
        self.generate_argument_increfs(lenv, code)
1732
 
        #self.generate_stararg_getting_code(code)
1733
 
        self.generate_argument_conversion_code(code)
1734
512
        # ----- Initialise local variables
1735
513
        for entry in lenv.var_entries:
1736
 
            if entry.type.is_pyobject and entry.init_to_none:
 
514
            if entry.type.is_pyobject and entry.init_to_none and entry.used:
1737
515
                code.put_init_var_to_py_none(entry)
1738
 
        # ----- Check types of arguments
 
516
        # ----- Check and convert arguments
 
517
        self.generate_argument_conversion_code(code)
1739
518
        self.generate_argument_type_tests(code)
1740
519
        # ----- Function body
1741
520
        self.body.generate_execution_code(code)
1751
530
            val = self.return_type.default_value
1752
531
            if val:
1753
532
                code.putln("%s = %s;" % (Naming.retval_cname, val))
1754
 
        code.putln("goto %s;" % code.return_label)
 
533
        #code.putln("goto %s;" % code.return_label)
1755
534
        # ----- Error cleanup
1756
 
        code.put_label(code.error_label)
1757
 
        code.put_var_xdecrefs(lenv.temp_entries)
1758
 
        err_val = self.error_value()
1759
 
        exc_check = self.caller_will_check_exceptions()
1760
 
        if err_val is not None or exc_check:
1761
 
            code.putln(
1762
 
                '__Pyx_AddTraceback("%s");' % 
1763
 
                    self.entry.qualified_name)
1764
 
            if err_val is not None:
1765
 
                code.putln(
1766
 
                    "%s = %s;" % (
1767
 
                        Naming.retval_cname, 
1768
 
                        err_val))
1769
 
        else:
1770
 
            code.putln(
1771
 
                '__Pyx_WriteUnraisable("%s");' % 
1772
 
                    self.entry.qualified_name)
1773
 
            env.use_utility_code(unraisable_exception_utility_code)
 
535
        if code.error_label in code.labels_used:
 
536
            code.put_goto(code.return_label)
 
537
            code.put_label(code.error_label)
 
538
            code.put_var_xdecrefs(lenv.temp_entries)
 
539
            err_val = self.error_value()
 
540
            exc_check = self.caller_will_check_exceptions()
 
541
            if err_val is not None or exc_check:
 
542
                code.putln(
 
543
                    '__Pyx_AddTraceback("%s");' % 
 
544
                        self.entry.qualified_name)
 
545
                if err_val is not None:
 
546
                    code.putln(
 
547
                        "%s = %s;" % (
 
548
                            Naming.retval_cname, 
 
549
                            err_val))
 
550
            else:
 
551
                code.putln(
 
552
                    '__Pyx_WriteUnraisable("%s");' % 
 
553
                        self.entry.qualified_name)
 
554
                env.use_utility_code(unraisable_exception_utility_code)
1774
555
        # ----- Return cleanup
1775
556
        code.put_label(code.return_label)
1776
 
        code.put_var_decrefs(lenv.var_entries)
 
557
        code.put_var_decrefs(lenv.var_entries, used_only = 1)
1777
558
        code.put_var_decrefs(lenv.arg_entries)
1778
559
        self.put_stararg_decrefs(code)
1779
560
        if not self.return_type.is_void:
1880
661
    def generate_argument_parsing_code(self, code):
1881
662
        pass
1882
663
    
1883
 
#       def generate_stararg_getting_code(self, code):
1884
 
#               pass
1885
 
    
1886
664
    def generate_argument_conversion_code(self, code):
1887
665
        pass
1888
666
    
2023
801
                arg.entry.init_to_none = 0
2024
802
            else:
2025
803
                arg.entry = self.declare_argument(env, arg)
 
804
            arg.entry.used = 1
2026
805
            arg.entry.is_self_arg = arg.is_self_arg
2027
806
            if arg.hdr_type:
2028
807
                if arg.is_self_arg or \
2033
812
 
2034
813
    def declare_python_arg(self, env, arg):
2035
814
        if arg:
2036
 
            arg.entry = env.declare_var(arg.name, 
 
815
            entry = env.declare_var(arg.name, 
2037
816
                PyrexTypes.py_object_type, arg.pos)
2038
 
            arg.entry.init = "0"
2039
 
            arg.entry.init_to_none = 0
2040
 
            arg.entry.xdecref_cleanup = 1
 
817
            entry.used = 1
 
818
            entry.init = "0"
 
819
            entry.init_to_none = 0
 
820
            entry.xdecref_cleanup = 1
 
821
            arg.entry = entry
2041
822
            
2042
823
    def analyse_expressions(self, env):
2043
824
        self.analyse_default_values(env)
2052
833
                    arg.default = arg.default.coerce_to(arg.type, env)
2053
834
                    arg.default.allocate_temps(env)
2054
835
                    arg.default_entry = env.add_default_value(arg.type)
 
836
                    arg.default_entry.used = 1
2055
837
                else:
2056
838
                    error(arg.pos,
2057
839
                        "This argument cannot have a default value")
2347
1129
        self.scope = cenv
2348
1130
        self.body.analyse_declarations(cenv)
2349
1131
        self.body.analyse_expressions(cenv)
2350
 
        self.target.analyse_target_expression(env)
 
1132
        self.target.analyse_target_expression(env, self.classobj)
2351
1133
        self.dict.release_temp(env)
2352
 
        self.classobj.release_temp(env)
2353
 
        self.target.release_target_temp(env)
2354
 
        #env.recycle_pending_temps()
 
1134
        #self.classobj.release_temp(env)
 
1135
        #self.target.release_target_temp(env)
2355
1136
    
2356
1137
    def generate_function_definitions(self, env, code):
2357
1138
        self.generate_py_string_decls(self.scope, code)
2496
1277
    def analyse_expressions(self, env):
2497
1278
        self.expr.analyse_expressions(env)
2498
1279
        self.expr.release_temp(env)
2499
 
        #env.recycle_pending_temps() # TEMPORARY
2500
1280
    
2501
1281
    def generate_execution_code(self, code):
2502
1282
        self.expr.generate_evaluation_code(code)
2515
1295
    #  to any of the left hand sides.
2516
1296
 
2517
1297
    def analyse_expressions(self, env):
2518
 
        self.analyse_expressions_1(env)
2519
 
        self.analyse_expressions_2(env)
 
1298
        self.analyse_types(env)
 
1299
        self.allocate_rhs_temps(env)
 
1300
        self.allocate_lhs_temps(env)
 
1301
 
 
1302
#       def analyse_expressions(self, env):
 
1303
#               self.analyse_expressions_1(env)
 
1304
#               self.analyse_expressions_2(env)
2520
1305
 
2521
1306
    def generate_execution_code(self, code):
2522
1307
        self.generate_rhs_evaluation_code(code)
2534
1319
    def analyse_declarations(self, env):
2535
1320
        self.lhs.analyse_target_declaration(env)
2536
1321
    
2537
 
    def analyse_expressions_1(self, env, use_temp = 0):
 
1322
    def analyse_types(self, env, use_temp = 0):
2538
1323
        self.rhs.analyse_types(env)
2539
1324
        self.lhs.analyse_target_types(env)
2540
1325
        self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2541
1326
        if use_temp:
2542
1327
            self.rhs = self.rhs.coerce_to_temp(env)
 
1328
    
 
1329
    def allocate_rhs_temps(self, env):
2543
1330
        self.rhs.allocate_temps(env)
 
1331
 
 
1332
    def allocate_lhs_temps(self, env):
 
1333
        self.lhs.allocate_target_temps(env, self.rhs)
 
1334
        #self.lhs.release_target_temp(env)
 
1335
        #self.rhs.release_temp(env)             
2544
1336
    
2545
 
    def analyse_expressions_2(self, env):
2546
 
        self.lhs.allocate_target_temps(env)
2547
 
        self.lhs.release_target_temp(env)
2548
 
        self.rhs.release_temp(env)              
 
1337
#       def analyse_expressions_1(self, env, use_temp = 0):
 
1338
#               self.rhs.analyse_types(env)
 
1339
#               self.lhs.analyse_target_types(env)
 
1340
#               self.rhs = self.rhs.coerce_to(self.lhs.type, env)
 
1341
#               if use_temp:
 
1342
#                       self.rhs = self.rhs.coerce_to_temp(env)
 
1343
#               self.rhs.allocate_temps(env)
 
1344
#       
 
1345
#       def analyse_expressions_2(self, env):
 
1346
#               self.lhs.allocate_target_temps(env)
 
1347
#               self.lhs.release_target_temp(env)
 
1348
#               self.rhs.release_temp(env)              
2549
1349
 
2550
1350
    def generate_rhs_evaluation_code(self, code):
2551
1351
        self.rhs.generate_evaluation_code(code)
2570
1370
        for lhs in self.lhs_list:
2571
1371
            lhs.analyse_target_declaration(env)
2572
1372
    
2573
 
#       def analyse_expressions(self, env):
2574
 
#               import ExprNodes
2575
 
#               self.rhs.analyse_types(env)
2576
 
#               self.rhs = self.rhs.coerce_to_temp(env)
2577
 
#               self.rhs.allocate_temps(env)
2578
 
#               self.coerced_rhs_list = []
2579
 
#               for lhs in self.lhs_list:
2580
 
#                       lhs.analyse_target_types(env)
2581
 
#                       coerced_rhs = ExprNodes.CloneNode(self.rhs).coerce_to(lhs.type, env)
2582
 
#                       self.coerced_rhs_list.append(coerced_rhs)
2583
 
#                       coerced_rhs.allocate_temps(env)
2584
 
#                       lhs.allocate_target_temps(env)
2585
 
#                       coerced_rhs.release_temp(env)
2586
 
#                       lhs.release_target_temp(env)
2587
 
#               self.rhs.release_temp(env)
2588
 
 
2589
 
    def analyse_expressions_1(self, env, use_temp = 0):
 
1373
    def analyse_types(self, env, use_temp = 0):
2590
1374
        self.rhs.analyse_types(env)
2591
1375
        if use_temp:
2592
1376
            self.rhs = self.rhs.coerce_to_temp(env)
2593
1377
        else:
2594
1378
            self.rhs = self.rhs.coerce_to_simple(env)
2595
 
        self.rhs.allocate_temps(env)
2596
 
    
2597
 
    def analyse_expressions_2(self, env):
2598
1379
        from ExprNodes import CloneNode
2599
1380
        self.coerced_rhs_list = []
2600
1381
        for lhs in self.lhs_list:
2602
1383
            rhs = CloneNode(self.rhs)
2603
1384
            rhs = rhs.coerce_to(lhs.type, env)
2604
1385
            self.coerced_rhs_list.append(rhs)
 
1386
 
 
1387
    def allocate_rhs_temps(self, env):
 
1388
        self.rhs.allocate_temps(env)
 
1389
    
 
1390
    def allocate_lhs_temps(self, env):
 
1391
        for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2605
1392
            rhs.allocate_temps(env)
2606
 
            lhs.allocate_target_temps(env)
2607
 
            lhs.release_target_temp(env)
2608
 
            rhs.release_temp(env)
 
1393
            lhs.allocate_target_temps(env, rhs)
 
1394
            #lhs.release_target_temp(env)
 
1395
            #rhs.release_temp(env)
2609
1396
        self.rhs.release_temp(env)
2610
 
            
2611
 
#       def generate_execution_code(self, code):
2612
 
#               self.rhs.generate_evaluation_code(code)
2613
 
#               for i in range(len(self.lhs_list)):
2614
 
#                       lhs = self.lhs_list[i]
2615
 
#                       rhs = self.coerced_rhs_list[i]
2616
 
#                       rhs.generate_evaluation_code(code)
2617
 
#                       lhs.generate_assignment_code(rhs, code)
2618
 
#                       # Assignment has already disposed of the cloned RHS
2619
 
#               self.rhs.generate_disposal_code(code)
 
1397
    
 
1398
#       def analyse_expressions_1(self, env, use_temp = 0):
 
1399
#               self.rhs.analyse_types(env)
 
1400
#               if use_temp:
 
1401
#                       self.rhs = self.rhs.coerce_to_temp(env)
 
1402
#               else:
 
1403
#                       self.rhs = self.rhs.coerce_to_simple(env)
 
1404
#               self.rhs.allocate_temps(env)
 
1405
#       
 
1406
#       def analyse_expressions_2(self, env):
 
1407
#               from ExprNodes import CloneNode
 
1408
#               self.coerced_rhs_list = []
 
1409
#               for lhs in self.lhs_list:
 
1410
#                       lhs.analyse_target_types(env)
 
1411
#                       rhs = CloneNode(self.rhs)
 
1412
#                       rhs = rhs.coerce_to(lhs.type, env)
 
1413
#                       self.coerced_rhs_list.append(rhs)
 
1414
#                       rhs.allocate_temps(env)
 
1415
#                       lhs.allocate_target_temps(env)
 
1416
#                       lhs.release_target_temp(env)
 
1417
#                       rhs.release_temp(env)
 
1418
#               self.rhs.release_temp(env)
2620
1419
    
2621
1420
    def generate_rhs_evaluation_code(self, code):
2622
1421
        self.rhs.generate_evaluation_code(code)
2650
1449
    
2651
1450
    def analyse_expressions(self, env):
2652
1451
        for stat in self.stats:
2653
 
            stat.analyse_expressions_1(env, use_temp = 1)
 
1452
            stat.analyse_types(env, use_temp = 1)
 
1453
            stat.allocate_rhs_temps(env)
2654
1454
        for stat in self.stats:
2655
 
            stat.analyse_expressions_2(env)
 
1455
            stat.allocate_lhs_temps(env)
 
1456
 
 
1457
#       def analyse_expressions(self, env):
 
1458
#               for stat in self.stats:
 
1459
#                       stat.analyse_expressions_1(env, use_temp = 1)
 
1460
#               for stat in self.stats:
 
1461
#                       stat.analyse_expressions_2(env)
2656
1462
    
2657
1463
    def generate_execution_code(self, code):
2658
1464
        for stat in self.stats:
2703
1509
    
2704
1510
    def analyse_expressions(self, env):
2705
1511
        for arg in self.args:
2706
 
            arg.analyse_target_expression(env)
 
1512
            arg.analyse_target_expression(env, None)
2707
1513
            if not arg.type.is_pyobject:
2708
1514
                error(arg.pos, "Deletion of non-Python object")
2709
 
            #env.recycle_pending_temps() # TEMPORARY
 
1515
            #arg.release_target_temp(env)
2710
1516
    
2711
1517
    def generate_execution_code(self, code):
2712
1518
        for arg in self.args:
2734
1540
        if not code.break_label:
2735
1541
            error(self.pos, "break statement not inside loop")
2736
1542
        else:
2737
 
            code.putln(
2738
 
                "goto %s;" %
2739
 
                    code.break_label)
 
1543
            #code.putln(
 
1544
            #   "goto %s;" %
 
1545
            #           code.break_label)
 
1546
            code.put_goto(code.break_label)
2740
1547
 
2741
1548
 
2742
1549
class ContinueStatNode(StatNode):
2750
1557
        elif not code.continue_label:
2751
1558
            error(self.pos, "continue statement not inside loop")
2752
1559
        else:
2753
 
            code.putln(
2754
 
                "goto %s;" %
2755
 
                    code.continue_label)
 
1560
            #code.putln(
 
1561
            #   "goto %s;" %
 
1562
            #           code.continue_label)
 
1563
            code.put_goto(code.continue_label)
2756
1564
 
2757
1565
 
2758
1566
class ReturnStatNode(StatNode):
2788
1596
        if not self.return_type:
2789
1597
            # error reported earlier
2790
1598
            return
2791
 
        for entry in self.temps_in_use:
2792
 
            code.put_var_decref_clear(entry)
2793
1599
        if self.value:
2794
1600
            self.value.generate_evaluation_code(code)
2795
1601
            self.value.make_owned_reference(code)
2806
1612
                    "%s = %s;" % (
2807
1613
                        Naming.retval_cname,
2808
1614
                        self.return_type.default_value))
2809
 
        code.putln(
2810
 
            "goto %s;" %
2811
 
                code.return_label)
 
1615
        for entry in self.temps_in_use:
 
1616
            code.put_var_decref_clear(entry)
 
1617
        #code.putln(
 
1618
        #       "goto %s;" %
 
1619
        #               code.return_label)
 
1620
        code.put_goto(code.return_label)
2812
1621
 
2813
1622
 
2814
1623
class RaiseStatNode(StatNode):
2970
1779
            "if (%s) {" %
2971
1780
                self.condition.result_code)
2972
1781
        self.body.generate_execution_code(code)
2973
 
        code.putln(
2974
 
            "goto %s;" %
2975
 
                end_label)
 
1782
        #code.putln(
 
1783
        #       "goto %s;" %
 
1784
        #               end_label)
 
1785
        code.put_goto(end_label)
2976
1786
        code.putln("}")
2977
1787
        
2978
1788
    
3001
1811
        old_loop_labels = code.new_loop_labels()
3002
1812
        code.putln(
3003
1813
            "while (1) {")
3004
 
        code.put_label(code.continue_label)
3005
1814
        self.condition.generate_evaluation_code(code)
3006
1815
        code.putln(
3007
1816
            "if (!%s) break;" %
3008
1817
                self.condition.result_code)
3009
1818
        self.body.generate_execution_code(code)
 
1819
        code.put_label(code.continue_label)
3010
1820
        code.putln("}")
3011
1821
        break_label = code.break_label
3012
1822
        code.set_loop_labels(old_loop_labels)
3039
1849
        self.item = ExprNodes.NextNode(self.iterator, env)
3040
1850
        self.item = self.item.coerce_to(self.target.type, env)
3041
1851
        self.item.allocate_temps(env)
3042
 
        self.target.allocate_target_temps(env)
3043
 
        self.item.release_temp(env)
3044
 
        self.target.release_target_temp(env)
3045
 
        #env.recycle_pending_temps() # TEMPORARY
 
1852
        self.target.allocate_target_temps(env, self.item)
 
1853
        #self.item.release_temp(env)
 
1854
        #self.target.release_target_temp(env)
3046
1855
        self.body.analyse_expressions(env)
3047
 
        #env.recycle_pending_temps() # TEMPORARY
3048
1856
        if self.else_clause:
3049
1857
            self.else_clause.analyse_expressions(env)
3050
1858
        self.iterator.release_temp(env)
3054
1862
        self.iterator.generate_evaluation_code(code)
3055
1863
        code.putln(
3056
1864
            "for (;;) {")
3057
 
        code.put_label(code.continue_label)
3058
1865
        self.item.generate_evaluation_code(code)
3059
1866
        self.target.generate_assignment_code(self.item, code)
3060
1867
        self.body.generate_execution_code(code)
 
1868
        code.put_label(code.continue_label)
3061
1869
        code.putln(
3062
1870
            "}")
3063
1871
        break_label = code.break_label
3083
1891
    #
3084
1892
    #  Used internally:
3085
1893
    #
 
1894
    #  is_py_target       bool
3086
1895
    #  loopvar_name       string
3087
1896
    #  py_loopvar_node    PyTempNode or None
3088
1897
    
3102
1911
        if not (self.bound2.is_name or self.bound2.is_literal):
3103
1912
            self.bound2 = self.bound2.coerce_to_temp(env)
3104
1913
        target_type = self.target.type
3105
 
        if not (target_type.is_pyobject
3106
 
            or target_type.assignable_from(PyrexTypes.c_int_type)):
3107
 
                error(self.target.pos,
3108
 
                    "Cannot assign integer to variable of type '%s'" % target_type)
 
1914
        if not (target_type.is_pyobject or target_type.is_int):
 
1915
            error(self.target.pos,
 
1916
                "Integer for-loop variable must be of type int or Python object")
 
1917
        #if not (target_type.is_pyobject
 
1918
        #       or target_type.assignable_from(PyrexTypes.c_int_type)):
 
1919
        #               error(self.target.pos,
 
1920
        #                       "Cannot assign integer to variable of type '%s'" % target_type)
3109
1921
        if target_type.is_int:
 
1922
            self.is_py_target = 0
3110
1923
            self.loopvar_name = self.target.entry.cname
3111
1924
            self.py_loopvar_node = None
3112
1925
        else:
 
1926
            self.is_py_target = 1
3113
1927
            c_loopvar_node = ExprNodes.TempNode(self.pos, 
3114
1928
                PyrexTypes.c_long_type, env)
3115
1929
            c_loopvar_node.allocate_temps(env)
3118
1932
                ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3119
1933
        self.bound1.allocate_temps(env)
3120
1934
        self.bound2.allocate_temps(env)
3121
 
        if self.py_loopvar_node:
 
1935
        if self.is_py_target:
3122
1936
            self.py_loopvar_node.allocate_temps(env)
3123
 
        self.target.allocate_target_temps(env)
3124
 
        self.target.release_target_temp(env)
3125
 
        if self.py_loopvar_node:
3126
 
            self.py_loopvar_node.release_temp(env)
 
1937
            self.target.allocate_target_temps(env, self.py_loopvar_node)
 
1938
            #self.target.release_target_temp(env)
 
1939
            #self.py_loopvar_node.release_temp(env)
3127
1940
        self.body.analyse_expressions(env)
3128
 
        if self.py_loopvar_node:
 
1941
        if self.is_py_target:
3129
1942
            c_loopvar_node.release_temp(env)
3130
1943
        if self.else_clause:
3131
1944
            self.else_clause.analyse_expressions(env)
3132
1945
        self.bound1.release_temp(env)
3133
1946
        self.bound2.release_temp(env)
3134
 
        #env.recycle_pending_temps() # TEMPORARY
3135
1947
            
3136
1948
    def generate_execution_code(self, code):
3137
1949
        old_loop_labels = code.new_loop_labels()
3208
2020
            self.else_clause.generate_execution_code(code)
3209
2021
            code.putln(
3210
2022
                "}")
3211
 
        code.putln(
3212
 
            "goto %s;" %
3213
 
                end_label)
 
2023
        #code.putln(
 
2024
        #       "goto %s;" %
 
2025
        #               end_label)
 
2026
        code.put_goto(end_label)
3214
2027
        code.put_label(our_error_label)
3215
2028
        code.put_var_xdecrefs_clear(self.cleanup_list)
3216
2029
        default_clause_seen = 0
3222
2035
                    error(except_clause.pos, "Default except clause not last")
3223
2036
            except_clause.generate_handling_code(code, end_label)
3224
2037
        if not default_clause_seen:
3225
 
            code.putln(
3226
 
                "goto %s;" %
3227
 
                    code.error_label)
 
2038
            #code.putln(
 
2039
            #   "goto %s;" %
 
2040
            #           code.error_label)
 
2041
            code.put_goto(code.error_label)
3228
2042
        code.put_label(end_label)
3229
2043
 
3230
2044
 
3256
2070
        self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
3257
2071
        self.exc_value.allocate_temps(env)
3258
2072
        if self.target:
3259
 
            self.target.analyse_target_expression(env)
3260
 
        self.exc_value.release_temp(env)
3261
 
        if self.target:
3262
 
            self.target.release_target_temp(env)
3263
 
        #env.recycle_pending_temps() # TEMPORARY
 
2073
            self.target.analyse_target_expression(env, self.exc_value)
 
2074
        else:
 
2075
            self.exc_value.release_temp(env)
 
2076
        #if self.target:
 
2077
        #       self.target.release_target_temp(env)
3264
2078
        self.body.analyse_expressions(env)
3265
2079
    
3266
2080
    def generate_handling_code(self, code, end_label):
3289
2103
        else:
3290
2104
            self.exc_value.generate_disposal_code(code)
3291
2105
        self.body.generate_execution_code(code)
3292
 
        code.putln(
3293
 
            "goto %s;"
3294
 
                % end_label)
 
2106
        #code.putln(
 
2107
        #       "goto %s;"
 
2108
        #               % end_label)
 
2109
        code.put_goto(end_label)
3295
2110
        code.putln(
3296
2111
            "}")
3297
2112
 
3361
2176
        #code.putln(
3362
2177
        #               "int %s;" %
3363
2178
        #                       self.lineno_var)
 
2179
        code.use_label(catch_label)
3364
2180
        code.putln(
3365
2181
                "__pyx_why = 0; goto %s;" %
3366
2182
                    catch_label)
3367
2183
        for i in range(len(new_labels)):
3368
 
            if new_labels[i] and new_labels[i] <> "<try>":
3369
 
                if new_labels[i] == new_error_label:
3370
 
                    self.put_error_catcher(code, 
3371
 
                        new_error_label, i+1, catch_label)
3372
 
                else:
3373
 
                    code.putln(
3374
 
                        "%s: __pyx_why = %s; goto %s;" % (
3375
 
                            new_labels[i],
3376
 
                            i+1,
3377
 
                            catch_label))
 
2184
            new_label = new_labels[i]
 
2185
            if new_label and new_label <> "<try>":
 
2186
                if new_label in code.labels_used:
 
2187
                    if new_label == new_error_label:
 
2188
                        self.put_error_catcher(code, 
 
2189
                            new_error_label, i+1, catch_label)
 
2190
                    else:
 
2191
                            code.putln(
 
2192
                                "%s: __pyx_why = %s; goto %s;" % (
 
2193
                                    new_label,
 
2194
                                    i+1,
 
2195
                                    catch_label))
3378
2196
        code.put_label(catch_label)
3379
2197
        code.set_all_labels(old_labels)
3380
2198
        self.finally_clause.generate_execution_code(code)
3385
2203
                if old_labels[i] == old_error_label:
3386
2204
                    self.put_error_uncatcher(code, i+1, old_error_label)
3387
2205
                else:
 
2206
                    code.use_label(old_labels[i])
3388
2207
                    code.putln(
3389
2208
                        "case %s: goto %s;" % (
3390
2209
                            i+1,
3408
2227
        code.putln(
3409
2228
                "%s = %s;" % (
3410
2229
                    self.lineno_var, Naming.lineno_cname))
3411
 
        code.putln(
3412
 
                "goto %s;" %
3413
 
                    catch_label)
 
2230
        #code.putln(
 
2231
        #               "goto %s;" %
 
2232
        #                       catch_label)
 
2233
        code.put_goto(catch_label)
3414
2234
        code.putln(
3415
2235
            "}")
3416
2236
            
3428
2248
            code.putln(
3429
2249
                "%s = 0;" %
3430
2250
                    var)
3431
 
        code.putln(
3432
 
                "goto %s;" %
3433
 
                    error_label)
 
2251
        #code.putln(
 
2252
        #               "goto %s;" %
 
2253
        #                       error_label)
 
2254
        code.put_goto(error_label)
3434
2255
        code.putln(
3435
2256
            "}")
3436
2257
 
3510
2331
        for name, target in self.items:
3511
2332
            if Options.intern_names:
3512
2333
                self.interned_items.append((env.intern(name), target))
3513
 
            target.analyse_target_expression(env)
3514
 
            target.release_temp(env)
 
2334
            target.analyse_target_expression(env, None)
 
2335
            #target.release_target_temp(env) # was release_temp ?!?
3515
2336
        self.module.release_temp(env)
3516
2337
        self.item.release_temp(env)
3517
 
        #env.recycle_pending_temps() # TEMPORARY
3518
2338
    
3519
2339
    def generate_execution_code(self, code):
3520
2340
        self.module.generate_evaluation_code(code)
3550
2370
"""
3551
2371
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
3552
2372
typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
3553
 
static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t); /*proto*/
3554
 
static int __Pyx_EndUnpack(PyObject *, Py_ssize_t); /*proto*/
 
2373
"""
 
2374
 
 
2375
#get_name_predeclaration = \
 
2376
#"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
 
2377
 
 
2378
#get_name_interned_predeclaration = \
 
2379
#"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
 
2380
 
 
2381
#------------------------------------------------------------------------------------
 
2382
 
 
2383
printing_utility_code = [
 
2384
"""
3555
2385
static int __Pyx_PrintItem(PyObject *); /*proto*/
3556
2386
static int __Pyx_PrintNewline(void); /*proto*/
3557
 
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
3558
 
static void __Pyx_ReRaise(void); /*proto*/
3559
 
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
3560
 
static PyObject *__Pyx_GetExcValue(void); /*proto*/
3561
 
static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
3562
 
static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
3563
 
static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,\
3564
 
 char *kwd_list[], Py_ssize_t nargs, PyObject **args2, PyObject **kwds2); /*proto*/
3565
 
static void __Pyx_WriteUnraisable(char *name); /*proto*/
3566
 
static void __Pyx_AddTraceback(char *funcname); /*proto*/
3567
 
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
3568
 
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
3569
 
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
3570
 
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
3571
 
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
3572
 
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
3573
 
"""
3574
 
 
3575
 
get_name_predeclaration = \
3576
 
"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
3577
 
 
3578
 
get_name_interned_predeclaration = \
3579
 
"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
3580
 
 
3581
 
#------------------------------------------------------------------------------------
3582
 
 
3583
 
printing_utility_code = \
3584
 
r"""
 
2387
""",r"""
3585
2388
static PyObject *__Pyx_GetStdout(void) {
3586
2389
    PyObject *f = PySys_GetObject("stdout");
3587
2390
    if (!f) {
3603
2406
        return -1;
3604
2407
    if (PyString_Check(v)) {
3605
2408
        char *s = PyString_AsString(v);
3606
 
        Py_ssize_t len = PyString_Size(v);
 
2409
        int len = PyString_Size(v);
3607
2410
        if (len > 0 &&
3608
2411
            isspace(Py_CHARMASK(s[len-1])) &&
3609
2412
            s[len-1] != ' ')
3622
2425
    PyFile_SoftSpace(f, 0);
3623
2426
    return 0;
3624
2427
}
3625
 
"""
 
2428
"""]
3626
2429
 
3627
2430
#------------------------------------------------------------------------------------
3628
2431
 
3629
2432
# The following function is based on do_raise() from ceval.c.
3630
2433
 
3631
 
raise_utility_code = \
 
2434
raise_utility_code = [
3632
2435
"""
 
2436
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
 
2437
""","""
3633
2438
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
3634
2439
    Py_XINCREF(type);
3635
2440
    Py_XINCREF(value);
3656
2461
        Py_INCREF(type);
3657
2462
        Py_DECREF(tmp);
3658
2463
    }
3659
 
    if (PyString_Check(type))
3660
 
        ;
 
2464
    if (PyString_Check(type)) {
 
2465
        if (PyErr_Warn(PyExc_DeprecationWarning,
 
2466
                "raising a string exception is deprecated"))
 
2467
            goto raise_error;
 
2468
    }
3661
2469
    else if (PyType_Check(type) || PyClass_Check(type))
3662
2470
        ; /*PyErr_NormalizeException(&type, &value, &tb);*/
3663
 
    else if (PyInstance_Check(type)) {
 
2471
    else {
3664
2472
        /* Raising an instance.  The value should be a dummy. */
3665
2473
        if (value != Py_None) {
3666
2474
            PyErr_SetString(PyExc_TypeError,
3667
 
              "instance exception may not have a separate value");
 
2475
                "instance exception may not have a separate value");
3668
2476
            goto raise_error;
3669
2477
        }
3670
 
        else {
3671
 
            /* Normalize to raise <class>, <instance> */
3672
 
            Py_DECREF(value);
3673
 
            value = type;
 
2478
        /* Normalize to raise <class>, <instance> */
 
2479
        Py_DECREF(value);
 
2480
        value = type;
 
2481
        if (PyInstance_Check(type))
3674
2482
            type = (PyObject*) ((PyInstanceObject*)type)->in_class;
3675
 
            Py_INCREF(type);
3676
 
        }
3677
 
    }
3678
 
    else {
3679
 
        /* Not something you can raise.  You get an exception
3680
 
           anyway, just not what you specified :-) */
3681
 
        PyErr_Format(PyExc_TypeError,
3682
 
                 "exceptions must be strings, classes, or "
3683
 
                 "instances, not %s", type->ob_type->tp_name);
3684
 
        goto raise_error;
 
2483
        else
 
2484
            type = (PyObject*) type->ob_type;
 
2485
        Py_INCREF(type);
3685
2486
    }
3686
2487
    PyErr_Restore(type, value, tb);
3687
2488
    return;
3691
2492
    Py_XDECREF(tb);
3692
2493
    return;
3693
2494
}
3694
 
"""
 
2495
"""]
3695
2496
 
3696
2497
#------------------------------------------------------------------------------------
3697
2498
 
3698
 
reraise_utility_code = \
 
2499
reraise_utility_code = [
3699
2500
"""
 
2501
static void __Pyx_ReRaise(void); /*proto*/
 
2502
""","""
3700
2503
static void __Pyx_ReRaise(void) {
3701
2504
    PyThreadState *tstate = PyThreadState_Get();
3702
2505
    PyObject *type = tstate->exc_type;
3707
2510
    Py_XINCREF(tb);
3708
2511
    PyErr_Restore(type, value, tb);
3709
2512
}
3710
 
"""
 
2513
"""]
3711
2514
 
3712
2515
#------------------------------------------------------------------------------------
3713
2516
 
3714
 
arg_type_test_utility_code = \
 
2517
arg_type_test_utility_code = [
3715
2518
"""
 
2519
static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
 
2520
""","""
3716
2521
static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
3717
2522
    if (!type) {
3718
2523
        PyErr_Format(PyExc_SystemError, "Missing type object");
3725
2530
        name, type->tp_name, obj->ob_type->tp_name);
3726
2531
    return 0;
3727
2532
}
3728
 
"""
 
2533
"""]
3729
2534
 
3730
2535
#------------------------------------------------------------------------------------
3731
2536
#
3741
2546
#  reference to the same dictionary is passed back in *kwds.
3742
2547
#
3743
2548
 
3744
 
get_starargs_utility_code = \
 
2549
get_starargs_utility_code = [
3745
2550
"""
 
2551
static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,\
 
2552
 char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
 
2553
""","""
3746
2554
static int __Pyx_GetStarArgs(
3747
2555
    PyObject **args, 
3748
2556
    PyObject **kwds,
3749
2557
    char *kwd_list[], 
3750
 
    Py_ssize_t nargs,
 
2558
    int nargs,
3751
2559
    PyObject **args2, 
3752
2560
    PyObject **kwds2)
3753
2561
{
3807
2615
bad:
3808
2616
    Py_XDECREF(args1);
3809
2617
    Py_XDECREF(kwds1);
3810
 
    Py_XDECREF(*args2);
3811
 
    Py_XDECREF(*kwds2);
 
2618
    if (*args2) {
 
2619
        Py_XDECREF(*args2);
 
2620
    }
 
2621
    if (*kwds2) {
 
2622
        Py_XDECREF(*kwds2);
 
2623
    }
3812
2624
    return -1;
3813
2625
}
3814
 
"""
 
2626
"""]
3815
2627
 
3816
2628
#------------------------------------------------------------------------------------
3817
2629
 
3818
 
unraisable_exception_utility_code = \
 
2630
unraisable_exception_utility_code = [
3819
2631
"""
 
2632
static void __Pyx_WriteUnraisable(char *name); /*proto*/
 
2633
""","""
3820
2634
static void __Pyx_WriteUnraisable(char *name) {
3821
2635
    PyObject *old_exc, *old_val, *old_tb;
3822
2636
    PyObject *ctx;
3827
2641
        ctx = Py_None;
3828
2642
    PyErr_WriteUnraisable(ctx);
3829
2643
}
3830
 
"""
 
2644
"""]
3831
2645
 
3832
2646
#------------------------------------------------------------------------------------
3833
2647
 
3834
 
traceback_utility_code = \
 
2648
traceback_utility_code = [
3835
2649
"""
 
2650
static void __Pyx_AddTraceback(char *funcname); /*proto*/
 
2651
""","""
3836
2652
#include "compile.h"
3837
2653
#include "frameobject.h"
3838
2654
#include "traceback.h"
3894
2710
    'FILENAME': Naming.filename_cname,
3895
2711
    'LINENO':  Naming.lineno_cname,
3896
2712
    'GLOBALS': Naming.module_cname
3897
 
}
 
2713
}]
3898
2714
 
3899
2715
#------------------------------------------------------------------------------------
3900
2716
 
3901
 
type_import_utility_code = \
 
2717
type_import_utility_code = [
3902
2718
"""
 
2719
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
 
2720
""","""
3903
2721
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, 
3904
2722
    long size) 
3905
2723
{
3949
2767
    Py_XDECREF(py_name_list);
3950
2768
    return (PyTypeObject *)result;
3951
2769
}
3952
 
"""
 
2770
"""]
3953
2771
 
3954
2772
#------------------------------------------------------------------------------------
3955
2773
 
3956
 
set_vtable_utility_code = \
 
2774
set_vtable_utility_code = [
3957
2775
"""
 
2776
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
 
2777
""","""
3958
2778
static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
3959
2779
    PyObject *pycobj = 0;
3960
2780
    int result;
3973
2793
    Py_XDECREF(pycobj);
3974
2794
    return result;
3975
2795
}
 
2796
"""]
 
2797
 
 
2798
#------------------------------------------------------------------------------------
 
2799
 
 
2800
get_vtable_utility_code = [
3976
2801
"""
3977
 
 
3978
 
#------------------------------------------------------------------------------------
3979
 
 
3980
 
get_vtable_utility_code = \
3981
 
r"""
 
2802
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
 
2803
""",r"""
3982
2804
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
3983
2805
    int result;
3984
2806
    PyObject *pycobj;
3998
2820
    Py_XDECREF(pycobj);
3999
2821
    return result;
4000
2822
}
4001
 
"""
 
2823
"""]
4002
2824
 
4003
2825
#------------------------------------------------------------------------------------
4004
2826
 
4005
 
init_intern_tab_utility_code = \
 
2827
init_intern_tab_utility_code = [
4006
2828
"""
 
2829
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
 
2830
""","""
4007
2831
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
4008
2832
    while (t->p) {
4009
2833
        *t->p = PyString_InternFromString(t->s);
4013
2837
    }
4014
2838
    return 0;
4015
2839
}
4016
 
""";
 
2840
"""]
4017
2841
 
4018
2842
#------------------------------------------------------------------------------------
4019
2843
 
4020
 
init_string_tab_utility_code = \
 
2844
init_string_tab_utility_code = [
4021
2845
"""
 
2846
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
 
2847
""","""
4022
2848
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
4023
2849
    while (t->p) {
4024
2850
        *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
4028
2854
    }
4029
2855
    return 0;
4030
2856
}
4031
 
""";
 
2857
"""]
4032
2858
 
4033
2859
#------------------------------------------------------------------------------------