479 ]. |
385 ]. |
480 ]. |
386 ]. |
481 ^ nil |
387 ^ nil |
482 ! ! |
388 ! ! |
483 |
389 |
484 !MessageNode methodsFor:'evaluating'! |
390 !MessageNode methodsFor:'code generation'! |
485 |
391 |
486 evaluate |
392 XXcodeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
487 |r nargs argValueArray class| |
393 "generate code for [...] whilexxx:[ ... ]" |
488 |
394 |
|
395 |pos pos2 theReceiver theArg theByteCode optByteCode| |
|
396 |
|
397 (selector == #whileTrue:) ifTrue:[ |
|
398 theByteCode := #falseJump |
|
399 ] ifFalse:[ |
|
400 theByteCode := #trueJump |
|
401 ]. |
|
402 |
|
403 theReceiver := receiver. |
|
404 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
|
405 optByteCode notNil ifTrue:[ |
|
406 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
407 theArg := receiver statements expression arg1 |
|
408 ]. |
|
409 theReceiver := receiver statements expression receiver. |
|
410 theByteCode := optByteCode |
|
411 ]. |
|
412 |
|
413 valueNeeded ifTrue:[aStream nextPut:#pushNil]. |
|
414 pos := aStream position. |
|
415 optByteCode notNil ifTrue:[ |
|
416 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
417 theArg notNil ifTrue:[ |
|
418 theArg codeOn:aStream inBlock:b for:aCompiler |
|
419 ] |
|
420 ] ifFalse:[ |
|
421 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler |
|
422 ]. |
|
423 |
|
424 (lineNr between:1 and:255) ifTrue:[ |
|
425 aStream nextPut:#lineno; nextPut:lineNr. |
|
426 ]. |
|
427 |
|
428 aStream nextPut:theByteCode. |
|
429 pos2 := aStream position. |
|
430 aStream nextPut:0. |
|
431 valueNeeded ifTrue:[aStream nextPut:#drop]. |
|
432 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
433 aStream nextPut:#jump; nextPut:pos. |
|
434 (aStream contents) at:pos2 put:(aStream position). |
|
435 ! |
|
436 |
|
437 codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
438 "generate code for (x and:[y]) ifxxx:[ ... ]" |
|
439 |
|
440 |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp| |
|
441 |
|
442 |
|
443 theByteCode := #falseJump. |
|
444 theReceiver := receiver receiver. |
|
445 |
|
446 optByteCode := self optimizedConditionFor:theReceiver |
|
447 with:theByteCode. |
|
448 optByteCode notNil ifTrue:[ |
|
449 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
450 theArg := theReceiver arg1 |
|
451 ]. |
|
452 theReceiver := theReceiver receiver. |
|
453 theByteCode := optByteCode |
|
454 ]. |
|
455 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
456 theArg notNil ifTrue:[ |
|
457 theArg codeOn:aStream inBlock:b for:aCompiler |
|
458 ]. |
|
459 aStream nextPut:theByteCode. |
|
460 pos1 := aStream position. |
|
461 aStream nextPut:0. |
|
462 |
|
463 theReceiver := receiver arg1. |
|
464 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler. |
|
465 (selector == #ifTrue:) ifTrue:[ |
|
466 jmp := #falseJump |
|
467 ] ifFalse:[ |
|
468 jmp := #trueJump |
|
469 ]. |
|
470 aStream nextPut:jmp. |
|
471 pos2 := aStream position. |
|
472 aStream nextPut:0. |
|
473 |
|
474 code := aStream contents. |
|
475 (selector == #ifFalse:) ifTrue:[ |
|
476 code at:pos1 put:(aStream position) |
|
477 ]. |
|
478 (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
479 |
|
480 valueNeeded ifTrue:[ |
|
481 aStream nextPut:#jump. |
|
482 pos3 := aStream position. |
|
483 aStream nextPut:0. |
|
484 here := aStream position. |
|
485 (selector == #ifTrue:) ifTrue:[ |
|
486 code at:pos1 put:here |
|
487 ]. |
|
488 code at:pos2 put:here. |
|
489 aStream nextPut:#pushNil. |
|
490 code at:pos3 put:(aStream position) |
|
491 ] ifFalse:[ |
|
492 here := aStream position. |
|
493 (selector == #ifTrue:) ifTrue:[ |
|
494 code at:pos1 put:here |
|
495 ]. |
|
496 code at:pos2 put:here |
|
497 ] |
|
498 ! |
|
499 |
|
500 codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
501 "generate code for x and/or:[y] - but not in an if" |
|
502 |
|
503 |pos theReceiver theByteCode| |
|
504 |
|
505 self halt. |
|
506 theReceiver := receiver. |
|
507 (selector == #and:) ifTrue:[ |
|
508 theByteCode := #falseJump |
|
509 ] ifFalse:[ |
|
510 theByteCode := #trueJump |
|
511 ]. |
|
512 " |
|
513 (self canOptimizeConditionFor:receiver) ifTrue:[ |
|
514 theByteCode := self optimizedConditionFor:theReceiver |
|
515 with:theByteCode. |
|
516 theReceiver := theReceiver receiver |
|
517 ]. |
|
518 " |
|
519 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
520 aStream nextPut:theByteCode. |
|
521 pos := aStream position. |
|
522 aStream nextPut:0. |
|
523 (argArray at: 1) codeInlineOn:aStream inBlock:b for:aCompiler. |
|
524 (aStream contents) at:pos put:(aStream position). |
|
525 valueNeeded ifFalse:[aStream nextPut:#drop] |
|
526 ! |
|
527 |
|
528 codeForCascadeOn:aStream inBlock:b for:aCompiler |
|
529 "like codeOn, but always leave the receiver instead of the result" |
|
530 |
|
531 |nargs isBuiltIn code litIndex| |
|
532 |
|
533 argArray isNil ifTrue:[ |
|
534 nargs := 0 |
|
535 ] ifFalse:[ |
|
536 nargs := argArray size |
|
537 ]. |
|
538 |
|
539 isBuiltIn := false. |
|
540 |
|
541 (nargs == 0) ifTrue:[ |
|
542 isBuiltIn := self class isBuiltInUnarySelector:selector |
|
543 ]. |
|
544 (nargs == 1) ifTrue:[ |
|
545 isBuiltIn := self class isBuiltIn1ArgSelector:selector |
|
546 ]. |
|
547 (nargs == 2) ifTrue:[ |
|
548 isBuiltIn := self class isBuiltIn2ArgSelector:selector |
|
549 ]. |
|
550 |
|
551 receiver codeOn:aStream inBlock:b for:aCompiler. |
|
552 aStream nextPut:#dup. |
|
553 |
|
554 "can we use a send-bytecode ?" |
|
555 isBuiltIn ifTrue:[ |
|
556 receiver isSuper ifFalse:[ |
|
557 (nargs > 0) ifTrue:[ |
|
558 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. |
|
559 (nargs > 1) ifTrue:[ |
|
560 (argArray at:2) codeOn:aStream inBlock:b for:aCompiler |
|
561 ] |
|
562 ]. |
|
563 aStream nextPut:selector. |
|
564 (self class hasLineNumber:selector) ifTrue:[ |
|
565 aStream nextPut:lineNr. |
|
566 ]. |
|
567 aStream nextPut:#drop. |
|
568 ^ self |
|
569 ] |
|
570 ]. |
|
571 |
|
572 "no - generate a send" |
|
573 argArray notNil ifTrue:[ |
|
574 argArray do:[:arg | |
|
575 arg codeOn:aStream inBlock:b for:aCompiler |
|
576 ] |
|
577 ]. |
|
578 litIndex := aCompiler addLiteral:selector. |
|
579 litIndex <= 255 ifTrue:[ |
|
580 receiver isSuper ifTrue:[ |
|
581 receiver isHere ifTrue:[ |
|
582 code := #hereSend |
|
583 ] ifFalse:[ |
|
584 code := #superSend. |
|
585 ]. |
|
586 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil; nextPut:#drop. |
|
587 ^ self |
|
588 ]. |
|
589 (nargs <= 3) ifTrue:[ |
|
590 code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1). |
|
591 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex. |
|
592 ^ self |
|
593 ]. |
|
594 |
|
595 aStream nextPut:#sendDrop; nextPut:lineNr; nextPut:litIndex; nextPut:nargs. |
|
596 ^ self |
|
597 ]. |
|
598 "need 16bit litIndex" |
489 receiver isSuper ifTrue:[ |
599 receiver isSuper ifTrue:[ |
490 r := receiver value. |
|
491 receiver isHere ifTrue:[ |
600 receiver isHere ifTrue:[ |
492 class := receiver definingClass. |
601 code := #hereSendL |
493 ] ifFalse:[ |
602 ] ifFalse:[ |
494 class := receiver definingClass superclass. |
603 code := #superSendL. |
495 ]. |
604 ]. |
496 argArray notNil ifTrue:[ |
605 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil; nextPut:#drop. |
497 argValueArray := argArray collect:[:arg | arg evaluate]. |
606 ^ self |
498 ] ifFalse:[ |
607 ]. |
499 argValueArray := #() |
608 aStream nextPut:#sendDropL; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs |
500 ]. |
609 ! |
501 ^ r perform:selector inClass:class withArguments:argValueArray |
|
502 ]. |
|
503 |
|
504 |
|
505 argArray isNil ifTrue:[ |
|
506 ^ (receiver evaluate) perform:selector |
|
507 ]. |
|
508 nargs := argArray size. |
|
509 (nargs == 1) ifTrue:[ |
|
510 ^ (receiver evaluate) perform:selector with:(argArray at:1) evaluate |
|
511 ]. |
|
512 (nargs == 2) ifTrue:[ |
|
513 ^ (receiver evaluate) perform:selector |
|
514 with:(argArray at:1) evaluate |
|
515 with:(argArray at:2) evaluate |
|
516 ]. |
|
517 (nargs == 3) ifTrue:[ |
|
518 ^ (receiver evaluate) perform:selector |
|
519 with:(argArray at:1) evaluate |
|
520 with:(argArray at:2) evaluate |
|
521 with:(argArray at:3) evaluate |
|
522 ]. |
|
523 r := receiver evaluate. |
|
524 argValueArray := argArray collect:[:arg | arg evaluate]. |
|
525 ^ r perform:selector withArguments:argValueArray |
|
526 ! |
|
527 |
|
528 evaluateForCascade |
|
529 |r nargs argValueArray class| |
|
530 |
|
531 receiver isSuper ifTrue:[ |
|
532 r := receiver value. |
|
533 class := receiver definingClass. |
|
534 receiver isHere ifFalse:[ |
|
535 class := class superclass. |
|
536 ]. |
|
537 argArray notNil ifTrue:[ |
|
538 argValueArray := argArray collect:[:arg | arg evaluate]. |
|
539 ] ifFalse:[ |
|
540 argValueArray := #() |
|
541 ]. |
|
542 r perform:selector inClass:class withArguments:argValueArray. |
|
543 ^ r |
|
544 ]. |
|
545 |
|
546 r := receiver evaluate. |
|
547 argArray isNil ifTrue:[ |
|
548 r perform:selector. |
|
549 ^ r |
|
550 ]. |
|
551 nargs := argArray size. |
|
552 (nargs == 1) ifTrue:[ |
|
553 r perform:selector with:(argArray at:1) evaluate. |
|
554 ^ r |
|
555 ]. |
|
556 (nargs == 2) ifTrue:[ |
|
557 r perform:selector with:(argArray at:1) evaluate |
|
558 with:(argArray at:2) evaluate. |
|
559 ^ r |
|
560 ]. |
|
561 (nargs == 3) ifTrue:[ |
|
562 r perform:selector with:(argArray at:1) evaluate |
|
563 with:(argArray at:2) evaluate |
|
564 with:(argArray at:3) evaluate. |
|
565 ^ r |
|
566 ]. |
|
567 argValueArray := argArray collect:[:arg | arg evaluate]. |
|
568 r perform:selector withArguments:argValueArray. |
|
569 ^ r |
|
570 ! ! |
|
571 |
|
572 !MessageNode methodsFor:'code generation'! |
|
573 |
610 |
574 codeForSideEffectOn:aStream inBlock:b for:aCompiler |
611 codeForSideEffectOn:aStream inBlock:b for:aCompiler |
575 self codeOn:aStream inBlock:b valueNeeded:false for:aCompiler |
612 self codeOn:aStream inBlock:b valueNeeded:false for:aCompiler |
576 ! |
613 ! |
577 |
614 |
|
615 codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
616 "generate code for x ifxxx:[ ... ] yyy:[ ...]" |
|
617 |
|
618 |pos pos2 theReceiver theArg theByteCode optByteCode subsel code| |
|
619 |
|
620 theReceiver := receiver. |
|
621 |
|
622 " |
|
623 (theReceiver isMessage) ifTrue:[ |
|
624 subsel := theReceiver selector. |
|
625 (subsel == #and:) ifTrue:[ |
|
626 self codeAndIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
627 ^ self |
|
628 ]. |
|
629 (subsel == #or:) ifTrue:[ |
|
630 self codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
631 ^ self |
|
632 ] |
|
633 ]. |
|
634 " |
|
635 (selector == #ifTrue:ifFalse:) ifTrue:[ |
|
636 theByteCode := #falseJump |
|
637 ] ifFalse:[ |
|
638 (selector == #ifFalse:ifTrue:) ifTrue:[ |
|
639 theByteCode := #trueJump |
|
640 ] |
|
641 ]. |
|
642 optByteCode := self optimizedConditionFor:theReceiver |
|
643 with:theByteCode. |
|
644 optByteCode notNil ifTrue:[ |
|
645 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
646 theArg := theReceiver arg1 |
|
647 ]. |
|
648 theReceiver := theReceiver receiver. |
|
649 theByteCode := optByteCode |
|
650 ]. |
|
651 theByteCode notNil ifTrue:[ |
|
652 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
653 theArg notNil ifTrue:[ |
|
654 theArg codeOn:aStream inBlock:b for:aCompiler |
|
655 ]. |
|
656 |
|
657 (lineNr between:1 and:255) ifTrue:[ |
|
658 aStream nextPut:#lineno; nextPut:lineNr. |
|
659 ]. |
|
660 |
|
661 aStream nextPut:theByteCode. |
|
662 pos := aStream position. |
|
663 aStream nextPut:0. |
|
664 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
665 aStream nextPut:#jump. |
|
666 pos2 := aStream position. |
|
667 aStream nextPut:0. |
|
668 code := aStream contents. |
|
669 code at:pos put:(aStream position). |
|
670 (argArray at:2) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
671 code at:pos2 put:(aStream position) |
|
672 ] |
|
673 ! |
|
674 |
|
675 codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
676 "generate code for x ifxxx:[ ... ]" |
|
677 |
|
678 |pos pos2 theReceiver theArg theByteCode optByteCode subsel code |
|
679 needLineNr| |
|
680 |
|
681 theReceiver := receiver. |
|
682 |
|
683 (theReceiver isMessage) ifTrue:[ |
|
684 subsel := theReceiver selector. |
|
685 (subsel == #and:) ifTrue:[ |
|
686 self codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
687 ^ self |
|
688 ]. |
|
689 (subsel == #or:) ifTrue:[ |
|
690 self codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
691 ^ self |
|
692 ] |
|
693 ]. |
|
694 (selector == #ifTrue:) ifTrue:[ |
|
695 theByteCode := #falseJump |
|
696 ] ifFalse:[ |
|
697 theByteCode := #trueJump |
|
698 ]. |
|
699 optByteCode := self optimizedConditionFor:theReceiver |
|
700 with:theByteCode. |
|
701 optByteCode notNil ifTrue:[ |
|
702 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
703 theArg := theReceiver arg1 |
|
704 ]. |
|
705 theReceiver := theReceiver receiver. |
|
706 theByteCode := optByteCode |
|
707 ]. |
|
708 |
|
709 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
710 theArg notNil ifTrue:[ |
|
711 theArg codeOn:aStream inBlock:b for:aCompiler |
|
712 ]. |
|
713 |
|
714 needLineNr := true. |
|
715 theArg isNil ifTrue:[ |
|
716 theReceiver isMessage ifTrue:[ |
|
717 (self class hasLineNumber:(theReceiver selector)) ifTrue:[ |
|
718 theReceiver lineNumber == lineNr ifTrue:[ |
|
719 needLineNr := false |
|
720 ] |
|
721 ] |
|
722 ] |
|
723 ]. |
|
724 |
|
725 needLineNr ifTrue:[ |
|
726 (lineNr between:1 and:255) ifTrue:[ |
|
727 aStream nextPut:#lineno; nextPut:lineNr. |
|
728 ] |
|
729 ]. |
|
730 |
|
731 aStream nextPut:theByteCode. |
|
732 pos := aStream position. |
|
733 aStream nextPut:0. |
|
734 (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
735 |
|
736 code := aStream contents. |
|
737 valueNeeded ifTrue:[ |
|
738 aStream nextPut:#jump. |
|
739 pos2 := aStream position. |
|
740 aStream nextPut:0. |
|
741 code at:pos put:(aStream position). |
|
742 aStream nextPut:#pushNil. |
|
743 code at:pos2 put:(aStream position) |
|
744 ] ifFalse:[ |
|
745 code at:pos put:(aStream position) |
|
746 ] |
|
747 ! |
|
748 |
578 codeOn:aStream inBlock:b for:aCompiler |
749 codeOn:aStream inBlock:b for:aCompiler |
579 self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler |
750 self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler |
|
751 ! |
|
752 |
|
753 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
754 |recType nargs isBuiltIn litIndex cls clsLitIndex code| |
|
755 |
|
756 argArray isNil ifTrue:[ |
|
757 nargs := 0 |
|
758 ] ifFalse:[ |
|
759 nargs := argArray size |
|
760 ]. |
|
761 |
|
762 isBuiltIn := false. |
|
763 recType := receiver type. |
|
764 |
|
765 (nargs == 0) ifTrue:[ |
|
766 (recType == #ThisContext) ifTrue:[ |
|
767 valueNeeded ifFalse:[ |
|
768 "for now, only do it in methods" |
|
769 b isNil ifTrue:[ |
|
770 (selector == #restart) ifTrue:[ |
|
771 aStream nextPut:#jump; nextPut:1. "jump to start" |
|
772 ^ self |
|
773 ]. |
|
774 ]. |
|
775 (selector == #return) ifTrue:[ "^ nil" |
|
776 aStream nextPut:#retNil. |
|
777 ^ self |
|
778 ]. |
|
779 ] |
|
780 ]. |
|
781 |
|
782 receiver isBlock ifTrue:[ |
|
783 selector == #value ifTrue:[ |
|
784 receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
785 ^ self |
|
786 ]. |
|
787 ]. |
|
788 isBuiltIn := self class isBuiltInUnarySelector:selector |
|
789 ]. |
|
790 |
|
791 (nargs == 1) ifTrue:[ |
|
792 (recType == #ThisContext) ifTrue:[ |
|
793 valueNeeded ifFalse:[ |
|
794 (selector == #return:) ifTrue:[ |
|
795 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. "^ value" |
|
796 aStream nextPut:#retTop. |
|
797 ^ self |
|
798 ]. |
|
799 ]. |
|
800 ]. |
|
801 |
|
802 ((argArray at:1) isBlock) ifTrue:[ |
|
803 ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[ |
|
804 receiver isBlock ifFalse:[ |
|
805 self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
806 ^ self |
|
807 ]. |
|
808 ]. |
|
809 " |
|
810 ((selector == #and:) or:[selector == #or:]) ifTrue:[ |
|
811 self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
812 ^ self |
|
813 ]. |
|
814 " |
|
815 (selector == #timesRepeat:) ifTrue:[ |
|
816 (receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[ |
|
817 self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
818 ^ self |
|
819 ] |
|
820 ]. |
|
821 |
|
822 ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[ |
|
823 (receiver isBlock) ifTrue:[ |
|
824 self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
825 ^ self |
|
826 ] |
|
827 ] |
|
828 ]. |
|
829 isBuiltIn := self class isBuiltIn1ArgSelector:selector |
|
830 ]. |
|
831 |
|
832 (nargs == 2) ifTrue:[ |
|
833 ((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[ |
|
834 receiver isBlock ifFalse:[ |
|
835 (argArray at:1) isBlock ifTrue:[ |
|
836 (argArray at:2) isBlock ifTrue:[ |
|
837 self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
838 ^ self |
|
839 ] |
|
840 ] |
|
841 ] |
|
842 ]. |
|
843 isBuiltIn := self class isBuiltIn2ArgSelector:selector |
|
844 ]. |
|
845 |
|
846 "can we use a send-bytecode ?" |
|
847 isBuiltIn ifTrue:[ |
|
848 receiver isSuper ifFalse:[ |
|
849 receiver codeOn:aStream inBlock:b for:aCompiler. |
|
850 (nargs > 0) ifTrue:[ |
|
851 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. |
|
852 (nargs > 1) ifTrue:[ |
|
853 (argArray at:2) codeOn:aStream inBlock:b for:aCompiler |
|
854 ] |
|
855 ]. |
|
856 aStream nextPut:selector. |
|
857 (self class hasLineNumber:selector) ifTrue:[ |
|
858 aStream nextPut:lineNr. |
|
859 ]. |
|
860 valueNeeded ifFalse:[ |
|
861 aStream nextPut:#drop |
|
862 ]. |
|
863 ^ self |
|
864 ] |
|
865 ]. |
|
866 |
|
867 ((nargs == 0) and:[selector == #yourself]) ifTrue:[ |
|
868 "yourself is often added to get the receiver - |
|
869 we get it without the yourself-message" |
|
870 |
|
871 valueNeeded ifTrue:[ |
|
872 receiver codeOn:aStream inBlock:b for:aCompiler |
|
873 ]. |
|
874 ^ self |
|
875 ]. |
|
876 |
|
877 "no - generate a send" |
|
878 |
|
879 receiver isSuper ifTrue:[ |
|
880 cls := aCompiler targetClass. |
|
881 receiver isHere ifTrue:[ |
|
882 code := #hereSend. |
|
883 ] ifFalse:[ |
|
884 code := #superSend. |
|
885 cls := cls superclass. |
|
886 ]. |
|
887 clsLitIndex := aCompiler addLiteral:cls. |
|
888 ] ifFalse:[ |
|
889 clsLitIndex := 0. |
|
890 ]. |
|
891 |
|
892 litIndex := aCompiler addLiteral:selector. |
|
893 (litIndex <= 255 and:[clsLitIndex <= 255]) ifTrue:[ |
|
894 (recType ~~ #Self) ifTrue:[ |
|
895 receiver codeOn:aStream inBlock:b for:aCompiler |
|
896 ]. |
|
897 argArray notNil ifTrue:[ |
|
898 argArray do:[:arg | |
|
899 arg codeOn:aStream inBlock:b for:aCompiler |
|
900 ] |
|
901 ]. |
|
902 |
|
903 receiver isSuper ifTrue:[ |
|
904 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex. |
|
905 valueNeeded ifFalse:[ |
|
906 aStream nextPut:#drop |
|
907 ]. |
|
908 ^ self |
|
909 ]. |
|
910 |
|
911 (nargs <= 3) ifTrue:[ |
|
912 |codes| |
|
913 |
|
914 valueNeeded ifTrue:[ |
|
915 (receiver type == #Self) ifTrue:[ |
|
916 codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3) |
|
917 ] ifFalse:[ |
|
918 codes := #(send0 send1 send2 send3) |
|
919 ] |
|
920 ] ifFalse:[ |
|
921 (receiver type == #Self) ifTrue:[ |
|
922 codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3) |
|
923 ] ifFalse:[ |
|
924 codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) |
|
925 ] |
|
926 ]. |
|
927 aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex. |
|
928 ^ self |
|
929 ]. |
|
930 |
|
931 (recType == #Self) ifTrue:[ |
|
932 code := #sendSelf |
|
933 ] ifFalse:[ |
|
934 valueNeeded ifTrue:[ |
|
935 code := #send |
|
936 ] ifFalse:[ |
|
937 code := #sendDrop |
|
938 ] |
|
939 ]. |
|
940 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs. |
|
941 valueNeeded ifFalse:[ |
|
942 (recType == #Self) ifTrue:[ |
|
943 aStream nextPut:#drop |
|
944 ] |
|
945 ]. |
|
946 ^ self |
|
947 ]. |
|
948 |
|
949 "needs 16bit literal index" |
|
950 |
|
951 receiver isSuper ifTrue:[ |
|
952 argArray notNil ifTrue:[ |
|
953 argArray do:[:arg | |
|
954 arg codeOn:aStream inBlock:b for:aCompiler |
|
955 ] |
|
956 ]. |
|
957 receiver isHere ifTrue:[ |
|
958 code := #hereSendL |
|
959 ] ifFalse:[ |
|
960 code := #superSendL. |
|
961 ]. |
|
962 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0. |
|
963 ] ifFalse:[ |
|
964 recType ~~ #Self ifTrue:[ |
|
965 receiver codeOn:aStream inBlock:b for:aCompiler. |
|
966 ]. |
|
967 argArray notNil ifTrue:[ |
|
968 argArray do:[:arg | |
|
969 arg codeOn:aStream inBlock:b for:aCompiler |
|
970 ] |
|
971 ]. |
|
972 |
|
973 recType == #Self ifTrue:[ |
|
974 code := #sendSelfL |
|
975 ] ifFalse:[ |
|
976 code := #sendL |
|
977 ]. |
|
978 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs. |
|
979 ]. |
|
980 valueNeeded ifFalse:[ |
|
981 aStream nextPut:#drop |
|
982 ]. |
|
983 |
|
984 "Modified: 3.9.1995 / 12:55:42 / claus" |
|
985 ! |
|
986 |
|
987 codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
988 "generate code for (x or:[y]) ifxxx:[ ... ]" |
|
989 |
|
990 |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp| |
|
991 |
|
992 theByteCode := #trueJump. |
|
993 theReceiver := receiver receiver. |
|
994 |
|
995 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
|
996 optByteCode notNil ifTrue:[ |
|
997 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
998 theArg := theReceiver arg1 |
|
999 ]. |
|
1000 theReceiver := theReceiver receiver. |
|
1001 theByteCode := optByteCode |
|
1002 ]. |
|
1003 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
1004 theArg notNil ifTrue:[ |
|
1005 theArg codeOn:aStream inBlock:b for:aCompiler |
|
1006 ]. |
|
1007 aStream nextPut:theByteCode. |
|
1008 pos1 := aStream position. |
|
1009 aStream nextPut:0. |
|
1010 |
|
1011 |
|
1012 theReceiver := receiver arg1. |
|
1013 |
|
1014 "new:" |
|
1015 (selector == #ifTrue:) ifTrue:[ |
|
1016 theByteCode := #falseJump |
|
1017 ] ifFalse:[ |
|
1018 theByteCode := #trueJump |
|
1019 ]. |
|
1020 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
|
1021 optByteCode notNil ifTrue:[ |
|
1022 theReceiver isBlock ifTrue:[ |
|
1023 theReceiver := theReceiver statements expression |
|
1024 ]. |
|
1025 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
1026 theArg := theReceiver arg1 |
|
1027 ]. |
|
1028 theReceiver := theReceiver receiver. |
|
1029 theByteCode := optByteCode. |
|
1030 |
|
1031 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
1032 theArg notNil ifTrue:[ |
|
1033 theArg codeOn:aStream inBlock:b for:aCompiler |
|
1034 ]. |
|
1035 aStream nextPut:theByteCode. |
|
1036 |
|
1037 ] ifFalse:[ |
|
1038 "org" |
|
1039 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler. |
|
1040 (selector == #ifTrue:) ifTrue:[ |
|
1041 jmp := #falseJump |
|
1042 ] ifFalse:[ |
|
1043 jmp := #trueJump |
|
1044 ]. |
|
1045 aStream nextPut:jmp |
|
1046 ]. |
|
1047 pos2 := aStream position. |
|
1048 aStream nextPut:0. |
|
1049 (selector == #ifTrue:) ifTrue:[ |
|
1050 (aStream contents) at:pos1 put:(aStream position) |
|
1051 ]. |
|
1052 (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1053 |
|
1054 code := aStream contents. |
|
1055 valueNeeded ifTrue:[ |
|
1056 aStream nextPut:#jump. |
|
1057 pos3 := aStream position. |
|
1058 aStream nextPut:0. |
|
1059 here := aStream position. |
|
1060 (selector == #ifFalse:) ifTrue:[ |
|
1061 code at:pos1 put:here |
|
1062 ]. |
|
1063 code at:pos2 put:here. |
|
1064 aStream nextPut:#pushNil. |
|
1065 code at:pos3 put:(aStream position) |
|
1066 ] ifFalse:[ |
|
1067 here := aStream position. |
|
1068 (selector == #ifFalse:) ifTrue:[ |
|
1069 code at:pos1 put:here |
|
1070 ]. |
|
1071 code at:pos2 put:here |
|
1072 ] |
|
1073 ! |
|
1074 |
|
1075 codeSendOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
1076 "like code on, but assumes that receiver has already been |
|
1077 coded onto stack - needed for cascade" |
|
1078 |
|
1079 |nargs isBuiltIn code litIndex| |
|
1080 |
|
1081 argArray isNil ifTrue:[ |
|
1082 nargs := 0 |
|
1083 ] ifFalse:[ |
|
1084 nargs := argArray size |
|
1085 ]. |
|
1086 |
|
1087 isBuiltIn := false. |
|
1088 |
|
1089 (nargs == 0) ifTrue:[ |
|
1090 isBuiltIn := self class isBuiltInUnarySelector:selector |
|
1091 ]. |
|
1092 (nargs == 1) ifTrue:[ |
|
1093 isBuiltIn := self class isBuiltIn1ArgSelector:selector |
|
1094 ]. |
|
1095 (nargs == 2) ifTrue:[ |
|
1096 isBuiltIn := self class isBuiltIn2ArgSelector:selector |
|
1097 ]. |
|
1098 |
|
1099 "can we use a send-bytecode ?" |
|
1100 isBuiltIn ifTrue:[ |
|
1101 receiver isSuper ifFalse:[ |
|
1102 (nargs > 0) ifTrue:[ |
|
1103 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. |
|
1104 (nargs > 1) ifTrue:[ |
|
1105 (argArray at:2) codeOn:aStream inBlock:b for:aCompiler |
|
1106 ] |
|
1107 ]. |
|
1108 aStream nextPut:selector. |
|
1109 (self class hasLineNumber:selector) ifTrue:[ |
|
1110 aStream nextPut:lineNr. |
|
1111 ]. |
|
1112 valueNeeded ifFalse:[ |
|
1113 aStream nextPut:#drop |
|
1114 ]. |
|
1115 ^ self |
|
1116 ] |
|
1117 ]. |
|
1118 |
|
1119 argArray notNil ifTrue:[ |
|
1120 argArray do:[:arg | |
|
1121 arg codeOn:aStream inBlock:b for:aCompiler |
|
1122 ] |
|
1123 ]. |
|
1124 |
|
1125 receiver isSuper ifTrue:[ |
|
1126 litIndex := aCompiler addLiteral:selector. |
|
1127 litIndex <= 255 ifTrue:[ |
|
1128 receiver isHere ifTrue:[ |
|
1129 code := #hereSend |
|
1130 ] ifFalse:[ |
|
1131 code := #superSend. |
|
1132 ]. |
|
1133 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil. |
|
1134 ] ifFalse:[ |
|
1135 receiver isHere ifTrue:[ |
|
1136 code := #hereSendL |
|
1137 ] ifFalse:[ |
|
1138 code := #superSendL. |
|
1139 ]. |
|
1140 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil. |
|
1141 ]. |
|
1142 valueNeeded ifFalse:[ |
|
1143 aStream nextPut:#drop |
|
1144 ]. |
|
1145 ^ self |
|
1146 ]. |
|
1147 (nargs == 0) ifTrue:[ |
|
1148 (selector == #yourself) ifTrue:[ |
|
1149 "yourself is often added to get the receiver - |
|
1150 we get it without the yourself-message" |
|
1151 |
|
1152 valueNeeded ifFalse:[ |
|
1153 aStream nextPut:#drop |
|
1154 ]. |
|
1155 ^ self |
|
1156 ]. |
|
1157 ]. |
|
1158 |
|
1159 litIndex := aCompiler addLiteral:selector. |
|
1160 litIndex <= 255 ifTrue:[ |
|
1161 (nargs <= 3) ifTrue:[ |
|
1162 valueNeeded ifTrue:[ |
|
1163 code := #(send0 send1 send2 send3) at:(nargs+1). |
|
1164 ] ifFalse:[ |
|
1165 code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1). |
|
1166 ]. |
|
1167 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex. |
|
1168 ^ self |
|
1169 ]. |
|
1170 |
|
1171 valueNeeded ifTrue:[ |
|
1172 code := #send |
|
1173 ] ifFalse:[ |
|
1174 code := #sendDrop |
|
1175 ]. |
|
1176 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs. |
|
1177 ^ self |
|
1178 ]. |
|
1179 |
|
1180 valueNeeded ifTrue:[ |
|
1181 code := #sendL |
|
1182 ] ifFalse:[ |
|
1183 code := #sendDropL |
|
1184 ]. |
|
1185 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs |
|
1186 ! |
|
1187 |
|
1188 codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
1189 "generate code for n timesRepeat:[ ... ]" |
|
1190 |
|
1191 |pos pos2 theReceiver| |
|
1192 |
|
1193 theReceiver := receiver. |
|
1194 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
1195 valueNeeded ifTrue:[aStream nextPut:#dup]. |
|
1196 |
|
1197 pos := aStream position. |
|
1198 "/ aStream nextPut:#dup; nextPut:#push0; nextPut:#>; nextPut:lineNr; nextPut:#falseJump. |
|
1199 "/ aStream nextPut:#dup; nextPut:#gt0; nextPut:lineNr; nextPut:#falseJump. |
|
1200 aStream nextPut:#pushgt0; nextPut:lineNr; nextPut:#falseJump. |
|
1201 pos2 := aStream position. |
|
1202 aStream nextPut:0. |
|
1203 |
|
1204 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler. |
|
1205 aStream nextPut:#minus1; nextPut:lineNr; nextPut:#jump; nextPut:pos. |
|
1206 |
|
1207 (aStream contents) at:pos2 put:(aStream position). |
|
1208 aStream nextPut:#drop. |
|
1209 ! |
|
1210 |
|
1211 codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
1212 "generate code for [...] whilexxx:[ ... ]" |
|
1213 |
|
1214 |pos pos2 theReceiver theArg theByteCode optByteCode| |
|
1215 |
|
1216 (selector == #whileTrue:) ifTrue:[ |
|
1217 theByteCode := #falseJump |
|
1218 ] ifFalse:[ |
|
1219 theByteCode := #trueJump |
|
1220 ]. |
|
1221 |
|
1222 theReceiver := receiver. |
|
1223 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
|
1224 optByteCode notNil ifTrue:[ |
|
1225 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
1226 theArg := receiver statements expression arg1 |
|
1227 ]. |
|
1228 theReceiver := receiver statements expression receiver. |
|
1229 theByteCode := optByteCode |
|
1230 ]. |
|
1231 |
|
1232 "/ OLD: |
|
1233 "/ valueNeeded ifTrue:[aStream nextPut:#pushNil]. |
|
1234 "/ |
|
1235 pos := aStream position. |
|
1236 optByteCode notNil ifTrue:[ |
|
1237 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
1238 theArg notNil ifTrue:[ |
|
1239 theArg codeOn:aStream inBlock:b for:aCompiler |
|
1240 ] |
|
1241 ] ifFalse:[ |
|
1242 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler |
|
1243 ]. |
|
1244 |
|
1245 (lineNr between:1 and:255) ifTrue:[ |
|
1246 aStream nextPut:#lineno; nextPut:lineNr. |
|
1247 ]. |
|
1248 |
|
1249 aStream nextPut:theByteCode. |
|
1250 pos2 := aStream position. |
|
1251 aStream nextPut:0. |
|
1252 "/ OLD: |
|
1253 "/ valueNeeded ifTrue:[aStream nextPut:#drop]. |
|
1254 "/ |
|
1255 "/ OLD: |
|
1256 "/ (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1257 "/ NEW: |
|
1258 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler. |
|
1259 aStream nextPut:#jump; nextPut:pos. |
|
1260 (aStream contents) at:pos2 put:(aStream position). |
|
1261 "/ NEW: |
|
1262 valueNeeded ifTrue:[aStream nextPut:#pushNil]. |
580 ! |
1263 ! |
581 |
1264 |
582 optimizedConditionFor:aReceiver with:aByteCode |
1265 optimizedConditionFor:aReceiver with:aByteCode |
583 |rec sel| |
1266 |rec sel| |
584 |
1267 |
655 (aByteCode == #falseJump) ifTrue:[^ #eqJump]. |
1338 (aByteCode == #falseJump) ifTrue:[^ #eqJump]. |
656 (aByteCode == #trueJump) ifTrue:[^ #notEqJump] |
1339 (aByteCode == #trueJump) ifTrue:[^ #notEqJump] |
657 ] |
1340 ] |
658 ]. |
1341 ]. |
659 ^ nil |
1342 ^ nil |
660 ! |
1343 ! ! |
661 |
1344 |
662 codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
1345 !MessageNode methodsFor:'evaluating'! |
663 "generate code for [...] whilexxx:[ ... ]" |
1346 |
664 |
1347 evaluate |
665 |pos pos2 theReceiver theArg theByteCode optByteCode| |
1348 |r nargs argValueArray class| |
666 |
1349 |
667 (selector == #whileTrue:) ifTrue:[ |
1350 receiver isSuper ifTrue:[ |
668 theByteCode := #falseJump |
1351 r := receiver value. |
669 ] ifFalse:[ |
1352 receiver isHere ifTrue:[ |
670 theByteCode := #trueJump |
1353 class := receiver definingClass. |
671 ]. |
1354 ] ifFalse:[ |
672 |
1355 class := receiver definingClass superclass. |
673 theReceiver := receiver. |
1356 ]. |
674 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
1357 argArray notNil ifTrue:[ |
675 optByteCode notNil ifTrue:[ |
1358 argValueArray := argArray collect:[:arg | arg evaluate]. |
676 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
1359 ] ifFalse:[ |
677 theArg := receiver statements expression arg1 |
1360 argValueArray := #() |
678 ]. |
1361 ]. |
679 theReceiver := receiver statements expression receiver. |
1362 ^ r perform:selector inClass:class withArguments:argValueArray |
680 theByteCode := optByteCode |
1363 ]. |
681 ]. |
1364 |
682 |
1365 |
683 "/ OLD: |
1366 argArray isNil ifTrue:[ |
684 "/ valueNeeded ifTrue:[aStream nextPut:#pushNil]. |
1367 ^ (receiver evaluate) perform:selector |
685 "/ |
1368 ]. |
686 pos := aStream position. |
1369 nargs := argArray size. |
687 optByteCode notNil ifTrue:[ |
1370 (nargs == 1) ifTrue:[ |
688 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
1371 ^ (receiver evaluate) perform:selector with:(argArray at:1) evaluate |
689 theArg notNil ifTrue:[ |
1372 ]. |
690 theArg codeOn:aStream inBlock:b for:aCompiler |
1373 (nargs == 2) ifTrue:[ |
691 ] |
1374 ^ (receiver evaluate) perform:selector |
692 ] ifFalse:[ |
1375 with:(argArray at:1) evaluate |
693 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler |
1376 with:(argArray at:2) evaluate |
694 ]. |
1377 ]. |
695 |
1378 (nargs == 3) ifTrue:[ |
696 (lineNr between:1 and:255) ifTrue:[ |
1379 ^ (receiver evaluate) perform:selector |
697 aStream nextPut:#lineno; nextPut:lineNr. |
1380 with:(argArray at:1) evaluate |
698 ]. |
1381 with:(argArray at:2) evaluate |
699 |
1382 with:(argArray at:3) evaluate |
700 aStream nextPut:theByteCode. |
1383 ]. |
701 pos2 := aStream position. |
1384 r := receiver evaluate. |
702 aStream nextPut:0. |
1385 argValueArray := argArray collect:[:arg | arg evaluate]. |
703 "/ OLD: |
1386 ^ r perform:selector withArguments:argValueArray |
704 "/ valueNeeded ifTrue:[aStream nextPut:#drop]. |
1387 ! |
705 "/ |
1388 |
706 "/ OLD: |
1389 evaluateForCascade |
707 "/ (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
1390 |r nargs argValueArray class| |
708 "/ NEW: |
1391 |
709 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler. |
1392 receiver isSuper ifTrue:[ |
710 aStream nextPut:#jump; nextPut:pos. |
1393 r := receiver value. |
711 (aStream contents) at:pos2 put:(aStream position). |
1394 class := receiver definingClass. |
712 "/ NEW: |
1395 receiver isHere ifFalse:[ |
713 valueNeeded ifTrue:[aStream nextPut:#pushNil]. |
1396 class := class superclass. |
714 ! |
1397 ]. |
715 |
1398 argArray notNil ifTrue:[ |
716 XXcodeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
1399 argValueArray := argArray collect:[:arg | arg evaluate]. |
717 "generate code for [...] whilexxx:[ ... ]" |
1400 ] ifFalse:[ |
718 |
1401 argValueArray := #() |
719 |pos pos2 theReceiver theArg theByteCode optByteCode| |
1402 ]. |
720 |
1403 r perform:selector inClass:class withArguments:argValueArray. |
721 (selector == #whileTrue:) ifTrue:[ |
1404 ^ r |
722 theByteCode := #falseJump |
1405 ]. |
723 ] ifFalse:[ |
1406 |
724 theByteCode := #trueJump |
1407 r := receiver evaluate. |
725 ]. |
1408 argArray isNil ifTrue:[ |
726 |
1409 r perform:selector. |
727 theReceiver := receiver. |
1410 ^ r |
728 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
1411 ]. |
729 optByteCode notNil ifTrue:[ |
1412 nargs := argArray size. |
730 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
1413 (nargs == 1) ifTrue:[ |
731 theArg := receiver statements expression arg1 |
1414 r perform:selector with:(argArray at:1) evaluate. |
732 ]. |
1415 ^ r |
733 theReceiver := receiver statements expression receiver. |
1416 ]. |
734 theByteCode := optByteCode |
1417 (nargs == 2) ifTrue:[ |
735 ]. |
1418 r perform:selector with:(argArray at:1) evaluate |
736 |
1419 with:(argArray at:2) evaluate. |
737 valueNeeded ifTrue:[aStream nextPut:#pushNil]. |
1420 ^ r |
738 pos := aStream position. |
1421 ]. |
739 optByteCode notNil ifTrue:[ |
1422 (nargs == 3) ifTrue:[ |
740 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
1423 r perform:selector with:(argArray at:1) evaluate |
741 theArg notNil ifTrue:[ |
1424 with:(argArray at:2) evaluate |
742 theArg codeOn:aStream inBlock:b for:aCompiler |
1425 with:(argArray at:3) evaluate. |
743 ] |
1426 ^ r |
744 ] ifFalse:[ |
1427 ]. |
745 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler |
1428 argValueArray := argArray collect:[:arg | arg evaluate]. |
746 ]. |
1429 r perform:selector withArguments:argValueArray. |
747 |
1430 ^ r |
748 (lineNr between:1 and:255) ifTrue:[ |
1431 ! ! |
749 aStream nextPut:#lineno; nextPut:lineNr. |
1432 |
750 ]. |
1433 !MessageNode methodsFor:'printing'! |
751 |
1434 |
752 aStream nextPut:theByteCode. |
1435 printOn:aStream indent:i |
753 pos2 := aStream position. |
1436 |needParen selectorParts index index2 arg| |
754 aStream nextPut:0. |
1437 |
755 valueNeeded ifTrue:[aStream nextPut:#drop]. |
1438 (#(whileTrue: whileFalse:) includes:selector) ifTrue:[ |
756 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
1439 receiver isBlock ifTrue:[ |
757 aStream nextPut:#jump; nextPut:pos. |
1440 ^ self printWhileOn:aStream indent:i |
758 (aStream contents) at:pos2 put:(aStream position). |
1441 ]. |
759 ! |
1442 ]. |
760 |
1443 |
761 codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
1444 index := 1. |
762 "generate code for n timesRepeat:[ ... ]" |
1445 selectorParts := OrderedCollection new. |
763 |
1446 [index == 0] whileFalse:[ |
764 |pos pos2 theReceiver| |
1447 index2 := selector indexOf:$: startingAt:index. |
765 |
1448 index2 ~~ 0 ifTrue:[ |
766 theReceiver := receiver. |
1449 selectorParts add:(selector copyFrom:index to:index2). |
767 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
1450 index2 := index2 + 1 |
768 valueNeeded ifTrue:[aStream nextPut:#dup]. |
1451 ]. |
769 |
1452 index := index2 |
770 pos := aStream position. |
1453 ]. |
771 "/ aStream nextPut:#dup; nextPut:#push0; nextPut:#>; nextPut:lineNr; nextPut:#falseJump. |
1454 |
772 "/ aStream nextPut:#dup; nextPut:#gt0; nextPut:lineNr; nextPut:#falseJump. |
1455 needParen := false. |
773 aStream nextPut:#pushgt0; nextPut:lineNr; nextPut:#falseJump. |
1456 receiver isMessage ifTrue:[ |
774 pos2 := aStream position. |
1457 receiver isUnaryMessage ifFalse:[ |
775 aStream nextPut:0. |
1458 receiver isBinaryMessage ifFalse:[ |
776 |
1459 needParen := true |
777 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler. |
1460 ]. |
778 aStream nextPut:#minus1; nextPut:lineNr; nextPut:#jump; nextPut:pos. |
1461 ]. |
779 |
1462 ]. |
780 (aStream contents) at:pos2 put:(aStream position). |
1463 needParen ifTrue:[ |
781 aStream nextPut:#drop. |
1464 aStream nextPutAll:'(' |
782 ! |
1465 ]. |
783 |
1466 receiver printOn:aStream indent:i. |
784 codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
1467 needParen ifTrue:[ |
785 "generate code for x ifxxx:[ ... ] yyy:[ ...]" |
1468 aStream nextPutAll:')' |
786 |
1469 ]. |
787 |pos pos2 theReceiver theArg theByteCode optByteCode subsel code| |
1470 |
788 |
1471 1 to:(argArray size) do:[:argIndex | |
789 theReceiver := receiver. |
1472 aStream space. |
790 |
1473 (selectorParts at:argIndex) printOn:aStream. |
791 " |
1474 aStream space. |
792 (theReceiver isMessage) ifTrue:[ |
1475 arg := argArray at:argIndex. |
793 subsel := theReceiver selector. |
1476 needParen := false. |
794 (subsel == #and:) ifTrue:[ |
1477 arg isMessage ifTrue:[ |
795 self codeAndIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
1478 arg isBinaryMessage ifFalse:[ |
796 ^ self |
1479 arg isUnaryMessage ifFalse:[ |
797 ]. |
1480 needParen := true |
798 (subsel == #or:) ifTrue:[ |
1481 ] |
799 self codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
1482 ]. |
800 ^ self |
1483 ]. |
801 ] |
1484 needParen ifTrue:[ |
802 ]. |
1485 aStream nextPutAll:'(' |
803 " |
1486 ]. |
804 (selector == #ifTrue:ifFalse:) ifTrue:[ |
1487 arg printOn:aStream indent:i. |
805 theByteCode := #falseJump |
1488 needParen ifTrue:[ |
806 ] ifFalse:[ |
1489 aStream nextPutAll:') ' |
807 (selector == #ifFalse:ifTrue:) ifTrue:[ |
1490 ]. |
808 theByteCode := #trueJump |
|
809 ] |
|
810 ]. |
|
811 optByteCode := self optimizedConditionFor:theReceiver |
|
812 with:theByteCode. |
|
813 optByteCode notNil ifTrue:[ |
|
814 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
815 theArg := theReceiver arg1 |
|
816 ]. |
|
817 theReceiver := theReceiver receiver. |
|
818 theByteCode := optByteCode |
|
819 ]. |
|
820 theByteCode notNil ifTrue:[ |
|
821 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
822 theArg notNil ifTrue:[ |
|
823 theArg codeOn:aStream inBlock:b for:aCompiler |
|
824 ]. |
|
825 |
|
826 (lineNr between:1 and:255) ifTrue:[ |
|
827 aStream nextPut:#lineno; nextPut:lineNr. |
|
828 ]. |
|
829 |
|
830 aStream nextPut:theByteCode. |
|
831 pos := aStream position. |
|
832 aStream nextPut:0. |
|
833 (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
834 aStream nextPut:#jump. |
|
835 pos2 := aStream position. |
|
836 aStream nextPut:0. |
|
837 code := aStream contents. |
|
838 code at:pos put:(aStream position). |
|
839 (argArray at:2) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
840 code at:pos2 put:(aStream position) |
|
841 ] |
1491 ] |
842 ! |
1492 ! |
843 |
1493 |
844 codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
1494 printWhileOn:aStream indent:i |
845 "generate code for x ifxxx:[ ... ]" |
1495 |needParen arg| |
846 |
1496 |
847 |pos pos2 theReceiver theArg theByteCode optByteCode subsel code |
1497 "special handling of whileTrue/whileFalse" |
848 needLineNr| |
1498 |
849 |
1499 aStream nextPutAll:'['. |
850 theReceiver := receiver. |
1500 receiver statements printOn:aStream indent:i. |
851 |
1501 aStream nextPutAll:'] whileTrue: '. |
852 (theReceiver isMessage) ifTrue:[ |
1502 |
853 subsel := theReceiver selector. |
1503 arg := argArray at:1. |
854 (subsel == #and:) ifTrue:[ |
1504 needParen := false. |
855 self codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
1505 arg isMessage ifTrue:[ |
856 ^ self |
1506 arg isBinaryMessage ifFalse:[ |
857 ]. |
1507 arg isUnaryMessage ifFalse:[ |
858 (subsel == #or:) ifTrue:[ |
1508 needParen := true |
859 self codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
860 ^ self |
|
861 ] |
|
862 ]. |
|
863 (selector == #ifTrue:) ifTrue:[ |
|
864 theByteCode := #falseJump |
|
865 ] ifFalse:[ |
|
866 theByteCode := #trueJump |
|
867 ]. |
|
868 optByteCode := self optimizedConditionFor:theReceiver |
|
869 with:theByteCode. |
|
870 optByteCode notNil ifTrue:[ |
|
871 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
872 theArg := theReceiver arg1 |
|
873 ]. |
|
874 theReceiver := theReceiver receiver. |
|
875 theByteCode := optByteCode |
|
876 ]. |
|
877 |
|
878 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
879 theArg notNil ifTrue:[ |
|
880 theArg codeOn:aStream inBlock:b for:aCompiler |
|
881 ]. |
|
882 |
|
883 needLineNr := true. |
|
884 theArg isNil ifTrue:[ |
|
885 theReceiver isMessage ifTrue:[ |
|
886 (self class hasLineNumber:(theReceiver selector)) ifTrue:[ |
|
887 theReceiver lineNumber == lineNr ifTrue:[ |
|
888 needLineNr := false |
|
889 ] |
|
890 ] |
1509 ] |
891 ] |
1510 ]. |
892 ]. |
1511 ]. |
893 |
1512 needParen ifTrue:[ |
894 needLineNr ifTrue:[ |
1513 aStream nextPutAll:'(' |
895 (lineNr between:1 and:255) ifTrue:[ |
1514 ]. |
896 aStream nextPut:#lineno; nextPut:lineNr. |
1515 arg printOn:aStream indent:i. |
897 ] |
1516 needParen ifTrue:[ |
898 ]. |
1517 aStream nextPutAll:') ' |
899 |
1518 ]. |
900 aStream nextPut:theByteCode. |
|
901 pos := aStream position. |
|
902 aStream nextPut:0. |
|
903 (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
904 |
|
905 code := aStream contents. |
|
906 valueNeeded ifTrue:[ |
|
907 aStream nextPut:#jump. |
|
908 pos2 := aStream position. |
|
909 aStream nextPut:0. |
|
910 code at:pos put:(aStream position). |
|
911 aStream nextPut:#pushNil. |
|
912 code at:pos2 put:(aStream position) |
|
913 ] ifFalse:[ |
|
914 code at:pos put:(aStream position) |
|
915 ] |
|
916 ! |
|
917 |
|
918 codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
919 "generate code for (x and:[y]) ifxxx:[ ... ]" |
|
920 |
|
921 |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp| |
|
922 |
|
923 |
|
924 theByteCode := #falseJump. |
|
925 theReceiver := receiver receiver. |
|
926 |
|
927 optByteCode := self optimizedConditionFor:theReceiver |
|
928 with:theByteCode. |
|
929 optByteCode notNil ifTrue:[ |
|
930 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
931 theArg := theReceiver arg1 |
|
932 ]. |
|
933 theReceiver := theReceiver receiver. |
|
934 theByteCode := optByteCode |
|
935 ]. |
|
936 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
937 theArg notNil ifTrue:[ |
|
938 theArg codeOn:aStream inBlock:b for:aCompiler |
|
939 ]. |
|
940 aStream nextPut:theByteCode. |
|
941 pos1 := aStream position. |
|
942 aStream nextPut:0. |
|
943 |
|
944 theReceiver := receiver arg1. |
|
945 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler. |
|
946 (selector == #ifTrue:) ifTrue:[ |
|
947 jmp := #falseJump |
|
948 ] ifFalse:[ |
|
949 jmp := #trueJump |
|
950 ]. |
|
951 aStream nextPut:jmp. |
|
952 pos2 := aStream position. |
|
953 aStream nextPut:0. |
|
954 |
|
955 code := aStream contents. |
|
956 (selector == #ifFalse:) ifTrue:[ |
|
957 code at:pos1 put:(aStream position) |
|
958 ]. |
|
959 (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
960 |
|
961 valueNeeded ifTrue:[ |
|
962 aStream nextPut:#jump. |
|
963 pos3 := aStream position. |
|
964 aStream nextPut:0. |
|
965 here := aStream position. |
|
966 (selector == #ifTrue:) ifTrue:[ |
|
967 code at:pos1 put:here |
|
968 ]. |
|
969 code at:pos2 put:here. |
|
970 aStream nextPut:#pushNil. |
|
971 code at:pos3 put:(aStream position) |
|
972 ] ifFalse:[ |
|
973 here := aStream position. |
|
974 (selector == #ifTrue:) ifTrue:[ |
|
975 code at:pos1 put:here |
|
976 ]. |
|
977 code at:pos2 put:here |
|
978 ] |
|
979 ! |
|
980 |
|
981 codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
982 "generate code for (x or:[y]) ifxxx:[ ... ]" |
|
983 |
|
984 |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp| |
|
985 |
|
986 theByteCode := #trueJump. |
|
987 theReceiver := receiver receiver. |
|
988 |
|
989 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
|
990 optByteCode notNil ifTrue:[ |
|
991 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
992 theArg := theReceiver arg1 |
|
993 ]. |
|
994 theReceiver := theReceiver receiver. |
|
995 theByteCode := optByteCode |
|
996 ]. |
|
997 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
998 theArg notNil ifTrue:[ |
|
999 theArg codeOn:aStream inBlock:b for:aCompiler |
|
1000 ]. |
|
1001 aStream nextPut:theByteCode. |
|
1002 pos1 := aStream position. |
|
1003 aStream nextPut:0. |
|
1004 |
|
1005 |
|
1006 theReceiver := receiver arg1. |
|
1007 |
|
1008 "new:" |
|
1009 (selector == #ifTrue:) ifTrue:[ |
|
1010 theByteCode := #falseJump |
|
1011 ] ifFalse:[ |
|
1012 theByteCode := #trueJump |
|
1013 ]. |
|
1014 optByteCode := self optimizedConditionFor:theReceiver with:theByteCode. |
|
1015 optByteCode notNil ifTrue:[ |
|
1016 theReceiver isBlock ifTrue:[ |
|
1017 theReceiver := theReceiver statements expression |
|
1018 ]. |
|
1019 ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[ |
|
1020 theArg := theReceiver arg1 |
|
1021 ]. |
|
1022 theReceiver := theReceiver receiver. |
|
1023 theByteCode := optByteCode. |
|
1024 |
|
1025 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
1026 theArg notNil ifTrue:[ |
|
1027 theArg codeOn:aStream inBlock:b for:aCompiler |
|
1028 ]. |
|
1029 aStream nextPut:theByteCode. |
|
1030 |
|
1031 ] ifFalse:[ |
|
1032 "org" |
|
1033 theReceiver codeInlineOn:aStream inBlock:b for:aCompiler. |
|
1034 (selector == #ifTrue:) ifTrue:[ |
|
1035 jmp := #falseJump |
|
1036 ] ifFalse:[ |
|
1037 jmp := #trueJump |
|
1038 ]. |
|
1039 aStream nextPut:jmp |
|
1040 ]. |
|
1041 pos2 := aStream position. |
|
1042 aStream nextPut:0. |
|
1043 (selector == #ifTrue:) ifTrue:[ |
|
1044 (aStream contents) at:pos1 put:(aStream position) |
|
1045 ]. |
|
1046 (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1047 |
|
1048 code := aStream contents. |
|
1049 valueNeeded ifTrue:[ |
|
1050 aStream nextPut:#jump. |
|
1051 pos3 := aStream position. |
|
1052 aStream nextPut:0. |
|
1053 here := aStream position. |
|
1054 (selector == #ifFalse:) ifTrue:[ |
|
1055 code at:pos1 put:here |
|
1056 ]. |
|
1057 code at:pos2 put:here. |
|
1058 aStream nextPut:#pushNil. |
|
1059 code at:pos3 put:(aStream position) |
|
1060 ] ifFalse:[ |
|
1061 here := aStream position. |
|
1062 (selector == #ifFalse:) ifTrue:[ |
|
1063 code at:pos1 put:here |
|
1064 ]. |
|
1065 code at:pos2 put:here |
|
1066 ] |
|
1067 ! |
|
1068 |
|
1069 codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
1070 "generate code for x and/or:[y] - but not in an if" |
|
1071 |
|
1072 |pos theReceiver theByteCode| |
|
1073 |
|
1074 self halt. |
|
1075 theReceiver := receiver. |
|
1076 (selector == #and:) ifTrue:[ |
|
1077 theByteCode := #falseJump |
|
1078 ] ifFalse:[ |
|
1079 theByteCode := #trueJump |
|
1080 ]. |
|
1081 " |
|
1082 (self canOptimizeConditionFor:receiver) ifTrue:[ |
|
1083 theByteCode := self optimizedConditionFor:theReceiver |
|
1084 with:theByteCode. |
|
1085 theReceiver := theReceiver receiver |
|
1086 ]. |
|
1087 " |
|
1088 theReceiver codeOn:aStream inBlock:b for:aCompiler. |
|
1089 aStream nextPut:theByteCode. |
|
1090 pos := aStream position. |
|
1091 aStream nextPut:0. |
|
1092 (argArray at: 1) codeInlineOn:aStream inBlock:b for:aCompiler. |
|
1093 (aStream contents) at:pos put:(aStream position). |
|
1094 valueNeeded ifFalse:[aStream nextPut:#drop] |
|
1095 ! |
|
1096 |
|
1097 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
1098 |recType nargs isBuiltIn litIndex cls clsLitIndex code| |
|
1099 |
|
1100 argArray isNil ifTrue:[ |
|
1101 nargs := 0 |
|
1102 ] ifFalse:[ |
|
1103 nargs := argArray size |
|
1104 ]. |
|
1105 |
|
1106 isBuiltIn := false. |
|
1107 recType := receiver type. |
|
1108 |
|
1109 (nargs == 0) ifTrue:[ |
|
1110 (recType == #ThisContext) ifTrue:[ |
|
1111 valueNeeded ifFalse:[ |
|
1112 "for now, only do it in methods" |
|
1113 b isNil ifTrue:[ |
|
1114 (selector == #restart) ifTrue:[ |
|
1115 aStream nextPut:#jump; nextPut:1. "jump to start" |
|
1116 ^ self |
|
1117 ]. |
|
1118 ]. |
|
1119 (selector == #return) ifTrue:[ "^ nil" |
|
1120 aStream nextPut:#retNil. |
|
1121 ^ self |
|
1122 ]. |
|
1123 ] |
|
1124 ]. |
|
1125 |
|
1126 receiver isBlock ifTrue:[ |
|
1127 selector == #value ifTrue:[ |
|
1128 receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1129 ^ self |
|
1130 ]. |
|
1131 ]. |
|
1132 isBuiltIn := self class isBuiltInUnarySelector:selector |
|
1133 ]. |
|
1134 |
|
1135 (nargs == 1) ifTrue:[ |
|
1136 (recType == #ThisContext) ifTrue:[ |
|
1137 valueNeeded ifFalse:[ |
|
1138 (selector == #return:) ifTrue:[ |
|
1139 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. "^ value" |
|
1140 aStream nextPut:#retTop. |
|
1141 ^ self |
|
1142 ]. |
|
1143 ]. |
|
1144 ]. |
|
1145 |
|
1146 ((argArray at:1) isBlock) ifTrue:[ |
|
1147 ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[ |
|
1148 receiver isBlock ifFalse:[ |
|
1149 self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1150 ^ self |
|
1151 ]. |
|
1152 ]. |
|
1153 " |
|
1154 ((selector == #and:) or:[selector == #or:]) ifTrue:[ |
|
1155 self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1156 ^ self |
|
1157 ]. |
|
1158 " |
|
1159 (selector == #timesRepeat:) ifTrue:[ |
|
1160 (receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[ |
|
1161 self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1162 ^ self |
|
1163 ] |
|
1164 ]. |
|
1165 |
|
1166 ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[ |
|
1167 (receiver isBlock) ifTrue:[ |
|
1168 self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1169 ^ self |
|
1170 ] |
|
1171 ] |
|
1172 ]. |
|
1173 isBuiltIn := self class isBuiltIn1ArgSelector:selector |
|
1174 ]. |
|
1175 |
|
1176 (nargs == 2) ifTrue:[ |
|
1177 ((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[ |
|
1178 receiver isBlock ifFalse:[ |
|
1179 (argArray at:1) isBlock ifTrue:[ |
|
1180 (argArray at:2) isBlock ifTrue:[ |
|
1181 self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler. |
|
1182 ^ self |
|
1183 ] |
|
1184 ] |
|
1185 ] |
|
1186 ]. |
|
1187 isBuiltIn := self class isBuiltIn2ArgSelector:selector |
|
1188 ]. |
|
1189 |
|
1190 "can we use a send-bytecode ?" |
|
1191 isBuiltIn ifTrue:[ |
|
1192 receiver isSuper ifFalse:[ |
|
1193 receiver codeOn:aStream inBlock:b for:aCompiler. |
|
1194 (nargs > 0) ifTrue:[ |
|
1195 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. |
|
1196 (nargs > 1) ifTrue:[ |
|
1197 (argArray at:2) codeOn:aStream inBlock:b for:aCompiler |
|
1198 ] |
|
1199 ]. |
|
1200 aStream nextPut:selector. |
|
1201 (self class hasLineNumber:selector) ifTrue:[ |
|
1202 aStream nextPut:lineNr. |
|
1203 ]. |
|
1204 valueNeeded ifFalse:[ |
|
1205 aStream nextPut:#drop |
|
1206 ]. |
|
1207 ^ self |
|
1208 ] |
|
1209 ]. |
|
1210 |
|
1211 ((nargs == 0) and:[selector == #yourself]) ifTrue:[ |
|
1212 "yourself is often added to get the receiver - |
|
1213 we get it without the yourself-message" |
|
1214 |
|
1215 valueNeeded ifTrue:[ |
|
1216 receiver codeOn:aStream inBlock:b for:aCompiler |
|
1217 ]. |
|
1218 ^ self |
|
1219 ]. |
|
1220 |
|
1221 "no - generate a send" |
|
1222 |
|
1223 receiver isSuper ifTrue:[ |
|
1224 cls := aCompiler targetClass. |
|
1225 receiver isHere ifTrue:[ |
|
1226 code := #hereSend. |
|
1227 ] ifFalse:[ |
|
1228 code := #superSend. |
|
1229 cls := cls superclass. |
|
1230 ]. |
|
1231 clsLitIndex := aCompiler addLiteral:cls. |
|
1232 ] ifFalse:[ |
|
1233 clsLitIndex := 0. |
|
1234 ]. |
|
1235 |
|
1236 litIndex := aCompiler addLiteral:selector. |
|
1237 (litIndex <= 255 and:[clsLitIndex <= 255]) ifTrue:[ |
|
1238 (recType ~~ #Self) ifTrue:[ |
|
1239 receiver codeOn:aStream inBlock:b for:aCompiler |
|
1240 ]. |
|
1241 argArray notNil ifTrue:[ |
|
1242 argArray do:[:arg | |
|
1243 arg codeOn:aStream inBlock:b for:aCompiler |
|
1244 ] |
|
1245 ]. |
|
1246 |
|
1247 receiver isSuper ifTrue:[ |
|
1248 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex. |
|
1249 valueNeeded ifFalse:[ |
|
1250 aStream nextPut:#drop |
|
1251 ]. |
|
1252 ^ self |
|
1253 ]. |
|
1254 |
|
1255 (nargs <= 3) ifTrue:[ |
|
1256 |codes| |
|
1257 |
|
1258 valueNeeded ifTrue:[ |
|
1259 (receiver type == #Self) ifTrue:[ |
|
1260 codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3) |
|
1261 ] ifFalse:[ |
|
1262 codes := #(send0 send1 send2 send3) |
|
1263 ] |
|
1264 ] ifFalse:[ |
|
1265 (receiver type == #Self) ifTrue:[ |
|
1266 codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3) |
|
1267 ] ifFalse:[ |
|
1268 codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) |
|
1269 ] |
|
1270 ]. |
|
1271 aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex. |
|
1272 ^ self |
|
1273 ]. |
|
1274 |
|
1275 (recType == #Self) ifTrue:[ |
|
1276 code := #sendSelf |
|
1277 ] ifFalse:[ |
|
1278 valueNeeded ifTrue:[ |
|
1279 code := #send |
|
1280 ] ifFalse:[ |
|
1281 code := #sendDrop |
|
1282 ] |
|
1283 ]. |
|
1284 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs. |
|
1285 valueNeeded ifFalse:[ |
|
1286 (recType == #Self) ifTrue:[ |
|
1287 aStream nextPut:#drop |
|
1288 ] |
|
1289 ]. |
|
1290 ^ self |
|
1291 ]. |
|
1292 |
|
1293 "needs 16bit literal index" |
|
1294 |
|
1295 receiver isSuper ifTrue:[ |
|
1296 argArray notNil ifTrue:[ |
|
1297 argArray do:[:arg | |
|
1298 arg codeOn:aStream inBlock:b for:aCompiler |
|
1299 ] |
|
1300 ]. |
|
1301 receiver isHere ifTrue:[ |
|
1302 code := #hereSendL |
|
1303 ] ifFalse:[ |
|
1304 code := #superSendL. |
|
1305 ]. |
|
1306 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0. |
|
1307 ] ifFalse:[ |
|
1308 recType ~~ #Self ifTrue:[ |
|
1309 receiver codeOn:aStream inBlock:b for:aCompiler. |
|
1310 ]. |
|
1311 argArray notNil ifTrue:[ |
|
1312 argArray do:[:arg | |
|
1313 arg codeOn:aStream inBlock:b for:aCompiler |
|
1314 ] |
|
1315 ]. |
|
1316 |
|
1317 recType == #Self ifTrue:[ |
|
1318 code := #sendSelfL |
|
1319 ] ifFalse:[ |
|
1320 code := #sendL |
|
1321 ]. |
|
1322 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs. |
|
1323 ]. |
|
1324 valueNeeded ifFalse:[ |
|
1325 aStream nextPut:#drop |
|
1326 ]. |
|
1327 |
|
1328 "Modified: 3.9.1995 / 12:55:42 / claus" |
|
1329 ! |
|
1330 |
|
1331 codeSendOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler |
|
1332 "like code on, but assumes that receiver has already been |
|
1333 coded onto stack - needed for cascade" |
|
1334 |
|
1335 |nargs isBuiltIn code litIndex| |
|
1336 |
|
1337 argArray isNil ifTrue:[ |
|
1338 nargs := 0 |
|
1339 ] ifFalse:[ |
|
1340 nargs := argArray size |
|
1341 ]. |
|
1342 |
|
1343 isBuiltIn := false. |
|
1344 |
|
1345 (nargs == 0) ifTrue:[ |
|
1346 isBuiltIn := self class isBuiltInUnarySelector:selector |
|
1347 ]. |
|
1348 (nargs == 1) ifTrue:[ |
|
1349 isBuiltIn := self class isBuiltIn1ArgSelector:selector |
|
1350 ]. |
|
1351 (nargs == 2) ifTrue:[ |
|
1352 isBuiltIn := self class isBuiltIn2ArgSelector:selector |
|
1353 ]. |
|
1354 |
|
1355 "can we use a send-bytecode ?" |
|
1356 isBuiltIn ifTrue:[ |
|
1357 receiver isSuper ifFalse:[ |
|
1358 (nargs > 0) ifTrue:[ |
|
1359 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. |
|
1360 (nargs > 1) ifTrue:[ |
|
1361 (argArray at:2) codeOn:aStream inBlock:b for:aCompiler |
|
1362 ] |
|
1363 ]. |
|
1364 aStream nextPut:selector. |
|
1365 (self class hasLineNumber:selector) ifTrue:[ |
|
1366 aStream nextPut:lineNr. |
|
1367 ]. |
|
1368 valueNeeded ifFalse:[ |
|
1369 aStream nextPut:#drop |
|
1370 ]. |
|
1371 ^ self |
|
1372 ] |
|
1373 ]. |
|
1374 |
|
1375 argArray notNil ifTrue:[ |
|
1376 argArray do:[:arg | |
|
1377 arg codeOn:aStream inBlock:b for:aCompiler |
|
1378 ] |
|
1379 ]. |
|
1380 |
|
1381 receiver isSuper ifTrue:[ |
|
1382 litIndex := aCompiler addLiteral:selector. |
|
1383 litIndex <= 255 ifTrue:[ |
|
1384 receiver isHere ifTrue:[ |
|
1385 code := #hereSend |
|
1386 ] ifFalse:[ |
|
1387 code := #superSend. |
|
1388 ]. |
|
1389 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil. |
|
1390 ] ifFalse:[ |
|
1391 receiver isHere ifTrue:[ |
|
1392 code := #hereSendL |
|
1393 ] ifFalse:[ |
|
1394 code := #superSendL. |
|
1395 ]. |
|
1396 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil. |
|
1397 ]. |
|
1398 valueNeeded ifFalse:[ |
|
1399 aStream nextPut:#drop |
|
1400 ]. |
|
1401 ^ self |
|
1402 ]. |
|
1403 (nargs == 0) ifTrue:[ |
|
1404 (selector == #yourself) ifTrue:[ |
|
1405 "yourself is often added to get the receiver - |
|
1406 we get it without the yourself-message" |
|
1407 |
|
1408 valueNeeded ifFalse:[ |
|
1409 aStream nextPut:#drop |
|
1410 ]. |
|
1411 ^ self |
|
1412 ]. |
|
1413 ]. |
|
1414 |
|
1415 litIndex := aCompiler addLiteral:selector. |
|
1416 litIndex <= 255 ifTrue:[ |
|
1417 (nargs <= 3) ifTrue:[ |
|
1418 valueNeeded ifTrue:[ |
|
1419 code := #(send0 send1 send2 send3) at:(nargs+1). |
|
1420 ] ifFalse:[ |
|
1421 code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1). |
|
1422 ]. |
|
1423 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex. |
|
1424 ^ self |
|
1425 ]. |
|
1426 |
|
1427 valueNeeded ifTrue:[ |
|
1428 code := #send |
|
1429 ] ifFalse:[ |
|
1430 code := #sendDrop |
|
1431 ]. |
|
1432 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs. |
|
1433 ^ self |
|
1434 ]. |
|
1435 |
|
1436 valueNeeded ifTrue:[ |
|
1437 code := #sendL |
|
1438 ] ifFalse:[ |
|
1439 code := #sendDropL |
|
1440 ]. |
|
1441 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs |
|
1442 ! |
|
1443 |
|
1444 codeForCascadeOn:aStream inBlock:b for:aCompiler |
|
1445 "like codeOn, but always leave the receiver instead of the result" |
|
1446 |
|
1447 |nargs isBuiltIn code litIndex| |
|
1448 |
|
1449 argArray isNil ifTrue:[ |
|
1450 nargs := 0 |
|
1451 ] ifFalse:[ |
|
1452 nargs := argArray size |
|
1453 ]. |
|
1454 |
|
1455 isBuiltIn := false. |
|
1456 |
|
1457 (nargs == 0) ifTrue:[ |
|
1458 isBuiltIn := self class isBuiltInUnarySelector:selector |
|
1459 ]. |
|
1460 (nargs == 1) ifTrue:[ |
|
1461 isBuiltIn := self class isBuiltIn1ArgSelector:selector |
|
1462 ]. |
|
1463 (nargs == 2) ifTrue:[ |
|
1464 isBuiltIn := self class isBuiltIn2ArgSelector:selector |
|
1465 ]. |
|
1466 |
|
1467 receiver codeOn:aStream inBlock:b for:aCompiler. |
|
1468 aStream nextPut:#dup. |
|
1469 |
|
1470 "can we use a send-bytecode ?" |
|
1471 isBuiltIn ifTrue:[ |
|
1472 receiver isSuper ifFalse:[ |
|
1473 (nargs > 0) ifTrue:[ |
|
1474 (argArray at:1) codeOn:aStream inBlock:b for:aCompiler. |
|
1475 (nargs > 1) ifTrue:[ |
|
1476 (argArray at:2) codeOn:aStream inBlock:b for:aCompiler |
|
1477 ] |
|
1478 ]. |
|
1479 aStream nextPut:selector. |
|
1480 (self class hasLineNumber:selector) ifTrue:[ |
|
1481 aStream nextPut:lineNr. |
|
1482 ]. |
|
1483 aStream nextPut:#drop. |
|
1484 ^ self |
|
1485 ] |
|
1486 ]. |
|
1487 |
|
1488 "no - generate a send" |
|
1489 argArray notNil ifTrue:[ |
|
1490 argArray do:[:arg | |
|
1491 arg codeOn:aStream inBlock:b for:aCompiler |
|
1492 ] |
|
1493 ]. |
|
1494 litIndex := aCompiler addLiteral:selector. |
|
1495 litIndex <= 255 ifTrue:[ |
|
1496 receiver isSuper ifTrue:[ |
|
1497 receiver isHere ifTrue:[ |
|
1498 code := #hereSend |
|
1499 ] ifFalse:[ |
|
1500 code := #superSend. |
|
1501 ]. |
|
1502 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil; nextPut:#drop. |
|
1503 ^ self |
|
1504 ]. |
|
1505 (nargs <= 3) ifTrue:[ |
|
1506 code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1). |
|
1507 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex. |
|
1508 ^ self |
|
1509 ]. |
|
1510 |
|
1511 aStream nextPut:#sendDrop; nextPut:lineNr; nextPut:litIndex; nextPut:nargs. |
|
1512 ^ self |
|
1513 ]. |
|
1514 "need 16bit litIndex" |
|
1515 receiver isSuper ifTrue:[ |
|
1516 receiver isHere ifTrue:[ |
|
1517 code := #hereSendL |
|
1518 ] ifFalse:[ |
|
1519 code := #superSendL. |
|
1520 ]. |
|
1521 aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil; nextPut:#drop. |
|
1522 ^ self |
|
1523 ]. |
|
1524 aStream nextPut:#sendDropL; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs |
|
1525 ! ! |
1519 ! ! |
|
1520 |
|
1521 !MessageNode methodsFor:'queries'! |
|
1522 |
|
1523 isMessage |
|
1524 ^ true |
|
1525 ! ! |
|
1526 |