"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