summaryrefslogtreecommitdiff
path: root/compiler/jvm
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-08-29 22:21:23 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-08-29 22:21:23 +0000
commit1d57dab27f3cebe563b498bbf216c632ff32e549 (patch)
treebbb71868adc1ff597bd265b0e7e309d31f6180cb /compiler/jvm
parent7da9fae2e8fb08ce41999e655f29a60ae15282f2 (diff)
downloadfpc-1d57dab27f3cebe563b498bbf216c632ff32e549.tar.gz
+ -CTinitlocals switch for the JVM that initialises all local variables
that may trigger JVM bytecode verification errors if they are used before they are initialised (this includes passing them as a "var" parameter) + test * sorted -CT parameters alphabetically and alligned them git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@25387 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/jvm')
-rw-r--r--compiler/jvm/njvmutil.pas80
1 files changed, 76 insertions, 4 deletions
diff --git a/compiler/jvm/njvmutil.pas b/compiler/jvm/njvmutil.pas
index 9c1cf89ace..d19537874d 100644
--- a/compiler/jvm/njvmutil.pas
+++ b/compiler/jvm/njvmutil.pas
@@ -26,9 +26,9 @@ unit njvmutil;
interface
uses
- node,
+ node,nbas,
ngenutil,
- symtype,symconst,symsym;
+ symtype,symconst,symsym,symdef;
type
@@ -38,6 +38,11 @@ interface
class function force_init: boolean; override;
class procedure insertbssdata(sym: tstaticvarsym); override;
class function create_main_procdef(const name: string; potype: tproctypeoption; ps: tprocsym): tdef; override;
+
+ class function check_insert_trashing(pd: tprocdef): boolean; override;
+ class function trashable_sym(p: tsym): boolean; override;
+ class procedure maybe_trash_variable(var stat: tstatementnode; p: tabstractnormalvarsym; trashn: tnode); override;
+
class procedure InsertInitFinalTable; override;
class procedure InsertThreadvarTablesTable; override;
class procedure InsertThreadvars; override;
@@ -56,8 +61,8 @@ implementation
uses
verbose,cutils,globtype,globals,constexp,fmodule,
aasmdata,aasmtai,cpubase,aasmcpu,
- symdef,symbase,symtable,defutil,jvmdef,
- nbas,ncnv,ncon,ninl,ncal,nld,nmem,
+ symbase,symtable,defutil,jvmdef,
+ ncnv,ncon,ninl,ncal,nld,nmem,
ppu,
pass_1;
@@ -301,6 +306,73 @@ implementation
end;
+ class function tjvmnodeutils.check_insert_trashing(pd: tprocdef): boolean;
+ begin
+ { initialise locals with 0 }
+ if ts_init_locals in current_settings.targetswitches then
+ localvartrashing:=high(trashintvalues);
+ result:=inherited;
+ end;
+
+
+ class function tjvmnodeutils.trashable_sym(p: tsym): boolean;
+ begin
+ result:=
+ inherited and
+ not jvmimplicitpointertype(tabstractnormalvarsym(p).vardef);
+ end;
+
+
+ class procedure tjvmnodeutils.maybe_trash_variable(var stat: tstatementnode; p: tabstractnormalvarsym; trashn: tnode);
+ var
+ enumdef: tenumdef;
+ trashintval: int64;
+ trashenumval: longint;
+ trashable: boolean;
+ begin
+ trashable:=trashable_sym(p);
+ trashintval:=trashintvalues[localvartrashing];
+ { widechar is a separate type in the JVM, can't cast left hand to integer
+ like in common code }
+ if trashable and
+ is_widechar(tabstractvarsym(p).vardef) then
+ trash_small(stat,trashn,
+ cordconstnode.create(word(trashintval),tabstractvarsym(p).vardef,false))
+ { enums are class instances in the JVM -> create a valid instance }
+ else if trashable and
+ is_enum(tabstractvarsym(p).vardef) then
+ begin
+ enumdef:=tenumdef(tabstractvarsym(p).vardef);
+ trashenumval:=longint(trashintval);
+ if not assigned(enumdef.int2enumsym(trashenumval)) then
+ trashintval:=longint(enumdef.min);
+ trash_small(stat,trashn,
+ cordconstnode.create(trashintval,enumdef,false))
+ end
+ { can't init pointers with arbitrary values; procvardef and objectdef are
+ always pointer-sized here because tjvmnodeutils.trashablesym returns
+ false for jvm implicit pointer types }
+ else if trashable and
+ (tabstractvarsym(p).vardef.typ in [pointerdef,classrefdef,objectdef,procvardef]) then
+ trash_small(stat,trashn,cnilnode.create)
+ else if trashable and
+ is_real(tabstractvarsym(p).vardef) then
+ trash_small(stat,trashn,crealconstnode.create(trashintval,tabstractvarsym(p).vardef))
+ { don't use inherited routines because it typecasts left to the target
+ type, and that doesn't always work in the JVM }
+ else if trashable and
+ (is_integer(tabstractvarsym(p).vardef) or
+ is_cbool(tabstractvarsym(p).vardef) or
+ is_anychar(tabstractvarsym(p).vardef) or
+ is_currency(tabstractvarsym(p).vardef)) then
+ trash_small(stat,trashn,cordconstnode.create(trashintval,tabstractvarsym(p).vardef,false))
+ else if trashable and
+ is_pasbool(tabstractvarsym(p).vardef) then
+ trash_small(stat,trashn,cordconstnode.create(trashintval and 1,tabstractvarsym(p).vardef,false))
+ else
+ inherited;
+ end;
+
class procedure tjvmnodeutils.InsertInitFinalTable;
var
hp : tused_unit;