+ 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:
Jonas Maebe 2011-08-20 08:02:22 +00:00
parent d13769204e
commit bf21cd7a15
3 changed files with 72 additions and 15 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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);