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