'Method for block not found on stack, can''t edit and continue'

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

'Method for block not found on stack, can''t edit and continue'

Frank Shearar-3
I often use Blocks for holding tiny bits of state not worth
formalising as a class. As a result, I often get this error because I
also spend a lot of time developing in the Debugger.

Is the following a completely crazy idea?

self selectedContext activeHome ifNil: [ |ctxt|
    ctxt := self selectedContext.
    "look up ctxt method methodClass >> ctxt selector."
    "Save the code as normal"
    ctxt method become: ctxt method methodClass >> ctxt selector].

You'd need to fiddle the stack pointer, but that you have to do anyway
in edit-and-continue.

frank

Reply | Threaded
Open this post in threaded view
|

Re: 'Method for block not found on stack, can''t edit and continue'

Eliot Miranda-2
Hi Frank,


On Mon, Jan 20, 2014 at 2:01 PM, Frank Shearar <[hidden email]> wrote:
I often use Blocks for holding tiny bits of state not worth
formalising as a class. As a result, I often get this error because I
also spend a lot of time developing in the Debugger.

Is the following a completely crazy idea?

self selectedContext activeHome ifNil: [ |ctxt|
    ctxt := self selectedContext.
    "look up ctxt method methodClass >> ctxt selector."
    "Save the code as normal"
    ctxt method become: ctxt method methodClass >> ctxt selector].

All but the last line is sane ;-)  You can't expect a become: to do the right thing. It'll leave the context's pc wrong, and perhaps its stack pointer too.  You're looking for

    ctxt privRefreshWith: ctxt method methodClass >> ctxt selector

But what do you want to do?  Are you rewriting a block as a block or as a method?  What yu have above will do the latter, not the former.
 

You'd need to fiddle the stack pointer, but that you have to do anyway
in edit-and-continue.

frank




--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: 'Method for block not found on stack, can''t edit and continue'

Frank Shearar-3
On 20 January 2014 23:47, Eliot Miranda <[hidden email]> wrote:

> Hi Frank,
>
>
> On Mon, Jan 20, 2014 at 2:01 PM, Frank Shearar <[hidden email]>
> wrote:
>>
>> I often use Blocks for holding tiny bits of state not worth
>> formalising as a class. As a result, I often get this error because I
>> also spend a lot of time developing in the Debugger.
>>
>> Is the following a completely crazy idea?
>>
>> self selectedContext activeHome ifNil: [ |ctxt|
>>     ctxt := self selectedContext.
>>     "look up ctxt method methodClass >> ctxt selector."
>>     "Save the code as normal"
>>     ctxt method become: ctxt method methodClass >> ctxt selector].
>
>
> All but the last line is sane ;-)  You can't expect a become: to do the
> right thing. It'll leave the context's pc wrong, and perhaps its stack
> pointer too.  You're looking for
>
>     ctxt privRefreshWith: ctxt method methodClass >> ctxt selector
>
> But what do you want to do?  Are you rewriting a block as a block or as a
> method?  What yu have above will do the latter, not the former.

Surely the wrongness of the pc doesn't matter? When you
edit-and-continue a method (as opposed to a block in a method), the
"continue" part resumes at the start of the method. Unless you mean
that, with this block, you'd need to position the pc _at the start of
the block_, or similar?

But the use case is this: I have a method that returns a block that
generates values. I don't have the source to hand right now, but it
goes something like this:

makeGeneratorFrom: aSymbol
    | base current |
    base := aSymbol. current := -1.
    ^ [current := current + 1.
        (base , current asStringg) asSymbol]

and then in the class I can say
genny := self makeGeneratorFrom: #z.
{genny value. genny value} "=> {#z0. #z1}"

If I see a bug - the deliberate #asStringg typo - the debugger pops
up, I correct the code, and then can't save the change because
#makeGeneratorFrom: isn't in the call stack. What I'd like is to (a)
save my change at all (rather than copy all the source, open a
Browser, find the right method, paste the source, accept), and (b)
have execution continue with the new version of the block.

