mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 21:49:06 +02:00
* support var/out managed types on the callee side in location_get_data_ref()
git-svn-id: branches/jvmbackend@18604 -
This commit is contained in:
parent
7e6261ff55
commit
887248af2d
@ -1452,7 +1452,7 @@ implementation
|
|||||||
{ This routine is a combination of a generalised a_loadaddr_ref_reg()
|
{ This routine is a combination of a generalised a_loadaddr_ref_reg()
|
||||||
that also works for addresses in registers (in case loadref is false)
|
that also works for addresses in registers (in case loadref is false)
|
||||||
and of a_load_ref_reg (in case loadref is true). It is used for
|
and of a_load_ref_reg (in case loadref is true). It is used for
|
||||||
a) getting the address of managed types
|
a) getting the address of managed var/out parameters
|
||||||
b) getting to the actual data of value types that are passed by
|
b) getting to the actual data of value types that are passed by
|
||||||
reference by the compiler (and then get a local copy at the caller
|
reference by the compiler (and then get a local copy at the caller
|
||||||
side). Normally, depending on whether this reference is passed in a
|
side). Normally, depending on whether this reference is passed in a
|
||||||
@ -1470,32 +1470,43 @@ implementation
|
|||||||
|
|
||||||
However, managed types are also implicit pointers in Pascal, so in that
|
However, managed types are also implicit pointers in Pascal, so in that
|
||||||
case "taking the address" again consists of simply returning the
|
case "taking the address" again consists of simply returning the
|
||||||
implicit pointer/current value.
|
implicit pointer/current value (in case of a var/out parameter, this
|
||||||
|
value is stored inside an array).
|
||||||
}
|
}
|
||||||
if not loadref then
|
if not loadref then
|
||||||
begin
|
begin
|
||||||
if not is_managed_type(def) then
|
if not is_managed_type(def) then
|
||||||
internalerror(2011020601);
|
internalerror(2011020601);
|
||||||
|
tmploc:=l;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if not jvmimplicitpointertype(def) then
|
if not jvmimplicitpointertype(def) then
|
||||||
internalerror(2011020602);
|
begin
|
||||||
|
{ passed by reference in array of single element; l contains the
|
||||||
|
base address of the array }
|
||||||
|
location_reset_ref(tmploc,LOC_REFERENCE,OS_ADDR,4);
|
||||||
|
reference_reset_base(tmploc.reference,getaddressregister(list,java_jlobject),0,4);
|
||||||
|
tmploc.reference.arrayreftype:=art_indexconst;
|
||||||
|
tmploc.reference.indexoffset:=0;
|
||||||
|
a_load_loc_reg(list,java_jlobject,java_jlobject,l,tmploc.reference.base);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
tmploc:=l;
|
||||||
end;
|
end;
|
||||||
case l.loc of
|
case tmploc.loc of
|
||||||
LOC_REGISTER,
|
LOC_REGISTER,
|
||||||
LOC_CREGISTER :
|
LOC_CREGISTER :
|
||||||
begin
|
begin
|
||||||
{ the implicit pointer is in a register and has to be in a
|
{ the implicit pointer is in a register and has to be in a
|
||||||
reference -> create a reference and put it there }
|
reference -> create a reference and put it there }
|
||||||
tmploc:=l;
|
|
||||||
location_force_mem(list,tmploc,java_jlobject);
|
location_force_mem(list,tmploc,java_jlobject);
|
||||||
ref:=tmploc.reference;
|
ref:=tmploc.reference;
|
||||||
end;
|
end;
|
||||||
LOC_REFERENCE,
|
LOC_REFERENCE,
|
||||||
LOC_CREFERENCE :
|
LOC_CREFERENCE :
|
||||||
begin
|
begin
|
||||||
ref:=l.reference;
|
ref:=tmploc.reference;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
internalerror(2011020603);
|
internalerror(2011020603);
|
||||||
|
Loading…
Reference in New Issue
Block a user