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