BlockClosure sources

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

BlockClosure sources

mario bancos
How can I get the source of a BlockClosure since it's a reference to
the bytecode of the CompiledMethod that contains it?.

VW and Squeak have a Decompiler class, but Dolphin's not.

Thanks


Reply | Threaded
Open this post in threaded view
|

Re: BlockClosure sources

Christopher J. Demers
"mario bancos" <[hidden email]> wrote in message
news:[hidden email]...
> How can I get the source of a BlockClosure since it's a reference to
> the bytecode of the CompiledMethod that contains it?.
>
> VW and Squeak have a Decompiler class, but Dolphin's not.

What an interesting ponderance.  I once wanted something like this when I
was debugging some code.  I decided to try to implement come code to
accomplish this.  Use this code at your own risk.  It can be found here
http://www.mitchellscientific.com/smalltalk/temp/cjdGetSourceForBlockClosure.st .

Dolphin does not seem to have a Decompiler, though it does have a
Disassembler.  It should not be too hard to make a Decompiler.  However that
is not the angle I chose to take.  I decided I would experiment with text
maps.  I added one method to BlockClosure, and it seems to work for the
limited cases I have tested it.  It is just a quick hack, and is not robust
or complete, but perhaps it will server as a starting point for someone
else.  Currently it only works for blocks in methods in classes, but not
blocks created in workspaces.  However I think the code could be adapted to
work for them as well.  I don't totally understand the need for the -1's I
had to use.  This code is public domain.  Hopefully someone can improve upon
it and post it here.  Here is the method (same as at the link above):

============
cjdGetSource
"cdemers - 3/12/2004 Try to return the source code of a block. This is a
quick hack, I don't consider it robust, and it may not even always be
correct."
| returnFromBlockIP sourceInterval interpreter operation |
interpreter := ByteCodeInterpreter on: self method.
operation := interpreter instructions at: ((interpreter reset; indexOfIP:
self initialIP) - 1).
returnFromBlockIP := (self initialIP + (ByteCodeInterpreter decodeLongJump:
operation value second byte2: operation value third)) - 1.
sourceInterval := (Compiler textMapOf: self method getSource in: self method
methodClass) detect: [:eachIP| eachIP key >= returnFromBlockIP].
^(self method getSource copyFrom: sourceInterval value start to:
sourceInterval value stop).
"This expression is handy for looking at the text map in a friendly way:
((Compiler textMapOf: self method getSource in: self method methodClass)
collect: [:eachMap | eachMap key -> (self method getSource copyFrom: eachMap
value start to: eachMap value stop)])"
============

Hopefully this will be of some use,
Chris