Documentation > PST v2.0a for Squeak v2.7 — How It Works
 
  • PST 2.0a Implementation Details
  • The basic place where Pocket Smalltalk starts is with the class PstSqueakProject. This class is a subclass of the standard Project class that exists within Squeak.  Modifications were made to the base Project class, see System Modifications, in order to add support for entering and exiting a project.

    A Pocket Smalltalk Project is created by:

    PstSqueakProject openNewMorphic

    Please note that what follows can seem pretty nasty, but what the hell it works. When this newly created project is entered, the method entering is called:

    PstSqueakProject>>#entering

        self swapPstProtoObjectSubclasses;
            initializeEnvironmentIfNecessary;
            setupGlobals;
            setupPatchedMethods

    swapPstProtoObjectSubclasses

    This method takes the existing subclasses of the class PstProtoObject and stores them to restore them later, and replaces them with the classes that exist in the project being entered.  Yes plays around with the subclasses instance variable of the class. All classes created within a Pocket Smalltalk project are rooted in this class.  Unlike Squeak, where all classes are rooted by nil. If you think this is bad, then don't read any further.

    initializeEnvironmentIfNecessary

    Create a new environment, much like the Smalltalk global, that will keep track of all the global variables and classes created within the project. Note that even the class Object is not sacred.  Pocket Smalltalk has its own Object class, and this is supported by these tricks.
    The reason we can have Pocket Smalltalk classes and Squeak classes with the same name, but potentially totally different structures is a mind twister.  When Smalltalk code containing references to global variables is compiled, the resulting code stores the association that exists in Smalltalk at the time of compilation.  What that means, is that if in the future the Smalltalk dictionary, or current environment is changed to be a new one, the old references stay.  This is why the Squeak code still runs, even though I place a new environment.  I had considered replacing the Smalltalk variable with another, but too much code in the system depends on this variable.  So instead I created a subclass of the compiler that requests the current project for its environment.

    setupGlobals

    Here I replace some global variables with ones that suit my needs, but still allow the system to function.  The variables and their corresponding values are as follows:

     

    • ClassBuilder with PstSqueakClassBuilder.
    • ClassCategoryReader with PstSqueakClassCategoryReader
    • Compiler PstSqueakCompiler
    • Parser PstSqueakParser
    • SystemOrganization with the PST project's system organization
    • Utilities with PstUtilities

     

    Most of these global variables are actually classes.  Most of them are replaced with specialized subclasses of the originals.  These subclasses take into account the fact that we are dealing with a project with its own environment for compilation and such.  We did not want to modify system code, and therefore created subclasses.  This does pose a problem if the class changes, but we will deal with those situations when they arise.  We could have used the method replacement trick that follows for some of the cases, but this works, we may revisit some of these and use the other trick.

    setupPatchedMethods

    As in the above trick, where we replace global variables, here we replace actual methods themselves.  The cool trick here is that the methods are replaced by ones implemented in PstSqueakProject itself.  Since the Squeak method lookup does not actually use the selector (in fact there isn't one) that could be stored in the CompiledMethod.  It uses the key in the method dictionary.  So we the following methods quietly, no change set or recompiling, simply replace one CompiledMethod with another:

    • SystemDictionary>>#environmentForCategory:

      Return the environment for the current project, instead of Smalltalk. This change should be made in general to support environments.

    • SystemDictionary>>#allBehaviorsDo:

      Instead of iterating over all of the classes in the system, the replacement method goes through all of the methods in the current PstProtoObject hierarchy. This works for Pocket Smalltalk since PstProtoObject is guaranteed to be the root of all classes.

    There is an equivalent restore method that restores the system to its original state.  Every replacement made above records the original value, so that it can be restored upon project exit.  Note that nested Pocket Smalltalk projects are supported as well, and special considerations in the initializeEnvironment method had to take this situation into account.

    Lastly, there were a few System Modifications that had to be made, but these are very minor and we may release these as general fixes since they do not harm normal Squeak operations.

    Figuring this stuff out was a bit of a problem.  Realize that if any problems are encountered on entering or exiting a project, that the Squeak environment gets left in a not so good state.  It took a few tries to get this right.  This is one of the reasons why we STRONGLY recommend to save your main image before filing this stuff in.  If entering or exiting a Pocket Smalltalk project breaks, then you might be left hanging without much recourse.

    Eric Arseneau — July 8, 2000

     

     

     

     

     

     

 

Last updated: Dec 7, 2001

Palm Powered is a trademark of Palm Inc. Pocket Smalltalk is trademark of Pocket Smalltalk Group. Copyright (c) 1998 - 2001 Pocket Smalltalk Group.