* fixed ansistring -> pchar type conversion on JVM target now that empty

ansistrings are represented by nil
  * fixed type conversion of constant empty ansistring/unicodestring to
    pchar/pwidechar on the JVM target

git-svn-id: branches/jvmbackend@21055 -
This commit is contained in:
Jonas Maebe 2012-04-25 22:29:20 +00:00
parent 9b6c426369
commit 0659058e44
4 changed files with 40 additions and 10 deletions

View File

@ -483,15 +483,16 @@ implementation
result:=nil;
exit;
end;
result:=ctypeconvnode.create_explicit(left,java_ansistring);
ps:=search_struct_member(java_ansistring,'INTERNCHARS');
if not assigned(ps) or
(ps.typ<>propertysym) then
(ps.typ<>procsym) then
internalerror(2011081401);
ps:=tpropertysym(ps).propaccesslist[palt_read].firstsym^.sym;
if (ps.typ<>procsym) then
internalerror(2011081402);
result:=ccallnode.create(nil,tprocsym(ps),ps.owner,result,[]);
{ AnsistringClass.internChars is a static class method that will either
return the internal fdata ansichar array of the string, or an array
with a single #0 }
result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
ps.owner,
cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[]);
include(result.flags,nf_isproperty);
result:=ctypeconvnode.create_explicit(result,resultdef);
{ reused }
@ -565,13 +566,30 @@ implementation
procedure tjvmtypeconvnode.second_cstring_to_pchar;
var
hr: treference;
vs: tstaticvarsym;
begin
{ don't use is_chararray because it doesn't support special arrays }
if (left.resultdef.typ<>arraydef) or
(tarraydef(left.resultdef).elementdef.typ<>orddef) or
(torddef(tarraydef(left.resultdef).elementdef).ordtype<>uchar) then
internalerror(2011081304);
location_copy(location,left.location);
if (tstringconstnode(left).cst_type in [cst_widestring,cst_unicodestring,cst_ansistring]) and
(tstringconstnode(left).len=0) then
begin
if tstringconstnode(left).cst_type=cst_ansistring then
vs:=tstaticvarsym(systemunit.Find('EMPTYPANSICHAR'))
else
vs:=tstaticvarsym(systemunit.Find('EMPTYPWIDECHAR'));
reference_reset(hr,4);
hr.symbol:=current_asmdata.RefAsmSymbol(vs.mangledname);
location_reset(location,LOC_REGISTER,OS_ADDR);
location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,resultdef);
hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,vs.vardef,resultdef,hr,location.register);
end
else
location_copy(location,left.location);
end;

View File

@ -41,7 +41,7 @@ type
function length: jint;
function codePage: TSystemCodePage;
function elementSize: Word;
property internChars: TAnsiCharArray read fdata;
class function internChars(const a: Ansistring): TAnsiCharArray; static;
end;

View File

@ -210,6 +210,17 @@ begin
result:=fElementSize;
end;
class function AnsistringClass.internChars(const a: Ansistring): TAnsiCharArray;
begin
if a<>'' then
result:=AnsistringClass(a).fdata
else
{ empty pchar: array with one element that is #0 }
setlength(result,1);
end;
{****************************************************************************
Internal functions, not in interface.
****************************************************************************}

View File

@ -98,8 +98,9 @@ const
{ Used by the ansi/widestrings and maybe also other things in the future }
var
{ widechar, because also used by widestring -> pwidechar conversions }
emptychar : widechar;public name 'FPC_EMPTYCHAR';
{ separated compared to generic version, for Java type safety }
emptypansichar : array[0..0] of ansichar; public name 'FPC_EMPTYANSICHAR';
emptypwidechar : array[0..0] of widechar; public name 'FPC_EMPTYWIDECHAR';
{$ifndef FPC_NO_GENERIC_STACK_CHECK}
{ if the OS does the stack checking, we don't need any stklen from the
main program }