From: <cod...@go...> - 2008-12-05 22:40:48
|
Author: jam...@us... Date: Fri Dec 5 13:29:52 2008 New Revision: 358 Added: branches/objc2/hoc/HOC_cbits/Ivars.h branches/objc2/hoc/HOC_cbits/Ivars.m Modified: branches/objc2/hoc/HOC/HOC/ExportClass.hs branches/objc2/hoc/HOC/HOC/NewClass.hs branches/objc2/hoc/HOC_cbits/Exceptions.m branches/objc2/hoc/HOC_cbits/NewClass.h branches/objc2/hoc/HOC_cbits/NewClass.m Log: Rough cut at separation of ivar lists in HOC from objc_ivar and objc_ivar_list structs. Modified: branches/objc2/hoc/HOC/HOC/ExportClass.hs ============================================================================== --- branches/objc2/hoc/HOC/HOC/ExportClass.hs (original) +++ branches/objc2/hoc/HOC/HOC/ExportClass.hs Fri Dec 5 13:29:52 2008 @@ -138,7 +138,7 @@ $(fillMethodList False 3 [|imethods|] instanceMethods) $(fillMethodList True 0 [|cmethods|] classMethods) clsname <- newCString name - newClass super clsname defaultIvarSize ivars imethods cmethods + newClass super clsname ivars imethods cmethods |] where typedInitIvars = [|initializeInstanceVariables|] Modified: branches/objc2/hoc/HOC/HOC/NewClass.hs ============================================================================== --- branches/objc2/hoc/HOC/HOC/NewClass.hs (original) +++ branches/objc2/hoc/HOC/HOC/NewClass.hs Fri Dec 5 13:29:52 2008 @@ -22,20 +22,29 @@ import HOC.Class import Foreign.C.String +import Foreign.C.Types import Foreign type IMP = FFICif -> Ptr () -> Ptr (Ptr ()) -> IO (Ptr ObjCObject) foreign import ccall "wrapper" wrapIMP :: IMP -> IO (FunPtr IMP) newtype MethodList = MethodList (Ptr MethodList) -newtype IvarList = IvarList (Ptr IvarList) +newtype IvarList = IvarList (ForeignPtr IvarList) foreign import ccall "NewClass.h newClass" - newClass :: Ptr ObjCObject -> CString - -> Int -> IvarList + c_newClass :: Ptr ObjCObject -> CString + -> Ptr IvarList -> MethodList -> MethodList -> IO () +newClass :: Ptr ObjCObject -> CString + -> IvarList + -> MethodList -> MethodList + -> IO () +newClass sc name (IvarList ivars) ms cms = + withForeignPtr ivars $ \ivars -> do + c_newClass sc name ivars ms cms + foreign import ccall "NewClass.h makeMethodList" makeMethodList :: Int -> IO MethodList foreign import ccall "NewClass.h setMethodInList" @@ -46,10 +55,22 @@ foreign import ccall "NewClass.h makeIvarList" - makeIvarList :: Int -> IO IvarList + c_makeIvarList :: Int -> IO (Ptr IvarList) foreign import ccall "NewClass.h setIvarInList" - setIvarInList :: IvarList -> Int - -> CString -> CString -> Int -> IO () + c_setIvarInList :: Ptr IvarList -> Int + -> CString -> CString -> CSize -> Word8 -> IO () + +makeIvarList :: Int -> IO IvarList +makeIvarList n = do + ivars <- c_makeIvarList n + ivars <- newForeignPtr freePtr ivars + return (IvarList ivars) + +setIvarInList:: IvarList -> Int + -> CString -> CString -> CSize -> Word8 -> IO () +setIvarInList (IvarList ivars) n name ty sz align = + withForeignPtr ivars $ \ivars -> do + c_setIvarInList ivars n name ty sz align setMethodInList methodList idx sel typ cif imp = do typC <- newCString typ @@ -60,7 +81,9 @@ list <- makeIvarList 1 name <- newCString "__retained_haskell_part__" typ <- newCString "^v" - setIvarInList list 0 name typ 0 + setIvarInList list 0 name typ + (fromIntegral $ sizeOf nullPtr) + (fromIntegral $ alignment nullPtr) return list defaultIvarSize = 4 :: Int Modified: branches/objc2/hoc/HOC_cbits/Exceptions.m ============================================================================== --- branches/objc2/hoc/HOC_cbits/Exceptions.m (original) +++ branches/objc2/hoc/HOC_cbits/Exceptions.m Fri Dec 5 13:29:52 2008 @@ -1,10 +1,14 @@ #include <objc/objc.h> #include "NewClass.h" #include "Class.h" +#include "Ivars.h" #include "Selector.h" #include "Marshalling.h" #include "HsFFI.h" +#define hsExceptionClassName "HOCHaskellException" +#define hsExceptionIvarName "_haskellException" + static BOOL excWrapperInited = NO; static int stablePtrOffset; static id clsHOCHaskellException; @@ -37,7 +41,8 @@ { struct objc_method_list *methods = makeMethodList(1); struct objc_method_list *class_methods = makeMethodList(0); - struct objc_ivar_list *ivars = makeIvarList(1); + struct hoc_ivar_list *ivars = makeIvarList(1); + struct objc_ivar *stablePtrIvar; selDealloc = getSelectorForName("dealloc"); @@ -49,16 +54,17 @@ methods->method_list[0].method_types = "v@:"; methods->method_list[0].method_imp = (IMP) &exc_dealloc; - setIvarInList(ivars, 0, "_haskellExecption", "^v", 0); + setIvarInList(ivars, 0, hsExceptionIvarName, "^v", sizeof(void *), IVAR_PTR_ALIGN); newClass(getClassByName("NSException"), - "HOCHaskellException", - sizeof(void*), + hsExceptionClassName, ivars, methods, class_methods); clsHOCHaskellException = getClassByName("HOCHaskellException"); - stablePtrOffset = ivars->ivar_list[0].ivar_offset; + stablePtrIvar = class_getInstanceVariable(clsHOCHaskellException, hsExceptionIvarName); + #warning TODO - ivar_getOffset needs backport or workaround for fact that offsets are no longer in the list + stablePtrOffset = ivar_getOffset(stablePtrIvar); selExceptionWithNameReasonUserInfo = getSelectorForName("exceptionWithName:reason:userInfo:"); Added: branches/objc2/hoc/HOC_cbits/Ivars.h ============================================================================== --- (empty file) +++ branches/objc2/hoc/HOC_cbits/Ivars.h Fri Dec 5 13:29:52 2008 @@ -0,0 +1,35 @@ +#include <stdlib.h> +#include <stdint.h> + +struct hoc_ivar { + char *ivar_name; + char *ivar_types; + size_t ivar_size; + uint8_t ivar_alignment; +}; + +#define IVAR_PTR_ALIGN ((uint8_t) sizeof(void *)) + +struct hoc_ivar_list { + int ivar_count; + + /* variable length structure */ + struct hoc_ivar ivar_list[1]; +}; + +struct hoc_ivar_list * makeIvarList(int n); + +void setIvarInList( + struct hoc_ivar_list *list, + int i, + char *name, /* never deallocate this */ + char *types, /* never deallocate this */ + size_t size, + uint8_t alignment + ); + +struct objc_ivar_list * buildIndexedIvarList( + struct hoc_ivar_list *list, + int start_offset, + int *instance_size /* out */ + ); Added: branches/objc2/hoc/HOC_cbits/Ivars.m ============================================================================== --- (empty file) +++ branches/objc2/hoc/HOC_cbits/Ivars.m Fri Dec 5 13:29:52 2008 @@ -0,0 +1,90 @@ +#ifdef GNUSTEP +#include <objc/objc-api.h> +#else +#include <objc/objc-runtime.h> +#endif + +#include <stdlib.h> +#include <assert.h> + +#include "Ivars.h" + +struct hoc_ivar_list * makeIvarList(int n) +{ + struct hoc_ivar_list *list = + calloc(1, sizeof(struct hoc_ivar_list) + + (n-1) * sizeof(struct hoc_ivar)); + list->ivar_count = n; + return list; +} + +void setIvarInList( + struct hoc_ivar_list *list, + int i, + char *name, + char *types, + size_t size, + uint8_t alignment + ) +{ + list->ivar_list[i].ivar_name = name; + list->ivar_list[i].ivar_types = types; + list->ivar_list[i].ivar_size = size; + list->ivar_list[i].ivar_alignment = alignment; +} + +/* Used to be makeIvarList in NewClass.m */ +struct objc_ivar_list * makeIndexedIvarList(int n) +{ + struct objc_ivar_list *list = + calloc(1, sizeof(struct objc_ivar_list) + + (n-1) * sizeof(struct objc_ivar)); + list->ivar_count = n; + return list; +} + +/* Used to be setIvarInList in NewClass.m */ +void setIvarInIndexedList( + struct objc_ivar_list *list, + int i, + char *name, + char *type, + int offset + ) +{ + list->ivar_list[i].ivar_name = name; + list->ivar_list[i].ivar_type = type; + list->ivar_list[i].ivar_offset = offset; +} + +#warning TODO - proofread buildIndexedIvarList +struct objc_ivar_list * buildIndexedIvarList( + struct hoc_ivar_list *list, + int start_offset, + int *instance_size /* out */ + ) +{ + struct objc_ivar_list * outList = makeIndexedIvarList(list->ivar_count); + int offset = start_offset; + int i; + + for (i = 0; i < list->ivar_count; i++) + { + struct hoc_ivar *ivar = &list->ivar_list[i]; + + int align = ivar->ivar_alignment; + int alignmask = align - 1; + + assert((align & alignmask) == 0); + if ((offset & alignmask) != 0) + offset = (offset & ~alignmask) + align; + + setIvarInIndexedList(outList, i, ivar->ivar_name, ivar->ivar_types, offset); + + offset += ivar->ivar_size; + } + + *instance_size = offset - start_offset; + return outList; +} + Modified: branches/objc2/hoc/HOC_cbits/NewClass.h ============================================================================== --- branches/objc2/hoc/HOC_cbits/NewClass.h (original) +++ branches/objc2/hoc/HOC_cbits/NewClass.h Fri Dec 5 13:29:52 2008 @@ -12,10 +12,11 @@ typedef void NSException; #endif +struct hoc_ivar_list; + void newClass(struct objc_class * super_class, const char * name, /* never deallocate this */ - int instance_size, - struct objc_ivar_list *ivars, /* never deallocate this */ + struct hoc_ivar_list *ivars, struct objc_method_list *methods, /* never deallocate this */ struct objc_method_list *class_methods); /* never deallocate this */ @@ -33,13 +34,4 @@ char *types, /* never deallocate this */ ffi_cif *cif, /* never deallocate this */ haskellIMP imp - ); - -struct objc_ivar_list * makeIvarList(int n); -void setIvarInList( - struct objc_ivar_list *list, - int i, - char *name, /* never deallocate this */ - char *type, /* never deallocate this */ - int offset ); Modified: branches/objc2/hoc/HOC_cbits/NewClass.m ============================================================================== --- branches/objc2/hoc/HOC_cbits/NewClass.m (original) +++ branches/objc2/hoc/HOC_cbits/NewClass.m Fri Dec 5 13:29:52 2008 @@ -2,6 +2,7 @@ #include <Foundation/NSException.h> #include <assert.h> #include "Class.h" +#include "Ivars.h" #include "NewClass.h" #include "Statistics.h" @@ -26,8 +27,7 @@ void newClass(struct objc_class * super_class, const char * name, - int instance_size, - struct objc_ivar_list *ivars, + struct hoc_ivar_list *ivars, struct objc_method_list *methods, struct objc_method_list *class_methods) { @@ -53,12 +53,13 @@ new_class->name = name; meta_class->name = name; - new_class->instance_size = super_class->instance_size + instance_size; - for(i=0; i<ivars->ivar_count; i++) - ivars->ivar_list[i].ivar_offset += super_class->instance_size; - - new_class->ivars = ivars; - + new_class->ivars = buildIndexedIvarList( + ivars, + super_class->instance_size, + &new_class->instance_size); + + new_class->instance_size += super_class->instance_size; + #ifdef GNUSTEP new_class->super_class = (void*)(super_class->name); meta_class->super_class = (void*)(super_class->isa->name); @@ -142,26 +143,4 @@ #endif list->method_list[i].method_types = types; list->method_list[i].method_imp = (IMP) newIMP(cif, imp); -} - -struct objc_ivar_list * makeIvarList(int n) -{ - struct objc_ivar_list *list = - calloc(1, sizeof(struct objc_ivar_list) - + (n-1) * sizeof(struct objc_ivar)); - list->ivar_count = n; - return list; -} - -void setIvarInList( - struct objc_ivar_list *list, - int i, - char *name, - char *type, - int offset - ) -{ - list->ivar_list[i].ivar_name = name; - list->ivar_list[i].ivar_type = type; - list->ivar_list[i].ivar_offset = offset; } |