Squeak
  links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Specifications For Named Primitives
Last updated at 5:49 pm UTC on 22 January 2006
Pleasse note that Andrew Greenberg started this page and clearly hasn't quite completed it. Tim Rowledge has done a little editing in the hope of clearing up a couple of points.

Overview

While much easier than creating numbered primitives (which required rebuilds of the entire VM), named primitives still were quite difficult to create. A thorough understanding of the Squeak VM was still necessary to do anything non-trivial. Even given that understanding, the detailed and painstaking process of building interpreter "glue" procedures to facilitate linking from the interpreter to the C-language code made the process difficult, time-consuming and error-prone, and obfuscated the real functional code of the primitive itself. As errors in primitives often crash the system, even in emulation, debugging was a major problem.

Hoping to make named primitives more practical and useful, I have rewritten the Slang translator (C language translator) so that Squeak will automatically generate much of the "glue," particularly linkage and stack implementation issues, that were often the bane of primitive designers. The translator still compiles "old-style" primitives as usual, but will instead generate the "autoglue," upon finding a primitive containing the following directive:

primFoo: arg1 with: arg2 with: arg3
     |rcvr size |
     rcvr := primitive: 'primFoo'
             parameters: #(Oop Boolean Array)
             receiver: #SmallInteger.
     
     . . . . arg3 at: 2 put: (23 asOop: SmallInteger) . . . .
     . . . . size := arg3 size . . . .
     . . . . ^ expression asOop: Array . . .

This snippet would produce a primitive named 'primFoo' which expects three arguments - a general oop (arg1), a boolean (arg3) and an array (arg3).

The autoglue includes the following:

The specification named primitive can then be invoked with language such as the following (assuming the primitive was defined in class FooPrimitive):


primFooOn: anyOop with: anyBoolean using: aString
     <primitive: 'primFoo' module: 'FooPrimitive'>
     ^FooPrimitive
          doPrimitive: 'primFoo:with:with:'
          withArguments: {anyOop. anyBoolean. aString}


Note that a specification named primitive will NOT work properly with the #doPrimitive InterpreterProxy method, and that traditional named primitives will NOT work properly with the new #doPrimitive:withArguments method.

Examples of the new system are found in the recently published changesets. Of particular interest may be Foo2, FlippyArray2 and TestOSAPlugin.

Getting Started


For now, the new language has been segregated to subclasses of the Slang code generator and interpreter plugin classes. In order to use the new specification system, your plugin must be made a subclass of TestInterpreterPlugin and not directly from InterpreterPlugin. No other special preparations need be followed.

New Translation Directives and Builtins


Specification Directive


[Discussion of #primitive:parameters:receiver]

Explicit Coercion Directive


[Discussion of #asOop:]

Other Special Directives and Builtins!

size

[Discussion of automatic oop pointer calculations]

next and atEnd

[Discussion of Streaming Integers]

Class Specifications

A key new feature of the system is the use of Class identifiers to specify coercions. Each class will specify (with inheritance for its subclasses) three following factors:

  1. How the identifier will be defined in C
  2. Whether and if so, how, the object will be coerced when loaded from Smalltalk to the C identifier
  3. Whether and if so, how, the object will be tested for consistency with the specification

As presently defined, the classes behave as follows:

Default Specification

Class Object
  1. Definition: 'int'
  2. Coercion: none
  3. Validation: Fail unless actual parameter or receiver is of the specified type or a subclass of that type

Special Scalar Specifications

Class Oop

Class Boolean
  1. Definition: 'int'
  2. Coercion: (loading) 1 if trueObject, 0 if not trueObject; (storing) falseObject if 0, trueObject otherwise
  3. Validation: (loading)fail unless object is either true or false (storing) none
Class SmallInteger
  1. Definition: 'int'
  2. Coercion: (loading) integer value corresponding to oop (storing) SmallInteger oop corresponding to the integer value
  3. Validation: (loading)fail unless object is SmallInteger (storing) fail unless integer value is within SmallInteger range (-2^30 to 2^30-1)
Class Unsigned
  1. Definition: 'unsigned int'
  2. Coercion: (loading) integer value corresponding to oop (storing) SmallInteger or LargePositiveInteger oop corresponding to value
  3. Validation: (loading) fail unless object is an Integer representing a non-negative number less than 2^32 (storing) fail unless non-negative#
Class Float
  1. Definition: 'double'
  2. Coercion: (loading) corresponding double precision floating point value (storing) oop for corresponding Float object
  3. Validation: (loading) fail unless object is a Float (storing) fail unless object is a double precision c value

Special Indexed Object Specifications

Class Array
  1. Definition: 'int '
  2. Coercion: (loading) C pointer to first oop in the array (storing) oop for the corresponding object
  3. Validation: (loading) fail unless oop is pointer indexable(storing) none
Classes ByteArray and String
  1. Definition: 'char'
  2. Coercion: (loading) C pointer to first oop in the array (storing) oop for the corresponding object
  3. Validation: (loading) fail unless oop is Byte indexable(storing) none
Classes IntegerArray
  1. Definition: 'int '
  2. Coercion: (loading) C pointer to first oop in the array (storing) oop for the corresponding object
  3. Validation: (loading) fail unless oop is Word indexable(storing) none
Classes WordArray
  1. Definition: 'unsigned int'
  2. Coercion: (loading) C pointer to first oop in the array (storing) oop for the corresponding object
  3. Validation: (loading) fail unless oop is Word indexable(storing) none
Custom Specifications
New specifications and their behaviors can be defined by overriding certain methods in the class side of a Smalltalk class, as was done for special classes Oop and Unsigned (none of which were really intended to be concrete in Smalltalk, but exist merely to define specific coercion and validation behaviors during translation) and the several classes referred to in TESTOSAPlugin (which permit seamless and straightforward access to C-language type classes such as may be used with a specialized API). Of particular use and interest in this regard is the new class ExternalArray and its subclasses.