This is really brilliant!

Doru


On Sat, Jun 28, 2014 at 9:34 AM, stepharo <stepharo@free.fr> wrote:
This is so cool. I remember when we played one afternoon in 2008 to see if this interplay would work.

Stef



On 27/6/14 10:19, Marcus Denker wrote:
Hi,

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
	aMethodBuilder
		pushLiteral: self;
		pushReceiver;
		send: #read:

emitStore: aMethodBuilder
	aMethodBuilder
		pushLiteral: self;
		pushReceiver;
		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
	^iv

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)


	Marcus




--
www.tudorgirba.com

"Every thing has its own flow"