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