mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 06:11:35 +02:00
+ support for array-of-const on the JVM target. Even though the
implementation is a bit different from that on native targets, the result is quite compatible git-svn-id: branches/jvmbackend@18765 -
This commit is contained in:
parent
549e51fdfa
commit
27731e342c
@ -48,6 +48,7 @@ type
|
|||||||
protected
|
protected
|
||||||
procedure makearrayref(var ref: treference; eledef: tdef); override;
|
procedure makearrayref(var ref: treference; eledef: tdef); override;
|
||||||
procedure advancearrayoffset(var ref: treference; elesize: asizeint); override;
|
procedure advancearrayoffset(var ref: treference; elesize: asizeint); override;
|
||||||
|
procedure wrapmanagedvarrec(var n: tnode);override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -216,6 +217,30 @@ procedure tjvmarrayconstructornode.advancearrayoffset(var ref: treference; elesi
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tjvmarrayconstructornode.wrapmanagedvarrec(var n: tnode);
|
||||||
|
var
|
||||||
|
varrecdef: trecorddef;
|
||||||
|
block: tblocknode;
|
||||||
|
stat: tstatementnode;
|
||||||
|
temp: ttempcreatenode;
|
||||||
|
begin
|
||||||
|
varrecdef:=trecorddef(search_system_type('TVARREC').typedef);
|
||||||
|
block:=internalstatements(stat);
|
||||||
|
temp:=ctempcreatenode.create(varrecdef,varrecdef.size,tt_persistent,false);
|
||||||
|
addstatement(stat,temp);
|
||||||
|
addstatement(stat,
|
||||||
|
ccallnode.createinternmethod(
|
||||||
|
ctemprefnode.create(temp),'INIT',ccallparanode.create(n,nil)));
|
||||||
|
{ note: this will not free the record contents, but just let its reference
|
||||||
|
on the stack be reused -- which is ok, because the reference will be
|
||||||
|
stored into the open array parameter }
|
||||||
|
addstatement(stat,ctempdeletenode.create_normal_temp(temp));
|
||||||
|
addstatement(stat,ctemprefnode.create(temp));
|
||||||
|
n:=block;
|
||||||
|
firstpass(n);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cloadnode:=tjvmloadnode;
|
cloadnode:=tjvmloadnode;
|
||||||
cassignmentnode:=tjvmassignmentnode;
|
cassignmentnode:=tjvmassignmentnode;
|
||||||
|
@ -320,11 +320,10 @@ implementation
|
|||||||
arraydef :
|
arraydef :
|
||||||
begin
|
begin
|
||||||
if is_array_of_const(def) then
|
if is_array_of_const(def) then
|
||||||
{$ifndef nounsupported}
|
begin
|
||||||
result:=jvmaddencodedtype(java_jlobject,false,encodedstr,forcesignature,founderror)
|
encodedstr:=encodedstr+'[';
|
||||||
{$else}
|
result:=jvmaddencodedtype(search_system_type('TVARREC').typedef,false,encodedstr,forcesignature,founderror);
|
||||||
result:=false
|
end
|
||||||
{$endif}
|
|
||||||
else if is_packed_array(def) then
|
else if is_packed_array(def) then
|
||||||
result:=false
|
result:=false
|
||||||
else
|
else
|
||||||
|
@ -1055,11 +1055,13 @@ implementation
|
|||||||
tmpreg : tregister;
|
tmpreg : tregister;
|
||||||
vaddr : boolean;
|
vaddr : boolean;
|
||||||
freetemp,
|
freetemp,
|
||||||
dovariant : boolean;
|
dovariant: boolean;
|
||||||
begin
|
begin
|
||||||
if is_packed_array(resultdef) then
|
if is_packed_array(resultdef) then
|
||||||
internalerror(200608042);
|
internalerror(200608042);
|
||||||
dovariant:=(nf_forcevaria in flags) or is_variant_array(resultdef);
|
dovariant:=
|
||||||
|
((nf_forcevaria in flags) or is_variant_array(resultdef)) and
|
||||||
|
not(target_info.system in systems_managed_vm);
|
||||||
if dovariant then
|
if dovariant then
|
||||||
begin
|
begin
|
||||||
eledef:=search_system_type('TVARREC').typedef;
|
eledef:=search_system_type('TVARREC').typedef;
|
||||||
@ -1113,7 +1115,6 @@ implementation
|
|||||||
|
|
||||||
if dovariant then
|
if dovariant then
|
||||||
begin
|
begin
|
||||||
{$if not defined(jvm) or defined(nounsupported)}
|
|
||||||
{ find the correct vtype value }
|
{ find the correct vtype value }
|
||||||
vtype:=$ff;
|
vtype:=$ff;
|
||||||
vaddr:=false;
|
vaddr:=false;
|
||||||
@ -1233,7 +1234,6 @@ implementation
|
|||||||
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 }
|
||||||
advancearrayoffset(href,sizeof(pint)*2);
|
advancearrayoffset(href,sizeof(pint)*2);
|
||||||
{$endif not jvm or nounsupported}
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{ normal array constructor of the same type }
|
{ normal array constructor of the same type }
|
||||||
|
@ -91,6 +91,9 @@ interface
|
|||||||
tarrayconstructorrangenodeclass = class of tarrayconstructorrangenode;
|
tarrayconstructorrangenodeclass = class of tarrayconstructorrangenode;
|
||||||
|
|
||||||
tarrayconstructornode = class(tbinarynode)
|
tarrayconstructornode = class(tbinarynode)
|
||||||
|
protected
|
||||||
|
procedure wrapmanagedvarrec(var n: tnode);virtual;abstract;
|
||||||
|
public
|
||||||
constructor create(l,r : tnode);virtual;
|
constructor create(l,r : tnode);virtual;
|
||||||
function dogetcopy : tnode;override;
|
function dogetcopy : tnode;override;
|
||||||
function pass_1 : tnode;override;
|
function pass_1 : tnode;override;
|
||||||
@ -152,7 +155,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
cutils,verbose,globtype,globals,systems,constexp,
|
cutils,verbose,globtype,globals,systems,constexp,
|
||||||
symnot,
|
symnot,symtable,
|
||||||
defutil,defcmp,
|
defutil,defcmp,
|
||||||
htypechk,pass_1,procinfo,paramgr,
|
htypechk,pass_1,procinfo,paramgr,
|
||||||
cpuinfo,
|
cpuinfo,
|
||||||
@ -1018,9 +1021,13 @@ implementation
|
|||||||
function tarrayconstructornode.pass_1 : tnode;
|
function tarrayconstructornode.pass_1 : tnode;
|
||||||
var
|
var
|
||||||
hp : tarrayconstructornode;
|
hp : tarrayconstructornode;
|
||||||
do_variant:boolean;
|
do_variant,
|
||||||
|
do_managed_variant:boolean;
|
||||||
begin
|
begin
|
||||||
do_variant:=(nf_forcevaria in flags) or (ado_isvariant in tarraydef(resultdef).arrayoptions);
|
do_variant:=(nf_forcevaria in flags) or (ado_isvariant in tarraydef(resultdef).arrayoptions);
|
||||||
|
do_managed_variant:=
|
||||||
|
do_variant and
|
||||||
|
(target_info.system in systems_managed_vm);
|
||||||
result:=nil;
|
result:=nil;
|
||||||
{ Insert required type convs, this must be
|
{ Insert required type convs, this must be
|
||||||
done in pass 1, because the call must be
|
done in pass 1, because the call must be
|
||||||
@ -1040,10 +1047,16 @@ implementation
|
|||||||
if not do_variant then
|
if not do_variant then
|
||||||
include(current_procinfo.flags,pi_do_call);
|
include(current_procinfo.flags,pi_do_call);
|
||||||
firstpass(hp.left);
|
firstpass(hp.left);
|
||||||
|
if do_managed_variant then
|
||||||
|
wrapmanagedvarrec(hp.left);
|
||||||
end;
|
end;
|
||||||
hp:=tarrayconstructornode(hp.right);
|
hp:=tarrayconstructornode(hp.right);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{ set the elementdef to the correct type in case of a managed
|
||||||
|
variant array }
|
||||||
|
if do_managed_variant then
|
||||||
|
tarraydef(resultdef).elementdef:=search_system_type('TVARREC').typedef;
|
||||||
expectloc:=LOC_CREFERENCE;
|
expectloc:=LOC_CREFERENCE;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -36,3 +36,249 @@
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(l: longint);
|
||||||
|
begin
|
||||||
|
VType:=vtInteger;
|
||||||
|
Value:=JLInteger.valueOf(l);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(b: boolean);
|
||||||
|
begin
|
||||||
|
VType:=vtBoolean;
|
||||||
|
Value:=JLBoolean.valueOf(b);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(c: ansichar);
|
||||||
|
begin
|
||||||
|
VType:=vtChar;
|
||||||
|
Value:=JLByte.valueOf(byte(c));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(w: widechar);
|
||||||
|
begin
|
||||||
|
VType:=vtWideChar;
|
||||||
|
Value:=JLCharacter.valueOf(w);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(d: extended);
|
||||||
|
var
|
||||||
|
arr: array[0..0] of extended;
|
||||||
|
begin
|
||||||
|
VType:=vtExtended;
|
||||||
|
{ VExtended has to return a PExtended -> return address of array (it
|
||||||
|
doesn't matter that this is a local variable, all arrays are garbage
|
||||||
|
collected pointers underneath!) }
|
||||||
|
arr[0]:=d;
|
||||||
|
Value:=JLObject(@arr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(const s: shortstring);
|
||||||
|
begin
|
||||||
|
VType:=vtString;
|
||||||
|
Value:=JLObject(@s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(constref p: pointer);
|
||||||
|
begin
|
||||||
|
// pointer = object
|
||||||
|
VType:=vtPointer;
|
||||||
|
Value:=JLObject(p);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(p: pchar);
|
||||||
|
begin
|
||||||
|
VType:=vtPChar;
|
||||||
|
Value:=JLObject(p);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(p: JLObject);
|
||||||
|
begin
|
||||||
|
VType:=vtObject;
|
||||||
|
Value:=p;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(c: TJClass);
|
||||||
|
begin
|
||||||
|
VType:=vtClass;
|
||||||
|
Value:=JLObject(c);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(p: pwidechar);
|
||||||
|
begin
|
||||||
|
VType:=vtPWideChar;
|
||||||
|
Value:=JLObject(p);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(const a: ansistring);
|
||||||
|
begin
|
||||||
|
VType:=vtAnsiString;
|
||||||
|
Value:=JLObject(a);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(constref c: currency);
|
||||||
|
begin
|
||||||
|
VType:=vtCurrency;
|
||||||
|
{ a constref parameter is internally passed as an array -> we can just
|
||||||
|
take its address and return it later as a pcurrency (which is also a
|
||||||
|
pointer internally) }
|
||||||
|
Value:=JLObject(@c);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(const w: widestring);
|
||||||
|
begin
|
||||||
|
VType:=vtUnicodeString;
|
||||||
|
Value:=JLObject(w);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(i: int64);
|
||||||
|
var
|
||||||
|
arr: array[0..0] of int64;
|
||||||
|
begin
|
||||||
|
VType:=vtInt64;
|
||||||
|
arr[0]:=i;
|
||||||
|
Value:=JLObject(@arr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tvarrec.init(q: qword; unsigned: boolean = true);
|
||||||
|
var
|
||||||
|
arr: array[0..0] of qword;
|
||||||
|
begin
|
||||||
|
init(int64(q));
|
||||||
|
{ parameter could be false in case it's called from Java code }
|
||||||
|
if unsigned then
|
||||||
|
VType:=vtQWord;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VInteger: longint;
|
||||||
|
begin
|
||||||
|
result:=JLInteger(Value).intValue
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VBoolean: boolean;
|
||||||
|
begin
|
||||||
|
result:=JLBoolean(Value).booleanValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VChar: ansichar;
|
||||||
|
begin
|
||||||
|
result:=char(JLByte(Value).byteValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VWideChar: widechar;
|
||||||
|
begin
|
||||||
|
result:=JLCharacter(Value).charValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VExtended: pextended;
|
||||||
|
begin
|
||||||
|
result:=PExtended(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VDouble: double;
|
||||||
|
begin
|
||||||
|
result:=JLDouble(Value).doubleValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VString: PShortString;
|
||||||
|
begin
|
||||||
|
result:=PShortString(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VPointer: pointer;
|
||||||
|
begin
|
||||||
|
result:=pointer(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VPChar: PChar;
|
||||||
|
begin
|
||||||
|
result:=PChar(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VObject: JLObject;
|
||||||
|
begin
|
||||||
|
result:=Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VClass: TJClass;
|
||||||
|
begin
|
||||||
|
result:=TJClass(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VPWideChar: PWideChar;
|
||||||
|
begin
|
||||||
|
result:=PWideChar(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VAnsiString: Pointer;
|
||||||
|
begin
|
||||||
|
result:=Pointer(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VCurrency: PCurrency;
|
||||||
|
begin
|
||||||
|
result:=PCurrency(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
// function tvarrec.VVariant: PVariant;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VInterface: JLObject;
|
||||||
|
begin
|
||||||
|
result:=Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VWideString: Pointer;
|
||||||
|
begin
|
||||||
|
result:=Pointer(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VInt64: PInt64;
|
||||||
|
begin
|
||||||
|
result:=PInt64(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VUnicodeString: Pointer;
|
||||||
|
begin
|
||||||
|
result:=Pointer(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tvarrec.VQWord: PQWord;
|
||||||
|
begin
|
||||||
|
result:=PQword(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
@ -26,7 +26,9 @@ type
|
|||||||
end;
|
end;
|
||||||
TClass = class of TObject;
|
TClass = class of TObject;
|
||||||
|
|
||||||
{$ifndef nounsupported}
|
TJClass = class of jlobject;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
vtInteger = 0;
|
vtInteger = 0;
|
||||||
vtBoolean = 1;
|
vtBoolean = 1;
|
||||||
@ -52,32 +54,51 @@ type
|
|||||||
|
|
||||||
type
|
type
|
||||||
TVarRec = record
|
TVarRec = record
|
||||||
case VType : sizeint of
|
VType: sizeint;
|
||||||
{$ifdef ENDIAN_BIG}
|
Value: JLObject;
|
||||||
vtInteger : ({$IFDEF CPU64}integerdummy1 : Longint;{$ENDIF CPU64}VInteger: Longint);
|
procedure init(l: longint);
|
||||||
vtBoolean : ({$IFDEF CPU64}booldummy : Longint;{$ENDIF CPU64}booldummy1,booldummy2,booldummy3: byte; VBoolean: Boolean);
|
procedure init(b: boolean);
|
||||||
vtChar : ({$IFDEF CPU64}chardummy : Longint;{$ENDIF CPU64}chardummy1,chardummy2,chardummy3: byte; VChar: Char);
|
procedure init(c: ansichar);
|
||||||
vtWideChar : ({$IFDEF CPU64}widechardummy : Longint;{$ENDIF CPU64}wchardummy1,VWideChar: WideChar);
|
procedure init(w: widechar);
|
||||||
{$else ENDIAN_BIG}
|
procedure init(d: extended);
|
||||||
vtInteger : (VInteger: Longint);
|
procedure init(const s: shortstring);
|
||||||
vtBoolean : (VBoolean: Boolean);
|
// pointer = object -> use constref to get different signature
|
||||||
vtChar : (VChar: Char);
|
procedure init(constref p: pointer);
|
||||||
vtWideChar : (VWideChar: WideChar);
|
procedure init(p: pchar);
|
||||||
{$endif ENDIAN_BIG}
|
procedure init(p: JLObject);
|
||||||
// vtString : (VString: PShortString);
|
procedure init(c: TJClass);
|
||||||
vtPointer : (VPointer: JLObject);
|
procedure init(p: pwidechar);
|
||||||
vtPChar : (VPChar: JLObject);
|
procedure init(const a: ansistring);
|
||||||
vtObject : (VObject: TObject);
|
// currency = int64 -> use constref to get different signature
|
||||||
vtClass : (VClass: TClass);
|
procedure init(constref c: currency);
|
||||||
vtPWideChar : (VPWideChar: JLObject);
|
// procedure init(const v: variant);
|
||||||
vtAnsiString : (VAnsiString: AnsiStringClass);
|
// interface = object
|
||||||
vtCurrency : (VCurrency: Currency);
|
procedure init(const w: widestring);
|
||||||
// vtVariant : (VVariant: PVariant);
|
procedure init(i: int64);
|
||||||
vtInterface : (VInterface: JLObject);
|
// unicodestring = widestring
|
||||||
vtWideString : (VWideString: JLString);
|
|
||||||
vtInt64 : (VInt64: Int64);
|
// qword = int64 -> extra parameter to solve signature problem
|
||||||
vtUnicodeString : (VUnicodeString: JLString);
|
procedure init(q: qword; unsigned: boolean = true);
|
||||||
vtQWord : (VQWord: QWord);
|
|
||||||
end;
|
function VInteger: longint;
|
||||||
{$endif}
|
function VBoolean: boolean;
|
||||||
|
function VChar: ansichar;
|
||||||
|
function VWideChar: widechar;
|
||||||
|
function VExtended: PExtended;
|
||||||
|
function VDouble: double;
|
||||||
|
function VString: PShortString;
|
||||||
|
function VPointer: pointer;
|
||||||
|
function VPChar: PChar;
|
||||||
|
function VObject: JLObject;
|
||||||
|
function VClass: TJClass;
|
||||||
|
function VPWideChar: PWideChar;
|
||||||
|
function VAnsiString: Pointer;
|
||||||
|
function VCurrency: PCurrency;
|
||||||
|
// function VVariant: PVariant;
|
||||||
|
function VInterface: JLObject;
|
||||||
|
function VWideString: Pointer;
|
||||||
|
function VInt64: PInt64;
|
||||||
|
function VUnicodeString: Pointer;
|
||||||
|
function VQWord: PQWord;
|
||||||
|
end;
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ Unit system;
|
|||||||
{$I-,Q-,H-,R-,V-,P+,T+}
|
{$I-,Q-,H-,R-,V-,P+,T+}
|
||||||
{$implicitexceptions off}
|
{$implicitexceptions off}
|
||||||
{$mode objfpc}
|
{$mode objfpc}
|
||||||
|
{$modeswitch advancedrecords}
|
||||||
|
|
||||||
Type
|
Type
|
||||||
{ Java primitive types }
|
{ Java primitive types }
|
||||||
|
Loading…
Reference in New Issue
Block a user