* added decorator support to the external assembler writers so the LLVM

assembler writer can postprocess their output

git-svn-id: trunk@31626 -
This commit is contained in:
Jonas Maebe 2015-09-12 23:32:05 +00:00
parent b3d0197f98
commit e1f78cb774

View File

@ -62,7 +62,15 @@ interface
TExternalAssembler = class; TExternalAssembler = class;
IExternalAssemblerOutputFileDecorator=interface
function LinePrefix: AnsiString;
function LinePostfix: AnsiString;
function LineFilter(const s: AnsiString): AnsiString;
end;
TExternalAssemblerOutputFile=class TExternalAssemblerOutputFile=class
private
fdecorator: IExternalAssemblerOutputFileDecorator;
protected protected
owner: TExternalAssembler; owner: TExternalAssembler;
{outfile} {outfile}
@ -72,8 +80,13 @@ interface
outbuf : array[0..AsmOutSize-1] of char; outbuf : array[0..AsmOutSize-1] of char;
outfile : file; outfile : file;
fioerror : boolean; fioerror : boolean;
linestart: boolean;
Procedure AsmClear; Procedure AsmClear;
Procedure MaybeAddLinePrefix;
Procedure MaybeAddLinePostfix;
Procedure AsmWriteAnsiStringUnfiltered(const s: ansistring);
public public
Constructor Create(_owner: TExternalAssembler); Constructor Create(_owner: TExternalAssembler);
@ -86,6 +99,12 @@ interface
{ clears the assembler output if nothing was added since it was marked { clears the assembler output if nothing was added since it was marked
as empty, and returns whether it was empty } as empty, and returns whether it was empty }
function ClearIfEmpty: boolean; function ClearIfEmpty: boolean;
{ these routines will write the filtered version of their argument
according to the current decorator }
procedure AsmWriteFiltered(const c:char);
procedure AsmWriteFiltered(const s:string);
procedure AsmWriteFiltered(const s:ansistring);
procedure AsmWriteFiltered(p:pchar; len: longint);
{# Write a string to the assembler file } {# Write a string to the assembler file }
Procedure AsmWrite(const c:char); Procedure AsmWrite(const c:char);
@ -107,6 +126,7 @@ interface
procedure AsmClose; procedure AsmClose;
property ioerror: boolean read fioerror; property ioerror: boolean read fioerror;
property decorator: IExternalAssemblerOutputFileDecorator read fdecorator write fdecorator;
end; end;
{# This is the base class which should be overridden for each each {# This is the base class which should be overridden for each each
@ -356,39 +376,67 @@ Implementation
end; end;
procedure TExternalAssemblerOutputFile.AsmWriteFiltered(const c: char);
begin
MaybeAddLinePrefix;
AsmWriteAnsiStringUnfiltered(decorator.LineFilter(c));
end;
procedure TExternalAssemblerOutputFile.AsmWriteFiltered(const s: string);
begin
MaybeAddLinePrefix;
AsmWriteAnsiStringUnfiltered(decorator.LineFilter(s));
end;
procedure TExternalAssemblerOutputFile.AsmWriteFiltered(const s: ansistring);
begin
MaybeAddLinePrefix;
AsmWriteAnsiStringUnfiltered(decorator.LineFilter(s));
end;
procedure TExternalAssemblerOutputFile.AsmWriteFiltered(p: pchar; len: longint);
var
s: ansistring;
begin
MaybeAddLinePrefix;
setlength(s,len);
move(p^,s[1],len);
AsmWriteAnsiStringUnfiltered(decorator.LineFilter(s));
end;
Procedure TExternalAssemblerOutputFile.AsmClear; Procedure TExternalAssemblerOutputFile.AsmClear;
begin begin
outcnt:=0; outcnt:=0;
end; end;
constructor TExternalAssemblerOutputFile.Create(_owner: TExternalAssembler); procedure TExternalAssemblerOutputFile.MaybeAddLinePrefix;
begin begin
owner:=_owner; if assigned(decorator) and
linestart then
begin
AsmWriteAnsiStringUnfiltered(decorator.LinePrefix);
linestart:=false;
end;
end; end;
Procedure TExternalAssemblerOutputFile.AsmWrite(const c: char); procedure TExternalAssemblerOutputFile.MaybeAddLinePostfix;
begin begin
if OutCnt+1>=AsmOutSize then if assigned(decorator) and
AsmFlush; not linestart then
OutBuf[OutCnt]:=c; begin
inc(OutCnt); AsmWriteAnsiStringUnfiltered(decorator.LinePostfix);
inc(AsmSize); linestart:=true;
end;
end; end;
Procedure TExternalAssemblerOutputFile.AsmWrite(const s:string); procedure TExternalAssemblerOutputFile.AsmWriteAnsiStringUnfiltered(const s: ansistring);
begin
if OutCnt+length(s)>=AsmOutSize then
AsmFlush;
Move(s[1],OutBuf[OutCnt],length(s));
inc(OutCnt,length(s));
inc(AsmSize,length(s));
end;
Procedure TExternalAssemblerOutputFile.AsmWrite(const s:ansistring);
var var
StartIndex, ToWrite: longint; StartIndex, ToWrite: longint;
begin begin
@ -413,6 +461,56 @@ Implementation
end; end;
constructor TExternalAssemblerOutputFile.Create(_owner: TExternalAssembler);
begin
owner:=_owner;
linestart:=true;
end;
Procedure TExternalAssemblerOutputFile.AsmWrite(const c: char);
begin
if assigned(decorator) then
AsmWriteFiltered(c)
else
begin
if OutCnt+1>=AsmOutSize then
AsmFlush;
OutBuf[OutCnt]:=c;
inc(OutCnt);
inc(AsmSize);
end;
end;
Procedure TExternalAssemblerOutputFile.AsmWrite(const s:string);
begin
if s='' then
exit;
if assigned(decorator) then
AsmWriteFiltered(s)
else
begin
if OutCnt+length(s)>=AsmOutSize then
AsmFlush;
Move(s[1],OutBuf[OutCnt],length(s));
inc(OutCnt,length(s));
inc(AsmSize,length(s));
end;
end;
Procedure TExternalAssemblerOutputFile.AsmWrite(const s:ansistring);
begin
if s='' then
exit;
if assigned(decorator) then
AsmWriteFiltered(s)
else
AsmWriteAnsiStringUnfiltered(s);
end;
procedure TExternalAssemblerOutputFile.AsmWriteLn(const c: char); procedure TExternalAssemblerOutputFile.AsmWriteLn(const c: char);
begin begin
AsmWrite(c); AsmWrite(c);
@ -439,23 +537,31 @@ Implementation
i,j : longint; i,j : longint;
begin begin
i:=StrLen(p); i:=StrLen(p);
j:=i; if i=0 then
while j>0 do exit;
begin if assigned(decorator) then
i:=min(j,AsmOutSize); AsmWriteFiltered(p,i)
if OutCnt+i>=AsmOutSize then else
AsmFlush; begin
Move(p[0],OutBuf[OutCnt],i); j:=i;
inc(OutCnt,i); while j>0 do
inc(AsmSize,i); begin
dec(j,i); i:=min(j,AsmOutSize);
p:=pchar(@p[i]); if OutCnt+i>=AsmOutSize then
end; AsmFlush;
Move(p[0],OutBuf[OutCnt],i);
inc(OutCnt,i);
inc(AsmSize,i);
dec(j,i);
p:=pchar(@p[i]);
end;
end;
end; end;
Procedure TExternalAssemblerOutputFile.AsmLn; Procedure TExternalAssemblerOutputFile.AsmLn;
begin begin
MaybeAddLinePostfix;
if OutCnt>=AsmOutSize-2 then if OutCnt>=AsmOutSize-2 then
AsmFlush; AsmFlush;
if (cs_link_on_target in current_settings.globalswitches) then if (cs_link_on_target in current_settings.globalswitches) then