[squeak-dev] Questions about FullBlock closures

Eliot Miranda eliot.miranda at gmail.com
Sun Feb 12 20:48:05 UTC 2023

Hi Tim, hi All,

On Feb 12, 2023, at 10:23 AM, tim Rowledge <tim at rowledge.org> wrote:


The actual primitives for Cog are *much* more complex. Whilst I wouldn't
normally advise looking at the C code for the VM, in this case it might be
instructive to peek at the generated gcc3x-cointerp.c file and find the
primitiveTerminateTo() routine.

No, no and thrice times no!! :-) There is a story I'll tell you at the end
if the email, but first...

The only times to look at this code are probably
- when one is checking that Slang has generated the correct code from the
VMMaker.oscog package’s Smalltalk code
- when debugging the VM at the C level instead of the Smalltalk level

If you do want to look at the code and make sense of it look at
the VMMaker.oscog code in an image.  There is a script,
that will build such an image.

The VM’s interpreter code is the hierarchy of StackInterpreter.
The VM’s JIT code is the hierarchies of
The VM's memory managers are

But on the "do..." menu you'll find
et al which make it much easier to browse this admittedly rather complex
system. And in finding methods MessageNames is your friend. It understands
patterns separated by semicolons.  So a MessageNames on *terminateTo* will
find the code you;re looking for.

You'll also find workspaces to help you run the VM simulator, generate VM
sources, JIOT a method, etc.

Now that story. Once upon a time Alan Kay's team were working at
Hewlett-Packard. HP were trying to sell 64-bit machines based on the 64-bit
HPPA RISC chip. One of the customers used Squeak.  So a team of HP
engineers tried to port Squeak to 64-bits by starting with interp.c, the
generated code for the 32-bit BackToTheFuture interpreter VM. They spent at
least 6 months, and failed.  Alan was alerted and Dan Ingalls, Ian Piumarta
and others did a very quick port, 3 months, IIRC, and this is why the
original 64-bit Squeak stull only had 31-bit SmallIntegers, etc, [and is
why I don't consider this a "real" 64-bit implementation.  It's merely a
widening of the 32-bit implementation so that one can have 64-bit oops, but
otherwise wastes lots of opportunities (64-bit Spur has 3 tagged
(immediate) types, SmallInteger, Character, and SmallFloat64; it also
supports 8-bit, 16-bit, 32-bit and 64-bit integer arrays, etc)].

The moral of this tale is that, no matter how good you are, you won't make
head nor tail of the overall VM architecture and functionality looking at
Slang's output. The only proper place to try and make sense of the VM is
the level at which it is written and debugged, which is in Smalltalk.

   1. Daniel Ingalls, Eliot Miranda, Clément Béra, and Elisa Gonzalez
Boix. *“Two
   Decades of Live Coding and Debugging of Virtual Machines through
   Simulation.”**Software: Practice and Experience* 50, no. 9 (2020):
   1629–50. https://onlinelibrary.wiley.com/doi/abs/10.1002/spe.2841.
   2. Eliot Miranda, Clément Béra, Elisa Gonzalez Boix, and Dan Ingalls. *“Two
   Decades of Smalltalk VM Development: Live VM Development Through Simulation
   Tools.”*In *Proceedings of the 10th ACM SIGPLAN International Workshop
   on Virtual Machines and Intermediate Languages*, 57–66. VMIL 2018. New
   York, NY, USA: ACM, 2018.https://doi.acm.org/10.1145/3281287.3281295.
   3. Available on request.

_,,,^..^,,,_ (phone)

On 2023-02-12, at 7:53 AM, Eliot Miranda <eliot.miranda at gmail.com> wrote:

Hi Jaromir,

On Feb 12, 2023, at 5:13 AM, Jaromir Matas <mail at jaromir.net> wrote:


What is the purpose of the primitive 196 Context>>#terminateTo:?

Strongly related to prim 195 & 197. You have to check each context up the
chain to see what exceptions might be dealt with & by which context.

My understanding is prim 195 (#findNextUnwindContextUpTo:) searches for
unwind contexts and prim 197 (#findNextHandlerContextStarting) searches for
handler context. But prim 195 (#terminateTo:) is unclear to me.
#terminateTo comment says:

"Terminate all the Contexts between me and previousContext, if
previousContext is on my Context stack. Make previousContext my sender."

Which doesn't say much except it's nilling all context's pc and sender
between self and the argument. I wonder what else it does behind the scenes
and why :)

In a paper from 2009 Eliot wrote:

"[...] there’s a primitive terminateTo: that does something similar to the
context nilling in non-local return. It is a little simpler than non-local
return (although not much) but it is just a variation on the same theme so
I’ll spare you."

I wish Eliot didn't spare us :) Other than that I haven't found any further

Because the primitive 196 dates back to 2001 I'm unable to judge whether
it's still essential to nil the intermediate contexts (to free stack pages
or something).

In particular I'm trying to understand whether the use of #terminateTo
*primitive* in #resumeEvaluating: and #resume:through: is essential or not.

There are three things that primitive 296, Context>>terminateTo: does, or
rather there are two things it does, and it does them in a particular way.
It sets senders and pcs of intervening contexts to nil. It sets the sender
of the receiver to the argument. If does this atomically.

I can’t say whether the last of these is necessary. If it is, then the
primitive is needed, essential. But the primitive merely optimized the
former two operations.

In the StackInterpreter & CoInterpreter it provides a significant
optimization because

- the primitive avoids creating any contexts; if if were not implemented
primitively then  contexts would have to be created for all intervening
frames, merely to throw unreferenced ones away

- intervening stack pages can be freed without looking at their contents

So the primitive is an important optimization for Stack/CoInterpreter.

But I suspect that atomicity is not crucial and that therefore the
terminateTo: primitive is only an optimization.

Any additional info greatly appreciated.





Jaromír Matas

mail at jaromir.net

From: tim Rowledge

Sent: Sunday, February 12, 2023 5:18

To: The general-purpose Squeak developers list

Subject: Re: [squeak-dev] Questions about FullBlock closures

On 2023-02-11, at 4:04 PM, Jaromir Matas <mail at jaromir.net> wrote:

If I may, I have a question here: What is the purpose of the primitive 196
Context>>#terminateTo:? Why primitive and why terminating each context
along the way? Naively, I'd think checking the two contexts are in the same
sender chain and patching them via privSender should do but I'm sure I'm
missing something here :)

Exception handling stuff. Strongly related to prim 195 & 197. You have to
check each context up the chain to see what exceptions might be dealt with
& by which context. Look at e.g. Process>>#terminate for some context.



tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim

When flying inverted, remember that down is up and up is expensive

tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
Useful random insult:- Life by Norman Rockwell, but screenplay by Stephen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20230212/3e0b6c16/attachment.html>

More information about the Squeak-dev mailing list