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 >>>>>> >>>>>> >>>>> >>>> >>> >> >
