| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 | {    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,        fcurrprocafterstart,        fcurrprocend: tasmsymbol;        procedure appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym; startlab: tasmsymbol);        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,symcpu,jvmdef,ppu      ;{****************************************************************************                              TDebugInfoJasmin****************************************************************************}  procedure TDebugInfoJasmin.appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym; startlab: tasmsymbol);    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,true),startlab,fcurrprocend);      tcpuprocdef(proc).exprasmlist.InsertAfter(jvar,proc.procstarttai);    end;  procedure TDebugInfoJasmin.appendsym_paravar(list: TAsmList; sym: tparavarsym);    begin      appendsym_localsym(list,sym,fcurrprocstart);    end;  procedure TDebugInfoJasmin.appendsym_localvar(list: TAsmList; sym: tlocalvarsym);    begin      appendsym_localsym(list,sym,fcurrprocafterstart);    end;  procedure TDebugInfoJasmin.beforeappenddef(list: TAsmList; def: tdef);    begin    end;  procedure TDebugInfoJasmin.appendprocdef(list: TAsmList; def: tprocdef);    var      procstartlabel,      procendlabel,      afterprocstartlabel : tasmlabel;      hp,      afterproccodestart  : tai;      instrcount          : longint;    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);      tcpuprocdef(def).exprasmlist.insertafter(tai_label.create(procstartlabel),def.procstarttai);      tcpuprocdef(def).exprasmlist.insertbefore(tai_label.create(procendlabel),def.procendtai);      fcurrprocstart:=procstartlabel;      { set the start label for local variables after the first instruction,        because javac's code completion support assumes that all info at        bytecode position 0 is for parameters }      instrcount:=0;      afterproccodestart:=def.procstarttai;      while assigned(afterproccodestart.next) do        begin          afterproccodestart:=tai(afterproccodestart.next);          if (afterproccodestart.typ=ait_instruction) then            break;        end;      { must be followed by at least one more instruction }      hp:=tai(afterproccodestart.next);      while assigned(hp) do        begin          if hp.typ=ait_instruction then            break;          hp:=tai(hp.next);        end;      if assigned(hp) then        begin          current_asmdata.getlabel(afterprocstartlabel,alt_dbgtype);          tcpuprocdef(def).exprasmlist.insertafter(tai_label.create(afterprocstartlabel),afterproccodestart);          fcurrprocafterstart:=afterprocstartlabel;        end      else        fcurrprocafterstart:=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.
 |