Swap operation for stack machinery?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Swap operation for stack machinery?

Christoph Thiede

Hi all,


I am curious to know whether the Squeak Context model provides any operation to swap the latest two elements from the stack. Something like:


doSwap

    | first second |

    first := self pop.

    second := self pop.

    self push: first.

    self push: second.


If it exists, I could not find it yet. If it does not exist, would you see any need to implement it (for both VM & simulation, of course)?


To me, this appears to be the most performant approach to implement a parametrized #caseError:. Something like:


81 <75> pushConstant: 0

82 <88> dup

83 <76> pushConstant: 1

84 <B6> send: =

85 <9A> jumpFalse: 89

86 <87> pop

87 <22> pushConstant: #one

88 <96> jumpTo: 97

89 <77> pushConstant: 2

90 <B6> send: =

91 <99> jumpFalse: 94

92 <21> pushConstant: #two

93 <91> jumpTo: 97

94 <70> self

95 <xx> swap

96 <D0> send: caseError:

97 <87> pop


Otherwise, we would need an extra temporary variable here.
Looking forward to your answers.


Best,

Christoph



Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: Swap operation for stack machinery?

Eliot Miranda-2
Hi Christoph,

On Feb 23, 2020, at 9:01 AM, Thiede, Christoph <[hidden email]> wrote:



Hi all,


I am curious to know whether the Squeak Context model provides any operation to swap the latest two elements from the stack. Something like:


doSwap

    | first second |

    first := self pop.

    second := self pop.

    self push: first.

    self push: second.


If it exists, I could not find it yet. If it does not exist, would you see any need to implement it (for both VM & simulation, of course)?


To me, this appears to be the most performant approach to implement a parametrized #caseError:. Something like:


81 <75> pushConstant: 0

82 <88> dup

83 <76> pushConstant: 1

84 <B6> send: =

85 <9A> jumpFalse: 89

86 <87> pop

87 <22> pushConstant: #one

88 <96> jumpTo: 97

89 <77> pushConstant: 2

90 <B6> send: =

91 <99> jumpFalse: 94

92 <21> pushConstant: #two

93 <91> jumpTo: 97

94 <70> self

95 <xx> swap

96 <D0> send: caseError:

97 <87> pop


Otherwise, we would need an extra temporary variable here.
Looking forward to your answers.

Interesting! No, there’s no swap as yet. If SqueakV3PlusClosures has an unused bytecode I’d say go for it. (SistaV1 definitely has unused bytecodes).  But it’ll take a while got this to percolate through your protection VMs so make a fix not dependent on the swap bytecode as well.


Best,

Christoph




Reply | Threaded
Open this post in threaded view
|

Re: Swap operation for stack machinery?

Eliot Miranda-2
In reply to this post by Christoph Thiede


On Feb 23, 2020, at 9:01 AM, Thiede, Christoph <[hidden email]> wrote:



Hi all,


I am curious to know whether the Squeak Context model provides any operation to swap the latest two elements from the stack. Something like:


doSwap

    | first second |

    first := self pop.

    second := self pop.

    self push: first.

    self push: second.


If it exists, I could not find it yet. If it does not exist, would you see any need to implement it (for both VM & simulation, of course)?


To me, this appears to be the most performant approach to implement a parametrized #caseError:. Something like:


81 <75> pushConstant: 0

82 <88> dup

83 <76> pushConstant: 1

84 <B6> send: =

85 <9A> jumpFalse: 89

86 <87> pop

87 <22> pushConstant: #one

88 <96> jumpTo: 97

89 <77> pushConstant: 2

90 <B6> send: =

91 <99> jumpFalse: 94

92 <21> pushConstant: #two

93 <91> jumpTo: 97

94 <70> self

95 <xx> swap

96 <D0> send: caseError:

97 <87> pop


Otherwise, we would need an extra temporary variable here.

BTW there is a horrible hack which avoids the extra temp.  Since the stack pointer and stack height are known during code generation then instead of this:

94 <70> self

95 <xx> swap

96 <D0> send: caseError:

one could emit this sequence:

    dup
    push self
    pop and store temp: N (where N gets to sp - 1)
    send caseError:

Looking forward to your answers.


Best,

Christoph




Reply | Threaded
Open this post in threaded view
|

Re: Swap operation for stack machinery?

Christoph Thiede

Hi Eliot,


Interesting! No, there’s no swap as yet. If SqueakV3PlusClosures has an unused bytecode I’d say go for it. (SistaV1 definitely has unused bytecodes).


Great to hear this! I would be glad to join the implementation of a new bytecode :-)


pop and store temp: N (where N gets to sp - 1)


Which bytecode are you referring to? #genStoreTemp:? This sounds indeed hacky ...

Just another question about bytecodes: Do we currently have any tools for exploring and playing around with the bytecodes? I would love to do say something like

Encoder default generateMethod: [:stack :encoder |
    encoder genPushReceiver.
    encoder genReturnTop].

But afaik, at the moment I have to manipulate the implementation of #emitCodeForValue:encoder: or so if I would like to test something new. Am I missing any existing tools to do so?

(Imagine if you could write your own bytecodes directly into a CodeHolder ... :D)

Best,
Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Eliot Miranda <[hidden email]>
Gesendet: Sonntag, 23. Februar 2020 18:19 Uhr
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] Swap operation for stack machinery?
 


On Feb 23, 2020, at 9:01 AM, Thiede, Christoph <[hidden email]> wrote:



Hi all,


I am curious to know whether the Squeak Context model provides any operation to swap the latest two elements from the stack. Something like:


doSwap

    | first second |

    first := self pop.

    second := self pop.

    self push: first.

    self push: second.


If it exists, I could not find it yet. If it does not exist, would you see any need to implement it (for both VM & simulation, of course)?


To me, this appears to be the most performant approach to implement a parametrized #caseError:. Something like:


81 <75> pushConstant: 0

82 <88> dup

83 <76> pushConstant: 1

84 <B6> send: =

85 <9A> jumpFalse: 89

86 <87> pop

87 <22> pushConstant: #one

88 <96> jumpTo: 97

89 <77> pushConstant: 2

90 <B6> send: =

91 <99> jumpFalse: 94

92 <21> pushConstant: #two

93 <91> jumpTo: 97

94 <70> self

95 <xx> swap

96 <D0> send: caseError:

97 <87> pop


Otherwise, we would need an extra temporary variable here.

BTW there is a horrible hack which avoids the extra temp.  Since the stack pointer and stack height are known during code generation then instead of this:

94 <70> self

95 <xx> swap

96 <D0> send: caseError:

one could emit this sequence:

    dup
    push self
    pop and store temp: N (where N gets to sp - 1)
    send caseError:

Looking forward to your answers.


Best,

Christoph




Carpe Squeak!