1 /*
2  *   Copyright (c) 2002 by Michael J. Roberts.  All Rights Reserved.
3  *
4  *   Please see the accompanying license file, LICENSE.TXT, for information
5  *   on using and copying this software.
6  */
7 /*
8 Name
9   vmpat.h - regular-expression compiled pattern object
10 Function
11   Encapsulates a compiled regular expression as an object.  This object
12   allows a compiled regular expression to be saved for re-use; since regex
13   compilation is time-consuming, it's much more efficient to re-use a
14   compiled pattern in repeated searches than to recompile the expression
15   each time it's needed.
16 Notes
17 
18 Modified
19   08/27/02 MJRoberts  - Creation
20 */
21 
22 #ifndef VMPAT_H
23 #define VMPAT_H
24 
25 #include <stdlib.h>
26 #include <os.h>
27 #include "vmtype.h"
28 #include "vmobj.h"
29 #include "vmglob.h"
30 #include "vmregex.h"
31 
32 /* ------------------------------------------------------------------------ */
33 /*
34  *   Our serialized data stream, in both the image file and a saved file,
35  *   consists of:
36  *
37  *   DATAHOLDER src_val
38  *
39  *   'src_val' is the source value - this is the string that was compiled to
40  *   create the pattern.
41  */
42 
43 /* ------------------------------------------------------------------------ */
44 /*
45  *   Our in-memory extension consists of a simple structure with a pointer
46  *   to the compiled pattern data (the re_compiled_pattern structure) and
47  *   the original string value that was used to create the pattern (we hold
48  *   onto the original string mostly for debugging purposes).
49  */
50 struct vmobj_pat_ext
51 {
52     /* the compiled pattern data */
53     re_compiled_pattern *pat;
54 
55     /* the original pattern source string */
56     vm_val_t str;
57 };
58 
59 /* ------------------------------------------------------------------------ */
60 /*
61  *   Pattern intrinsic class
62  */
63 class CVmObjPattern: public CVmObject
64 {
65     friend class CVmMetaclassPattern;
66 
67 public:
68     /* metaclass registration object */
69     static class CVmMetaclass *metaclass_reg_;
get_metaclass_reg()70     class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; }
71 
72     /* am I of the given metaclass? */
is_of_metaclass(class CVmMetaclass * meta)73     virtual int is_of_metaclass(class CVmMetaclass *meta) const
74     {
75         /* try my own metaclass and my base class */
76         return (meta == metaclass_reg_
77                 || CVmObject::is_of_metaclass(meta));
78     }
79 
80     /* create dynamically using stack arguments */
81     static vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr,
82                                          uint argc);
83 
84     /*
85      *   call a static property - we don't have any of our own, so simply
86      *   "inherit" the base class handling
87      */
call_stat_prop(VMG_ vm_val_t * result,const uchar ** pc_ptr,uint * argc,vm_prop_id_t prop)88     static int call_stat_prop(VMG_ vm_val_t *result,
89                               const uchar **pc_ptr, uint *argc,
90                               vm_prop_id_t prop)
91     {
92         /* defer to our base class */
93         return CVmObject::call_stat_prop(vmg_ result, pc_ptr, argc, prop);
94     }
95 
96     /* notify of deletion */
97     void notify_delete(VMG_ int in_root_set);
98 
99     /* set a property */
100     void set_prop(VMG_ class CVmUndo *undo,
101                   vm_obj_id_t self, vm_prop_id_t prop, const vm_val_t *val);
102 
103     /* get a property */
104     int get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val,
105                  vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc);
106 
107     /* undo operations - we are immutable and hence keep no undo */
notify_new_savept()108     void notify_new_savept() { }
apply_undo(VMG_ struct CVmUndoRecord *)109     void apply_undo(VMG_ struct CVmUndoRecord *) { }
mark_undo_ref(VMG_ struct CVmUndoRecord *)110     void mark_undo_ref(VMG_ struct CVmUndoRecord *) { }
remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *)111     void remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *) { }
112 
113     /* mark references */
114     void mark_refs(VMG_ uint);
115 
116     /* remove stale weak references - we have no weak references */
remove_stale_weak_refs(VMG0_)117     void remove_stale_weak_refs(VMG0_) { }
118 
119     /* load from an image file */
120     void load_from_image(VMG_ vm_obj_id_t, const char *ptr, size_t);
121 
122     /* perform post-load initialization */
123     void post_load_init(VMG_ vm_obj_id_t self);
124 
125     /* rebuild for image file */
126     virtual ulong rebuild_image(VMG_ char *buf, ulong buflen);
127 
128     /* convert to constant data */
129     virtual void convert_to_const_data(VMG_ class CVmConstMapper *mapper,
130                                        vm_obj_id_t self);
131 
132     /* save to a file */
133     void save_to_file(VMG_ class CVmFile *fp);
134 
135     /* restore from a file */
136     void restore_from_file(VMG_ vm_obj_id_t self,
137                            class CVmFile *fp, class CVmObjFixup *fixup);
138 
139     /* get my compiled pattern */
get_pattern(VMG0_)140     re_compiled_pattern *get_pattern(VMG0_) { return get_ext()->pat; }
141 
142     /* am I a pattern object? */
is_pattern_obj(VMG_ vm_obj_id_t obj)143     static int is_pattern_obj(VMG_ vm_obj_id_t obj)
144         { return vm_objp(vmg_ obj)->is_of_metaclass(metaclass_reg_); }
145 
146 protected:
147     /* create with no extension */
CVmObjPattern()148     CVmObjPattern() { ext_ = 0; }
149 
150     /* create with a given pattern object and source string value */
151     CVmObjPattern(VMG_ re_compiled_pattern *pat, const vm_val_t *src_str);
152 
153     /* set my compiled pattern data structure */
set_pattern(re_compiled_pattern * pat)154     void set_pattern(re_compiled_pattern *pat) { get_ext()->pat = pat; }
155 
156     /* get/set my original source string value */
get_orig_str()157     const vm_val_t *get_orig_str() const { return &get_ext()->str; }
set_orig_str(const vm_val_t * val)158     void set_orig_str(const vm_val_t *val) { get_ext()->str = *val; }
159 
160     /* get my extension data */
get_ext()161     vmobj_pat_ext *get_ext() const { return (vmobj_pat_ext *)ext_; }
162 
163     /* property evaluator - undefined property */
getp_undef(VMG_ vm_obj_id_t,vm_val_t *,uint *)164     int getp_undef(VMG_ vm_obj_id_t, vm_val_t *, uint *) { return FALSE; }
165 
166     /* property evaluator - get my original string */
167     int getp_get_str(VMG_ vm_obj_id_t, vm_val_t *val, uint *argc);
168 
169     /* property evaluation function table */
170     static int (CVmObjPattern::*func_table_[])(VMG_ vm_obj_id_t self,
171                                                vm_val_t *retval, uint *argc);
172 };
173 
174 /* ------------------------------------------------------------------------ */
175 /*
176  *   Registration table object
177  */
178 class CVmMetaclassPattern: public CVmMetaclass
179 {
180 public:
181     /* get the global name */
get_meta_name()182     const char *get_meta_name() const { return "regex-pattern/030000"; }
183 
184     /* create from image file */
create_for_image_load(VMG_ vm_obj_id_t id)185     void create_for_image_load(VMG_ vm_obj_id_t id)
186     {
187         new (vmg_ id) CVmObjPattern();
188         G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE);
189     }
190 
191     /* create from restoring from saved state */
create_for_restore(VMG_ vm_obj_id_t id)192     void create_for_restore(VMG_ vm_obj_id_t id)
193     {
194         new (vmg_ id) CVmObjPattern();
195         G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE);
196     }
197 
198     /* create dynamically using stack arguments */
create_from_stack(VMG_ const uchar ** pc_ptr,uint argc)199     vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc)
200         { return CVmObjPattern::create_from_stack(vmg_ pc_ptr, argc); }
201 
202     /* call a static property */
call_stat_prop(VMG_ vm_val_t * result,const uchar ** pc_ptr,uint * argc,vm_prop_id_t prop)203     int call_stat_prop(VMG_ vm_val_t *result,
204                        const uchar **pc_ptr, uint *argc,
205                        vm_prop_id_t prop)
206     {
207         return CVmObjPattern::call_stat_prop(vmg_ result, pc_ptr, argc, prop);
208     }
209 };
210 
211 #endif /* VMPAT_H */
212 
213 /*
214  *   Register the class
215  */
216 VM_REGISTER_METACLASS(CVmObjPattern)
217 
218