On Thu, Jan 21, 2010 at 4:33 AM, Juan Vuletich <[hidden email]> wrote: Thanks, Nicolas. You're right. I did include the preference in Cuis. By default it is set not to allow assignment to block args. I recompiled the whole system this way, removing any block arg assgnment left. I see no reason to allow them, but the preference is there if someone needs it. Agreed. I put in the preference for cases such as loading packages containing assignments to block temps. Without the preference it is additional work to load the package (unpacking the .mcz by hand and editing the source file). Once the package is loaded one can hunt down and rewrite those assignments. But how does one find them other than by resetting the preference and recompiling the package? And how does one find block argument assignments lurking in unpackaged code save recompiling the entire system? One abuses MessageNotUnderstood, that's how. Here's a hack implementation of SystemNavigation allBlockArgumentAssignations. It has just found 35 such abominations in my development image (shock, horror). Change set attached. Code in all its syntax coloured glory below. Enjoy.
SystemNavigation methods for query allBlockArgumentAssignations "Answer all methods containing an assignment to a block argument." "SystemNavigation default browseMessageList: SystemNavigation default allBlockArgumentAssignations asSortedCollection name: 'Assignments to block arguments'" ^self allMethodsSelect: [:m| | d assignsToBlockArg scanner | assignsToBlockArg := false. (d := m blockpcsToBlockExtents) size >= 2 ifTrue: [scanner := InstructionStream on: m. d keysDo: [:interval| | nArgs | (interval first ~= m initialPC and: [(nArgs := m argumentCountForBlockAtPC: interval first) > 0]) ifTrue: [scanner pc: interval first. [scanner pc <= interval last] whileTrue: [[scanner interpretNextInstructionFor: nil] on: MessageNotUnderstood do: [:ex| ((#(popIntoTemporaryVariable: storeIntoTemporaryVariable:) includes: ex message selector) and: [ex message arguments first + 1 <= nArgs]) ifTrue: [assignsToBlockArg := true]]]]]]. assignsToBlockArg] CompiledMethod methods for debugger support argumentCountForBlockAtPC: blockStartPC "Answer the argument count of the block whose first bytecode is startpc." (self pcPreviousTo: blockStartPC) ifNotNil: [:closureCreationPC| [(InstructionStream on: self) pc: closureCreationPC; interpretNextInstructionFor: nil] on: MessageNotUnderstood do: [:ex| ex message selector == #pushClosureCopyNumCopiedValues:numArgs:blockSize: ifTrue: [^ex message arguments at: 2]]]. self error: 'pc is not a block start pc' blockpcsToBlockExtents "Answer a Dictionary of (Interval from startpc to lastpc) to (Interval of blockExtent), for the method and any blocks within it, using the identical numbering scheme described in and orchestrated by BlockNode>>analyseArguments:temporaries:rootNode:. This is a variation on startpcsToBlockExtents whcih only answers startpc to interval." | index | index := 0. ^self blockRangesAndExtentsInto: Dictionary new from: self initialPC to: self endPC scanner: (InstructionStream on: self) numberer: [| value | value := index. index := index + 2. value] blockRangesAndExtentsInto: aDictionary from: initialPC to: endPC scanner: scanner numberer: numbererBlock "Support routine for blockpcsToBlockExtents" | extentStart blockSizeOrLocator | self flag: 'belongs in DebuggerMethodMap'. extentStart := numbererBlock value. [scanner pc <= endPC] whileTrue: [blockSizeOrLocator := scanner interpretNextInstructionFor: BlockStartLocator new. blockSizeOrLocator isInteger ifTrue: [self blockRangesAndExtentsInto: aDictionary from: scanner pc to: scanner pc + blockSizeOrLocator - 1 scanner: scanner numberer: numbererBlock]]. aDictionary at: (initialPC to: endPC) put: (extentStart to: numbererBlock value). ^aDictionary p.s. its my birthday today. I should be doing something useful but this was too much fun, my present to myself.
_______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Free forum by Nabble | Edit this page |