|
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;
}
|