AlekId / dwscript

Automatically exported from code.google.com/p/dwscript
0 stars 0 forks source link

Non compilable on Delphi 2010 #252

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
[DCC Error] dwsExprs.pas(149): E2467 Record or object type required

Original issue reported on code.google.com by kazantse...@mail.ru on 30 Apr 2012 at 8:52

GoogleCodeExporter commented 9 years ago
Looks like a D2010 bug, the type is actually a record...

Anyway to workaround it? by aliasing the generic type f.i?

Original comment by zar...@gmail.com on 30 Apr 2012 at 9:03

GoogleCodeExporter commented 9 years ago
Inlined accessor?

Original comment by kazantse...@mail.ru on 30 Apr 2012 at 9:07

GoogleCodeExporter commented 9 years ago
It's for performance since generics don't get inlined, so using a method would 
negate the point.
Though inline accessors have been supported on records for aeons.

Does using an alias rather than the straight generic works around the issue?

rather than TArray<TSymbolPosition>, definining

TArrayOfSymbolPosition = TArray<TSymbolPosition>

and using that instead?

Original comment by zar...@gmail.com on 30 Apr 2012 at 9:28

GoogleCodeExporter commented 9 years ago
Type aliase don't solve this problem.

>It's for performance since generics don't get inlined, so using a method would 
negate the point.

But TSymbolPositionList is not generic type, and his inlined methods will be 
expand in code.

Function GetList : TArray<TSymbolPosition>; Inline;
...
property List : TArray<TSymbolPosition> read GetList; //FPosList.List;

//
function  TSymbolPositionList.GetList : TArray<TSymbolPosition>;
Begin

 Result := FPosList.List;

end;
//

Check:

lst : TSymbolPositionList;

lst := TSymbolPositionList.Create(nil);
if Length(lst.List) > 0 Then Halt;
lst.Free;

asm:

MainFormUnit.pas.665: lst := TSymbolPositionList.Create(nil);
005DB42F 33C9             xor ecx,ecx
005DB431 B201             mov dl,$01
005DB433 A1881B5100       mov eax,[$00511b88]
005DB438 E88368F4FF       call TSymbolPositionList.Create
005DB43D 8BD8             mov ebx,eax
MainFormUnit.pas.666: if Length(lst.List) > 0 Then Halt;
005DB43F 8B430C           mov eax,[ebx+$0c]
005DB442 E805DAE2FF       call @DynArrayLength
005DB447 85C0             test eax,eax
005DB449 7E05             jle $005db450
005DB44B E82CB4E2FF       call @Halt0
MainFormUnit.pas.667: lst.Free;
005DB450 8BC3             mov eax,ebx
005DB452 E84D9FE2FF       call TObject.Free

Original comment by kazantse...@mail.ru on 30 Apr 2012 at 9:58

GoogleCodeExporter commented 9 years ago
Tried, but it doesn't work for the routine where the optimization is used 
(TdwsSymbolDictionary.RemoveInRange):

dwsExprs.pas.7087: symPos:=list.List[j];
00553BA4 8D55DC           lea edx,[ebp-$24]
00553BA7 8B45E8           mov eax,[ebp-$18]
00553BAA E88D040000       call TSymbolPositionList.GetList
00553BAF 8B45DC           mov eax,[ebp-$24]
00553BB2 8B55EC           mov edx,[ebp-$14]
00553BB5 8B0490           mov eax,[eax+edx*4]
00553BB8 8945E4           mov [ebp-$1c],eax

and there is also an exception frame added sin cthe function results in the 
dynamic array being copied.

And the GetPosition form isn't inlined either:

dwsExprs.pas.7088: symPos:=list[j];
005515FF 8BD3             mov edx,ebx
00551601 8BC7             mov eax,edi
00551603 E8A4020000       call TSymbolPositionList.GetPosition
00551608 8BF0             mov esi,eax

I've tried breaking up RemoveInRange, it's somewhat less efficient now, but is 
it working in D2010?

Original comment by zar...@gmail.com on 30 Apr 2012 at 11:44

GoogleCodeExporter commented 9 years ago
Now it working in Delphi 2010.

For inlining, method must be implemented before than anywhere call him. If 
GetList will be implemented before RemoveInRange and GetPosition then all will 
be ok.

RemoveInRange:

begin
   for i:=FPosList.Count-1 downto 0 do begin
      symPos:=GetList{FPosList.List}[i]; // method call here (!)
      if     startPos.IsBeforeOrEqual(symPos.ScriptPos)
         and symPos.ScriptPos.IsBeforeOrEqual(endPos) then
         FPosList.Delete(i);
   end;
end;

asm:

dwsExprs.pas.7343: symPos:=GetList{FPosList.List}[i];
0052540D 8B470C           mov eax,[edi+$0c]
00525410 8B3498           mov esi,[eax+ebx*4]

// GetPosition
//
function TSymbolPositionList.GetPosition(Index: Integer): TSymbolPosition;
begin
   Result:=GetList{FPosList}[Index]; // method call here (!)
end;

Code for GetPosition:

 lst := TSymbolPositionList.Create(NIL);
 lst.Items[0].ClassName;

asm:

MainFormUnit.pas.672: lst := TSymbolPositionList.Create(NIL);
005DB429 33C9             xor ecx,ecx
005DB42B B201             mov dl,$01
005DB42D A1881B5100       mov eax,[$00511b88]
005DB432 E88968F4FF       call TSymbolPositionList.Create
MainFormUnit.pas.673: lst.Items[0].ClassName;
005DB437 8B400C           mov eax,[eax+$0c]
005DB43A 33D2             xor edx,edx
005DB43C 8B0490           mov eax,[eax+edx*4]
005DB43F 8B00             mov eax,[eax]
005DB441 8D55EC           lea edx,[ebp-$14]
005DB444 E8339EE2FF       call TObject.ClassName

Original comment by kazantse...@mail.ru on 30 Apr 2012 at 12:20

GoogleCodeExporter commented 9 years ago
Ok!

Original comment by zar...@gmail.com on 30 Apr 2012 at 12:31