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