mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 06:29:32 +02:00
+ support for (non-variant) arrayconstructornodes for the JVM target
o when allocating array temps for the JVM target, use the specified "forcesize" for the first dimension, since the arraydef size may be invalid (e.g., in case it's an array constructor) git-svn-id: branches/jvmbackend@18468 -
This commit is contained in:
parent
d13769204e
commit
bf21cd7a15
@ -26,6 +26,9 @@ unit njvmld;
|
||||
interface
|
||||
|
||||
uses
|
||||
globtype,
|
||||
symtype,
|
||||
cgutils,
|
||||
node, ncgld;
|
||||
|
||||
type
|
||||
@ -33,12 +36,20 @@ type
|
||||
function is_addr_param_load: boolean; override;
|
||||
end;
|
||||
|
||||
tjvmarrayconstructornode = class(tcgarrayconstructornode)
|
||||
protected
|
||||
procedure makearrayref(var ref: treference; eledef: tdef); override;
|
||||
procedure advancearrayoffset(var ref: treference; elesize: asizeint); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,
|
||||
aasmdata,
|
||||
nld,
|
||||
symsym,
|
||||
jvmdef;
|
||||
symsym,symdef,jvmdef,
|
||||
cgbase,hlcgobj;
|
||||
|
||||
function tjvmloadnode.is_addr_param_load: boolean;
|
||||
begin
|
||||
@ -48,7 +59,29 @@ function tjvmloadnode.is_addr_param_load: boolean;
|
||||
end;
|
||||
|
||||
|
||||
{ tjvmarrayconstructornode }
|
||||
|
||||
procedure tjvmarrayconstructornode.makearrayref(var ref: treference; eledef: tdef);
|
||||
var
|
||||
basereg: tregister;
|
||||
begin
|
||||
{ arrays are implicitly dereferenced }
|
||||
basereg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,java_jlobject);
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,java_jlobject,java_jlobject,ref,basereg);
|
||||
reference_reset_base(ref,basereg,0,1);
|
||||
ref.arrayreftype:=art_indexconst;
|
||||
ref.indexoffset:=0;
|
||||
end;
|
||||
|
||||
|
||||
procedure tjvmarrayconstructornode.advancearrayoffset(var ref: treference; elesize: asizeint);
|
||||
begin
|
||||
inc(ref.indexoffset);
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
cloadnode:=tjvmloadnode;
|
||||
carrayconstructornode:=tjvmarrayconstructornode;
|
||||
end.
|
||||
|
||||
|
@ -78,9 +78,13 @@ unit tgcpu;
|
||||
ndim:=0;
|
||||
eledef:=def;
|
||||
repeat
|
||||
thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,tarraydef(eledef).elecount,R_INTREGISTER);
|
||||
if forcesize<>-1 then
|
||||
thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,forcesize div tarraydef(eledef).elesize,R_INTREGISTER)
|
||||
else
|
||||
thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,tarraydef(eledef).elecount,R_INTREGISTER);
|
||||
eledef:=tarraydef(eledef).elementdef;
|
||||
inc(ndim);
|
||||
forcesize:=-1;
|
||||
until (eledef.typ<>arraydef) or
|
||||
is_dynamic_array(eledef);
|
||||
eledef:=tarraydef(def).elementdef;
|
||||
|
@ -27,6 +27,8 @@ unit ncgld;
|
||||
interface
|
||||
|
||||
uses
|
||||
globtype,
|
||||
symtype,
|
||||
node,nld,cgutils;
|
||||
|
||||
type
|
||||
@ -41,6 +43,10 @@ interface
|
||||
end;
|
||||
|
||||
tcgarrayconstructornode = class(tarrayconstructornode)
|
||||
protected
|
||||
procedure makearrayref(var ref: treference; eledef: tdef);virtual;
|
||||
procedure advancearrayoffset(var ref: treference; elesize: asizeint);virtual;
|
||||
public
|
||||
procedure pass_generate_code;override;
|
||||
end;
|
||||
|
||||
@ -54,9 +60,9 @@ implementation
|
||||
uses
|
||||
cutils,
|
||||
systems,
|
||||
verbose,globtype,globals,constexp,
|
||||
verbose,globals,constexp,
|
||||
nutils,
|
||||
symtable,symconst,symtype,symdef,symsym,defutil,paramgr,
|
||||
symtable,symconst,symdef,symsym,defutil,paramgr,
|
||||
ncnv,ncon,nmem,nbas,ncgrtti,
|
||||
aasmbase,aasmtai,aasmdata,aasmcpu,
|
||||
cgbase,pass_2,
|
||||
@ -1007,6 +1013,19 @@ implementation
|
||||
vtAnsiString16 = 19;
|
||||
vtAnsiString64 = 20;
|
||||
|
||||
|
||||
procedure tcgarrayconstructornode.makearrayref(var ref: treference; eledef: tdef);
|
||||
begin
|
||||
{ do nothing by default }
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarrayconstructornode.advancearrayoffset(var ref: treference; elesize: asizeint);
|
||||
begin
|
||||
inc(ref.offset,elesize);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarrayconstructornode.pass_generate_code;
|
||||
var
|
||||
hp : tarrayconstructornode;
|
||||
@ -1042,10 +1061,11 @@ implementation
|
||||
{ Allocate always a temp, also if no elements are required, to
|
||||
be sure that location is valid (PFV) }
|
||||
if tarraydef(resultdef).highrange=-1 then
|
||||
tg.gethltemp(current_asmdata.CurrAsmList,eledef,elesize,tt_normal,location.reference)
|
||||
tg.gethltemp(current_asmdata.CurrAsmList,resultdef,elesize,tt_normal,location.reference)
|
||||
else
|
||||
tg.gethltemp(current_asmdata.CurrAsmList,eledef,(tarraydef(resultdef).highrange+1)*elesize,tt_normal,location.reference);
|
||||
tg.gethltemp(current_asmdata.CurrAsmList,resultdef,(tarraydef(resultdef).highrange+1)*elesize,tt_normal,location.reference);
|
||||
href:=location.reference;
|
||||
makearrayref(href,eledef);
|
||||
{ Process nodes in array constructor }
|
||||
hp:=self;
|
||||
while assigned(hp) do
|
||||
@ -1063,7 +1083,7 @@ implementation
|
||||
secondpass(hp.left);
|
||||
{ Move flags and jump in register }
|
||||
if hp.left.location.loc in [LOC_FLAGS,LOC_JUMP] then
|
||||
location_force_reg(current_asmdata.CurrAsmList,hp.left.location,def_cgsize(hp.left.resultdef),false);
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,hp.left.location,hp.left.resultdef,hp.left.resultdef,false);
|
||||
|
||||
if (hp.left.location.loc=LOC_JUMP) then
|
||||
begin
|
||||
@ -1193,7 +1213,7 @@ implementation
|
||||
dec(href.offset,sizeof(pint));
|
||||
cg.a_load_const_ref(current_asmdata.CurrAsmList, OS_INT,vtype,href);
|
||||
{ goto next array element }
|
||||
inc(href.offset,sizeof(pint)*2);
|
||||
advancearrayoffset(href,sizeof(pint)*2);
|
||||
end
|
||||
else
|
||||
{ normal array constructor of the same type }
|
||||
@ -1207,15 +1227,15 @@ implementation
|
||||
hp.left.location.register,href,mms_movescalar);
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER :
|
||||
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,hp.left.location.size,hp.left.location.size,hp.left.location.register,href);
|
||||
hlcg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,hp.left.resultdef,hp.left.resultdef,hp.left.location.register,href);
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
if is_shortstring(hp.left.resultdef) then
|
||||
cg.g_copyshortstring(current_asmdata.CurrAsmList,hp.left.location.reference,href,
|
||||
Tstringdef(hp.left.resultdef).len)
|
||||
hlcg.g_copyshortstring(current_asmdata.CurrAsmList,hp.left.location.reference,href,
|
||||
Tstringdef(hp.left.resultdef))
|
||||
else
|
||||
cg.g_concatcopy(current_asmdata.CurrAsmList,hp.left.location.reference,href,elesize);
|
||||
hlcg.g_concatcopy(current_asmdata.CurrAsmList,eledef,hp.left.location.reference,href);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
@ -1224,10 +1244,10 @@ implementation
|
||||
cg64.a_load64_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
cg.a_load_loc_ref(current_asmdata.CurrAsmList,hp.left.location.size,hp.left.location,href);
|
||||
hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,eledef,eledef,hp.left.location,href);
|
||||
end;
|
||||
end;
|
||||
inc(href.offset,elesize);
|
||||
advancearrayoffset(href,elesize);
|
||||
end;
|
||||
if freetemp then
|
||||
location_freetemp(current_asmdata.CurrAsmList,hp.left.location);
|
||||
|
Loading…
Reference in New Issue
Block a user