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-message-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 <nicolas.cellier.aka.nice@gmai >> l.com>: >> >>> 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 >>>> >>>> >>> >> >
