summaryrefslogtreecommitdiff
path: root/Objective-C/JIGS
diff options
context:
space:
mode:
Diffstat (limited to 'Objective-C/JIGS')
-rw-r--r--Objective-C/JIGS/ObjcRuntimeUtilities.c220
-rw-r--r--Objective-C/JIGS/ObjcRuntimeUtilities.h171
-rw-r--r--Objective-C/JIGS/ObjcRuntimeUtilities2.m51
3 files changed, 442 insertions, 0 deletions
diff --git a/Objective-C/JIGS/ObjcRuntimeUtilities.c b/Objective-C/JIGS/ObjcRuntimeUtilities.c
new file mode 100644
index 0000000..9fbb3fc
--- /dev/null
+++ b/Objective-C/JIGS/ObjcRuntimeUtilities.c
@@ -0,0 +1,220 @@
+/* ObjcRuntimeUtilities.m - Utilities to add classes and methods
+ in the Objective-C runtime, at runtime.
+
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+ Written by: Nicola Pero <nicola@brainstorm.co.uk>
+ Date: June 2000
+
+ This file is part of the GNUstep Java Interface Library.
+
+ It was partially derived by:
+
+ --
+ gg_class.m - interface between guile and GNUstep
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
+ Date: September 1998
+
+ This file is part of the GNUstep-Guile Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+ */
+
+/* This file is a C file so that we can declare and use
+ * __objc_exec_class() without conflicting with the declaration and
+ * usage of the ObjC compiler.
+ */
+
+/*
+ * NOTE - OBJC_VERSION needs to be defined to be the version of the
+ * Objective-C runtime you are using. You can find this in the file
+ * 'init.c' in the GNU objective-C runtime source.
+ */
+#define OBJC_VERSION 8
+
+#include "ObjcRuntimeUtilities.h"
+#include <string.h>
+
+#ifndef objc_EXPORT
+#if libobjc_ISDLL /* linking against DLL version of libobjc */
+# define objc_EXPORT extern __declspec(dllimport)
+#else
+# define objc_EXPORT extern
+#endif
+#endif
+
+BOOL ObjcUtilities_new_class (const char *name,
+ const char *superclassName,
+ int ivarNumber, ...)
+{
+ objc_EXPORT void __objc_exec_class (Module_t module);
+ objc_EXPORT void __objc_resolve_class_links ();
+ Module_t module;
+ Symtab_t symtab;
+ Class super_class;
+ Class new_class;
+ int ivarsize;
+
+ //
+ // Check that the name for the new class isn't already in use.
+ //
+ if (objc_lookup_class (name) != Nil)
+ {
+ return NO;
+ }
+
+ //
+ // Check that the superclass exists.
+ //
+ super_class = objc_lookup_class (superclassName);
+ if (super_class == Nil)
+ {
+ return NO;
+ }
+
+ //
+ // Prepare a fake module containing only this class.
+ //
+ module = objc_calloc (1, sizeof (Module));
+ module->version = OBJC_VERSION;
+ module->size = sizeof (Module);
+ module->name = objc_malloc (strlen (name) + 15);
+ strcpy ((char*)module->name, "GNUstep-Proxy-");
+ strcat ((char*)module->name, name);
+ module->symtab = objc_calloc (1, sizeof (Symtab));
+
+ symtab = module->symtab;
+ symtab->sel_ref_cnt = 0;
+ symtab->refs = 0;
+ symtab->cls_def_cnt = 1; // We are defining a single class.
+ symtab->cat_def_cnt = 0; // But no categories
+ // Allocate space for two classes (the class and its meta class)
+ symtab->defs[0] = objc_calloc (2, sizeof (struct objc_class));
+ symtab->defs[1] = 0; // NULL terminate the list.
+
+ //
+ // Build class structure.
+ //
+
+ // Class
+ new_class = (Class)symtab->defs[0];
+
+ // NB: There is a trick here.
+ // The runtime system will look up the name in the following string,
+ // and replace it with a pointer to the actual superclass structure.
+ // This also means the type of pointer will change, that's why we
+ // need to force it with a (void *)
+ new_class->super_class = (void *)superclassName;
+
+ new_class->name = objc_malloc (strlen (name) + 1);
+ strcpy ((char*)new_class->name, name);
+ new_class->version = 0;
+ new_class->info = _CLS_CLASS;
+ ivarsize = super_class->instance_size;
+
+ if (ivarNumber > 0)
+ {
+ // Prepare ivars
+ va_list ap;
+ struct objc_ivar *ivar;
+ int size, i;
+
+ size = sizeof (struct objc_ivar_list);
+ size += (ivarNumber - 1) * sizeof (struct objc_ivar);
+
+ new_class->ivars = (struct objc_ivar_list*) objc_malloc (size);
+ new_class->ivars->ivar_count = ivarNumber;
+
+ va_start (ap, ivarNumber);
+
+ ivar = new_class->ivars->ivar_list;
+
+ for (i = 0; i < ivarNumber; i++)
+ {
+ char *name = strdup (va_arg (ap, char *));
+ char *type = strdup (va_arg (ap, char *));
+
+ int align;
+
+ ivar->ivar_name = name;
+ ivar->ivar_type = type;
+
+ align = objc_alignof_type (ivar->ivar_type); // pad to alignment
+ ivarsize = align * ((ivarsize + align - 1) /align); // ROUND
+ ivar->ivar_offset = ivarsize;
+ ivarsize += objc_sizeof_type (ivar->ivar_type);
+ ivar++;
+ }
+ va_end (ap);
+ }
+
+ new_class->instance_size = ivarsize;
+
+ // Meta class
+ new_class->class_pointer = &new_class[1];
+ new_class->class_pointer->super_class = (void *)superclassName;
+ new_class->class_pointer->name = new_class->name;
+ new_class->class_pointer->version = 0;
+ new_class->class_pointer->info = _CLS_META;
+ new_class->class_pointer->instance_size
+ = super_class->class_pointer->instance_size;
+
+ // Insert our new class into the runtime.
+ __objc_exec_class (module);
+ __objc_resolve_class_links();
+
+ return YES;
+}
+
+MethodList *ObjcUtilities_alloc_method_list (int count)
+{
+ MethodList *ml;
+ int extra;
+
+ extra = (sizeof (struct objc_method)) * (count - 1);
+ ml = objc_calloc (1, sizeof(MethodList) + extra);
+ ml->method_count = count;
+ return ml;
+}
+
+void ObjcUtilities_insert_method_in_list (MethodList *ml,
+ int index, const char *name,
+ const char *types, IMP imp)
+{
+ Method *method;
+
+ method = &(ml->method_list[index]);
+ method->method_name = (void *)strdup (name);
+ method->method_types = strdup (types);
+ method->method_imp = imp;
+}
+
+void ObjcUtilities_register_method_list (Class class, MethodList *ml)
+{
+ objc_EXPORT void class_add_method_list (Class class, MethodList_t list);
+ objc_EXPORT objc_mutex_t __objc_runtime_mutex;
+
+ objc_mutex_lock (__objc_runtime_mutex);
+ class_add_method_list (class, ml);
+ objc_mutex_unlock (__objc_runtime_mutex);
+}
+
+
+
+
+
+
diff --git a/Objective-C/JIGS/ObjcRuntimeUtilities.h b/Objective-C/JIGS/ObjcRuntimeUtilities.h
new file mode 100644
index 0000000..563a43d
--- /dev/null
+++ b/Objective-C/JIGS/ObjcRuntimeUtilities.h
@@ -0,0 +1,171 @@
+/* ObjcRuntimeUtilities.h - Utilities to add classes and methods
+ in the Objective-C runtime, at runtime.
+
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+ Written by: Nicola Pero <nicola@brainstorm.co.uk>
+ Date: June 2000
+
+ This file is part of the GNUstep Java Interface Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+ */
+
+#ifndef __ObjcRuntimeUtilities_h_GNUSTEP_JAVA_INCLUDE
+#define __ObjcRuntimeUtilities_h_GNUSTEP_JAVA_INCLUDE
+
+#include <objc/objc-api.h>
+#include <objc/thr.h>
+#include <objc/encoding.h>
+
+/*
+ * This code is by no means tidied to Java.
+
+ * It provides facilities to programmatically add classes and methods
+ * to the objc runtime, while the runtime is already running.
+
+ * It could be reused for building interfaces to other languages.
+
+ * At present this code only works with the GNU Objective-C Runtime,
+ * because we need to access the runtime internal structures to add
+ * classes and methods.
+ */
+
+/*
+
+ Creating a new class
+
+ */
+
+/*
+ * ObjcUtilities_new_class:
+ *
+ * Create a new Objective-C class called name, inheriting from
+ * superClass.
+
+ * If ivarNumber is zero, the new class has not any more instance
+ * variables than the class it inherits from.
+
+ * Otherwise, appropriate optional arguments should be provided; they
+ * should come in couples; the first one is the ivar name, the second
+ * one the ivar type. For example:
+ * ObjcUtilities_new_class ("MyNiceClass", "NSObject", 2,
+ * "aJavaObject", @encode (jobject),
+ * "tag", @encode (int));
+ * creates a class as it would be created by
+ *
+ * @interface MyNiceClass : NSObject
+ * {
+ * jobject aJavaObject;
+ * int tag;
+ * }
+ * @end
+
+ * Return NO upon failure (because the class already exists or the
+ * superclass does not exist), and YES upon success.
+
+ */
+
+BOOL ObjcUtilities_new_class (const char *name, const char *superclassName,
+ int ivarNumber, ...);
+
+/*
+
+ Adding new methods to a class
+
+ Quick HOWTO:
+ A. alloc a MethodList using ObjcUtilities_alloc_method_list.
+ B. insert the methods you want to register in the MethodList using
+ ObjcUtilities_insert_method_in_list.
+ To get the objective-C runtime type for a method, you may want to use
+ ObjcUtilities_build_runtime_Objc_signature
+ C. register your method list with the objective-C runtime using
+ ObjcUtilities_register_method_list.
+ */
+
+/*
+ * ObjcUtilities_alloc_method_list:
+ *
+ * Allocate a MethodList capable of containing `count' methods.
+ * A pointer to the allocated list is returned.
+ *
+ */
+
+MethodList *ObjcUtilities_alloc_method_list (int count);
+
+/*
+ * ObjcUtilities_insert_method_in_list:
+ *
+ * Insert a method definition in a MethodList. `ml' is a pointer to
+ * the MethodList. `index' is the index of the method to add. `name'
+ * is the name of the method; `types' is the objective-C run-time
+ * signature of the method (see below for a facility to create this
+ * automatically), `imp' is the IMP (ie, the actual implementation of
+ * the method). `imp' must be a pointer to a function taking the
+ * correct arguments and returning the correct type; cast it to an IMP
+ * then before calling this function.
+ */
+
+void ObjcUtilities_insert_method_in_list (MethodList *ml,
+ int index, const char *name,
+ const char *types, IMP imp);
+
+/*
+ * ObjcUtilities_build_runtime_Objc_signature:
+ *
+ * This method creates a runtime objc signature which can be used
+ * to describe type for a selector *on this machine* (you need this
+ * signature for example to insert a method description in a method list,
+ * using the ObjcUtilities_insert_method_in_list function above).
+ *
+ * It takes as argument a 'naive' objc signature, in the form of
+ * a string obtained by concatenating the following strings:
+ *
+ * @encode(return_type)
+ *
+ * @encode(Class) if it's a class method, or @encode(id) if it's an
+ * instance method (corresponding to the first hidden argument, self)
+ *
+ * @encode(SEL) (corresponding to the second hidden argument, the selector)
+ *
+ * @encode(arg1) @encode(arg2) ... if there are any real arguments.
+ *
+ * An example is:
+ * "i@:@" for an instance method returning int and taking an object arg.
+ * (NB: "i" = @encode(int), "@" = @encode(id), ":" = @encode(SEL)).
+ *
+ * On my machine, ObjcUtilities_build_runtime_Objc_signature ("i@:@")
+ * returns "i12@0:4@8", which I can then use as selector type when
+ * creating entries in MethodList.
+ *
+ */
+
+const char *ObjcUtilities_build_runtime_Objc_signature (const char *);
+
+/*
+ * ObjcUtilities_register_method_list:
+ *
+ * Add the list `ml' of methods to an existing Class `class'.
+ * They are registered as instance methods.
+ * To add class methods, you simply need to pass the meta class
+ * [(Class)class->class_pointer] instead of the class.
+ *
+ * *Never* release or modify a method list after registering it with
+ * *the objective-C runtime.
+ */
+
+void ObjcUtilities_register_method_list (Class class, MethodList *ml);
+
+#endif /* __ObjcRuntimeUtilitis_h_GNUSTEP_JAVA_INCLUDE */
diff --git a/Objective-C/JIGS/ObjcRuntimeUtilities2.m b/Objective-C/JIGS/ObjcRuntimeUtilities2.m
new file mode 100644
index 0000000..986600a
--- /dev/null
+++ b/Objective-C/JIGS/ObjcRuntimeUtilities2.m
@@ -0,0 +1,51 @@
+/* ObjcRuntimeUtilities2.m - Utilities to add classes and methods
+ in the Objective-C runtime, at runtime; ObjC code.
+
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+ Written by: Nicola Pero <nicola@brainstorm.co.uk>
+ Date: June 2000
+
+ This file is part of the GNUstep Java Interface Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+*/
+
+/* This file contains the only function of ObjCRuntimeUtilites which must
+ * be compiled using the Objective-C compiler.
+ */
+
+#include <Foundation/Foundation.h>
+
+const char *ObjcUtilities_build_runtime_Objc_signature (const char
+ *types)
+{
+ NSMethodSignature *sig;
+
+ sig = [NSMethodSignature signatureWithObjCTypes: types];
+
+#if defined GNUSTEP_BASE_VERSION || defined(LIB_FOUNDATION_LIBRARY)
+ return [sig methodType];
+#else
+# error "Don't know how to get method signature on this platform!"
+#endif
+}
+
+
+
+
+
+
+