From 39adb3dfae0fdfdf24552be5e655594116fc8551 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Tue, 20 Sep 2011 22:22:26 +0000 Subject: [PATCH] * fixed loading the nested framepointer when calling another nested routine at the same or a higher nesting level in case the current nested routine's framepointer was not part of the nestedfpstruct (because it doesn't have nested routines itself, or because those don't access any data in parent routines) on targets with explicit parentfpstruct management (JVM) + adapted test git-svn-id: branches/jvmbackend@19164 - --- compiler/ncgnstmm.pas | 28 ++++++++++++++++++---------- tests/test/jvm/tnestproc.pp | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/compiler/ncgnstmm.pas b/compiler/ncgnstmm.pas index f09e3cd409..4ccb576dbb 100644 --- a/compiler/ncgnstmm.pas +++ b/compiler/ncgnstmm.pas @@ -87,24 +87,33 @@ implementation var fsym : tfieldvarsym; hsym : tparavarsym; - currpi, - nextpi : tprocinfo; + currpi : tprocinfo; + useparentfppara : boolean; begin result:=nil; - if not assigned(current_procinfo.procdef.parentfpstruct) then + { if the current routine does not call a nested routine, or if that + nested routine does nothing for which it needs the nestedfp pointer + of the current routine (and hence it has not been moved into the + nestedfp struct), get the original nestedfp parameter } + useparentfppara:=not assigned(current_procinfo.procdef.parentfpstruct); + hsym:=tparavarsym(current_procinfo.procdef.parast.Find('parentfp')); + if current_procinfo.procdef.parast.symtablelevel>parentpd.parast.symtablelevel then + useparentfppara:= + useparentfppara or + (find_sym_in_parentfpstruct(current_procinfo.procdef,hsym)=nil); + if useparentfppara then begin - hsym:=tparavarsym(current_procinfo.procdef.parast.Find('parentfp')); result:=cloadnode.create(hsym,hsym.owner); + currpi:=current_procinfo.parent; end else begin result:=caddrnode.create_internal(cloadnode.create(current_procinfo.procdef.parentfpstruct,current_procinfo.procdef.parentfpstruct.owner)); include(result.flags,nf_typedaddr); + currpi:=current_procinfo; end; - { mark all parent parentfp parameters for inclusion in the struct that - holds all locals accessed from nested routines } - currpi:=current_procinfo.parent; - nextpi:=currpi.parent; + { follow the chain of parentfpstructs until we arrive at the one we + need } while (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do begin hsym:=tparavarsym(currpi.procdef.parast.Find('parentfp')); @@ -112,8 +121,7 @@ implementation if not assigned(fsym) then internalerror(2011060405); result:=csubscriptnode.create(fsym,cderefnode.create(result)); - currpi:=nextpi; - nextpi:=nextpi.parent; + currpi:=currpi.parent; end; end; diff --git a/tests/test/jvm/tnestproc.pp b/tests/test/jvm/tnestproc.pp index d6f8046da6..bc2bdf7721 100644 --- a/tests/test/jvm/tnestproc.pp +++ b/tests/test/jvm/tnestproc.pp @@ -9,9 +9,16 @@ procedure outer(var para: byte); const xxx: longint = 5; var a: longint; + called: boolean; procedure inner; begin + if not called then + begin + called:=true; + inner; + exit; + end; if a<>1 then raise JLException.Create('a1'); if para<>2 then @@ -20,8 +27,26 @@ procedure outer(var para: byte); para:=3; end; + + procedure inner2; + var + b: longint; + + procedure doubleinner; + begin + b:=3; + end; + + begin + doubleinner; + if b<>3 then + raise JLException.Create('b'); + inner; + end; + begin a:=1; + called:=false; inner; if a<>2 then raise JLException.Create('a2');