newCTFE a "funny" bug
Stefan Koch
uplink.coder at googlemail.com
Tue Jan 29 20:13:12 UTC 2019
Hi Guys,
I have exciting news for you.
I've made huge progress on issues which were confusing me for a
while.
The following is a description of the problem:
class A { int f1; }
class B : A { int f2; }
int[2] f()
{
B b;
b.f2 = 2;
b.f1 = 1;
return [b.f2, b.f1];
}
pragma(msg, f()); // this had the output [1, 1]
What was indeed going on here looked like an ABI issue, but went
deeper.
In order the have a stable ABI, I cannot relay on the class-sizes
or field-offsets which dmd gives me.
Therefore I build my own representation of types and store them
in type-tables.
when I get the request to store something in a field, I'll go
look the type up in the type table and get the offset from the
field information for that particular type.
For the above code this would have gone like this (code
simplified):
> {b.f2 = 2}; const type = classes.indexOf(B); // would be 3
> because there are 3 classes known (A, B and Object)
> const fieldIndex = type.fieldIndex(f2) // would be 1 because f2
> is the first Field in B
> const fieldOffset = type.offsetOf(fieldIndex) // would be 0
> because there is no field preceeding f2
> memoryLocationOf(b) + fieldOffset = 2; // same as
> memoryLocationOf(b) becaue fieldOffset is zero
and then for the next statement
> {b.f2 = 2}; const type = classes.indexOf(B); // would be 3
> because there are 3 classes known (A, B and Object)
> const fieldIndex = type.fieldIndex(f2) // can't find in B so
> look in A; would be 1 because f1 is the first Field in A and
> therfore falls onto the same index as f2
> const fieldOffset = type.offsetOf(fieldIndex) // would be 0
> because there is no field preceeding f2 in B
> memoryLocationOf(b) + fieldOffset = 1; // same as
> memoryLocationOf(b) because fieldOffset is zero
lastly:
> Return(CreateArrayOf([memoryLocation(b) + 0, memoryLocation(b)
> + 0])); // this location has been set to one in the previous
> statement.
In the actual code there is a multi-level lookup in a few
diffrent tables going on, therefore this was much less straight
forward to find as it seems.
Now that I have tracked down the root-cause of this problem is
should not be too hard to fix.
Though it should be noted that about 40% of complexity in newCTFE
is entirely for oop support, another 40% being delegates!
While I do think that delegates are genuinely useful I cannot the
same about classes.
One of the reasons it took me so long to even notice this issue,
is because I don't classes often myself, much less multi-level
inheritance.
Cheers,
Stefan
P.S. I currently on a short vacation and working on getting
newCTFE to a state where I can release it with a clear
consciousness.
More information about the Digitalmars-d
mailing list