Can we collect this as a nice 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- > 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 >>>>> >>>>> >>>> >>> >> >
