소스 검색

* use Object_getClass(obj) instead of obj._class to get the class of an
Objective-C instance on AArch64, as the latter helper from the runtime
is a plain function call rather than an expensive message dispatch,
and moreover it also works for protocols (the "class" method is part
of NSObject, and protocols do not support it since there is no single
root class and hence they may represent an instance of a class that
does not derive from NSObject)
o also call it to get the "self" pointer when calling class methods for
protocols on AArch64 (fixes tobjc22a and tobjc22b on Darwin/AArch64)
o also call it to get the metaclass of a class on Darwin/AArch64 (fixes
tobjc25)
- removed special handling of getting the Objective-C (meta)class for
non-type nodes on other Darwin platforms, as this is also correctly
handled by the generic pass_generate_code

git-svn-id: trunk@30018 -

Jonas Maebe 10 년 전
부모
커밋
37c2d0e60d
1개의 변경된 파일9개의 추가작업 그리고 29개의 파일을 삭제
  1. 9 29
      compiler/nmem.pas

+ 9 - 29
compiler/nmem.pas

@@ -248,36 +248,16 @@ implementation
            include(current_procinfo.flags,pi_needs_got);
            include(current_procinfo.flags,pi_needs_got);
          if left.nodetype<>typen then
          if left.nodetype<>typen then
            begin
            begin
-             if is_objcclass(left.resultdef) and
-                (left.nodetype<>typen) then
+             if (target_info.system=system_aarch64_darwin) and
+                (is_objc_class_or_protocol(left.resultdef) or
+                 is_objcclassref(left.resultdef)) then
                begin
                begin
-                 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);
-                     { the ISA pointer is guaranteed to be aligned, while
-                       dereferencing a void pointer is normally not aligned at
-                       all }
-                     result:=geninlinenode(in_aligned_x,false,result);
-                     { 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;
+                 { on Darwin/AArch64, the isa field is opaque and we must
+                   call Object_getClass to obtain the actual ISA pointer }
+                 result:=ccallnode.createinternfromunit('OBJC','OBJECT_GETCLASS',ccallparanode.create(left,nil));
+                 inserttypeconv_explicit(result,resultdef);
+                 { reused }
+                 left:=nil;
                end
                end
              else if is_javaclass(left.resultdef) and
              else if is_javaclass(left.resultdef) and
                 (left.nodetype<>typen) and
                 (left.nodetype<>typen) and