1 #!/usr/bin/env python 2 3 """ 4 Translate the AST of a Python program into a more interpretable representation. 5 6 Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from micropython.common import operator_functions 23 from micropython.data import * 24 from micropython.errors import * 25 from micropython.rsvp import * 26 import compiler.ast 27 28 class Helper: 29 30 "Internal helper methods for AST visitors." 31 32 # Common methods. 33 34 def _generateGuards(self, node): 35 36 if not (self.optimiser.should_optimise_accesses_by_attribute_usage() and node._attrtypes): 37 return 38 39 # For each name, attempt to restrict the type employed. 40 41 for name, targets in node._attrtypes.items(): 42 43 # NOTE: Need to merge targets using the same type but suggesting 44 # NOTE: different kinds of attributes (instance vs. class). 45 46 # Where only one object type is suggested, produce a guard. 47 # NOTE: This only supports classes as types, not modules. 48 49 if len(targets) == 1: 50 target_name, is_static = list(targets)[0] 51 52 # Access the object table to get the attribute. 53 # This depends on a special entry in the table for class 54 # equivalence tests. 55 56 try: 57 obj = self.objtable.get_object(target_name) 58 59 # Where no attribute entry exists, the target could be a module. 60 # NOTE: Should perhaps raise an error. 61 62 except TableError, exc: 63 print "Possible guard for", target_name, "not enforceable." 64 continue 65 66 # NOTE: Could test the correctness of the guard where the nature 67 # NOTE: of the name is known. 68 # NOTE: The known value would be retrieved from the unit's 69 # NOTE: locals and tested as being a class or an instance of a 70 # NOTE: particular class. 71 72 # Generate the guard by loading a reference to the class. 73 74 after_test_block = self.new_block() 75 76 self.new_op(LoadClass(obj, target="source")) 77 78 # For only static attributes, classes are acceptable. 79 80 if is_static: 81 82 # Generate name is target (for classes). 83 84 self.dispatch(compiler.ast.Name(name)) 85 self.new_op(TestIdentity(source="source", target="status")) 86 87 # Jump to the next guard or the code if successful. 88 89 self.new_op(JumpIfTrue(after_test_block, working="status")) 90 91 # Where instance attributes are involved, only instances are 92 # acceptable. 93 94 if not isinstance(obj, Module): 95 96 # Generate isinstance(name, target). 97 98 self.dispatch(compiler.ast.Name(name)) 99 self.new_op(CheckInstance(source="source", target="status")) 100 101 # Jump to the next guard or the code if successful. 102 103 self.new_op(JumpIfTrue(after_test_block, working="status")) 104 105 # Where the type is inappropriate, raise an exception. 106 107 self.make_exception("TypeError") 108 self.set_target("exception") 109 self.new_op(RaiseException()) 110 111 self.set_block(after_test_block) 112 113 def _visitAttr(self, node, classes): 114 115 """ 116 Visit the attribute-related 'node', generating instructions based on the 117 given 'classes'. 118 """ 119 120 self.dispatch(node.expr) 121 self._generateAttr(node, node.attrname, classes) 122 123 def _generateAttr(self, node, attrname, classes): 124 125 """ 126 Generate code for the access to 'attrname' using the given 'classes'. 127 """ 128 129 AddressInstruction, AddressContextInstruction, AddressContextCondInstruction, \ 130 AttrInstruction, AttrIndexInstruction, AttrIndexContextCondInstruction = classes 131 132 # Where the last operation (defining the attribute owner) yields a 133 # constant... 134 135 target_plus_name = self.optimiser.optimise_constant_accessor() 136 137 # Only try and discover the position if the target can be resolved. 138 # Since instances cannot be constants in general, this involves classes 139 # and modules, but constants known at compile-time must also be handled. 140 141 if target_plus_name is not None: 142 target, target_name = target_plus_name 143 144 # Check for class.__class__. 145 146 if attrname == "__class__": 147 if isinstance(target, Class): 148 if AddressInstruction is LoadAddress: 149 self.replace_active_value("working", LoadAddress(self.get_builtin("type"))) 150 return 151 else: 152 raise TranslateError("Assigning to __class__ is not permitted.") 153 154 # Access the object table to get the attribute. 155 156 try: 157 attr = self.objtable.access(target_name, attrname) 158 except TableError, exc: 159 raise TranslateError(exc.args[0]) 160 161 # Produce a suitable instruction. 162 163 if AddressInstruction is not None: 164 165 # Where the target is a constant instance, the constant input 166 # needs to be retained as the context of the resulting 167 # attribute. 168 169 if isinstance(target, Instance): 170 self.new_op(AddressContextInstruction(attr)) 171 172 # It is acceptable to replace the instruction providing the 173 # constant input because doing so does not lose any input 174 # information required by the replacement instructions. 175 176 else: 177 self.replace_active_value("working", AddressInstruction(attr)) 178 else: 179 raise TranslateError("Storing of class or module attribute %r via an object is not permitted." % attrname) 180 181 return 182 183 # Where the last operation involves the special 'self' name, check to 184 # see if the attribute is acceptably positioned and produce a direct 185 # access to the attribute. 186 187 # This is the only reliable way of detecting instance accesses at 188 # compile-time since in general, objects could be classes or modules, 189 # but 'self' should only refer to instances. 190 191 elif self.optimiser.optimise_self_access(self.unit, attrname): 192 193 # Either generate an instruction operating on an instance attribute. 194 195 try: 196 attr = self.unit.parent.instance_attributes()[attrname] 197 self.new_op(AttrInstruction(attr)) 198 return 199 200 # Or generate an instruction operating on a class attribute. 201 # NOTE: Any simple instruction providing self is not removed. 202 203 except KeyError: 204 205 try: 206 attr = self.unit.parent.all_attributes()[attrname] 207 208 # Switch the context if the class attribute is compatible with 209 # the instance. 210 211 if attr.defined_within_hierarchy(): 212 213 # Only permit loading (not storing) of class attributes via self. 214 215 if AddressContextInstruction is not None: 216 self.new_op(AddressContextInstruction(attr)) 217 else: 218 raise TranslateError("Storing of class attribute %r via self not permitted." % attrname) 219 220 # Preserve the context if the class attribute comes from an 221 # incompatible class. 222 223 elif attr.defined_outside_hierarchy(): 224 225 # Only permit loading (not storing) of class attributes via self. 226 227 if AddressInstruction is not None: 228 self.new_op(AddressInstruction(attr)) 229 else: 230 raise TranslateError("Storing of class attribute %r via self not permitted." % attrname) 231 232 # Otherwise, test for a suitable context at run-time. 233 234 else: 235 236 # Only permit loading (not storing) of class attributes via self. 237 238 if AddressContextCondInstruction is not None: 239 self.new_op(AddressContextCondInstruction(attr)) 240 else: 241 raise TranslateError("Storing of class attribute %r via self not permitted." % attrname) 242 243 return 244 245 # Or delegate the attribute access to a general instruction 246 # since the kind of attribute cannot be deduced. 247 248 except KeyError: 249 pass 250 251 # Attempt to deduce the target of an attribute access by searching for a 252 # unique type providing the names associated with the accessed object. 253 254 elif self.optimiser.should_optimise_accesses_by_attribute_usage() and \ 255 isinstance(node, compiler.ast.AttributeAccessor): 256 257 targets = self.possible_accessors_from_usage(node) 258 259 if targets and len(targets) == 1: 260 target = list(targets)[0] 261 attr = target.all_attributes().get(attrname) 262 263 # Produce a suitable instruction. 264 265 if attr: 266 if AddressContextCondInstruction is not None and attr.is_static_attribute(): 267 self.new_op(AddressContextCondInstruction(attr)) 268 elif AttrInstruction is not None and not attr.is_static_attribute(): 269 self.new_op(AttrInstruction(attr)) 270 else: 271 raise TranslateError("Storing of class or module attribute %r via an object is not permitted." % attrname) 272 273 return 274 275 # Check for class.__class__. 276 277 if attrname == "__class__": 278 279 # Remember the accessor. 280 281 temp_accessor = self.get_temp() 282 283 attr_block = self.new_block() 284 end_block = self.new_block() 285 286 self.new_op(CheckClass(target="status")) 287 self.new_op(JumpIfFalse(attr_block, working="status")) 288 self.load_builtin("type", node) 289 self.new_op(Jump(end_block)) 290 self.set_block(attr_block) 291 292 # Recall the accessor. 293 294 self.new_op(temp_accessor) 295 296 # Otherwise, perform a normal operation. 297 298 try: 299 index = self.objtable.get_index(attrname) 300 301 except self.objtable.TableError: 302 303 # If this error arises on generated code, check the names_used 304 # attribute on the Importer. 305 306 raise TranslateError("No attribute entry exists for name %r." % attrname) 307 308 # NOTE: Test for class vs. instance attributes, generating 309 # NOTE: context-related instructions. 310 311 if AttrIndexContextCondInstruction is not None: 312 self.new_op(AttrIndexContextCondInstruction(index)) 313 314 # Store instructions do not need to consider context modifications. 315 316 else: 317 self.new_op(AttrIndexInstruction(index)) 318 319 # Where __class__ was involved, define the start of the following code. 320 321 if attrname == "__class__": 322 self.set_block(end_block) 323 self.discard_temp(temp_accessor) 324 325 # Invocations involve the following: 326 # 327 # 1. Reservation of a frame for the arguments 328 # 2. Identification of the target which is then held in temporary storage 329 # 3. Optional inclusion of a context (important for methods) 330 # 4. Preparation of the argument frame 331 # 5. Invocation of the target 332 # 6. Discarding of the frame 333 # 334 # In order to support nested invocations - such as a(b(c)) - use of the 335 # temporary storage is essential. 336 337 def _startCallFunc(self): 338 339 "Record the location of the invocation." 340 341 op = MakeFrame() 342 self.new_op(op) # records the start of the frame 343 self.frame_makers.append(op) 344 345 def _generateCallFunc(self, args, node): 346 347 """ 348 Support a generic function invocation using the given 'args', occurring 349 on the given 'node', where the expression providing the invocation 350 target has just been generated. 351 352 In other situations, the invocation is much simpler and does not need to 353 handle the full flexibility of a typical Python invocation. Internal 354 invocations, such as those employed by operators and certain 355 control-flow mechanisms, use predetermined arguments and arguably do not 356 need to support the same things as the more general invocations. 357 """ 358 359 target, context, temp_target, temp_context = self._generateCallFuncContext() 360 self._generateCallFuncArgs(target, context, temp_target, temp_context, args, node) 361 return temp_target, target, temp_context 362 363 def _generateCallFuncContext(self): 364 365 """ 366 Produce code which loads and checks the context of the current 367 invocation, the instructions for whose target have already been 368 produced, returning a list of instructions which reference the 369 invocation target. 370 """ 371 372 t = self.optimiser.optimise_known_target() 373 if t: 374 target, context = t 375 376 # Detect dynamic functions acting like instances. 377 378 if isinstance(target, Function) and target.is_dynamic(): 379 target, context = None, None 380 else: 381 target, context = None, None 382 383 # Store the target in temporary storage for subsequent referencing. 384 385 temp_target = self.optimiser.optimise_temp_storage() 386 387 # Where a target or context are not known or where an instance is known 388 # to be the context, load the context. 389 390 if target is None or isinstance(context, Instance): 391 self.new_op(temp_target) 392 self.new_op(Transfer(source="working_context", target="working")) 393 temp_context = self.optimiser.optimise_temp_storage() 394 self.new_op(StoreFrame(0)) 395 396 # Class contexts should be made available for testing of the first 397 # argument. 398 # NOTE: Class methods should eventually be supported. 399 400 elif isinstance(context, Class): 401 self.new_op(temp_target) 402 self.new_op(Transfer(source="working_context", target="working")) 403 temp_context = self.optimiser.optimise_temp_storage() 404 405 # Otherwise omit the context. 406 407 else: 408 temp_context = None 409 410 return target, context, temp_target, temp_context 411 412 def _generateCallFuncArgs(self, target, context, temp_target, temp_context, args, node): 413 414 """ 415 Given invocation 'target' and 'context' information, the 'temp_target' 416 reference to the target, the 'temp_context' reference to the context, a 417 list of nodes representing the 'args' (arguments), generate instructions 418 which load the arguments for the invocation defined by the given 'node'. 419 """ 420 421 # Evaluate the arguments. 422 423 employed_positions = set() 424 employed_keywords = set() 425 extra_keywords = [] 426 positional_args = [] 427 keyword_args = [] 428 429 # Find keyword arguments in advance in order to help resolve targets. 430 431 have_keywords = False 432 433 for arg in args: 434 if isinstance(arg, compiler.ast.Keyword): 435 employed_keywords.add(arg.name) 436 keyword_args.append(arg) 437 have_keywords = True 438 elif not have_keywords: 439 positional_args.append(arg) 440 441 possible_targets = self.paramtable.all_possible_objects(employed_keywords) 442 443 # Note the presence of the context in the frame where appropriate. 444 445 # For unknown invocations and method invocations. 446 447 if target is None or isinstance(context, Instance): 448 ncontext = 1 449 expect_testable_self = False 450 451 # Handle calls to classes by obtaining the instantiator function. 452 # A context is reserved for the new instance, but this is not provided 453 # in the invocation (since the instantiator will fill the locals slot 454 # concerned). 455 456 elif isinstance(target, Class): 457 ncontext = 1 458 expect_testable_self = False 459 target = target.get_instantiator() 460 461 # Method calls via classes. 462 463 elif isinstance(context, Class): 464 ncontext = 0 465 expect_testable_self = True 466 467 # Function calls. 468 469 else: 470 ncontext = 0 471 expect_testable_self = False 472 473 # Traverse the positional arguments adding them using the incrementing 474 # frame position. 475 476 first = True 477 frame_pos = ncontext 478 temp_first_argument = None 479 480 for arg in positional_args: 481 self.dispatch(arg) 482 self.new_op(StoreFrame(frame_pos)) 483 employed_positions.add(frame_pos) 484 485 # Check to see if the first argument is appropriate (compatible with 486 # the target where methods are being invoked via classes). 487 488 if first and (expect_testable_self or target is None): 489 490 # Drop any test if the target and the context are known. 491 492 if not self.optimiser.have_correct_self_for_target(context, self.unit): 493 494 # Otherwise, remember the first argument for a subsequent 495 # test. 496 497 temp_first_argument = self.optimiser.optimise_temp_storage() 498 499 first = False 500 frame_pos += 1 501 502 # Adjust the invocation frame for unknown invocations. 503 # Test the first argument if appropriate. 504 505 self._generateCallFuncContextTest(target, temp_context, temp_first_argument, node) 506 507 # Traverse the keyword arguments adding them at the appropriate frame 508 # positions. 509 510 max_keyword_pos = -1 511 512 for arg in keyword_args: 513 514 # Optimise where the target is known now. 515 516 if target is not None: 517 518 # Find the parameter table entry for the target. 519 520 target_name = target.full_name() 521 522 # Look for a callable with the precise target name. 523 524 table_entry = self.paramtable.table[target_name] 525 526 # Look the name up in the parameter table entry. 527 528 try: 529 pos = table_entry[arg.name] 530 531 # Where no position is found, this could be an extra keyword 532 # argument. 533 534 except KeyError: 535 extra_keywords.append(arg) 536 continue 537 538 # Test for illegal conditions. 539 540 if pos in employed_positions: 541 raise TranslateError("Keyword argument %r overwrites parameter %r." % (arg.name, pos)) 542 543 employed_positions.add(pos) 544 545 # Generate code for the keyword and the positioning 546 # operation. 547 548 self.dispatch(arg.expr) 549 self.new_op(StoreFrame(pos)) 550 551 # Otherwise, generate the code needed to obtain the details of 552 # the parameter location. 553 554 else: 555 556 # Combine the target details with the name to get the location. 557 # See the access method on the List class. 558 559 try: 560 paramindex = self.paramtable.get_index(arg.name) 561 562 # Where no position is found, this could be an extra keyword 563 # argument. 564 565 except self.paramtable.TableError: 566 extra_keywords.append(arg) 567 continue 568 569 # Generate code for the keyword and the positioning 570 # operation. Get the value as the source of the assignment. 571 572 self.dispatch(arg.expr) 573 self.record_value() 574 self.start_target() 575 576 # Store the source value using the callable's parameter 577 # table information. 578 579 self.new_op(temp_target) 580 self.new_op(StoreFrameIndex(paramindex)) 581 582 self.assign_value() 583 self.discard_value() 584 585 # Record the highest possible frame position for this argument. 586 587 max_keyword_pos = max(max_keyword_pos, max(self.paramtable.all_attribute_positions(arg.name))) 588 589 # Use the frame position counter as a general argument counter. 590 591 frame_pos += 1 592 593 # NOTE: Extra keywords are not supported. 594 # NOTE: Somehow, the above needs to be combined with * arguments. 595 596 if extra_keywords: 597 print "Warning: extra keyword argument(s) %s not handled." % ", ".join([arg.name for arg in extra_keywords]) 598 599 # Either test for a complete set of arguments. 600 601 if target is not None: 602 603 # Make sure that enough arguments have been given. 604 605 nargs_max = len(target.positional_names) 606 ndefaults = len(target.defaults) 607 nargs_min = nargs_max - ndefaults 608 609 # Visit each argument position and look for a supplied argument. 610 611 for i in range(ncontext, nargs_min): 612 if i not in employed_positions: 613 raise TranslateError( 614 "Argument %r not supplied for %r: need at least %d argument(s)." % (i+1, target.name, nargs_min)) 615 616 nargs = frame_pos 617 618 # Determine whether too many arguments have been given and how big 619 # the frame should be. 620 621 # For parameter lists with * or ** parameters, accept as many 622 # arguments as are allowed or as many as we have. 623 624 if target.has_star or target.has_dstar: 625 frame_size = max(nargs, nargs_max) 626 627 # NOTE: We now need to pack these arguments into a suitable 628 # NOTE: structure for the * parameter. 629 630 # For other parameter lists, only accept as many arguments as we are 631 # allowed. 632 633 elif nargs > nargs_max: 634 raise TranslateError( 635 "Too many arguments for %r: need at most %d argument(s)." % (target.name, nargs_max)) 636 637 else: 638 frame_size = nargs_max 639 640 # Where defaults are involved, put them into the frame. 641 642 self._generateCallFuncDefaultArgs(target, temp_target, nargs_min, nargs_max, employed_positions) 643 644 # Set the frame size. 645 646 self._endCallFuncArgs(frame_size) 647 648 # Or just set the frame size and have the function check the arguments. 649 650 else: 651 max_pos = max(max(employed_positions or [-1]), max_keyword_pos, frame_pos - 1) 652 self._endCallFuncArgs(max_pos + 1) 653 654 def _generateCallFuncDefaultArgs(self, target, temp_target, nargs_min, nargs_max, employed_positions): 655 656 """ 657 For the given 'target' and 'temp_target' reference to the target, 658 generate default arguments for those positions in the range 659 'nargs_min'...'nargs_max' which are not present in the 660 'employed_positions' collection. 661 """ 662 663 # Where appropriate, construct a dynamic object to hold the defaults. 664 665 dynamic = target.is_dynamic() 666 667 # Here, we use negative index values to visit the right hand end of 668 # the defaults list. 669 670 for pos in range(nargs_min, nargs_max): 671 if pos not in employed_positions: 672 if dynamic: 673 self.new_op(temp_target) 674 self.new_op(LoadAttr(target.default_attrs[pos - nargs_min])) 675 else: 676 self.new_op(LoadAddress(target.default_attrs[pos - nargs_min])) 677 self.new_op(StoreFrame(pos)) 678 679 def _generateCallFuncContextTest(self, target, temp_context, temp_first_argument, node): 680 681 """ 682 Generate code involved in a call to the given 'target' to test the 683 context provided by 'temp_context' against 'temp_first_argument', and to 684 signal an exception if the context is incompatible with the first frame 685 argument. 686 687 In addition, the invocation frame will be shifted if 'temp_context' 688 indicates a function or a class. 689 """ 690 691 # Need to store the explicit first argument in the working register for 692 # the eventual test. 693 694 if temp_first_argument is not None: 695 self.new_op(temp_first_argument) 696 697 # Put the context in the source register. 698 699 if target is None or temp_first_argument is not None: 700 if self.new_op(temp_context.copy()): 701 self.last_op().target = "source" 702 else: 703 self.new_op(Transfer(source="working", target="source")) 704 705 # Add some preliminary tests where the target is not known. 706 707 if target is None: 708 if temp_first_argument is not None: 709 self.new_op(JumpInFrameDirect(self.native.getCallFuncUnknownTargetTestableSelf())) 710 else: 711 self.new_op(JumpInFrameDirect(self.native.getCallFuncUnknownTarget())) 712 713 elif temp_first_argument is not None: 714 self.new_op(JumpInFrameDirect(self.native.getCallFuncKnownTargetTestableSelf())) 715 716 def _doCallFunc(self, temp_target, target=None): 717 718 "Make the invocation." 719 720 # For classes, the target itself is used, since the instantiator will be 721 # obtained via the class. 722 723 if isinstance(target, (Class, Function)): 724 self.new_op(JumpWithFrameDirect(target, working="status")) 725 else: 726 self.new_op(temp_target) 727 self.new_op(LoadCallable()) 728 self.new_op(JumpWithFrame()) 729 730 def _endCallFuncArgs(self, nargs): 731 732 "Set the frame size." 733 734 self.frame_makers[-1].attr = nargs 735 self.frame_makers.pop() 736 737 def _endCallFunc(self, temp_target=None, temp_context=None): 738 739 "Finish the invocation and tidy up afterwards." 740 741 self.new_op(DropFrame()) 742 743 # Discard any temporary storage instructions. 744 745 if temp_target is not None: 746 self.discard_temp(temp_target) 747 748 if temp_context is not None: 749 self.discard_temp(temp_context) 750 751 def _visitFunctionDeclaration(self, node): 752 753 """ 754 Visit the function declaration at 'node', which can be a lambda or a 755 named function. As a consequence an instruction will be generated which 756 provides a reference to the function. 757 """ 758 759 fn = node.unit 760 ndefaults = len(fn.defaults) 761 temp = self._generateFunctionDefaults(fn) 762 763 # Populate the new object required for the function. 764 765 if temp is not None: 766 self.new_op(LoadConst(fn)) 767 self.new_op(LoadCallable(target="source")) 768 self.new_op(temp) 769 self.new_op(StoreCallable(source="source")) 770 self.new_op(temp) 771 #self.discard_temp(temp) 772 else: 773 self.new_op(LoadFunction(fn)) 774 775 def _visitFunctionDefinition(self, node): 776 777 """ 778 Visit the function definition at 'node', which can be a lambda or a 779 named function, generating the prelude with argument and default 780 checking, plus the body of the function itself. 781 """ 782 783 # Check frames using the function's details. 784 785 fn = node.unit 786 nparams = len(fn.positional_names) 787 ndefaults = len(fn.defaults) 788 789 fn.body_block = self.new_block() 790 791 # Check the number of parameters and defaults. 792 793 self.new_op(CheckFrame((nparams, ndefaults), target="status")) 794 795 if ndefaults > 0: 796 if fn.is_dynamic(): 797 self.new_op(LoadTemp(0)) # context provides storage 798 else: 799 self.new_op(LoadFunction(fn)) 800 801 self.new_op(FillDefaults((nparams, ndefaults))) 802 803 # Produce the body. 804 805 self.set_block(fn.body_block) 806 807 # For functions with star parameters, make a special list for the 808 # extra arguments and re-map the parameter. 809 810 if fn.has_star: 811 self.new_op(CopyExtra(nparams)) 812 813 # Ensure that the star parameter has a slot in the frame. 814 815 self.new_op(CheckExtra(nparams, target="status")) 816 self.new_op(StoreTemp(nparams)) 817 818 # Extend the frame for local usage. 819 820 extend = ExtendFrame() 821 self.new_op(extend) 822 823 # Perform tuple assignment for any tuple parameters. 824 825 self._visitFunctionTupleParameters(fn, node) 826 827 # Add any attribute usage guards. 828 829 self._generateGuards(node) 830 831 # Visit the actual code. 832 833 self.dispatch(node.code) 834 835 # Add a return statement where one is not already produced. 836 837 if not isinstance(self.last_op(), Return): 838 839 # Return None for normal functions without explicit return 840 # statements. 841 842 if not fn.is_lambda(): 843 self.dispatch(compiler.ast.Name("None")) 844 845 self.new_op(Return()) 846 847 # Make sure that enough frame space is reserved from the start. 848 849 self.set_frame_usage(node, extend) 850 851 def _visitFunctionTupleParameters(self, fn, node, parameters=None): 852 853 """ 854 Visit the tuple parameters for function 'fn', obtaining the appropriate 855 elements from each supplied argument and assigning them to the specified 856 names for each parameter. 857 """ 858 859 if parameters is not None: 860 self._generateAttr(node, "__getitem__", self.attribute_load_instructions) 861 temp_getitem = self.optimiser.optimise_temp_storage() 862 863 for i, parameter in parameters or fn.tuple_parameters(): 864 865 # Either load the parameter from the frame. 866 867 if parameters is None: 868 self.new_op(LoadName(Attr(i, None, None))) 869 870 # Or load a value from the current collection. 871 872 else: 873 self._startCallFunc() 874 self.new_op(temp_getitem) 875 temp_target, target, temp_context = self._generateCallFunc([compiler.ast.Const(i)], node) 876 self._doCallFunc(temp_target, target) 877 self._endCallFunc() 878 879 # Where a tuple is the target, attempt to descend into the value 880 # obtained. 881 882 if isinstance(parameter, list): 883 self._visitFunctionTupleParameters(fn, node, parameter) 884 885 # Store the item in the namespace entry for the given name. 886 887 else: 888 self.record_value() 889 self.start_target() 890 self.new_op(StoreName(fn[parameter])) 891 self.assign_value() 892 self.discard_value() 893 894 if parameters is not None: 895 self.discard_temp(temp_getitem) 896 897 def _generateFunctionDefaults(self, function): 898 899 """ 900 Generate the default initialisation code for 'function', returning 901 a temporary storage reference if a dynamic object was created for the 902 function. 903 """ 904 905 attr_to_default = zip(function.default_attrs, function.defaults) 906 if not attr_to_default: 907 return None 908 909 # Where non-constant defaults are involved, construct a dynamic object 910 # to hold the defaults. 911 912 dynamic = function.is_dynamic() 913 914 if dynamic: 915 self.make_instance(self.get_builtin_class("function"), len(attr_to_default)) 916 temp = self.get_temp() 917 918 for attr, default in attr_to_default: 919 self.dispatch(default) 920 921 self.record_value() 922 self.start_target() 923 if dynamic: 924 self.new_op(temp) 925 self.new_op(StoreAttr(attr)) 926 else: 927 self.new_op(StoreAddress(attr)) 928 self.assign_value() 929 self.discard_value() 930 931 if dynamic: 932 return temp 933 else: 934 return None 935 936 def _storeName(self, node, name=None): 937 938 """ 939 A convenience method that stores the current working value using the 940 name provided by the given 'node' or the specified 'name' if provided. 941 """ 942 943 self.record_value() 944 self.start_target() 945 self._generateName(name or node.name, self.name_store_instructions, node) 946 self.assign_value() 947 self.discard_value() 948 949 def _visitName(self, node, classes): 950 951 """ 952 Visit the name-related 'node', generating instructions based on the 953 given 'classes'. 954 """ 955 956 name = node.name 957 self._generateName(name, classes, node) 958 959 def _generateName(self, name, classes, node): 960 961 """ 962 Generate code for the access to 'name' in 'scope' using the given 963 'classes', and using the given 'node' as the source of the access. 964 """ 965 966 NameInstruction, AddressInstruction, AddressContextInstruction = classes 967 968 # Get the expected scope of the name. 969 970 scope = getattr(node, "_scope", None) or self.get_scope(name) 971 972 # Handle names referring to constants. 973 974 if scope == "constant": 975 const = self.importer.get_predefined_constant(name) 976 self.new_op(LoadConst(const)) 977 978 # Handle all other names. 979 980 elif scope == "local": 981 unit = self.unit 982 if isinstance(unit, Function): 983 self.new_op(NameInstruction(unit.all_locals()[name])) 984 elif isinstance(unit, Class): 985 if AddressContextInstruction is not None: 986 self.new_op(LoadConst(unit)) 987 self.new_op(AddressContextInstruction(unit.all_class_attributes()[name])) 988 else: 989 self.new_op(AddressInstruction(unit.all_class_attributes()[name])) 990 elif isinstance(unit, Module): 991 self.new_op(AddressInstruction(unit.module_attributes()[name])) 992 else: 993 raise TranslateError("Program unit has no local %r." % name) 994 995 elif scope == "global": 996 globals = self.module.module_attributes() 997 if globals.has_key(name): 998 self.new_op(AddressInstruction(globals[name])) 999 else: 1000 raise TranslateError("Module has no attribute %r." % name) 1001 1002 elif scope == "builtins": 1003 self.new_op(AddressInstruction(self.get_builtin(name))) 1004 1005 else: 1006 # NOTE: This may happen because a class attribute is optimised away. 1007 print >>sys.stderr, "Program unit uses unknown name %r." % name 1008 1009 def _visitUnary(self, node): 1010 1011 """ 1012 Invoke the appropriate operator module function for the operation 1013 represented by 'node'. 1014 """ 1015 1016 temp_fn = self._getOperatorFunction(node) 1017 self._visitCall(node, temp_fn, (node.expr,)) 1018 self.discard_temp(temp_fn) 1019 1020 def _visitBinaryBit(self, node): 1021 1022 """ 1023 Need to impose binary rules over a sequence of nodes. The 1024 short-circuiting of the similar logical operators is not imposed by the 1025 bitwise operators. 1026 """ 1027 1028 temp_fn = self._getOperatorFunction(node) 1029 left = None 1030 1031 for right in node.nodes: 1032 if left is not None: 1033 self._visitCall(node, temp_fn, (left, right)) 1034 left = right 1035 1036 self.discard_temp(temp_fn) 1037 1038 def _visitBinary(self, node): 1039 1040 """ 1041 Invoke the appropriate operator module function for the operation 1042 represented by 'node'. 1043 """ 1044 1045 temp_fn = self._getOperatorFunction(node) 1046 self._visitCall(node, temp_fn, (node.left, node.right)) 1047 self.discard_temp(temp_fn) 1048 1049 def _visitCall(self, node, temp_fn, args): 1050 1051 """ 1052 Invoke the appropriate operator module function for the operation 1053 represented by 'node', given a 'temp_fn' reference to a function, along 1054 with the 'args' (the operand nodes). 1055 """ 1056 1057 # Evaluate and store the operands in temporary storage. 1058 1059 temp_list = [] 1060 1061 for arg in args: 1062 self.dispatch(arg) 1063 temp_list.append(self.optimiser.optimise_temp_storage()) 1064 1065 self._generateInvocation(temp_fn, temp_list) 1066 1067 # Compilation duties... 1068 1069 for temp in temp_list: 1070 self.discard_temp(temp) 1071 1072 def _generateInvocation(self, temp_fn, temp_list): 1073 1074 """ 1075 Invoke the function 'temp_fn' using the operands from 'temp_list' as 1076 arguments. 1077 """ 1078 1079 self._startCallFunc() 1080 1081 for i, temp in enumerate(temp_list): 1082 self.new_op(temp) 1083 self.new_op(StoreFrame(i)) 1084 1085 self._endCallFuncArgs(len(temp_list)) 1086 self._doCallFunc(temp_fn) 1087 self._endCallFunc(temp_fn) 1088 1089 def _getOperatorFunction(self, node, operator_name=None): 1090 1091 "Return an operator function reference for the given 'node'." 1092 1093 return self._generateOperatorFunction(operator_name or node.__class__.__name__) 1094 1095 def _getOperatorAugAssignFunction(self, node): 1096 1097 """ 1098 Return an operator augmented assignment function reference for the given 1099 'node'. 1100 """ 1101 1102 return self._generateOperatorFunction(node.op) 1103 1104 def _generateOperatorFunction(self, opname): 1105 1106 "Return an operator function reference for the given 'opname'." 1107 1108 operator_fn = operator_functions[opname] 1109 1110 # Get the operator module. 1111 1112 operator_module = self.importer.get_module("operator") 1113 1114 # Get the appropriate function from the operator module. 1115 1116 self.new_op(LoadAddress(operator_module[operator_fn])) 1117 return self.optimiser.optimise_temp_storage() 1118 1119 def _handleAttributeError(self, node, temp_method, handled_block): 1120 1121 """ 1122 Add exception handling to the method acquisition instructions where the 1123 attribute access cannot be resolved at compile-time. 1124 """ 1125 1126 if not (self.optimiser.should_optimise_known_target() and self.optimiser.is_constant_input(temp_method)): 1127 self.load_builtin("AttributeError", node) 1128 self.new_op(CheckException(target="status")) 1129 self.new_op(JumpIfTrue(handled_block, working="status")) 1130 self.new_op(RaiseException()) 1131 1132 def _generateTuple(self, node): 1133 1134 "Make a tuple using the given program 'node'." 1135 1136 # Reserve space for the elements themselves. 1137 1138 self.make_instance(self.get_builtin_class("tuple"), len(node.nodes)) 1139 temp = self.get_temp() 1140 1141 # Store using 0-based index values. 1142 1143 self._populateSequence(temp, node.nodes) 1144 1145 self.new_op(temp) 1146 self.discard_temp(temp) 1147 1148 def _generateList(self, node, nodes=None): 1149 1150 "Make a list using the given program 'node' and optional 'nodes'." 1151 1152 nodes = nodes or [] 1153 1154 # Make a fragment containing the list elements. 1155 1156 self.new_op(MakeFragment(len(nodes) + 1)) 1157 temp = self.get_temp() 1158 self._populateSequence(temp, nodes) 1159 self.new_op(temp) 1160 self.record_value() 1161 1162 # Reserve space for _elements (the fragment reference). 1163 1164 self.make_instance(self.get_builtin_class("list"), 1) 1165 list_temp = self.get_temp() 1166 1167 self.start_target() 1168 self.new_op(list_temp) 1169 self.new_op(StoreAttr(Attr(0, None, None))) # _elements is at position 0 1170 self.assign_value() 1171 self.discard_value() 1172 1173 self.new_op(list_temp) 1174 self.discard_temp(temp) 1175 self.discard_temp(list_temp) 1176 1177 def _populateSequence(self, temp, nodes, offset=0): 1178 1179 """ 1180 Populate a sequence using the given 'temp' reference and 'nodes'. 1181 """ 1182 1183 for i, n in enumerate(nodes): 1184 self.dispatch(n) 1185 self.record_value() 1186 self._storeInSequence(temp, i, offset) 1187 self.discard_value() 1188 1189 def _storeInSequence(self, temp, i, offset=0): 1190 1191 """ 1192 Store the current active value in the fragment referenced by 'temp' at 1193 position 'i' with the given starting 'offset'. 1194 """ 1195 1196 self.start_target() 1197 self.new_op(temp) 1198 self.new_op(StoreAttr(Attr(i + offset, None, None))) 1199 self.assign_value() 1200 1201 def _generateTestBoolean(self, node, temp): 1202 1203 """ 1204 Generate a test of the boolean status of the current value for the given 1205 program 'node'. 1206 """ 1207 1208 # Get method on temp. 1209 # NOTE: Using __bool__ instead of __nonzero__. 1210 1211 self._generateAttr(node, "__bool__", self.attribute_load_instructions) 1212 temp_method = self.optimiser.optimise_temp_storage() 1213 1214 self._generateInvocation(temp_method, (temp,)) 1215 1216 self.discard_temp(temp_method) 1217 1218 # Convert result to boolean (a StoreBoolean operation). 1219 1220 self.new_op(TestIdentityAddress(self.importer.get_predefined_constant("True"), target="status")) 1221 1222 def _generateLoadBoolean(self, node): 1223 1224 """ 1225 Generate instructions to load the appropriate value given the current 1226 boolean status. 1227 """ 1228 1229 false_block = self.get_block() 1230 true_block = self.new_block() 1231 end_block = self.new_block() 1232 1233 self.new_op(JumpIfTrue(true_block, working="status")) 1234 self.new_op(LoadConst(self.importer.get_predefined_constant("False"))) 1235 self.new_op(Jump(end_block)) 1236 1237 self.set_block(true_block) 1238 self.new_op(LoadConst(self.importer.get_predefined_constant("True"))) 1239 1240 self.set_block(end_block, [false_block, true_block]) 1241 1242 # Common AST operations. 1243 1244 def _startFor(self, node, else_=None): 1245 1246 """ 1247 Generate the start of a loop using the given 'node' and 'else_' clause, 1248 if defined. The iterator and next, exit and else blocks are returned. 1249 """ 1250 1251 next_handler_block = self.new_block() 1252 end_handler_block = self.new_block() 1253 exit_block = self.new_block() 1254 next_block = self.new_block() 1255 else_block = self.new_block() 1256 1257 temp_iterator = self._visitForList(node) 1258 1259 # In the loop... 1260 1261 self.set_block(next_block) 1262 1263 # Handle exceptions when calling "next"... 1264 1265 self.add_exception_blocks(next_handler_block, end_handler_block) 1266 self.new_op(PushHandler(next_handler_block)) 1267 1268 # Invoke the next method. 1269 1270 self._visitForNext(node, temp_iterator) 1271 1272 # Record the value to be assigned. 1273 1274 self.record_value() 1275 1276 # Skip the handler where the call was successful. 1277 1278 self.new_op(PopHandler(1)) 1279 self.new_op(Jump(end_handler_block)) 1280 1281 # Enter the exception handler. 1282 1283 self.set_block(next_handler_block) 1284 self.new_op(PopHandler(1)) 1285 1286 # Disable the handlers. 1287 1288 self.drop_exception_blocks() 1289 1290 # Test for StopIteration. 1291 1292 self.load_builtin("StopIteration", node) 1293 self.new_op(CheckException(target="status")) 1294 if else_ is not None: 1295 self.new_op(JumpIfTrue(else_block, working="status")) 1296 else: 1297 self.new_op(JumpIfTrue(exit_block, working="status")) 1298 1299 # Re-raise the exception otherwise. 1300 1301 self.new_op(RaiseException()) 1302 1303 # After the handler, clear the exception. 1304 1305 self.set_block(end_handler_block) 1306 1307 # Assign to the target. 1308 1309 self.dispatch(node.assign) 1310 self.discard_value() 1311 1312 # Process the body with the current next and exit points. 1313 1314 self.add_loop_blocks(next_block, exit_block) 1315 1316 return temp_iterator, next_block, exit_block, else_block 1317 1318 def _endFor(self, node, temp_iterator, next_block, exit_block, else_block=None, else_=None): 1319 1320 """ 1321 Generate the end of a loop for the given 'node' using the given 1322 'temp_iterator' and 'next_block', 'exit_block' and 'else_block' 1323 definitions, together with an 'else_' clause, if defined. 1324 """ 1325 1326 self.drop_loop_blocks() 1327 1328 # Repeat the loop. 1329 1330 self.new_op(Jump(next_block)) 1331 1332 # Produce the "else" section. 1333 1334 if else_ is not None: 1335 self.set_block(else_block) 1336 self.new_op(ClearException(target="exception")) 1337 self.dispatch(else_) 1338 1339 # After the loop... 1340 1341 self.set_block(exit_block) 1342 1343 else: 1344 # After the loop... 1345 1346 self.set_block(exit_block) 1347 self.new_op(ClearException(target="exception")) 1348 1349 # Compilation duties... 1350 1351 self.discard_temp(temp_iterator) 1352 1353 def _visitForList(self, node): 1354 1355 "Get the list to be iterated over, returning its iterator." 1356 1357 self._startCallFunc() 1358 self.dispatch(node.list) 1359 self._generateAttr(node, "__iter__", self.attribute_load_instructions) 1360 temp_target, target, temp_context = self._generateCallFunc([], node) 1361 self._doCallFunc(temp_target, target) 1362 self._endCallFunc(temp_target, temp_context) 1363 1364 # Use a long-lasting temporary storage slot, since any result from the 1365 # __iter__ method will not remain around for long. 1366 1367 return self.get_temp() 1368 1369 def _visitForNext(self, node, temp_iterator): 1370 1371 "Use the iterator to get the next value." 1372 1373 self._startCallFunc() 1374 self.new_op(temp_iterator) 1375 self._generateAttr(node, "next", self.attribute_load_instructions) 1376 temp_target, target, temp_context = self._generateCallFunc([], node) 1377 self._doCallFunc(temp_target, target) 1378 self._endCallFunc(temp_target, temp_context) 1379 1380 def _visitPrint(self, node, function_name): 1381 self._startCallFunc() 1382 self.load_builtin(function_name, node) 1383 1384 args = [node.dest or compiler.ast.Name("None")] + node.nodes 1385 1386 temp_target, target, temp_context = self._generateCallFunc(args, node) 1387 self._doCallFunc(temp_target, target) 1388 self._endCallFunc(temp_target, temp_context) 1389 1390 def _visitImport(self, node): 1391 1392 """ 1393 Although imported code already resides in any generated image, the 1394 module code must be executed. Module code uses its own frame for any 1395 temporary storage and thus behaves like a function. 1396 """ 1397 1398 modules = self.importer.importers.get(node) 1399 if modules: 1400 for module in modules: 1401 self.new_op(MakeFrame(0)) 1402 self.new_op(LoadConst(module)) 1403 self.new_op(LoadCallable()) 1404 self.new_op(JumpWithFrame()) 1405 self.new_op(DropFrame()) 1406 1407 def _importName(self, module, name, alias, node): 1408 1409 # Get the source of the name. 1410 1411 attr = module[name] 1412 self.new_op(LoadAddress(attr)) 1413 1414 # Record the object in the current namespace. 1415 1416 self.record_value() 1417 1418 self.start_target() 1419 self._generateName(alias or name, self.name_store_instructions, node) # AssName equivalent 1420 self.assign_value() 1421 self.discard_value() 1422 1423 # vim: tabstop=4 expandtab shiftwidth=4