1 /* $Header$ */ 2 3 /* Copyright (c) 2000, 2002 Michael J. Roberts. All Rights Reserved. */ 4 /* 5 Name 6 vmintcls.h - T3 metaclass - intrinsic class 7 Function 8 9 Notes 10 11 Modified 12 03/08/00 MJRoberts - Creation 13 */ 14 15 #ifndef VMINTCLS_H 16 #define VMINTCLS_H 17 18 19 #include <stdlib.h> 20 21 #include "vmtype.h" 22 #include "vmobj.h" 23 #include "vmglob.h" 24 25 /* 26 * An IntrinsicClass object represents the class of an instance of an 27 * intrinsic class. For example, if we create a BigNumber instance, 28 * then ask for its class, the result is the IntrinsicClass object 29 * associated with the BigNumber intrinsic class: 30 * 31 * Each metaclass in the metaclass dependency table will be associated 32 * with an IntrinsicClass object. 33 * 34 * The image file format for an IntrinsicClass object consists of the 35 * following: 36 * 37 * UINT2 byte_count (currently, this is always 8) 38 *. UINT2 metaclass_dependency_table_index 39 *. UINT4 modifier_object_id 40 */ 41 42 /* 43 * intrinsic class object 44 */ 45 class CVmObjClass: public CVmObject 46 { 47 friend class CVmMetaclassClass; 48 49 public: 50 /* metaclass registration object */ 51 static class CVmMetaclass *metaclass_reg_; get_metaclass_reg()52 class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; } 53 54 /* am I of the given metaclass? */ is_of_metaclass(class CVmMetaclass * meta)55 virtual int is_of_metaclass(class CVmMetaclass *meta) const 56 { 57 /* try my own metaclass and my base class */ 58 return (meta == metaclass_reg_ 59 || CVmObject::is_of_metaclass(meta)); 60 } 61 62 /* is the given object an IntrinsicClass object? */ is_intcls_obj(VMG_ vm_obj_id_t obj)63 static int is_intcls_obj(VMG_ vm_obj_id_t obj) 64 { return vm_objp(vmg_ obj)->is_of_metaclass(metaclass_reg_); } 65 66 /* create dynamically using stack arguments */ 67 static vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, 68 uint argc); 69 70 /* create for a given dependency table index */ 71 static vm_obj_id_t create_dyn(VMG_ uint meta_idx); 72 73 /* 74 * call a static property - we don't have any of our own, so simply 75 * "inherit" the base class handling 76 */ call_stat_prop(VMG_ vm_val_t * result,const uchar ** pc_ptr,uint * argc,vm_prop_id_t prop)77 static int call_stat_prop(VMG_ vm_val_t *result, 78 const uchar **pc_ptr, uint *argc, 79 vm_prop_id_t prop) 80 { return CVmObject::call_stat_prop(vmg_ result, pc_ptr, argc, prop); } 81 82 /* determine if I'm an instance of the given object */ 83 virtual int is_instance_of(VMG_ vm_obj_id_t obj); 84 85 /* get superclass information */ 86 int get_superclass_count(VMG_ vm_obj_id_t self) const; 87 vm_obj_id_t get_superclass(VMG_ vm_obj_id_t self, int idx) const; 88 89 /* 90 * Determine if this is a class object. All intrinsic class objects 91 * indicate true. 92 */ is_class_object(VMG_ vm_obj_id_t)93 virtual int is_class_object(VMG_ vm_obj_id_t /*self*/) const 94 { return TRUE; } 95 96 /* reserve constant data */ reserve_const_data(VMG_ class CVmConstMapper * mapper,vm_obj_id_t self)97 virtual void reserve_const_data(VMG_ class CVmConstMapper *mapper, 98 vm_obj_id_t self) 99 { 100 /* 101 * we reference no other data and cannot be converted to constant 102 * data ourselves, so there's nothing to do here 103 */ 104 } 105 106 /* convert to constant data */ convert_to_const_data(VMG_ class CVmConstMapper * mapper,vm_obj_id_t self)107 virtual void convert_to_const_data(VMG_ class CVmConstMapper *mapper, 108 vm_obj_id_t self) 109 { 110 /* 111 * we reference no other data and cannot be converted to constant 112 * data ourselves, so there's nothing to do here 113 */ 114 } 115 116 /* create with no initial contents */ 117 static vm_obj_id_t create(VMG_ int in_root_set); 118 119 /* notify of deletion */ 120 void notify_delete(VMG_ int in_root_set); 121 122 /* set a property */ 123 void set_prop(VMG_ class CVmUndo *undo, 124 vm_obj_id_t self, vm_prop_id_t prop, const vm_val_t *val); 125 126 /* get a property */ 127 int get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val, 128 vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc); 129 130 /* build a list of my properties */ 131 void build_prop_list(VMG_ vm_obj_id_t self, vm_val_t *retval); 132 133 /* undo operations - classes are immutable and hence keep no undo */ notify_new_savept()134 void notify_new_savept() { } apply_undo(VMG_ struct CVmUndoRecord *)135 void apply_undo(VMG_ struct CVmUndoRecord *) { } mark_undo_ref(VMG_ struct CVmUndoRecord *)136 void mark_undo_ref(VMG_ struct CVmUndoRecord *) { } remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *)137 void remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *) { } 138 139 /* mark references - we have none */ mark_refs(VMG_ uint)140 void mark_refs(VMG_ uint) { } 141 142 /* remove weak references - we have none */ remove_stale_weak_refs(VMG0_)143 void remove_stale_weak_refs(VMG0_) { } 144 145 /* load from an image file */ 146 void load_from_image(VMG_ vm_obj_id_t self, const char *ptr, size_t siz); 147 148 /* rebuild for image file */ 149 virtual ulong rebuild_image(VMG_ char *buf, ulong buflen); 150 151 /* save to a file */ 152 void save_to_file(VMG_ class CVmFile *fp); 153 154 /* restore from a file */ 155 void restore_from_file(VMG_ vm_obj_id_t self, 156 class CVmFile *fp, class CVmObjFixup *fixups); 157 158 /* reset to the initial load state */ 159 void reset_to_image(VMG_ vm_obj_id_t self); 160 161 /* get the user modifier object for the intrinsic class */ get_mod_obj()162 vm_obj_id_t get_mod_obj() const 163 { 164 /* return the modifier object ID from our extension */ 165 return (vm_obj_id_t)osrp4(ext_ + 4); 166 } 167 168 /* 169 * find the intrinsic class for the given modifier object, searching 170 * myself and my intrinsic superclasses 171 */ 172 vm_obj_id_t find_mod_src_obj(VMG_ vm_obj_id_t self, vm_obj_id_t mod_obj); 173 174 protected: 175 /* create with no initial contents */ CVmObjClass()176 CVmObjClass() { ext_ = 0; } 177 178 /* create with a given dependency table index */ 179 CVmObjClass(VMG_ int in_root_set, uint meta_idx, vm_obj_id_t self); 180 181 /* 182 * get my metaclass registration table index - this can be compared to 183 * the metaclass_reg_ element for a given C++ intrinsic class 184 * implementation to determine if this intrinsic class object is the 185 * intrinsic class object for a given C++ intrinsic class 186 */ get_meta_idx()187 uint get_meta_idx() const { return osrp2(ext_ + 2); } 188 189 /* get my metaclass table entry */ 190 struct vm_meta_entry_t *get_meta_entry(VMG0_) const; 191 192 /* list our intrinsic class's properties */ 193 size_t list_class_props(VMG_ vm_obj_id_t self, 194 struct vm_meta_entry_t *entry, 195 class CVmObjList *lst, size_t starting_idx, 196 int static_only); 197 198 /* 199 * Find the intrinsic class for the given modifier object. We override 200 * this because we want an intrinsic class's effective intrinsic class 201 * to be its intrinsic superclass, not its metaclass. The metaclass of 202 * an intrinsic class object is always IntrinsicClass; instead, we want 203 * to see, for example, List->Collection->Object, which is the 204 * intrinsic superclass hierarchy. 205 */ find_intcls_for_mod(VMG_ vm_obj_id_t self,vm_obj_id_t mod_obj)206 vm_obj_id_t find_intcls_for_mod(VMG_ vm_obj_id_t self, 207 vm_obj_id_t mod_obj) 208 { 209 /* 210 * The implementation is very simple: just look for a modifier 211 * object attached to this object or one of its intrinsic 212 * superclasses. The difference between this and the regular 213 * CVmObject implementation is that the CVmObject implementation 214 * looks in the object's metaclass; we simply look in our intrinsic 215 * superclasses directly, since, for reflection purposes, we are 216 * our own metaclass. 217 */ 218 return find_mod_src_obj(vmg_ self, mod_obj); 219 } 220 221 /* 222 * search for a property among our modifiers, searching our own 223 * modifier and modifiers for our superclasses 224 */ 225 int get_prop_from_mod(VMG_ vm_prop_id_t prop, vm_val_t *val, 226 vm_obj_id_t self, vm_obj_id_t *source_obj, 227 uint *argc); 228 229 /* register myself with the dependency table */ 230 void register_meta(VMG_ vm_obj_id_t self); 231 }; 232 233 /* ------------------------------------------------------------------------ */ 234 /* 235 * Registration table object 236 */ 237 class CVmMetaclassClass: public CVmMetaclass 238 { 239 public: 240 /* get the global name */ get_meta_name()241 const char *get_meta_name() const { return "intrinsic-class/030000"; } 242 243 /* create from image file */ create_for_image_load(VMG_ vm_obj_id_t id)244 void create_for_image_load(VMG_ vm_obj_id_t id) 245 { 246 new (vmg_ id) CVmObjClass(); 247 G_obj_table->set_obj_gc_characteristics(id, FALSE, FALSE); 248 } 249 250 /* create from restoring from saved state */ create_for_restore(VMG_ vm_obj_id_t id)251 void create_for_restore(VMG_ vm_obj_id_t id) 252 { 253 new (vmg_ id) CVmObjClass(); 254 G_obj_table->set_obj_gc_characteristics(id, FALSE, FALSE); 255 } 256 257 /* create dynamically using stack arguments */ create_from_stack(VMG_ const uchar ** pc_ptr,uint argc)258 vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc) 259 { return CVmObjClass::create_from_stack(vmg_ pc_ptr, argc); } 260 261 /* call a static property */ call_stat_prop(VMG_ vm_val_t * result,const uchar ** pc_ptr,uint * argc,vm_prop_id_t prop)262 int call_stat_prop(VMG_ vm_val_t *result, 263 const uchar **pc_ptr, uint *argc, 264 vm_prop_id_t prop) 265 { 266 return CVmObjClass::call_stat_prop(vmg_ result, pc_ptr, argc, prop); 267 } 268 }; 269 270 #endif /* VMINTCLS_H */ 271 272 /* 273 * Register the class 274 */ 275 VM_REGISTER_METACLASS(CVmObjClass) 276