Efficient expanded implementation

Current issues

Expanded were hard to implement correctly because of the high requirement on the GC. It was done so that the embedded expanded reference was just treated as a normal reference except it was pointed on a subpart of the enclosing object. Therefore when within the expanded object, we were assigning a new object, we needed to go back not to the expanded header, but to the enclosing object header. Most of the bugs we had were related to an incorrect header update.

 

Better solution?

We believe there is a better solution. To describe it, we are going to take an example, with two classes A and B:

class A
feature
	a: STRING
	b: expanded B
	f is
		local
			i: INTEGER
		do
			b.g
			i := b.i
		end
end
class B
feature
	i: INTEGER
	s: STRING
	g is
		do
			print (i)
		end
end

For class A we can generate the following attribute layout, that does not take into account the way an instance of B is laid out.

  1. s: STRING
  2. a: STRING
  3. i: INTEGER

For class B, a possibly layout is:

  1. s: STRING
  2. i: INTEGER

Don't forget that reference types have to be before the basic types.

So when we generate the code for f in A, we generate something like:

void f (EIF_REFERENCE Current) {
	EIF_INTEGER i;
	B_g (Current);	// Call b.g
	i = Current->i;	// Call b.i
}

Let's see what is `B_g' in code generated for `expanded B':

void B_g (EIF_REFERENCE Current) {
	print (Current->(access_i (Current)))
}

where `access_i' is a function returning the offset of `i' in `Current' object. This offset depends on where the expanded B is located. For the case of A, it points to the following function:

EIF_INTEGER access_i (EIF_REFERENCE Current) {
	return offset (Current, &Current->i)
}