1 /* $Header$ */ 2 3 /* 4 * Copyright (c) 2000, 2002 Michael J. Roberts. All Rights Reserved. 5 * 6 * Please see the accompanying license file, LICENSE.TXT, for information 7 * on using and copying this software. 8 */ 9 /* 10 Name 11 vmanonfn.h - anonymous function metaclass 12 Function 13 The anonymous function metaclass is a subclass of the Vector metaclass 14 that provides encapsulation of an anonymous function and the context it 15 shares with its enclosing scope. 16 Notes 17 18 Modified 19 03/21/00 MJRoberts - Creation 20 */ 21 22 #ifndef VMANONFN_H 23 #define VMANONFN_H 24 25 #include <stdlib.h> 26 #include "vmtype.h" 27 #include "vmobj.h" 28 #include "vmvec.h" 29 #include "vmglob.h" 30 31 /* 32 * Anonymous Function Metaclass 33 */ 34 class CVmObjAnonFn: public CVmObjVector 35 { 36 friend class CVmMetaclassAnonFn; 37 38 public: 39 /* metaclass registration object */ 40 static class CVmMetaclass *metaclass_reg_; get_metaclass_reg()41 class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; } 42 43 /* am I of the given metaclass? */ is_of_metaclass(class CVmMetaclass * meta)44 virtual int is_of_metaclass(class CVmMetaclass *meta) const 45 { 46 /* try my own metaclass and my base class */ 47 return (meta == metaclass_reg_ 48 || CVmObjVector::is_of_metaclass(meta)); 49 } 50 51 /* is the given object an anonymous function object? */ is_anonfn_obj(VMG_ vm_obj_id_t obj)52 static int is_anonfn_obj(VMG_ vm_obj_id_t obj) 53 { return vm_objp(vmg_ obj)->is_of_metaclass(metaclass_reg_); } 54 55 /* create dynamically using stack arguments */ 56 static vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, 57 uint argc); 58 59 /* get a property */ 60 int get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val, 61 vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc); 62 63 /* check for equality - compare strictly by reference */ equals(VMG_ vm_obj_id_t self,const vm_val_t * val,int)64 int equals(VMG_ vm_obj_id_t self, const vm_val_t *val, int) const 65 { 66 /* return true if the other value is a reference to this object */ 67 return (val->typ == VM_OBJ && val->val.obj == self); 68 } 69 70 /* calculate a hash value */ calc_hash(VMG_ vm_obj_id_t self,int)71 uint calc_hash(VMG_ vm_obj_id_t self, int) const 72 { 73 /* we compare by reference, so hash by object ID */ 74 return (uint)(((ulong)self & 0xffff) 75 ^ (((ulong)self & 0xffff0000) >> 16)); 76 } 77 78 protected: 79 /* create an empty object */ CVmObjAnonFn()80 CVmObjAnonFn() { ext_ = 0; } 81 82 /* create with the given number of elements */ CVmObjAnonFn(VMG_ size_t cnt)83 CVmObjAnonFn(VMG_ size_t cnt) 84 : CVmObjVector(vmg_ cnt) 85 { 86 /* set to our full initial size */ 87 set_element_count(cnt); 88 } 89 }; 90 91 92 /* ------------------------------------------------------------------------ */ 93 /* 94 * Registration table object 95 */ 96 class CVmMetaclassAnonFn: public CVmMetaclass 97 { 98 public: 99 /* get the global name */ get_meta_name()100 const char *get_meta_name() const { return "anon-func-ptr/030000"; } 101 102 /* create from image file */ create_for_image_load(VMG_ vm_obj_id_t id)103 void create_for_image_load(VMG_ vm_obj_id_t id) 104 { 105 new (vmg_ id) CVmObjAnonFn(); 106 G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE); 107 } 108 109 /* create from restoring from saved state */ create_for_restore(VMG_ vm_obj_id_t id)110 void create_for_restore(VMG_ vm_obj_id_t id) 111 { 112 new (vmg_ id) CVmObjAnonFn(); 113 G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE); 114 } 115 116 /* create dynamically using stack arguments */ create_from_stack(VMG_ const uchar ** pc_ptr,uint argc)117 vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc) 118 { return CVmObjAnonFn::create_from_stack(vmg_ pc_ptr, argc); } 119 120 /* call a static property */ call_stat_prop(VMG_ vm_val_t * result,const uchar ** pc_ptr,uint * argc,vm_prop_id_t prop)121 int call_stat_prop(VMG_ vm_val_t *result, 122 const uchar **pc_ptr, uint *argc, 123 vm_prop_id_t prop) 124 { 125 /* fall back directly on the vector static property evaluator */ 126 return CVmObjVector::call_stat_prop(vmg_ result, pc_ptr, argc, prop); 127 } 128 129 /* I'm a Vector subclass */ get_supermeta_reg()130 CVmMetaclass *get_supermeta_reg() const 131 { return CVmObjVector::metaclass_reg_; } 132 }; 133 134 #endif /* VMANONFN_H */ 135 136 /* 137 * Register the class 138 */ 139 VM_REGISTER_METACLASS(CVmObjAnonFn) 140 141 142