Coming from another Smalltalk
Smalltalk MT (STMT) has many similarities to other Smalltalks but because this is
compiled Smalltalk there are a number of necessary differences.
- In the Source subdirectory of the STMT installation you will find SMALLTALK
EXTENSIONS.SP, SMALLTALK SYSTEM EXTENSIONS.SP and SMALLTALK.SP.
These projects include some abstractions that may be helpful when moving to
STMT.
- An object pointer in STMT is actually the address of the object. Sending an object
basicAddress returns this pointer and this will be constant for the life of
the object.
The
object header is 8 bytes back from this pointer.
To demonstrate this, in one workspace enter str := 'abcde'. Now
evaluate str basicAddress. This will return a 32 bit number (both the
objects address and its hash value). Copy this number into another workspace and send it _asObject and
inspect the result. You will get the same string back. This is similar to a
GemStone object identifier.
- Objects can live in one of four places depending on the allocation method.
Object Memory which uses Virtual
Memory when allocated with new.
The stack which uses a Frame
Allocation when allocated with localNew.
Heap Memory which uses the Private
Heap when allocated with heapAlloc.
MMF memory when used in a Memory
Mapped file (see classes MemoryStream and MappedObjectStream).
- Since Windows manages the
memory for all allocation types, STMT is not concerned about memory fragmentation or having to move
objects around in memory.
- DLL's can be statically loaded into the image. Image properties allow you
to add a DLL. On an image save the DLL header is bound directly into the new
image. When the image is brought up next, all of the DLL entries are
available inline.
- APIs can be called directly. For example try to evaluate
WINAPI strlen:
'My string' basicAddress
strlen is an API in the C runtime library which is included as part of the
STMT environment. STMT makes extensive use of the C runtime library instead
of recreating this functionality. The C runtime library is fully documented
in both the MSDN library (http://msdn.microsoft.com)
and the MC Visual C/C++ documentation.
Note that API calls are faster than message sends. On encountering a WINAPI,
the compiler generates code to push the arguments on the stack and jump to
the API address directly.
- Some messages are inlined which means that the compiler knows how to
generate code for them directly. An example of this is anObject _longAtOffset:
4.
There is no compiled method object so grep is used to find
senders, implementors and instance variable references. This means that
strings in comments will show up. There is also a query in the Class
Hierarchy Browser (CHB) which will search for strings across methods (current
class or all classes). In the CHB, methods can also be found by typing their
name.
- When you send fork or forkAt: to a context block, the context block runs
in its own windows thread. This means that you must be concerned about
synchronization if multiple threads touch the same objects. See the
Philosophers sample for an example of multi-threading.
- Categories are more than just a way of classifying methods. They advise
the compiler of the type of a method. Putting a method into the category .INTERNALDEV
for example means that the method is available in the development
environment but will not included in a runtime project. If you don't want to
see categories, they can be turned off in the View Menu of the Class
Hierarchy Browser.
- Projects are the way to manage source code. Multiple projects can be
loaded into the development environment and projects can specify other
projects as prerequisites. A project is required to create a runtime
application.
- You can expand up the method pane to full-size using Ctrl-Z.
- Ctrl-Break (i.e. user break) is done by using the ThreadViewer. Start the
Thread Viewer from the Tools menu in the Transcript. This load a tray
program (look in the task bar tray). Opening this will show all the
currently running threads. Thread #0 is the main process thread. Selecting
this thread and pressing Break will cause an exception to be sent to the
main thread. Then you can debug where this exception happened.