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-... 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