MessageNode.st
changeset 565 00673e9d6edc
parent 564 ffac5191213f
child 567 a6e4c44ff326
equal deleted inserted replaced
564:ffac5191213f 565:00673e9d6edc
   760     self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler
   760     self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler
   761 !
   761 !
   762 
   762 
   763 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
   763 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
   764     |recType nargs isBuiltIn litIndex cls clsLitIndex code isSpecial
   764     |recType nargs isBuiltIn litIndex cls clsLitIndex code isSpecial
   765      specialCode stackTop arg1 arg2|
   765      specialCode stackTop arg1 arg2 arg3 okToInline|
   766 
   766 
   767     argArray isNil ifTrue:[
   767     argArray isNil ifTrue:[
   768         nargs := 0
   768         nargs := 0
   769     ] ifFalse:[
   769     ] ifFalse:[
   770         nargs := argArray size
   770         nargs := argArray size
   869                 ]
   869                 ]
   870             ]
   870             ]
   871         ].
   871         ].
   872 
   872 
   873         selector == #to:do: ifTrue:[
   873         selector == #to:do: ifTrue:[
   874             (receiver isConstant
   874             okToInline := true.
   875             and:[receiver type == #Integer]) ifTrue:[
   875 
   876                 (arg1 isConstant
   876             (arg2 isBlock and:[arg2 numArgs == 1]) ifFalse:[
   877                 and:[arg1 type == #Integer]) ifTrue:[
   877                 okToInline := false.
   878                     receiver value <= arg1 value ifTrue:[
   878             ].
   879                         arg2 isBlock ifTrue:[
   879             okToInline ifTrue:[
   880                             arg2 numArgs == 1 ifTrue:[
   880                 ^ self codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
   881                                 ^ self codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   882                             ]
       
   883                         ].    
       
   884                     ]
       
   885                 ]
       
   886             ]
   881             ]
   887         ].
   882         ].
   888 
   883 
   889         isBuiltIn := aCompiler isBuiltIn2ArgSelector:selector forReceiver:receiver.
   884         isBuiltIn := aCompiler isBuiltIn2ArgSelector:selector forReceiver:receiver.
       
   885     ].
       
   886 
       
   887     (nargs == 3) ifTrue:[
       
   888         arg1 := argArray at:1.
       
   889         arg2 := argArray at:2.
       
   890         arg3 := argArray at:3.
       
   891 
       
   892         selector == #to:by:do: ifTrue:[
       
   893             okToInline := true.
       
   894 
       
   895             (arg2 isConstant and:[arg2 type == #Integer]) ifFalse:[
       
   896                 "/ step must be a constant (need to know how to compare)
       
   897                 okToInline := false.
       
   898             ].
       
   899             (arg3 isBlock and:[arg3 numArgs == 1]) ifFalse:[
       
   900                 okToInline := false.
       
   901             ].
       
   902             okToInline ifTrue:[
       
   903                 ^ self codeToByDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   904             ]
       
   905         ].
   890     ].
   906     ].
   891 
   907 
   892     isBuiltIn ifFalse:[
   908     isBuiltIn ifFalse:[
   893         specialCode := aCompiler specialSendCodeFor:selector.
   909         specialCode := aCompiler specialSendCodeFor:selector.
   894         isSpecial := specialCode notNil.
   910         isSpecial := specialCode notNil.
  1046     valueNeeded ifFalse:[
  1062     valueNeeded ifFalse:[
  1047         aStream nextPut:#drop
  1063         aStream nextPut:#drop
  1048     ].
  1064     ].
  1049 
  1065 
  1050     "Modified: 3.9.1995 / 12:55:42 / claus"
  1066     "Modified: 3.9.1995 / 12:55:42 / claus"
  1051     "Modified: 26.6.1997 / 13:22:08 / cg"
  1067     "Modified: 27.6.1997 / 13:41:41 / cg"
  1052 !
  1068 !
  1053 
  1069 
  1054 codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1070 codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1055     "generate code for (x or:[y]) ifxxx:[ ... ] ifyyy:[ ... ]"
  1071     "generate code for (x or:[y]) ifxxx:[ ... ] ifyyy:[ ... ]"
  1056 
  1072 
  1405     ]
  1421     ]
  1406 
  1422 
  1407     "Modified: 27.5.1997 / 14:28:49 / cg"
  1423     "Modified: 27.5.1997 / 14:28:49 / cg"
  1408 !
  1424 !
  1409 
  1425 
  1410 codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1426 codeToByDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1411     "generate code for n to:n do:[:unusedArg | ... ]"
  1427     "generate code for a to:b by:c do:[:arg | ... ]"
  1412 
  1428 
  1413     |pos pos2 start stop lateEval theBlock loopVarIndex|
  1429     |pos pos2 start stop step lateEval theBlock loopVarIndex
  1414 
  1430      stepVal stopVarIndex|
  1415     "/ NOTICE: could compile it as a timesRepeat, if
  1431 
       
  1432     "/ NOTICE: could compile it as a timesRepeat-like loop, if
  1416     "/ the loop-counter is not accessed within the loop-block.
  1433     "/ the loop-counter is not accessed within the loop-block.
  1417     "/ This generates somewhat (15%) faster code, but makes
  1434     "/ This generates somewhat (15%) faster code, but makes
  1418     "/ debugging somewhat difficult (no loop-value seen in debugger).
  1435     "/ debugging somewhat difficult (no loop-value seen in debugger).
  1419 
  1436 
  1420     start := receiver.
  1437     start := receiver.
  1421     stop := (argArray at:1).
  1438     stop := (argArray at:1).
  1422     stop isConstant ifFalse:[self halt:'should not happen'].
  1439     step := (argArray at:2).
  1423     (stop evaluate isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
  1440 
       
  1441 "/    stop isConstant ifFalse:[self halt:'should not happen'].
       
  1442 "/    (stop evaluate isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
       
  1443 
       
  1444     step isConstant ifFalse:[self halt:'should not happen'].
       
  1445     stepVal := step evaluate.
       
  1446     (stepVal isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
  1424 
  1447 
  1425     start codeOn:aStream inBlock:b for:aCompiler.
  1448     start codeOn:aStream inBlock:b for:aCompiler.
  1426 
  1449 
  1427     lateEval := false.
  1450     lateEval := false.
  1428 
  1451 
  1436         lateEval ifFalse:[
  1459         lateEval ifFalse:[
  1437             aStream nextPut:#dup
  1460             aStream nextPut:#dup
  1438         ].
  1461         ].
  1439     ].
  1462     ].
  1440 
  1463 
       
  1464     "/ if stop is not constant, and not an argVar,
       
  1465     "/  evaluate it into a temp slot ...
       
  1466 
       
  1467     (stop isConstant and:[stop type == #Integer]) ifFalse:[
       
  1468         "/ a method/blockArg is constant as well ...
       
  1469         (stop isVariable and:[stop isArgument]) ifFalse:[
       
  1470             stop codeOn:aStream inBlock:b for:aCompiler.
       
  1471 
       
  1472             b isNil ifTrue:[
       
  1473                 stopVarIndex := aCompiler addTempVar.
       
  1474                 aStream nextPut:#storeMethodVar; nextPut:stopVarIndex.
       
  1475             ] ifFalse:[
       
  1476                 stopVarIndex := b addTempVar.
       
  1477                 aStream nextPut:#storeBlockVar; nextPut:stopVarIndex.
       
  1478             ].
       
  1479         ]
       
  1480     ].
       
  1481 
  1441     pos := aStream position.
  1482     pos := aStream position.
  1442 
  1483 
  1443     aStream nextPut:#dup.
  1484     aStream nextPut:#dup.
  1444     stop codeOn:aStream inBlock:b for:aCompiler.
  1485     stopVarIndex notNil ifTrue:[
  1445     aStream nextPut:#>.
  1486         b isNil ifTrue:[
       
  1487             aStream nextPut:#pushMethodVar; nextPut:stopVarIndex.
       
  1488         ] ifFalse:[
       
  1489             aStream nextPut:#pushBlockVar; nextPut:stopVarIndex.
       
  1490         ]
       
  1491     ] ifFalse:[
       
  1492         stop codeOn:aStream inBlock:b for:aCompiler.
       
  1493     ].
       
  1494     stepVal > 0 ifTrue:[
       
  1495         aStream nextPut:#>.
       
  1496     ] ifFalse:[
       
  1497         aStream nextPut:#<.
       
  1498     ].
  1446     (aCompiler hasLineNumber:selector) ifTrue:[
  1499     (aCompiler hasLineNumber:selector) ifTrue:[
  1447         aStream nextPut:lineNr.
  1500         aStream nextPut:lineNr.
  1448     ].
  1501     ].
  1449     aStream nextPut:#trueJump.
  1502     aStream nextPut:#trueJump.
  1450     pos2 := aStream position.
  1503     pos2 := aStream position.
  1451     aStream nextPut:0.
  1504     aStream nextPut:0.
  1452 
  1505 
  1453     theBlock := argArray at:2.
  1506     theBlock := argArray at:3.
  1454 
  1507 
  1455     "/ need a temporary in the outer context for
  1508     "/ need a temporary in the outer context for
  1456     "/ the loop ...
  1509     "/ the loop ...
  1457     b isNil ifTrue:[
  1510     b isNil ifTrue:[
  1458         loopVarIndex := aCompiler addTempVar.
  1511         loopVarIndex := aCompiler addTempVar.
  1465     ].
  1518     ].
  1466     theBlock indexOfFirstTemp:loopVarIndex.
  1519     theBlock indexOfFirstTemp:loopVarIndex.
  1467 
  1520 
  1468     theBlock codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
  1521     theBlock codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
  1469 
  1522 
  1470     "/ increment counter & jump back.
  1523     "/ increment/decrement counter & jump back.
  1471 
  1524 
  1472     aStream nextPut:#plus1; nextPut:lineNr; nextPut:#jump; nextPut:pos.
  1525     stepVal == 1 ifTrue:[
       
  1526         aStream nextPut:#plus1; nextPut:lineNr.
       
  1527     ] ifFalse:[
       
  1528         stepVal == -1 ifTrue:[
       
  1529             aStream nextPut:#minus1; nextPut:lineNr.
       
  1530         ] ifFalse:[
       
  1531             step codeOn:aStream inBlock:b for:aCompiler.
       
  1532             aStream nextPut:#+.
       
  1533             (aCompiler hasLineNumber:#+) ifTrue:[
       
  1534                 aStream nextPut:lineNr.
       
  1535             ].
       
  1536         ]
       
  1537     ].
       
  1538 
       
  1539     aStream nextPut:#jump; nextPut:pos.
  1473 
  1540 
  1474     (aStream contents) at:pos2 put:(aStream position).
  1541     (aStream contents) at:pos2 put:(aStream position).
  1475     aStream nextPut:#drop.  "/ drop run variable
  1542     aStream nextPut:#drop.  "/ drop run variable
  1476     lateEval ifTrue:[
  1543     lateEval ifTrue:[
  1477         start codeOn:aStream inBlock:b for:aCompiler.
  1544         start codeOn:aStream inBlock:b for:aCompiler.
  1482 
  1549 
  1483     b isNil ifTrue:[
  1550     b isNil ifTrue:[
  1484         aCompiler removeTempVar
  1551         aCompiler removeTempVar
  1485     ] ifFalse:[
  1552     ] ifFalse:[
  1486         b removeTempVar
  1553         b removeTempVar
  1487     ]
  1554     ].
       
  1555 
       
  1556     stopVarIndex notNil ifTrue:[
       
  1557         b isNil ifTrue:[
       
  1558             aCompiler removeTempVar
       
  1559         ] ifFalse:[
       
  1560             b removeTempVar
       
  1561         ]
       
  1562     ].
       
  1563 
       
  1564     "Created: 27.6.1997 / 12:48:18 / cg"
       
  1565     "Modified: 27.6.1997 / 13:43:06 / cg"
       
  1566 !
       
  1567 
       
  1568 codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
  1569     "generate code for n to:n do:[:unusedArg | ... ]"
       
  1570 
       
  1571     |pos pos2 start stop lateEval theBlock loopVarIndex
       
  1572      stopVarIndex|
       
  1573 
       
  1574     "/ NOTICE: could compile it as a timesRepeat, if
       
  1575     "/ the loop-counter is not accessed within the loop-block.
       
  1576     "/ This generates somewhat (15%) faster code, but makes
       
  1577     "/ debugging somewhat difficult (no loop-value seen in debugger).
       
  1578 
       
  1579     start := receiver.
       
  1580     stop := (argArray at:1).
       
  1581 "/    stop isConstant ifFalse:[self halt:'should not happen'].
       
  1582 "/    (stop evaluate isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
       
  1583 
       
  1584     start codeOn:aStream inBlock:b for:aCompiler.
       
  1585 
       
  1586     lateEval := false.
       
  1587 
       
  1588     valueNeeded ifTrue:[
       
  1589         "/ easily reconstructable - no need to keep on stack
       
  1590         start isConstant ifTrue:[
       
  1591             (start evaluate isMemberOf:SmallInteger) ifTrue:[
       
  1592                 lateEval := true.
       
  1593             ]
       
  1594         ].
       
  1595         lateEval ifFalse:[
       
  1596             aStream nextPut:#dup
       
  1597         ].
       
  1598     ].
       
  1599 
       
  1600     "/ if stop is not constant, and not an argVar,
       
  1601     "/  evaluate it into a temp slot ...
       
  1602 
       
  1603     (stop isConstant and:[stop type == #Integer]) ifFalse:[
       
  1604         "/ a method/blockArg is constant as well ...
       
  1605         (stop isVariable and:[stop isArgument]) ifFalse:[
       
  1606             stop codeOn:aStream inBlock:b for:aCompiler.
       
  1607 
       
  1608             b isNil ifTrue:[
       
  1609                 stopVarIndex := aCompiler addTempVar.
       
  1610                 aStream nextPut:#storeMethodVar; nextPut:stopVarIndex.
       
  1611             ] ifFalse:[
       
  1612                 stopVarIndex := b addTempVar.
       
  1613                 aStream nextPut:#storeBlockVar; nextPut:stopVarIndex.
       
  1614             ].
       
  1615         ]
       
  1616     ].
       
  1617 
       
  1618     pos := aStream position.
       
  1619 
       
  1620     aStream nextPut:#dup.
       
  1621     stopVarIndex notNil ifTrue:[
       
  1622         b isNil ifTrue:[
       
  1623             aStream nextPut:#pushMethodVar; nextPut:stopVarIndex.
       
  1624         ] ifFalse:[
       
  1625             aStream nextPut:#pushBlockVar; nextPut:stopVarIndex.
       
  1626         ]
       
  1627     ] ifFalse:[
       
  1628         stop codeOn:aStream inBlock:b for:aCompiler.
       
  1629     ].
       
  1630     aStream nextPut:#>.
       
  1631     (aCompiler hasLineNumber:selector) ifTrue:[
       
  1632         aStream nextPut:lineNr.
       
  1633     ].
       
  1634     aStream nextPut:#trueJump.
       
  1635     pos2 := aStream position.
       
  1636     aStream nextPut:0.
       
  1637 
       
  1638     theBlock := argArray at:2.
       
  1639 
       
  1640     "/ need a temporary in the outer context for
       
  1641     "/ the loop ...
       
  1642     b isNil ifTrue:[
       
  1643         loopVarIndex := aCompiler addTempVar.
       
  1644         aStream nextPut:#dup.
       
  1645         aStream nextPut:#storeMethodVar; nextPut:loopVarIndex.
       
  1646     ] ifFalse:[
       
  1647         loopVarIndex := b addTempVar.
       
  1648         aStream nextPut:#dup.
       
  1649         aStream nextPut:#storeBlockVar; nextPut:loopVarIndex.
       
  1650     ].
       
  1651     theBlock indexOfFirstTemp:loopVarIndex.
       
  1652 
       
  1653     theBlock codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
       
  1654 
       
  1655     "/ increment counter & jump back.
       
  1656 
       
  1657     aStream nextPut:#plus1; nextPut:lineNr; nextPut:#jump; nextPut:pos.
       
  1658 
       
  1659     (aStream contents) at:pos2 put:(aStream position).
       
  1660     aStream nextPut:#drop.  "/ drop run variable
       
  1661     lateEval ifTrue:[
       
  1662         start codeOn:aStream inBlock:b for:aCompiler.
       
  1663     ].
       
  1664 
       
  1665     "/ no need to nil-out loop-tempVar to help GC
       
  1666     "/ (its integer, anyway).
       
  1667 
       
  1668     b isNil ifTrue:[
       
  1669         aCompiler removeTempVar
       
  1670     ] ifFalse:[
       
  1671         b removeTempVar
       
  1672     ].
       
  1673 
       
  1674     stopVarIndex notNil ifTrue:[
       
  1675         b isNil ifTrue:[
       
  1676             aCompiler removeTempVar
       
  1677         ] ifFalse:[
       
  1678             b removeTempVar
       
  1679         ]
       
  1680     ].
  1488 
  1681 
  1489     "Created: 26.6.1997 / 10:58:47 / cg"
  1682     "Created: 26.6.1997 / 10:58:47 / cg"
  1490     "Modified: 26.6.1997 / 11:04:05 / cg"
  1683     "Modified: 27.6.1997 / 13:21:54 / cg"
  1491 !
  1684 !
  1492 
  1685 
  1493 codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1686 codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1494     "generate code for
  1687     "generate code for
  1495         [...] whileXXX:[ ... ] 
  1688         [...] whileXXX:[ ... ] 
  1927 ! !
  2120 ! !
  1928 
  2121 
  1929 !MessageNode class methodsFor:'documentation'!
  2122 !MessageNode class methodsFor:'documentation'!
  1930 
  2123 
  1931 version
  2124 version
  1932     ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.73 1997-06-26 11:22:48 cg Exp $'
  2125     ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.74 1997-06-27 12:08:18 cg Exp $'
  1933 ! !
  2126 ! !