(And a "wrinkle" (he says naively) is that to edit-and-continue here,
the new BlockContext (or whatever) would need to have references to
the variables closed over by the old BlockContext.)

Even if I can't edit-and-continue this, at the least I'd like to save
the source from within the Debugger, and possibly abandon the Process.

frank

>> You'd need to fiddle the stack pointer, but that you have to do anyway
>> in edit-and-continue.
>>
>> frank
>>
>
>
>
> --
> best,
> Eliot

Reply | Threaded
Open this post in threaded view
|

Re: 'Method for block not found on stack, can''t edit and continue'

Eliot Miranda-2



On Tue, Jan 21, 2014 at 2:26 AM, Frank Shearar <[hidden email]> wrote:
On 20 January 2014 23:47, Eliot Miranda <[hidden email]> wrote:
> Hi Frank,
>
>
> On Mon, Jan 20, 2014 at 2:01 PM, Frank Shearar <[hidden email]>
> wrote:
>>
>> I often use Blocks for holding tiny bits of state not worth
>> formalising as a class. As a result, I often get this error because I
>> also spend a lot of time developing in the Debugger.
>>
>> Is the following a completely crazy idea?
>>
>> self selectedContext activeHome ifNil: [ |ctxt|
>>     ctxt := self selectedContext.
>>     "look up ctxt method methodClass >> ctxt selector."
>>     "Save the code as normal"
>>     ctxt method become: ctxt method methodClass >> ctxt selector].
>
>
> All but the last line is sane ;-)  You can't expect a become: to do the
> right thing. It'll leave the context's pc wrong, and perhaps its stack
> pointer too.  You're looking for
>
>     ctxt privRefreshWith: ctxt method methodClass >> ctxt selector
>
> But what do you want to do?  Are you rewriting a block as a block or as a
> method?  What yu have above will do the latter, not the former.

Surely the wrongness of the pc doesn't matter? When you
edit-and-continue a method (as opposed to a block in a method), the
"continue" part resumes at the start of the method. Unless you mean
that, with this block, you'd need to position the pc _at the start of
the block_, or similar?

Right.  That's what privRefresh does; reset the pc and the stack pointer to the relevant values for the beginning of the method or block.
 

But the use case is this: I have a method that returns a block that
generates values. I don't have the source to hand right now, but it
goes something like this:

makeGeneratorFrom: aSymbol
    | base current |
    base := aSymbol. current := -1.
    ^ [current := current + 1.
        (base , current asStringg) asSymbol]

and then in the class I can say
genny := self makeGeneratorFrom: #z.
{genny value. genny value} "=> {#z0. #z1}"

If I see a bug - the deliberate #asStringg typo - the debugger pops
up, I correct the code, and then can't save the change because
#makeGeneratorFrom: isn't in the call stack. What I'd like is to (a)
save my change at all (rather than copy all the source, open a
Browser, find the right method, paste the source, accept), and (b)
have execution continue with the new version of the block.

(And a "wrinkle" (he says naively) is that to edit-and-continue here,
the new BlockContext (or whatever) would need to have references to
the variables closed over by the old BlockContext.)

