The 'show bytescodes' option on the method text pane menu doesn't
work. How ca I look at the bytecodes of a method? |
> The 'show bytescodes' option on the method text pane menu doesn't
> work. How ca I look at the bytecodes of a method? Inspect the expression: ClassName >> #methodName Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
Ok, this gets me into the CompiledMethod, with which I have very
little experience. I did find that the 'source' toggle button in a browser has a bytecodes option. It didn't help me much, seeing the bytecodes. I am trying to find a way to invoke a bytecode primitive from the image. So, for instance, given 2 SmallIntegers in hand, I want to run bytecodePrimAdd without running #+. Is there a way to do this? I am digging through #lookupInMethodCacheSel:class: at the moment to see how primitive dispatch works. On Oct 13, 2007, at 1:40 PM, Lukas Renggli wrote: >> The 'show bytescodes' option on the method text pane menu doesn't >> work. How ca I look at the bytecodes of a method? > > Inspect the expression: > > ClassName >> #methodName > > Cheers, > Lukas > > -- > Lukas Renggli > http://www.lukas-renggli.ch > |
On 13-Oct-07, at 2:02 PM, Robert Withers wrote: > Ok, this gets me into the CompiledMethod, with which I have very > little experience. I did find that the 'source' toggle button in a > browser has a bytecodes option. It didn't help me much, seeing the > bytecodes. I am trying to find a way to invoke a bytecode > primitive from the image. Why? > So, for instance, given 2 SmallIntegers in hand, I want to run > bytecodePrimAdd without running #+. Err, given a bytecode named 'bytecodePrimAdd' what would you expect it to do? Why, it runs the same code that primitiveAdd does, modulo the bytecode version knowing that it will be inlined into the big bytecode loop. And oddly enough, that very fact means that if you *did* manage to invoke it by some devious magic, it would cause some interesting issue because you'd be affecting the in-loop values of stack pointer etc, which could cause all sorts of fun. > Is there a way to do this? I am digging through > #lookupInMethodCacheSel:class: at the moment to see how primitive > dispatch works. Why? What on earth are you doing? Message sending is designed to be atomic and trying to insert yourself in the middle is likely to go boom. You really are in danger of branching to the Halt and Catch Fire instruction... tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim I came, I saw, I deleted all your files. |
In reply to this post by Rob Withers
On Sat, 13 Oct 2007 23:02:48 +0200, Robert Withers wrote:
> Ok, this gets me into the CompiledMethod, with which I have very little > experience. I did find that the 'source' toggle button in a browser has > a bytecodes option. It didn't help me much, seeing the bytecodes. I am > trying to find a way to invoke a bytecode primitive from the image. So, > for instance, given 2 SmallIntegers in hand, I want to run > bytecodePrimAdd without running #+. Since #+ belong to the special selectors, the VM will indeed first try bytecodePrimAdd. See "special selectors" in Object>>#whatIsAPrimitive and Object>>#howToModifyPrimitives, watch for "no lookup". /Klaus > Is there a way to do this? I am digging through > #lookupInMethodCacheSel:class: at the moment to see how primitive > dispatch works. > > On Oct 13, 2007, at 1:40 PM, Lukas Renggli wrote: > >>> The 'show bytescodes' option on the method text pane menu doesn't >>> work. How ca I look at the bytecodes of a method? >> >> Inspect the expression: >> >> ClassName >> #methodName >> >> Cheers, >> Lukas >> >> --Lukas Renggli >> http://www.lukas-renggli.ch >> > > > |
In reply to this post by timrowledge
On Oct 13, 2007, at 2:52 PM, tim Rowledge wrote: > > On 13-Oct-07, at 2:02 PM, Robert Withers wrote: > >> Ok, this gets me into the CompiledMethod, with which I have very >> little experience. I did find that the 'source' toggle button in >> a browser has a bytecodes option. It didn't help me much, seeing >> the bytecodes. I am trying to find a way to invoke a bytecode >> primitive from the image. > > Why? I will do my best to answer this seemingly innocuous, simple question. The short answer is that I am reviving my efforts at incorporating eventual references, a la SqueakElib, in the Squeak image. This entails making the VM eventual safe. The longer answer forgets all of the networking work I did, which I managed to leverage into SSL and SSH. I want to allow some object references to be eventual and thereby defer method evaluation to some future time after invocation. This works ok for receivers that are eventual (4 eventual + 5) -> promise that later evaluates #+ and resolves to eventual(9). In this case, I intercept the msg send and send it eventually. The problem I perceive I have is when we have (4 + 5 eventual). There is nothing that intercepts it. We can't have eventual references which are used as arguments to indexed or named primitives. I am trying to fix this. It's fuzzy, but there are several issues I am working through here, which I have just now named the intercept problem, the invocation problem, the inoculation problem. The intercept problem: modify all bytecode/primitive functions to check arguments on the stack for eventual references (ugh), if eventual arg exists, contaminate the receiver as an eventual ref (#becomeForward:), package the args and the primitiveIndex (call it an EventualPrimitiveInvocation) and eventally send to an eventual join of all eventual args + receiver. It runs when all eventual refs are resolved. It gets fuzzy here, but the eventual contagion will spread to all objects using an eventual ref to maintain message order. Return a promise ref on the stack for the eventual result of this future computation. The invocation problem: the issue I am exploring in this email. I need to unwrap local eventual refs (not remote eventual refs or promises) to use as arguments. I need to invoke the bytecode/ primitive prim where interception occurred. I need to resolve the promise created from the intercept. The inoculation problem: when the system has finished eventual sending to system contaminated eventual ref, then inoculate the ref back to a non-eventual reference. I hope this makes some sense. > >> So, for instance, given 2 SmallIntegers in hand, I want to run >> bytecodePrimAdd without running #+. > > Err, given a bytecode named 'bytecodePrimAdd' what would you expect > it to do? Why, it runs the same code that primitiveAdd does, modulo > the bytecode version knowing that it will be inlined into the big > bytecode loop. And oddly enough, that very fact means that if you > *did* manage to invoke it by some devious magic, it would cause > some interesting issue because you'd be affecting the in-loop > values of stack pointer etc, which could cause all sorts of fun. Ok, I am confused as to which gets called. #primitiveAdd is in the primitive table as number 1, so I guess that shows up in the mcache for primitiveIndex 1, and thus gets invoked. Is it right? I would be happy to run #primitiveAdd, but wouldn't it also have fun with affecting values of the stack pointer and such? > >> Is there a way to do this? I am digging through >> #lookupInMethodCacheSel:class: at the moment to see how primitive >> dispatch works. > Why? What on earth are you doing? Message sending is designed to be > atomic and trying to insert yourself in the middle is likely to go > boom. You really are in danger of branching to the Halt and Catch > Fire instruction... I think I need a primitive of my own to marshall the stack args, so method lookup and activate the primitive. On eventual ref resolution, I can call a method with this primitiveIndex, where the receiver is the EventualPrimitiveInvocation obj. thanks, Rob > > tim > -- > tim Rowledge; [hidden email]; http://www.rowledge.org/tim > I came, I saw, I deleted all your files. > > > |
On 13-Oct-07, at 3:55 PM, Robert Withers wrote: > The problem I perceive I have is when we have (4 + 5 eventual). > There is nothing that intercepts it. Err. 4 + {some not-integer-not-float} will fail. It will get trapped in the prim failure code for SmallInteger>+ and the {some not-integer- not-float} will be sent #adaptToInteger:andSend: which rather usefully includes both the original 5 and the #+ selector. Seems like a perfect opportunity to build a promise and return it, no? That looks like intercepting your problem to me, how about you? I think you're probably making this far more complex than it needs to be. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Useful random insult:- He has a tenuous grip on the obvious. |
In reply to this post by Rob Withers
On Oct 13, 2007, at 3:55 PM, Robert Withers wrote: > ... which I have just now named the intercept problem, the > invocation problem, the inoculation problem ... This should be the intercept problem, the evaluation problem, the inoculation problem. > The invocation problem: ... The evaluation problem: ... |
In reply to this post by timrowledge
On Oct 13, 2007, at 6:14 PM, tim Rowledge wrote: > > On 13-Oct-07, at 3:55 PM, Robert Withers wrote: > >> The problem I perceive I have is when we have (4 + 5 eventual). >> There is nothing that intercepts it. > > Err. 4 + {some not-integer-not-float} will fail. It will get > trapped in the prim failure code for SmallInteger>+ and the {some > not-integer-not-float} will be sent #adaptToInteger:andSend: which > rather usefully includes both the original 5 and the #+ selector. > Seems like a perfect opportunity to build a promise and return it, no? This one could be done using double dispatch to the eventual arg, 'tis true. But what about the following, just as additional examples? primitiveAt primitiveAtPut primitiveNextPut primitiveStringAt primitiveStringAtPut primitiveStringReplace and what about all the named primitives in various plugins? > > That looks like intercepting your problem to me, how about you? I > think you're probably making this far more complex than it needs to > be. There is no question that I am making it complicated, but I am trying to have all primitives/bytecoded special selectors be eventual safe. Since we are considering changing a fundamental invariant of the vm, and saying that a reference does not have to have immediate evaluation semantics and can be a promise with no current value, it is no surprise that it is complicated. This is undoubtedly confusing my thinking and my solution. Rob |
I should be clearer. Since my email service is hosed up, this may
very well post 2 hours after I send it. On Oct 13, 2007, at 6:32 PM, Robert Withers wrote: > > On Oct 13, 2007, at 6:14 PM, tim Rowledge wrote: > >> >> On 13-Oct-07, at 3:55 PM, Robert Withers wrote: >> >>> The problem I perceive I have is when we have (4 + 5 eventual). >>> There is nothing that intercepts it. >> >> Err. 4 + {some not-integer-not-float} will fail. It will get >> trapped in the prim failure code for SmallInteger>+ and the {some >> not-integer-not-float} will be sent #adaptToInteger:andSend: which >> rather usefully includes both the original 5 and the #+ selector. >> Seems like a perfect opportunity to build a promise and return it, >> no? > > This one could be done using double dispatch to the eventual arg, > 'tis true. But what about the following, just as additional examples? > primitiveAt > primitiveAtPut > primitiveNextPut > primitiveStringAt > primitiveStringAtPut > primitiveStringReplace > and what about all the named primitives in various plugins? I considered taking the approach you describe for all primitives/ bytecode methods. There are problems with it, I think: 1) doesn't deal with bytecode methods called by special selectors. Doesn't this bypass the #+ method and its primitive failure code? It has been my understanding that dealing with bytecode methods would require vm changes. 2) Would require lots of double dispatch coding for those selectors that don't currently use them. This problem is compounded if there is more than 1 argument. 3) Doesn't deal with named primitives that are not currently in the image. My hope is that I can make vm changes when primitive dispatch occurs prior to entering the named primitive function. Verify all args on the stack at this point and do the eventual sending prior to activating the named primitive. Is this even possible? If so then perhaps it is possible for indexed primitives too. 4) Difficulties in finding all methods specifying a primitive. This is all I can come up with at the moment, but these are some of the thoughts which have steered me to consider changing the vm. Rob |
In reply to this post by Rob Withers
Hi Robert,
I you are using a recent squeak-dev image, there is a button on the right of OmniBrowser labeled 'view...'. If you click on it, you will be able to see the bytecode version, but also the decompile and prettyprint versions. Bye 2007/10/13, Robert Withers <[hidden email]>: > The 'show bytescodes' option on the method text pane menu doesn't > work. How ca I look at the bytecodes of a method? > > -- Damien Cassou |
In reply to this post by timrowledge
On Oct 13, 2007, at 6:14 PM, tim Rowledge wrote: > > On 13-Oct-07, at 3:55 PM, Robert Withers wrote: > >> The problem I perceive I have is when we have (4 + 5 eventual). >> There is nothing that intercepts it. > > Err. 4 + {some not-integer-not-float} will fail. It will get > trapped in the prim failure code for SmallInteger>+ and the {some > not-integer-not-float} will be sent #adaptToInteger:andSend: which > rather usefully includes both the original 5 and the #+ selector. > Seems like a perfect opportunity to build a promise and return it, no? > > That looks like intercepting your problem to me, how about you? I > think you're probably making this far more complex than it needs to > be. Well, Tim, it seems this may be the extent of the comments you are willing to make on my problem. I can understand you not wanting to get too deep on the issue, still it disappoints me. I spent some effort trying to explain my problem clearly. I hadn't even described the hard problem yet, which is having eventual sends in a context with multiple returns. Unfortunately, my original question remains unanswered: how can I execute bytecodePrims and primitives from the image? To test the possibility of doing this in the image with the example we were exploring (4 + 5 eventual), I loaded up SqueakElib for the first time in well over a year, to see what happens. I knew it didn't succeed for some reason. It blows up with a #mustBeBoolean error when it gets inside of: Integer>>#+ aNumber "Refer to the comment in Number + " aNumber isInteger ifTrue: [self negative == aNumber negative ifTrue: [^ (self digitAdd: aNumber) normalize] ifFalse: [^ self digitSubtract: aNumber]]. ^ aNumber adaptToInteger: self andSend: #+ Because aNumber is eventual, sending #isInteger returns a promise which is the receiver for the inlined #ifTrue:. The promise is not a boolean (yet), so it errors out with #mustBeBoolean. So, at the very minimum I will need to make ifTrue:, ifFalse:, ifTrue:ifFalse:, and ifFalse:ifTrue: all special selectors and normalSend them. Here are the bytecodes for the above method, and line 43 represents the ifTrue, I believe (why are the line numbers starting with 41?), although knowing which flavor of if it is seems to have been lost when compiling. Bytecodes for the #ifTrue: emitted by the MessageNode somehow (emitIf:on:value:). I looked for where #+ is encoded as bytecodePrimAdd, but couldn't find it. 41 <10> pushTemp: 0 42 <D4> send: isInteger 43 <AC 0F> jumpFalse: 60 45 <70> self 46 <D3> send: negative 47 <10> pushTemp: 0 48 <D3> send: negative 49 <C6> send: == 50 <9C> jumpFalse: 56 51 <70> self 52 <10> pushTemp: 0 53 <E2> send: digitAdd: 54 <D1> send: normalize 55 <7C> returnTop 56 <70> self 57 <10> pushTemp: 0 58 <E0> send: digitSubtract: 59 <7C> returnTop 60 <10> pushTemp: 0 61 <70> self 62 <26> pushConstant: #+ 63 <F5> send: adaptToInteger:andSend: 64 <7C> returnTop This method (Number>>#+) also contains multiple returns, illuminating the hard problem, since eventually sending doesn't know in advance what the result of executing conditional logic will be, it needs to be prepared to execute all branches and when one succeeds, to bail on the other possible branches. I'm not sure what I will do about this. Rob |
In reply to this post by Damien Cassou-3
After you mentioned these I took a look in the normal browser, since
I don't have OmniBrowser loaded I don't believe. The 'Source' button popup also has prettyPrint and decompile listed. Decompile is particularly interesting to see what a given conditional statement actually compiles to. An ifTrue:ifFalse: statement turns into an ifTrue: statement, which reflects the bytecodes of a longJumpIfFalse, to jump around the conditionally executed block. thanks, Rob On Oct 14, 2007, at 10:27 PM, Damien Cassou wrote: > Hi Robert, > > I you are using a recent squeak-dev image, there is a button on the > right of OmniBrowser labeled 'view...'. If you click on it, you will > be able to see the bytecode version, but also the decompile and > prettyprint versions. > > Bye > > 2007/10/13, Robert Withers <[hidden email]>: >> The 'show bytescodes' option on the method text pane menu doesn't >> work. How ca I look at the bytecodes of a method? >> >> > > > -- > Damien Cassou > |
In reply to this post by Rob Withers
On 15-Oct-07, at 1:35 PM, Robert Withers wrote: > > Well, Tim, it seems this may be the extent of the comments you are > willing to make on my problem. Pretty much I'm afraid; I simply don't have enough time available to delve into a completely different system. I don't think there is any chance of being able to help much without spending a lot more time than I have. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Klingon Code Warrior:- 1) "Behold, the keyboard of Kalis! The greatest Klingon code warrior that ever lived!" |
In reply to this post by Rob Withers
Robert Withers a écrit :
> > On Oct 13, 2007, at 6:14 PM, tim Rowledge wrote: > >> >> On 13-Oct-07, at 3:55 PM, Robert Withers wrote: >> >>> The problem I perceive I have is when we have (4 + 5 eventual). >>> There is nothing that intercepts it. >> >> Err. 4 + {some not-integer-not-float} will fail. It will get trapped >> in the prim failure code for SmallInteger>+ and the {some >> not-integer-not-float} will be sent #adaptToInteger:andSend: which >> rather usefully includes both the original 5 and the #+ selector. >> Seems like a perfect opportunity to build a promise and return it, no? >> >> That looks like intercepting your problem to me, how about you? I >> think you're probably making this far more complex than it needs to be. > > Well, Tim, it seems this may be the extent of the comments you are > willing to make on my problem. I can understand you not wanting to get > too deep on the issue, still it disappoints me. I spent some effort > trying to explain my problem clearly. I hadn't even described the hard > problem yet, which is having eventual sends in a context with multiple > returns. Unfortunately, my original question remains unanswered: how > can I execute bytecodePrims and primitives from the image? > > To test the possibility of doing this in the image with the example we > were exploring (4 + 5 eventual), I loaded up SqueakElib for the first > time in well over a year, to see what happens. I knew it didn't succeed > for some reason. It blows up with a #mustBeBoolean error when it gets > inside of: > > Integer>>#+ aNumber > "Refer to the comment in Number + " > aNumber isInteger ifTrue: > [self negative == aNumber negative > ifTrue: [^ (self digitAdd: aNumber) normalize] > ifFalse: [^ self digitSubtract: aNumber]]. > ^ aNumber adaptToInteger: self andSend: #+ > > Because aNumber is eventual, sending #isInteger returns a promise which > is the receiver for the inlined #ifTrue:. The promise is not a boolean > (yet), so it errors out with #mustBeBoolean. > > So, at the very minimum I will need to make ifTrue:, ifFalse:, > ifTrue:ifFalse:, and ifFalse:ifTrue: all special selectors and > normalSend them. Here are the bytecodes for the above method, and line > 43 represents the ifTrue, I believe (why are the line numbers starting > with 41?), although knowing which flavor of if it is seems to have been > lost when compiling. Bytecodes for the #ifTrue: emitted by the > MessageNode somehow (emitIf:on:value:). I looked for where #+ is > encoded as bytecodePrimAdd, but couldn't find it. > > 41 <10> pushTemp: 0 > 42 <D4> send: isInteger > 43 <AC 0F> jumpFalse: 60 > 45 <70> self > 46 <D3> send: negative > 47 <10> pushTemp: 0 > 48 <D3> send: negative > 49 <C6> send: == > 50 <9C> jumpFalse: 56 > 51 <70> self > 52 <10> pushTemp: 0 > 53 <E2> send: digitAdd: > 54 <D1> send: normalize > 55 <7C> returnTop > 56 <70> self > 57 <10> pushTemp: 0 > 58 <E0> send: digitSubtract: > 59 <7C> returnTop > 60 <10> pushTemp: 0 > 61 <70> self > 62 <26> pushConstant: #+ > 63 <F5> send: adaptToInteger:andSend: > 64 <7C> returnTop > > > This method (Number>>#+) also contains multiple returns, illuminating > the hard problem, since eventually sending doesn't know in advance what > the result of executing conditional logic will be, it needs to be > prepared to execute all branches and when one succeeds, to bail on the > other possible branches. I'm not sure what I will do about this. > > Rob > Doing this, you will inline code until the viral #eventual message has contaminated every other message receiver. Risk is to end up with huge unmanageable expressions. You don't have to develop all possible branches... #ifTrue:ifFalse: would result in an EventualMessageSend with 5 eventual as receiver and some blocks as argument, once you know how to recompile with optimization off (You should also consider NewCompiler for compiling blocks...). Shouldn't you concentrate on resolving the promise as a kind of message send at highest level possible, like (4 + 5 eventual) resolve in (EventualSend receiver: 4 message: #+ argument: 5 eventual)? That's however quite a challenge... Maybe an ExceptionHandler trapping the Eventual>>doesNotUnderstand to backtrack thisContext stack while an eventual argument has been passed... Nicolas |
Hi Nicolas,
On Oct 15, 2007, at 3:25 PM, nicolas cellier wrote: > > Doing this, you will inline code until the viral #eventual message > has contaminated every other message receiver. > Risk is to end up with huge unmanageable expressions. It's true that it seems that an eventual ref will contaminate method contexts and objects which come into contact with the eventual ref and that that could spread to all references and activations within a process. While I haven't thought through this viral aspect that deeply, my hope is that some way could be found to inoculate as fast as they get contaminated or otherwise limit how much gets contaminated. > You don't have to develop all possible branches... #ifTrue:ifFalse: > would result in an EventualMessageSend with 5 eventual as receiver > and some blocks as argument, once you know how to recompile with > optimization off (You should also consider NewCompiler for > compiling blocks...). Yes, but one or both of these blocks (both in the example given) may have a return statement, which would return from the method context that called ifTrue:ifFalse:. So I am thinking that context needs to be infected as an eventual context and generate a promise:resolver pair such that an internal return, like the one in the block above or the one at the end, would resolve the promise. Also, all statements in the context would need to be eventually sent, and all refs would need to become eventual, to maintain msg ordering. I think. > > Shouldn't you concentrate on resolving the promise as a kind of > message send at highest level possible, like (4 + 5 eventual) > resolve in (EventualSend receiver: 4 message: #+ argument: 5 > eventual)? Yes, but you have already made it viral by making the #+ be sent eventually. What I am saying instead is making that happen from inside the implementation of #+, and it is occurring because inside of that implementation is is sending ifTrue:ifFalse: which is a primitive/bytecodePrim. Not making normal activations eventual, but just activations that contain a primitive call, was a way I was planning to limit the viral nature. Your point about full contamination may trump this hope. > > That's however quite a challenge... > Maybe an ExceptionHandler trapping the Eventual>>doesNotUnderstand > to backtrack thisContext stack while an eventual argument has been > passed... That's an interesting idea. Then we would be explicitly infecting all contexts on the stack, but perhaps it could be done without much VM work. I still need to get ifTrue: and friends (and possibly others like #whileTrue:) to normalSend their selectors if they fail, so I can intercept the msg send and make it eventual. Then we can start playing with it. Cheers, Rob |
Free forum by Nabble | Edit this page |