diff --git a/moo/README.md b/moo/README.md index b558a5c..d7c5a55 100644 --- a/moo/README.md +++ b/moo/README.md @@ -84,6 +84,16 @@ X new -> create an object with 2 words. X new: 4 -> create an object with 6 words. ``` +if an object is asked to instantiate with trailer in the class defintion, it becomes +uncopyable, without the #uncopyable attribute. + +``` +class Shader(Object) from 'shader' +{ +// if the shaer module calls moo_setclasstrsize(), an instance of Shader is uncopyable +} +``` + ### Flow Control ``` k := if (i < 20) { 30 } else { 40 }. diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 0bb6613..04c7c83 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -646,7 +646,7 @@ int moo_ignite (moo_t* moo, moo_oow_t heapsz) moo->_nil = moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t)); if (!moo->_nil) goto oops; - moo->_nil->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 1, moo->igniting, 0, 0, 0, 0); + moo->_nil->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 1, moo->igniting, 0, 0, 0, 0, 0); moo->_nil->_size = 0; if (ignite_1(moo) <= -1 || ignite_2(moo) <= -1 || ignite_3(moo)) goto oops;; @@ -1126,10 +1126,10 @@ 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_UNCOPYABLE(oop) || MOO_OBJ_GET_FLAGS_TRAILER(oop)) + if (MOO_OBJ_GET_FLAGS_UNCOPYABLE(oop)) { /* 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, "uncopyable object"); return MOO_NULL; } diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 3d98c86..c3ca3dc 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -361,16 +361,17 @@ typedef enum moo_gcfin_t moo_gcfin_t; /* [NOTE] this macro doesn't check the range of the actual value. * make sure that the value of each bit fields given falls within the * possible range of the defined bits */ -#define MOO_OBJ_MAKE_FLAGS(_ty,_u,_e,_k,_p,_m,_g,_tr,_h) ( \ - (((moo_oow_t)(_ty)) << MOO_OBJ_FLAGS_TYPE_SHIFT) | \ - (((moo_oow_t)(_u)) << MOO_OBJ_FLAGS_UNIT_SHIFT) | \ - (((moo_oow_t)(_e)) << MOO_OBJ_FLAGS_EXTRA_SHIFT) | \ - (((moo_oow_t)(_k)) << MOO_OBJ_FLAGS_KERNEL_SHIFT) | \ - (((moo_oow_t)(_p)) << MOO_OBJ_FLAGS_PERM_SHIFT) | \ - (((moo_oow_t)(_m)) << MOO_OBJ_FLAGS_MOVED_SHIFT) | \ - (((moo_oow_t)(_g)) << MOO_OBJ_FLAGS_PROC_SHIFT) | \ - (((moo_oow_t)(_tr)) << MOO_OBJ_FLAGS_TRAILER_SHIFT) | \ - (((moo_oow_t)(_h)) << MOO_OBJ_FLAGS_HASH_SHIFT) \ +#define MOO_OBJ_MAKE_FLAGS(_ty,_u,_e,_k,_p,_m,_g,_tr,_h,_uncp) ( \ + (((moo_oow_t)(_ty)) << MOO_OBJ_FLAGS_TYPE_SHIFT) | \ + (((moo_oow_t)(_u)) << MOO_OBJ_FLAGS_UNIT_SHIFT) | \ + (((moo_oow_t)(_e)) << MOO_OBJ_FLAGS_EXTRA_SHIFT) | \ + (((moo_oow_t)(_k)) << MOO_OBJ_FLAGS_KERNEL_SHIFT) | \ + (((moo_oow_t)(_p)) << MOO_OBJ_FLAGS_PERM_SHIFT) | \ + (((moo_oow_t)(_m)) << MOO_OBJ_FLAGS_MOVED_SHIFT) | \ + (((moo_oow_t)(_g)) << MOO_OBJ_FLAGS_PROC_SHIFT) | \ + (((moo_oow_t)(_tr)) << MOO_OBJ_FLAGS_TRAILER_SHIFT) | \ + (((moo_oow_t)(_h)) << MOO_OBJ_FLAGS_HASH_SHIFT) | \ + (((moo_oow_t)(_uncp)) << MOO_OBJ_FLAGS_UNCOPYABLE_SHIFT) \ ) #define MOO_OBJ_FLAGS_KERNEL_USER 0 /* not a kernel object */ diff --git a/moo/lib/obj.c b/moo/lib/obj.c index ad703bf..e4ff146 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -76,7 +76,7 @@ moo_oop_t moo_allocoopobj (moo_t* moo, moo_oow_t size) hdr = (moo_oop_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); if (!hdr) return MOO_NULL; - hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 0, 0); + hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 0, 0, 0); MOO_OBJ_SET_SIZE (hdr, size); MOO_OBJ_SET_CLASS (hdr, moo->_nil); @@ -102,7 +102,7 @@ moo_oop_t moo_allocoopobjwithtrailer (moo_t* moo, moo_oow_t size, const moo_oob_ hdr = (moo_oop_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); if (!hdr) return MOO_NULL; - hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 1, 0); /* TRAILER bit -> 1 */ + hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 1, 0, 1); /* TRAILER -> 1, UNCOPYABLE -> 1 */ MOO_OBJ_SET_SIZE (hdr, size); MOO_OBJ_SET_CLASS (hdr, moo->_nil); @@ -149,7 +149,7 @@ static MOO_INLINE moo_oop_t alloc_numeric_array (moo_t* moo, const void* ptr, mo hdr = (moo_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); if (!hdr) return MOO_NULL; - hdr->_flags = MOO_OBJ_MAKE_FLAGS(type, unit, extra, 0, moo->igniting, 0, 0, 0, 0); /* TODO: review. ngc and perm flags seems to conflict with each other ... the diff is that ngc is malloc() and perm is allocated in the perm heap */ + hdr->_flags = MOO_OBJ_MAKE_FLAGS(type, unit, extra, 0, moo->igniting, 0, 0, 0, 0, 0); /* TODO: review. ngc and perm flags seems to conflict with each other ... the diff is that ngc is malloc() and perm is allocated in the perm heap */ hdr->_size = len; MOO_OBJ_SET_SIZE (hdr, len); MOO_OBJ_SET_CLASS (hdr, moo->_nil); @@ -388,8 +388,9 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_class_t _class, moo_oo MOO_OBJ_SET_CLASS (oop, _class); 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); + /* the object with trailer is to to uncopyable in moo_allocoopobjwithtrailer() so no need to check/set it again here + if (MOO_CLASS_SPEC_IS_UNCOPYABLE(spec)) MOO_OBJ_SET_FLAGS_UNCOPYABLE (oop, 1); + */ } moo_popvolats (moo, tmp_count);