VarNode.st
changeset 559 42cf4afd99b3
parent 554 d5e548c4d49d
child 566 90969df02c85
--- a/VarNode.st	Wed Jun 25 15:22:40 1997 +0200
+++ b/VarNode.st	Thu Jun 26 10:41:55 1997 +0200
@@ -192,8 +192,9 @@
     ^ self
 !
 
-codeOn:aStream inBlock:codeBlock for:aCompiler
-    |theCode b deltaLevel litIndex specialGlobalIndex|
+codeLoadOn:aStream type:type index:index inBlock:codeBlock for:aCompiler
+    |theCode b deltaLevel litIndex specialGlobalIndex
+     bvIdx bvTyp blocksCode|
 
     (type == #MethodArg) ifTrue:[
         (index <= 4) ifTrue:[
@@ -236,24 +237,68 @@
 
     ((type == #BlockArg) 
     or:[type == #BlockVariable]) ifTrue:[
-        "/ find deltaLevel to block, where argument was defined
+        "/ compiling for codeBlock; accessing variable in block.
+
+        bvIdx := index.
+        bvTyp := type.
+
+        "/ find the context where that variable is contained physically
+        blocksCode := block.
+        [blocksCode notNil and:[blocksCode isInlineBlock]] whileTrue:[
+            blocksCode := blocksCode home
+        ].
+
+        "/ find deltaLevel from code-context to the containing block
         b := codeBlock.
         deltaLevel := 0.
-        [b notNil and:[b ~~ block]] whileTrue:[
+        [b notNil and:[b ~~ blocksCode]] whileTrue:[
             b isInlineBlock ifFalse:[
                 deltaLevel := deltaLevel + 1
             ].
             b := b home
         ].
 
-        b isInlineBlock ifTrue:[
-            "/ an inlined block. Generate a pushTempVar
+        b isNil ifTrue:[
+            codeBlock isNil ifTrue:[
+                "/ a var of a block which is inlined in the method. 
+                "/ Generate a pushMVAR
+
+                bvIdx := block indexOfFirstTemp + index - 1.
+                type == #BlockVariable ifTrue:[
+                    bvIdx := bvIdx + block numArgs
+                ].
+                ^ self 
+                    codeLoadOn:aStream
+                    type:#MethodVariable
+                    index:bvIdx
+                    inBlock:codeBlock
+                    for:aCompiler
+            ].
+
+            "/ a var of a block which is inlined in the outer block.
+            "/ Generate a pushBVAR
+
+            bvIdx := block indexOfFirstTemp + index - 1.
+            type == #BlockVariable ifTrue:[
+                bvIdx := bvIdx + block numArgs
+            ].
+            bvTyp := #BlockVariable.
+        ] ifFalse:[
+            block isInlineBlock ifTrue:[
+                "/ a var of a block which is inlined in another block.
+                "/ Generate a pushBVAR / pushOuterBVAR
+                bvIdx := block indexOfFirstTemp + index - 1.
+                type == #BlockVariable ifTrue:[
+                    bvIdx := bvIdx + block numArgs
+                ].
+                bvTyp := #BlockVariable.
+            ]
         ].
 
-        (type == #BlockVariable) ifTrue:[
+        (bvTyp == #BlockVariable) ifTrue:[
             (deltaLevel == 0) ifTrue:[
-                index <= 3 ifTrue:[
-                    aStream nextPut:(#(pushBlockVar1 pushBlockVar2 pushBlockVar3) at:index).
+                bvIdx <= 3 ifTrue:[
+                    aStream nextPut:(#(pushBlockVar1 pushBlockVar2 pushBlockVar3) at:bvIdx).
                     ^ self
                 ].
                 aStream nextPut:#pushBlockVar.
@@ -262,10 +307,9 @@
             ].
         ] ifFalse:[
             (deltaLevel == 0) ifTrue:[
-                (index <= 4) ifTrue:[
-                    theCode := #(pushBlockArg1 pushBlockArg2 pushBlockArg3
-                                 pushBlockArg4) at:index.
-                    aStream nextPut:theCode.
+                (bvIdx <= 4) ifTrue:[
+                    aStream nextPut:(#(pushBlockArg1 pushBlockArg2 pushBlockArg3
+                                       pushBlockArg4) at:bvIdx).
                     ^ self
                 ].
                 aStream nextPut:#pushBlockArg.
@@ -281,7 +325,7 @@
                 ].
             ].
         ].
-        aStream nextPut:index.
+        aStream nextPut:bvIdx.
         ^ self
     ].
 
@@ -333,11 +377,27 @@
     "not reached"
     self halt:'bad type'.
 
-    "Modified: 25.6.1997 / 14:11:49 / cg"
+    "Created: 25.6.1997 / 16:14:17 / cg"
+    "Modified: 26.6.1997 / 10:15:11 / cg"
+!
+
+codeOn:aStream inBlock:codeBlock for:aCompiler
+    self
+        codeLoadOn:aStream type:type index:index inBlock:codeBlock for:aCompiler
+
+    "Modified: 26.6.1997 / 10:06:10 / cg"
 !
 
 codeStoreOn:aStream inBlock:codeBlock valueNeeded:valueNeeded for:aCompiler
-    |theCode b deltaLevel litIndex|
+    self
+        codeStoreOn:aStream type:type index:index
+        inBlock:codeBlock valueNeeded:valueNeeded for:aCompiler
+
+    "Modified: 25.6.1997 / 16:15:28 / cg"
+!
+
+codeStoreOn:aStream type:type index:index inBlock:codeBlock valueNeeded:valueNeeded for:aCompiler
+    |theCode b deltaLevel litIndex bvIdx blocksCode|
 
     valueNeeded ifTrue:[
         aStream nextPut:#dup
@@ -370,26 +430,62 @@
     ].
 
     (type == #BlockVariable) ifTrue:[
+        bvIdx := index.
+        
+        "/ find the context where that variable is contained physically
+        blocksCode := block.
+        [blocksCode notNil and:[blocksCode isInlineBlock]] whileTrue:[
+            blocksCode := blocksCode home
+        ].
+
         "find deltaLevel to block, where variable was defined"
         b := codeBlock.
         deltaLevel := 0.
-        [b notNil and:[b ~~ block]] whileTrue:[
+        [b notNil and:[b ~~ blocksCode]] whileTrue:[
             b isInlineBlock ifFalse:[
                 deltaLevel := deltaLevel + 1
             ].
             b := b home
         ].
 
+        b isNil ifTrue:[
+            codeBlock isNil ifTrue:[
+                "/ a block which is inlined in the method. 
+                "/ Generate a pushMVAR
+
+                bvIdx := block indexOfFirstTemp + index - 1.
+                bvIdx := bvIdx + block numArgs.
+                ^ self
+                    codeStoreOn:aStream 
+                    type:#MethodVariable index:bvIdx 
+                    inBlock:codeBlock 
+                    valueNeeded:false       "/ already dupped if value is needed
+                    for:aCompiler
+            ].
+            "/ a var of a block which is inlined in the outer block.
+            "/ Generate a pushBVAR
+
+            bvIdx := block indexOfFirstTemp + index - 1.
+            bvIdx := bvIdx + block numArgs.
+        ] ifFalse:[
+            block isInlineBlock ifTrue:[
+                "/ a var of a block which is inlined in another block.
+                "/ Generate a pushBVAR / pushOuterBVAR
+                bvIdx := block indexOfFirstTemp + index - 1.
+                bvIdx := bvIdx + block numArgs.
+            ]
+        ].
+
         (deltaLevel == 0) ifTrue:[
-            index <= 3 ifTrue:[
-                aStream nextPut:(#(storeBlockVar1 storeBlockVar2 storeBlockVar3) at:index).
+            bvIdx <= 3 ifTrue:[
+                aStream nextPut:(#(storeBlockVar1 storeBlockVar2 storeBlockVar3) at:bvIdx).
                 ^ self
             ].
             aStream nextPut:#storeBlockVar
         ] ifFalse:[
             aStream nextPut:#storeOuterBlockVar; nextPut:deltaLevel
         ].
-        aStream nextPut:index.
+        aStream nextPut:bvIdx.
         ^ self
     ].
 
@@ -421,7 +517,8 @@
     "not reached"
     ^ self error:'bad assignment'
 
-    "Modified: 25.6.1997 / 14:12:18 / cg"
+    "Created: 25.6.1997 / 16:14:40 / cg"
+    "Modified: 26.6.1997 / 10:18:53 / cg"
 ! !
 
 !VariableNode methodsFor:'enumeration'!
@@ -578,5 +675,5 @@
 !VariableNode class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/Attic/VarNode.st,v 1.28 1997-06-25 12:23:06 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/Attic/VarNode.st,v 1.29 1997-06-26 08:41:55 cg Exp $'
 ! !