First class instance variables getting exciting

Marcus Denker is improving the interaction between the new compiler and the
first class instance variables and the results look exciting. I remember brainstorming and
prototyping a solution in 2007 with him and this is wonderful to see this getting real.
Here is the description made by Marcus:

So now Opal delegates code generation for read and write to the Slot meta objects.
The methods called are #emitValue: and #emitStore:, the parameter is an IRBuilder.

With this the implementor of a Slot is free to generate whatever bytecode needed, it will
be inlined at the read or assignment site in the method.

For the ivar Slot this is e.g. just

emitStore: methodBuilder

 methodBuilder storeInstVar: index

emitValue: methodBuilder

 methodBuilder pushInstVar: index.

Now the implementors of Slots should not need to be bothered about bytecode, therefore we have
in the superclass of all Slots defaults emit methods that implement a *reflective* read and write using
the MOP of the Slot itself (slower than code generation, but often enough):

emitValue: aMethodBuilder
 pushLiteral: self;
 send: #read:

emitStore: aMethodBuilder
 pushLiteral: self;
 send: #writeToSlot:of: 

What this means is that for someone who wants to implement a slot, you do not have to deal with bytecode at all.

Here is a simple Slot:

Slot subclass: #TestSlot
 instanceVariableNames: 'value'
 classVariableNames: ''
 category: 'Slot-Scope’

read: anObject
 ^ value

write: aValue to: anObject
 value := aValue

So this is a strange kind of Slot that stores the value in itself, which means it is shared between all objects as there is only
one Slot meta object per class per slot. (not something you want to do in real world, but a nice demo)

Now we can create a class (not yet easily as we have not yet enabled a class template, so lets use the ClassBuilder directly):

PharoClassInstaller make: [ :builder |
 builder name: #A;
 slots: { TestSlot named: #iv };
 category: #Playground ].

In class A we can implement accessors:


iv: anObject
 iv := anObject

They look like normal ivar accesses, but in the background, the compiler delegated to the Slot the code generation, calling emit*, which leads
to the bytecode e.g. for the read:

21 <20> pushConstant: iv => TestSlot
22 <70> self
23 <E1> send: read:
24 <7C> returnTop

you could override the emit* methods to generate faster code, but to get something running it is not needed.

To test, e.g. you can set the slot from one object and read it from another:

A new iv: 6
A new iv

Then inspect the slot:

(A slotNamed: #iv) inspect

(this should all Work in 4.0 048, the example is there as TestSlot for now)

…next steps:

1) Class Definition template for classes with Slots
2) How do we save these classes in Monticello?
3) Virtual Slots (Boolean and PropertySlots)



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: