]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Makefile.in (C_SOURCE_FILES): Added methods.c.
authorNicola Pero <nicola.pero@meta-innovation.com>
Tue, 12 Oct 2010 22:00:01 +0000 (22:00 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Tue, 12 Oct 2010 22:00:01 +0000 (22:00 +0000)
2010-10-12  Nicola Pero  <nicola.pero@meta-innovation.com>

        * Makefile.in (C_SOURCE_FILES): Added methods.c.
        * encoding.c (method_getNumberOfArguments): New.
        (method_get_number_of_arguments): Call
        method_getNumberOfArguments.
        * ivars.c (ivar_getName): Check for NULL variable argument.
        (ivar_getOffset): Check for NULL variable argument.
        (ivar_getTypeEncoding): Check for NULL variable argument.
        (class_copyIvarList): New.
        * methods.c: New.
        * protocols.c (class_copyProtocolList): Check for Nil class_
        argument.
        * sendmsg.c: Use 'struct objc_method *' instead of Method_t, and
        'struct objc_method_list *' instead of MethodList_t.
        (class_getMethodImplementation): New.
        (class_respondsToSelector): New.
        (class_getInstanceMethod): New.
        (class_getClassMethod): New.
        * objc/runtime.h: Updated comments.
        (class_copyIvarList): New.
        (class_getInstanceMethod): New.
        (class_getClassMethod): New.
        (class_getMethodImplementation): New.
        (class_respondsToSelector): New.
        (method_getName): New.
        (method_getImplementation): New.
        (method_getTypeEncoding): New.
        (class_copyMethodList): New.
        (method_getNumberOfArguments): New.

From-SVN: r165400

libobjc/ChangeLog
libobjc/Makefile.in
libobjc/encoding.c
libobjc/ivars.c
libobjc/methods.c [new file with mode: 0644]
libobjc/objc/runtime.h
libobjc/protocols.c
libobjc/sendmsg.c

index ec0a98f37905a77d1460f299fafec80300e0ad6a..300bb3e7e20ab80712035a47a6c155fe406e2691 100644 (file)
@@ -1,3 +1,34 @@
+2010-10-12  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * Makefile.in (C_SOURCE_FILES): Added methods.c.
+       * encoding.c (method_getNumberOfArguments): New.
+       (method_get_number_of_arguments): Call
+       method_getNumberOfArguments.
+       * ivars.c (ivar_getName): Check for NULL variable argument.
+       (ivar_getOffset): Check for NULL variable argument.
+       (ivar_getTypeEncoding): Check for NULL variable argument.
+       (class_copyIvarList): New.
+       * methods.c: New.
+       * protocols.c (class_copyProtocolList): Check for Nil class_
+       argument.
+       * sendmsg.c: Use 'struct objc_method *' instead of Method_t, and
+       'struct objc_method_list *' instead of MethodList_t.
+       (class_getMethodImplementation): New.
+       (class_respondsToSelector): New.
+       (class_getInstanceMethod): New.
+       (class_getClassMethod): New.
+       * objc/runtime.h: Updated comments.
+       (class_copyIvarList): New.
+       (class_getInstanceMethod): New.
+       (class_getClassMethod): New.
+       (class_getMethodImplementation): New.
+       (class_respondsToSelector): New.
+       (method_getName): New.
+       (method_getImplementation): New.
+       (method_getTypeEncoding): New.
+       (class_copyMethodList): New.
+       (method_getNumberOfArguments): New.
+       
 2010-10-12  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * class.c: Include objc/runtime.h and objc-private/module-abi-8.h
index 4790f952b9dce4c3ebebe4bec83c7642c6f6e546..b644b3f48321100ed53e7dfa0b5afc5811d9f427 100644 (file)
@@ -173,6 +173,7 @@ C_SOURCE_FILES = \
    init.c \
    ivars.c \
    memory.c \
+   methods.c \
    nil_method.c \
    objc-foreach.c \
    objc-sync.c \
index 87517f4eaf85cdcbbbe0612557eb7c58f1322a4d..b30389ee0e495c3977e236846b3cd0fe072f2a3b 100644 (file)
@@ -797,22 +797,39 @@ objc_skip_argspec (const char *type)
   return type;
 }
 
-/*
-  Return the number of arguments that the method MTH expects.
-  Note that all methods need two implicit arguments `self' and
-  `_cmd'.
-*/
-int
-method_get_number_of_arguments (struct objc_method *mth)
+unsigned int
+method_getNumberOfArguments (struct objc_method *method)
 {
-  int i = 0;
-  const char *type = mth->method_types;
-  while (*type)
+  if (method == NULL)
+    return 0;
+  else
     {
-      type = objc_skip_argspec (type);
-      i += 1;
+      unsigned int i = 0;
+      const char *type = method->method_types;
+      while (*type)
+       {
+         type = objc_skip_argspec (type);
+         i += 1;
+       }
+
+      if (i == 0)
+       {
+         /* This could only happen if method_types is invalid; in
+            that case, return 0.  */
+         return 0;
+       }
+      else
+       {
+         /* Remove the return type.  */
+         return (i - 1);
+       }
     }
-  return i - 1;
+}
+
+int
+method_get_number_of_arguments (struct objc_method *mth)
+{
+  return method_getNumberOfArguments (mth);
 }
 
 /*
index 52b71af1124bb576476d835e301de91f4fbf4021..0dbb45b676af0bafab5949b7cd57ea744d3a8d17 100644 (file)
@@ -26,8 +26,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "objc/runtime.h"
 #include "objc-private/module-abi-8.h" /* For runtime structures  */
 #include "objc/thr.h"
-#include "objc-private/runtime.h"              /* the kitchen sink */
-#include <string.h> /* For strcmp */
+#include "objc-private/runtime.h"      /* the kitchen sink */
+#include <string.h>                    /* For strcmp */
 
 struct objc_ivar *
 class_getInstanceVariable (Class class_, const char *name)
@@ -157,15 +157,74 @@ void object_setIvar (id object, struct objc_ivar * variable, id value)
 
 const char * ivar_getName (struct objc_ivar * variable)
 {
+  if (variable == NULL)
+    return NULL;
+
   return variable->ivar_name;
 }
 
 ptrdiff_t ivar_getOffset (struct objc_ivar * variable)
 {
+  if (variable == NULL)
+    return 0;
+
   return (ptrdiff_t)(variable->ivar_offset);
 }
 
 const char * ivar_getTypeEncoding (struct objc_ivar * variable)
 {
+  if (variable == NULL)
+    return NULL;
+
   return variable->ivar_type;
 }
+
+struct objc_ivar ** class_copyIvarList (Class class_, unsigned int *numberOfReturnedIvars)
+{
+  unsigned int count = 0;
+  struct objc_ivar **returnValue = NULL;
+  struct objc_ivar_list* ivar_list;
+
+  if (class_ == Nil)
+    {
+      if (numberOfReturnedIvars)
+       *numberOfReturnedIvars = 0;
+      return NULL;
+    }
+
+  /* TODO: We do not need to lock the runtime mutex if the class has
+     been registered with the runtime, since the instance variable
+     list can not change after the class is registered.  The only case
+     where the lock may be useful if the class is still being created
+     using objc_allocateClassPair(), but has not been registered using
+     objc_registerClassPair() yet.  I'm not even sure that is
+     allowed.  */
+  objc_mutex_lock (__objc_runtime_mutex);
+
+  /* Count how many ivars we have.  */
+  ivar_list = class_->ivars;
+  count = ivar_list->ivar_count;
+
+  if (count != 0)
+    {
+      unsigned int i = 0;
+      
+      /* Allocate enough memory to hold them.  */
+      returnValue = (struct objc_ivar **)(malloc (sizeof (struct objc_ivar *) * (count + 1)));
+      
+      /* Copy the ivars.  */
+      for (i = 0; i < count; i++)
+       {
+         returnValue[i] = &(ivar_list->ivar_list[i]);
+       }
+      
+      returnValue[i] = NULL;
+    }
+  
+  objc_mutex_unlock (__objc_runtime_mutex);
+
+  if (numberOfReturnedIvars)
+    *numberOfReturnedIvars = count;
+
+  return returnValue;
+}
diff --git a/libobjc/methods.c b/libobjc/methods.c
new file mode 100644 (file)
index 0000000..c6236a1
--- /dev/null
@@ -0,0 +1,114 @@
+/* GNU Objective C Runtime method related functions.
+   Copyright (C) 2010 Free Software Foundation, Inc.
+   Contributed by Nicola Pero
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3, or (at your option) any later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "objc-private/common.h"
+#include "objc/runtime.h"
+#include "objc-private/module-abi-8.h" /* For runtime structures.   */
+#include "objc/thr.h"
+#include "objc-private/runtime.h"      /* For __objc_runtime_mutex.  */
+#include <stdlib.h>                    /* For malloc.  */
+
+SEL method_getName (struct objc_method * method)
+{
+  if (method == NULL)
+    return NULL;
+
+  return method->method_name;
+}
+
+const char * method_getTypeEncoding (struct objc_method * method)
+{
+  if (method == NULL)
+    return NULL;
+
+  return method->method_types;
+}
+
+IMP method_getImplementation (struct objc_method * method)
+{
+  if (method == NULL)
+    return NULL;
+
+  return method->method_imp;
+}
+
+struct objc_method ** class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods)
+{
+  unsigned int count = 0;
+  struct objc_method **returnValue = NULL;
+  struct objc_method_list* method_list;
+
+  if (class_ == Nil)
+    {
+      if (numberOfReturnedMethods)
+       *numberOfReturnedMethods = 0;
+      return NULL;
+    }
+
+  /* Lock the runtime mutex because the class methods may be
+     concurrently modified.  */
+  objc_mutex_lock (__objc_runtime_mutex);
+
+  /* Count how many methods we have.  */
+  method_list = class_->methods;
+
+  while (method_list)
+    {
+      count = count + method_list->method_count;
+      method_list = method_list->method_next;
+    }
+
+  if (count != 0)
+    {
+      unsigned int i = 0;
+      
+      /* Allocate enough memory to hold them.  */
+      returnValue 
+       = (struct objc_method **)(malloc (sizeof (struct objc_method *) 
+                                         * (count + 1)));
+      
+      /* Copy the methods.  */
+      method_list = class_->methods;
+      
+      while (method_list)
+       {
+         int j;
+         for (j = 0; j < method_list->method_count; j++)
+           {
+             returnValue[i] = &(method_list->method_list[j]);
+             i++;
+           }
+         method_list = method_list->method_next;
+       }
+      
+      returnValue[i] = NULL;
+    }
+
+  objc_mutex_unlock (__objc_runtime_mutex);
+
+  if (numberOfReturnedMethods)
+    *numberOfReturnedMethods = count;
+
+  return returnValue;
+}
index a52c7611857a74cc081d98914eee5e7ba4d4b99e..a11d283586f7e14df1a2179176c57af6818f1aa0 100644 (file)
@@ -284,16 +284,27 @@ objc_EXPORT id object_getIvar (id object, Ivar variable);
    object_setInstanceVariable.  */
 objc_EXPORT void object_setIvar (id object, Ivar variable, id value);
 
-/* Return the name of the instance variable.  */
+/* Return the name of the instance variable.  Return NULL if
+   'variable' is NULL.  */
 objc_EXPORT const char * ivar_getName (Ivar variable);
 
 /* Return the offset of the instance variable from the start of the
-   object data.  */
+   object data.  Return 0 if 'variable' is NULL.  */
 objc_EXPORT ptrdiff_t ivar_getOffset (Ivar variable);
 
-/* Return the type encoding of the variable.  */
+/* Return the type encoding of the variable.  Return NULL if
+   'variable' is NULL.  */
 objc_EXPORT const char * ivar_getTypeEncoding (Ivar variable);
 
