[squeak-dev] #ifCurtailed - why the "complete := true" line?

Tobias Pape Das.Linux at gmx.de
Sat Feb 13 14:36:52 UTC 2021


Hi


> On 13. Feb 2021, at 12:55, Jaromir <m at jaromir.net> wrote:
> 
> Hi,
> I can't figure this one out - is the value of /complete / in #ifCurtailed
> method used somewhere? 
> Very confusing ;) Thanks a lot!
> Jaromir
> 
> ifCurtailed: aBlock
> 	| complete result |
> 	<primitive: 198>
> 	result := self valueNoContextSwitch.
> 	complete := true.
> 	^result


Yes.
But first thing to notice is that #ensure: uses the same primitive and the same names and oder of local variables.

In both methods, the comment states:
 " The VM uses prim 198 in a context's method as the mark for an ensure:/ifCurtailed: activation"

But more so:

Look at Context>>unwindTo:

unwindTo: aContext

	| ctx unwindBlock |
	ctx := self.
	[(ctx := ctx findNextUnwindContextUpTo: aContext) isNil] whileFalse: [
		(ctx tempAt: 2) ifNil:[
			ctx tempAt: 2 put: true.
			unwindBlock := ctx tempAt: 1.
			unwindBlock value]
	].


In a Context, that is the "running" form of a Block, tempAt: 1 is the argument of #ifCurtailed:/#ensure:.
and tempAt: 2 is "completed". So: the context will be marked as being completed either via #ifCurtailed: directly or via #unwindTo:.  However, in #ensure:

ensure: aBlock
	| complete returnValue |
	<primitive: 198>
	returnValue := self valueNoContextSwitch.
	complete ifNil:[
		complete := true.
		aBlock value.
	].
	^ returnValue

The aBlock will only be run if the action was not completed yet.
"complete" can be set from the outside as can be seen in #unwindTo:.
It is also visible, that #unwindTo: and #ensure: have a similar structure, but #unwindTo: operates on the data structure of the "running" code.

See also in Context: #restart #resume: #resume:through:  or Process>>#terminate.

I hope this helps :)

Best regards
	-Tobias





More information about the Squeak-dev mailing list