Browse Source

* added decorator support to the external assembler writers so the LLVM
assembler writer can postprocess their output

git-svn-id: trunk@31626 -

Jonas Maebe 10 years ago
parent
commit
e1f78cb774
1 changed files with 135 additions and 29 deletions
  1. 135 29
      compiler/assemble.pas

+ 135 - 29
compiler/assemble.pas

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