+/* Return all the instance variables of the class.  The return value
+   of the function is a pointer to an area, allocated with malloc(),
+   that contains all the instance variables of the class.  It does not
+   include instance variables of superclasses.  The list is terminated
+   by NULL.  Optionally, if you pass a non-NULL
+   'numberOfReturnedIvars' pointer, the unsigned int that it points to
+   will be filled with the number of instance variables returned.  */
+objc_EXPORT Ivar * class_copyIvarList (Class class_, unsigned int *numberOfReturnedIvars);
+
 
 /** Implementation: the following functions are in class.c.  */
 
@@ -412,6 +423,84 @@ objc_EXPORT void class_setVersion (Class class_, int version);
 objc_EXPORT size_t class_getInstanceSize (Class class_);
 
 
+/** Implementation: the following functions are in sendmsg.c.  */
+
+/* Return the instance method with selector 'selector' of class
+   'class_', or NULL if the class (or one of its superclasses) does
+   not implement the method.  Return NULL if class_ is Nil or selector
+   is NULL.  */
+objc_EXPORT Method class_getInstanceMethod (Class class_, SEL selector);
+
+/* Return the class method with selector 'selector' of class 'class_',
+   or NULL if the class (or one of its superclasses) does not
+   implement the method.  Return NULL if class_ is Nil or selector is
+   NULL.  */
+objc_EXPORT Method class_getClassMethod (Class class_, SEL selector);
+
+/* Return the IMP (pointer to the function implementing a method) for
+   the instance method with selector 'selector' in class 'class_'.
+   This is the same routine that is used while messaging, and should
+   be very fast.  Note that you most likely would need to cast the
+   return function pointer to a function pointer with the appropriate
+   arguments and return type before calling it.  To get a class
+   method, you can pass the meta-class as the class_ argument (ie, use
+   class_getMethodImplementation (object_getClass (class_),
+   selector)).  Return NULL if class_ is Nil or selector is NULL.  */
+objc_EXPORT IMP class_getMethodImplementation (Class class_, SEL selector);
+
+/* Compatibility Note: the Apple/NeXT runtime has the function
+   class_getMethodImplementation_stret () which currently does not
+   exist on the GNU runtime because the messaging implementation is
+   different.  */
+
+/* Return YES if class 'class_' has an instance method implementing
+   selector 'selector', and NO if not.  Return NO if class_ is Nil or
+   selector is NULL.  If you need to check a class method, use the
+   meta-class as the class_ argument (ie, use class_respondsToSelector
+   (object_getClass (class_), selector)).  */
+objc_EXPORT BOOL class_respondsToSelector (Class class_, SEL selector);
+
+
+/** Implementation: the following functions are in methods.c.  */
+
+/* Return the selector for method 'method'.  Return NULL if 'method'
+   is NULL.
+
+   This function is misnamed; it should be called
+   'method_getSelector'.  To get the actual name, get the selector,
+   then the name from the selector (ie, use sel_getName
+   (method_getName (method))).  */
+objc_EXPORT SEL method_getName (Method method);
+
+/* Return the IMP of the method.  Return NULL if 'method' is NULL.  */
+objc_EXPORT IMP method_getImplementation (Method method);
+
+/* Return the type encoding of the method.  Return NULL if 'method' is
+   NULL.  */
+objc_EXPORT const char * method_getTypeEncoding (Method method);
+
+/* Return all the instance methods of the class.  The return value of
+   the function is a pointer to an area, allocated with malloc(), that
+   contains all the instance methods of the class.  It does not
+   include instance methods of superclasses.  The list is terminated
+   by NULL.  Optionally, if you pass a non-NULL
+   'numberOfReturnedMethods' pointer, the unsigned int that it points
+   to will be filled with the number of instance methods returned.  To
+   get the list of class methods, pass the meta-class in the 'class_'
+   argument, (ie, use class_copyMethodList (object_getClass (class_),
+   &numberOfReturnedMethods)).  */
+objc_EXPORT Method * class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods);
+
+
+/** Implementation: the following functions are in encoding.c.  */
+
+/* Return the number of arguments that the method 'method' expects.
+   Note that all methods need two implicit arguments ('self' for the
+   receiver, and '_cmd' for the selector).  Return 0 if 'method' is
+   NULL.  */
+objc_EXPORT unsigned int method_getNumberOfArguments (Method method);
+
+
 /** Implementation: the following functions are in protocols.c.  */
 
 /* Return the protocol with name 'name', or nil if it the protocol is
index 6d429803c8fd584168ce425d64f006a444090941..bc714ae63ae0bbecd4bdfdec483721a2936d403d 100644 (file)
@@ -211,6 +211,13 @@ class_copyProtocolList (Class class_, unsigned int *numberOfReturnedProtocols)
   Protocol **returnValue = NULL;
   struct objc_protocol_list* proto_list;
 
+  if (class_ == Nil)
+    {
+      if (numberOfReturnedProtocols)
+       *numberOfReturnedProtocols = 0;
+      return NULL;
+    }
+
   /* Lock the runtime mutex because the class protocols may be
      concurrently modified.  */
   objc_mutex_lock (__objc_runtime_mutex);
