ソースを参照

* we cannot directly load the ISA pointer on AArch64, we have to call the
class instance method
(http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html )

git-svn-id: trunk@29943 -

Jonas Maebe 10 年 前
コミット
2340da410c
2 ファイル変更31 行追加12 行削除
  1. 23 7
      compiler/nmem.pas
  2. 8 5
      compiler/objcutil.pas

+ 23 - 7
compiler/nmem.pas

@@ -251,13 +251,29 @@ implementation
              if is_objcclass(left.resultdef) and
              if is_objcclass(left.resultdef) and
                 (left.nodetype<>typen) then
                 (left.nodetype<>typen) then
                begin
                begin
-                 { don't use the ISA field name, assume this field is at offset
-                   0 (just like gcc/clang) }
-                 result:=ctypeconvnode.create_internal(left,voidpointertype);
-                 result:=cderefnode.create(result);
-                 inserttypeconv_internal(result,resultdef);
-                 { reused }
-                 left:=nil;
+                 if target_info.system<>system_aarch64_darwin then
+                   begin
+                     { don't use the ISA field name, assume this field is at offset
+                       0 (just like gcc/clang) }
+                     result:=ctypeconvnode.create_internal(left,voidpointertype);
+                     result:=cderefnode.create(result);
+                     inserttypeconv_internal(result,resultdef);
+                     { reused }
+                     left:=nil;
+                   end
+                 else
+                   begin
+                     { Darwin/AArch64, the isa field is opaque and we must call
+                       _class to obtain the actual ISA pointer }
+                     vs:=search_struct_member(tobjectdef(left.resultdef),'_CLASS');
+                     if not assigned(vs) or
+                        (tsym(vs).typ<>procsym) then
+                       internalerror(2011041901);
+                     result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[]);
+                     inserttypeconv_explicit(result,resultdef);
+                     { reused }
+                     left:=nil;
+                   end;
                end
                end
              else if is_javaclass(left.resultdef) and
              else if is_javaclass(left.resultdef) and
                 (left.nodetype<>typen) and
                 (left.nodetype<>typen) and

+ 8 - 5
compiler/objcutil.pas

@@ -138,16 +138,19 @@ end;
                 { in case we are in a category method, we need the metaclass of the
                 { in case we are in a category method, we need the metaclass of the
                   superclass class extended by this category (= metaclass of superclass of superclass)
                   superclass class extended by this category (= metaclass of superclass of superclass)
                   for the fragile abi, and the metaclass of the superclass for the non-fragile ABI }
                   for the fragile abi, and the metaclass of the superclass for the non-fragile ABI }
-{$if defined(onlymacosx10_6) or defined(arm) }
+{$if defined(onlymacosx10_6) or defined(arm) or defined(aarch64)}
                 { NOTE: those send2 methods are only available on Mac OS X 10.6 and later!
                 { NOTE: those send2 methods are only available on Mac OS X 10.6 and later!
                     (but also on all iPhone SDK revisions we support) }
                     (but also on all iPhone SDK revisions we support) }
                 if (target_info.system in systems_objc_nfabi) then
                 if (target_info.system in systems_objc_nfabi) then
                   result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof))
                   result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof))
                 else
                 else
-{$endif onlymacosx10_6 or arm}
+{$endif onlymacosx10_6 or arm aarch64}
                   result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof.childof));
                   result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof.childof));
                 tloadvmtaddrnode(result).forcall:=true;
                 tloadvmtaddrnode(result).forcall:=true;
-                result:=objcloadbasefield(result,'ISA');
+                if target_info.system<>system_aarch64_darwin then
+                  result:=objcloadbasefield(result,'ISA')
+                else
+                  result:=cloadvmtaddrnode.create(result);
                 typecheckpass(result);
                 typecheckpass(result);
                 { we're done }
                 { we're done }
                 exit;
                 exit;
@@ -168,14 +171,14 @@ end;
             tloadvmtaddrnode(result).forcall:=true;
             tloadvmtaddrnode(result).forcall:=true;
           end;
           end;
 
 
-{$if defined(onlymacosx10_6) or defined(arm) }
+{$if defined(onlymacosx10_6) or defined(arm) or defined(aarch64)}
         { For the non-fragile ABI, the superclass send2 method itself loads the
         { For the non-fragile ABI, the superclass send2 method itself loads the
           superclass. For the fragile ABI, we have to do this ourselves.
           superclass. For the fragile ABI, we have to do this ourselves.
 
 
           NOTE: those send2 methods are only available on Mac OS X 10.6 and later!
           NOTE: those send2 methods are only available on Mac OS X 10.6 and later!
             (but also on all iPhone SDK revisions we support) }
             (but also on all iPhone SDK revisions we support) }
         if not(target_info.system in systems_objc_nfabi) then
         if not(target_info.system in systems_objc_nfabi) then
-{$endif onlymacosx10_6 or arm}
+{$endif onlymacosx10_6 or arm or aarch64}
           result:=objcloadbasefield(result,'SUPERCLASS');
           result:=objcloadbasefield(result,'SUPERCLASS');
         typecheckpass(result);
         typecheckpass(result);
       end;
       end;