Cython has moved to github.
pyrex
view Pyrex/Compiler/Nodes.py @ 86:da6e97bb7e6d
Multiple compilation fixed
| author | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| date | Sat May 24 15:50:12 2008 +1200 (4 years ago) |
| parents | 12072e0e4fd5 |
| children | 152fab7779d2 |
line source
1 #
2 # Pyrex - Parse tree nodes
3 #
5 import string, sys
7 import Code
8 from Errors import error, InternalError
9 import Naming
10 import PyrexTypes
11 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
12 from Symtab import ModuleScope, LocalScope, \
13 StructOrUnionScope, PyClassScope, CClassScope
14 from Pyrex.Utils import open_new_file, replace_suffix
15 import Options
17 from DebugFlags import debug_disposal_code
19 class Node:
20 # pos (string, int, int) Source file position
21 # is_name boolean Is a NameNode
22 # is_literal boolean Is a ConstNode
24 is_name = 0
25 is_literal = 0
27 def __init__(self, pos, **kw):
28 self.pos = pos
29 self.__dict__.update(kw)
31 gil_message = "Operation"
33 def gil_check(self, env):
34 if env.nogil:
35 self.gil_error()
37 def gil_error(self):
38 error(self.pos, "%s not allowed without gil" % self.gil_message)
40 #
41 # There are 3 phases of parse tree processing, applied in order to
42 # all the statements in a given scope-block:
43 #
44 # (1) analyse_declarations
45 # Make symbol table entries for all declarations at the current
46 # level, both explicit (def, cdef, etc.) and implicit (assignment
47 # to an otherwise undeclared name).
48 #
49 # (2) analyse_expressions
50 # Determine the result types of expressions and fill in the
51 # 'type' attribute of each ExprNode. Insert coercion nodes into the
52 # tree where needed to convert to and from Python objects.
53 # Allocate temporary locals for intermediate results.
54 #
55 # (3) generate_code
56 # Emit C code for all declarations, statements and expressions.
57 # Recursively applies the 3 processing phases to the bodies of
58 # functions.
59 #
61 def analyse_declarations(self, env):
62 pass
64 def analyse_expressions(self, env):
65 raise InternalError("analyse_expressions not implemented for %s" % \
66 self.__class__.__name__)
68 def generate_code(self, code):
69 raise InternalError("generate_code not implemented for %s" % \
70 self.__class__.__name__)
73 class BlockNode:
74 # Mixin class for nodes representing a declaration block.
75 pass
77 # def generate_const_definitions(self, env, code):
78 # if env.const_entries:
79 # code.putln("")
80 # for entry in env.const_entries:
81 # if not entry.is_interned:
82 # code.put_var_declaration(entry, static = 1)
84 # def generate_interned_name_decls(self, env, code):
85 # # Flush accumulated interned names from the global scope
86 # # and generate declarations for them.
87 # genv = env.global_scope()
88 # intern_map = genv.intern_map
89 # names = genv.interned_names
90 # if names:
91 # code.putln("")
92 # for name in names:
93 # code.putln(
94 # "static PyObject *%s;" % intern_map[name])
95 # del names[:]
97 # def generate_py_string_decls(self, env, code):
98 # entries = env.pystring_entries
99 # if entries:
100 # code.putln("")
101 # for entry in entries:
102 # code.putln(
103 # "static PyObject *%s;" % entry.pystring_cname)
106 class StatListNode(Node):
107 # stats a list of StatNode
109 def analyse_declarations(self, env):
110 #print "StatListNode.analyse_declarations" ###
111 for stat in self.stats:
112 stat.analyse_declarations(env)
114 def analyse_expressions(self, env):
115 #print "StatListNode.analyse_expressions" ###
116 for stat in self.stats:
117 stat.analyse_expressions(env)
119 def generate_function_definitions(self, env, code):
120 #print "StatListNode.generate_function_definitions" ###
121 for stat in self.stats:
122 stat.generate_function_definitions(env, code)
124 def generate_execution_code(self, code):
125 #print "StatListNode.generate_execution_code" ###
126 for stat in self.stats:
127 code.mark_pos(stat.pos)
128 stat.generate_execution_code(code)
131 class StatNode(Node):
132 #
133 # Code generation for statements is split into the following subphases:
134 #
135 # (1) generate_function_definitions
136 # Emit C code for the definitions of any structs,
137 # unions, enums and functions defined in the current
138 # scope-block.
139 #
140 # (2) generate_execution_code
141 # Emit C code for executable statements.
142 #
144 def generate_function_definitions(self, env, code):
145 pass
147 def generate_execution_code(self, code):
148 raise InternalError("generate_execution_code not implemented for %s" % \
149 self.__class__.__name__)
152 class CDefExternNode(StatNode):
153 # include_file string or None
154 # body StatNode
156 def analyse_declarations(self, env):
157 if self.include_file:
158 env.add_include_file(self.include_file)
159 old_cinclude_flag = env.in_cinclude
160 env.in_cinclude = 1
161 self.body.analyse_declarations(env)
162 env.in_cinclude = old_cinclude_flag
164 def analyse_expressions(self, env):
165 pass
167 def generate_execution_code(self, code):
168 pass
171 class CDeclaratorNode(Node):
172 # Part of a C declaration.
173 #
174 # Processing during analyse_declarations phase:
175 #
176 # analyse
177 # Returns (name, type) pair where name is the
178 # CNameDeclaratorNode of the name being declared
179 # and type is the type it is being declared as.
180 #
181 # calling_convention string Calling convention of CFuncDeclaratorNode
182 # for which this is a base
184 calling_convention = ""
187 class CNameDeclaratorNode(CDeclaratorNode):
188 # name string The Pyrex name being declared
189 # cname string or None C name, if specified
191 def analyse(self, base_type, env):
192 return self, base_type
195 class CPtrDeclaratorNode(CDeclaratorNode):
196 # base CDeclaratorNode
198 def analyse(self, base_type, env):
199 if base_type.is_pyobject:
200 error(self.pos,
201 "Pointer base type cannot be a Python object")
202 ptr_type = PyrexTypes.c_ptr_type(base_type)
203 return self.base.analyse(ptr_type, env)
206 class CArrayDeclaratorNode(CDeclaratorNode):
207 # base CDeclaratorNode
208 # dimension ExprNode
210 def analyse(self, base_type, env):
211 if self.dimension:
212 self.dimension.analyse_const_expression(env)
213 if not self.dimension.type.is_int:
214 error(self.dimension.pos, "Array dimension not integer")
215 size = self.dimension.result()
216 else:
217 size = None
218 if not base_type.is_complete():
219 error(self.pos,
220 "Array element type '%s' is incomplete" % base_type)
221 if base_type.is_pyobject:
222 error(self.pos,
223 "Array element cannot be a Python object")
224 if base_type.is_cfunction:
225 error(self.pos,
226 "Array element cannot be a function")
227 array_type = PyrexTypes.c_array_type(base_type, size)
228 return self.base.analyse(array_type, env)
231 class CFuncDeclaratorNode(CDeclaratorNode):
232 # base CDeclaratorNode
233 # args [CArgDeclNode]
234 # has_varargs boolean
235 # exception_value ConstNode
236 # exception_check boolean True if PyErr_Occurred check needed
237 # nogil boolean Can be called without gil
238 # with_gil boolean Acquire gil around function body
240 def analyse(self, return_type, env):
241 func_type_args = []
242 for arg_node in self.args:
243 name_declarator, type = arg_node.analyse(env)
244 name = name_declarator.name
245 if name_declarator.cname:
246 error(self.pos,
247 "Function argument cannot have C name specification")
248 # Turn *[] argument into **
249 if type.is_array:
250 type = PyrexTypes.c_ptr_type(type.base_type)
251 # Catch attempted C-style func(void) decl
252 if type.is_void:
253 error(arg_node.pos, "Function argument cannot be void")
254 func_type_args.append(
255 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
256 if arg_node.default:
257 error(arg_node.pos, "C function argument cannot have default value")
258 exc_val = None
259 exc_check = 0
260 if return_type.is_pyobject \
261 and (self.exception_value or self.exception_check):
262 error(self.pos,
263 "Exception clause not allowed for function returning Python object")
264 else:
265 if self.exception_value:
266 self.exception_value.analyse_const_expression(env)
267 exc_val = self.exception_value.result()
268 if not return_type.assignable_from(self.exception_value.type):
269 error(self.exception_value.pos,
270 "Exception value incompatible with function return type")
271 exc_check = self.exception_check
272 if return_type.is_array:
273 error(self.pos,
274 "Function cannot return an array")
275 if return_type.is_cfunction:
276 error(self.pos,
277 "Function cannot return a function")
278 func_type = PyrexTypes.CFuncType(
279 return_type, func_type_args, self.has_varargs,
280 exception_value = exc_val, exception_check = exc_check,
281 calling_convention = self.base.calling_convention,
282 nogil = self.nogil, with_gil = self.with_gil)
283 return self.base.analyse(func_type, env)
286 class CArgDeclNode(Node):
287 # Item in a function declaration argument list.
288 #
289 # base_type CBaseTypeNode
290 # declarator CDeclaratorNode
291 # not_none boolean Tagged with 'not None'
292 # default ExprNode or None
293 # default_entry Symtab.Entry Entry for the variable holding the default value
294 # is_self_arg boolean Is the "self" arg of an extension type method
295 # is_kw_only boolean Is a keyword-only argument
297 is_self_arg = 0
299 def analyse(self, env):
300 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
301 base_type = self.base_type.analyse(env)
302 return self.declarator.analyse(base_type, env)
305 class CBaseTypeNode(Node):
306 # Abstract base class for C base type nodes.
307 #
308 # Processing during analyse_declarations phase:
309 #
310 # analyse
311 # Returns the type.
313 pass
316 class CSimpleBaseTypeNode(CBaseTypeNode):
317 # name string
318 # module_path [string] Qualifying name components
319 # is_basic_c_type boolean
320 # signed boolean
321 # longness integer
322 # is_self_arg boolean Is self argument of C method
324 def analyse(self, env):
325 # Return type descriptor.
326 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
327 type = None
328 if self.is_basic_c_type:
329 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
330 if not type:
331 error(self.pos, "Unrecognised type modifier combination")
332 elif self.name == "object" and not self.module_path:
333 type = py_object_type
334 elif self.name is None:
335 if self.is_self_arg and env.is_c_class_scope:
336 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
337 type = env.parent_type
338 else:
339 type = py_object_type
340 else:
341 scope = env.find_imported_module(self.module_path, self.pos)
342 if scope:
343 entry = scope.find(self.name, self.pos)
344 if entry and entry.is_type:
345 type = entry.type
346 else:
347 error(self.pos, "'%s' is not a type identifier" % self.name)
348 if type:
349 return type
350 else:
351 return PyrexTypes.error_type
354 class CComplexBaseTypeNode(CBaseTypeNode):
355 # base_type CBaseTypeNode
356 # declarator CDeclaratorNode
358 def analyse(self, env):
359 base = self.base_type.analyse(env)
360 _, type = self.declarator.analyse(base, env)
361 return type
364 class CVarDefNode(StatNode):
365 # C variable definition or forward/extern function declaration.
366 #
367 # visibility 'private' or 'public' or 'extern'
368 # base_type CBaseTypeNode
369 # declarators [CDeclaratorNode]
370 # in_pxd boolean
371 # api boolean
373 def analyse_declarations(self, env, dest_scope = None):
374 if not dest_scope:
375 dest_scope = env
376 base_type = self.base_type.analyse(env)
377 for declarator in self.declarators:
378 name_declarator, type = declarator.analyse(base_type, env)
379 if not type.is_complete():
380 if not (self.visibility == 'extern' and type.is_array):
381 error(declarator.pos,
382 "Variable type '%s' is incomplete" % type)
383 if self.visibility == 'extern' and type.is_pyobject:
384 error(declarator.pos,
385 "Python object cannot be declared extern")
386 name = name_declarator.name
387 cname = name_declarator.cname
388 if type.is_cfunction:
389 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
390 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
391 api = self.api)
392 else:
393 if self.in_pxd and self.visibility <> 'extern':
394 error(self.pos,
395 "Only 'extern' C variable declaration allowed in .pxd file")
396 dest_scope.declare_var(name, type, declarator.pos,
397 cname = cname, visibility = self.visibility, is_cdef = 1)
399 def analyse_expressions(self, env):
400 pass
402 def generate_execution_code(self, code):
403 pass
406 class CStructOrUnionDefNode(StatNode):
407 # name string
408 # cname string or None
409 # module_path [string]
410 # kind "struct" or "union"
411 # typedef_flag boolean
412 # visibility "public" or "private"
413 # in_pxd boolean
414 # attributes [CVarDefNode] or None
415 # entry Entry
417 def analyse_declarations(self, env):
418 scope = None
419 if self.attributes is not None:
420 scope = StructOrUnionScope()
421 if self.module_path:
422 home_scope = env.find_imported_module(self.module_path, self.pos)
423 if not home_scope:
424 return
425 else:
426 home_scope = env
427 self.entry = home_scope.declare_struct_or_union(
428 self.name, self.kind, scope, self.typedef_flag, self.pos,
429 self.cname, visibility = self.visibility)
430 if self.attributes is not None:
431 if self.in_pxd and not env.in_cinclude:
432 self.entry.defined_in_pxd = 1
433 for attr in self.attributes:
434 attr.analyse_declarations(env, scope)
436 def analyse_expressions(self, env):
437 pass
439 def generate_execution_code(self, code):
440 pass
443 class CEnumDefNode(StatNode):
444 # name string or None
445 # cname string or None
446 # items [CEnumDefItemNode]
447 # typedef_flag boolean
448 # visibility "public" or "private"
449 # in_pxd boolean
450 # entry Entry
452 def analyse_declarations(self, env):
453 self.entry = env.declare_enum(self.name, self.pos,
454 cname = self.cname, typedef_flag = self.typedef_flag,
455 visibility = self.visibility)
456 if self.items is not None:
457 if self.in_pxd and not env.in_cinclude:
458 self.entry.defined_in_pxd = 1
459 for item in self.items:
460 item.analyse_declarations(env, self.entry)
462 def analyse_expressions(self, env):
463 pass
465 def generate_execution_code(self, code):
466 pass
469 class CEnumDefItemNode(StatNode):
470 # name string
471 # cname string or None
472 # value ExprNode or None
474 def analyse_declarations(self, env, enum_entry):
475 value_node = self.value
476 if value_node:
477 value_node.analyse_const_expression(env)
478 type = value_node.type
479 if type.is_int or type.is_enum:
480 value = value_node.result()
481 else:
482 error(self.pos,
483 "Type '%s' is not a valid enum value" % type)
484 value = "<error>"
485 else:
486 value = self.name
487 entry = env.declare_const(self.name, enum_entry.type,
488 value, self.pos, cname = self.cname)
489 enum_entry.enum_values.append(entry)
492 class CTypeDefNode(StatNode):
493 # base_type CBaseTypeNode
494 # declarator CDeclaratorNode
495 # visibility "public" or "private"
496 # in_pxd boolean
498 def analyse_declarations(self, env):
499 base = self.base_type.analyse(env)
500 name_declarator, type = self.declarator.analyse(base, env)
501 name = name_declarator.name
502 cname = name_declarator.cname
503 entry = env.declare_typedef(name, type, self.pos,
504 cname = cname, visibility = self.visibility)
505 if self.in_pxd and not env.in_cinclude:
506 entry.defined_in_pxd = 1
508 def analyse_expressions(self, env):
509 pass
511 def generate_execution_code(self, code):
512 pass
515 class FuncDefNode(StatNode, BlockNode):
516 # Base class for function definition nodes.
517 #
518 # return_type PyrexType
519 # #filename string C name of filename string const
520 # entry Symtab.Entry
522 def analyse_expressions(self, env):
523 pass
525 def need_gil_acquisition(self, lenv):
526 return 0
528 def generate_function_definitions(self, env, code):
529 # Generate C code for header and body of function
530 genv = env.global_scope()
531 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
532 lenv.return_type = self.return_type
533 type = self.entry.type
534 if type.is_cfunction:
535 lenv.nogil = type.nogil and not type.with_gil
536 code.init_labels()
537 self.declare_arguments(lenv)
538 self.body.analyse_declarations(lenv)
539 self.body.analyse_expressions(lenv)
540 # Code for nested function definitions would go here
541 # if we supported them, which we probably won't.
542 # ----- Top-level constants used by this function
543 #self.generate_interned_name_decls(lenv, code)
544 #self.generate_py_string_decls(lenv, code)
545 #self.generate_const_definitions(lenv, code)
546 # ----- Function header
547 code.putln("")
548 self.generate_function_header(code,
549 with_pymethdef = env.is_py_class_scope)
550 # ----- Local variable declarations
551 self.generate_argument_declarations(lenv, code)
552 code.put_var_declarations(lenv.var_entries)
553 init = ""
554 if not self.return_type.is_void:
555 code.putln(
556 "%s%s;" %
557 (self.return_type.declaration_code(
558 Naming.retval_cname),
559 init))
560 code.put_var_declarations(lenv.temp_entries)
561 self.generate_keyword_list(code)
562 # ----- Extern library function declarations
563 lenv.generate_library_function_declarations(code)
564 # ----- GIL acquisition
565 acquire_gil = self.need_gil_acquisition(lenv)
566 if acquire_gil:
567 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
568 # ----- Fetch arguments
569 self.generate_argument_parsing_code(code)
570 self.generate_argument_increfs(lenv, code)
571 # ----- Initialise local variables
572 for entry in lenv.var_entries:
573 if entry.type.is_pyobject and entry.init_to_none and entry.used:
574 code.put_init_var_to_py_none(entry)
575 # ----- Check and convert arguments
576 self.generate_argument_conversion_code(code)
577 self.generate_argument_type_tests(code)
578 # ----- Function body
579 self.body.generate_execution_code(code)
580 # ----- Default return value
581 code.putln("")
582 if self.return_type.is_pyobject:
583 #if self.return_type.is_extension_type:
584 # lhs = "(PyObject *)%s" % Naming.retval_cname
585 #else:
586 lhs = Naming.retval_cname
587 code.put_init_to_py_none(lhs, self.return_type)
588 else:
589 val = self.return_type.default_value
590 if val:
591 code.putln("%s = %s;" % (Naming.retval_cname, val))
592 #code.putln("goto %s;" % code.return_label)
593 # ----- Error cleanup
594 if code.error_label in code.labels_used:
595 code.put_goto(code.return_label)
596 code.put_label(code.error_label)
597 code.put_var_xdecrefs(lenv.temp_entries)
598 err_val = self.error_value()
599 exc_check = self.caller_will_check_exceptions()
600 if err_val is not None or exc_check:
601 code.putln(
602 '__Pyx_AddTraceback("%s");' %
603 self.entry.qualified_name)
604 if err_val is not None:
605 code.putln(
606 "%s = %s;" % (
607 Naming.retval_cname,
608 err_val))
609 else:
610 code.use_utility_code(unraisable_exception_utility_code)
611 code.putln(
612 '__Pyx_WriteUnraisable("%s");' %
613 self.entry.qualified_name)
614 #if not self.return_type.is_void:
615 default_retval = self.return_type.default_value
616 if default_retval:
617 code.putln(
618 "%s = %s;" % (
619 Naming.retval_cname,
620 default_retval))
621 #self.return_type.default_value))
622 # ----- Return cleanup
623 code.put_label(code.return_label)
624 code.put_var_decrefs(lenv.var_entries, used_only = 1)
625 #code.put_var_decrefs(lenv.arg_entries)
626 self.generate_argument_decrefs(lenv, code)
627 self.put_stararg_decrefs(code)
628 if acquire_gil:
629 code.putln("PyGILState_Release(_save);")
630 if not self.return_type.is_void:
631 code.putln("return %s;" % Naming.retval_cname)
632 code.putln("}")
634 def put_stararg_decrefs(self, code):
635 pass
637 def declare_argument(self, env, arg, readonly = 0):
638 if arg.type.is_void:
639 error(arg.pos, "Invalid use of 'void'")
640 elif not arg.type.is_complete() and not arg.type.is_array:
641 error(arg.pos,
642 "Argument type '%s' is incomplete" % arg.type)
643 return env.declare_arg(arg.name, arg.type, arg.pos,
644 readonly = readonly)
646 def generate_argument_increfs(self, env, code):
647 # Turn writable borrowed argument refs into owned refs.
648 # This is necessary, because if the argument is assigned to,
649 # it will be decrefed.
650 for entry in env.arg_entries:
651 if not entry.is_readonly:
652 code.put_var_incref(entry)
654 def generate_argument_decrefs(self, env, code):
655 for entry in env.arg_entries:
656 if not entry.is_readonly:
657 code.put_var_decref(entry)
659 def generate_execution_code(self, code):
660 pass
663 class CFuncDefNode(FuncDefNode):
664 # C function definition.
665 #
666 # visibility 'private' or 'public' or 'extern'
667 # base_type CBaseTypeNode
668 # declarator CDeclaratorNode
669 # body StatListNode
670 # api boolean
671 #
672 # with_gil boolean Acquire GIL around body
673 # type CFuncType
675 def unqualified_name(self):
676 return self.entry.name
678 def analyse_declarations(self, env):
679 base_type = self.base_type.analyse(env)
680 name_declarator, type = self.declarator.analyse(base_type, env)
681 if not type.is_cfunction:
682 error(self.pos,
683 "Suite attached to non-function declaration")
684 # Remember the actual type according to the function header
685 # written here, because the type in the symbol table entry
686 # may be different if we're overriding a C method inherited
687 # from the base type of an extension type.
688 self.type = type
689 name = name_declarator.name
690 cname = name_declarator.cname
691 self.entry = env.declare_cfunction(
692 name, type, self.pos,
693 cname = cname, visibility = self.visibility,
694 defining = self.body is not None,
695 api = self.api)
696 self.return_type = type.return_type
698 def declare_arguments(self, env):
699 type = self.type
700 without_gil = type.nogil and not type.with_gil
701 for arg in type.args:
702 if not arg.name:
703 error(arg.pos, "Missing argument name")
704 self.declare_argument(env, arg,
705 readonly = without_gil and arg.type.is_pyobject)
707 def need_gil_acquisition(self, lenv):
708 type = self.type
709 with_gil = type.with_gil
710 if type.nogil and not with_gil:
711 # for arg in type.args:
712 # if arg.type.is_pyobject:
713 # error(self.pos,
714 # "Function with Python argument cannot be declared nogil")
715 if type.return_type.is_pyobject:
716 error(self.pos,
717 "Function with Python return type cannot be declared nogil")
718 for entry in lenv.var_entries + lenv.temp_entries:
719 #print "CFuncDefNode.need_gil_acquisition:", entry.name, entry.cname, "readonly =", entry.is_readonly ###
720 if entry.type.is_pyobject and not entry.is_readonly:
721 error(self.pos, "Function declared nogil has Python locals or temporaries")
722 return with_gil
724 def generate_function_header(self, code, with_pymethdef):
725 arg_decls = []
726 type = self.type
727 visibility = self.entry.visibility
728 for arg in type.args:
729 arg_decls.append(arg.declaration_code())
730 if type.has_varargs:
731 arg_decls.append("...")
732 if not arg_decls:
733 arg_decls = ["void"]
734 entity = type.function_header_code(self.entry.func_cname,
735 string.join(arg_decls, ","))
736 if visibility == 'public':
737 dll_linkage = "DL_EXPORT"
738 else:
739 dll_linkage = None
740 header = self.return_type.declaration_code(entity,
741 dll_linkage = dll_linkage)
742 if visibility <> 'private':
743 storage_class = "%s " % Naming.extern_c_macro
744 else:
745 storage_class = "static "
746 code.putln("%s%s {" % (
747 storage_class,
748 header))
750 def generate_argument_declarations(self, env, code):
751 # Arguments already declared in function header
752 pass
754 def generate_keyword_list(self, code):
755 pass
757 def generate_argument_parsing_code(self, code):
758 pass
760 def generate_argument_conversion_code(self, code):
761 pass
763 def generate_argument_type_tests(self, code):
764 pass
766 def error_value(self):
767 if self.return_type.is_pyobject:
768 return "0"
769 else:
770 #return None
771 return self.entry.type.exception_value
773 def caller_will_check_exceptions(self):
774 return self.entry.type.exception_check
777 class PyArgDeclNode(Node):
778 # Argument which must be a Python object (used
779 # for * and ** arguments).
780 #
781 # name string
782 # entry Symtab.Entry
784 pass
787 class DefNode(FuncDefNode):
788 # A Python function definition.
789 #
790 # name string the Python name of the function
791 # args [CArgDeclNode] formal arguments
792 # star_arg PyArgDeclNode or None * argument
793 # starstar_arg PyArgDeclNode or None ** argument
794 # doc string or None
795 # body StatListNode
796 #
797 # The following subnode is constructed internally
798 # when the def statement is inside a Python class definition.
799 #
800 # assmt AssignmentNode Function construction/assignment
802 assmt = None
803 num_kwonly_args = 0
804 reqd_kw_flags_cname = "0"
805 has_star_or_kwonly_args = 0
807 def __init__(self, pos, **kwds):
808 FuncDefNode.__init__(self, pos, **kwds)
809 n = 0
810 for arg in self.args:
811 if arg.kw_only:
812 n += 1
813 self.num_kwonly_args = n
814 if self.star_arg or self.starstar_arg or n > 0:
815 self.has_star_or_kwonly_args = 1
817 def analyse_declarations(self, env):
818 for arg in self.args:
819 base_type = arg.base_type.analyse(env)
820 name_declarator, type = \
821 arg.declarator.analyse(base_type, env)
822 arg.name = name_declarator.name
823 if name_declarator.cname:
824 error(self.pos,
825 "Python function argument cannot have C name specification")
826 arg.type = type.as_argument_type()
827 arg.hdr_type = None
828 arg.needs_conversion = 0
829 arg.needs_type_test = 0
830 arg.is_generic = 1
831 if arg.not_none and not arg.type.is_extension_type:
832 error(self.pos,
833 "Only extension type arguments can have 'not None'")
834 self.declare_pyfunction(env)
835 self.analyse_signature(env)
836 self.return_type = self.entry.signature.return_type()
837 # if self.has_star_or_kwonly_args:
838 # env.use_utility_code(get_starargs_utility_code)
840 def analyse_signature(self, env):
841 any_type_tests_needed = 0
842 sig = self.entry.signature
843 nfixed = sig.num_fixed_args()
844 for i in range(nfixed):
845 if i < len(self.args):
846 arg = self.args[i]
847 arg.is_generic = 0
848 if sig.is_self_arg(i):
849 arg.is_self_arg = 1
850 arg.hdr_type = arg.type = env.parent_type
851 arg.needs_conversion = 0
852 else:
853 arg.hdr_type = sig.fixed_arg_type(i)
854 if not arg.type.same_as(arg.hdr_type):
855 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
856 arg.needs_type_test = 1
857 any_type_tests_needed = 1
858 else:
859 arg.needs_conversion = 1
860 if arg.needs_conversion:
861 arg.hdr_cname = Naming.arg_prefix + arg.name
862 else:
863 arg.hdr_cname = Naming.var_prefix + arg.name
864 else:
865 self.bad_signature()
866 return
867 if nfixed < len(self.args):
868 if not sig.has_generic_args:
869 self.bad_signature()
870 for arg in self.args:
871 if arg.is_generic and arg.type.is_extension_type:
872 arg.needs_type_test = 1
873 any_type_tests_needed = 1
874 # if any_type_tests_needed:
875 # env.use_utility_code(arg_type_test_utility_code)
877 def bad_signature(self):
878 sig = self.entry.signature
879 expected_str = "%d" % sig.num_fixed_args()
880 if sig.has_generic_args:
881 expected_str = expected_str + " or more"
882 name = self.name
883 if name.startswith("__") and name.endswith("__"):
884 desc = "Special method"
885 else:
886 desc = "Method"
887 error(self.pos,
888 "%s %s has wrong number of arguments "
889 "(%d declared, %s expected)" % (
890 desc, self.name, len(self.args), expected_str))
892 def declare_pyfunction(self, env):
893 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
894 name = self.name
895 entry = env.declare_pyfunction(self.name, self.pos)
896 self.entry = entry
897 prefix = env.scope_prefix
898 entry.func_cname = \
899 Naming.func_prefix + prefix + name
900 entry.pymethdef_cname = \
901 Naming.pymethdef_prefix + prefix + name
902 if not entry.is_special:
903 entry.doc = self.doc
904 entry.doc_cname = \
905 Naming.funcdoc_prefix + prefix + name
907 def declare_arguments(self, env):
908 for arg in self.args:
909 if not arg.name:
910 error(arg.pos, "Missing argument name")
911 if arg.needs_conversion:
912 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
913 if arg.type.is_pyobject:
914 arg.entry.init = "0"
915 arg.entry.init_to_none = 0
916 else:
917 arg.entry = self.declare_argument(env, arg)
918 arg.entry.used = 1
919 arg.entry.is_self_arg = arg.is_self_arg
920 if arg.hdr_type:
921 if arg.is_self_arg or \
922 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
923 arg.entry.is_declared_generic = 1
924 self.declare_python_arg(env, self.star_arg)
925 self.declare_python_arg(env, self.starstar_arg)
927 def declare_python_arg(self, env, arg):
928 if arg:
929 entry = env.declare_var(arg.name,
930 PyrexTypes.py_object_type, arg.pos)
931 entry.used = 1
932 entry.init = "0"
933 entry.init_to_none = 0
934 entry.xdecref_cleanup = 1
935 arg.entry = entry
937 def analyse_expressions(self, env):
938 self.analyse_default_values(env)
939 if env.is_py_class_scope:
940 self.synthesize_assignment_node(env)
942 def analyse_default_values(self, env):
943 for arg in self.args:
944 if arg.default:
945 if arg.is_generic:
946 arg.default.analyse_types(env)
947 arg.default = arg.default.coerce_to(arg.type, env)
948 arg.default.allocate_temps(env)
949 arg.default_entry = env.add_default_value(arg.type)
950 arg.default_entry.used = 1
951 else:
952 error(arg.pos,
953 "This argument cannot have a default value")
954 arg.default = None
956 def synthesize_assignment_node(self, env):
957 import ExprNodes
958 self.assmt = SingleAssignmentNode(self.pos,
959 lhs = ExprNodes.NameNode(self.pos, name = self.name),
960 rhs = ExprNodes.UnboundMethodNode(self.pos,
961 class_cname = env.class_obj_cname,
962 function = ExprNodes.PyCFunctionNode(self.pos,
963 pymethdef_cname = self.entry.pymethdef_cname)))
964 self.assmt.analyse_declarations(env)
965 self.assmt.analyse_expressions(env)
967 def generate_function_header(self, code, with_pymethdef):
968 arg_code_list = []
969 sig = self.entry.signature
970 if sig.has_dummy_arg:
971 arg_code_list.append(
972 "PyObject *%s" % Naming.self_cname)
973 for arg in self.args:
974 if not arg.is_generic:
975 if arg.is_self_arg:
976 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
977 else:
978 arg_code_list.append(
979 arg.hdr_type.declaration_code(arg.hdr_cname))
980 if sig.has_generic_args:
981 arg_code_list.append(
982 "PyObject *%s, PyObject *%s"
983 % (Naming.args_cname, Naming.kwds_cname))
984 arg_code = ", ".join(arg_code_list)
985 dc = self.return_type.declaration_code(self.entry.func_cname)
986 header = "static %s(%s)" % (dc, arg_code)
987 code.putln("%s; /*proto*/" % header)
988 if self.entry.doc:
989 code.putln(
990 'static char %s[] = "%s";' % (
991 self.entry.doc_cname,
992 self.entry.doc))
993 if with_pymethdef:
994 code.put(
995 "static PyMethodDef %s = " %
996 self.entry.pymethdef_cname)
997 code.put_pymethoddef(self.entry, ";")
998 code.putln("%s {" % header)
1000 def generate_argument_declarations(self, env, code):
1001 for arg in self.args:
1002 if arg.is_generic: # or arg.needs_conversion:
1003 code.put_var_declaration(arg.entry)
1005 def generate_keyword_list(self, code):
1006 if self.entry.signature.has_generic_args:
1007 reqd_kw_flags = []
1008 has_reqd_kwds = False
1009 code.put(
1010 "static char *%s[] = {" %
1011 Naming.kwdlist_cname)
1012 for arg in self.args:
1013 if arg.is_generic:
1014 code.put(
1015 '"%s",' %
1016 arg.name)
1017 if arg.kw_only and not arg.default:
1018 has_reqd_kwds = 1
1019 flag = "1"
1020 else:
1021 flag = "0"
1022 reqd_kw_flags.append(flag)
1023 code.putln(
1024 "0};")
1025 if has_reqd_kwds:
1026 flags_name = Naming.reqd_kwds_cname
1027 self.reqd_kw_flags_cname = flags_name
1028 code.putln(
1029 "static char %s[] = {%s};" % (
1030 flags_name,
1031 ",".join(reqd_kw_flags)))
1033 def generate_argument_parsing_code(self, code):
1034 # Generate PyArg_ParseTuple call for generic
1035 # arguments, if any.
1036 has_kwonly_args = self.num_kwonly_args > 0
1037 has_star_or_kw_args = self.star_arg is not None \
1038 or self.starstar_arg is not None or has_kwonly_args
1039 if not self.entry.signature.has_generic_args:
1040 if has_star_or_kw_args:
1041 error(self.pos, "This method cannot have * or keyword arguments")
1042 else:
1043 arg_addrs = []
1044 arg_formats = []
1045 default_seen = 0
1046 for arg in self.args:
1047 arg_entry = arg.entry
1048 if arg.is_generic:
1049 if arg.default:
1050 code.putln(
1051 "%s = %s;" % (
1052 arg_entry.cname,
1053 arg.default_entry.cname))
1054 if not default_seen:
1055 arg_formats.append("|")
1056 default_seen = 1
1057 elif default_seen and not arg.kw_only:
1058 error(arg.pos, "Non-default argument following default argument")
1059 arg_addrs.append("&" + arg_entry.cname)
1060 format = arg_entry.type.parsetuple_format
1061 if format:
1062 arg_formats.append(format)
1063 else:
1064 error(arg.pos,
1065 "Cannot convert Python object argument to type '%s'"
1066 % arg.type)
1067 error_return_code = "return %s;" % self.error_value()
1068 argformat = '"%s"' % string.join(arg_formats, "")
1069 if has_star_or_kw_args:
1070 self.generate_stararg_getting_code(code)
1071 pt_arglist = [Naming.args_cname, Naming.kwds_cname, argformat,
1072 Naming.kwdlist_cname] + arg_addrs
1073 pt_argstring = string.join(pt_arglist, ", ")
1074 code.put(
1075 'if (!PyArg_ParseTupleAndKeywords(%s)) ' %
1076 pt_argstring)
1077 if has_star_or_kw_args:
1078 code.putln("{")
1079 code.put_xdecref(Naming.args_cname, py_object_type)
1080 code.put_xdecref(Naming.kwds_cname, py_object_type)
1081 self.generate_arg_xdecref(self.star_arg, code)
1082 self.generate_arg_xdecref(self.starstar_arg, code)
1083 code.putln(error_return_code)
1084 code.putln("}")
1085 else:
1086 code.putln(error_return_code)
1088 def put_stararg_decrefs(self, code):
1089 if self.has_star_or_kwonly_args:
1090 code.put_xdecref(Naming.args_cname, py_object_type)
1091 code.put_xdecref(Naming.kwds_cname, py_object_type)
1093 def generate_arg_xdecref(self, arg, code):
1094 if arg:
1095 code.put_var_xdecref(arg.entry)
1097 def arg_address(self, arg):
1098 if arg:
1099 return "&%s" % arg.entry.cname
1100 else:
1101 return 0
1103 def generate_stararg_getting_code(self, code):
1104 num_kwonly = self.num_kwonly_args
1105 nargs = len(self.args) - num_kwonly - self.entry.signature.num_fixed_args()
1106 star_arg_addr = self.arg_address(self.star_arg)
1107 starstar_arg_addr = self.arg_address(self.starstar_arg)
1108 code.use_utility_code(get_starargs_utility_code)
1109 code.putln(
1110 "if (__Pyx_GetStarArgs(&%s, &%s, %s, %s, %s, %s, %s) < 0) return %s;" % (
1111 Naming.args_cname,
1112 Naming.kwds_cname,
1113 Naming.kwdlist_cname,
1114 nargs,
1115 star_arg_addr,
1116 starstar_arg_addr,
1117 self.reqd_kw_flags_cname,
1118 self.error_value()))
1120 def generate_argument_conversion_code(self, code):
1121 # Generate code to convert arguments from
1122 # signature type to declared type, if needed.
1123 for arg in self.args:
1124 if arg.needs_conversion:
1125 self.generate_arg_conversion(arg, code)
1127 def generate_arg_conversion(self, arg, code):
1128 # Generate conversion code for one argument.
1129 old_type = arg.hdr_type
1130 new_type = arg.type
1131 if old_type.is_pyobject:
1132 self.generate_arg_conversion_from_pyobject(arg, code)
1133 elif new_type.is_pyobject:
1134 self.generate_arg_conversion_to_pyobject(arg, code)
1135 else:
1136 if new_type.assignable_from(old_type):
1137 code.putln(
1138 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
1139 else:
1140 error(arg.pos,
1141 "Cannot convert argument from '%s' to '%s'" %
1142 (old_type, new_type))
1144 def generate_arg_conversion_from_pyobject(self, arg, code):
1145 new_type = arg.type
1146 func = new_type.from_py_function
1147 if func:
1148 code.putln("%s = %s(%s); if (PyErr_Occurred()) %s" % (
1149 arg.entry.cname,
1150 func,
1151 arg.hdr_cname,
1152 code.error_goto(arg.pos)))
1153 else:
1154 error(arg.pos,
1155 "Cannot convert Python object argument to type '%s'"
1156 % new_type)
1158 def generate_arg_conversion_to_pyobject(self, arg, code):
1159 old_type = arg.hdr_type
1160 func = old_type.to_py_function
1161 if func:
1162 code.putln("%s = %s(%s); if (!%s) %s" % (
1163 arg.entry.cname,
1164 func,
1165 arg.hdr_cname,
1166 arg.entry.cname,
1167 code.error_goto(arg.pos)))
1168 else:
1169 error(arg.pos,
1170 "Cannot convert argument of type '%s' to Python object"
1171 % old_type)
1173 def generate_argument_type_tests(self, code):
1174 # Generate type tests for args whose signature
1175 # type is PyObject * and whose declared type is
1176 # a subtype thereof.
1177 for arg in self.args:
1178 if arg.needs_type_test:
1179 self.generate_arg_type_test(arg, code)
1181 def generate_arg_type_test(self, arg, code):
1182 # Generate type test for one argument.
1183 if arg.type.typeobj_is_available():
1184 typeptr_cname = arg.type.typeptr_cname
1185 arg_code = "((PyObject *)%s)" % arg.entry.cname
1186 code.use_utility_code(arg_type_test_utility_code)
1187 code.putln(
1188 'if (!__Pyx_ArgTypeTest(%s, %s, %d, "%s")) %s' % (
1189 arg_code,
1190 typeptr_cname,
1191 not arg.not_none,
1192 arg.name,
1193 code.error_goto(arg.pos)))
1194 else:
1195 error(arg.pos, "Cannot test type of extern C class "
1196 "without type object name specification")
1198 def generate_execution_code(self, code):
1199 # Evaluate and store argument default values
1200 for arg in self.args:
1201 default = arg.default
1202 if default:
1203 default.generate_evaluation_code(code)
1204 default.make_owned_reference(code)
1205 code.putln(
1206 "%s = %s;" % (
1207 arg.default_entry.cname,
1208 default.result_as(arg.default_entry.type)))
1209 default.generate_post_assignment_code(code)
1210 # if default.is_temp and default.type.is_pyobject:
1211 # code.putln(
1212 # "%s = 0;" %
1213 # default.result())
1214 # For Python class methods, create and store function object
1215 if self.assmt:
1216 self.assmt.generate_execution_code(code)
1218 def error_value(self):
1219 return self.entry.signature.error_value
1221 def caller_will_check_exceptions(self):
1222 return 1
1225 class PyClassDefNode(StatNode, BlockNode):
1226 # A Python class definition.
1227 #
1228 # name string Name of the class
1229 # doc string or None
1230 # body StatNode Attribute definition code
1231 # entry Symtab.Entry
1232 # scope PyClassScope
1233 #
1234 # The following subnodes are constructed internally:
1235 #
1236 # dict DictNode Class dictionary
1237 # classobj ClassNode Class object
1238 # target NameNode Variable to assign class object to
1240 def __init__(self, pos, name, bases, doc, body):
1241 StatNode.__init__(self, pos)
1242 self.name = name
1243 self.doc = doc
1244 self.body = body
1245 import ExprNodes
1246 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
1247 if self.doc:
1248 doc_node = ExprNodes.StringNode(pos, value = self.doc)
1249 else:
1250 doc_node = None
1251 self.classobj = ExprNodes.ClassNode(pos,
1252 name = ExprNodes.StringNode(pos, value = name),
1253 bases = bases, dict = self.dict, doc = doc_node)
1254 self.target = ExprNodes.NameNode(pos, name = name)
1256 def analyse_declarations(self, env):
1257 self.target.analyse_target_declaration(env)
1259 def analyse_expressions(self, env):
1260 self.dict.analyse_expressions(env)
1261 self.classobj.analyse_expressions(env)
1262 genv = env.global_scope()
1263 cenv = PyClassScope(name = self.name, outer_scope = genv)
1264 cenv.class_dict_cname = self.dict.result()
1265 cenv.class_obj_cname = self.classobj.result()
1266 self.scope = cenv
1267 self.body.analyse_declarations(cenv)
1268 self.body.analyse_expressions(cenv)
1269 self.target.analyse_target_expression(env, self.classobj)
1270 self.dict.release_temp(env)
1271 #self.classobj.release_temp(env)
1272 #self.target.release_target_temp(env)
1274 def generate_function_definitions(self, env, code):
1275 #self.generate_py_string_decls(self.scope, code)
1276 self.body.generate_function_definitions(
1277 self.scope, code)
1279 def generate_execution_code(self, code):
1280 self.dict.generate_evaluation_code(code)
1281 self.classobj.generate_evaluation_code(code)
1282 self.body.generate_execution_code(code)
1283 self.target.generate_assignment_code(self.classobj, code)
1284 self.dict.generate_disposal_code(code)
1287 class CClassDefNode(StatNode):
1288 # An extension type definition.
1289 #
1290 # visibility 'private' or 'public' or 'extern'
1291 # typedef_flag boolean
1292 # api boolean
1293 # module_name string or None For import of extern type objects
1294 # class_name string Unqualified name of class
1295 # as_name string or None Name to declare as in this scope
1296 # base_class_module string or None Module containing the base class
1297 # base_class_name string or None Name of the base class
1298 # objstruct_name string or None Specified C name of object struct
1299 # typeobj_name string or None Specified C name of type object
1300 # in_pxd boolean Is in a .pxd file
1301 # doc string or None
1302 # body StatNode or None
1303 # entry Symtab.Entry
1304 # base_type PyExtensionType or None
1306 entry = None
1308 def analyse_declarations(self, env):
1309 #print "CClassDefNode.analyse_declarations:", self.class_name
1310 #print "...visibility =", self.visibility
1311 #print "...module_name =", self.module_name
1312 if env.in_cinclude and not self.objstruct_name:
1313 error(self.pos, "Object struct name specification required for "
1314 "C class defined in 'extern from' block")
1315 self.base_type = None
1316 if self.base_class_name:
1317 if self.base_class_module:
1318 base_class_scope = env.find_module(self.base_class_module, self.pos)
1319 else:
1320 base_class_scope = env
1321 if base_class_scope:
1322 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
1323 if base_class_entry:
1324 if not base_class_entry.is_type:
1325 error(self.pos, "'%s' is not a type name" % self.base_class_name)
1326 elif not base_class_entry.type.is_extension_type:
1327 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
1328 elif not base_class_entry.type.is_complete():
1329 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
1330 else:
1331 self.base_type = base_class_entry.type
1332 has_body = self.body is not None
1333 if self.module_name and self.visibility <> 'extern':
1334 module_path = self.module_name.split(".")
1335 home_scope = env.find_imported_module(module_path, self.pos)
1336 if not home_scope:
1337 return
1338 else:
1339 home_scope = env
1340 self.entry = home_scope.declare_c_class(
1341 name = self.class_name,
1342 pos = self.pos,
1343 defining = has_body and self.in_pxd,
1344 implementing = has_body and not self.in_pxd,
1345 module_name = self.module_name,
1346 base_type = self.base_type,
1347 objstruct_cname = self.objstruct_name,
1348 typeobj_cname = self.typeobj_name,
1349 visibility = self.visibility,
1350 typedef_flag = self.typedef_flag,
1351 api = self.api)
1352 if home_scope is not env and self.visibility == 'extern':
1353 env.add_imported_entry(self.class_name, self.entry, pos)
1354 scope = self.entry.type.scope
1355 if self.doc:
1356 scope.doc = self.doc
1357 if has_body:
1358 self.body.analyse_declarations(scope)
1359 if self.in_pxd:
1360 scope.defined = 1
1361 else:
1362 scope.implemented = 1
1363 env.allocate_vtable_names(self.entry)
1365 def analyse_expressions(self, env):
1366 if self.body:
1367 self.body.analyse_expressions(env)
1369 def generate_function_definitions(self, env, code):
1370 if self.entry and self.body:
1371 # self.body.generate_function_definitions(
1372 # self.entry.type.scope, code)
1373 self.body.generate_function_definitions(env, code)
1375 def generate_execution_code(self, code):
1376 # This is needed to generate evaluation code for
1377 # default values of method arguments.
1378 if self.body:
1379 self.body.generate_execution_code(code)
1382 class PropertyNode(StatNode):
1383 # Definition of a property in an extension type.
1384 #
1385 # name string
1386 # doc string or None Doc string
1387 # body StatListNode
1389 def analyse_declarations(self, env):
1390 #print "PropertyNode.analyse_declarations:", env ###
1391 entry = env.declare_property(self.name, self.doc, self.pos)
1392 if entry:
1393 #if self.doc:
1394 # doc_entry = env.get_string_const(self.doc)
1395 # entry.doc_cname = doc_entry.cname
1396 self.body.analyse_declarations(entry.scope)
1398 def analyse_expressions(self, env):
1399 self.body.analyse_expressions(env)
1401 def generate_function_definitions(self, env, code):
1402 self.body.generate_function_definitions(env, code)
1404 def generate_execution_code(self, code):
1405 pass
1408 class GlobalNode(StatNode):
1409 # Global variable declaration.
1410 #
1411 # names [string]
1413 def analyse_declarations(self, env):
1414 for name in self.names:
1415 env.declare_global(name, self.pos)
1417 def analyse_expressions(self, env):
1418 pass
1420 def generate_execution_code(self, code):
1421 pass
1424 class ExprStatNode(StatNode):
1425 # Expression used as a statement.
1426 #
1427 # expr ExprNode
1429 def analyse_expressions(self, env):
1430 self.expr.analyse_expressions(env)
1431 self.expr.release_temp(env)
1433 def generate_execution_code(self, code):
1434 self.expr.generate_evaluation_code(code)
1435 if not self.expr.is_temp and self.expr.result():
1436 code.putln("%s;" % self.expr.result())
1437 self.expr.generate_disposal_code(code)
1440 class AssignmentNode(StatNode):
1441 # Abstract base class for assignment nodes.
1442 #
1443 # The analyse_expressions and generate_execution_code
1444 # phases of assignments are split into two sub-phases
1445 # each, to enable all the right hand sides of a
1446 # parallel assignment to be evaluated before assigning
1447 # to any of the left hand sides.
1449 def analyse_expressions(self, env):
1450 self.analyse_types(env)
1451 self.allocate_rhs_temps(env)
1452 self.allocate_lhs_temps(env)
1454 def generate_execution_code(self, code):
1455 self.generate_rhs_evaluation_code(code)
1456 self.generate_assignment_code(code)
1459 class SingleAssignmentNode(AssignmentNode):
1460 # The simplest case:
1461 #
1462 # a = b
1463 #
1464 # lhs ExprNode Left hand side
1465 # rhs ExprNode Right hand side
1467 def analyse_declarations(self, env):
1468 self.lhs.analyse_target_declaration(env)
1470 def analyse_types(self, env, use_temp = 0):
1471 self.rhs.analyse_types(env)
1472 self.lhs.analyse_target_types(env)
1473 self.lhs.gil_assignment_check(env)
1474 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
1475 if use_temp:
1476 self.rhs = self.rhs.coerce_to_temp(env)
1478 def allocate_rhs_temps(self, env):
1479 self.rhs.allocate_temps(env)
1481 def allocate_lhs_temps(self, env):
1482 self.lhs.allocate_target_temps(env, self.rhs)
1484 def generate_rhs_evaluation_code(self, code):
1485 self.rhs.generate_evaluation_code(code)
1487 def generate_assignment_code(self, code):
1488 self.lhs.generate_assignment_code(self.rhs, code)
1491 class AugmentedAssignmentNode(SingleAssignmentNode):
1492 # An in-place operation:
1493 #
1494 # a op= b
1495 #
1496 # lhs ExprNode Left hand side
1497 # operator string
1498 # rhs ExprNode Right hand side
1500 def analyse_types(self, env):
1501 self.rhs.analyse_types(env)
1502 self.lhs.analyse_inplace_types(env)
1503 type = self.lhs.type
1504 if type.is_pyobject:
1505 type = py_object_type
1506 else:
1507 if self.operator == "**=":
1508 error(self.pos, "**= operator not supported for non-Python types")
1509 self.rhs = self.rhs.coerce_to(type, env)
1511 def allocate_lhs_temps(self, env):
1512 self.lhs.allocate_inplace_target_temps(env, self.rhs)
1514 def generate_assignment_code(self, code):
1515 self.lhs.generate_inplace_assignment_code(self.operator, self.rhs, code)
1518 class CascadedAssignmentNode(AssignmentNode):
1519 # An assignment with multiple left hand sides:
1520 #
1521 # a = b = c
1522 #
1523 # lhs_list [ExprNode] Left hand sides
1524 # rhs ExprNode Right hand sides
1525 #
1526 # Used internally:
1527 #
1528 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
1530 def analyse_declarations(self, env):
1531 for lhs in self.lhs_list:
1532 lhs.analyse_target_declaration(env)
1534 def analyse_types(self, env, use_temp = 0):
1535 self.rhs.analyse_types(env)
1536 if use_temp:
1537 self.rhs = self.rhs.coerce_to_temp(env)
1538 else:
1539 self.rhs = self.rhs.coerce_to_simple(env)
1540 from ExprNodes import CloneNode
1541 self.coerced_rhs_list = []
1542 for lhs in self.lhs_list:
1543 lhs.analyse_target_types(env)
1544 lhs.gil_assignment_check(env)
1545 rhs = CloneNode(self.rhs)
1546 rhs = rhs.coerce_to(lhs.type, env)
1547 self.coerced_rhs_list.append(rhs)
1549 def allocate_rhs_temps(self, env):
1550 self.rhs.allocate_temps(env)
1552 def allocate_lhs_temps(self, env):
1553 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
1554 rhs.allocate_temps(env)
1555 lhs.allocate_target_temps(env, rhs)
1556 #lhs.release_target_temp(env)
1557 #rhs.release_temp(env)
1558 self.rhs.release_temp(env)
1560 def generate_rhs_evaluation_code(self, code):
1561 self.rhs.generate_evaluation_code(code)
1563 def generate_assignment_code(self, code):
1564 for i in range(len(self.lhs_list)):
1565 lhs = self.lhs_list[i]
1566 rhs = self.coerced_rhs_list[i]
1567 rhs.generate_evaluation_code(code)
1568 lhs.generate_assignment_code(rhs, code)
1569 # Assignment has disposed of the cloned RHS
1570 self.rhs.generate_disposal_code(code)
1572 class ParallelAssignmentNode(AssignmentNode):
1573 # A combined packing/unpacking assignment:
1574 #
1575 # a, b, c = d, e, f
1576 #
1577 # This has been rearranged by the parser into
1578 #
1579 # a = d ; b = e ; c = f
1580 #
1581 # but we must evaluate all the right hand sides
1582 # before assigning to any of the left hand sides.
1583 #
1584 # stats [AssignmentNode] The constituent assignments
1586 def analyse_declarations(self, env):
1587 for stat in self.stats:
1588 stat.analyse_declarations(env)
1590 def analyse_expressions(self, env):
1591 for stat in self.stats:
1592 stat.analyse_types(env, use_temp = 1)
1593 stat.allocate_rhs_temps(env)
1594 for stat in self.stats:
1595 stat.allocate_lhs_temps(env)
1597 def generate_execution_code(self, code):
1598 for stat in self.stats:
1599 stat.generate_rhs_evaluation_code(code)
1600 for stat in self.stats:
1601 stat.generate_assignment_code(code)
1604 class PrintStatNode(StatNode):
1605 # print statement
1606 #
1607 # args [ExprNode]
1608 # ends_with_comma boolean
1610 def analyse_expressions(self, env):
1611 for i in range(len(self.args)):
1612 arg = self.args[i]
1613 arg.analyse_types(env)
1614 arg = arg.coerce_to_pyobject(env)
1615 arg.allocate_temps(env)
1616 arg.release_temp(env)
1617 self.args[i] = arg
1618 # env.use_utility_code(printing_utility_code)
1619 self.gil_check(env)
1621 gil_message = "Python print statement"
1623 def generate_execution_code(self, code):
1624 for arg in self.args:
1625 arg.generate_evaluation_code(code)
1626 code.use_utility_code(printing_utility_code)
1627 code.putln(
1628 "if (__Pyx_PrintItem(%s) < 0) %s" % (
1629 arg.py_result(),
1630 code.error_goto(self.pos)))
1631 arg.generate_disposal_code(code)
1632 if not self.ends_with_comma:
1633 code.use_utility_code(printing_utility_code)
1634 code.putln(
1635 "if (__Pyx_PrintNewline() < 0) %s" %
1636 code.error_goto(self.pos))
1639 class DelStatNode(StatNode):
1640 # del statement
1641 #
1642 # args [ExprNode]
1644 def analyse_declarations(self, env):
1645 for arg in self.args:
1646 arg.analyse_target_declaration(env)
1648 def analyse_expressions(self, env):
1649 for arg in self.args:
1650 arg.analyse_target_expression(env, None)
1651 if not arg.type.is_pyobject:
1652 error(arg.pos, "Deletion of non-Python object")
1653 else:
1654 self.gil_check(env)
1656 gil_message = "Deleting Python object"
1658 def generate_execution_code(self, code):
1659 for arg in self.args:
1660 if arg.type.is_pyobject:
1661 arg.generate_deletion_code(code)
1662 # else error reported earlier
1665 class PassStatNode(StatNode):
1666 # pass statement
1668 def analyse_expressions(self, env):
1669 pass
1671 def generate_execution_code(self, code):
1672 pass
1675 class BreakStatNode(StatNode):
1677 def analyse_expressions(self, env):
1678 pass
1680 def generate_execution_code(self, code):
1681 if not code.break_label:
1682 error(self.pos, "break statement not inside loop")
1683 else:
1684 #code.putln(
1685 # "goto %s;" %
1686 # code.break_label)
1687 code.put_goto(code.break_label)
1690 class ContinueStatNode(StatNode):
1692 def analyse_expressions(self, env):
1693 pass
1695 def generate_execution_code(self, code):
1696 if code.in_try_finally:
1697 error(self.pos, "continue statement inside try of try...finally")
1698 elif not code.continue_label:
1699 error(self.pos, "continue statement not inside loop")
1700 else:
1701 #code.putln(
1702 # "goto %s;" %
1703 # code.continue_label)
1704 code.put_goto(code.continue_label)
1707 class ReturnStatNode(StatNode):
1708 # return statement
1709 #
1710 # value ExprNode or None
1711 # return_type PyrexType
1712 # temps_in_use [Entry] Temps in use at time of return
1714 def analyse_expressions(self, env):
1715 return_type = env.return_type
1716 self.return_type = return_type
1717 self.temps_in_use = env.temps_in_use()
1718 if not return_type:
1719 error(self.pos, "Return not inside a function body")
1720 return
1721 if self.value:
1722 self.value.analyse_types(env)
1723 if return_type.is_void or return_type.is_returncode:
1724 error(self.value.pos,
1725 "Return with value in void function")
1726 else:
1727 self.value = self.value.coerce_to(env.return_type, env)
1728 self.value.allocate_temps(env)
1729 self.value.release_temp(env)
1730 else:
1731 if (not return_type.is_void
1732 and not return_type.is_pyobject
1733 and not return_type.is_returncode):
1734 error(self.pos, "Return value required")
1735 if return_type.is_pyobject:
1736 self.gil_check(env)
1738 gil_message = "Returning Python object"
1740 def generate_execution_code(self, code):
1741 if not self.return_type:
1742 # error reported earlier
1743 return
1744 if self.value:
1745 self.value.generate_evaluation_code(code)
1746 self.value.make_owned_reference(code)
1747 code.putln(
1748 "%s = %s;" % (
1749 Naming.retval_cname,
1750 self.value.result_as(self.return_type)))
1751 self.value.generate_post_assignment_code(code)
1752 else:
1753 if self.return_type.is_pyobject:
1754 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
1755 elif self.return_type.is_returncode:
1756 code.putln(
1757 "%s = %s;" % (
1758 Naming.retval_cname,
1759 self.return_type.default_value))
1760 for entry in self.temps_in_use:
1761 code.put_var_decref_clear(entry)
1762 #code.putln(
1763 # "goto %s;" %
1764 # code.return_label)
1765 code.put_goto(code.return_label)
1768 class RaiseStatNode(StatNode):
1769 # raise statement
1770 #
1771 # exc_type ExprNode or None
1772 # exc_value ExprNode or None
1773 # exc_tb ExprNode or None
1775 def analyse_expressions(self, env):
1776 if self.exc_type:
1777 self.exc_type.analyse_types(env)
1778 self.exc_type = self.exc_type.coerce_to_pyobject(env)
1779 self.exc_type.allocate_temps(env)
1780 if self.exc_value:
1781 self.exc_value.analyse_types(env)
1782 self.exc_value = self.exc_value.coerce_to_pyobject(env)
1783 self.exc_value.allocate_temps(env)
1784 if self.exc_tb:
1785 self.exc_tb.analyse_types(env)
1786 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
1787 self.exc_tb.allocate_temps(env)
1788 if self.exc_type:
1789 self.exc_type.release_temp(env)
1790 if self.exc_value:
1791 self.exc_value.release_temp(env)
1792 if self.exc_tb:
1793 self.exc_tb.release_temp(env)
1794 # env.use_utility_code(raise_utility_code)
1795 self.gil_check(env)
1797 gil_message = "Raising exception"
1799 def generate_execution_code(self, code):
1800 if self.exc_type:
1801 self.exc_type.generate_evaluation_code(code)
1802 type_code = self.exc_type.py_result()
1803 else:
1804 type_code = 0
1805 if self.exc_value:
1806 self.exc_value.generate_evaluation_code(code)
1807 value_code = self.exc_value.py_result()
1808 else:
1809 value_code = "0"
1810 if self.exc_tb:
1811 self.exc_tb.generate_evaluation_code(code)
1812 tb_code = self.exc_tb.py_result()
1813 else:
1814 tb_code = "0"
1815 if self.exc_type or self.exc_value or self.exc_tb:
1816 code.use_utility_code(raise_utility_code)
1817 code.putln(
1818 "__Pyx_Raise(%s, %s, %s);" % (
1819 type_code,
1820 value_code,
1821 tb_code))
1822 else:
1823 code.putln(
1824 "__Pyx_ReRaise();")
1825 if self.exc_type:
1826 self.exc_type.generate_disposal_code(code)
1827 if self.exc_value:
1828 self.exc_value.generate_disposal_code(code)
1829 if self.exc_tb:
1830 self.exc_tb.generate_disposal_code(code)
1831 code.putln(
1832 code.error_goto(self.pos))
1835 class ReraiseStatNode(StatNode):
1837 def analyse_expressions(self, env):
1838 # env.use_utility_code(raise_utility_code)
1839 self.gil_check(env)
1841 gil_message = "Raising exception"
1843 def generate_execution_code(self, code):
1844 vars = code.exc_vars
1845 if vars:
1846 code.use_utility_code(raise_utility_code)
1847 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
1848 code.putln(code.error_goto(self.pos))
1849 else:
1850 error(self.pos, "Reraise not inside except clause")
1853 class AssertStatNode(StatNode):
1854 # assert statement
1855 #
1856 # cond ExprNode
1857 # value ExprNode or None
1859 def analyse_expressions(self, env):
1860 self.cond = self.cond.analyse_boolean_expression(env)
1861 if self.value:
1862 self.value.analyse_types(env)
1863 self.value = self.value.coerce_to_pyobject(env)
1864 self.value.allocate_temps(env)
1865 self.cond.release_temp(env)
1866 if self.value:
1867 self.value.release_temp(env)
1868 self.gil_check(env)
1870 gil_message = "Raising exception"
1872 def generate_execution_code(self, code):
1873 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
1874 self.cond.generate_evaluation_code(code)
1875 code.putln(
1876 "if (!%s) {" %
1877 self.cond.result())
1878 if self.value:
1879 self.value.generate_evaluation_code(code)
1880 if self.value:
1881 code.putln(
1882 "PyErr_SetObject(PyExc_AssertionError, %s);" %
1883 self.value.py_result())
1884 else:
1885 code.putln(
1886 "PyErr_SetNone(PyExc_AssertionError);")
1887 code.putln(
1888 code.error_goto(self.pos))
1889 code.putln(
1890 "}")
1891 self.cond.generate_disposal_code(code)
1892 # Disposal code for value not needed because exception always raised
1893 #if self.value:
1894 # self.value.generate_disposal_code(code)
1895 code.putln("#endif")
1897 class IfStatNode(StatNode):
1898 # if statement
1899 #
1900 # if_clauses [IfClauseNode]
1901 # else_clause StatNode or None
1903 def analyse_declarations(self, env):
1904 for if_clause in self.if_clauses:
1905 if_clause.analyse_declarations(env)
1906 if self.else_clause:
1907 self.else_clause.analyse_declarations(env)
1909 def analyse_expressions(self, env):
1910 for if_clause in self.if_clauses:
1911 if_clause.analyse_expressions(env)
1912 if self.else_clause:
1913 self.else_clause.analyse_expressions(env)
1915 def generate_execution_code(self, code):
1916 end_label = code.new_label()
1917 for if_clause in self.if_clauses:
1918 if_clause.generate_execution_code(code, end_label)
1919 if self.else_clause:
1920 code.putln("/*else*/ {")
1921 self.else_clause.generate_execution_code(code)
1922 code.putln("}")
1923 code.put_label(end_label)
1926 class IfClauseNode(Node):
1927 # if or elif clause in an if statement
1928 #
1929 # condition ExprNode
1930 # body StatNode
1932 def analyse_declarations(self, env):
1933 self.condition.analyse_declarations(env)
1934 self.body.analyse_declarations(env)
1936 def analyse_expressions(self, env):
1937 self.condition = \
1938 self.condition.analyse_temp_boolean_expression(env)
1939 self.condition.release_temp(env)
1940 self.body.analyse_expressions(env)
1942 def generate_execution_code(self, code, end_label):
1943 self.condition.generate_evaluation_code(code)
1944 code.putln(
1945 "if (%s) {" %
1946 self.condition.result())
1947 self.body.generate_execution_code(code)
1948 #code.putln(
1949 # "goto %s;" %
1950 # end_label)
1951 code.put_goto(end_label)
1952 code.putln("}")
1955 class WhileStatNode(StatNode):
1956 # while statement
1957 #
1958 # condition ExprNode
1959 # body StatNode
1960 # else_clause StatNode
1962 def analyse_declarations(self, env):
1963 self.body.analyse_declarations(env)
1964 if self.else_clause:
1965 self.else_clause.analyse_declarations(env)
1967 def analyse_expressions(self, env):
1968 self.condition = \
1969 self.condition.analyse_temp_boolean_expression(env)
1970 self.condition.release_temp(env)
1971 #env.recycle_pending_temps() # TEMPORARY
1972 self.body.analyse_expressions(env)
1973 if self.else_clause:
1974 self.else_clause.analyse_expressions(env)
1976 def generate_execution_code(self, code):
1977 old_loop_labels = code.new_loop_labels()
1978 code.putln(
1979 "while (1) {")
1980 self.condition.generate_evaluation_code(code)
1981 code.putln(
1982 "if (!%s) break;" %
1983 self.condition.result())
1984 self.body.generate_execution_code(code)
1985 code.put_label(code.continue_label)
1986 code.putln("}")
1987 break_label = code.break_label
1988 code.set_loop_labels(old_loop_labels)
1989 if self.else_clause:
1990 code.putln("/*else*/ {")
1991 self.else_clause.generate_execution_code(code)
1992 code.putln("}")
1993 code.put_label(break_label)
1996 class ForInStatNode(StatNode):
1997 # for statement
1998 #
1999 # target ExprNode
2000 # iterator IteratorNode
2001 # body StatNode
2002 # else_clause StatNode
2003 # item NextNode used internally
2005 def analyse_declarations(self, env):
2006 self.target.analyse_target_declaration(env)
2007 self.body.analyse_declarations(env)
2008 if self.else_clause:
2009 self.else_clause.analyse_declarations(env)
2011 def analyse_expressions(self, env):
2012 import ExprNodes
2013 self.iterator.analyse_expressions(env)
2014 self.target.analyse_target_types(env)
2015 self.item = ExprNodes.NextNode(self.iterator, env)
2016 self.item = self.item.coerce_to(self.target.type, env)
2017 self.item.allocate_temps(env)
2018 self.target.allocate_target_temps(env, self.item)
2019 #self.item.release_temp(env)
2020 #self.target.release_target_temp(env)
2021 self.body.analyse_expressions(env)
2022 if self.else_clause:
2023 self.else_clause.analyse_expressions(env)
2024 self.iterator.release_temp(env)
2026 def generate_execution_code(self, code):
2027 old_loop_labels = code.new_loop_labels()
2028 self.iterator.generate_evaluation_code(code)
2029 code.putln(
2030 "for (;;) {")
2031 self.item.generate_evaluation_code(code)
2032 self.target.generate_assignment_code(self.item, code)
2033 self.body.generate_execution_code(code)
2034 code.put_label(code.continue_label)
2035 code.putln(
2036 "}")
2037 break_label = code.break_label
2038 code.set_loop_labels(old_loop_labels)
2039 if self.else_clause:
2040 code.putln("/*else*/ {")
2041 self.else_clause.generate_execution_code(code)
2042 code.putln("}")
2043 code.put_label(break_label)
2044 self.iterator.generate_disposal_code(code)
2047 class IntegerForStatNode(StatNode):
2048 # for expr rel name rel expr
2049 #
2050 # bound1 ExprNode
2051 # relation1 string
2052 # target NameNode
2053 # relation2 string
2054 # bound2 ExprNode
2055 # body StatNode
2056 # else_clause StatNode or None
2057 #
2058 # Used internally:
2059 #
2060 # is_py_target bool
2061 # loopvar_name string
2062 # py_loopvar_node PyTempNode or None
2064 def analyse_declarations(self, env):
2065 self.target.analyse_target_declaration(env)
2066 self.body.analyse_declarations(env)
2067 if self.else_clause:
2068 self.else_clause.analyse_declarations(env)
2070 def analyse_expressions(self, env):
2071 import ExprNodes
2072 self.target.analyse_target_types(env)
2073 self.bound1.analyse_types(env)
2074 self.bound2.analyse_types(env)
2075 self.bound1 = self.bound1.coerce_to_integer(env)
2076 self.bound2 = self.bound2.coerce_to_integer(env)
2077 if not (self.bound2.is_name or self.bound2.is_literal):
2078 self.bound2 = self.bound2.coerce_to_temp(env)
2079 target_type = self.target.type
2080 if not (target_type.is_pyobject or target_type.is_int):
2081 error(self.target.pos,
2082 "Integer for-loop variable must be of type int or Python object")
2083 #if not (target_type.is_pyobject
2084 # or target_type.assignable_from(PyrexTypes.c_int_type)):
2085 # error(self.target.pos,
2086 # "Cannot assign integer to variable of type '%s'" % target_type)
2087 if target_type.is_int:
2088 self.is_py_target = 0
2089 self.loopvar_name = self.target.entry.cname
2090 self.py_loopvar_node = None
2091 else:
2092 self.is_py_target = 1
2093 c_loopvar_node = ExprNodes.TempNode(self.pos,
2094 PyrexTypes.c_long_type, env)
2095 c_loopvar_node.allocate_temps(env)
2096 self.loopvar_name = c_loopvar_node.result()
2097 self.py_loopvar_node = \
2098 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
2099 self.bound1.allocate_temps(env)
2100 self.bound2.allocate_temps(env)
2101 if self.is_py_target:
2102 self.py_loopvar_node.allocate_temps(env)
2103 self.target.allocate_target_temps(env, self.py_loopvar_node)
2104 #self.target.release_target_temp(env)
2105 #self.py_loopvar_node.release_temp(env)
2106 self.body.analyse_expressions(env)
2107 if self.is_py_target:
2108 c_loopvar_node.release_temp(env)
2109 if self.else_clause:
2110 self.else_clause.analyse_expressions(env)
2111 self.bound1.release_temp(env)
2112 self.bound2.release_temp(env)
2114 def generate_execution_code(self, code):
2115 old_loop_labels = code.new_loop_labels()
2116 self.bound1.generate_evaluation_code(code)
2117 self.bound2.generate_evaluation_code(code)
2118 offset, incop = self.relation_table[self.relation1]
2119 code.putln(
2120 "for (%s = %s%s; %s %s %s; %s%s) {" % (
2121 self.loopvar_name,
2122 self.bound1.result(), offset,
2123 self.loopvar_name, self.relation2, self.bound2.result(),
2124 incop, self.loopvar_name))
2125 if self.py_loopvar_node:
2126 self.py_loopvar_node.generate_evaluation_code(code)
2127 self.target.generate_assignment_code(self.py_loopvar_node, code)
2128 self.body.generate_execution_code(code)
2129 code.put_label(code.continue_label)
2130 code.putln("}")
2131 break_label = code.break_label
2132 code.set_loop_labels(old_loop_labels)
2133 if self.else_clause:
2134 code.putln("/*else*/ {")
2135 self.else_clause.generate_execution_code(code)
2136 code.putln("}")
2137 code.put_label(break_label)
2138 self.bound1.generate_disposal_code(code)
2139 self.bound2.generate_disposal_code(code)
2141 relation_table = {
2142 # {relop : (initial offset, increment op)}
2143 '<=': ("", "++"),
2144 '<' : ("+1", "++"),
2145 '>=': ("", "--"),
2146 '>' : ("-1", "--")
2147 }
2150 class TryExceptStatNode(StatNode):
2151 # try .. except statement
2152 #
2153 # body StatNode
2154 # except_clauses [ExceptClauseNode]
2155 # else_clause StatNode or None
2156 # cleanup_list [Entry] temps to clean up on error
2158 def analyse_declarations(self, env):
2159 self.body.analyse_declarations(env)
2160 for except_clause in self.except_clauses:
2161 except_clause.analyse_declarations(env)
2162 if self.else_clause:
2163 self.else_clause.analyse_declarations(env)
2164 self.gil_check(env)
2166 def analyse_expressions(self, env):
2167 self.body.analyse_expressions(env)
2168 self.cleanup_list = env.free_temp_entries[:]
2169 for except_clause in self.except_clauses:
2170 except_clause.analyse_expressions(env)
2171 if self.else_clause:
2172 self.else_clause.analyse_expressions(env)
2173 self.gil_check(env)
2175 gil_message = "Try-except statement"
2177 def generate_execution_code(self, code):
2178 old_error_label = code.new_error_label()
2179 our_error_label = code.error_label
2180 end_label = code.new_label()
2181 code.putln(
2182 "/*try:*/ {")
2183 self.body.generate_execution_code(code)
2184 code.putln(
2185 "}")
2186 code.error_label = old_error_label
2187 if self.else_clause:
2188 code.putln(
2189 "/*else:*/ {")
2190 self.else_clause.generate_execution_code(code)
2191 code.putln(
2192 "}")
2193 code.put_goto(end_label)
2194 code.put_label(our_error_label)
2195 code.put_var_xdecrefs_clear(self.cleanup_list)
2196 default_clause_seen = 0
2197 for except_clause in self.except_clauses:
2198 if not except_clause.pattern:
2199 default_clause_seen = 1
2200 else:
2201 if default_clause_seen:
2202 error(except_clause.pos, "Default except clause not last")
2203 except_clause.generate_handling_code(code, end_label)
2204 if not default_clause_seen:
2205 code.put_goto(code.error_label)
2206 code.put_label(end_label)
2209 class ExceptClauseNode(Node):
2210 # Part of try ... except statement.
2211 #
2212 # pattern ExprNode
2213 # target ExprNode or None
2214 # body StatNode
2215 # match_flag string result of exception match
2216 # exc_value ExcValueNode used internally
2217 # function_name string qualified name of enclosing function
2218 # exc_vars (string * 3) local exception variables
2220 def analyse_declarations(self, env):
2221 if self.target:
2222 self.target.analyse_target_declaration(env)
2223 self.body.analyse_declarations(env)
2225 def analyse_expressions(self, env):
2226 import ExprNodes
2227 genv = env.global_scope()
2228 self.function_name = env.qualified_name
2229 if self.pattern:
2230 self.pattern.analyse_expressions(env)
2231 self.pattern = self.pattern.coerce_to_pyobject(env)
2232 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
2233 self.pattern.release_temp(env)
2234 env.release_temp(self.match_flag)
2235 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
2236 if self.target:
2237 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
2238 self.exc_value.allocate_temps(env)
2239 self.target.analyse_target_expression(env, self.exc_value)
2240 self.body.analyse_expressions(env)
2241 for var in self.exc_vars:
2242 env.release_temp(var)
2243 # env.use_utility_code(get_exception_utility_code)
2245 def generate_handling_code(self, code, end_label):
2246 code.mark_pos(self.pos)
2247 if self.pattern:
2248 self.pattern.generate_evaluation_code(code)
2249 code.putln(
2250 "%s = PyErr_ExceptionMatches(%s);" % (
2251 self.match_flag,
2252 self.pattern.py_result()))
2253 self.pattern.generate_disposal_code(code)
2254 code.putln(
2255 "if (%s) {" %
2256 self.match_flag)
2257 else:
2258 code.putln(
2259 "/*except:*/ {")
2260 code.putln(
2261 '__Pyx_AddTraceback("%s");' % (self.function_name))
2262 # We always have to fetch the exception value even if
2263 # there is no target, because this also normalises the
2264 # exception and stores it in the thread state.
2265 exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
2266 code.use_utility_code(get_exception_utility_code)
2267 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
2268 code.error_goto(self.pos)))
2269 if self.target:
2270 self.exc_value.generate_evaluation_code(code)
2271 self.target.generate_assignment_code(self.exc_value, code)
2272 old_exc_vars = code.exc_vars
2273 code.exc_vars = self.exc_vars
2274 self.body.generate_execution_code(code)
2275 code.exc_vars = old_exc_vars
2276 for var in self.exc_vars:
2277 code.putln("Py_DECREF(%s); %s = 0;" % (var, var))
2278 code.put_goto(end_label)
2279 code.putln(
2280 "}")
2283 class TryFinallyStatNode(StatNode):
2284 # try ... finally statement
2285 #
2286 # body StatNode
2287 # finally_clause StatNode
2288 #
2289 # cleanup_list [Entry] temps to clean up on error
2290 #
2291 # The plan is that we funnel all continue, break
2292 # return and error gotos into the beginning of the
2293 # finally block, setting a variable to remember which
2294 # one we're doing. At the end of the finally block, we
2295 # switch on the variable to figure out where to go.
2296 # In addition, if we're doing an error, we save the
2297 # exception on entry to the finally block and restore
2298 # it on exit.
2300 preserve_exception = 1
2302 disallow_continue_in_try_finally = 0
2303 # There doesn't seem to be any point in disallowing
2304 # continue in the try block, since we have no problem
2305 # handling it.
2307 def analyse_declarations(self, env):
2308 self.body.analyse_declarations(env)
2309 self.finally_clause.analyse_declarations(env)
2311 def analyse_expressions(self, env):
2312 self.body.analyse_expressions(env)
2313 self.cleanup_list = env.free_temp_entries[:]
2314 self.finally_clause.analyse_expressions(env)
2315 self.gil_check(env)
2317 gil_message = "Try-finally statement"
2319 def generate_execution_code(self, code):
2320 old_error_label = code.error_label
2321 old_labels = code.all_new_labels()
2322 new_labels = code.get_all_labels()
2323 new_error_label = code.error_label
2324 catch_label = code.new_label()
2325 code.putln(
2326 "/*try:*/ {")
2327 if self.disallow_continue_in_try_finally:
2328 was_in_try_finally = code.in_try_finally
2329 code.in_try_finally = 1
2330 self.body.generate_execution_code(code)
2331 if self.disallow_continue_in_try_finally:
2332 code.in_try_finally = was_in_try_finally
2333 code.putln(
2334 "}")
2335 code.putln(
2336 "/*finally:*/ {")
2337 cases_used = []
2338 error_label_used = 0
2339 for i, new_label in enumerate(new_labels):
2340 if new_label in code.labels_used:
2341 cases_used.append(i)
2342 if new_label == new_error_label:
2343 error_label_used = 1
2344 error_label_case = i
2345 if cases_used:
2346 code.putln(
2347 "int __pyx_why;")
2348 if error_label_used and self.preserve_exception:
2349 code.putln(
2350 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
2351 code.putln(
2352 "int %s;" % Naming.exc_lineno_name)
2353 code.use_label(catch_label)
2354 code.putln(
2355 "__pyx_why = 0; goto %s;" % catch_label)
2356 for i in cases_used:
2357 new_label = new_labels[i]
2358 #if new_label and new_label <> "<try>":
2359 if new_label == new_error_label and self.preserve_exception:
2360 self.put_error_catcher(code,
2361 new_error_label, i+1, catch_label)
2362 else:
2363 code.putln(
2364 "%s: __pyx_why = %s; goto %s;" % (
2365 new_label,
2366 i+1,
2367 catch_label))
2368 code.put_label(catch_label)
2369 code.set_all_labels(old_labels)
2370 if error_label_used:
2371 code.new_error_label()
2372 finally_error_label = code.error_label
2373 self.finally_clause.generate_execution_code(code)
2374 if error_label_used:
2375 if finally_error_label in code.labels_used and self.preserve_exception:
2376 over_label = code.new_label()
2377 code.put_goto(over_label);
2378 code.put_label(finally_error_label)
2379 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
2380 for var in Naming.exc_vars:
2381 code.putln("Py_XDECREF(%s);" % var)
2382 code.putln("}")
2383 code.put_goto(old_error_label)
2384 code.put_label(over_label)
2385 code.error_label = old_error_label
2386 if cases_used:
2387 code.putln(
2388 "switch (__pyx_why) {")
2389 for i in cases_used:
2390 old_label = old_labels[i]
2391 if old_label == old_error_label and self.preserve_exception:
2392 self.put_error_uncatcher(code, i+1, old_error_label)
2393 else:
2394 code.use_label(old_label)
2395 code.putln(
2396 "case %s: goto %s;" % (
2397 i+1,
2398 old_label))
2399 code.putln(
2400 "}")
2401 code.putln(
2402 "}")
2404 def put_error_catcher(self, code, error_label, i, catch_label):
2405 code.putln(
2406 "%s: {" %
2407 error_label)
2408 code.putln(
2409 "__pyx_why = %s;" %
2410 i)
2411 code.put_var_xdecrefs_clear(self.cleanup_list)
2412 code.putln(
2413 "PyErr_Fetch(&%s, &%s, &%s);" %
2414 Naming.exc_vars)
2415 code.putln(
2416 "%s = %s;" % (
2417 Naming.exc_lineno_name, Naming.lineno_cname))
2418 #code.putln(
2419 # "goto %s;" %
2420 # catch_label)
2421 code.put_goto(catch_label)
2422 code.putln(
2423 "}")
2425 def put_error_uncatcher(self, code, i, error_label):
2426 code.putln(
2427 "case %s: {" %
2428 i)
2429 code.putln(
2430 "PyErr_Restore(%s, %s, %s);" %
2431 Naming.exc_vars)
2432 code.putln(
2433 "%s = %s;" % (
2434 Naming.lineno_cname, Naming.exc_lineno_name))
2435 for var in Naming.exc_vars:
2436 code.putln(
2437 "%s = 0;" %
2438 var)
2439 code.put_goto(error_label)
2440 code.putln(
2441 "}")
2444 class GILStatNode(TryFinallyStatNode):
2445 # 'with gil' or 'with nogil' statement
2446 #
2447 # state string 'gil' or 'nogil'
2449 preserve_exception = 0
2451 def __init__(self, pos, state, body):
2452 self.state = state
2453 TryFinallyStatNode.__init__(self, pos,
2454 body = body,
2455 finally_clause = GILExitNode(pos, state = state))
2457 def analyse_expressions(self, env):
2458 was_nogil = env.nogil
2459 env.nogil = 1
2460 TryFinallyStatNode.analyse_expressions(self, env)
2461 env.nogil = was_nogil
2463 def gil_check(self, env):
2464 pass
2466 def generate_execution_code(self, code):
2467 code.putln("/*with %s:*/ {" % self.state)
2468 if self.state == 'gil':
2469 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
2470 else:
2471 code.putln("PyThreadState *_save;")
2472 code.putln("Py_UNBLOCK_THREADS")
2473 TryFinallyStatNode.generate_execution_code(self, code)
2474 code.putln("}")
2477 class GILExitNode(StatNode):
2478 # Used as the 'finally' block in a GILStatNode
2479 #
2480 # state string 'gil' or 'nogil'
2482 def analyse_expressions(self, env):
2483 pass
2485 def generate_execution_code(self, code):
2486 if self.state == 'gil':
2487 code.putln("PyGILState_Release();")
2488 else:
2489 code.putln("Py_BLOCK_THREADS")
2492 class CImportStatNode(StatNode):
2493 # cimport statement
2494 #
2495 # module_name string Qualified name of module being imported
2496 # as_name string or None Name specified in "as" clause, if any
2498 def analyse_declarations(self, env):
2499 module_scope = env.find_module(self.module_name, self.pos)
2500 if "." in self.module_name:
2501 names = self.module_name.split(".")
2502 top_name = names[0]
2503 top_module_scope = env.context.find_submodule(top_name)
2504 module_scope = top_module_scope
2505 for name in names[1:]:
2506 submodule_scope = module_scope.find_submodule(name)
2507 module_scope.declare_module(name, submodule_scope, self.pos)
2508 if not self.as_name:
2509 env.add_imported_module(submodule_scope)
2510 module_scope = submodule_scope
2511 if self.as_name:
2512 env.declare_module(self.as_name, module_scope, self.pos)
2513 env.add_imported_module(module_scope)
2514 else:
2515 env.declare_module(top_name, top_module_scope, self.pos)
2516 env.add_imported_module(top_module_scope)
2517 else:
2518 name = self.as_name or self.module_name
2519 env.declare_module(name, module_scope, self.pos)
2520 env.add_imported_module(module_scope)
2522 def analyse_expressions(self, env):
2523 pass
2525 def generate_execution_code(self, code):
2526 pass
2529 class FromCImportStatNode(StatNode):
2530 # from ... cimport statement
2531 #
2532 # module_name string Qualified name of module
2533 # imported_names Parsing.ImportedName Names to be imported
2535 def analyse_declarations(self, env):
2536 module_scope = env.find_module(self.module_name, self.pos)
2537 env.add_imported_module(module_scope)
2538 for imp in self.imported_names:
2539 kind = imp.kind
2540 #entry = module_scope.find(imp.name, imp.pos)
2541 entry = module_scope.lookup(imp.name)
2542 if entry:
2543 if kind and not self.declaration_matches(entry, kind):
2544 entry.redeclared(pos)
2545 else:
2546 if kind == 'struct' or kind == 'union':
2547 entry = module_scope.declare_struct_or_union(imp.name,
2548 kind = kind, scope = None, typedef_flag = 0, pos = imp.pos)
2549 elif kind == 'class':
2550 entry = module_scope.declare_c_class(imp.name, pos = imp.pos,
2551 module_name = self.module_name)
2552 else:
2553 error(imp.pos, "Name '%s' not declared in module '%s'"
2554 % (imp.name, self.module_name))
2555 if entry:
2556 local_name = imp.as_name or imp.name
2557 env.add_imported_entry(local_name, entry, imp.pos)
2559 def declaration_matches(self, entry, kind):
2560 if not entry.is_type:
2561 return 0
2562 type = entry.type
2563 if kind == 'class':
2564 if not type.is_extension_type:
2565 return 0
2566 else:
2567 if not type.is_struct_or_union:
2568 return 0
2569 if kind <> type.kind:
2570 return 0
2571 return 1
2573 def analyse_expressions(self, env):
2574 pass
2576 def generate_execution_code(self, code):
2577 pass
2580 class FromImportStatNode(StatNode):
2581 # from ... import statement
2582 #
2583 # module ImportNode
2584 # items [(string, NameNode)]
2585 # #interned_items [(string, NameNode)]
2586 # item PyTempNode used internally
2588 def analyse_declarations(self, env):
2589 for _, target in self.items:
2590 target.analyse_target_declaration(env)
2592 def analyse_expressions(self, env):
2593 import ExprNodes
2594 self.module.analyse_expressions(env)
2595 self.item = ExprNodes.PyTempNode(self.pos, env)
2596 self.item.allocate_temp(env)
2597 #self.interned_items = []
2598 for name, target in self.items:
2599 #self.interned_items.append((env.intern(name), target))
2600 target.analyse_target_expression(env, None)
2601 self.module.release_temp(env)
2602 self.item.release_temp(env)
2604 def generate_execution_code(self, code):
2605 self.module.generate_evaluation_code(code)
2606 #for cname, target in self.interned_items:
2607 for name, target in self.items:
2608 cname = code.intern(name)
2609 code.putln(
2610 '%s = PyObject_GetAttr(%s, %s); if (!%s) %s' % (
2611 self.item.result(),
2612 self.module.py_result(),
2613 cname,
2614 self.item.result(),
2615 code.error_goto(self.pos)))
2616 target.generate_assignment_code(self.item, code)
2617 self.module.generate_disposal_code(code)
2619 #------------------------------------------------------------------------------------
2620 #
2621 # Runtime support code
2622 #
2623 #------------------------------------------------------------------------------------
2625 #utility_function_predeclarations = \
2626 #"""
2627 #typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
2628 #typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
2629 #"""
2631 utility_function_predeclarations = \
2632 """
2633 typedef struct {PyObject **p; int i; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
2634 """
2636 #get_name_predeclaration = \
2637 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
2639 #get_name_interned_predeclaration = \
2640 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
2642 #------------------------------------------------------------------------------------
2644 printing_utility_code = [
2645 """
2646 static int __Pyx_PrintItem(PyObject *); /*proto*/
2647 static int __Pyx_PrintNewline(void); /*proto*/
2648 """,r"""
2649 static PyObject *__Pyx_GetStdout(void) {
2650 PyObject *f = PySys_GetObject("stdout");
2651 if (!f) {
2652 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
2653 }
2654 return f;
2655 }
2657 static int __Pyx_PrintItem(PyObject *v) {
2658 PyObject *f;
2660 if (!(f = __Pyx_GetStdout()))
2661 return -1;
2662 if (PyFile_SoftSpace(f, 1)) {
2663 if (PyFile_WriteString(" ", f) < 0)
2664 return -1;
2665 }
2666 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
2667 return -1;
2668 if (PyString_Check(v)) {
2669 char *s = PyString_AsString(v);
2670 Py_ssize_t len = PyString_Size(v);
2671 if (len > 0 &&
2672 isspace(Py_CHARMASK(s[len-1])) &&
2673 s[len-1] != ' ')
2674 PyFile_SoftSpace(f, 0);
2675 }
2676 return 0;
2677 }
2679 static int __Pyx_PrintNewline(void) {
2680 PyObject *f;
2682 if (!(f = __Pyx_GetStdout()))
2683 return -1;
2684 if (PyFile_WriteString("\n", f) < 0)
2685 return -1;
2686 PyFile_SoftSpace(f, 0);
2687 return 0;
2688 }
2689 """]
2691 #------------------------------------------------------------------------------------
2693 # The following function is based on do_raise() from ceval.c.
2695 raise_utility_code = [
2696 """
2697 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
2698 ""","""
2699 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
2700 Py_XINCREF(type);
2701 Py_XINCREF(value);
2702 Py_XINCREF(tb);
2703 /* First, check the traceback argument, replacing None with NULL. */
2704 if (tb == Py_None) {
2705 Py_DECREF(tb);
2706 tb = 0;
2707 }
2708 else if (tb != NULL && !PyTraceBack_Check(tb)) {
2709 PyErr_SetString(PyExc_TypeError,
2710 "raise: arg 3 must be a traceback or None");
2711 goto raise_error;
2712 }
2713 /* Next, replace a missing value with None */
2714 if (value == NULL) {
2715 value = Py_None;
2716 Py_INCREF(value);
2717 }
2718 #if PY_VERSION_HEX < 0x02050000
2719 if (!PyClass_Check(type))
2720 #else
2721 if (!PyType_Check(type))
2722 #endif
2723 {
2724 /* Raising an instance. The value should be a dummy. */
2725 if (value != Py_None) {
2726 PyErr_SetString(PyExc_TypeError,
2727 "instance exception may not have a separate value");
2728 goto raise_error;
2729 }
2730 /* Normalize to raise <class>, <instance> */
2731 Py_DECREF(value);
2732 value = type;
2733 #if PY_VERSION_HEX < 0x02050000
2734 if (PyInstance_Check(type)) {
2735 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
2736 Py_INCREF(type);
2737 }
2738 else {
2739 PyErr_SetString(PyExc_TypeError,
2740 "raise: exception must be an old-style class or instance");
2741 goto raise_error;
2742 }
2743 #else
2744 type = (PyObject*) type->ob_type;
2745 Py_INCREF(type);
2746 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
2747 PyErr_SetString(PyExc_TypeError,
2748 "raise: exception class must be a subclass of BaseException");
2749 goto raise_error;
2750 }
2751 #endif
2752 }
2753 PyErr_Restore(type, value, tb);
2754 return;
2755 raise_error:
2756 Py_XDECREF(value);
2757 Py_XDECREF(type);
2758 Py_XDECREF(tb);
2759 return;
2760 }
2761 """]
2763 #------------------------------------------------------------------------------------
2765 reraise_utility_code = [
2766 """
2767 static void __Pyx_ReRaise(void); /*proto*/
2768 ""","""
2769 static void __Pyx_ReRaise(void) {
2770 PyThreadState *tstate = PyThreadState_Get();
2771 PyObject *type = tstate->exc_type;
2772 PyObject *value = tstate->exc_value;
2773 PyObject *tb = tstate->exc_traceback;
2774 Py_XINCREF(type);
2775 Py_XINCREF(value);
2776 Py_XINCREF(tb);
2777 PyErr_Restore(type, value, tb);
2778 }
2779 """]
2781 #------------------------------------------------------------------------------------
2783 arg_type_test_utility_code = [
2784 """
2785 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
2786 ""","""
2787 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
2788 if (!type) {
2789 PyErr_Format(PyExc_SystemError, "Missing type object");
2790 return 0;
2791 }
2792 if ((none_allowed && obj == Py_None) || PyObject_TypeCheck(obj, type))
2793 return 1;
2794 PyErr_Format(PyExc_TypeError,
2795 "Argument '%s' has incorrect type (expected %s, got %s)",
2796 name, type->tp_name, obj->ob_type->tp_name);
2797 return 0;
2798 }
2799 """]
2801 #------------------------------------------------------------------------------------
2802 #
2803 # __Pyx_GetStarArgs splits the args tuple and kwds dict into two parts
2804 # each, one part suitable for passing to PyArg_ParseTupleAndKeywords,
2805 # and the other containing any extra arguments. On success, replaces
2806 # the borrowed references *args and *kwds with references to a new
2807 # tuple and dict, and passes back new references in *args2 and *kwds2.
2808 # Does not touch any of its arguments on failure.
2809 #
2810 # Any of *kwds, args2 and kwds2 may be 0 (but not args or kwds). If
2811 # *kwds == 0, it is not changed. If kwds2 == 0 and *kwds != 0, a new
2812 # reference to the same dictionary is passed back in *kwds.
2813 #
2814 # If rqd_kwds is not 0, it is an array of booleans corresponding to the
2815 # names in kwd_list, indicating required keyword arguments. If any of
2816 # these are not present in kwds, an exception is raised.
2817 #
2819 get_starargs_utility_code = [
2820 """
2821 static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds, char *kwd_list[], \
2822 Py_ssize_t nargs, PyObject **args2, PyObject **kwds2, char rqd_kwds[]); /*proto*/
2823 ""","""
2824 static int __Pyx_GetStarArgs(
2825 PyObject **args,
2826 PyObject **kwds,
2827 char *kwd_list[],
2828 Py_ssize_t nargs,
2829 PyObject **args2,
2830 PyObject **kwds2,
2831 char rqd_kwds[])
2832 {
2833 PyObject *x = 0, *args1 = 0, *kwds1 = 0;
2834 int i;
2835 char **p;
2837 if (args2)
2838 *args2 = 0;
2839 if (kwds2)
2840 *kwds2 = 0;
2842 if (args2) {
2843 args1 = PyTuple_GetSlice(*args, 0, nargs);
2844 if (!args1)
2845 goto bad;
2846 *args2 = PyTuple_GetSlice(*args, nargs, PyTuple_GET_SIZE(*args));
2847 if (!*args2)
2848 goto bad;
2849 }
2850 else if (PyTuple_GET_SIZE(*args) > nargs) {
2851 int m = nargs;
2852 int n = PyTuple_GET_SIZE(*args);
2853 PyErr_Format(PyExc_TypeError,
2854 "function takes at most %d positional arguments (%d given)",
2855 m, n);
2856 goto bad;
2857 }
2858 else {
2859 args1 = *args;
2860 Py_INCREF(args1);
2861 }
2863 if (rqd_kwds && !*kwds)
2864 for (i = 0, p = kwd_list; *p; i++, p++)
2865 if (rqd_kwds[i])
2866 goto missing_kwarg;
2868 if (kwds2) {
2869 if (*kwds) {
2870 kwds1 = PyDict_New();
2871 if (!kwds1)
2872 goto bad;
2873 *kwds2 = PyDict_Copy(*kwds);
2874 if (!*kwds2)
2875 goto bad;
2876 for (i = 0, p = kwd_list; *p; i++, p++) {
2877 x = PyDict_GetItemString(*kwds, *p);
2878 if (x) {
2879 if (PyDict_SetItemString(kwds1, *p, x) < 0)
2880 goto bad;
2881 if (PyDict_DelItemString(*kwds2, *p) < 0)
2882 goto bad;
2883 }
2884 else if (rqd_kwds && rqd_kwds[i])
2885 goto missing_kwarg;
2886 }
2887 }
2888 else {
2889 *kwds2 = PyDict_New();
2890 if (!*kwds2)
2891 goto bad;
2892 }
2893 }
2894 else {
2895 kwds1 = *kwds;
2896 Py_XINCREF(kwds1);
2897 if (rqd_kwds && *kwds)
2898 for (i = 0, p = kwd_list; *p; i++, p++)
2899 if (rqd_kwds[i] && !PyDict_GetItemString(*kwds, *p))
2900 goto missing_kwarg;
2901 }
2903 *args = args1;
2904 *kwds = kwds1;
2905 return 0;
2906 missing_kwarg:
2907 PyErr_Format(PyExc_TypeError,
2908 "required keyword argument '%s' is missing", *p);
2909 bad:
2910 Py_XDECREF(args1);
2911 Py_XDECREF(kwds1);
2912 if (args2) {
2913 Py_XDECREF(*args2);
2914 }
2915 if (kwds2) {
2916 Py_XDECREF(*kwds2);
2917 }
2918 return -1;
2919 }
2920 """]
2922 #------------------------------------------------------------------------------------
2924 unraisable_exception_utility_code = [
2925 """
2926 static void __Pyx_WriteUnraisable(char *name); /*proto*/
2927 ""","""
2928 static void __Pyx_WriteUnraisable(char *name) {
2929 PyObject *old_exc, *old_val, *old_tb;
2930 PyObject *ctx;
2931 PyErr_Fetch(&old_exc, &old_val, &old_tb);
2932 ctx = PyString_FromString(name);
2933 PyErr_Restore(old_exc, old_val, old_tb);
2934 if (!ctx)
2935 ctx = Py_None;
2936 PyErr_WriteUnraisable(ctx);
2937 }
2938 """]
2940 #------------------------------------------------------------------------------------
2942 traceback_utility_code = [
2943 """
2944 static void __Pyx_AddTraceback(char *funcname); /*proto*/
2945 ""","""
2946 #include "compile.h"
2947 #include "frameobject.h"
2948 #include "traceback.h"
2950 static void __Pyx_AddTraceback(char *funcname) {
2951 PyObject *py_srcfile = 0;
2952 PyObject *py_funcname = 0;
2953 PyObject *py_globals = 0;
2954 PyObject *empty_tuple = 0;
2955 PyObject *empty_string = 0;
2956 PyCodeObject *py_code = 0;
2957 PyFrameObject *py_frame = 0;
2959 py_srcfile = PyString_FromString(%(FILENAME)s);
2960 if (!py_srcfile) goto bad;
2961 py_funcname = PyString_FromString(funcname);
2962 if (!py_funcname) goto bad;
2963 py_globals = PyModule_GetDict(%(GLOBALS)s);
2964 if (!py_globals) goto bad;
2965 empty_tuple = PyTuple_New(0);
2966 if (!empty_tuple) goto bad;
2967 empty_string = PyString_FromString("");
2968 if (!empty_string) goto bad;
2969 py_code = PyCode_New(
2970 0, /*int argcount,*/
2971 0, /*int nlocals,*/
2972 0, /*int stacksize,*/
2973 0, /*int flags,*/
2974 empty_string, /*PyObject *code,*/
2975 empty_tuple, /*PyObject *consts,*/
2976 empty_tuple, /*PyObject *names,*/
2977 empty_tuple, /*PyObject *varnames,*/
2978 empty_tuple, /*PyObject *freevars,*/
2979 empty_tuple, /*PyObject *cellvars,*/
2980 py_srcfile, /*PyObject *filename,*/
2981 py_funcname, /*PyObject *name,*/
2982 %(LINENO)s, /*int firstlineno,*/
2983 empty_string /*PyObject *lnotab*/
2984 );
2985 if (!py_code) goto bad;
2986 py_frame = PyFrame_New(
2987 PyThreadState_Get(), /*PyThreadState *tstate,*/
2988 py_code, /*PyCodeObject *code,*/
2989 py_globals, /*PyObject *globals,*/
2990 0 /*PyObject *locals*/
2991 );
2992 if (!py_frame) goto bad;
2993 py_frame->f_lineno = %(LINENO)s;
2994 PyTraceBack_Here(py_frame);
2995 bad:
2996 Py_XDECREF(py_srcfile);
2997 Py_XDECREF(py_funcname);
2998 Py_XDECREF(empty_tuple);
2999 Py_XDECREF(empty_string);
3000 Py_XDECREF(py_code);
3001 Py_XDECREF(py_frame);
3002 }
3003 """ % {
3004 'FILENAME': Naming.filename_cname,
3005 'LINENO': Naming.lineno_cname,
3006 'GLOBALS': Naming.module_cname
3007 }]
3009 #------------------------------------------------------------------------------------
3011 set_vtable_utility_code = [
3012 """
3013 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
3014 ""","""
3015 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
3016 PyObject *pycobj = 0;
3017 int result;
3019 pycobj = PyCObject_FromVoidPtr(vtable, 0);
3020 if (!pycobj)
3021 goto bad;
3022 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
3023 goto bad;
3024 result = 0;
3025 goto done;
3027 bad:
3028 result = -1;
3029 done:
3030 Py_XDECREF(pycobj);
3031 return result;
3032 }
3033 """]
3035 #------------------------------------------------------------------------------------
3037 get_vtable_utility_code = [
3038 """
3039 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
3040 """,r"""
3041 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
3042 int result;
3043 PyObject *pycobj;
3045 pycobj = PyMapping_GetItemString(dict, "__pyx_vtable__");
3046 if (!pycobj)
3047 goto bad;
3048 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
3049 if (!*(void **)vtabptr)
3050 goto bad;
3051 result = 0;
3052 goto done;
3054 bad:
3055 result = -1;
3056 done:
3057 Py_XDECREF(pycobj);
3058 return result;
3059 }
3060 """]
3062 #------------------------------------------------------------------------------------
3064 #init_intern_tab_utility_code = [
3065 #"""
3066 #static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
3067 #""","""
3068 #static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
3069 # while (t->p) {
3070 # *t->p = PyString_InternFromString(t->s);
3071 # if (!*t->p)
3072 # return -1;
3073 # ++t;
3074 # }
3075 # return 0;
3076 #}
3077 #"""]
3079 #init_intern_tab_utility_code = [
3080 #"""
3081 #static int __Pyx_InternStrings(PyObject **t[]); /*proto*/
3082 #""","""
3083 #static int __Pyx_InternStrings(PyObject **t[]) {
3084 # while (*t) {
3085 # PyString_InternInPlace(*t);
3086 # if (!**t)
3087 # return -1;
3088 # ++t;
3089 # }
3090 # return 0;
3091 #}
3092 #"""]
3094 #------------------------------------------------------------------------------------
3096 init_string_tab_utility_code = [
3097 """
3098 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
3099 ""","""
3100 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
3101 while (t->p) {
3102 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
3103 if (!*t->p)
3104 return -1;
3105 if (t->i)
3106 PyString_InternInPlace(t->p);
3107 ++t;
3108 }
3109 return 0;
3110 }
3111 """]
3113 #------------------------------------------------------------------------------------
3115 get_exception_utility_code = [
3116 """
3117 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
3118 ""","""
3119 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
3120 PyThreadState *tstate = PyThreadState_Get();
3121 PyErr_Fetch(type, value, tb);
3122 PyErr_NormalizeException(type, value, tb);
3123 if (PyErr_Occurred())
3124 goto bad;
3125 Py_INCREF(*type);
3126 Py_INCREF(*value);
3127 Py_INCREF(*tb);
3128 Py_XDECREF(tstate->exc_type);
3129 Py_XDECREF(tstate->exc_value);
3130 Py_XDECREF(tstate->exc_traceback);
3131 tstate->exc_type = *type;
3132 tstate->exc_value = *value;
3133 tstate->exc_traceback = *tb;
3134 return 0;
3135 bad:
3136 Py_XDECREF(*type);
3137 Py_XDECREF(*value);
3138 Py_XDECREF(*tb);
3139 return -1;
3140 }
3141 """]
3143 #------------------------------------------------------------------------------------
