Support rastport clipping rectangle for layerless rastports
[tangerine.git] / rom / oop / metaclass.c
blob0f06179a6781d7865de7b8b3f28d62f95b35ddc9
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: OOP metaclass
6 Lang: english
7 */
9 #include <proto/exec.h>
10 #include <proto/utility.h>
11 #include <exec/memory.h>
13 #include <proto/oop.h>
14 #include <oop/oop.h>
16 #include "intern.h"
17 #include "hash.h"
18 #include "private.h"
20 #undef SDEBUG
21 #undef DEBUG
22 #define SDEBUG 0
23 #define DEBUG 0
24 #include <aros/debug.h>
26 #define MD(cl) ((struct metadata *)cl)
27 #define IFI(cl) ((struct ifmeta_inst *)cl)
29 # define IntCallMethod(cl, o, msg) \
30 { \
31 register struct IFBucket *b; \
32 register OOP_MethodID mid = *msg; \
33 register ULONG ifid = mid & (~METHOD_MASK); \
34 register struct IFMethod *method; \
36 mid &= METHOD_MASK; \
38 b = IFI(cl)->data.iftab_directptr[ifid & IFI(cl)->data.hashmask]; \
39 while (b) \
40 { \
41 if (b->InterfaceID == ifid) \
42 { \
43 method = &(b->MethodTable[mid]); \
44 return (method->MethodFunc(method->mClass, o, msg)); \
45 } \
46 b = b->Next; \
47 } \
48 return (0UL); \
53 #define UB(x) ((UBYTE *)x)
55 /* Allocates and initializes the interface hashtable, and the methodtables */
56 static BOOL ifmeta_allocdisptabs(OOP_Class *cl, OOP_Object *o, struct P_meta_allocdisptabs *msg);
57 static VOID ifmeta_freedisptabs(OOP_Class *cl, OOP_Object *o, OOP_Msg msg);
59 static IPTR Meta_DoMethod(OOP_Object *o, OOP_Msg msg);
60 static IPTR Meta_CoerceMethod(OOP_Class *cl, OOP_Object *o, OOP_Msg msg);
61 static IPTR Meta_DoSuperMethod(OOP_Class *cl, OOP_Object *o, OOP_Msg msg);
63 /* Hooks */
64 VOID freebucket(struct Bucket *b, struct IntOOPBase *OOPBase);
65 struct Bucket *copybucket(struct Bucket *old_b, APTR data, struct IntOOPBase *OOPBase);
67 /* Internal */
68 static struct IFBucket *createbucket(
69 STRPTR interface_id
70 ,ULONG num_methods
71 ,struct IntOOPBase *OOPBase);
73 static ULONG calc_ht_entries(struct ifmeta_inst *cl
74 ,OOP_Class *super
75 ,struct OOP_InterfaceDescr *ifDescr
76 ,struct IntOOPBase *OOPBase);
81 The metaclass is used to create class. That means,
82 classes are instances of the meta class.
83 The meta class is itself both a class (you can
84 create instances of it), and an object (you can invoke
85 methods on it.
86 */
89 #define OOPBase (GetOBase(cl->OOPBasePtr))
91 /********************
92 ** IFMeta::New() **
93 ********************/
94 static OOP_Object *ifmeta_new(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
97 IPTR (*domethod)(OOP_Object *, OOP_Msg) = NULL;
98 IPTR (*coercemethod)(OOP_Class *, OOP_Object *, OOP_Msg) = NULL;
99 IPTR (*dosupermethod)(OOP_Class *, OOP_Object *, OOP_Msg) = NULL;
101 EnterFunc(bug("IFMeta::New(cl=%s, msg = %p)\n",
102 cl->ClassNode.ln_Name, msg));
104 /* Let the BaseMeta class initialize some stuff for us */
105 o = (OOP_Object *)OOP_DoSuperMethod((OOP_Class *)cl, o, (OOP_Msg)msg);
106 if (o)
109 struct ifmeta_inst *inst;
111 inst = (struct ifmeta_inst *)o;
113 domethod = (IPTR (*)())GetTagData(aMeta_DoMethod, NULL, msg->attrList);
114 coercemethod = (IPTR (*)())GetTagData(aMeta_CoerceMethod, NULL, msg->attrList);
115 dosupermethod = (IPTR (*)())GetTagData(aMeta_DoSuperMethod, NULL, msg->attrList);
118 D(bug("Instance allocated %p\n", inst));
121 if (!domethod)
122 domethod = Meta_DoMethod;
124 if (!coercemethod)
125 coercemethod = Meta_CoerceMethod;
127 if (!dosupermethod)
130 OOP_Class *superptr = inst->base.superclass;
131 if (superptr)
133 D(bug("Got superptr: %p\n", superptr));
134 /* Use superclass' DoSupermethod call if superclass isn't
135 an instance of the HIDDMetaClass
137 if (OOP_OCLASS(superptr) != (OOP_Class *)cl)
139 D(bug("superptr has different meta\n"));
141 dosupermethod = superptr->cl_DoSuperMethod;
143 else
145 D(bug("superptr has same meta\n"));
147 dosupermethod = Meta_DoSuperMethod;
151 else /* if (class has no superclass) */
153 dosupermethod = NULL;
158 inst->base.public.OOPBasePtr = (struct IntOOPBase *)OOPBase;
160 inst->base.public.cl_DoMethod = domethod;
161 inst->base.public.cl_CoerceMethod = coercemethod;
162 inst->base.public.cl_DoSuperMethod = dosupermethod;
164 D(bug("Classes' functions set\n"));
167 ReturnPtr ("IFMeta::New", OOP_Object *, o);
170 /******************************
171 ** IFMeta::allocdisptabs() **
172 ******************************/
174 /* Allocates and initializes the interface hashtable, and the methodtables */
175 static BOOL ifmeta_allocdisptabs(OOP_Class *cl, OOP_Object *o, struct P_meta_allocdisptabs *msg)
177 ULONG num_if;
179 struct ifmeta_inst *inst = (struct ifmeta_inst *)o;
181 EnterFunc(bug("IFMeta::allocdisptabs(cl=%p, o=%p,ifDescr=%p)\n",
182 cl, o, msg->ifdescr));
184 /* Get number of needed hash entries */
185 num_if = calc_ht_entries(inst, msg->superclass, msg->ifdescr, OOPBase);
187 inst->base.numinterfaces = num_if;
189 D(bug("numinterfaces set to %ld\n", num_if));
191 /* Create a new integer hashtable, with a reasonable size */
192 inst->data.iftable = NewHash(num_if, HT_INTEGER, OOPBase);
193 if (inst->data.iftable)
195 struct OOP_InterfaceDescr *ifdescr;
196 D(bug("Got iftable\n"));
197 /* Save hashmask for use in method lookup */
198 inst->data.hashmask = HashMask(inst->data.iftable);
200 if (msg->superclass) /* This test makes it work for initializing root classes */
203 /* Copy parent interfaces into the new class */
204 struct IFMethod *superif;
205 struct P_meta_iterateifs ii_msg;
206 STRPTR interface_id;
207 ULONG num_methods;
209 /* must be initialized to zero */
210 IPTR iterval = 0UL;
212 D(bug("Adding superclass' methods\n"));
214 ii_msg.mid = OOP_GetMethodID(IID_Meta, MO_meta_iterateifs);
216 ii_msg.iterval_ptr = &iterval;
217 ii_msg.interface_id_ptr = &interface_id;
218 ii_msg.num_methods_ptr = &num_methods;
221 for (;;)
223 struct IFBucket *ifb;
224 struct IFMethod *ifm = NULL;
225 ULONG mtab_size;
227 superif = (struct IFMethod *)OOP_CoerceMethod(OOP_OCLASS(msg->superclass)
228 ,(OOP_Object *)msg->superclass
229 ,(OOP_Msg)&ii_msg);
230 if (!superif)
231 break;
233 /* Allocate and insert the interface into the new class */
234 ifb = createbucket(interface_id, num_methods, OOPBase);
235 D(bug("Created bucket: %p\n", ifb));
236 if (!ifb)
237 goto failure;
239 /* Copy the interface */
240 mtab_size = UB (&ifm[num_methods]) - UB( &ifm[0]);
241 D(bug("Copying from superclass methods for if %s, mtab_size=%d,basmetaroot %p, superif %p\n",
242 ifb->GlobalInterfaceID, mtab_size, OOPBase->ob_BaseMetaObject.inst.rootif, superif));
244 CopyMem(superif, ifb->MethodTable, mtab_size);
245 InsertBucket(inst->data.iftable, (struct Bucket *)ifb, OOPBase);
247 } /* for (;;) */
249 } /* if (we inherit interfaces from some superclass) */
251 /* Insert our own interfaces */
252 D(bug("Inserting own methods\n"));
253 for ( ifdescr = msg->ifdescr; ifdescr->MethodTable; ifdescr ++)
255 struct IFBucket *ifb;
256 ULONG i;
258 ULONG iid;
259 /* Get variable interface ID */
261 D(bug("Getting Local ifID for global ID %s\n", ifdescr->InterfaceID));
262 if (!init_mi_methodbase(ifdescr->InterfaceID, &iid, OOPBase))
263 goto failure;
265 D(bug("Got local ifID %ld\n", iid));
267 /* Lookup hashtable to see if interface has been copied from superclass */
268 ifb = (struct IFBucket *)inst->data.iftable->Lookup(
269 inst->data.iftable
270 , iid
271 , OOPBase);
273 D(bug("tried to find bucket in hashtable: %p\n", ifb));
274 if (!ifb)
276 D(bug("Bucket doesn't exist, creating..\n"));
277 /* Bucket doesn't exist, allocate it */
278 ifb = createbucket(ifdescr->InterfaceID, ifdescr->NumMethods, OOPBase);
279 if (!ifb)
280 goto failure;
281 else
283 D(bug("Inserting bucket for IF %s\n", ifdescr->InterfaceID));
284 InsertBucket(inst->data.iftable, (struct Bucket *)ifb, OOPBase);
289 D(bug("overriding methods\n"));
291 /* Ovveride the superclass methods with our new ones */
292 for (i = 0; ifdescr->MethodTable[i].MethodFunc; i ++)
294 if (ifdescr->MethodTable[i].MethodFunc)
296 ifb->MethodTable[ ifdescr->MethodTable[i].MethodIdx ].MethodFunc = ifdescr->MethodTable[i].MethodFunc;
297 ifb->MethodTable[ ifdescr->MethodTable[i].MethodIdx ].mClass = (OOP_Class *)o;
299 } /* for (each method in the interface) */
301 } /* for (each interface to add to class) */
303 /* For speedup in method lookup */
304 inst->data.iftab_directptr = (struct IFBucket **)inst->data.iftable->Table;
306 ReturnBool ("IFMeta::allocdisptabs", TRUE);
308 } /* if (interface hash table allocated) */
310 failure:
311 D(bug("FAILURE\n"));
312 if (inst->data.iftable)
313 FreeHash(inst->data.iftable, freebucket, OOPBase);
314 ReturnBool ("IFMeta::allocdisptabs", FALSE);
317 /*****************************
318 ** IFMeta::freedisptabs() **
319 *****************************/
320 static VOID ifmeta_freedisptabs(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
323 struct ifmeta_inst *inst = (struct ifmeta_inst *)o;
324 /* This frees the hashtable + all buckets */
326 FreeHash(inst->data.iftable, freebucket, OOPBase);
328 return;
331 /**************************
332 ** IFMeta::getifinfo() **
333 **************************/
334 static struct IFMethod *ifmeta_getifinfo(OOP_Class *cl, OOP_Object *o, struct P_meta_getifinfo *msg)
336 ULONG iid;
337 struct ifmeta_inst *inst = (struct ifmeta_inst *)o;
338 struct IFMethod *mtab = NULL;
339 struct IFBucket *b;
341 /* Get the ULONG variable interface id */
342 iid = OOP_GetMethodID(msg->interface_id, 0);
344 /* Try looking it up in the class' table */
345 b = (struct IFBucket *)inst->data.iftable->Lookup(inst->data.iftable, iid, OOPBase);
347 *(msg->num_methods_ptr) = b->NumMethods;
349 mtab = b->MethodTable;
352 return mtab;
355 /***************************
356 ** IFMeta::iterateifs() **
357 ***************************/
358 static struct IFMethod *ifmeta_iterateifs(OOP_Class *cl, OOP_Object *o, struct P_meta_iterateifs *msg)
360 struct HashTable *ht = ((struct ifmeta_inst *)o)->data.iftable;
361 struct IFBucket *found_bucket = NULL; /* MUST default to NULL */
363 struct IFBucket *ifb = NULL; /* keep compiler happy */
366 struct IFMethod *current_if = NULL; /* MUST default to NULL */
368 UWORD last_idx = (*(msg->iterval_ptr)) >> 16;
369 UWORD last_bucket_no = (*(msg->iterval_ptr)) & 0x0000FFFF;
371 UWORD idx;
373 UWORD bucket_no = 0; /* keep compiler happy */
374 EnterFunc(bug("IFMeta::iterateifs(cl=%s, o=%s)\n",
375 cl->ClassNode.ln_Name, ((Class *)o)->ClassNode.ln_Name ));
377 D(bug("last_idx: %ld, last_bucket_no=%ld\n", last_idx, last_bucket_no));
380 for (idx = last_idx ;idx < HashSize(ht); idx ++)
382 D(bug("idx=%ld\n", idx));
384 bucket_no = 0;
386 for (ifb = (struct IFBucket *)ht->Table[idx]; ifb; )
388 D(bug("ifb=%s, netx=%p, bucket_no=%ld\n",
389 ifb->GlobalInterfaceID, ifb->Next, bucket_no));
390 /* Is this a new bucket in the iteration ? */
392 if ((idx > last_idx) || (bucket_no >= last_bucket_no))
394 found_bucket = ifb;
396 /* Yes, it's a goto, but it really simplifies things here */
397 goto after_loop;
399 else
401 ifb = ifb->Next;
402 bucket_no ++;
405 } /* for (all buckets at each idx) */
407 } /* for (each entry at east index from last idx) */
409 after_loop:
411 /* OK, found a bucket ? */
412 if (found_bucket)
414 D(bug("bucket found: %s at idx %ld, b_no %ld\n",
415 found_bucket->GlobalInterfaceID, idx, bucket_no));
416 *(msg->iterval_ptr) = (idx << 16) + bucket_no + 1;
417 *(msg->interface_id_ptr) = ifb->GlobalInterfaceID;
418 *(msg->num_methods_ptr) = ifb->NumMethods;
420 current_if = ifb->MethodTable;
423 ReturnPtr ("IFMeta::iterateifs", struct IFMethod *, current_if);
426 /***************************
427 ** IFMeta::findmethod() **
428 ***************************/
430 /* Used for finding a method for method objects */
431 static struct IFMethod *ifmeta_findmethod(OOP_Class *cl, OOP_Object *o, struct P_meta_findmethod *msg)
433 register struct IFBucket *b;
434 register ULONG method_offset;
435 struct ifmeta_inst *inst = (struct ifmeta_inst *)o;
437 /* Get interfaceID part of methodID */
438 register ULONG ifid = msg->method_to_find & (~METHOD_MASK);
440 EnterFunc(bug("IFMeta::findmethod(o=%p, mid=%ld)\n", o, msg->method_to_find));
443 /* Get method offset part of methdoID */
444 method_offset = msg->method_to_find & METHOD_MASK;
446 /* Look up ID in hashtable and get linked list of buckets,
447 storing interfaces
449 b = inst->data.iftab_directptr[ifid & inst->data.hashmask];
450 loop:
451 if (b)
453 /* Found correct interface ? */
454 if (b->InterfaceID == ifid)
456 /* Yep. Return method at supplied method offset */
457 ReturnPtr ("IFMeta::findmethod", struct IFMethod *, &(b->MethodTable[method_offset]));
460 b = b->Next;
461 goto loop;
463 /* Method not found, return NULL */
464 ReturnPtr ("IFMeta::findmethod", struct IFMethod *, NULL);
468 #undef OOPBase
470 /**********
471 Support
472 **********/
474 /*************************
475 ** init_ifmetaclass() **
476 *************************/
478 #define NUM_META_METHODS 5
479 #define NUM_ROOT_METHODS 1
480 BOOL init_ifmetaclass(struct IntOOPBase *OOPBase)
482 struct OOP_MethodDescr root_mdescr[NUM_ROOT_METHODS + 1]=
484 { (IPTR (*)())ifmeta_new, moRoot_New },
485 { NULL, 0UL }
488 struct OOP_MethodDescr meta_mdescr[NUM_META_METHODS + 1]=
490 { (IPTR (*)())ifmeta_allocdisptabs, MO_meta_allocdisptabs },
491 { (IPTR (*)())ifmeta_freedisptabs, MO_meta_freedisptabs },
492 { (IPTR (*)())ifmeta_getifinfo, MO_meta_getifinfo },
493 { (IPTR (*)())ifmeta_iterateifs, MO_meta_iterateifs },
494 { (IPTR (*)())ifmeta_findmethod, MO_meta_findmethod },
495 { NULL, 0UL }
499 struct OOP_InterfaceDescr meta_descr[] =
501 {root_mdescr, IID_Root, 1},
502 {meta_mdescr, IID_Meta, NUM_META_METHODS},
503 {NULL, NULL, 0UL}
506 struct ifmetaobject *imo = &(OOPBase->ob_IFMetaObject);
507 struct P_meta_allocdisptabs adt_msg;
508 OOP_Class *ifmeta_cl;
510 EnterFunc(bug("init_ifmetaclass()\n"));
512 ifmeta_cl = &(imo->inst.base.public);
514 D(bug("Got ifmeta classptr\n"));
516 imo->inst.base.superclass = BASEMETAPTR;
517 imo->inst.base.public.OOPBasePtr = (struct OOPBase *)OOPBase;
519 D(bug("Initialized ifmeta superclass\n"));
521 adt_msg.superclass = imo->inst.base.superclass;
522 adt_msg.ifdescr = meta_descr;
524 /* allocdisptabs() must know the OOPBase */
525 imo->inst.base.public.UserData = (APTR)OOPBase;
526 /* It must also have a valid DoSuperMethod(), more exatly
527 the DoSuperMethod() of the BaseMeta class
529 imo->inst.base.public.cl_DoSuperMethod = BASEMETAPTR->cl_DoSuperMethod;
532 D(bug("Allocating ifmeta disptabs\n"));
535 if (ifmeta_allocdisptabs(ifmeta_cl, (OOP_Object *)ifmeta_cl, &adt_msg))
537 D(bug("ifmeta disptabs allocated\n"));
538 /* initialize Class ID */
540 imo->inst.base.public.ClassNode.ln_Name = CLID_MIMeta;
541 imo->inst.base.public.InstOffset = sizeof (struct metadata);
543 D(bug("IFMeta DoMethod=%p\n", Meta_DoMethod));
544 imo->inst.base.public.cl_DoMethod = Meta_DoMethod;
545 imo->inst.base.public.cl_CoerceMethod = Meta_CoerceMethod;
547 imo->inst.base.instsize = sizeof (struct ifmeta_data);
548 imo->inst.base.subclasscount = 0UL;
549 imo->inst.base.objectcount = 0UL;
551 imo->inst.data.numinterfaces = 2UL;
553 /* This class' class is itself */
554 imo->oclass = &(imo->inst.base.public);
556 /* {
557 ULONG i;
558 D(bug("Trying to call get_if_info on ifmeta many times\n"));
559 for (i = 0; i < 10; i ++)
561 ULONG num_methods;
562 meta_getifinfo((OOP_Object *)imo->oclass, IID_Meta, &num_methods);
564 D(bug("IF has %ld methods\n", num_methods));
568 */ /* Make it public */
569 OOP_AddClass(ifmeta_cl);
570 ReturnBool ("init_metaclass", TRUE);
572 ReturnBool ("init_ifmetaclass", FALSE);
577 /************************
578 ** calc_ht_entries() **
579 ************************/
581 /* Calculates the number of interfaces the new class has
582 ( == number of buckets in the hashtable)
584 static ULONG calc_ht_entries(struct ifmeta_inst *cl
585 ,OOP_Class *super
586 ,struct OOP_InterfaceDescr *ifDescr
587 ,struct IntOOPBase *OOPBase)
589 ULONG num_if = 0;
591 EnterFunc(bug("calc_ht_entries(cl=%p, ifDescr=%p, super=%p)\n", cl, ifDescr, super));
595 if (super)
597 /* Get number of interfaces (method tables) in superclass */
600 num_if = MD(super)->numinterfaces;
602 D(bug("Super-interfaces: %ld\n", num_if));
604 /* Check if there are any new interfaces in this class */
606 for (; ifDescr->MethodTable; ifDescr ++)
608 struct P_meta_getifinfo gii_msg;
609 ULONG num_methods;
611 D(bug("Checking for interface %s\n", ifDescr->InterfaceID));
613 gii_msg.mid = OOP_GetMethodID(IID_Meta, MO_meta_getifinfo);
614 gii_msg.interface_id = ifDescr->InterfaceID;
615 gii_msg.num_methods_ptr = &num_methods;
618 /* Does super support interface ? */
619 D(bug("Calling CoerceMethod on class %s\n", OOP_OCLASS(super)->ClassNode.ln_Name));
620 if (!OOP_CoerceMethod(OOP_OCLASS(super), (OOP_Object *)super, (OOP_Msg)&gii_msg))
622 D(bug("Found new interface: %s\n", ifDescr->InterfaceID));
624 /* If it didn't then we have a new interface for this class */
625 num_if ++;
628 } /* for (each interface in the description for the class) */
631 else
633 /* This is a baseclass, count the interfaces */
634 for (; ifDescr->MethodTable; ifDescr ++)
636 num_if ++;
638 } /* for (each interface in the description for the class) */
640 ReturnInt ("calc_ht_entries", ULONG, num_if);
648 /*********************
649 ** createbucket() **
650 *********************/
651 /* Creates a new interface bucket */
652 static struct IFBucket *createbucket(
653 STRPTR interface_id
654 ,ULONG num_methods
655 ,struct IntOOPBase *OOPBase)
657 struct IFMethod *ifm = NULL;
658 ULONG mtab_size = UB (&ifm[num_methods]) - UB( &ifm[0]);
660 /* Allocate bucket */
661 struct IFBucket *ifb;
663 ifb = (struct IFBucket *)AllocMem( sizeof (struct IFBucket), MEMF_ANY );
664 if (ifb)
666 /* Allocate method table for this interface */
667 ifb->MethodTable = (struct IFMethod *)AllocVec(mtab_size, MEMF_ANY);
668 if (ifb->MethodTable)
670 /* Get correct ID for the interface (string ID => interface ID mapping) */
672 if (init_mi_methodbase(interface_id, &(ifb->InterfaceID), OOPBase))
674 /* Save number of methods in the interface */
675 ifb->NumMethods = num_methods;
677 /* Save the global string representations of the ID */
678 ifb->GlobalInterfaceID = interface_id;
679 return (ifb);
683 FreeMem (ifb, sizeof (struct IFBucket));
685 return (NULL);
689 /***********************
690 ** Hash table hooks **
691 ***********************/
692 #define IB(x) ((struct IFBucket *)x)
694 VOID freebucket(struct Bucket *b, struct IntOOPBase *OOPBase)
697 /* Free methodtable */
698 FreeVec(IB(b)->MethodTable);
700 /* Free the bucket itself */
701 FreeMem(b, sizeof (struct IFBucket));
704 return;
707 /* Copies a hashtable bucket */
708 struct Bucket *copyBucket(struct Bucket *old_b, APTR data, struct IntOOPBase *OOPBase)
710 struct IFBucket *new_b;
712 EnterFunc(bug("CopyBucket(old_b=%p)\n", old_b));
714 /* Allocate memory for the new interface bucket */
715 new_b = (struct IFBucket *)AllocMem(sizeof (struct IFBucket), MEMF_ANY );
716 if (new_b)
718 struct IFMethod *ifm = NULL;
719 ULONG mtab_size;
721 /* Get number of methods in source methodtable */
722 ULONG numentries = IB(old_b)->NumMethods;
724 mtab_size = UB(&ifm[numentries]) - UB(&ifm[0]);
726 /* Allocate memory for methodtable of same size as source one */
727 new_b->MethodTable = (struct IFMethod *)AllocVec(mtab_size, MEMF_ANY);
728 if (new_b->MethodTable)
730 /* Copy methodtable to destination */
731 CopyMem(IB(old_b)->MethodTable, new_b->MethodTable, mtab_size);
733 /* Initialize bucket */
734 new_b->InterfaceID = IB(old_b)->InterfaceID;
735 new_b->NumMethods = IB(old_b)->NumMethods;
736 new_b->GlobalInterfaceID = IB(old_b)->GlobalInterfaceID;
738 ReturnPtr ("CopyBucket", struct Bucket *, (struct Bucket *)new_b );
740 FreeMem (new_b, sizeof (struct IFBucket));
743 ReturnPtr ("CopyBucket", struct Bucket *, NULL);
748 /* Default function for calling DoMethod() on a local object */
749 /*****************
750 ** DoMethod() **
751 *****************/
753 #define OOPBase ((struct IntOOPBase *)OOP_OOPBASE(object))
755 static IPTR Meta_DoMethod(OOP_Object *object, OOP_Msg msg)
757 struct metadata *cl = (struct metadata *)OOP_OCLASS(object);
760 /* Macro below defined in intern.h */
761 IntCallMethod(cl, object, msg);
766 /*******************
767 ** CoerceMethod **
768 *******************/
769 static IPTR Meta_CoerceMethod(OOP_Class *cl, OOP_Object *object, OOP_Msg msg)
771 IntCallMethod(cl, object, msg);
774 /********************
775 ** DoSuperMethod **
776 ********************/
777 static IPTR Meta_DoSuperMethod(OOP_Class *cl, OOP_Object *object, OOP_Msg msg)
779 cl = IFI(cl)->base.superclass;
780 IntCallMethod(cl, object, msg);
783 #undef OOPBase