index 02be39c5b0528d3e70d8e3ac64253d6cdd7dacaa..d68e3040f4f33edbda11facfe51a7293b54c1cd8 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU Objective C Runtime message lookup 
    Copyright (C) 1993, 1995, 1996, 1997, 1998,
-   2001, 2002, 2004, 2009 Free Software Foundation, Inc.
+   2001, 2002, 2004, 2009, 2010 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
 
 This file is part of GCC.
@@ -91,8 +91,8 @@ static __big
 static id
 #endif
 __objc_block_forward (id, SEL, ...);
-static Method_t search_for_method_in_hierarchy (Class class, SEL sel);
-Method_t search_for_method_in_list (MethodList_t list, SEL op);
+static struct objc_method * search_for_method_in_hierarchy (Class class, SEL sel);
+struct objc_method * search_for_method_in_list (struct objc_method_list * list, SEL op);
 id nil_method (id, SEL);
 
 /* Given a selector, return the proper forwarding implementation. */
@@ -193,11 +193,22 @@ get_imp (Class class, SEL sel)
   return res;
 }
 
+/* The new name of get_imp().  */
+IMP
+class_getMethodImplementation (Class class_, SEL selector)
+{
+  if (class_ == Nil  ||  selector == NULL)
+    return NULL;
+
+  /* get_imp is inlined, so we're good.  */
+  return get_imp (class_, selector);
+}
+
 /* Given a method, return its implementation.  */
 IMP
-method_get_imp (Method_t method)
+method_get_imp (struct objc_method * method)
 {
-  return (method != (Method_t)0) ? method->method_imp : (IMP)0;
+  return (method != (struct objc_method *)0) ? method->method_imp : (IMP)0;
 }
 
 /* Query if an object can respond to a selector, returns YES if the
@@ -225,6 +236,30 @@ __objc_responds_to (id object, SEL sel)
   return (res != 0);
 }
 
+BOOL
+class_respondsToSelector (Class class_, SEL selector)
+{
+  void *res;
+
+  if (class_ == Nil  ||  selector == NULL)
+    return NO;
+
+  /* Install dispatch table if need be */
+  if (class_->dtable == __objc_uninstalled_dtable)
+    {
+      objc_mutex_lock (__objc_runtime_mutex);
+      if (class_->dtable == __objc_uninstalled_dtable)
+       {
+         __objc_install_dispatch_table_for_class (class_);
+       }
+      objc_mutex_unlock (__objc_runtime_mutex);
+    }
+
+  /* Get the method from the dispatch table */
+  res = sarray_get_safe (class_->dtable, (size_t) selector->sel_id);
+  return (res != 0);
+}
+
 /* This is the lookup function.  All entries in the table are either a 
    valid method *or* zero.  If zero then either the dispatch table
    needs to be installed or it doesn't exist and forwarding is attempted. */
