* 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; result:=nil;
exit; exit;
end; end;
result:=ctypeconvnode.create_explicit(left,java_ansistring);
ps:=search_struct_member(java_ansistring,'INTERNCHARS'); ps:=search_struct_member(java_ansistring,'INTERNCHARS');
if not assigned(ps) or if not assigned(ps) or
(ps.typ<>propertysym) then (ps.typ<>procsym) then
internalerror(2011081401); internalerror(2011081401);
ps:=tpropertysym(ps).propaccesslist[palt_read].firstsym^.sym; { AnsistringClass.internChars is a static class method that will either
if (ps.typ<>procsym) then return the internal fdata ansichar array of the string, or an array
internalerror(2011081402); with a single #0 }
result:=ccallnode.create(nil,tprocsym(ps),ps.owner,result,[]); result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
ps.owner,
cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[]);
include(result.flags,nf_isproperty); include(result.flags,nf_isproperty);
result:=ctypeconvnode.create_explicit(result,resultdef); result:=ctypeconvnode.create_explicit(result,resultdef);
{ reused } { reused }
@ -565,12 +566,29 @@ implementation
procedure tjvmtypeconvnode.second_cstring_to_pchar; procedure tjvmtypeconvnode.second_cstring_to_pchar;
var
hr: treference;
vs: tstaticvarsym;
begin begin
{ don't use is_chararray because it doesn't support special arrays } { don't use is_chararray because it doesn't support special arrays }
if (left.resultdef.typ<>arraydef) or if (left.resultdef.typ<>arraydef) or
(tarraydef(left.resultdef).elementdef.typ<>orddef) or (tarraydef(left.resultdef).elementdef.typ<>orddef) or
(torddef(tarraydef(left.resultdef).elementdef).ordtype<>uchar) then (torddef(tarraydef(left.resultdef).elementdef).ordtype<>uchar) then
internalerror(2011081304); internalerror(2011081304);
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); location_copy(location,left.location);
end; end;

View File

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

View File

@ -210,6 +210,17 @@ begin
result:=fElementSize; result:=fElementSize;
end; 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. 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 } { Used by the ansi/widestrings and maybe also other things in the future }
var var
{ widechar, because also used by widestring -> pwidechar conversions } { separated compared to generic version, for Java type safety }
emptychar : widechar;public name 'FPC_EMPTYCHAR'; 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} {$ifndef FPC_NO_GENERIC_STACK_CHECK}
{ if the OS does the stack checking, we don't need any stklen from the { if the OS does the stack checking, we don't need any stklen from the
main program } main program }