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