+ 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 interface
uses uses
globtype,
symtype,
cgutils,
node, ncgld; node, ncgld;
type type
@ -33,12 +36,20 @@ type
function is_addr_param_load: boolean; override; function is_addr_param_load: boolean; override;
end; end;
tjvmarrayconstructornode = class(tcgarrayconstructornode)
protected
procedure makearrayref(var ref: treference; eledef: tdef); override;
procedure advancearrayoffset(var ref: treference; elesize: asizeint); override;
end;
implementation implementation
uses uses
verbose,
aasmdata,
nld, nld,
symsym, symsym,symdef,jvmdef,
jvmdef; cgbase,hlcgobj;
function tjvmloadnode.is_addr_param_load: boolean; function tjvmloadnode.is_addr_param_load: boolean;
begin begin
@ -48,7 +59,29 @@ function tjvmloadnode.is_addr_param_load: boolean;
end; 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 begin
cloadnode:=tjvmloadnode; cloadnode:=tjvmloadnode;
carrayconstructornode:=tjvmarrayconstructornode;
end. end.

View File

@ -78,9 +78,13 @@ unit tgcpu;
ndim:=0; ndim:=0;
eledef:=def; eledef:=def;
repeat 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; eledef:=tarraydef(eledef).elementdef;
inc(ndim); inc(ndim);
forcesize:=-1;
until (eledef.typ<>arraydef) or until (eledef.typ<>arraydef) or
is_dynamic_array(eledef); is_dynamic_array(eledef);
eledef:=tarraydef(def).elementdef; eledef:=tarraydef(def).elementdef;

View File

@ -27,6 +27,8 @@ unit ncgld;
interface interface
uses uses
globtype,
symtype,
node,nld,cgutils; node,nld,cgutils;
type type
@ -41,6 +43,10 @@ interface
end; end;
tcgarrayconstructornode = class(tarrayconstructornode) 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; procedure pass_generate_code;override;
end; end;
@ -54,9 +60,9 @@ implementation
uses uses
cutils, cutils,
systems, systems,
verbose,globtype,globals,constexp, verbose,globals,constexp,
nutils, nutils,
symtable,symconst,symtype,symdef,symsym,defutil,paramgr, symtable,symconst,symdef,symsym,defutil,paramgr,
ncnv,ncon,nmem,nbas,ncgrtti, ncnv,ncon,nmem,nbas,ncgrtti,
aasmbase,aasmtai,aasmdata,aasmcpu, aasmbase,aasmtai,aasmdata,aasmcpu,
cgbase,pass_2, cgbase,pass_2,
@ -1007,6 +1013,19 @@ implementation
vtAnsiString16 = 19; vtAnsiString16 = 19;
vtAnsiString64 = 20; 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; procedure tcgarrayconstructornode.pass_generate_code;
var var
hp : tarrayconstructornode; hp : tarrayconstructornode;
@ -1042,10 +1061,11 @@ implementation
{ Allocate always a temp, also if no elements are required, to { Allocate always a temp, also if no elements are required, to
be sure that location is valid (PFV) } be sure that location is valid (PFV) }
if tarraydef(resultdef).highrange=-1 then 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 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; href:=location.reference;
makearrayref(href,eledef);
{ Process nodes in array constructor } { Process nodes in array constructor }
hp:=self; hp:=self;
while assigned(hp) do while assigned(hp) do
@ -1063,7 +1083,7 @@ implementation
secondpass(hp.left); secondpass(hp.left);
{ Move flags and jump in register } { Move flags and jump in register }
if hp.left.location.loc in [LOC_FLAGS,LOC_JUMP] then 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 if (hp.left.location.loc=LOC_JUMP) then
begin begin
@ -1193,7 +1213,7 @@ implementation
dec(href.offset,sizeof(pint)); dec(href.offset,sizeof(pint));
cg.a_load_const_ref(current_asmdata.CurrAsmList, OS_INT,vtype,href); cg.a_load_const_ref(current_asmdata.CurrAsmList, OS_INT,vtype,href);
{ goto next array element } { goto next array element }
inc(href.offset,sizeof(pint)*2); advancearrayoffset(href,sizeof(pint)*2);
end end
else else
{ normal array constructor of the same type } { normal array constructor of the same type }
@ -1207,15 +1227,15 @@ implementation
hp.left.location.register,href,mms_movescalar); hp.left.location.register,href,mms_movescalar);
LOC_FPUREGISTER, LOC_FPUREGISTER,
LOC_CFPUREGISTER : 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_REFERENCE,
LOC_CREFERENCE : LOC_CREFERENCE :
begin begin
if is_shortstring(hp.left.resultdef) then if is_shortstring(hp.left.resultdef) then
cg.g_copyshortstring(current_asmdata.CurrAsmList,hp.left.location.reference,href, hlcg.g_copyshortstring(current_asmdata.CurrAsmList,hp.left.location.reference,href,
Tstringdef(hp.left.resultdef).len) Tstringdef(hp.left.resultdef))
else 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; end;
else else
begin begin
@ -1224,10 +1244,10 @@ implementation
cg64.a_load64_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href) cg64.a_load64_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
else else
{$endif not cpu64bitalu} {$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;
end; end;
inc(href.offset,elesize); advancearrayoffset(href,elesize);
end; end;
if freetemp then if freetemp then
location_freetemp(current_asmdata.CurrAsmList,hp.left.location); location_freetemp(current_asmdata.CurrAsmList,hp.left.location);