Преглед изворни кода

* 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
                 (left.nodetype<>typen) 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;
+                 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
              else if is_javaclass(left.resultdef) 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
                   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 }
-{$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!
                     (but also on all iPhone SDK revisions we support) }
                 if (target_info.system in systems_objc_nfabi) then
                   result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof))
                 else
-{$endif onlymacosx10_6 or arm}
+{$endif onlymacosx10_6 or arm aarch64}
                   result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof.childof));
                 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);
                 { we're done }
                 exit;
@@ -168,14 +171,14 @@ end;
             tloadvmtaddrnode(result).forcall:=true;
           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
           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!
             (but also on all iPhone SDK revisions we support) }
         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');
         typecheckpass(result);
       end;