Tuesday, August 21, 2007

NewCompiler repport

Last two weeks I worked on decompilation and optimization

For the decompilation I made some fixes for the closure decompiler.

Mainly fixes concern scope. Now I have a clear view of how variables are accessed.
This is not really what you can understand when you read the implementation. And I think we should concentrate to go in this direction.
So there is 3 different way to access a variable (I am talking only about temp and inst var).

- "Simple access": This is when we access a variable that is not captured.
The generated bytecodes are #pushTemp: offset, #storeTemp: offset , #pushInstVar: offset or #storeInstVar: offset.


| a |
a := 3.
[ | b | b:= 5 factorial.]

- "Captured access": This is when we have to access to a temp defined in the same scope that is captured by a block.


| a b |
a := 2. "A captured access"
b := 1. "An other captured access"
[a + [b] value ] value.

The compiler here needs to access to the ClosureEnvironment stored in the MethodContext:
pushConstant: 2
pushConstant: 5
send: privGetInstVar:
pushConstant: 1
send: privStoreIn:instVar:

- "Far captured access": When we want to access to a variable which is in the parent scope

| a b |
a := 2.
b := 1.
[| c |
c := 3.
a + [b + c] value ] value. "Two different kind of Far captured access "

The right closure need to be pushed before we can access to the temp.

for the inst var a:

pushInstVar: 1 "since the receiver of the block is the closure environment"

for b:

pushInstVar: 0
pushConstant: 2
send: privGetInstVar: " Closure environment are chain by storing them in the first slot of the parent closure environment ".

Now to optimize the NewCompiler I have implemented 5 bytecodes.

- the first one is to push or store the closure environment:

send: privGetInstVar:

will be replace by:


This bytecode is needed when you create the block. (Remember the receiver of the block is the closure environment)
I have also implemented the bytecode for the "captured access" and the far "captured access":

pushConstant: 2
pushConstant: 5
send: privGetInstVar:
pushConstant: 1
send: privStoreIn:instVar:

is replaced by:

pushNestedClosure: 0 offset: 0


pushInstVar: 0
pushConstant: 2
send: privGetInstVar:


pushNestedClosure: 1 offset: 1

If you get confused with the value of the offset is normal.
In the image and more particularly for the message #privGetInstVar:, the instance variable are count starting from 1.
But in the VM the offset is count starting from 0.

The last bytecode concern the closure creation:

pushConstant: ClosureEnvironment
pushConstant: 1
send #mew:

replace by:

new closure: 1

I have made a small benchmark to see the performance:
[| a | a := 0. #(1 2 3 4 5 6 7 8 9 10) do: [:each | a := each + a].a halt] bench.

the result is:
For the new compiler:
'405 558 per second.'.

For the old closure and old compiler:
'567 088 per second.'.

Full closure performance is now quite close the the non full closure performance.
Some other benchmark is needed to confirm that result.
They is also some other optimization inside the bytecode and primitive to make closure faster.
At the end the new compiler could have similar performance to the old one.

Saturday, August 18, 2007


Hello. I've implemented headings and tables (without "=" as table haders for now.). I'm planning to finish tables and start implementing next tags. Remaining tags are: Links, Lists, Image, Placeholder and partly Escape character. Current status page with examples.

Wednesday, August 15, 2007

Having MC2 look like MC1

I'm currently working on making MC2 really look like MC1. This is what results from the discussion we had with my mentor when he visited me two weeks ago. My main goal is to have the same features as in MC1 to ease adoption, not more not less.

What have changed recently:

- I've implemented the 'Changes' feature. Changes are calculated but a tool must be built to display them.
- I've also implemented a browser for repositories. This is really like the Repository Browser in MC1.
- Some classes avoids the creation of equal instances (the slices, the slice stati...).
- Corrects a bug with the directory repository.

Here is a screenshot of the two MC2 browsers. When there are '?' around a button label, that means the feature is not yet implemented.

What I plan to do in future weeks:

- Finish the implementation of the 'Changes'
- Change the format of commits to contain textual information (a zip with the source code, the change comment, and the binary data that is already generated)

Monday, August 13, 2007


I worked on html tables last week. DomView is now able to display simple tables(with small bugs).
I have to display HEAD and FOOT nodes and manage colspans/rowspans - it will be my next week task.

If those milestones are reached, i will have to work on table borders and others table CSS attributes.

Tomorrow,I will add screenshots on my blog.

Monday, August 6, 2007

HTML Tables

Last week was devoted to Html tables renderer. I thought of an effective manner to display tables.
This one is not completed yet, but I have a start. I will have to adapt this method to be able to render complex tables (with rowspan or/and collspan attributes).

First, I wanted to use an existing package named SFC-Layout - Finally i am writing my own code.

I will continue this work during this next week - I hope that a pretty screenshot will be available next week :-) .


Ok. Finally I've got Preformatted tags working. That also helped me to find some bugs which I've fixed too. I'm going to implement next tags in this week. Also I'm planning to get a new image from Keithy so I could start next task in parallel. The only problem with Preformatted is that string: //yoyo{{{preformatted}}}yoyoyo// will be in italics at any position (preformatted too). I thought that this is a bug, but Creole sandbox shows the same result. Please visit my site at Services -> CreoleTest and feel free to edit that page. (**bold**, //italics//,{{{preformatted}}},---- and \\).