fpc/compiler/jvm/dbgjasm.pas
Jonas Maebe c264c24fb0 + support for unit initialisation sections for the JVM target,
and initialise global variables that are wrapped (records, arrays)
    in those sections
   o check whether pd.localst is assigned in dbgjasm, because it's
     not for the unit initialisation routine
   o moved insertbssdata() from ncgutil to ngenutil and override it
     njvmutil (it does nothing in the latter, since global variables
     are added as fields to the class representing the unit; the
     initialisation is done in gen_initialize_code() in thlcgjvm)
   o added force_init() and force_final() methods to ngenutil, so
     that targets can force init/final routines separate from the
     regular managed types infrastructure (used by JVM for forcing
     an init section in case of records/arrays)

git-svn-id: branches/jvmbackend@18460 -
2011-08-20 08:01:39 +00:00

203 lines
6.3 KiB
ObjectPascal

{
Copyright (c) 2003-2006 by Peter Vreman, Florian Klaempfl, and Jonas Maebe
This units contains support for Jasmin debug info generation
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 dbgjasm;
{$i fpcdefs.inc}
interface
uses
cclasses,globtype,
aasmbase,aasmtai,aasmdata,
symbase,symconst,symtype,symdef,symsym,
finput,
DbgBase;
type
{ TDebugInfoJasmin }
TDebugInfoJasmin=class(TDebugInfo)
protected
fcurrprocstart,
fcurrprocend: tasmsymbol;
procedure appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym);
procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
procedure beforeappenddef(list:TAsmList;def:tdef);override;
procedure appendprocdef(list:TAsmList;def:tprocdef);override;
public
procedure inserttypeinfo;override;
procedure insertlineinfo(list:TAsmList);override;
end;
implementation
uses
sysutils,cutils,cfileutl,constexp,
version,globals,verbose,systems,
cpubase,cpuinfo,cgbase,paramgr,
fmodule,
defutil,symtable,jvmdef,ppu
;
{****************************************************************************
TDebugInfoJasmin
****************************************************************************}
procedure TDebugInfoJasmin.appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym);
var
jvar: tai_jvar;
proc: tprocdef;
begin
if tdef(sym.owner.defowner).typ<>procdef then
exit;
if not(sym.localloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
exit;
proc:=tprocdef(sym.owner.defowner);
jvar:=tai_jvar.create(sym.localloc.reference.offset,jvmmangledbasename(sym),fcurrprocstart,fcurrprocend);
proc.exprasmlist.InsertAfter(jvar,proc.procstarttai);
end;
procedure TDebugInfoJasmin.appendsym_paravar(list: TAsmList; sym: tparavarsym);
begin
appendsym_localsym(list,sym);
end;
procedure TDebugInfoJasmin.appendsym_localvar(list: TAsmList; sym: tlocalvarsym);
begin
appendsym_localsym(list,sym);
end;
procedure TDebugInfoJasmin.beforeappenddef(list: TAsmList; def: tdef);
begin
end;
procedure TDebugInfoJasmin.appendprocdef(list: TAsmList; def: tprocdef);
var
procstartlabel,
procendlabel : tasmlabel;
begin
{ insert debug information for local variables and parameters, but only
for routines implemented in the Pascal code }
if not assigned(def.procstarttai) then
exit;
current_asmdata.getlabel(procstartlabel,alt_dbgtype);
current_asmdata.getlabel(procendlabel,alt_dbgtype);
def.exprasmlist.insertafter(tai_label.create(procstartlabel),def.procstarttai);
def.exprasmlist.insertbefore(tai_label.create(procendlabel),def.procendtai);
fcurrprocstart:=procstartlabel;
fcurrprocend:=procendlabel;
write_symtable_parasyms(list,def.paras);
{ not assigned for unit init }
if assigned(def.localst) then
write_symtable_syms(list,def.localst);
end;
procedure TDebugInfoJasmin.inserttypeinfo;
begin
{ write all procedures and methods }
if assigned(current_module.globalsymtable) then
write_symtable_procdefs(nil,current_module.globalsymtable);
if assigned(current_module.localsymtable) then
write_symtable_procdefs(nil,current_module.localsymtable);
end;
procedure TDebugInfoJasmin.insertlineinfo(list: TAsmList);
var
currfileinfo,
lastfileinfo : tfileposinfo;
nolineinfolevel : Integer;
currfuncname : pshortstring;
hp : tai;
begin
FillChar(lastfileinfo,sizeof(lastfileinfo),0);
hp:=Tai(list.first);
nolineinfolevel:=0;
while assigned(hp) do
begin
case hp.typ of
ait_function_name :
begin
currfuncname:=tai_function_name(hp).funcname;
list.concat(tai_comment.Create(strpnew('function: '+currfuncname^)));
end;
ait_force_line :
begin
lastfileinfo.line:=-1;
end;
ait_marker :
begin
case tai_marker(hp).kind of
mark_NoLineInfoStart:
inc(nolineinfolevel);
mark_NoLineInfoEnd:
dec(nolineinfolevel);
end;
end;
end;
{ Java does not support multiple source files }
if (hp.typ=ait_instruction) and
(nolineinfolevel=0) and
(tailineinfo(hp).fileinfo.fileindex=main_module.unit_index) then
begin
currfileinfo:=tailineinfo(hp).fileinfo;
{ line changed ? }
if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then
begin
{ line directive }
list.insertbefore(tai_directive.Create(asd_jline,tostr(currfileinfo.line)),hp);
end;
lastfileinfo:=currfileinfo;
end;
hp:=tai(hp.next);
end;
end;
{****************************************************************************
****************************************************************************}
const
dbg_jasmin_info : tdbginfo =
(
id : dbg_jasmin;
idtxt : 'JASMIN';
);
initialization
RegisterDebugInfo(dbg_jasmin_info,TDebugInfoJasmin);
end.