On Sat, Sep 17, 2011 at 9:00 PM, Eliot Miranda <[email protected]>wrote:
> > > On Sat, Sep 17, 2011 at 8:39 AM, Mariano Martinez Peck < > [email protected]> wrote: > >> I wanted to write a test (before Stef asked) but I don't know how to >> clearly copy a CompiledMethod. First I tried >> >> CompiledMethodTest >> testEqualityClassSideMethod >> | method1 method2 | >> method1 := self class class >> #returnPlusOne:. >> method2 := method1 veryDeepCopy. >> self deny: (method1 literalAt: method1 numLiterals) == (method2 >> literalAt: method2 numLiterals). >> self assert: method1 = method2. >> >> And it doesn't work, the last literal of both CM point are #==. >> >> Then I tried: >> >> testEqualityClassSideMethod >> | method1 method2 originalAssociation | >> method1 := self class class >> #returnPlusOne:. >> method2 := method1 veryDeepCopy. >> originalAssociation := method2 literalAt: method2 numLiterals. >> method2 literalAt: method2 numLiterals put: (Association key: >> originalAssociation key value: originalAssociation value). >> method1 literalAt: method1 numLiterals put: (Association key: >> originalAssociation key value: originalAssociation value). >> self deny: (method1 literalAt: method1 numLiterals) == (method2 >> literalAt: method2 numLiterals). >> self assert: method1 = method2. >> >> Again, same problem. >> >> So...I don't know how can I copy a CM completly, that means, even use >> different objects for the last literals. Any ideas? >> > > Compile them from source using the same and different source. Generate > source with subtle differences etc. e.g. use > Behavior>compile:classified:notifying:trailer:ifFail: which answers a > compiled method. > Thanks Eliot for the point :) Two new test: #testEqualityInstanceSideMethod and #testEqualityClassSideMethod. testEqualityClassSideMethod should be failing before http://code.google.com/p/pharo/issues/detail?id=4814 and green after it. > > > >> Thanks! >> >> >> On Sat, Sep 17, 2011 at 11:30 AM, Mariano Martinez Peck < >> [email protected]> wrote: >> >>> >>> Or maybe after reading: >>>>> >>>>> literal1 := self literalAt: numLits. >>>>> literal2 := method literalAt: numLits. >>>>> ^ (literal1 == literal2) or: [literal1 key isNil == literal2 key >>>>> isNil and: [literal1 value == literal2 value]]. >>>>> >>>>> I we are sure that the last literal is always an Association >>>>> >>>> >>>> If it's not then one is playing fast and loose with the system. But if >>>> the method doesn't contain a super send then as far as the VM is concerned >>>> it doesn't need an association, and that might be the case with, for >>>> example, shared inst var accessors in Newspeak. So instead of assuming its >>>> an association write it something like >>>> >>>> ^literal1 class == literal2 class >>>> and: [literal1 isVariableBinding >>>> ifTrue: [literal1 key = literal2 key and: [literal1 >>>> value = literal2 value]] >>>> ifFalse: [literal1 = literal2]] >>>> >>>> >>>>> >>> Thanks. Issue and slice in >>> http://code.google.com/p/pharo/issues/detail?id=4814 >>> >>> >>> >>> >>>> Nicolas >>>>> >>>>> >> On Fri, Sep 16, 2011 at 8:12 PM, Stéphane Ducasse >>>>> >> <[email protected]> wrote: >>>>> >>> >>>>> >>> Mariano >>>>> >>> >>>>> >>> So should we intgerate a fix? >>>>> >>> >>>>> >>> Stef >>>>> >>> >>>>> >>> On Sep 15, 2011, at 11:27 PM, Mariano Martinez Peck wrote: >>>>> >>> >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > BUT, it doesn't mean that Association is always used for globals. >>>>> >>> > CompiledMethod equality is failing because of the last literal, >>>>> the one that >>>>> >>> > maps class name (symbol) and point to the real class. So...when I >>>>> >>> > materialize, both CMs have non-identical associations for the >>>>> last literal, >>>>> >>> > but equal. >>>>> >>> > >>>>> >>> > As Henrik says the last literals are ideally #== to each other. >>>>> >>> > However, no Squeak dialect makes any attempt to keep the >>>>> class0side >>>>> >>> > associations equal. Look at a class-side method and you'll see >>>>> it's last >>>>> >>> > literal is nil->SomeClass class. Now since this association >>>>> doesn't exist >>>>> >>> > in Smalltalk (unlike last literals on the instance side) the >>>>> compiler merely >>>>> >>> > creates distinct ones for each class-side method. >>>>> >>> > >>>>> >>> > >>>>> >>> > Thanks Eliot for that point. In fact, I have just checked and you >>>>> are >>>>> >>> > right. The tests that are failing for me is those where class >>>>> side methods >>>>> >>> > are involded. In this case, the last literal of the original CM >>>>> and the >>>>> >>> > materialized, gives false in #literalEqual: hence, originalCM >>>>> = >>>>> >>> > materializedCM is false :( >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > Personally I don't think one can defend the position where method >>>>> >>> > equality is different for instance-side or class-side methods so >>>>> there must >>>>> >>> > be some solutions: >>>>> >>> > >>>>> >>> > 1. special case comparison of the last literal (the methodClass >>>>> >>> > literal), comparing keys and insisting that the keys be #== and >>>>> the values >>>>> >>> > be #== (can't just define it as keys #== since all similar >>>>> class-side >>>>> >>> > methods will be equal irrespective of their actual class). >>>>> >>> > >>>>> >>> > >>>>> >>> > This one seems the easier and fixes my problem :) >>>>> >>> > >>>>> >>> > sameLiteralsAs: method >>>>> >>> > "Compare my literals to those of method. This is needed to >>>>> compare >>>>> >>> > compiled methods." >>>>> >>> > >>>>> >>> > | numLits literal1 literal2 | >>>>> >>> > (numLits := self numLiterals) ~= method numLiterals >>>>> >>> > ifTrue: [ ^ false ]. >>>>> >>> > "The last literal requires special checking instead of using >>>>> >>> > #literalEqual:" >>>>> >>> > 1 to: numLits - 1 do: [ :index | >>>>> >>> > literal1 := self literalAt: index. >>>>> >>> > literal2 := method literalAt: index. >>>>> >>> > (literal1 == literal2 or: [ literal1 literalEqual: >>>>> literal2 ]) >>>>> >>> > ifFalse: [ >>>>> >>> > (index = 1 and: [ #(117 120) includes: self >>>>> primitive ]) >>>>> >>> > ifTrue: [ >>>>> >>> > literal1 isArray >>>>> >>> > ifTrue: [ >>>>> >>> > (literal2 isArray and: [ literal1 >>>>> >>> > allButLast = literal2 allButLast ]) >>>>> >>> > ifFalse: [ self halt. ^ false >>>>> ] ] >>>>> >>> > ifFalse: [ >>>>> >>> > "ExternalLibraryFunction" >>>>> >>> > (literal1 analogousCodeTo: >>>>> literal2) >>>>> >>> > ifFalse: [ self halt. ^ false >>>>> ] ] ] >>>>> >>> > ifFalse: [ >>>>> >>> > index = (numLits - 1) >>>>> >>> > ifTrue: [ >>>>> >>> > "properties" >>>>> >>> > (self properties analogousCodeTo: >>>>> method >>>>> >>> > properties) >>>>> >>> > ifFalse: [ self halt. ^ false >>>>> ] ] >>>>> >>> > ifFalse: [ self halt. ^ false ] ] ] >>>>> ]. >>>>> >>> > literal1 := self literalAt: numLits. >>>>> >>> > literal2 := method literalAt: numLits. >>>>> >>> > ^ ((literal1 key == literal2 key) and: [literal1 value == >>>>> literal2 >>>>> >>> > value]). >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > 2. special case comparison of the last literal (the methodClass >>>>> >>> > literal), insisting only that the class of the literal be the >>>>> same if it >>>>> >>> > isVariableBinding. >>>>> >>> > >>>>> >>> > 3. make the compile unique class-side methodClass literals. i.e. >>>>> if a >>>>> >>> > class already has a class-side method then the compiler or method >>>>> dictionary >>>>> >>> > insertion code must find that existing association and reuse it >>>>> >>> > >>>>> >>> > Other ideas? >>>>> >>> > >>>>> >>> > >From my point of view, that literal, the last one does not need >>>>> to be >>>>> >>> > identical to assume 2 CMs are equal. They just need to be equal. >>>>> >>> > >>>>> >>> > >>>>> >>> > -- >>>>> >>> > Mariano >>>>> >>> > http://marianopeck.wordpress.com >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > -- >>>>> >>> > best, >>>>> >>> > Eliot >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > >>>>> >>> > -- >>>>> >>> > Mariano >>>>> >>> > http://marianopeck.wordpress.com >>>>> >>> > >>>>> >>> >>>>> >>> >>>>> >> >>>>> >> >>>>> >> >>>>> >> -- >>>>> >> Mariano >>>>> >> http://marianopeck.wordpress.com >>>>> >> >>>>> >> >>>>> > >>>>> >>>>> >>>> >>>> >>>> -- >>>> best, >>>> Eliot >>>> >>>> >>>> >>>> >>>> >>> >>> >>> -- >>> Mariano >>> http://marianopeck.wordpress.com >>> >>> >> >> >> -- >> Mariano >> http://marianopeck.wordpress.com >> >> > > > -- > best, > Eliot > > -- Mariano http://marianopeck.wordpress.com
