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