@@ -374,11 +409,11 @@ __objc_send_initialize (Class class)
       {
        SEL          op = sel_register_name ("initialize");
        IMP          imp = 0;
-        MethodList_t method_list = class->class_pointer->methods;
+        struct objc_method_list * method_list = class->class_pointer->methods;
 
         while (method_list) {
          int i;
-          Method_t method;
+          struct objc_method * method;
 
           for (i = 0; i < method_list->method_count; i++) {
            method = &(method_list->method_list[i]);
@@ -409,7 +444,7 @@ __objc_send_initialize (Class class)
    method nothing is guaranteed about what method will be used.
    Assumes that __objc_runtime_mutex is locked down. */
 static void
-__objc_install_methods_in_dtable (Class class, MethodList_t method_list)
+__objc_install_methods_in_dtable (Class class, struct objc_method_list * method_list)
 {
   int i;
 
@@ -421,7 +456,7 @@ __objc_install_methods_in_dtable (Class class, MethodList_t method_list)
 
   for (i = 0; i < method_list->method_count; i++)
     {
-      Method_t method = &(method_list->method_list[i]);
+      struct objc_method * method = &(method_list->method_list[i]);
       sarray_at_put_safe (class->dtable,
                          (sidx) method->method_name->sel_id,
                          method->method_imp);
@@ -492,7 +527,7 @@ __objc_update_dispatch_table_for_class (Class class)
    methods installed right away, and their selectors are made into
    SEL's by the function __objc_register_selectors_from_class. */
 void
-class_add_method_list (Class class, MethodList_t list)
+class_add_method_list (Class class, struct objc_method_list * list)
 {
   /* Passing of a linked list is not allowed.  Do multiple calls.  */
   assert (! list->method_next);
@@ -507,27 +542,44 @@ class_add_method_list (Class class, MethodList_t list)
   __objc_update_dispatch_table_for_class (class);
 }
 
-Method_t
+struct objc_method *
 class_get_instance_method (Class class, SEL op)
 {
   return search_for_method_in_hierarchy (class, op);
 }
 
-Method_t
+struct objc_method *
 class_get_class_method (MetaClass class, SEL op)
 {
   return search_for_method_in_hierarchy (class, op);
 }
 
+struct objc_method *
+class_getInstanceMethod (Class class_, SEL selector)
+{
+  if (class_ == Nil  ||  selector == NULL)
+    return NULL;
+
+  return search_for_method_in_hierarchy (class_, selector);
+}
+
+struct objc_method *
+class_getClassMethod (Class class_, SEL selector)
+{
+  if (class_ == Nil  ||  selector == NULL)
+    return NULL;
+  
+  return search_for_method_in_hierarchy (class_->class_pointer, 
+                                        selector);
+}
 
 /* Search for a method starting from the current class up its hierarchy.
    Return a pointer to the method's method structure if found.  NULL
    otherwise. */   
-
-static Method_t
+static struct objc_method *
 search_for_method_in_hierarchy (Class cls, SEL sel)
 {
-  Method_t method = NULL;
+  struct objc_method * method = NULL;
   Class class;
 
   if (! sel_is_mapped (sel))
@@ -546,10 +598,10 @@ search_for_method_in_hierarchy (Class cls, SEL sel)
 /* Given a linked list of method and a method's name.  Search for the named
    method's method structure.  Return a pointer to the method's method
    structure if found.  NULL otherwise. */  
-Method_t
-search_for_method_in_list (MethodList_t list, SEL op)
+struct objc_method *
+search_for_method_in_list (struct objc_method_list * list, SEL op)
 {
-  MethodList_t method_list = list;
+  struct objc_method_list * method_list = list;
 
   if (! sel_is_mapped (op))
     return NULL;
@@ -562,7 +614,7 @@ search_for_method_in_list (MethodList_t list, SEL op)
       /* Search the method list.  */
       for (i = 0; i < method_list->method_count; ++i)
         {
-          Method_t method = &method_list->method_list[i];
+          struct objc_method * method = &method_list->method_list[i];
 
           if (method->method_name)
             if (method->method_name->sel_id == op->sel_id)