[BTW, BlockContext isn't used any more.  Only MethodContext, which is now misnamed and should be renamed to Context.  Block and method activations are differentiated by blocks having a non-nil closureOrNil inst var].


So the change to the method is easy, but replacing the activation more difficult, simply because of the necessary UI plumbing.  BlockClosure>>asContextWithSender: does almost all you need (it doesn't push arguments) tio generate the activation.  You'll have to figure otu how to plumb that nto the debugger.


Even if I can't edit-and-continue this, at the least I'd like to save
the source from within the Debugger, and possibly abandon the Process.

Sure.  That's all about hacking out the warning in some way you can live with.

Please report back.  This is intriguing :)
 

frank

>> You'd need to fiddle the stack pointer, but that you have to do anyway
>> in edit-and-continue.
>>
>> frank
>>
>
>
>
> --
> best,
> Eliot




--
best,
Eliot


cbc
Reply | Threaded
Open this post in threaded view
|

Re: 'Method for block not found on stack, can''t edit and continue'

cbc
On Tue, Jan 21, 2014 at 1:49 PM, Eliot Miranda <[hidden email]> wrote:
On Tue, Jan 21, 2014 at 2:26 AM, Frank Shearar <[hidden email]> wrote:
On 20 January 2014 23:47, Eliot Miranda <[hidden email]> wrote:
> Hi Frank,
>
>
> On Mon, Jan 20, 2014 at 2:01 PM, Frank Shearar <[hidden email]>
> wrote:
>>
>> I often use Blocks for holding tiny bits of state not worth
>> formalising as a class. As a result, I often get this error because I
>> also spend a lot of time developing in the Debugger.
>>
>> Is the following a completely crazy idea?
>>
>> self selectedContext activeHome ifNil: [ |ctxt|
>>     ctxt := self selectedContext.
>>     "look up ctxt method methodClass >> ctxt selector."
>>     "Save the code as normal"
>>     ctxt method become: ctxt method methodClass >> ctxt selector].
>
>
> All but the last line is sane ;-)  You can't expect a become: to do the
> right thing. It'll leave the context's pc wrong, and perhaps its stack
> pointer too.  You're looking for
>
>     ctxt privRefreshWith: ctxt method methodClass >> ctxt selector
>
> But what do you want to do?  Are you rewriting a block as a block or as a
> method?  What yu have above will do the latter, not the former.

Surely the wrongness of the pc doesn't matter? When you
edit-and-continue a method (as opposed to a block in a method), the
"continue" part resumes at the start of the method. Unless you mean
that, with this block, you'd need to position the pc _at the start of
the block_, or similar?

Right.  That's what privRefresh does; reset the pc and the stack pointer to the relevant values for the beginning of the method or block.
 

But the use case is this: I have a method that returns a block that
generates values. I don't have the source to hand right now, but it
goes something like this:

makeGeneratorFrom: aSymbol
    | base current |
    base := aSymbol. current := -1.
    ^ [current := current + 1.
        (base , current asStringg) asSymbol]

and then in the class I can say
genny := self makeGeneratorFrom: #z.
{genny value. genny value} "=> {#z0. #z1}"

If I see a bug - the deliberate #asStringg typo - the debugger pops
up, I correct the code, and then can't save the change because
#makeGeneratorFrom: isn't in the call stack. What I'd like is to (a)
save my change at all (rather than copy all the source, open a
Browser, find the right method, paste the source, accept), and (b)
have execution continue with the new version of the block.

(And a "wrinkle" (he says naively) is that to edit-and-continue here,
the new BlockContext (or whatever) would need to have references to
the variables closed over by the old BlockContext.)

[BTW, BlockContext isn't used any more.  Only MethodContext, which is now misnamed and should be renamed to Context.  Block and method activations are differentiated by blocks having a non-nil closureOrNil inst var].


So the change to the method is easy, but replacing the activation more difficult, simply because of the necessary UI plumbing.  BlockClosure>>asContextWithSender: does almost all you need (it doesn't push arguments) tio generate the activation.  You'll have to figure otu how to plumb that nto the debugger.


Even if I can't edit-and-continue this, at the least I'd like to save
the source from within the Debugger, and possibly abandon the Process.

Sure.  That's all about hacking out the warning in some way you can live with.

Please report back.  This is intriguing :)
 
Definitely intriguing.  I'd love it to be able to work that way. 

frank

>> You'd need to fiddle the stack pointer, but that you have to do anyway
>> in edit-and-continue.
>>
>> frank
>>
>
>
>
> --
> best,
> Eliot




--
best,
Eliot