The following method looks complicated for me. Do you know if it is still valid in latest Cog ?
Thanks :)


eliotsClosureMeasurementsOn: m over: aFiveArgBlock
��� "
��� See senders.
��� Or try something like:
��� ��� Smalltalk
��� ��� ��� eliotsClosureMeasurementsOn: FileList >> #defaultContents
��� ��� ��� over: [ :closuresCount :hasCopiedValuesForClosure :hasIndirectTemps :anyClosureHasCopied :anyClosureDoesUAR :anyClosureUsesSelf |
��� ��� ��� ��� (Array with: closuresCount with: hasCopiedValuesForClosure with: hasIndirectTemps with: anyClosureHasCopied with: anyClosureDoesUAR with: anyClosureUsesSelf)]

��� From http://www.mirandabanda.org/cogblog/2008/11/14/mechanised-modifications-and-miscellaneous-measurements/
��� by Eliot Miranda
��� "
��� | s nextScanStart thisClosureHasCopied closuresCount hasIndirectTemps blkPc blkSz anyClosureHasCopied anyClosureDoesUAR anyClosureUsesSelf analyzedClosures |
��� closuresCount := 0.
��� hasIndirectTemps := false.
��� anyClosureHasCopied :=� anyClosureDoesUAR := anyClosureUsesSelf := false.
��� s := InstructionStream on: m.
��� s scanFor: [ :b |
��� ��� b = 16r8F "16r8F = 143 closure creation" ifTrue: [
��� ��� ��� closuresCount := closuresCount + 1].
��� ��� (b = 16r8A "16r8A = 138indirect temp vector creation" and: [ s followingByte <= 127]) ifTrue: [
��� ��� ��� ��� hasIndirectTemps := true].
��� ��� false].
��� nextScanStart := m initialPC.
��� analyzedClosures := 0.
��� [ analyzedClosures < closuresCount ] whileTrue: [
��� ��� s pc: nextScanStart; scanFor: [ :b | b = 16r8F ].��� "16r8F = 143 Search for first closure"
��� ��� analyzedClosures := analyzedClosures + 1.
��� ��� thisClosureHasCopied := s followingByte >= 16r10.
��� ��� anyClosureHasCopied := anyClosureHasCopied | thisClosureHasCopied.
��� ��� blkSz := s interpretNextInstructionFor: BlockStartLocator new.��� ��� "Findout size of first closure"
��� ��� blkPc := s pc.
��� ��� s scanFor: [ :b |
��� ��� ��� s pc >= (blkPc + blkSz)
��� ��� ��� ��� ifTrue: [
��� ��� ��� ��� ��� nextScanStart := s pc.
��� ��� ��� ��� ��� true]
��� ��� ��� ��� ifFalse: [
��� ��� ��� ��� ��� b = 16r8F ifTrue: [��� ��� ���
��� ��� ��� ��� ��� ��� thisClosureHasCopied := s followingByte >= 16r10.
��� ��� ��� ��� ��� ��� anyClosureHasCopied := anyClosureHasCopied | thisClosureHasCopied.
��� ��� ��� ��� ��� ��� analyzedClosures := analyzedClosures + 1 ].
��� ��� ��� ��� ��� anyClosureDoesUAR := anyClosureDoesUAR or: [s willReturn and: [s willBlockReturn not]].
��� ��� ��� ��� ��� anyClosureUsesSelf := anyClosureUsesSelf or: [b = 16r70 "pushSelf"
��� ��� ��� ��� ��� ��� ��� ��� ��� ��� or: [b < 16r10 "pushInstVar"
��� ��� ��� ��� ��� ��� ��� ��� ��� ��� or: [(b = 16r80 and: [s followingByte <= 16r3F]) "pushInstVar"
��� ��� ��� ��� ��� ��� ��� ��� ��� ��� or: [(b between: 16r60 and: 16r60 + 7) "storePopInstVar"
��� ��� ��� ��� ��� ��� ��� ��� ��� ��� or: [(b = 16r82 and: [s followingByte <= 63]) "storePopInstVar"
��� ��� ��� ��� ��� ��� ��� ��� ��� ��� or: [(b = 16r81 and: [s followingByte <= 63]) "storeInstVar"
��� ��� ��� ��� ��� ��� ��� ��� ��� ��� or: [b = 16r84 and: [s followingByte = 160]]]]]]]].
��� ��� ��� ��� ��� false]]].
��� ^aFiveArgBlock valueWithArguments: (Array
��� ��� ��� with: closuresCount
��� ��� ��� with: hasIndirectTemps
��� ��� ��� with: anyClosureHasCopied
��� ��� ��� with: anyClosureDoesUAR
��� ��� ��� with: anyClosureUsesSelf)

On Fri, Dec 2, 2011 at 9:40 PM, Mariano Martinez Peck <marianopeck@gmail.com> wrote:


On Fri, Dec 2, 2011 at 8:30 PM, Juan Vuletich <juan@jvuletich.org> wrote:
Eliot Miranda wrote:


On Fri, Dec 2, 2011 at 10:55 AM, Mariano Martinez Peck <marianopeck@gmail.com <mailto:marianopeck@gmail.com>> wrote:

� �Thanks both. I am right to assume that if the block refers to temp
� �vars, parameters, or whatever in another scope, then such solution
� �won't work. I mean, if I have this example for example:

� �| bytes result blah |
� �blah := 42.
� �bytes := FLSerializer serializeToByteArray: (SortedCollection
� �sortBlock: [:a :b | (a + blah) > b ]).

� �Then the 'blah' is in a different context. So the mentioned
� �solution works for "clean" closures, which are "self contained".
� �In the other cases (such as this example), we should serialize the
� �whole stack. Is this correct?


No. �The closure implementation arranges that any and all temporary variables accessed by the closure are directly accessible from the closure without accessing the outer contexts.
�...

WRT clean closures, check what I did in Cuis to serialize SortedCollections. See implementors and senders of #isClean.


Nice. Thanks Juan. I was checking your code, and that's exactly why I asked Eliot. In your method you say:

isClean
��� "A clean closure is one that doesn't really need the home context because:
��� ��� - It doesn't send messages to self or super
��� ��� - It doesn't access any instance variable
��� ��� - It doesn't access any outer temp
��� ��� - It doesn't do ^ return"
.....

So... my question is, WHAT do I need to serialize if I want to be able to serialize also "non clean". I mean, for each item on that list, what do I need apart from the closure instance and the receiver and method from the outerContext ?� the whole stack of contexts ?


Thanks a lot in advance!



--
Mariano
http://marianopeck.wordpress.com




--
Mariano
http://marianopeck.wordpress.com