mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-27 03:28:15 +02:00
142 lines
5.0 KiB
ObjectPascal
142 lines
5.0 KiB
ObjectPascal
{
|
|
Copyright (c) 1998-2011 by Florian Klaempfl and Jonas Maebe
|
|
|
|
Generate assembler for constant nodes for the JVM
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************
|
|
}
|
|
unit njvmcon;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
symtype,
|
|
node,ncon,ncgcon;
|
|
|
|
type
|
|
tjvmrealconstnode = class(tcgrealconstnode)
|
|
procedure pass_generate_code;override;
|
|
end;
|
|
|
|
tjvmstringconstnode = class(tstringconstnode)
|
|
function pass_1: tnode; override;
|
|
procedure pass_generate_code;override;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
globtype,cutils,widestr,verbose,
|
|
symdef,symsym,symtable,symconst,
|
|
aasmdata,aasmcpu,defutil,
|
|
ncal,
|
|
cgbase,hlcgobj,hlcgcpu,cgutils,cpubase
|
|
;
|
|
|
|
|
|
{*****************************************************************************
|
|
TJVMREALCONSTNODE
|
|
*****************************************************************************}
|
|
|
|
procedure tjvmrealconstnode.pass_generate_code;
|
|
begin
|
|
location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
|
|
location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
|
|
thlcgjvm(hlcg).a_loadfpu_const_stack(current_asmdata.CurrAsmList,resultdef,value_real);
|
|
thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
|
|
end;
|
|
|
|
|
|
{ tcgstringconstnode }
|
|
|
|
function tjvmstringconstnode.pass_1: tnode;
|
|
var
|
|
strclass: tobjectdef;
|
|
psym: tsym;
|
|
pw: pcompilerwidestring;
|
|
begin
|
|
{ all Java strings are utf-16. However, there is no way to
|
|
declare a constant array of bytes (or any other type), those
|
|
have to be constructed by declaring a final field and then
|
|
initialising them in the class constructor element per
|
|
element. We therefore put the straight ASCII values into
|
|
the UTF-16 string, and then at run time extract those and
|
|
store them in an Ansistring/AnsiChar array }
|
|
result:=inherited pass_1;
|
|
if assigned(result) or
|
|
(cst_type in [cst_unicodestring,cst_widestring]) then
|
|
exit;
|
|
{ convert the constant into a widestring representation without any
|
|
code page conversion }
|
|
initwidestring(pw);
|
|
ascii2unicode(value_str,len,pw,false);
|
|
ansistringdispose(value_str,len);
|
|
pcompilerwidestring(value_str):=pw;
|
|
{ and now add a node to convert the data into ansistring format at
|
|
run time }
|
|
case cst_type of
|
|
cst_ansistring:
|
|
strclass:=tobjectdef(search_system_type('ANSISTRINGCLASS').typedef);
|
|
cst_shortstring:
|
|
strclass:=tobjectdef(search_system_type('SHORTSTRINGCLASS').typedef);
|
|
cst_conststring:
|
|
{ used for array of char }
|
|
strclass:=tobjectdef(search_system_type('ANSICHARARRAYCLASS').typedef);
|
|
else
|
|
internalerror(2011052401);
|
|
end;
|
|
cst_type:=cst_unicodestring;
|
|
psym:=search_struct_member(strclass,'CREATEFROMLITERALSTRINGBYTES');
|
|
if not assigned(psym) or
|
|
(psym.typ<>procsym) then
|
|
internalerror(2011052001);
|
|
{ since self will be freed, have to make a copy }
|
|
result:=ccallnode.create(ccallparanode.create(self.getcopy,nil),
|
|
tprocsym(psym),psym.owner,nil,[]);
|
|
end;
|
|
|
|
|
|
procedure tjvmstringconstnode.pass_generate_code;
|
|
begin
|
|
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
|
|
location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,resultdef);
|
|
case cst_type of
|
|
cst_ansistring:
|
|
begin
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_string(a_ldc,len,value_str));
|
|
end;
|
|
cst_shortstring,
|
|
cst_conststring:
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_string(a_ldc,len,value_str));
|
|
cst_unicodestring,
|
|
cst_widestring:
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_wstring(a_ldc,pcompilerwidestring(value_str)));
|
|
end;
|
|
thlcgjvm(hlcg).incstack(current_asmdata.CurrAsmList,1);
|
|
thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
crealconstnode:=tjvmrealconstnode;
|
|
cstringconstnode:=tjvmstringconstnode;
|
|
end.
|