added the #uncopyable attribute to the class definition.
This commit is contained in:
parent
97f264398d
commit
de72bc6b58
@ -69,6 +69,7 @@ The word class can be followed by attribute list enclosed in parenthesis. e.g.)
|
|||||||
* #limited - not instantiable with new.
|
* #limited - not instantiable with new.
|
||||||
* #immutable - instantiated object to be read-only.
|
* #immutable - instantiated object to be read-only.
|
||||||
* #final - disallow subclasses.
|
* #final - disallow subclasses.
|
||||||
|
* #uncopyable - instantiated object not to be copied.
|
||||||
* #byte, #character, #halfword, #word, #liword, #pointer -
|
* #byte, #character, #halfword, #word, #liword, #pointer -
|
||||||
specify the type of a non-pointer object. a non-pointer type can have an additional size
|
specify the type of a non-pointer object. a non-pointer type can have an additional size
|
||||||
enclosed in parenthesis. e.g.) #character(2)
|
enclosed in parenthesis. e.g.) #character(2)
|
||||||
|
@ -8,7 +8,7 @@ interface ClassInterface
|
|||||||
// the Class object should be a variable-pointer object because
|
// the Class object should be a variable-pointer object because
|
||||||
// it needs to accomodate class instance variables.
|
// 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 spec, selfspec, superclass, subclasses, name, modname.
|
||||||
var instvars, classinstvars, classvars, pooldics.
|
var instvars, classinstvars, classvars, pooldics.
|
||||||
@ -44,7 +44,7 @@ class(#pointer,#limited) Class(Apex) [ClassInterface]
|
|||||||
method nsdic { ^self.nsdic }
|
method nsdic { ^self.nsdic }
|
||||||
}
|
}
|
||||||
|
|
||||||
class(#pointer,#limited) Interface(Apex)
|
class(#pointer,#limited,#uncopyable) Interface(Apex)
|
||||||
{
|
{
|
||||||
var name.
|
var name.
|
||||||
var instmthdic, classmthdic, nsup.
|
var instmthdic, classmthdic, nsup.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
class(#pointer,#final,#limited) Process(Object)
|
class(#pointer,#final,#limited,#uncopyable) Process(Object)
|
||||||
{
|
{
|
||||||
var(#get) initialContext, currentContext, id, state.
|
var(#get) initialContext, currentContext, id, state.
|
||||||
var sp.
|
var sp.
|
||||||
@ -76,7 +76,7 @@ class(#pointer,#final,#limited) Process(Object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Semaphore(Object)
|
class(#uncopyable) Semaphore(Object)
|
||||||
{
|
{
|
||||||
var waiting_head := nil,
|
var waiting_head := nil,
|
||||||
waiting_tail := nil.
|
waiting_tail := nil.
|
||||||
@ -152,7 +152,7 @@ class Semaphore(Object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Mutex(Semaphore)
|
class(#uncopyable) Mutex(Semaphore)
|
||||||
{
|
{
|
||||||
method(#class) new
|
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.
|
// the first two variables must match those of Semaphore.
|
||||||
var waiting_head := nil,
|
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.
|
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) active, total_count := 0.
|
||||||
var(#get) runnable_count := 0.
|
var(#get) runnable_count := 0.
|
||||||
|
@ -59,7 +59,8 @@ enum class_mod_t
|
|||||||
CLASS_FINAL = (1 << 0),
|
CLASS_FINAL = (1 << 0),
|
||||||
CLASS_LIMITED = (1 << 1),
|
CLASS_LIMITED = (1 << 1),
|
||||||
CLASS_INDEXED = (1 << 2),
|
CLASS_INDEXED = (1 << 2),
|
||||||
CLASS_IMMUTABLE = (1 << 3)
|
CLASS_IMMUTABLE = (1 << 3),
|
||||||
|
CLASS_UNCOPYABLE = (1 << 4)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum var_type_t
|
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','C','o','n','t','e','x','t' } },
|
||||||
{ 11, { 't','h','i','s','P','r','o','c','e','s','s' } },
|
{ 11, { 't','h','i','s','P','r','o','c','e','s','s' } },
|
||||||
{ 4, { 't','r','u','e' } },
|
{ 4, { 't','r','u','e' } },
|
||||||
|
{ 11, { '#','u','n','c','o','p','y','a','b','l','e' } },
|
||||||
{ 5, { 'u','n','t','i','l' } },
|
{ 5, { 'u','n','t','i','l' } },
|
||||||
{ 3, { 'v','a','r' } },
|
{ 3, { 'v','a','r' } },
|
||||||
{ 8, { 'v','a','r','i','a','b','l','e' } },
|
{ 8, { 'v','a','r','i','a','b','l','e' } },
|
||||||
@ -233,6 +235,7 @@ enum voca_id_t
|
|||||||
VOCA_THIS_CONTEXT,
|
VOCA_THIS_CONTEXT,
|
||||||
VOCA_THIS_PROCESS,
|
VOCA_THIS_PROCESS,
|
||||||
VOCA_TRUE,
|
VOCA_TRUE,
|
||||||
|
VOCA_UNCOPYABLE_S,
|
||||||
VOCA_UNTIL,
|
VOCA_UNTIL,
|
||||||
VOCA_VAR,
|
VOCA_VAR,
|
||||||
VOCA_VARIABLE,
|
VOCA_VARIABLE,
|
||||||
@ -8147,6 +8150,7 @@ static int make_defined_class (moo_t* moo)
|
|||||||
flags = 0;
|
flags = 0;
|
||||||
if (cc->flags & CLASS_INDEXED) flags |= MOO_CLASS_SPEC_FLAG_INDEXED;
|
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_IMMUTABLE) flags |= MOO_CLASS_SPEC_FLAG_IMMUTABLE;
|
||||||
|
if (cc->flags & CLASS_UNCOPYABLE) flags |= MOO_CLASS_SPEC_FLAG_UNCOPYABLE;
|
||||||
|
|
||||||
if (cc->non_pointer_instsize > 0)
|
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;
|
cc->flags |= CLASS_IMMUTABLE;
|
||||||
GET_TOKEN(moo);
|
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)
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN)
|
||||||
{
|
{
|
||||||
/* no modifier is present */
|
/* no modifier is present */
|
||||||
@ -9077,7 +9091,6 @@ static int __compile_class_definition (moo_t* moo, int class_type)
|
|||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TODO: load constants here? */
|
/* TODO: load constants here? */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
20
moo/lib/gc.c
20
moo/lib/gc.c
@ -124,7 +124,7 @@ static kernel_class_info_t kernel_classes[] =
|
|||||||
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
||||||
0,
|
0,
|
||||||
MOO_CLASS_NAMED_INSTVARS,
|
MOO_CLASS_NAMED_INSTVARS,
|
||||||
1,
|
MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_UNCOPYABLE,
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
MOO_OFFSETOF(moo_t, _class) },
|
MOO_OFFSETOF(moo_t, _class) },
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ static kernel_class_info_t kernel_classes[] =
|
|||||||
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
||||||
0,
|
0,
|
||||||
MOO_INTERFACE_NAMED_INSTVARS,
|
MOO_INTERFACE_NAMED_INSTVARS,
|
||||||
1,
|
MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_UNCOPYABLE,
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
MOO_OFFSETOF(moo_t, _interface) },
|
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,
|
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
||||||
0,
|
0,
|
||||||
MOO_PROCESS_NAMED_INSTVARS,
|
MOO_PROCESS_NAMED_INSTVARS,
|
||||||
MOO_CLASS_SPEC_FLAG_INDEXED,
|
MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_UNCOPYABLE,
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
MOO_OFFSETOF(moo_t, _process) },
|
MOO_OFFSETOF(moo_t, _process) },
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ static kernel_class_info_t kernel_classes[] =
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
MOO_SEMAPHORE_NAMED_INSTVARS,
|
MOO_SEMAPHORE_NAMED_INSTVARS,
|
||||||
0,
|
MOO_CLASS_SPEC_FLAG_UNCOPYABLE,
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
MOO_OFFSETOF(moo_t, _semaphore) },
|
MOO_OFFSETOF(moo_t, _semaphore) },
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ static kernel_class_info_t kernel_classes[] =
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
MOO_SEMAPHORE_GROUP_NAMED_INSTVARS,
|
MOO_SEMAPHORE_GROUP_NAMED_INSTVARS,
|
||||||
0,
|
MOO_CLASS_SPEC_FLAG_UNCOPYABLE,
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
MOO_OFFSETOF(moo_t, _semaphore_group) },
|
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,
|
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
||||||
0,
|
0,
|
||||||
MOO_PROCESS_SCHEDULER_NAMED_INSTVARS,
|
MOO_PROCESS_SCHEDULER_NAMED_INSTVARS,
|
||||||
0,
|
MOO_CLASS_SPEC_FLAG_UNCOPYABLE,
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
MOO_OFFSETOF(moo_t, _process_scheduler) },
|
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)
|
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_oop_class_t c;
|
||||||
|
moo_ooi_t cspec;
|
||||||
|
|
||||||
c = (moo_oop_class_t)moo_allocoopobj(moo, MOO_CLASS_NAMED_INSTVARS + num_classvars);
|
c = (moo_oop_class_t)moo_allocoopobj(moo, MOO_CLASS_NAMED_INSTVARS + num_classvars);
|
||||||
if (!c) return MOO_NULL;
|
if (!c) return MOO_NULL;
|
||||||
|
|
||||||
MOO_OBJ_SET_FLAGS_KERNEL (c, MOO_OBJ_FLAGS_KERNEL_IMMATURE);
|
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);
|
MOO_OBJ_SET_CLASS (c, (moo_oop_t)moo->_class);
|
||||||
c->spec = MOO_SMOOI_TO_OOP(spec);
|
c->spec = MOO_SMOOI_TO_OOP(spec);
|
||||||
c->selfspec = MOO_SMOOI_TO_OOP(MOO_CLASS_SELFSPEC_MAKE(num_classvars, 0, class_flags));
|
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_oop_t z;
|
||||||
moo_oow_t total_bytes;
|
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? */
|
/* TOOD: should i disallow this or return without copying? */
|
||||||
moo_seterrbfmt (moo, MOO_EPERM, "not allowed to copy process or object with trailer");
|
moo_seterrbfmt (moo, MOO_EPERM, "not allowed to copy process or object with trailer");
|
||||||
|
@ -140,13 +140,13 @@
|
|||||||
* For example, on a platform where sizeof(moo_oow_t) is 4,
|
* 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:
|
* 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
|
* 31 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||||
* |number of named instance variables|indexed-type|flags |oop-tag|
|
* |number of named instance variables|indexed-type|flags |oop-tag|
|
||||||
*
|
*
|
||||||
* the number of named instance variables is stored in high 23 bits.
|
* the number of named instance variables is stored in high 21 bits.
|
||||||
* the indexed type takes up bit 3 to bit 8 (assuming MOO_OBJ_TYPE_BITS is 6.
|
* 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).
|
* 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:
|
* 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
|
* 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.
|
* 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.
|
* 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));
|
* _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) ( \
|
#define MOO_CLASS_SPEC_MAKE(named_instvar,flags,indexed_type) ( \
|
||||||
(((moo_oow_t)(named_instvar)) << (MOO_OBJ_FLAGS_TYPE_BITS + 2)) | \
|
(((moo_oow_t)(named_instvar)) << (MOO_OBJ_FLAGS_TYPE_BITS + MOO_CLASS_SPEC_FLAG_BITS)) | \
|
||||||
(((moo_oow_t)(indexed_type)) << 2) | (((moo_oow_t)flags) & 3) )
|
(((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?
|
/* what is the number of named instance variables?
|
||||||
* MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec))
|
* MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec))
|
||||||
* ensure to update Class<<specNumInstVars if you change this macro. */
|
* ensure to update Class<<specNumInstVars if you change this macro. */
|
||||||
#define MOO_CLASS_SPEC_NAMED_INSTVARS(spec) \
|
#define MOO_CLASS_SPEC_NAMED_INSTVARS(spec) \
|
||||||
(((moo_oow_t)(spec)) >> (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?
|
/* is it a user-indexable class?
|
||||||
* all objects can be indexed with basicAt:.
|
* all objects can be indexed with basicAt:.
|
||||||
* this indicates if an object can be instantiated with a dynamic size
|
* this indicates if an object can be instantiated with a dynamic size
|
||||||
* (new: size) and and can be indexed with at:.
|
* (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? */
|
/* if so, what is the indexing type? character? pointer? etc? */
|
||||||
#define MOO_CLASS_SPEC_INDEXED_TYPE(spec) \
|
#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_INDEXED (1 << 0)
|
||||||
#define MOO_CLASS_SPEC_FLAG_IMMUTABLE (1 << 1)
|
#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_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_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?
|
/* What is the maximum number of named instance variables?
|
||||||
* This limit is set this way because the number must be encoded into
|
* This limit is set this way because the number must be encoded into
|
||||||
@ -198,7 +202,7 @@
|
|||||||
* the number of named instance variables.
|
* the number of named instance variables.
|
||||||
*/
|
*/
|
||||||
#define MOO_MAX_NAMED_INSTVARS \
|
#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
|
/* Given the number of named instance variables, what is the maximum number
|
||||||
* of indexed instance variables? The number of indexed instance variables
|
* 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)
|
#define MOO_MAX_INDEXED_INSTVARS(named_instvar) (MOO_OBJ_SIZE_MAX - named_instvar)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* self-specification of a class
|
* self-specification of a class
|
||||||
* | classinstvars | classvars | flags |
|
* | classinstvars | classvars | flags |
|
||||||
|
@ -301,6 +301,7 @@ typedef enum moo_gcfin_t moo_gcfin_t;
|
|||||||
#define MOO_OBJ_FLAGS_GCFIN_BITS 4
|
#define MOO_OBJ_FLAGS_GCFIN_BITS 4
|
||||||
#define MOO_OBJ_FLAGS_TRAILER_BITS 1
|
#define MOO_OBJ_FLAGS_TRAILER_BITS 1
|
||||||
#define MOO_OBJ_FLAGS_HASH_BITS 2
|
#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_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_UNIT_SHIFT (MOO_OBJ_FLAGS_EXTRA_BITS + MOO_OBJ_FLAGS_EXTRA_SHIFT)
|
||||||
@ -312,7 +313,8 @@ typedef enum moo_gcfin_t moo_gcfin_t;
|
|||||||
#define MOO_OBJ_FLAGS_RDONLY_SHIFT (MOO_OBJ_FLAGS_GCFIN_BITS + MOO_OBJ_FLAGS_GCFIN_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_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_TRAILER_SHIFT (MOO_OBJ_FLAGS_HASH_BITS + MOO_OBJ_FLAGS_HASH_SHIFT)
|
||||||
#define MOO_OBJ_FLAGS_HASH_SHIFT (0)
|
#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_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_UNIT(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS)
|
||||||
@ -325,6 +327,7 @@ typedef enum moo_gcfin_t moo_gcfin_t;
|
|||||||
#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_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_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_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_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_UNIT(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS, v)
|
||||||
@ -337,6 +340,7 @@ typedef enum moo_gcfin_t moo_gcfin_t;
|
|||||||
#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_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_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_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_SIZE(oop) ((oop)->_size)
|
||||||
#define MOO_OBJ_GET_CLASS(oop) ((moo_oop_class_t)((oop)->_class))
|
#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) \
|
(((moo_oow_t)(_h)) << MOO_OBJ_FLAGS_HASH_SHIFT) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define MOO_OBJ_FLAGS_KERNEL_USER 0
|
#define MOO_OBJ_FLAGS_KERNEL_USER 0 /* not a kernel object */
|
||||||
#define MOO_OBJ_FLAGS_KERNEL_IMMATURE 1
|
#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
|
#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_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 */
|
#define MOO_OBJ_FLAGS_HASH_CALLED 1 /* the hash method has been invoked for this object */
|
||||||
|
@ -322,8 +322,11 @@ moo_oop_t moo_instantiate (moo_t* moo, moo_oop_class_t _class, const void* vptr,
|
|||||||
|
|
||||||
if (oop)
|
if (oop)
|
||||||
{
|
{
|
||||||
|
moo_ooi_t spec;
|
||||||
MOO_OBJ_SET_CLASS (oop, (moo_oop_t)_class);
|
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);
|
moo_popvolats (moo, tmp_count);
|
||||||
return oop;
|
return oop;
|
||||||
@ -381,9 +384,14 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_class_t _class, moo_oo
|
|||||||
|
|
||||||
if (oop)
|
if (oop)
|
||||||
{
|
{
|
||||||
|
moo_ooi_t spec;
|
||||||
MOO_OBJ_SET_CLASS (oop, _class);
|
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);
|
moo_popvolats (moo, tmp_count);
|
||||||
return oop;
|
return oop;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user