/[svn]/linuxsampler/trunk/src/scriptvm/common.h
ViewVC logotype

Annotation of /linuxsampler/trunk/src/scriptvm/common.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2612 - (hide annotations) (download) (as text)
Tue Jun 10 13:32:16 2014 UTC (9 years, 10 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 14391 byte(s)
* Fixed crashes when exiting the sampler.
* Bumped version (1.0.0.svn47).

1 schoenebeck 2581 /*
2     * Copyright (c) 2014 Christian Schoenebeck
3     *
4     * http://www.linuxsampler.org
5     *
6     * This file is part of LinuxSampler and released under the same terms.
7     * See README file for details.
8     */
9    
10     // This header defines data types shared between the VM core implementation
11     // (inside the current source directory) and other parts of the sampler
12     // (located at other source directories).
13    
14     #ifndef LS_INSTR_SCRIPT_PARSER_COMMON_H
15     #define LS_INSTR_SCRIPT_PARSER_COMMON_H
16    
17     #include "../common/global.h"
18 schoenebeck 2588 #include <vector>
19 schoenebeck 2594 #include <map>
20     #include <stddef.h> // offsetof()
21 schoenebeck 2581
22     namespace LinuxSampler {
23    
24     enum ParserIssueType_t {
25     PARSER_ERROR,
26     PARSER_WARNING
27     };
28    
29     enum ExprType_t {
30     EMPTY_EXPR, ///< i.e. on invalid expressions or i.e. a function call that does not return a result value
31     INT_EXPR,
32     INT_ARR_EXPR,
33     STRING_EXPR,
34     STRING_ARR_EXPR,
35     };
36    
37     enum StmtFlags_t {
38     STMT_SUCCESS = 0, ///< Function / statement was executed successfully, no error occurred.
39     STMT_ABORT_SIGNALLED = 1, ///< VM should stop the current callback execution (usually because of an error, but might also be without an error reason).
40     STMT_SUSPEND_SIGNALLED = (1<<1),
41     STMT_ERROR_OCCURRED = (1<<2),
42     };
43    
44     enum VMExecStatus_t {
45     VM_EXEC_NOT_RUNNING = 0,
46     VM_EXEC_RUNNING = 1,
47     VM_EXEC_SUSPENDED = (1<<1),
48     VM_EXEC_ERROR = (1<<2),
49     };
50    
51 schoenebeck 2596 class VMIntExpr;
52     class VMStringExpr;
53    
54 schoenebeck 2581 class VMExpr {
55     public:
56     virtual ExprType_t exprType() const = 0;
57 schoenebeck 2596 VMIntExpr* asInt() const;
58     VMStringExpr* asString() const;
59 schoenebeck 2581 };
60    
61     class VMIntExpr : virtual public VMExpr {
62     public:
63     virtual int evalInt() = 0;
64     ExprType_t exprType() const { return INT_EXPR; }
65     };
66    
67     class VMStringExpr : virtual public VMExpr {
68     public:
69     virtual String evalStr() = 0;
70     ExprType_t exprType() const { return STRING_EXPR; }
71     };
72    
73     class VMFnArgs {
74     public:
75     virtual int argsCount() const = 0;
76     virtual VMExpr* arg(int i) = 0;
77     };
78    
79     class VMFnResult {
80     public:
81     virtual VMExpr* resultValue() = 0;
82     virtual StmtFlags_t resultFlags() { return STMT_SUCCESS; }
83     };
84    
85 schoenebeck 2612 /** @brief VM built-in function.
86     *
87     * Abstract base class for built-in script functions, defining the interface
88     * for all built-in script function implementations.
89     */
90 schoenebeck 2581 class VMFunction {
91     public:
92 schoenebeck 2612 /**
93     * Script data type of the function's return value. If the function does
94     * not return any value, then it returns EMPTY_EXPR here.
95     */
96 schoenebeck 2581 virtual ExprType_t returnType() = 0;
97 schoenebeck 2612
98     /**
99     * Minimum amount of function arguments this function accepts. If a
100     * script is calling this function with less arguments, the script
101     * parser will throw a parser error.
102     */
103 schoenebeck 2581 virtual int minRequiredArgs() const = 0;
104 schoenebeck 2612
105     /**
106     * Maximum amount of function arguments this functions accepts. If a
107     * script is calling this function with more arguments, the script
108     * parser will throw a parser error.
109     */
110 schoenebeck 2581 virtual int maxAllowedArgs() const = 0;
111 schoenebeck 2612
112     /**
113     * Script data type of the function's @c iArg 'th function argument.
114     * The information provided here is less strong than acceptsArgType().
115     * The parser will compare argument data types provided in scripts by
116     * calling cceptsArgType(). The return value of argType() is used by the
117     * parser instead to show an appropriate parser error which data type
118     * this function usually expects as "default" data type. Reason: a
119     * function may accept multiple data types for a certain function
120     * argument and would automatically cast the passed argument value in
121     * that case to the type it actually needs.
122     *
123     * @param iArg - index of the function argument in question
124     */
125 schoenebeck 2581 virtual ExprType_t argType(int iArg) const = 0;
126 schoenebeck 2612
127     /**
128     * This function is called by the parser to check whether arguments
129     * passed in scripts to this function are accepted by this function. If
130     * a script calls this function with an argument's data type not
131     * accepted by this function, the parser will throw a parser error.
132     *
133     * @param iArg - index of the function argument in question
134     * @param type - script data type used for this function argument by
135     * currently parsed script
136     */
137 schoenebeck 2581 virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;
138 schoenebeck 2612
139     /**
140     * Implements the actual function execution. This function is called by
141     * the VM when this function shall be executed at script runtime.
142     *
143     * @param args - function arguments for executing this built-in function
144     */
145 schoenebeck 2581 virtual VMFnResult* exec(VMFnArgs* args) = 0;
146 schoenebeck 2612
147     /**
148     * Concenience method for function implementations to show warning
149     * messages.
150     *
151     * @param txt - warning text
152     */
153 schoenebeck 2598 void wrnMsg(const String& txt);
154 schoenebeck 2612
155     /**
156     * Concenience method for function implementations to show error
157     * messages.
158     *
159     * @param txt - error text
160     */
161 schoenebeck 2598 void errMsg(const String& txt);
162 schoenebeck 2581 };
163    
164 schoenebeck 2594 /**
165     * POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be
166     * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.
167     */
168     struct VMRelPtr {
169     void** base; ///< Base pointer.
170     int offset; ///< Offset (in bytes) to base pointer.
171     };
172    
173     /** @brief Pointer to built-in VM integer variable (of C/C++ type int).
174     *
175     * Used for defining built-in integer script variables.
176     *
177     * @b CAUTION: You may only use this class for pointing to C/C++ variables
178     * of type "int" (which on most systems is 32 bit in size). If the C/C++ int
179     * variable you want to reference is only 8 bit in size, then you @b must
180     * use VMInt8RelPtr instead!
181     *
182     * For efficiency reasons the actual native C/C++ int variable is referenced
183     * by two components here. The actual native int C/C++ variable in memory
184     * is dereferenced at VM run-time by taking the @c base pointer dereference
185     * and adding @c offset bytes. This has the advantage that for a large
186     * number of built-in int variables, only one (or few) base pointer need
187     * to be re-assigned before running a script, instead of updating each
188     * built-in variable each time before a script is executed.
189     *
190     * Refer to DECLARE_VMINT() for example code.
191     *
192     * @see VMInt8RelPtr, DECLARE_VMINT()
193     */
194     struct VMIntRelPtr : VMRelPtr {
195     VMIntRelPtr() {
196     base = NULL;
197     offset = 0;
198     }
199     VMIntRelPtr(const VMRelPtr& data) {
200     base = data.base;
201     offset = data.offset;
202     }
203     virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }
204     virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }
205     };
206    
207     /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).
208     *
209     * Used for defining built-in integer script variables.
210     *
211     * @b CAUTION: You may only use this class for pointing to C/C++ variables
212     * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to
213     * reference is an "int" type (which is 32 bit on most systems), then you
214     * @b must use VMIntRelPtr instead!
215     *
216     * For efficiency reasons the actual native C/C++ int variable is referenced
217     * by two components here. The actual native int C/C++ variable in memory
218     * is dereferenced at VM run-time by taking the @c base pointer dereference
219     * and adding @c offset bytes. This has the advantage that for a large
220     * number of built-in int variables, only one (or few) base pointer need
221     * to be re-assigned before running a script, instead of updating each
222     * built-in variable each time before a script is executed.
223     *
224     * Refer to DECLARE_VMINT() for example code.
225     *
226     * @see VMIntRelPtr, DECLARE_VMINT()
227     */
228     struct VMInt8RelPtr : VMIntRelPtr {
229     VMInt8RelPtr() : VMIntRelPtr() {}
230     VMInt8RelPtr(const VMRelPtr& data) : VMIntRelPtr(data) {}
231     virtual int evalInt() OVERRIDE {
232     return *(uint8_t*)&(*(uint8_t**)base)[offset];
233     }
234     virtual void assign(int i) OVERRIDE {
235     *(uint8_t*)&(*(uint8_t**)base)[offset] = i;
236     }
237     };
238    
239     /**
240     * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr
241     * structures. Example:
242     * @code
243     * struct Foo {
244     * uint8_t a;
245     * int b;
246     * };
247     *
248     * Foo foo1 = (Foo) { 1, 3000 };
249     * Foo foo2 = (Foo) { 2, 4000 };
250     *
251     * Foo* pFoo;
252     *
253     * VMInt8RelPtr var1 = DECLARE_VMINT(pFoo, class Foo, a);
254     * VMIntRelPtr var2 = DECLARE_VMINT(pFoo, class Foo, b);
255     *
256     * pFoo = &foo1;
257     * printf("%d\n", var1->evalInt()); // will print 1
258     * printf("%d\n", var2->evalInt()); // will print 3000
259     *
260     * pFoo = &foo2;
261     * printf("%d\n", var1->evalInt()); // will print 2
262     * printf("%d\n", var2->evalInt()); // will print 4000
263     * @endcode
264     */
265     #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \
266     (VMRelPtr) { \
267     (void**) &basePtr, \
268     offsetof(T_struct, T_member) \
269     } \
270     ) \
271    
272     /** @brief Built-in VM 8 bit integer array variable.
273     *
274     * Used for defining built-in integer array script variables.
275     */
276     struct VMInt8Array {
277     int8_t* data;
278     int size;
279    
280     VMInt8Array() : data(NULL), size(0) {}
281     };
282    
283 schoenebeck 2612 /** @brief Provider for built-in script functions and variables.
284     *
285     * Abstract base class defining the interface for all classes which add and
286     * implement built-in script functions and built-in script variables.
287     */
288 schoenebeck 2581 class VMFunctionProvider {
289     public:
290 schoenebeck 2612 /**
291     * Returns pointer to the built-in function with the given function
292     * name, or NULL if there is no built-in function with that name.
293     *
294     * @param name - function name
295     */
296 schoenebeck 2581 virtual VMFunction* functionByName(const String& name) = 0;
297 schoenebeck 2612
298     /**
299     * Returns a variable name indexed map of all built-in script variables
300     * which point to native "int" (usually 32 bit) variables.
301     */
302 schoenebeck 2594 virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
303 schoenebeck 2612
304     /**
305     * Returns a variable name indexed map of all built-in script variables
306     * which point to native "int8_t" (8 bit) variables.
307     */
308 schoenebeck 2594 virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
309 schoenebeck 2612
310     /**
311     * Returns a variable name indexed map of all built-in constant script
312     * variables, which never change their value at runtime.
313     */
314 schoenebeck 2594 virtual std::map<String,int> builtInConstIntVariables() = 0;
315 schoenebeck 2581 };
316    
317 schoenebeck 2594 /** @brief Execution state of a virtual machine.
318     *
319     * An instance of this abstract base class represents exactly one execution
320     * state of a virtual machine. This encompasses most notably the VM
321 schoenebeck 2612 * execution stack, and VM polyphonic variables. It does not contain global
322     * variable. Global variables are contained in the VMParserContext object.
323     * You might see a VMExecContext object as one virtual thread of the virtual
324     * machine.
325 schoenebeck 2594 *
326 schoenebeck 2612 * In contrast to a VMParserContext, a VMExecContext is not tied to a
327     * ScriptVM instance. Thus you can use a VMExecContext with different
328     * ScriptVM instances, however not concurrently at the same time.
329     *
330 schoenebeck 2594 * @see VMParserContext
331     */
332 schoenebeck 2581 class VMExecContext {
333     public:
334     virtual ~VMExecContext() {}
335     virtual int suspensionTimeMicroseconds() const = 0;
336     };
337    
338     class VMEventHandler {
339     public:
340     virtual String eventHandlerName() const = 0;
341     };
342    
343     struct ParserIssue {
344     String txt;
345     int line;
346     ParserIssueType_t type;
347    
348     inline void dump() {
349     switch (type) {
350     case PARSER_ERROR:
351     printf("[ERROR] line %d: %s\n", line, txt.c_str());
352     break;
353     case PARSER_WARNING:
354     printf("[Warning] line %d: %s\n", line, txt.c_str());
355     break;
356     }
357     }
358    
359     inline bool isErr() const { return type == PARSER_ERROR; }
360     inline bool isWrn() const { return type == PARSER_WARNING; }
361     };
362    
363     inline String typeStr(const ExprType_t& type) {
364     switch (type) {
365     case EMPTY_EXPR: return "empty";
366     case INT_EXPR: return "integer";
367     case INT_ARR_EXPR: return "integer array";
368     case STRING_EXPR: return "string";
369     case STRING_ARR_EXPR: return "string array";
370     }
371     return "invalid";
372     }
373    
374 schoenebeck 2594 /** @brief Virtual machine representation of a script.
375     *
376     * An instance of this abstract base class represents a parsed script,
377     * translated into a virtual machine. You should first check if there were
378     * any parser errors. If there were any parser errors, you should refrain
379     * from executing the virtual machine. Otherwise if there were no parser
380     * errors (i.e. only warnings), then you might access one of the script's
381     * event handlers by i.e. calling eventHandlerByName() and pass the
382     * respective event handler to the ScriptVM class (or to one of its
383     * descendants) for execution.
384     *
385     * @see VMExecContext
386     */
387 schoenebeck 2588 class VMParserContext {
388     public:
389     virtual ~VMParserContext() {}
390     virtual std::vector<ParserIssue> issues() const = 0;
391     virtual std::vector<ParserIssue> errors() const = 0;
392     virtual std::vector<ParserIssue> warnings() const = 0;
393     virtual VMEventHandler* eventHandler(uint index) = 0;
394     virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
395     };
396    
397 schoenebeck 2581 } // namespace LinuxSampler
398    
399     #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC