From de72bc6b585e8d5efe1b0045176cc2c5f2060d47 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sun, 22 Sep 2019 15:59:09 +0000 Subject: [PATCH] added the #uncopyable attribute to the class definition. --- moo/README.md | 1 + moo/kernel/Class.moo | 4 +- moo/kernel/Process.moo | 12 +++--- moo/lib/comp.c | 17 +++++++- moo/lib/gc.c | 20 ++++++--- moo/lib/moo-prv.h | 31 +++++++------ moo/lib/moo.h | 98 ++++++++++++++++++++++-------------------- moo/lib/obj.c | 12 +++++- 8 files changed, 115 insertions(+), 80 deletions(-) diff --git a/moo/README.md b/moo/README.md index 74eef5e..b558a5c 100644 --- a/moo/README.md +++ b/moo/README.md @@ -69,6 +69,7 @@ The word class can be followed by attribute list enclosed in parenthesis. e.g.) * #limited - not instantiable with new. * #immutable - instantiated object to be read-only. * #final - disallow subclasses. +* #uncopyable - instantiated object not to be copied. * #byte, #character, #halfword, #word, #liword, #pointer - specify the type of a non-pointer object. a non-pointer type can have an additional size enclosed in parenthesis. e.g.) #character(2) diff --git a/moo/kernel/Class.moo b/moo/kernel/Class.moo index 3f16bbc..00e8f7c 100644 --- a/moo/kernel/Class.moo +++ b/moo/kernel/Class.moo @@ -8,7 +8,7 @@ interface ClassInterface // the Class object should be a variable-pointer object because // it needs to accomodate class instance variables. // -class(#pointer,#limited) Class(Apex) [ClassInterface] +class(#pointer,#limited,#uncopyable) Class(Apex) [ClassInterface] { var spec, selfspec, superclass, subclasses, name, modname. var instvars, classinstvars, classvars, pooldics. @@ -44,7 +44,7 @@ class(#pointer,#limited) Class(Apex) [ClassInterface] method nsdic { ^self.nsdic } } -class(#pointer,#limited) Interface(Apex) +class(#pointer,#limited,#uncopyable) Interface(Apex) { var name. var instmthdic, classmthdic, nsup. diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 011c75a..4b50650 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -1,5 +1,5 @@ -class(#pointer,#final,#limited) Process(Object) +class(#pointer,#final,#limited,#uncopyable) Process(Object) { var(#get) initialContext, currentContext, id, state. var sp. @@ -76,7 +76,7 @@ class(#pointer,#final,#limited) Process(Object) } } -class Semaphore(Object) +class(#uncopyable) Semaphore(Object) { var waiting_head := nil, waiting_tail := nil. @@ -152,7 +152,7 @@ class Semaphore(Object) } } -class Mutex(Semaphore) +class(#uncopyable) Mutex(Semaphore) { method(#class) new { @@ -179,7 +179,7 @@ TODO: how to prohibit wait and signal??? } -class SemaphoreGroup(Object) +class(#uncopyable) SemaphoreGroup(Object) { // the first two variables must match those of Semaphore. var waiting_head := nil, @@ -252,7 +252,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit } } -class SemaphoreHeap(Object) +class(#uncopyable) SemaphoreHeap(Object) { var arr, size. @@ -418,7 +418,7 @@ class SemaphoreHeap(Object) } } -class(#final,#limited) ProcessScheduler(Object) +class(#final,#limited,#uncopyable) ProcessScheduler(Object) { var(#get) active, total_count := 0. var(#get) runnable_count := 0. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 522d5f7..b607f19 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -59,7 +59,8 @@ enum class_mod_t CLASS_FINAL = (1 << 0), CLASS_LIMITED = (1 << 1), CLASS_INDEXED = (1 << 2), - CLASS_IMMUTABLE = (1 << 3) + CLASS_IMMUTABLE = (1 << 3), + CLASS_UNCOPYABLE = (1 << 4) }; enum var_type_t @@ -163,6 +164,7 @@ static struct voca_t { 11, { 't','h','i','s','C','o','n','t','e','x','t' } }, { 11, { 't','h','i','s','P','r','o','c','e','s','s' } }, { 4, { 't','r','u','e' } }, + { 11, { '#','u','n','c','o','p','y','a','b','l','e' } }, { 5, { 'u','n','t','i','l' } }, { 3, { 'v','a','r' } }, { 8, { 'v','a','r','i','a','b','l','e' } }, @@ -233,6 +235,7 @@ enum voca_id_t VOCA_THIS_CONTEXT, VOCA_THIS_PROCESS, VOCA_TRUE, + VOCA_UNCOPYABLE_S, VOCA_UNTIL, VOCA_VAR, VOCA_VARIABLE, @@ -8147,6 +8150,7 @@ static int make_defined_class (moo_t* moo) flags = 0; if (cc->flags & CLASS_INDEXED) flags |= MOO_CLASS_SPEC_FLAG_INDEXED; if (cc->flags & CLASS_IMMUTABLE) flags |= MOO_CLASS_SPEC_FLAG_IMMUTABLE; + if (cc->flags & CLASS_UNCOPYABLE) flags |= MOO_CLASS_SPEC_FLAG_UNCOPYABLE; if (cc->non_pointer_instsize > 0) { @@ -8415,6 +8419,16 @@ static int process_class_modifiers (moo_t* moo, moo_ioloc_t* type_loc) cc->flags |= CLASS_IMMUTABLE; GET_TOKEN(moo); } + else if (is_token_symbol(moo, VOCA_UNCOPYABLE_S)) + { + if (cc->flags & CLASS_UNCOPYABLE) + { + moo_setsynerr (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + cc->flags |= CLASS_UNCOPYABLE; + GET_TOKEN(moo); + } else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) { /* no modifier is present */ @@ -9077,7 +9091,6 @@ static int __compile_class_definition (moo_t* moo, int class_type) while (1); } - /* TODO: load constants here? */ } else diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 86317dd..0bb6613 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -124,7 +124,7 @@ static kernel_class_info_t kernel_classes[] = MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_CLASS_NAMED_INSTVARS, - 1, + MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_UNCOPYABLE, MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _class) }, @@ -133,7 +133,7 @@ static kernel_class_info_t kernel_classes[] = MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_INTERFACE_NAMED_INSTVARS, - 1, + MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_UNCOPYABLE, MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _interface) }, @@ -278,7 +278,7 @@ static kernel_class_info_t kernel_classes[] = MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_PROCESS_NAMED_INSTVARS, - MOO_CLASS_SPEC_FLAG_INDEXED, + MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_UNCOPYABLE, MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _process) }, @@ -287,7 +287,7 @@ static kernel_class_info_t kernel_classes[] = 0, 0, MOO_SEMAPHORE_NAMED_INSTVARS, - 0, + MOO_CLASS_SPEC_FLAG_UNCOPYABLE, MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _semaphore) }, @@ -296,7 +296,7 @@ static kernel_class_info_t kernel_classes[] = 0, 0, MOO_SEMAPHORE_GROUP_NAMED_INSTVARS, - 0, + MOO_CLASS_SPEC_FLAG_UNCOPYABLE, MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _semaphore_group) }, @@ -305,7 +305,7 @@ static kernel_class_info_t kernel_classes[] = MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_PROCESS_SCHEDULER_NAMED_INSTVARS, - 0, + MOO_CLASS_SPEC_FLAG_UNCOPYABLE, MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _process_scheduler) }, @@ -422,11 +422,17 @@ static moo_oow_t move_finalizable_objects (moo_t* moo); static moo_oop_class_t alloc_kernel_class (moo_t* moo, int class_flags, moo_oow_t num_classvars, moo_oow_t spec) { moo_oop_class_t c; + moo_ooi_t cspec; c = (moo_oop_class_t)moo_allocoopobj(moo, MOO_CLASS_NAMED_INSTVARS + num_classvars); if (!c) return MOO_NULL; MOO_OBJ_SET_FLAGS_KERNEL (c, MOO_OBJ_FLAGS_KERNEL_IMMATURE); + + cspec = kernel_classes[KCI_CLASS].class_spec_flags; + if (MOO_CLASS_SPEC_IS_IMMUTABLE(cspec)) MOO_OBJ_SET_FLAGS_RDONLY (c, 1); /* just for completeness of code. will never be true as it's not defined in the kernel class info table */ + if (MOO_CLASS_SPEC_IS_UNCOPYABLE(cspec)) MOO_OBJ_SET_FLAGS_UNCOPYABLE (c, 1); /* class itself is uncopyable */ + MOO_OBJ_SET_CLASS (c, (moo_oop_t)moo->_class); c->spec = MOO_SMOOI_TO_OOP(spec); c->selfspec = MOO_SMOOI_TO_OOP(MOO_CLASS_SELFSPEC_MAKE(num_classvars, 0, class_flags)); @@ -1120,7 +1126,7 @@ moo_oop_t moo_shallowcopy (moo_t* moo, moo_oop_t oop) moo_oop_t z; moo_oow_t total_bytes; - if (MOO_OBJ_GET_FLAGS_TRAILER(oop) || MOO_OBJ_GET_FLAGS_PROC(oop)) + if (MOO_OBJ_GET_FLAGS_UNCOPYABLE(oop) || MOO_OBJ_GET_FLAGS_TRAILER(oop)) { /* TOOD: should i disallow this or return without copying? */ moo_seterrbfmt (moo, MOO_EPERM, "not allowed to copy process or object with trailer"); diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 87671bf..2ab3841 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -140,13 +140,13 @@ * For example, on a platform where sizeof(moo_oow_t) is 4, * the layout of the spec field of a class as an OOP value looks like this: * - * 31 11 10 9 8 7 6 5 4 3 2 1 0 - * |number of named instance variables|indexed-type|flags|oop-tag| + * 31 12 11 10 9 8 7 6 5 4 3 2 1 0 + * |number of named instance variables|indexed-type|flags |oop-tag| * - * the number of named instance variables is stored in high 23 bits. - * the indexed type takes up bit 3 to bit 8 (assuming MOO_OBJ_TYPE_BITS is 6. + * the number of named instance variables is stored in high 21 bits. + * the indexed type takes up bit 5 to bit 10 (assuming MOO_OBJ_TYPE_BITS is 6. * MOO_OBJ_TYPE_XXX enumerators are used to represent actual values). - * and the indexability is stored in bit 2. + * and the indexability is stored in the flag bits which span from bit 2 to 4. * * The maximum number of named(fixed) instance variables for a class is: * 2 ^ ((BITS-IN-OOW - MOO_OOP_TAG_BITS_LO) - MOO_OBJ_TYPE_BITS - 1 - 2) - 1 @@ -161,36 +161,40 @@ * indexed_type is one of the #moo_obj_type_t enumerators. */ +#define MOO_CLASS_SPEC_FLAG_BITS (3) + /* * The MOO_CLASS_SPEC_MAKE() macro creates a class spec value. * _class->spec = MOO_SMOOI_TO_OOP(MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_CHAR)); */ #define MOO_CLASS_SPEC_MAKE(named_instvar,flags,indexed_type) ( \ - (((moo_oow_t)(named_instvar)) << (MOO_OBJ_FLAGS_TYPE_BITS + 2)) | \ - (((moo_oow_t)(indexed_type)) << 2) | (((moo_oow_t)flags) & 3) ) + (((moo_oow_t)(named_instvar)) << (MOO_OBJ_FLAGS_TYPE_BITS + MOO_CLASS_SPEC_FLAG_BITS)) | \ + (((moo_oow_t)(indexed_type)) << (MOO_CLASS_SPEC_FLAG_BITS)) | (((moo_oow_t)flags) & MOO_LBMASK(moo_oow_t,MOO_CLASS_SPEC_FLAG_BITS))) /* what is the number of named instance variables? * MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec)) * ensure to update Class<> (MOO_OBJ_FLAGS_TYPE_BITS + 2)) + (((moo_oow_t)(spec)) >> (MOO_OBJ_FLAGS_TYPE_BITS + MOO_CLASS_SPEC_FLAG_BITS)) /* is it a user-indexable class? * all objects can be indexed with basicAt:. * this indicates if an object can be instantiated with a dynamic size * (new: size) and and can be indexed with at:. */ -#define MOO_CLASS_SPEC_FLAGS(spec) (((moo_oow_t)(spec)) & 3) +#define MOO_CLASS_SPEC_FLAGS(spec) (((moo_oow_t)(spec)) & MOO_LBMASK(moo_oow_t,MOO_CLASS_SPEC_FLAG_BITS)) /* if so, what is the indexing type? character? pointer? etc? */ #define MOO_CLASS_SPEC_INDEXED_TYPE(spec) \ - ((((moo_oow_t)(spec)) >> 2) & MOO_LBMASK(moo_oow_t, MOO_OBJ_FLAGS_TYPE_BITS)) + ((((moo_oow_t)(spec)) >> MOO_CLASS_SPEC_FLAG_BITS) & MOO_LBMASK(moo_oow_t, MOO_OBJ_FLAGS_TYPE_BITS)) -#define MOO_CLASS_SPEC_FLAG_INDEXED (1 << 0) -#define MOO_CLASS_SPEC_FLAG_IMMUTABLE (1 << 1) +#define MOO_CLASS_SPEC_FLAG_INDEXED (1 << 0) +#define MOO_CLASS_SPEC_FLAG_IMMUTABLE (1 << 1) +#define MOO_CLASS_SPEC_FLAG_UNCOPYABLE (1 << 2) #define MOO_CLASS_SPEC_IS_INDEXED(spec) (MOO_CLASS_SPEC_FLAGS(spec) & MOO_CLASS_SPEC_FLAG_INDEXED) #define MOO_CLASS_SPEC_IS_IMMUTABLE(spec) (MOO_CLASS_SPEC_FLAGS(spec) & MOO_CLASS_SPEC_FLAG_IMMUTABLE) +#define MOO_CLASS_SPEC_IS_UNCOPYABLE(spec) (MOO_CLASS_SPEC_FLAGS(spec) & MOO_CLASS_SPEC_FLAG_UNCOPYABLE) /* What is the maximum number of named instance variables? * This limit is set this way because the number must be encoded into @@ -198,7 +202,7 @@ * the number of named instance variables. */ #define MOO_MAX_NAMED_INSTVARS \ - MOO_BITS_MAX(moo_oow_t, MOO_SMOOI_ABS_BITS - (MOO_OBJ_FLAGS_TYPE_BITS + 2)) + MOO_BITS_MAX(moo_oow_t, MOO_SMOOI_ABS_BITS - (MOO_OBJ_FLAGS_TYPE_BITS + MOO_CLASS_SPEC_FLAG_BITS)) /* Given the number of named instance variables, what is the maximum number * of indexed instance variables? The number of indexed instance variables @@ -209,7 +213,6 @@ */ #define MOO_MAX_INDEXED_INSTVARS(named_instvar) (MOO_OBJ_SIZE_MAX - named_instvar) - /* * self-specification of a class * | classinstvars | classvars | flags | diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 94a060a..3d98c86 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -290,53 +290,57 @@ typedef enum moo_gcfin_t moo_gcfin_t; * size calculation and the access to the payload fields become more complex. * Therefore, i've dropped the idea. * ========================================================================= */ -#define MOO_OBJ_FLAGS_TYPE_BITS 6 -#define MOO_OBJ_FLAGS_UNIT_BITS 5 -#define MOO_OBJ_FLAGS_EXTRA_BITS 1 -#define MOO_OBJ_FLAGS_KERNEL_BITS 2 -#define MOO_OBJ_FLAGS_PERM_BITS 1 -#define MOO_OBJ_FLAGS_MOVED_BITS 1 -#define MOO_OBJ_FLAGS_PROC_BITS 1 -#define MOO_OBJ_FLAGS_RDONLY_BITS 1 -#define MOO_OBJ_FLAGS_GCFIN_BITS 4 -#define MOO_OBJ_FLAGS_TRAILER_BITS 1 -#define MOO_OBJ_FLAGS_HASH_BITS 2 +#define MOO_OBJ_FLAGS_TYPE_BITS 6 +#define MOO_OBJ_FLAGS_UNIT_BITS 5 +#define MOO_OBJ_FLAGS_EXTRA_BITS 1 +#define MOO_OBJ_FLAGS_KERNEL_BITS 2 +#define MOO_OBJ_FLAGS_PERM_BITS 1 +#define MOO_OBJ_FLAGS_MOVED_BITS 1 +#define MOO_OBJ_FLAGS_PROC_BITS 1 +#define MOO_OBJ_FLAGS_RDONLY_BITS 1 +#define MOO_OBJ_FLAGS_GCFIN_BITS 4 +#define MOO_OBJ_FLAGS_TRAILER_BITS 1 +#define MOO_OBJ_FLAGS_HASH_BITS 2 +#define MOO_OBJ_FLAGS_UNCOPYABLE_BITS 1 -#define MOO_OBJ_FLAGS_TYPE_SHIFT (MOO_OBJ_FLAGS_UNIT_BITS + MOO_OBJ_FLAGS_UNIT_SHIFT) -#define MOO_OBJ_FLAGS_UNIT_SHIFT (MOO_OBJ_FLAGS_EXTRA_BITS + MOO_OBJ_FLAGS_EXTRA_SHIFT) -#define MOO_OBJ_FLAGS_EXTRA_SHIFT (MOO_OBJ_FLAGS_KERNEL_BITS + MOO_OBJ_FLAGS_KERNEL_SHIFT) -#define MOO_OBJ_FLAGS_KERNEL_SHIFT (MOO_OBJ_FLAGS_PERM_BITS + MOO_OBJ_FLAGS_PERM_SHIFT) -#define MOO_OBJ_FLAGS_PERM_SHIFT (MOO_OBJ_FLAGS_MOVED_BITS + MOO_OBJ_FLAGS_MOVED_SHIFT) -#define MOO_OBJ_FLAGS_MOVED_SHIFT (MOO_OBJ_FLAGS_PROC_BITS + MOO_OBJ_FLAGS_PROC_SHIFT) -#define MOO_OBJ_FLAGS_PROC_SHIFT (MOO_OBJ_FLAGS_RDONLY_BITS + MOO_OBJ_FLAGS_RDONLY_SHIFT) -#define MOO_OBJ_FLAGS_RDONLY_SHIFT (MOO_OBJ_FLAGS_GCFIN_BITS + MOO_OBJ_FLAGS_GCFIN_SHIFT) -#define MOO_OBJ_FLAGS_GCFIN_SHIFT (MOO_OBJ_FLAGS_TRAILER_BITS + MOO_OBJ_FLAGS_TRAILER_SHIFT) -#define MOO_OBJ_FLAGS_TRAILER_SHIFT (MOO_OBJ_FLAGS_HASH_BITS + MOO_OBJ_FLAGS_HASH_SHIFT) -#define MOO_OBJ_FLAGS_HASH_SHIFT (0) +#define MOO_OBJ_FLAGS_TYPE_SHIFT (MOO_OBJ_FLAGS_UNIT_BITS + MOO_OBJ_FLAGS_UNIT_SHIFT) +#define MOO_OBJ_FLAGS_UNIT_SHIFT (MOO_OBJ_FLAGS_EXTRA_BITS + MOO_OBJ_FLAGS_EXTRA_SHIFT) +#define MOO_OBJ_FLAGS_EXTRA_SHIFT (MOO_OBJ_FLAGS_KERNEL_BITS + MOO_OBJ_FLAGS_KERNEL_SHIFT) +#define MOO_OBJ_FLAGS_KERNEL_SHIFT (MOO_OBJ_FLAGS_PERM_BITS + MOO_OBJ_FLAGS_PERM_SHIFT) +#define MOO_OBJ_FLAGS_PERM_SHIFT (MOO_OBJ_FLAGS_MOVED_BITS + MOO_OBJ_FLAGS_MOVED_SHIFT) +#define MOO_OBJ_FLAGS_MOVED_SHIFT (MOO_OBJ_FLAGS_PROC_BITS + MOO_OBJ_FLAGS_PROC_SHIFT) +#define MOO_OBJ_FLAGS_PROC_SHIFT (MOO_OBJ_FLAGS_RDONLY_BITS + MOO_OBJ_FLAGS_RDONLY_SHIFT) +#define MOO_OBJ_FLAGS_RDONLY_SHIFT (MOO_OBJ_FLAGS_GCFIN_BITS + MOO_OBJ_FLAGS_GCFIN_SHIFT) +#define MOO_OBJ_FLAGS_GCFIN_SHIFT (MOO_OBJ_FLAGS_TRAILER_BITS + MOO_OBJ_FLAGS_TRAILER_SHIFT) +#define MOO_OBJ_FLAGS_TRAILER_SHIFT (MOO_OBJ_FLAGS_HASH_BITS + MOO_OBJ_FLAGS_HASH_SHIFT) +#define MOO_OBJ_FLAGS_HASH_SHIFT (MOO_OBJ_FLAGS_UNCOPYABLE_BITS + MOO_OBJ_FLAGS_UNCOPYABLE_SHIFT) +#define MOO_OBJ_FLAGS_UNCOPYABLE_SHIFT (0) -#define MOO_OBJ_GET_FLAGS_TYPE(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS) -#define MOO_OBJ_GET_FLAGS_UNIT(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS) -#define MOO_OBJ_GET_FLAGS_EXTRA(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_EXTRA_SHIFT, MOO_OBJ_FLAGS_EXTRA_BITS) -#define MOO_OBJ_GET_FLAGS_KERNEL(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_KERNEL_SHIFT, MOO_OBJ_FLAGS_KERNEL_BITS) -#define MOO_OBJ_GET_FLAGS_PERM(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PERM_SHIFT, MOO_OBJ_FLAGS_PERM_BITS) -#define MOO_OBJ_GET_FLAGS_MOVED(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_MOVED_SHIFT, MOO_OBJ_FLAGS_MOVED_BITS) -#define MOO_OBJ_GET_FLAGS_PROC(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PROC_SHIFT, MOO_OBJ_FLAGS_PROC_BITS) -#define MOO_OBJ_GET_FLAGS_RDONLY(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS) -#define MOO_OBJ_GET_FLAGS_GCFIN(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS) -#define MOO_OBJ_GET_FLAGS_TRAILER(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS) -#define MOO_OBJ_GET_FLAGS_HASH(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_HASH_SHIFT, MOO_OBJ_FLAGS_HASH_BITS) +#define MOO_OBJ_GET_FLAGS_TYPE(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS) +#define MOO_OBJ_GET_FLAGS_UNIT(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS) +#define MOO_OBJ_GET_FLAGS_EXTRA(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_EXTRA_SHIFT, MOO_OBJ_FLAGS_EXTRA_BITS) +#define MOO_OBJ_GET_FLAGS_KERNEL(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_KERNEL_SHIFT, MOO_OBJ_FLAGS_KERNEL_BITS) +#define MOO_OBJ_GET_FLAGS_PERM(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PERM_SHIFT, MOO_OBJ_FLAGS_PERM_BITS) +#define MOO_OBJ_GET_FLAGS_MOVED(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_MOVED_SHIFT, MOO_OBJ_FLAGS_MOVED_BITS) +#define MOO_OBJ_GET_FLAGS_PROC(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PROC_SHIFT, MOO_OBJ_FLAGS_PROC_BITS) +#define MOO_OBJ_GET_FLAGS_RDONLY(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS) +#define MOO_OBJ_GET_FLAGS_GCFIN(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS) +#define MOO_OBJ_GET_FLAGS_TRAILER(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS) +#define MOO_OBJ_GET_FLAGS_HASH(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_HASH_SHIFT, MOO_OBJ_FLAGS_HASH_BITS) +#define MOO_OBJ_GET_FLAGS_UNCOPYABLE(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNCOPYABLE_SHIFT, MOO_OBJ_FLAGS_UNCOPYABLE_BITS) -#define MOO_OBJ_SET_FLAGS_TYPE(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS, v) -#define MOO_OBJ_SET_FLAGS_UNIT(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS, v) -#define MOO_OBJ_SET_FLAGS_EXTRA(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_EXTRA_SHIFT, MOO_OBJ_FLAGS_EXTRA_BITS, v) -#define MOO_OBJ_SET_FLAGS_KERNEL(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_KERNEL_SHIFT, MOO_OBJ_FLAGS_KERNEL_BITS, v) -#define MOO_OBJ_SET_FLAGS_PERM(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PERM_SHIFT, MOO_OBJ_FLAGS_PERM_BITS, v) -#define MOO_OBJ_SET_FLAGS_MOVED(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_MOVED_SHIFT, MOO_OBJ_FLAGS_MOVED_BITS, v) -#define MOO_OBJ_SET_FLAGS_PROC(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PROC_SHIFT, MOO_OBJ_FLAGS_PROC_BITS, v) -#define MOO_OBJ_SET_FLAGS_RDONLY(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS, v) -#define MOO_OBJ_SET_FLAGS_GCFIN(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS, v) -#define MOO_OBJ_SET_FLAGS_TRAILER(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS, v) -#define MOO_OBJ_SET_FLAGS_HASH(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_HASH_SHIFT, MOO_OBJ_FLAGS_HASH_BITS, v) +#define MOO_OBJ_SET_FLAGS_TYPE(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS, v) +#define MOO_OBJ_SET_FLAGS_UNIT(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS, v) +#define MOO_OBJ_SET_FLAGS_EXTRA(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_EXTRA_SHIFT, MOO_OBJ_FLAGS_EXTRA_BITS, v) +#define MOO_OBJ_SET_FLAGS_KERNEL(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_KERNEL_SHIFT, MOO_OBJ_FLAGS_KERNEL_BITS, v) +#define MOO_OBJ_SET_FLAGS_PERM(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PERM_SHIFT, MOO_OBJ_FLAGS_PERM_BITS, v) +#define MOO_OBJ_SET_FLAGS_MOVED(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_MOVED_SHIFT, MOO_OBJ_FLAGS_MOVED_BITS, v) +#define MOO_OBJ_SET_FLAGS_PROC(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_PROC_SHIFT, MOO_OBJ_FLAGS_PROC_BITS, v) +#define MOO_OBJ_SET_FLAGS_RDONLY(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS, v) +#define MOO_OBJ_SET_FLAGS_GCFIN(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS, v) +#define MOO_OBJ_SET_FLAGS_TRAILER(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS, v) +#define MOO_OBJ_SET_FLAGS_HASH(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_HASH_SHIFT, MOO_OBJ_FLAGS_HASH_BITS, v) +#define MOO_OBJ_SET_FLAGS_UNCOPYABLE(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNCOPYABLE_SHIFT, MOO_OBJ_FLAGS_UNCOPYABLE_BITS, v) #define MOO_OBJ_GET_SIZE(oop) ((oop)->_size) #define MOO_OBJ_GET_CLASS(oop) ((moo_oop_class_t)((oop)->_class)) @@ -369,9 +373,9 @@ typedef enum moo_gcfin_t moo_gcfin_t; (((moo_oow_t)(_h)) << MOO_OBJ_FLAGS_HASH_SHIFT) \ ) -#define MOO_OBJ_FLAGS_KERNEL_USER 0 -#define MOO_OBJ_FLAGS_KERNEL_IMMATURE 1 -#define MOO_OBJ_FLAGS_KERNEL_MATURE 2 +#define MOO_OBJ_FLAGS_KERNEL_USER 0 /* not a kernel object */ +#define MOO_OBJ_FLAGS_KERNEL_IMMATURE 1 /* incomplete kernel object. defined in gc.c for bootstrapping. but no complete class definition has been read */ +#define MOO_OBJ_FLAGS_KERNEL_MATURE 2 /* kernel object with its full class defintion read in */ #define MOO_OBJ_FLAGS_HASH_UNUSED 0 /* the hash method has never been invoked */ #define MOO_OBJ_FLAGS_HASH_CALLED 1 /* the hash method has been invoked for this object */ diff --git a/moo/lib/obj.c b/moo/lib/obj.c index e6fc41a..ad703bf 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -322,8 +322,11 @@ moo_oop_t moo_instantiate (moo_t* moo, moo_oop_class_t _class, const void* vptr, if (oop) { + moo_ooi_t spec; MOO_OBJ_SET_CLASS (oop, (moo_oop_t)_class); - if (MOO_CLASS_SPEC_IS_IMMUTABLE(MOO_OOP_TO_SMOOI(_class->spec))) MOO_OBJ_SET_FLAGS_RDONLY (oop, 1); + spec = MOO_OOP_TO_SMOOI(_class->spec); + if (MOO_CLASS_SPEC_IS_IMMUTABLE(spec)) MOO_OBJ_SET_FLAGS_RDONLY (oop, 1); + if (MOO_CLASS_SPEC_IS_UNCOPYABLE(spec)) MOO_OBJ_SET_FLAGS_UNCOPYABLE (oop, 1); } moo_popvolats (moo, tmp_count); return oop; @@ -381,9 +384,14 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_class_t _class, moo_oo if (oop) { + moo_ooi_t spec; MOO_OBJ_SET_CLASS (oop, _class); - if (MOO_CLASS_SPEC_IS_IMMUTABLE(MOO_OOP_TO_SMOOI(_class->spec))) MOO_OBJ_SET_FLAGS_RDONLY (oop, 1); + spec = MOO_OOP_TO_SMOOI(_class->spec); + if (MOO_CLASS_SPEC_IS_IMMUTABLE(spec)) MOO_OBJ_SET_FLAGS_RDONLY (oop, 1); + /* the object with a trailer is always uncopyable */ + /*if (MOO_CLASS_SPEC_IS_UNCOPYABLE(spec)) */MOO_OBJ_SET_FLAGS_UNCOPYABLE (oop, 1); } + moo_popvolats (moo, tmp_count); return oop; }