Automatic Generation of Glue for Named Primitives

Raab, Andreas Andreas.Raab at disney.com
Sun Sep 5 23:54:25 UTC 1999


Andrew,

This is neat stuff! I feel, however, that it is still kind of complicated to
write code based on it since one still has to figure out what the
specification must look like. Have you considered using an approach similar
to that of the translated primitives (e.g., like in String
class>>translate:from:to:table:)?! I would love to actually start writing
primitives by simply providing a small per-primitive specification such as

MyPlugin>>mySmallIntegerAdd: arg1 arg2: arg2

	self primitiveSpecification:
		#(
			SmallInteger			"Return type"
			'mySmallIntegerAdd'		"The name of the
primitive"
			(SmallInteger SmallInteger) "Argument types"
		).

	^arg1 + arg2

And then have the glue generated on the fly around the actual code (using
the mechanisms you've introduced). This would be extremely helpful for the
(most common) case of writing a few simple primitives while it would still
allow one to use a more complex glue specification (which might be necessary
for global variables) or even hand-code everything (by not using a glue-spec
at all).

What do you think?!

  Andreas
--
+===== Andreas Raab ========= (andreasr at wdi.disney.com) ==+
| Walt Disney Imagineering        Phone: +1 818 544 5016  I
I Glendale, CA                    Fax:   +1 818 544 4544  I
+======< http://isgwww.cs.uni-magdeburg.de/~raab >========+


> ----------
> From: 	Andrew C. Greenberg
> Reply To: 	squeak at cs.uiuc.edu
> Sent: 	Sunday, September 5, 1999 12:04 AM
> To: 	squeak at cs.uiuc.edu
> Cc: 	recipient list not shown
> Subject: 	Automatic Generation of Glue for Named Primitives
> 
> <<File: PrimPluginSupport.5Sept213am.cs>>
> Attached is a changefile with a working first cut at a tool for 
> automatically generating named (pluggable) primitives glue.  After 
> filing in the changeset, one can create a subclass of 
> InterpreterPlugin, as usual, but instead of manually coding the glue, 
> one may instead generates a "specification" in a #gluespecification 
> method in the class side of the plugin.
> 
> Several examples can be found after filing in by browsing in category 
> PPGen-Demo.
> 
> For example, the following is a sample specification for the "Foo" 
> example found in my Swiki discussion of named primitives:
> 
> glueSpecification
> 
>     ^super glueSpecification
>        primitive: 'primFooIntegerSeventeen' on: nil returns: SmallInteger;
>            code: #('result _ 17');
>        primitive: 'primFooIntegerIdentity' on: nil returns: SmallInteger;
>            parameter: 'anInteger' as: SmallInteger;
>            code: #('result _ anInteger');
>        primitive: 'primFooIntegerSumAnd' on: nil returns: SmallInteger;
>            parameter: 'firstInteger' as: SmallInteger;
>            parameter: 'secondInteger' as: SmallInteger;
>            code: #('result _ firstInteger + secondInteger');
>        primitive: 'primFooIntegerSumWith' on: Foo returns: SmallInteger;
>            parameter: 'anInteger' as: SmallInteger;
>            instVar: 'myInteger' as: SmallInteger;
>            code: #('result _ anInteger + myInteger')
> 
> After building the gluespecification, one can generate the glue with 
> a doit along the following lines.
> 
> 	YourPrimitiveNameHere generateGlue
> 
> This doIt performs the following:
> 
> A.  Adjust the Plugin's definition, as necessary, to assure that all 
> global instance variables are defined as plugin instance variables.
> B.  Automatically generate a #declareCVarsIn: method in the class 
> side (in category 'glue'), consistent with the specification.
> C.  Automatically generate a primitive glue method for each primitive 
> specified in the glueSpecification, consistent with each 
> specification.  Each method does the following:
> 
> 	1. loads parameters into temporary variables, with or without 
> validation as specified in the glueSpecification;
> 	2. loads receiver instance variables into either temporary 
> variables or global variables, with or without validation, as 
> specified in the glueSpecification;
> 	3. return if the primitive failed validation, or if not, 
> execute the specified code;
> 	4. return if the primitive failed validation, or if not, 
> validate and save those instance variables identified for saving in 
> the specification.
> 	4. pop the stack and return a value, as appropriate.
> 
> Detailed for the specification methods will be forthcoming once I 
> have a stable, solid version of the tool.  In the meanwhile, one can 
> scry the basics from a review of class PluginSpecifiction.  A summary 
> follows:
> 
> I. Major Sections of the Specification
> 
> >>gInstVarsFrom: aReceiver (zero or more of these)
> 
> 	Subsequent gInstVar: definitions will be treated as 
> specifying a global instance variable to be loaded from the specified 
> receiver object.
> 
> >>primitive: pName on: rcvrClass returns: resultClass (zero or more of
> these)
> 
> 	Subsequent specifications will relate to the definition of 
> primitive method pName, which will expect to be called by an object 
> with the general "shape" (see below) of rcvrClass, and return an 
> object with the general "shape" of resultClass.
> 
> II. Specifying a method.  Further defining a primitive method 
> comprises specifying all parameters, instance variables actually 
> loaded or saved from the receiver.  These can be specified as follows:
> 
> 	>>parameter: pString as: pClass
> 
> This specifies a parameter named pString, which will be loaded and 
> validated for having the "general shape" of class pClass.  Otherwise 
> the primitive will fail.
> 
> 	>>parameter: pString kindOf: pClass
> 
> This specifies a parameter named pString, which will be loaded and 
> validated only if it is a member of pClass or of a subclass of 
> pClass.  Otherwise the primitive will fail.
> 
> 	>>parameter: pString memberOf: pClass
> 
> This specifies a parameter named pString, which will be loaded and 
> validated only if the actual parameter is a member of pClass. 
> Otherwise the primitive will fail.
> 
> 	>>parameter: pString asNoCheck: pClass
> 
> Same as #parameter:as:, except that no validation is done.
> 
> 
> 	>>instVar: pString as: pClass
> 	>>instVar: pString kindOf: pClass
> 	>>instVar: pString memberOf: pClass
> 	>>instVar: pString asNoCheck: pClass
> 
> This loads an instance variable from the receiver into a temporary 
> variable or variables of the method.  Note that the receiver must be 
> a member of the specified receiver class or a subclass thereof, and 
> pString must be the name of an instance variable of that reciever. or 
> else an error will be reported.  instVars can be loaded with as:, 
> kindOf, memberOf and asNoCheck variants, similar to those described 
> above.
> 
> 	>>instVar: pString declareC: aString
> 
> This defines a programmer's temporary variable, which will be 
> declared in the C-module as specified in aString.  All loading to or 
> storing from these variables must be done in the user's code -- the 
> generator will only declare these variables.
> 
> 
> 	>>gInstVar: pString
> 	>>loadAllGVars
> 
> This loads the named instance variable into the global variable 
> specified (or all global variables defined above), provided that 
> pString had been defined in an earlier gInstVar definition and 
> further provided that pString is defined as an instance variable of 
> the method's reported receiver class or a subclass thereof.
> 
> 	>>saveInstVar: pName
> 	>>saveAllInstVars
> 
> This directs the generator to generate code to assign the specified 
> instance variables back to the receiver upon the successful execution 
> of the primitive.
> 
> 	>>code: aCollectionOfStrings
> 
> The collection of strings will be inserted into the code after the 
> parameters and instance variables are loaded, in #do: order.
> 
> III. Specfying global instance variables.
> 
> 	>>gInstVar: iName as: iClass
> 	>>gInstVar: iName kindOf: iClass
> 	>>gInstVar: iName memberOf: iClass
> 	>>gInstVar: iName asNoCheck: iClass
> 	>>gInstVar: iName declareC: aString
> 
> Specifies a for loading receiver instance variables into the 
> primitive plugin's instance (and the C-module's global) variables. 
> The shape definitions are set forth as for primitives and temporary 
> instance variables.
> 
> IV. Notion of "shape"
> 
> Smalltalk doesn't have classes, per se, but instances of Smalltalk 
> classes have measurable and discernable representations in the 
> computer.  SmallIntegers, for example, are 30-bit values stored in a 
> specially munged way to be distinguishable from object pointers. 
> Other objects may have zero or more instance variables and zero or 
> more indexable variables.  The indexable variables might themselves 
> contain pointers to other objects, or might merely be 8- or 32-bit 
> quantities.  I refer to this collective information as the "shape" of 
> a Smalltalk object.
> 
> For these reasons, the manner in which a C-language program can load, 
> store and/or manipulate this information depends upon knowledge of 
> the shape of the object.  Later documentation will elaborate further 
> upon this notion and how it is used by the plugin generator.
> 
> 
> 





More information about the Squeak-dev mailing list