Browse Source

* x86 Intel asm reader: handle special variables "self" and "result" similar to regular ones in terms of subscripting. This makes fix from r34911 apply to these special variables. Resolves #31542.

git-svn-id: trunk@35669 -
sergei 8 years ago
parent
commit
8ae0864c9a
3 changed files with 65 additions and 3 deletions
  1. 1 0
      .gitattributes
  2. 10 3
      compiler/x86/rax86int.pas
  3. 54 0
      tests/test/tasm10.pp

+ 1 - 0
.gitattributes

@@ -12045,6 +12045,7 @@ tests/test/tarrconstr2.pp svneol=native#text/pascal
 tests/test/tarrconstr3.pp svneol=native#text/pascal
 tests/test/tarrconstr3.pp svneol=native#text/pascal
 tests/test/tarrconstr4.pp svneol=native#text/pascal
 tests/test/tarrconstr4.pp svneol=native#text/pascal
 tests/test/tasm1.pp svneol=native#text/plain
 tests/test/tasm1.pp svneol=native#text/plain
+tests/test/tasm10.pp svneol=native#text/plain
 tests/test/tasm2.inc svneol=native#text/plain
 tests/test/tasm2.inc svneol=native#text/plain
 tests/test/tasm2.pp svneol=native#text/plain
 tests/test/tasm2.pp svneol=native#text/plain
 tests/test/tasm2a.pp svneol=native#text/plain
 tests/test/tasm2a.pp svneol=native#text/plain

+ 10 - 3
compiler/x86/rax86int.pas

@@ -1862,6 +1862,7 @@ Unit Rax86int;
                     Begin
                     Begin
                       oper.SetupResult;
                       oper.SetupResult;
                       Consume(AS_ID);
                       Consume(AS_ID);
+                      expr:='result';
                     end
                     end
                    else
                    else
                     if (actasmpattern = '@CODE') or (actasmpattern = '@DATA') then
                     if (actasmpattern = '@CODE') or (actasmpattern = '@DATA') then
@@ -1887,6 +1888,7 @@ Unit Rax86int;
                   begin
                   begin
                     oper.SetUpResult;
                     oper.SetUpResult;
                     Consume(AS_ID);
                     Consume(AS_ID);
+                    expr:='result';
                   end
                   end
                 { probably a variable or normal expression }
                 { probably a variable or normal expression }
                 { or a procedure (such as in CALL ID)      }
                 { or a procedure (such as in CALL ID)      }
@@ -1961,10 +1963,15 @@ Unit Rax86int;
                             Begin
                             Begin
                               { not a variable, check special variables.. }
                               { not a variable, check special variables.. }
                               if expr = 'SELF' then
                               if expr = 'SELF' then
-                                oper.SetupSelf
+                                begin
+                                  oper.SetupSelf;
+                                  expr:='self';
+                                end
                               else
                               else
-                                Message1(sym_e_unknown_id,expr);
-                              expr:='';
+                                begin
+                                  Message1(sym_e_unknown_id,expr);
+                                  expr:='';
+                                end;
                             end;
                             end;
                           { indexed access to variable? }
                           { indexed access to variable? }
                           if actasmtoken=AS_LBRACKET then
                           if actasmtoken=AS_LBRACKET then

+ 54 - 0
tests/test/tasm10.pp

@@ -0,0 +1,54 @@
+{ %CPU=x86_64 }
+{ Tests that object fields with zero offset are handled by Intel assembler reader
+  the same way as fields with nonzero offset }
+{$ifdef fpc}
+{$mode delphi}
+{$asmmode intel}
+{$endif}
+
+type
+  TTest=object
+    Data1,Data2:Integer;
+    procedure Setter;
+    function Getter1: TTest;
+    function Getter2: TTest;
+  end;
+
+
+ procedure TTest.Setter; assembler;
+ asm
+   mov Self.Data1,1234
+   mov Self.Data2,5678
+ end;
+ 
+ function TTest.Getter1: TTest; assembler;
+ asm
+   mov eax,Self.Data1
+   mov result.Data1, eax
+   mov eax,Self.Data2
+   mov result.Data2, eax
+ end;
+ 
+ 
+ function TTest.Getter2: TTest; assembler;
+ asm
+   mov  eax,Self.Data1
+   mov  @result.Data1, eax
+   mov  eax,Self.Data2
+   mov  @result.Data2, eax
+ end;
+ 
+ var
+   testobj, testobj2: TTest;
+ 
+ begin
+   testobj.Setter;
+   testobj2:=testobj.Getter1;
+   if (testobj2.Data1 <> 1234) or (testobj2.Data2 <> 5678) then
+     Halt(1);
+   testobj2:=testobj.Getter2;
+   if (testobj2.Data1 <> 1234) or (testobj2.Data2 <> 5678) then
+     Halt(2);
+   writeln('ok');
+ end.
+