mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-09 19:28:55 +02:00
* simplified enum lookup table management by using tfplist instead of
an ad hoc dynamic array implementation git-svn-id: trunk@31295 -
This commit is contained in:
parent
d9359ea4af
commit
4c0807c596
@ -1156,6 +1156,36 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function enumsym_compare_name(item1, item2: pointer): Integer;
|
||||||
|
var
|
||||||
|
enum1: tenumsym absolute item1;
|
||||||
|
enum2: tenumsym absolute item2;
|
||||||
|
begin
|
||||||
|
if enum1=enum2 then
|
||||||
|
result:=0
|
||||||
|
else if enum1.name>enum2.name then
|
||||||
|
result:=1
|
||||||
|
else
|
||||||
|
{ there can't be equal names, identifiers are unique }
|
||||||
|
result:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function enumsym_compare_value(item1, item2: pointer): Integer;
|
||||||
|
var
|
||||||
|
enum1: tenumsym absolute item1;
|
||||||
|
enum2: tenumsym absolute item2;
|
||||||
|
begin
|
||||||
|
if enum1.value>enum2.value then
|
||||||
|
result:=1
|
||||||
|
else if enum1.value<enum2.value then
|
||||||
|
result:=-1
|
||||||
|
else
|
||||||
|
result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TRTTIWriter.write_rtti_extrasyms(def:Tdef;rt:Trttitype;mainrtti:Tasmsymbol);
|
procedure TRTTIWriter.write_rtti_extrasyms(def:Tdef;rt:Trttitype;mainrtti:Tasmsymbol);
|
||||||
|
|
||||||
type Penumsym = ^Tenumsym;
|
type Penumsym = ^Tenumsym;
|
||||||
@ -1163,22 +1193,24 @@ implementation
|
|||||||
{ Writes a helper table for accelerated conversion of ordinal enum values to strings.
|
{ Writes a helper table for accelerated conversion of ordinal enum values to strings.
|
||||||
If you change something in this method, make sure to adapt the corresponding code
|
If you change something in this method, make sure to adapt the corresponding code
|
||||||
in sstrings.inc. }
|
in sstrings.inc. }
|
||||||
procedure enumdef_rtti_ord2stringindex(rttidef: trecorddef; const sym_count:longint; {const offsets:plongint;} const syms:Penumsym{; const st:longint});
|
procedure enumdef_rtti_ord2stringindex(rttidef: trecorddef; const syms: tfplist);
|
||||||
|
|
||||||
var rttilab:Tasmsymbol;
|
var rttilab:Tasmsymbol;
|
||||||
h,i,o,prev_value:longint;
|
h,i,o,prev_value:longint;
|
||||||
mode:(lookup,search); {Modify with care, ordinal value of enum is written.}
|
mode:(lookup,search); {Modify with care, ordinal value of enum is written.}
|
||||||
r:single; {Must be real type because of integer overflow risk.}
|
r:single; {Must be real type because of integer overflow risk.}
|
||||||
tcb: ttai_typedconstbuilder;
|
tcb: ttai_typedconstbuilder;
|
||||||
|
sym_count: integer;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
{Decide wether a lookup array is size efficient.}
|
{Decide wether a lookup array is size efficient.}
|
||||||
mode:=lookup;
|
mode:=lookup;
|
||||||
|
sym_count:=syms.count;
|
||||||
if sym_count>0 then
|
if sym_count>0 then
|
||||||
begin
|
begin
|
||||||
i:=1;
|
i:=1;
|
||||||
r:=0;
|
r:=0;
|
||||||
h:=syms[0].value; {Next expected enum value is min.}
|
h:=tenumsym(syms[0]).value; {Next expected enum value is min.}
|
||||||
{ set prev_value for the first iteration to a value that is
|
{ set prev_value for the first iteration to a value that is
|
||||||
different from the first one without risking overflow (it's used
|
different from the first one without risking overflow (it's used
|
||||||
to detect whether two enum values are the same) }
|
to detect whether two enum values are the same) }
|
||||||
@ -1195,9 +1227,9 @@ implementation
|
|||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
{Calculate size of hole between values. Avoid integer overflows.}
|
{Calculate size of hole between values. Avoid integer overflows.}
|
||||||
r:=r+(single(syms[i].value)-single(h))-1;
|
r:=r+(single(tenumsym(syms[i]).value)-single(h))-1;
|
||||||
prev_value:=h;
|
prev_value:=h;
|
||||||
h:=syms[i].value;
|
h:=tenumsym(syms[i]).value;
|
||||||
inc(i);
|
inc(i);
|
||||||
end;
|
end;
|
||||||
if r>sym_count then
|
if r>sym_count then
|
||||||
@ -1219,10 +1251,10 @@ implementation
|
|||||||
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
||||||
if mode=lookup then
|
if mode=lookup then
|
||||||
begin
|
begin
|
||||||
o:=syms[0].value; {Start with min value.}
|
o:=tenumsym(syms[0]).value; {Start with min value.}
|
||||||
for i:=0 to sym_count-1 do
|
for i:=0 to sym_count-1 do
|
||||||
begin
|
begin
|
||||||
while o<syms[i].value do
|
while o<tenumsym(syms[i]).value do
|
||||||
begin
|
begin
|
||||||
tcb.emit_tai(Tai_const.create_pint(0),ptruinttype);
|
tcb.emit_tai(Tai_const.create_pint(0),ptruinttype);
|
||||||
inc(o);
|
inc(o);
|
||||||
@ -1233,7 +1265,7 @@ implementation
|
|||||||
['size_start_rec',
|
['size_start_rec',
|
||||||
'min_max_rec',
|
'min_max_rec',
|
||||||
'basetype_array_rec',
|
'basetype_array_rec',
|
||||||
'enumname'+tostr(syms[i].symid)]
|
'enumname'+tostr(tenumsym(syms[i]).symid)]
|
||||||
);
|
);
|
||||||
tcb.queue_emit_asmsym(mainrtti,rttidef);
|
tcb.queue_emit_asmsym(mainrtti,rttidef);
|
||||||
end;
|
end;
|
||||||
@ -1246,13 +1278,13 @@ implementation
|
|||||||
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
||||||
for i:=0 to sym_count-1 do
|
for i:=0 to sym_count-1 do
|
||||||
begin
|
begin
|
||||||
tcb.emit_ord_const(syms[i].value,s32inttype);
|
tcb.emit_ord_const(tenumsym(syms[i]).value,s32inttype);
|
||||||
tcb.queue_init(voidpointertype);
|
tcb.queue_init(voidpointertype);
|
||||||
tcb.queue_subscriptn_multiple_by_name(rttidef,
|
tcb.queue_subscriptn_multiple_by_name(rttidef,
|
||||||
['size_start_rec',
|
['size_start_rec',
|
||||||
'min_max_rec',
|
'min_max_rec',
|
||||||
'basetype_array_rec',
|
'basetype_array_rec',
|
||||||
'enumname'+tostr(syms[i].symid)]
|
'enumname'+tostr(tenumsym(syms[i]).symid)]
|
||||||
);
|
);
|
||||||
tcb.queue_emit_asmsym(mainrtti,rttidef);
|
tcb.queue_emit_asmsym(mainrtti,rttidef);
|
||||||
end;
|
end;
|
||||||
@ -1266,10 +1298,11 @@ implementation
|
|||||||
tcb.free;
|
tcb.free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Writes a helper table for accelerated conversion of string to ordinal enum values.
|
{ Writes a helper table for accelerated conversion of string to ordinal enum values.
|
||||||
If you change something in this method, make sure to adapt the corresponding code
|
If you change something in this method, make sure to adapt the corresponding code
|
||||||
in sstrings.inc. }
|
in sstrings.inc. }
|
||||||
procedure enumdef_rtti_string2ordindex(rttidef: trecorddef; const sym_count:longint; {const offsets:plongint; } const syms:Penumsym {; const st:longint});
|
procedure enumdef_rtti_string2ordindex(rttidef: trecorddef; const syms: tfplist);
|
||||||
|
|
||||||
var
|
var
|
||||||
tcb: ttai_typedconstbuilder;
|
tcb: ttai_typedconstbuilder;
|
||||||
@ -1283,21 +1316,21 @@ implementation
|
|||||||
tcb.begin_anonymous_record('',defaultpacking,reqalign,
|
tcb.begin_anonymous_record('',defaultpacking,reqalign,
|
||||||
targetinfos[target_info.system]^.alignment.recordalignmin,
|
targetinfos[target_info.system]^.alignment.recordalignmin,
|
||||||
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
||||||
tcb.emit_ord_const(sym_count,s32inttype);
|
tcb.emit_ord_const(syms.count,s32inttype);
|
||||||
{ begin of "data" array in Tstring_to_ord }
|
{ begin of "data" array in Tstring_to_ord }
|
||||||
tcb.begin_anonymous_record('',defaultpacking,reqalign,
|
tcb.begin_anonymous_record('',defaultpacking,reqalign,
|
||||||
targetinfos[target_info.system]^.alignment.recordalignmin,
|
targetinfos[target_info.system]^.alignment.recordalignmin,
|
||||||
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
||||||
for i:=0 to sym_count-1 do
|
for i:=0 to syms.count-1 do
|
||||||
begin
|
begin
|
||||||
tcb.emit_ord_const(syms[i].value,s32inttype);
|
tcb.emit_ord_const(tenumsym(syms[i]).value,s32inttype);
|
||||||
{ alignment of pointer value handled by enclosing record already }
|
{ alignment of pointer value handled by enclosing record already }
|
||||||
tcb.queue_init(voidpointertype);
|
tcb.queue_init(voidpointertype);
|
||||||
tcb.queue_subscriptn_multiple_by_name(rttidef,
|
tcb.queue_subscriptn_multiple_by_name(rttidef,
|
||||||
['size_start_rec',
|
['size_start_rec',
|
||||||
'min_max_rec',
|
'min_max_rec',
|
||||||
'basetype_array_rec',
|
'basetype_array_rec',
|
||||||
'enumname'+tostr(syms[i].SymId)]
|
'enumname'+tostr(tenumsym(syms[i]).SymId)]
|
||||||
);
|
);
|
||||||
tcb.queue_emit_asmsym(mainrtti,rttidef);
|
tcb.queue_emit_asmsym(mainrtti,rttidef);
|
||||||
end;
|
end;
|
||||||
@ -1311,16 +1344,14 @@ implementation
|
|||||||
procedure enumdef_rtti_extrasyms(def:Tenumdef);
|
procedure enumdef_rtti_extrasyms(def:Tenumdef);
|
||||||
var
|
var
|
||||||
t:Tenumsym;
|
t:Tenumsym;
|
||||||
syms:Penumsym;
|
syms:tfplist;
|
||||||
sym_count,sym_alloc:sizeuint;
|
|
||||||
h,i,p:longint;
|
h,i,p:longint;
|
||||||
rttitypesym: ttypesym;
|
rttitypesym: ttypesym;
|
||||||
rttidef: trecorddef;
|
rttidef: trecorddef;
|
||||||
begin
|
begin
|
||||||
{Random access needed, put in array.}
|
{ collect enumsyms belonging to this enum type (could be a subsection
|
||||||
getmem(syms,64*sizeof(Tenumsym));
|
in case of a subrange type) }
|
||||||
sym_count:=0;
|
syms:=tfplist.create;
|
||||||
sym_alloc:=64;
|
|
||||||
for i := 0 to def.symtable.SymList.Count - 1 do
|
for i := 0 to def.symtable.SymList.Count - 1 do
|
||||||
begin
|
begin
|
||||||
t:=tenumsym(def.symtable.SymList[i]);
|
t:=tenumsym(def.symtable.SymList[i]);
|
||||||
@ -1329,68 +1360,20 @@ implementation
|
|||||||
else
|
else
|
||||||
if t.value>def.maxval then
|
if t.value>def.maxval then
|
||||||
break;
|
break;
|
||||||
if sym_count>=sym_alloc then
|
syms.add(t);
|
||||||
begin
|
|
||||||
reallocmem(syms,2*sym_alloc*sizeof(Tenumsym));
|
|
||||||
sym_alloc:=sym_alloc*2;
|
|
||||||
end;
|
|
||||||
syms[sym_count]:=t;
|
|
||||||
inc(sym_count);
|
|
||||||
end;
|
|
||||||
{Sort the syms by enum name}
|
|
||||||
if sym_count>=2 then
|
|
||||||
begin
|
|
||||||
p:=1;
|
|
||||||
while 2*p<sym_count do
|
|
||||||
p:=2*p;
|
|
||||||
while p<>0 do
|
|
||||||
begin
|
|
||||||
for h:=p to sym_count-1 do
|
|
||||||
begin
|
|
||||||
i:=h;
|
|
||||||
t:=syms[i];
|
|
||||||
repeat
|
|
||||||
if syms[i-p].name<=t.name then
|
|
||||||
break;
|
|
||||||
syms[i]:=syms[i-p];
|
|
||||||
dec(i,p);
|
|
||||||
until i<p;
|
|
||||||
syms[i]:=t;
|
|
||||||
end;
|
|
||||||
p:=p shr 1;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
{ sort the syms by enum name }
|
||||||
|
syms.sort(@enumsym_compare_name);
|
||||||
rttitypesym:=try_search_current_module_type(internaltypeprefixName[itp_rttidef]+def.rtti_mangledname(fullrtti));
|
rttitypesym:=try_search_current_module_type(internaltypeprefixName[itp_rttidef]+def.rtti_mangledname(fullrtti));
|
||||||
if not assigned(rttitypesym) or
|
if not assigned(rttitypesym) or
|
||||||
(ttypesym(rttitypesym).typedef.typ<>recorddef) then
|
(ttypesym(rttitypesym).typedef.typ<>recorddef) then
|
||||||
internalerror(2015071402);
|
internalerror(2015071402);
|
||||||
rttidef:=trecorddef(ttypesym(rttitypesym).typedef);
|
rttidef:=trecorddef(ttypesym(rttitypesym).typedef);
|
||||||
enumdef_rtti_string2ordindex(rttidef,sym_count,syms);
|
enumdef_rtti_string2ordindex(rttidef,syms);
|
||||||
{ Sort the syms by enum value }
|
{ sort the syms by enum value }
|
||||||
if sym_count>=2 then
|
syms.sort(@enumsym_compare_value);
|
||||||
begin
|
enumdef_rtti_ord2stringindex(rttidef,syms);
|
||||||
p:=1;
|
syms.free;
|
||||||
while 2*p<sym_count do
|
|
||||||
p:=2*p;
|
|
||||||
while p<>0 do
|
|
||||||
begin
|
|
||||||
for h:=p to sym_count-1 do
|
|
||||||
begin
|
|
||||||
i:=h;
|
|
||||||
t:=syms[i];
|
|
||||||
repeat
|
|
||||||
if syms[i-p].value<=t.value then
|
|
||||||
break;
|
|
||||||
syms[i]:=syms[i-p];
|
|
||||||
dec(i,p);
|
|
||||||
until i<p;
|
|
||||||
syms[i]:=t;
|
|
||||||
end;
|
|
||||||
p:=p shr 1;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
enumdef_rtti_ord2stringindex(rttidef,sym_count,syms);
|
|
||||||
freemem(syms);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user