Skip to content

Commit 171f7b4

Browse files
sglienkevincentparrett
authored andcommitted
fixed spurious internal compiler errors in XE6 and XE7
1 parent 65dfe00 commit 171f7b4

File tree

3 files changed

+76
-43
lines changed

3 files changed

+76
-43
lines changed

Source/Base/Collections/Spring.Collections.Base.pas

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,26 +2700,28 @@ function TIterator<T>.MoveNext: Boolean;
27002700
label
27012701
_STATE_RUNNING;
27022702
begin
2703-
case fState of
2704-
STATE_RUNNING:
2705-
_STATE_RUNNING:
2706-
begin
2707-
Result := fTryMoveNext(Self, fCurrent);
2708-
if Result then
2709-
Exit;
2703+
repeat
2704+
case fState of
2705+
STATE_RUNNING:
2706+
_STATE_RUNNING:
2707+
begin
2708+
Result := fTryMoveNext(Self, fCurrent);
2709+
if Result then
2710+
Exit;
27102711

2711-
Dispose;
2712-
fCurrent := Default(T);
2713-
fState := STATE_FINISHED;
2714-
end;
2715-
STATE_ENUMERATOR:
2716-
begin
2717-
Start;
2718-
fState := STATE_RUNNING;
2719-
goto _STATE_RUNNING;
2712+
Dispose;
2713+
fCurrent := Default(T);
2714+
fState := STATE_FINISHED;
2715+
end;
2716+
STATE_ENUMERATOR:
2717+
begin
2718+
Start;
2719+
fState := STATE_RUNNING;
2720+
Continue;
2721+
end;
27202722
end;
2721-
end;
2722-
Result := False;
2723+
Exit(False);
2724+
until False;
27232725
end;
27242726

27252727
procedure TIterator<T>.Start;

Source/Base/Collections/Spring.Collections.pas

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11083,31 +11083,30 @@ function TOfTypeIterator.TEnumerator.GetCurrent: TObject;
1108311083
Result := fCurrent;
1108411084
end;
1108511085

11086-
function TOfTypeIterator.TEnumerator.MoveNext: Boolean; //FI:W521
11087-
label
11088-
HasEnumerator;
11086+
function TOfTypeIterator.TEnumerator.MoveNext: Boolean;
1108911087
var
1109011088
current: TObject;
1109111089
begin
11092-
if Assigned(fEnumerator) then
11093-
begin
11094-
HasEnumerator:
11095-
repeat
11096-
Result := fEnumerator.MoveNext;
11097-
if not Result then
11098-
Break;
11099-
current := fEnumerator.Current;
11100-
fCurrent := current;
11101-
Result := current.InheritsFrom(fResultClass);
11102-
until Result;
11103-
Exit;
11104-
end;
11105-
{$IFDEF MSWINDOWS}
11106-
IEnumerableInternal(Parent.fSource).GetEnumerator(IEnumerator(fEnumerator));
11107-
{$ELSE}
11108-
fEnumerator := Parent.fSource.GetEnumerator;
11109-
{$ENDIF}
11110-
goto HasEnumerator;
11090+
repeat
11091+
if Assigned(fEnumerator) then
11092+
begin
11093+
repeat
11094+
Result := fEnumerator.MoveNext;
11095+
if not Result then
11096+
Break;
11097+
current := fEnumerator.Current;
11098+
fCurrent := current;
11099+
Result := current.InheritsFrom(fResultClass);
11100+
until Result;
11101+
Exit;
11102+
end;
11103+
{$IFDEF MSWINDOWS}
11104+
IEnumerableInternal(Parent.fSource).GetEnumerator(IEnumerator(fEnumerator));
11105+
{$ELSE}
11106+
fEnumerator := Parent.fSource.GetEnumerator;
11107+
{$ENDIF}
11108+
until True;
11109+
Result := False;
1111111110
end;
1111211111

1111311112
{$ENDREGION}

Source/Base/Spring.HashTable.pas

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ implementation
186186
Spring.Hash,
187187
Spring.ResourceStrings;
188188

189+
{$IF defined(DELPHIXE6) or defined(DELPHIXE7)}
190+
// there seems to be some compiler glitch in XE6 and XE7 that causes
191+
// internal compiler error in some rare cases when using goto - here is one
192+
{$DEFINE GOTO_OFF}
193+
{$IFEND}
194+
189195
// copied here from Spring.pas to enable inlining
190196
function DynArrayLength(const A: Pointer): NativeInt; inline;
191197
begin
@@ -342,10 +348,12 @@ function THashTable.FindItem(const key): Pointer;
342348
end;
343349

344350
function THashTable.FindEntry(const key; var entry: THashTableEntry): Boolean;
351+
{$IFNDEF GOTO_OFF}
345352
label
346353
first;
354+
{$ENDIF}
347355
var
348-
mask, perturb: Integer;
356+
perturb, mask: Integer;
349357
hashTable: PHashTable;
350358
item: PByte;
351359
begin
@@ -357,6 +365,7 @@ function THashTable.FindEntry(const key; var entry: THashTableEntry): Boolean;
357365
mask := PInteger(@PByte(hashTable.Buckets)[-SizeOf(NativeInt)])^ - 1;
358366
entry.BucketIndex := entry.HashCode and mask;
359367

368+
{$IFNDEF GOTO_OFF}
360369
goto first;
361370
repeat
362371
{$IFDEF DEBUG}
@@ -374,10 +383,33 @@ function THashTable.FindEntry(const key; var entry: THashTableEntry): Boolean;
374383
begin
375384
entry.ItemIndex := entry.ItemIndex and mask;
376385
item := @hashTable.Items[NativeInt(hashTable.ItemSize) * entry.ItemIndex];
377-
if hashTable.fEquals(Pointer(hashTable.fComparer), item[KeyOffset], key) then
378-
Exit(True);
386+
Result := hashTable.fEquals(Pointer(hashTable.fComparer), item[KeyOffset], key);
387+
if Result then Exit;
388+
end;
389+
until False;
390+
{$ELSE}
391+
repeat
392+
entry.ItemIndex := hashTable.Buckets[entry.BucketIndex];
393+
if entry.ItemIndex <> UsedBucket then
394+
begin
395+
if entry.ItemIndex = EmptyBucket then Break;
396+
if (entry.ItemIndex xor entry.HashCode) and not mask = 0 then
397+
begin
398+
entry.ItemIndex := entry.ItemIndex and mask;
399+
item := @hashTable.Items[NativeInt(hashTable.ItemSize) * entry.ItemIndex];
400+
Result := hashTable.fEquals(Pointer(hashTable.fComparer), item[KeyOffset], key);
401+
if Result then Exit;
402+
end;
379403
end;
404+
405+
{$IFDEF DEBUG}
406+
Inc(CollisionCount);
407+
{$ENDIF}
408+
409+
perturb := perturb shr PerturbShift;
410+
entry.BucketIndex := (5 * entry.BucketIndex + 1 + perturb) and mask;
380411
until False;
412+
{$ENDIF}
381413
end;
382414
entry.ItemIndex := hashTable.ItemCount;
383415
Result := False;

0 commit comments

Comments
 (0)