mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 00:09:17 +02:00
* changed initialization of records from constructing a new instance and
copying that over the old one into calling a dedicated fpcInitializeRec() method that initializes the required fields. The reason is that this initialization is performed for out-parameters, and the fpcDeepCopy() method (used to copy one instance over another) has an out-parameter -> infinite loop git-svn-id: branches/jvmbackend@18674 -
This commit is contained in:
parent
b52dcd4a56
commit
5bf16214cd
@ -1449,7 +1449,8 @@ implementation
|
|||||||
procedure thlcgjvm.g_initialize(list: TAsmList; t: tdef; const ref: treference);
|
procedure thlcgjvm.g_initialize(list: TAsmList; t: tdef; const ref: treference);
|
||||||
var
|
var
|
||||||
dummyloc: tlocation;
|
dummyloc: tlocation;
|
||||||
recref: treference;
|
sym: tsym;
|
||||||
|
pd: tprocdef;
|
||||||
begin
|
begin
|
||||||
if (t.typ=arraydef) and
|
if (t.typ=arraydef) and
|
||||||
not is_dynamic_array(t) then
|
not is_dynamic_array(t) then
|
||||||
@ -1459,12 +1460,19 @@ implementation
|
|||||||
end
|
end
|
||||||
else if is_record(t) then
|
else if is_record(t) then
|
||||||
begin
|
begin
|
||||||
{ create a new, empty record and replace the contents of the old one
|
{ call the fpcInitializeRec method }
|
||||||
with those of the new one (in the future we can generate a dedicate
|
sym:=tsym(trecorddef(t).symtable.find('FPCINITIALIZEREC'));
|
||||||
initialization helper) }
|
if assigned(sym) and
|
||||||
tg.gethltemp(list,t,t.size,tt_persistent,recref);
|
(sym.typ=procsym) then
|
||||||
g_concatcopy(list,t,recref,ref);
|
begin
|
||||||
tg.ungettemp(list,recref);
|
if tprocsym(sym).procdeflist.Count<>1 then
|
||||||
|
internalerror(2011071713);
|
||||||
|
pd:=tprocdef(tprocsym(sym).procdeflist[0]);
|
||||||
|
end;
|
||||||
|
a_load_ref_stack(list,java_jlobject,ref,prepare_stack_for_ref(list,ref,false));
|
||||||
|
a_call_name(list,pd,pd.mangledname,false);
|
||||||
|
{ parameter removed, no result }
|
||||||
|
decstack(list,1);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
a_load_const_ref(list,t,0,ref);
|
a_load_const_ref(list,t,0,ref);
|
||||||
|
@ -195,6 +195,15 @@ implementation
|
|||||||
pd.synthetickind:=tsk_record_deepcopy
|
pd.synthetickind:=tsk_record_deepcopy
|
||||||
else
|
else
|
||||||
internalerror(2011032807);
|
internalerror(2011032807);
|
||||||
|
if def.needs_inittable then
|
||||||
|
begin
|
||||||
|
{ 'var' instead of 'out' parameter, because 'out' would trigger
|
||||||
|
calling the initialize method recursively }
|
||||||
|
if str_parse_method_dec('procedure fpcInitializeRec;',potype_procedure,false,def,pd) then
|
||||||
|
pd.synthetickind:=tsk_record_initialize
|
||||||
|
else
|
||||||
|
internalerror(2011071711);
|
||||||
|
end;
|
||||||
restore_scanner(sstate);
|
restore_scanner(sstate);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -375,6 +375,38 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure implement_record_initialize(pd: tprocdef);
|
||||||
|
var
|
||||||
|
struct: tabstractrecorddef;
|
||||||
|
str: ansistring;
|
||||||
|
i: longint;
|
||||||
|
sym: tsym;
|
||||||
|
fsym: tfieldvarsym;
|
||||||
|
begin
|
||||||
|
if not(pd.struct.typ in [recorddef,objectdef]) then
|
||||||
|
internalerror(2011071710);
|
||||||
|
struct:=pd.struct;
|
||||||
|
{ anonymous record types must get an artificial name, so we can generate
|
||||||
|
a typecast at the scanner level }
|
||||||
|
if (struct.typ=recorddef) and
|
||||||
|
not assigned(struct.typesym) then
|
||||||
|
internalerror(2011032811);
|
||||||
|
{ walk over all fields that need initialization }
|
||||||
|
str:='begin ';
|
||||||
|
for i:=0 to struct.symtable.symlist.count-1 do
|
||||||
|
begin
|
||||||
|
sym:=tsym(struct.symtable.symlist[i]);
|
||||||
|
if (sym.typ=fieldvarsym) then
|
||||||
|
begin
|
||||||
|
fsym:=tfieldvarsym(sym);
|
||||||
|
if fsym.vardef.needs_inittable then
|
||||||
|
str:=str+'system.initialize(&'+fsym.realname+');';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
str:=str+'end;';
|
||||||
|
str_parse_method_impl(str,pd,false);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure implement_empty(pd: tprocdef);
|
procedure implement_empty(pd: tprocdef);
|
||||||
var
|
var
|
||||||
str: ansistring;
|
str: ansistring;
|
||||||
@ -618,6 +650,8 @@ implementation
|
|||||||
implement_jvm_clone(pd);
|
implement_jvm_clone(pd);
|
||||||
tsk_record_deepcopy:
|
tsk_record_deepcopy:
|
||||||
implement_record_deepcopy(pd);
|
implement_record_deepcopy(pd);
|
||||||
|
tsk_record_initialize:
|
||||||
|
implement_record_initialize(pd);
|
||||||
tsk_empty,
|
tsk_empty,
|
||||||
{ special handling for this one is done in tnodeutils.wrap_proc_body }
|
{ special handling for this one is done in tnodeutils.wrap_proc_body }
|
||||||
tsk_tcinit:
|
tsk_tcinit:
|
||||||
|
@ -499,6 +499,7 @@ interface
|
|||||||
tsk_anon_inherited, // anonymous inherited call
|
tsk_anon_inherited, // anonymous inherited call
|
||||||
tsk_jvm_clone, // Java-style clone method
|
tsk_jvm_clone, // Java-style clone method
|
||||||
tsk_record_deepcopy, // deepcopy for records field by field
|
tsk_record_deepcopy, // deepcopy for records field by field
|
||||||
|
tsk_record_initialize, // initialize for records field by field (explicit rather than via rtti)
|
||||||
tsk_empty, // an empty routine
|
tsk_empty, // an empty routine
|
||||||
tsk_tcinit, // initialisation of typed constants
|
tsk_tcinit, // initialisation of typed constants
|
||||||
tsk_callthrough, // call through to another routine with the same parameters/return type (its def is stored in the skpara field)
|
tsk_callthrough, // call through to another routine with the same parameters/return type (its def is stored in the skpara field)
|
||||||
|
Loading…
Reference in New Issue
Block a user