BlockClosure source code
Hi, I need to extract a source code from a block closure and I found something strange: [ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ]. Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]' Print of the second line returns: '[ ctx atEnd ]' And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4. Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line? Thank you in advance! Jan
Can you provide a simple test to execute?
On 08.10.2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi,
I need to extract a source code from a block closure and I found something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line?
Thank you in advance! Jan
On 08 Oct 2014, at 17:35, Max Leske <maxleske@gmail.com> wrote:
Can you provide a simple test to execute?
[ :ctx | [ ctx atEnd ] whileTrue:[1+2 ] ] sourceNode
On 08.10.2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi,
I need to extract a source code from a block closure and I found something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line?
Thank you in advance! Jan
On Wed, Oct 8, 2014 at 5:39 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 08 Oct 2014, at 17:35, Max Leske <maxleske@gmail.com> wrote:
Can you provide a simple test to execute?
[ :ctx | [ ctx atEnd ] whileTrue:[1+2 ] ] sourceNode
On 08.10.2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi,
I need to extract a source code from a block closure and I found
something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3
and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx
atEnd ] whileTrue:[ ] ]' for a second line?
Thank you in advance!
Can you check https://pharo.fogbugz.com/f/cases/14284/fix-sourceNode-for-Blocks This solves the issue for Blocks... for contexts there are still problems, but this is another step...
On 08 Oct 2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi,
I need to extract a source code from a block closure and I found something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line?
I think this is an example that exposes a bug that we still have in the source mapping⦠on Context, see sourceNode "Return the source node of the method or the block corresponding to the receiver" ^ (method sourceNodeForPC: self neighborPCWithCorrectMapping) enclosingMethodOrBlockNode "Uncomment the following once the pc->AST mapping is fixed" "^ (method sourceNodeForPC: (pc ifNil: [ self startpc ])) enclosingMethodOrBlockNode" #neighborPCWithCorrectMapping returns the inner send, which is wrong⦠this method needs to be rethought. Marcus
On 8 oct. 2014, at 17:49, Marcus Denker <marcus.denker@inria.fr> wrote:
On 08 Oct 2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi,
I need to extract a source code from a block closure and I found something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line?
I think this is an example that exposes a bug that we still have in the source mapping⦠on Context, see
sourceNode "Return the source node of the method or the block corresponding to the receiver" ^ (method sourceNodeForPC: self neighborPCWithCorrectMapping) enclosingMethodOrBlockNode "Uncomment the following once the pc->AST mapping is fixed" "^ (method sourceNodeForPC: (pc ifNil: [ self startpc ])) enclosingMethodOrBlockNode"
#neighborPCWithCorrectMapping returns the inner send, which is wrong⦠this method needs to be rethought.
Yes it should. But that's not easy with optimized loop messages like whileTrue: & co. Ideally, the source mapping needs to be fixed because that's the reason this method exists in the first place. Or else we accepts that "1 to: 1 do: [ :i | ^ thisContext sourceNode ]" returns a method node instead of a block node and use a different implementation.
Marcus
On 08 Oct 2014, at 18:28, Camille Teruel <camille.teruel@gmail.com> wrote:
On 8 oct. 2014, at 17:49, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 08 Oct 2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch <mailto:kurs@iam.unibe.ch>> wrote:
Hi,
I need to extract a source code from a block closure and I found something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line?
I think this is an example that exposes a bug that we still have in the source mapping⦠on Context, see
sourceNode "Return the source node of the method or the block corresponding to the receiver" ^ (method sourceNodeForPC: self neighborPCWithCorrectMapping) enclosingMethodOrBlockNode "Uncomment the following once the pc->AST mapping is fixed" "^ (method sourceNodeForPC: (pc ifNil: [ self startpc ])) enclosingMethodOrBlockNode"
#neighborPCWithCorrectMapping returns the inner send, which is wrong⦠this method needs to be rethought.
Yes it should. But that's not easy with optimized loop messages like whileTrue: & co. Ideally, the source mapping needs to be fixed because that's the reason this method exists in the first place.
The first step is to record a range for the byte code that an IRNode createsâ¦
Or else we accepts that "1 to: 1 do: [ :i | ^ thisContext sourceNode ]" returns a method node instead of a block node and use a different implementation.
Marcus
Hi All, Thank you for the replies. I see it is not an easy bug to fix. Do you have any idea, when this can be fixed? Or can you suggest me some other way/workaround, how to get/generate the source code of a block? Thank you very much! Cheers, Jan BTW, the tests to execute: self assert: [ :ctx | [ ctx atEnd ] ifTrue: [ ] ] asString = '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]' self assert: [ :ctx | [ ctx atEnd ] whileTrue: [ ] ] asString = '[ :ctx | [ ctx atEnd ] whileTrue: [ ] ]' On 8 October 2014 18:43, Marcus Denker <marcus.denker@inria.fr> wrote:
On 08 Oct 2014, at 18:28, Camille Teruel <camille.teruel@gmail.com> wrote:
On 8 oct. 2014, at 17:49, Marcus Denker <marcus.denker@inria.fr> wrote:
On 08 Oct 2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi,
I need to extract a source code from a block closure and I found something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line?
I think this is an example that exposes a bug that we still have in the source mapping⦠on Context, see
sourceNode "Return the source node of the method or the block corresponding to the receiver" ^ (method sourceNodeForPC: self neighborPCWithCorrectMapping) enclosingMethodOrBlockNode "Uncomment the following once the pc->AST mapping is fixed" "^ (method sourceNodeForPC: (pc ifNil: [ self startpc ])) enclosingMethodOrBlockNode"
#neighborPCWithCorrectMapping returns the inner send, which is wrong⦠this method needs to be rethought.
Yes it should. But that's not easy with optimized loop messages like whileTrue: & co. Ideally, the source mapping needs to be fixed because that's the reason this method exists in the first place.
The first step is to record a range for the byte code that an IRNode createsâ¦
Or else we accepts that "1 to: 1 do: [ :i | ^ thisContext sourceNode ]" returns a method node instead of a block node and use a different implementation.
Marcus
On 10 Oct 2014, at 10:57, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi All,
Thank you for the replies. I see it is not an easy bug to fix. Do you have any idea, when this can be fixed?
I will try to fix it next week...
Or can you suggest me some other way/workaround, how to get/generate the source code of a block?
The old compiler used a hack to decompile blocks for getting a textual representation⦠one could port the code from Pharo2 to the Package OpalDecompiler in Pharo4. (but I actually like the current scheme of using the byte code-offset-to-AST mapping more). Marcus
Thank you very much! Cheers, Jan
BTW, the tests to execute: self assert: [ :ctx | [ ctx atEnd ] ifTrue: [ ] ] asString = '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]' self assert: [ :ctx | [ ctx atEnd ] whileTrue: [ ] ] asString = '[ :ctx | [ ctx atEnd ] whileTrue: [ ] ]'
On 8 October 2014 18:43, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 08 Oct 2014, at 18:28, Camille Teruel <camille.teruel@gmail.com <mailto:camille.teruel@gmail.com>> wrote:
On 8 oct. 2014, at 17:49, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 08 Oct 2014, at 16:46, Jan Kurš <kurs@iam.unibe.ch <mailto:kurs@iam.unibe.ch>> wrote:
Hi,
I need to extract a source code from a block closure and I found something strange:
[ :ctx | [ ctx atEnd ] ifTrue: [ ] ] . [ :ctx | [ ctx atEnd ] whileTrue:[ ] ].
Print of the first line returns: '[ :ctx | [ ctx atEnd ] ifTrue: [ ] ]'
Print of the second line returns: '[ ctx atEnd ]'
And honestly, I have no idea why. This behaviour was observed in Pharo3 and Pharo4.
Is there a way how to get a consistent result, i.e. '[ :ctx | [ ctx atEnd ] whileTrue:[ ] ]' for a second line?
I think this is an example that exposes a bug that we still have in the source mapping⦠on Context, see
sourceNode "Return the source node of the method or the block corresponding to the receiver" ^ (method sourceNodeForPC: self neighborPCWithCorrectMapping) enclosingMethodOrBlockNode "Uncomment the following once the pc->AST mapping is fixed" "^ (method sourceNodeForPC: (pc ifNil: [ self startpc ])) enclosingMethodOrBlockNode"
#neighborPCWithCorrectMapping returns the inner send, which is wrong⦠this method needs to be rethought.
Yes it should. But that's not easy with optimized loop messages like whileTrue: & co. Ideally, the source mapping needs to be fixed because that's the reason this method exists in the first place.
The first step is to record a range for the byte code that an IRNode createsâ¦
Or else we accepts that "1 to: 1 do: [ :i | ^ thisContext sourceNode ]" returns a method node instead of a block node and use a different implementation.
Marcus
On 10 Oct 2014, at 12:29, Marcus Denker <marcus.denker@inria.fr> wrote:
On 10 Oct 2014, at 10:57, Jan Kurš <kurs@iam.unibe.ch <mailto:kurs@iam.unibe.ch>> wrote:
Hi All,
Thank you for the replies. I see it is not an easy bug to fix. Do you have any idea, when this can be fixed?
I will try to fix it next week...
Or can you suggest me some other way/workaround, how to get/generate the source code of a block?
The old compiler used a hack to decompile blocks for getting a textual representation⦠one could port the code from Pharo2 to the Package OpalDecompiler in Pharo4. (but I actually like the current scheme of using the byte code-offset-to-AST mapping more).
step one: A nice tool⦠GTInspector view of the byte codes that highlights what is thinks is the corresponding code in the source. (This living Bytecode view replaces what before just printed out the #longPrintString of the CompiledMethod):
Very nice !! On 14 Oct 2014, at 16:42, Marcus Denker <marcus.denker@inria.fr> wrote:
On 10 Oct 2014, at 12:29, Marcus Denker <marcus.denker@inria.fr> wrote:
On 10 Oct 2014, at 10:57, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi All,
Thank you for the replies. I see it is not an easy bug to fix. Do you have any idea, when this can be fixed?
I will try to fix it next week...
Or can you suggest me some other way/workaround, how to get/generate the source code of a block?
The old compiler used a hack to decompile blocks for getting a textual representation⦠one could port the code from Pharo2 to the Package OpalDecompiler in Pharo4. (but I actually like the current scheme of using the byte code-offset-to-AST mapping more).
step one: A nice tool⦠GTInspector view of the byte codes that highlights what is thinks is the corresponding code in the source. (This living Bytecode view replaces what before just printed out the #longPrintString of the CompiledMethod):
<Playground.jpeg>
I love these little things. This is a great example of how value should not be confused with cost. Small can be quite big after all :) Doru On Tue, Oct 14, 2014 at 4:46 PM, Sven Van Caekenberghe <sven@stfx.eu> wrote:
Very nice !!
On 14 Oct 2014, at 16:42, Marcus Denker <marcus.denker@inria.fr> wrote:
On 10 Oct 2014, at 12:29, Marcus Denker <marcus.denker@inria.fr> wrote:
On 10 Oct 2014, at 10:57, Jan Kurš <kurs@iam.unibe.ch> wrote:
Hi All,
Thank you for the replies. I see it is not an easy bug to fix. Do you
have any idea, when this can be fixed?
I will try to fix it next week...
Or can you suggest me some other way/workaround, how to get/generate the source code of a block?
The old compiler used a hack to decompile blocks for getting a textual representation⦠one could port the code from Pharo2 to the Package OpalDecompiler in Pharo4. (but I actually like the current scheme of using the byte code-offset-to-AST mapping more).
step one: A nice tool⦠GTInspector view of the byte codes that highlights what is thinks is the corresponding code in the source. (This living Bytecode view replaces what before just printed out the #longPrintString of the CompiledMethod):
<Playground.jpeg>
-- www.tudorgirba.com "Every thing has its own flow"
On 14 Oct 2014, at 22:01, Tudor Girba <tudor@tudorgirba.com> wrote:
I love these little things.
This is a great example of how value should not be confused with cost. Small can be quite big after all :)
It should be noted that there is almost no code âwastedâ on this⦠the parser that creates the objects behind replaces InstructionPrinter (as we can just printOn: the SymbolicBytecodes for the longPrintString). The GTInspector related code is 5 short methods, in the end, after building the tool the system was smaller. Marcus
On 14 Oct 2014, at 16:42, Marcus Denker <marcus.denker@inria.fr> wrote:
On 10 Oct 2014, at 12:29, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 10 Oct 2014, at 10:57, Jan Kurš <kurs@iam.unibe.ch <mailto:kurs@iam.unibe.ch>> wrote:
Hi All,
Thank you for the replies. I see it is not an easy bug to fix. Do you have any idea, when this can be fixed?
I will try to fix it next week...
Or can you suggest me some other way/workaround, how to get/generate the source code of a block?
The old compiler used a hack to decompile blocks for getting a textual representation⦠one could port the code from Pharo2 to the Package OpalDecompiler in Pharo4. (but I actually like the current scheme of using the byte code-offset-to-AST mapping more).
step one: A nice tool⦠GTInspector view of the byte codes that highlights what is thinks is the corresponding code in the source. (This living Bytecode view replaces what before just printed out the #longPrintString of the CompiledMethod):
This is now in 4.0 update 306. e.g. inspect OrderedCollection>>#do: then select the âSymbolicBCâ tab, click on a byte code, then select in the second view the âSourceâ tab. ==> when moving around the byte code, the text highlights the code that generated the byte code. Marcus
Marcus Denker wrote:
On 14 Oct 2014, at 16:42, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 10 Oct 2014, at 12:29, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 10 Oct 2014, at 10:57, Jan Kurš <kurs@iam.unibe.ch <mailto:kurs@iam.unibe.ch>> wrote:
Hi All,
Thank you for the replies. I see it is not an easy bug to fix. Do you have any idea, when this can be fixed?
I will try to fix it next week...
Or can you suggest me some other way/workaround, how to get/generate the source code of a block?
The old compiler used a hack to decompile blocks for getting a textual representation⦠one could port the code from Pharo2 to the Package OpalDecompiler in Pharo4. (but I actually like the current scheme of using the byte code-offset-to-AST mapping more).
step one: A nice tool⦠GTInspector view of the byte codes that highlights what is thinks is the corresponding code in the source. (This living Bytecode view replaces what before just printed out the #longPrintString of the CompiledMethod):
This is now in 4.0 update 306.
e.g. inspect
OrderedCollection>>#do:
then select the âSymbolicBCâ tab, click on a byte code, then select in the second view the âSourceâ tab. ==> when moving around the byte code, the text highlights the code that generated the byte code.
Marcus
This is be great to pull more people into understanding (and helping) the dark depths. What about a tab in the second pane named "Help" that describes what each bytecode does? (half serious) For example, line 32, what is the "2" in "pushTemp: 2", and "1" in "pushConstant: 1". cheers -ben
Le 15 oct. 2014 à 14:18, Ben Coman a écrit :
Marcus Denker wrote:
On 14 Oct 2014, at 16:42, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 10 Oct 2014, at 12:29, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 10 Oct 2014, at 10:57, Jan Kurš <kurs@iam.unibe.ch <mailto:kurs@iam.unibe.ch>> wrote:
Hi All,
Thank you for the replies. I see it is not an easy bug to fix. Do you have any idea, when this can be fixed? I will try to fix it next week...
Or can you suggest me some other way/workaround, how to get/generate the source code of a block?
The old compiler used a hack to decompile blocks for getting a textual representation⦠one could port the code from Pharo2 to the Package OpalDecompiler in Pharo4. (but I actually like the current scheme of using the byte code-offset-to-AST mapping more).
step one: A nice tool⦠GTInspector view of the byte codes that highlights what is thinks is the corresponding code in the source. (This living Bytecode view replaces what before just printed out the #longPrintString of the CompiledMethod):
This is now in 4.0 update 306. e.g. inspect OrderedCollection>>#do: then select the âSymbolicBCâ tab, click on a byte code, then select in the second view the âSourceâ tab. ==> when moving around the byte code, the text highlights the code that generated the byte code. Marcus
This is be great to pull more people into understanding (and helping) the dark depths. What about a tab in the second pane named "Help" that describes what each bytecode does? (half serious)
For example, line 32, what is the "2" in "pushTemp: 2", and "1" in "pushConstant: 1".
the index
participants (8)
-
Ben Coman -
Camille Teruel -
Christophe Demarey -
Jan Kurš -
Marcus Denker -
Max Leske -
Sven Van Caekenberghe -
Tudor Girba