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