2016-12-05 10:55 GMT+01:00 Stephane Ducasse <[email protected]>:

> Can we collect this as a nice class comment?
>

Yes, I 'll try to add this as class comment.


>
> On Mon, Dec 5, 2016 at 10:42 AM, Nicolai Hess <[email protected]>
> wrote:
>
>>
>>
>> 2016-12-05 10:08 GMT+01:00 Clément Bera <[email protected]>:
>>
>>> Both are used for each compilation. They're instance variables of each
>>> other.
>>>
>>> | *Who decides which to use*
>>>
>>> In each AST node translation, you know for each value which one to use.
>>>
>>> For example, when translating a return, the value to return needs to be
>>> pushed on stack, so the valueTranslator is used:
>>> visitReturnNode: aReturnNode
>>> valueTranslator visitNode: aReturnNode value.
>>> methodBuilder returnTop.
>>>
>>> Yet, in #visitMethodNode:, you can see that the effectTranslator is
>>> used, because no value is pushed on stack at the end of the method body:
>>> ...effectTranslator visitNode: aMethodNode body...
>>>
>>> Then some behavior can be conditional, for example, in OCASTTranslator
>>> >> #visitArrayNode:
>>> ...^ self visitLargeArrayNode: anArrayNode ]...
>>> The self here represents either the value or effect translator and
>>> dispatches to the correct method using polymorphism.
>>>
>>> *| when do I know that I need to use ?*
>>>
>>> If you need the value on stack, use the valueTranslator.
>>> If you need the effect but not the value, use the effectTranslator.
>>>
>>> If you're implementing something in the valueTranslator, it needs to
>>> push something on stack at the end.
>>> If you're implementing something in the effectTranslator, it doesn't
>>> push anything on stack at the end.
>>>
>>> | * the effect translator only or the value translator?*
>>>
>>> I think you always need both.Let's take this method:
>>>
>>> MyClass>>return1
>>>      ^ 42.0
>>>
>>> The method uses the effect translator to translate is body (^ 42.0).
>>> The body is a sequence node, with one statement only. A sequence node
>>> translates all its statements for effect, except the last one which depends
>>> on how it's called (in this case, it's called with the effectTranslator, so
>>> it's also for effect). Sequence translated for value are used in inlined
>>> control structures.
>>> So the first statement is translated for effect.
>>> The return node asks first the value translator to push the float (42.0)
>>> on stack, generating pushLiteral: 42.0
>>> Then the return node generates the returnTop instruction.
>>>
>>> **
>>>
>>> I don't know how to explain better. I like to think of this problem as
>>> the difference between procedures and functions in old programming
>>> languages.
>>>
>>
>> Thank you clement, this helped a lot.
>>
>> Some background why I am asking:
>>
>> http://forum.world.st/Stack-underflow-with-meta-links-on-mes
>> sage-nodes-tp4925154.html
>>
>> Adding a "before" metalink to a message node like "1+1" and trying use a
>> the receiver value within the metalink
>> will raise a stack underflow error.
>> This is caused by the RFEReceiverReification, it will pop the arguments
>> of the stack, to access the receiver. It will
>> create temporaries for the popped arguments and expects this temporaries
>> to be pushed on to the stack again, after storing the
>> receiver value.
>> But this does not work (the arguments aren't pushed back).
>> It works if we assign this metalink to a return node *value*, the "1+1" in
>> ^ 1 + 1
>>
>> Now there is no stack underflow, because the return node value uses the
>> valueTranslator that does do the pushTemp, as expected by the
>> RFEReceiverReification.
>> (Best seen by comparing both IRs.
>> First, link is attached to a message that is not a return statement:
>>
>> label: 1
>> pushLiteral: '1'
>> pushLiteral: '1'
>> popIntoTemp: #RFArg1RFReification
>> storeTemp: #RFReceiverReificationVar
>> pushLiteralVariable: RFMetaLink
>> pushTemp: #RFReceiverReificationVar
>> pushLiteral: RBMessageNode('1' , '1')
>> send: #value:value:
>> popTop
>> send: #,
>> popTop
>> returnReceiver
>>
>> Next, if the link is attached to the expression of a return statement:
>>
>> label: 1
>> pushLiteral: '1'
>> pushLiteral: '1'
>> popIntoTemp: #RFArg1RFReification
>> storeTemp: #RFReceiverReificationVar
>> pushTemp: #RFArg1RFReification                           "<<<- this is
>> missing in the other IR"
>> pushLiteralVariable: RFMetaLink
>> pushTemp: #RFReceiverReificationVar
>> pushLiteral: RBMessageNode('1' , '1')
>> send: #value:value:
>> popTop
>> send: #,
>> returnTop
>>
>>
>> Solution ?
>>
>> @Marcus,
>> can we *always* use the valueTranslator when visiting a link preamble ?
>> (I tried this, the above method now works, and all tests are green, but I
>> am not sure if this is the right solution).
>>
>> nicolai
>>
>>
>>
>>>
>>> On Mon, Dec 5, 2016 at 9:36 AM, Nicolai Hess <[email protected]>
>>> wrote:
>>>
>>>>
>>>>
>>>> 2016-12-05 8:51 GMT+01:00 Nicolas Cellier <
>>>> [email protected]>:
>>>>
>>>>> Translate AST to byte codes?
>>>>>
>>>>
>>>> (For opal, this first creates the intermediate representation (IR), but
>>>> yes translating from AST to (finally) byte codes)
>>>>
>>>>
>>>>> One for the case when we don't care of the result (we will pop it off
>>>>> the stack), we just want the effect.
>>>>>
>>>>
>>>> Ok.
>>>>
>>>>
>>>>> The other case when we want to keep the resulting value on the stack.
>>>>>
>>>>
>>>> Who decides which to use, when do I know that I need to use, the effect
>>>> translator only or the value translator?
>>>>
>>>>
>>>>>
>>>>> 2016-12-05 8:47 GMT+01:00 Nicolai Hess <[email protected]>:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> I need a short description for what the OCASTTranslator subclasses
>>>>>> OCASTTranslatorForEffect
>>>>>> OCASTTranslatorForValue
>>>>>> are.
>>>>>>
>>>>>> I don't fully understand the usage.
>>>>>>
>>>>>> thanks in advance
>>>>>> Nicolai
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

Reply via email to