1 /*
2  * Copyright (C) 2000-2005 Chris Ross and various contributors
3  * Copyright (C) 1999-2000 Chris Ross
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * o Redistributions of source code must retain the above copyright notice, this
10  *   list of conditions and the following disclaimer.
11  * o Redistributions in binary form must reproduce the above copyright notice,
12  *   this list of conditions and the following disclaimer in the documentation
13  *   and/or other materials provided with the distribution.
14  * o Neither the name of the ferite software nor the names of its contributors may
15  *   be used to endorse or promote products derived from this software without
16  *   specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef __FERITE_STRUCTS_H__
32 # define __FERITE_STRUCTS_H__
33 
34 /*
35  * The 'typedefs' for the structures. If you are going to play with ferite
36  * do it using the typedef's _not_ the raw structures.
37  */
38 typedef struct _ferite_hash_bucket                 FeriteHashBucket;
39 typedef struct _ferite_hash                        FeriteHash;
40 typedef struct _ferite_stack                       FeriteStack;
41 typedef struct _ferite_string                      FeriteString;
42 typedef struct _ferite_unified_array               FeriteUnifiedArray;
43 typedef struct _ferite_function                    FeriteFunction;
44 typedef struct _ferite_class                       FeriteClass;
45 typedef struct _ferite_script                      FeriteScript;
46 typedef struct _ferite_object                      FeriteObject;
47 typedef struct _ferite_object_variable             FeriteObjectVariable;
48 typedef struct _ferite_function_native_information FeriteFunctionNative;
49 typedef struct _ferite_parameter_record            FeriteParameterRecord;
50 typedef struct _ferite_variable                    FeriteVariable;
51 typedef struct _ferite_op                          FeriteOp;
52 typedef struct _ferite_op_function_data            FeriteOpFncData;
53 typedef struct _ferite_opcode_list                 FeriteOpcodeList;
54 typedef struct _ferite_iterator                    FeriteIterator;
55 typedef struct _ferite_buffer                      FeriteBuffer;
56 typedef struct _ferite_namespace                   FeriteNamespace;
57 typedef struct _ferite_execute_rec                 FeriteExecuteRec;
58 typedef struct _ferite_gc_generation               FeriteGCGeneration;
59 typedef struct _ferite_gen_gc                      FeriteGenGC;
60 typedef struct _ferite_std_gc                      FeriteStdGC;
61 typedef struct _ferite_thread                      FeriteThread;
62 typedef struct _ferite_thread_group                FeriteThreadGroup;
63 typedef struct _ferite_namespace_bucket            FeriteNamespaceBucket;
64 typedef struct _ferite_module                      FeriteModule;
65 typedef struct _ferite_regex                       FeriteRegex;
66 typedef struct _ferite_native_function_record      FeriteNativeFunctionRecord;
67 typedef struct _ferite_op_table                    FeriteOpTable;
68 typedef struct _ferite_compile_record              FeriteCompileRecord;
69 typedef struct _ferite_bk_req                      FeriteBkRequest;
70 typedef struct _ferite_variable_accessors          FeriteVariableAccessors;
71 typedef FeriteHash                                 FeriteVariableHash;
72 typedef void (*FeriteVariableGetAccessor)(FeriteScript*,FeriteVariable*);
73 typedef void (*FeriteVariableSetAccessor)(FeriteScript*,FeriteVariable*,FeriteVariable*);
74 typedef void (*FeriteVariableCleanupAccessor)(FeriteScript*,void*odata);
75 
76   /*
77  * The actual structures
78  */
79 
80 struct _ferite_stack
81 {
82     int    stack_ptr; /* The point where the top of the stack points too */
83     int    size;      /* The allocated size of the stack */
84     void **stack;     /* The stack itself */
85 };
86 
87 struct _ferite_string
88 {
89     size_t  length;     /* How long the string is */
90     int     encoding;   /* What encoding the string has, eg. Latin-1 or UTF-8 etc */
91     size_t  pos;        /* Current position within the string */
92 	char   *data;       /* The strings actual data */
93 };
94 
95 struct _ferite_variable_accessors
96 {
97     FeriteVariableGetAccessor      get;
98     FeriteVariableSetAccessor      set;
99     FeriteVariableCleanupAccessor  cleanup;
100     void                          *odata;
101     int                            owner;
102 };
103 
104 enum
105 {
106       FE_FLAG_DISPOSABLE = 1,   /* if we can nuke it */
107       FE_FLAG_FINAL = 2,        /* if it's a final variable */
108       FE_FLAG_FINALSET = 4,     /* if it's a final variable and has a value */
109       FE_FLAG_COMPILED = 8,     /* if it's a compiled in constant */
110       FE_FLAG_IS_STATIC = 16,   /* if the varaible is a static variable */
111       FE_FLAG_PLACEHOLDER = 32, /* if this var is just a placeholder in the stack */
112       FE_FLAG_STATIC_NAME = 64  /* if the variable name is allocated or not */
113 };
114 
115 struct _ferite_variable
116 {
117     short                    type;       /* The variables type */
118     short                    flags;      /* Enum flags as above */
119     short                    state;      /* Wether or not the variable is public, protected, private */
120     char                    *name;       /* It's name - used for hashing the variable and debug */
121     union
122     {
123         long                 lval; /* The value of the variable if it is a number [long] */
124         double               dval; /* The value of the variable if it is a number [double] */
125         FeriteString        *sval; /* Pointer to the value if it is a string */
126         FeriteObject        *oval; /* If it is an object, == NULL if it's not instantiated */
127         FeriteUnifiedArray  *aval; /* The array */
128         void                *pval; /* Used to sneak non-variable around the engine */
129         FeriteClass         *cval; /* A class */
130         FeriteNamespace     *nval; /* A namespace */
131     }
132     data;
133     long                     index;     /* It's index if it is in an array */
134     void                    *lock;      /* If the variable is 'atomic' this will be an AphexMutex */
135     short                    refcount;  /* The number of references to this variable */
136     FeriteVariableAccessors *accessors; /* Native variable accessors */
137 };
138 
139 struct _ferite_op_function_data
140 {
141     int             argument_count;  /* Number of arguements within the call */
142     int             is_autoload;     /* If the function is autoloaded */
143     FeriteFunction *function;        /* The function to call */
144 };
145 
146 struct _ferite_op
147 {
148     int   OP_TYPE;              /* The op's type */
149     void *opdata;               /* Usually a pointer to a char* which holds a name */
150     FeriteOpFncData *opdataf;   /* the function data we require */
151     long  addr;                 /* The address to jump to [depending on instruction] */
152     int   line;                 /* The line the op was generated from in the source - for error reporting */
153     int   block_depth;          /* block depth */
154 };
155 
156 struct _ferite_opcode_list
157 {
158     long       size;            /* Size of the opcodelist */
159     long       current_op_loc;  /* The current opcode we are pointing to, used when populating the list */
160     char      *filename;        /* The file in which the opcode list was generated */
161     FeriteOp **list;            /* The list */
162 };
163 
164 struct ferite_memory_block     /* This is used by the classic memory manager for debugging */
165 {
166     void   *data;               /* The allocated pointer */
167     int     size;               /* The size of the data allocated */
168     char   *file;               /* The .c file it was allocated in */
169     int     line;               /* The line it was allocated on */
170     struct ferite_memory_block *next;
171 };
172 
173 struct _ferite_bk_req  /* Used within the compiler for internal address resolving in loops and jumps */
174 {
175     FeriteOp *reqop;    /* The op that needs the address */
176     int       addr;     /* .. or an address to give to an op */
177     int       type;     /* The type of op/block this is for - sanity check */
178 };
179 
180 struct _ferite_hash_bucket
181 {
182     char *id;                /* The hash key of the bucket */
183     unsigned int hashval;    /* It's hashed value */
184     void *data;              /* The data it holds */
185     FeriteHashBucket *next;  /* The next bucket in the chain */
186 };
187 
188 struct _ferite_hash
189 {
190     int size;                /* Size of the hash */
191     FeriteHashBucket **hash; /* The top level hash list */
192 };
193 
194 struct _ferite_iterator /* Used to iterate through a hash */
195 {
196     int curindex;                 /* Current index within the hash */
197     FeriteHashBucket *curbucket;  /* The Current Bucket */
198 };
199 
200 struct _ferite_parameter_record /* Used in function signatures */
201 {
202     FeriteVariable *variable;          /* A variable do describe it */
203     int             has_default_value; /* If it has a default value - NB: not currently used */
204     int             pass_type;         /* either FE_BY_VALUE or FE_BY_REFERENCE */
205 };
206 
207 struct _ferite_function_native_information /* Stores the native code info for builder and ferite */
208 {
209     char *code;   /* The code in the block */
210     char *file;   /* The file it was declared in */
211     int   line;   /* The line it was declared on */
212 };
213 
214 struct _ferite_function  /* Encapsulate a native and script function */
215 {
216     char                   *name;      /* Name of the function */
217     char                   type;      /* It's type - see include/ferite/ffunction.h */
218     FeriteVariable         *(*fncPtr)( FeriteScript*,void*,FeriteObject*,FeriteFunction*,FeriteVariable**);
219                                        /* If it is native, it's function pointer */
220     FeriteFunctionNative   *native_information; /* The native infomation about the function */
221     void                   *odata;     /* If we happen to have any native data */
222     int                     arg_count; /* The number of arguments in the signature */
223     char                   is_static; /* If the function is a static class method */
224     FeriteParameterRecord **signature; /* Description of the functions' arguments */
225     FeriteStack            *localvars; /* Local variables in the function - script only */
226     FeriteOpcodeList       *ccode;     /* The compiled function body */
227     void                   *lock;      /* If the function is atomic this will be a AphexMutex */
228     FeriteClass            *klass;     /* The class that owns this function, NULL= a namespace function */
229     char                   state;      /* The state of the function - public, protected, private */
230     char                   is_alias;   /* The structure is an alias and therefore can't have it's members freed */
231     FeriteFunction         *next;
232 };
233 
234 struct _ferite_class
235 {
236     char               *name;           /* The name of the class */
237     long                id;             /* It's unique id in the engine - runtime generated */
238     short               state;          /* Abstract or final or protocol */
239     void               *odata;          /* If we happen to have any native data */
240     FeriteClass        *parent;         /* The class it inherits from */
241     FeriteVariableHash *object_vars;    /* The object's variables */
242     FeriteVariableHash *class_vars;     /* The class's variables */
243     FeriteHash         *object_methods; /* The class's functions */
244     FeriteHash         *class_methods;  /* The class's functions */
245     FeriteClass        *next;           /* The next class in the list - NB: not used at the moment */
246     FeriteNamespace    *container;      /* The namespace that the class resides in */
247     FeriteStack        *impl_list;      /* List that carries the protocol list */
248 };
249 
250 struct _ferite_object_variable
251 {
252     FeriteClass          *klass;
253     FeriteHash           *variables;
254     FeriteObjectVariable *parent;
255 };
256 
257 struct _ferite_object /* an actual instance of a FeriteClass */
258 {
259     char                 *name;       /* The objects name -> same as the class's name */
260     int                   oid;        /* It's id -> same as the class's id */
261     void                 *odata;      /* A pointer in each object that can be used by a programmer writing
262                                        * native code, this is _not_ touched by ferite. It is up to the
263                                        * programmer using it to clear things up
264                                        */
265     int                   refcount;   /* How many times the object is referenced */
266     FeriteClass          *klass;      /* the class template used */
267     FeriteObjectVariable *variables;  /* Instance variables */
268     FeriteHash           *functions;  /* A pointer to the class's function hash */
269 };
270 
271 struct _ferite_buffer /* Used to quickly build up data without reallocing data */
272 {
273    /* A buffer is a block of memory where this struct is placed first, and data are
274     * appended after the struct, so the 'void *ptr' must not be free'd */
275     size_t size;                /* The size of the this buffer page */
276     size_t count;               /* Number of bytes allocated from this page */
277     void *ptr;                  /* Pointer to where data begins */
278     FeriteBuffer *next;         /* The next buffer in the list */
279     FeriteBuffer *current;      /* The current buffer, is only used in the first page */
280 };
281 
282 struct _ferite_execute_rec  /* Used in the executor to bundle information together */
283 {
284     FeriteFunction     *function;       /* The function being executed */
285     FeriteVariable    **variable_list;  /* A duplicate of the function's local variable hash */
286     FeriteStack        *stack;          /* The function's local execution stack */
287     int                 block_depth;
288 };
289 
290 struct _ferite_gc_generation /* Used in the generational GC */
291 {
292     int size;                     /* Size of the generation */
293     int next_free;                /* The next free slot in the generation */
294     FeriteObject **contents;      /* The contents holds pointers to the objects */
295     FeriteGCGeneration *younger;  /* The generation younger than this one */
296     FeriteGCGeneration *older;    /* The generation older than this one */
297 };
298 
299 struct _ferite_std_gc /* Standard 'old skool' GC */
300 {
301     FeriteObject **contents; /* The contents holds pointers to the objects */
302     int            size;     /* Size of the GC */
303     int            count;    /* Number of objects within the GC */
304 };
305 
306 struct _ferite_thread
307 {
308     void         *ctxt;    /* actually an AphexThread* */
309     FeriteScript *script;  /* The script the thread is running in */
310     FeriteObject *obj;     /* The thread object that owns the thread */
311     int           running; /* Is it running ? */
312     int           referenced; /* true until a thread destructor is called */
313     int           pass_exceptions; /* Should we pass exceptions in the thread onto the parent script? */
314 };
315 
316 struct _ferite_thread_group /* Used to group running threads so a script wont exit until they
317                              * have finished */
318 {
319     void         *lock;         /* The lock */
320     FeriteStack  *thread_list;  /* The list of currently running threads. A thread gets added when the
321                                  * .start() method gets called */
322     FeriteScript *owner; /* The script that owns this thread_group */
323 };
324 
325 struct _ferite_script
326 {
327     /* once compiled these variables never change */
328     char               *filename;           /* The file the script was generated from */
329     char               *scripttext;         /* The contents of the script file - only used during compilation */
330     FeriteNamespace    *mainns;             /* The main namespace of the script */
331 
332     /* only these variables are altered */
333     FeriteStack        *include_list;       /* Absolute path list of all included modules */
334 
335     /* Threading stuff */
336     void               *lock;               /* Script based lock */
337     void               *gc_lock;            /* GC lock */
338     FeriteThreadGroup  *thread_group;       /* ... and it's thread group */
339     FeriteScript       *parent;             /* The parent script where the thread was executed from */
340 
341     /* Caching stuff */
342     FeriteStack        *vars;               /* Variable cache */
343     FeriteStack        *objects;            /* Object cache */
344     FeriteStack        *stacks;             /* Stack cache */
345 
346     /* error stuff */
347     char               *current_op_file;    /* File being executed in */
348     unsigned int        current_op_line;    /* Current line */
349     unsigned int        error_state;        /* The error state of the script */
350     unsigned int        keep_execution;     /* If FE_FALSE the script will stop running */
351     unsigned int        is_executing;       /* If the script is running */
352     unsigned int        is_being_deleted;   /* If the script is being deleted */
353     unsigned int        return_value;       /* The scripts return value */
354     unsigned int        stack_level;        /* How deep are we in execution depth? */
355     /* regex counting */
356     unsigned int        last_regex_count;   /* The number of captured strings last time round */
357 
358     FeriteBuffer        *error;             /* The error messages */
359     FeriteBuffer        *warning;           /* The warning messages */
360 
361     /* ferite gc */
362     void               *gc;                 /* The scripts GC */
363 
364     /* user information */
365     void               *odata;              /* A programmer can attach data to a script if they so wish */
366 };
367 
368 struct _ferite_namespace_bucket
369 {
370     int   type;  /* Type of data - see include/ferite/fns.h */
371     void *data;  /* The data */
372 };
373 
374 struct _ferite_namespace
375 {
376     char            *name;       /* The name of the namespace */
377     int              num;        /* Size of the namespace */
378     int             *code_fork_ref;
379     FeriteHash      *data_fork;
380     FeriteHash      *code_fork; /* The code hash! */
381     FeriteNamespace *container;  /* The namespace that holds this namespace */
382 };
383 
384 struct _ferite_module /* A native module that is loaded by ferite */
385 {
386     char *name;      /* Name of the module */
387     char *filename;  /* It's filename */
388     void *handle;    /* Pointer to the dl'd library */
389    /* These are the functions that a module must export to be 'ferite' friendly */
390     void (*module_register)();
391     void (*module_unregister)();
392     void (*module_init)( FeriteScript *script );
393     void (*module_deinit)( FeriteScript *script );
394     FeriteModule *next; /* Next module */
395 };
396 
397 struct _ferite_regex
398 {
399     char       *pattern;         /* original string pattern */
400     int         pcre_options;    /* pcre options */
401     int         fergx_options;   /* regex options we have to implement */
402     void       *compiled_re;     /* compiled regex */
403     char       *compile_buf;     /* the actual buffer to compile */
404     char       *swap_buf;        /* string to swap with */
405     void       *extra_info;      /* extra information */
406 };
407 
408 struct _ferite_unified_array
409 {
410     FeriteHash      *hash;        /* The hash keys are stored in this, strange huh? ;) */
411     FeriteVariable **array;       /* our array */
412     long             size;        /* where we are in the array */
413     long             actual_size; /* size of allocated memory */
414     long             iteration;   /* where we are currently sitting in the array */
415     void            *iterator;    /* the iterator on the array */
416     int              iterator_type; /* So we can maintain void on the iteration */
417 };
418 
419 struct _ferite_native_function_record /* This is used to register a native function when a module
420                                        * is loaded */
421 {
422     FeriteVariable *(*function)( FeriteScript *, void *, FeriteObject*, FeriteFunction*, FeriteVariable ** );
423 };
424 
425 struct _ferite_op_table /* Table of op-codes */
426 {
427     int    id;    /* Op ID - how it is refered to in the compiler */
428     char  *name;  /* Name of the op */
429     void  *ptr;   /* Pointer to it's function */
430 };
431 
432 struct _ferite_compile_record /* Used in the compiler */
433 {
434     FeriteFunction     *function;
435     FeriteStack        *variables;
436     FeriteClass        *cclass;
437     FeriteScript       *script;
438     FeriteNamespace    *ns;
439    FeriteStack *shadowed_local_variables;
440    FeriteStack *local_scope_frame;
441    FeriteHash  *local_variable_hash;
442    int in_closure;
443 };
444 
445 #endif /* __FERITE_STRUCTS_H__ */
446