diff options
-rw-r--r-- | Objective-C/GNUmakefile | 4 | ||||
-rw-r--r-- | Objective-C/JIGS/ObjcRuntimeUtilities.c | 220 | ||||
-rw-r--r-- | Objective-C/JIGS/ObjcRuntimeUtilities.h | 171 | ||||
-rw-r--r-- | Objective-C/JIGS/ObjcRuntimeUtilities2.m | 51 |
4 files changed, 445 insertions, 1 deletions
diff --git a/Objective-C/GNUmakefile b/Objective-C/GNUmakefile index 7401667..d97998b 100644 --- a/Objective-C/GNUmakefile +++ b/Objective-C/GNUmakefile @@ -33,7 +33,8 @@ LIBRARY_NAME = libobjcl RPM_DISABLE_RELOCATABLE = YES ADDITIONAL_OBJCFLAGS = -Wall -g -DVERSION=\"$(VERSION)\" -I/usr/local/include -libobjcl_OBJC_FILES = libobjcl.m PyObjC/objc_support.m PyObjC/objc-runtime-apple.m PyObjC/objc-runtime-gnu.m +libobjcl_OBJC_FILES = JIGS/ObjcRuntimeUtilities2.m libobjcl.m PyObjC/objc_support.m PyObjC/objc-runtime-apple.m PyObjC/objc-runtime-gnu.m +libobjcl_C_FILES = JIGS/ObjcRuntimeUtilities.c LIBRARIES_DEPEND_UPON = $(FND_LIBS) $(GUI_LIBS) $(OBJC_LIBS) $(SYSTEM_LIBS) $(CONFIG_SYSTEM_LIBS) ADDITIONAL_LDFLAGS = $(LIBS) @@ -57,6 +58,7 @@ ifneq ($(COMMON_MAKE_LOADED),) before-all:: $(FFI_DEPS) mkdir -p $(GNUSTEP_OBJ_DIR)/PyObjC + mkdir -p $(GNUSTEP_OBJ_DIR)/JIGS after-clean:: $(FFI_CLEAN) 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 +} + + + + + + + |