diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-08-29 22:21:23 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-08-29 22:21:23 +0000 |
commit | 1d57dab27f3cebe563b498bbf216c632ff32e549 (patch) | |
tree | bbb71868adc1ff597bd265b0e7e309d31f6180cb /compiler/jvm | |
parent | 7da9fae2e8fb08ce41999e655f29a60ae15282f2 (diff) | |
download | fpc-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.pas | 80 |
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; |