23 |
namespace LinuxSampler { |
namespace LinuxSampler { |
24 |
|
|
25 |
/** |
/** |
26 |
|
* Native data type used by the script engine both internally, as well as |
27 |
|
* for all integer data types used by scripts (i.e. for all $foo variables |
28 |
|
* in NKSP scripts). Note that this is different from the original KSP which |
29 |
|
* is limited to 32 bit for integer variables in KSP scripts. |
30 |
|
*/ |
31 |
|
typedef int64_t vmint; |
32 |
|
|
33 |
|
/** |
34 |
|
* Native data type used internally by the script engine for all unsigned |
35 |
|
* integer types. This type is currently not exposed to scripts. |
36 |
|
*/ |
37 |
|
typedef uint64_t vmuint; |
38 |
|
|
39 |
|
/** |
40 |
* Identifies the type of a noteworthy issue identified by the script |
* Identifies the type of a noteworthy issue identified by the script |
41 |
* parser. That's either a parser error or parser warning. |
* parser. That's either a parser error or parser warning. |
42 |
*/ |
*/ |
95 |
* |
* |
96 |
* Identifies one of the possible event handler callback types defined by |
* Identifies one of the possible event handler callback types defined by |
97 |
* the NKSP script language. |
* the NKSP script language. |
98 |
|
* |
99 |
|
* IMPORTANT: this type is forced to be emitted as int32_t type ATM, because |
100 |
|
* that's the native size expected by the built-in instrument script |
101 |
|
* variable bindings (see occurrences of VMInt32RelPtr and DECLARE_VMINT |
102 |
|
* respectively. A native type mismatch between the two could lead to |
103 |
|
* undefined behavior! Background: By definition the C/C++ compiler is free |
104 |
|
* to choose a bit size for individual enums which it might find |
105 |
|
* appropriate, which is usually decided by the compiler according to the |
106 |
|
* biggest enum constant value defined (in practice it is usually 32 bit). |
107 |
*/ |
*/ |
108 |
enum VMEventHandlerType_t { |
enum VMEventHandlerType_t : int32_t { |
109 |
VM_EVENT_HANDLER_INIT, ///< Initilization event handler, that is script's "on init ... end on" code block. |
VM_EVENT_HANDLER_INIT, ///< Initilization event handler, that is script's "on init ... end on" code block. |
110 |
VM_EVENT_HANDLER_NOTE, ///< Note event handler, that is script's "on note ... end on" code block. |
VM_EVENT_HANDLER_NOTE, ///< Note event handler, that is script's "on note ... end on" code block. |
111 |
VM_EVENT_HANDLER_RELEASE, ///< Release event handler, that is script's "on release ... end on" code block. |
VM_EVENT_HANDLER_RELEASE, ///< Release event handler, that is script's "on release ... end on" code block. |
238 |
* Returns the result of this expression as integer (scalar) value. |
* Returns the result of this expression as integer (scalar) value. |
239 |
* This abstract method must be implemented by deriving classes. |
* This abstract method must be implemented by deriving classes. |
240 |
*/ |
*/ |
241 |
virtual int evalInt() = 0; |
virtual vmint evalInt() = 0; |
242 |
|
|
243 |
/** |
/** |
244 |
* Returns always INT_EXPR for instances of this class. |
* Returns always INT_EXPR for instances of this class. |
280 |
* Returns amount of elements in this array. This abstract method must |
* Returns amount of elements in this array. This abstract method must |
281 |
* be implemented by deriving classes. |
* be implemented by deriving classes. |
282 |
*/ |
*/ |
283 |
virtual int arraySize() const = 0; |
virtual vmint arraySize() const = 0; |
284 |
}; |
}; |
285 |
|
|
286 |
/** @brief Virtual Machine Integer Array Expression |
/** @brief Virtual Machine Integer Array Expression |
298 |
* |
* |
299 |
* @param i - array element index (must be between 0 .. arraySize() - 1) |
* @param i - array element index (must be between 0 .. arraySize() - 1) |
300 |
*/ |
*/ |
301 |
virtual int evalIntElement(uint i) = 0; |
virtual vmint evalIntElement(vmuint i) = 0; |
302 |
|
|
303 |
/** |
/** |
304 |
* Changes the current value of an element (given by array element |
* Changes the current value of an element (given by array element |
307 |
* @param i - array element index (must be between 0 .. arraySize() - 1) |
* @param i - array element index (must be between 0 .. arraySize() - 1) |
308 |
* @param value - new integer scalar value to be assigned to that array element |
* @param value - new integer scalar value to be assigned to that array element |
309 |
*/ |
*/ |
310 |
virtual void assignIntElement(uint i, int value) = 0; |
virtual void assignIntElement(vmuint i, vmint value) = 0; |
311 |
|
|
312 |
/** |
/** |
313 |
* Returns always INT_ARR_EXPR for instances of this class. |
* Returns always INT_ARR_EXPR for instances of this class. |
329 |
* Returns the amount of arguments going to be passed to the script |
* Returns the amount of arguments going to be passed to the script |
330 |
* function. |
* function. |
331 |
*/ |
*/ |
332 |
virtual int argsCount() const = 0; |
virtual vmint argsCount() const = 0; |
333 |
|
|
334 |
/** |
/** |
335 |
* Returns the respective argument (requested by argument index @a i) of |
* Returns the respective argument (requested by argument index @a i) of |
339 |
* |
* |
340 |
* @param i - function argument index (indexed from left to right) |
* @param i - function argument index (indexed from left to right) |
341 |
*/ |
*/ |
342 |
virtual VMExpr* arg(int i) = 0; |
virtual VMExpr* arg(vmint i) = 0; |
343 |
}; |
}; |
344 |
|
|
345 |
/** @brief Result value returned from a call to a built-in script function. |
/** @brief Result value returned from a call to a built-in script function. |
403 |
* script is calling this function with less arguments, the script |
* script is calling this function with less arguments, the script |
404 |
* parser will throw a parser error. |
* parser will throw a parser error. |
405 |
*/ |
*/ |
406 |
virtual int minRequiredArgs() const = 0; |
virtual vmint minRequiredArgs() const = 0; |
407 |
|
|
408 |
/** |
/** |
409 |
* Maximum amount of function arguments this functions accepts. If a |
* Maximum amount of function arguments this functions accepts. If a |
410 |
* script is calling this function with more arguments, the script |
* script is calling this function with more arguments, the script |
411 |
* parser will throw a parser error. |
* parser will throw a parser error. |
412 |
*/ |
*/ |
413 |
virtual int maxAllowedArgs() const = 0; |
virtual vmint maxAllowedArgs() const = 0; |
414 |
|
|
415 |
/** |
/** |
416 |
* Script data type of the function's @c iArg 'th function argument. |
* Script data type of the function's @c iArg 'th function argument. |
426 |
* @param iArg - index of the function argument in question |
* @param iArg - index of the function argument in question |
427 |
* (must be between 0 .. maxAllowedArgs() - 1) |
* (must be between 0 .. maxAllowedArgs() - 1) |
428 |
*/ |
*/ |
429 |
virtual ExprType_t argType(int iArg) const = 0; |
virtual ExprType_t argType(vmint iArg) const = 0; |
430 |
|
|
431 |
/** |
/** |
432 |
* This method is called by the parser to check whether arguments |
* This method is called by the parser to check whether arguments |
444 |
* @return true if the given data type would be accepted for the |
* @return true if the given data type would be accepted for the |
445 |
* respective function argument by the function |
* respective function argument by the function |
446 |
*/ |
*/ |
447 |
virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0; |
virtual bool acceptsArgType(vmint iArg, ExprType_t type) const = 0; |
448 |
|
|
449 |
/** |
/** |
450 |
* This method is called by the parser to check whether some arguments |
* This method is called by the parser to check whether some arguments |
459 |
* @param iArg - index of the function argument in question |
* @param iArg - index of the function argument in question |
460 |
* (must be between 0 .. maxAllowedArgs() - 1) |
* (must be between 0 .. maxAllowedArgs() - 1) |
461 |
*/ |
*/ |
462 |
virtual bool modifiesArg(int iArg) const = 0; |
virtual bool modifiesArg(vmint iArg) const = 0; |
463 |
|
|
464 |
/** |
/** |
465 |
* Implements the actual function execution. This exec() method is |
* Implements the actual function execution. This exec() method is |
493 |
|
|
494 |
/** @brief Virtual machine relative pointer. |
/** @brief Virtual machine relative pointer. |
495 |
* |
* |
496 |
* POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be |
* POD base of VMInt64RelPtr, VMInt32RelPtr and VMInt8RelPtr structures. Not |
497 |
* used directly. Use VMIntRelPtr or VMInt8RelPtr instead. |
* intended to be used directly. Use VMInt64RelPtr, VMInt32RelPtr, |
498 |
|
* VMInt8RelPtr instead. |
499 |
* |
* |
500 |
* @see VMIntRelPtr, VMInt8RelPtr |
* @see VMInt64RelPtr, VMInt32RelPtr, VMInt8RelPtr |
501 |
*/ |
*/ |
502 |
struct VMRelPtr { |
struct VMRelPtr { |
503 |
void** base; ///< Base pointer. |
void** base; ///< Base pointer. |
504 |
int offset; ///< Offset (in bytes) relative to base pointer. |
vmint offset; ///< Offset (in bytes) relative to base pointer. |
505 |
bool readonly; ///< Whether the pointed data may be modified or just be read. |
bool readonly; ///< Whether the pointed data may be modified or just be read. |
506 |
}; |
}; |
507 |
|
|
508 |
/** @brief Pointer to built-in VM integer variable (of C/C++ type int). |
/** @brief Pointer to built-in VM integer variable (interface class). |
509 |
|
* |
510 |
|
* This class acts as an abstract interface to all built-in integer script |
511 |
|
* variables, independent of their actual native size (i.e. some built-in |
512 |
|
* script variables are internally using a native int size of 64 bit or 32 |
513 |
|
* bit or 8 bit). The virtual machine is using this interface class instead |
514 |
|
* of its implementing descendants (VMInt64RelPtr, VMInt32RelPtr, |
515 |
|
* VMInt8RelPtr) in order for the virtual machine for not being required to |
516 |
|
* handle each of them differently. |
517 |
|
*/ |
518 |
|
struct VMIntPtr { |
519 |
|
virtual vmint evalInt() = 0; |
520 |
|
virtual void assign(vmint i) = 0; |
521 |
|
virtual bool isAssignable() const = 0; |
522 |
|
}; |
523 |
|
|
524 |
|
/** @brief Pointer to built-in VM integer variable (of C/C++ type int64_t). |
525 |
|
* |
526 |
|
* Used for defining built-in 64 bit integer script variables. |
527 |
|
* |
528 |
|
* @b CAUTION: You may only use this class for pointing to C/C++ variables |
529 |
|
* of type "int64_t" (thus being exactly 64 bit in size). If the C/C++ int |
530 |
|
* variable you want to reference is only 32 bit in size then you @b must |
531 |
|
* use VMInt32RelPtr instead! Respectively for a referenced native variable |
532 |
|
* with only 8 bit in size you @b must use VMInt8RelPtr instead! |
533 |
|
* |
534 |
|
* For efficiency reasons the actual native C/C++ int variable is referenced |
535 |
|
* by two components here. The actual native int C/C++ variable in memory |
536 |
|
* is dereferenced at VM run-time by taking the @c base pointer dereference |
537 |
|
* and adding @c offset bytes. This has the advantage that for a large |
538 |
|
* number of built-in int variables, only one (or few) base pointer need |
539 |
|
* to be re-assigned before running a script, instead of updating each |
540 |
|
* built-in variable each time before a script is executed. |
541 |
|
* |
542 |
|
* Refer to DECLARE_VMINT() for example code. |
543 |
|
* |
544 |
|
* @see VMInt32RelPtr, VMInt8RelPtr, DECLARE_VMINT() |
545 |
|
*/ |
546 |
|
struct VMInt64RelPtr : VMRelPtr, VMIntPtr { |
547 |
|
VMInt64RelPtr() { |
548 |
|
base = NULL; |
549 |
|
offset = 0; |
550 |
|
readonly = false; |
551 |
|
} |
552 |
|
VMInt64RelPtr(const VMRelPtr& data) { |
553 |
|
base = data.base; |
554 |
|
offset = data.offset; |
555 |
|
readonly = false; |
556 |
|
} |
557 |
|
vmint evalInt() OVERRIDE { |
558 |
|
return (vmint)*(int64_t*)&(*(uint8_t**)base)[offset]; |
559 |
|
} |
560 |
|
void assign(vmint i) OVERRIDE { |
561 |
|
*(int64_t*)&(*(uint8_t**)base)[offset] = (int64_t)i; |
562 |
|
} |
563 |
|
bool isAssignable() const OVERRIDE { return !readonly; } |
564 |
|
}; |
565 |
|
|
566 |
|
/** @brief Pointer to built-in VM integer variable (of C/C++ type int32_t). |
567 |
* |
* |
568 |
* Used for defining built-in 32 bit integer script variables. |
* Used for defining built-in 32 bit integer script variables. |
569 |
* |
* |
570 |
* @b CAUTION: You may only use this class for pointing to C/C++ variables |
* @b CAUTION: You may only use this class for pointing to C/C++ variables |
571 |
* of type "int" (which on most systems is 32 bit in size). If the C/C++ int |
* of type "int32_t" (thus being exactly 32 bit in size). If the C/C++ int |
572 |
* variable you want to reference is only 8 bit in size, then you @b must |
* variable you want to reference is 64 bit in size then you @b must use |
573 |
* use VMInt8RelPtr instead! |
* VMInt64RelPtr instead! Respectively for a referenced native variable with |
574 |
|
* only 8 bit in size you @b must use VMInt8RelPtr instead! |
575 |
* |
* |
576 |
* For efficiency reasons the actual native C/C++ int variable is referenced |
* For efficiency reasons the actual native C/C++ int variable is referenced |
577 |
* by two components here. The actual native int C/C++ variable in memory |
* by two components here. The actual native int C/C++ variable in memory |
583 |
* |
* |
584 |
* Refer to DECLARE_VMINT() for example code. |
* Refer to DECLARE_VMINT() for example code. |
585 |
* |
* |
586 |
* @see VMInt8RelPtr, DECLARE_VMINT() |
* @see VMInt64RelPtr, VMInt8RelPtr, DECLARE_VMINT() |
587 |
*/ |
*/ |
588 |
struct VMIntRelPtr : VMRelPtr { |
struct VMInt32RelPtr : VMRelPtr, VMIntPtr { |
589 |
VMIntRelPtr() { |
VMInt32RelPtr() { |
590 |
base = NULL; |
base = NULL; |
591 |
offset = 0; |
offset = 0; |
592 |
readonly = false; |
readonly = false; |
593 |
} |
} |
594 |
VMIntRelPtr(const VMRelPtr& data) { |
VMInt32RelPtr(const VMRelPtr& data) { |
595 |
base = data.base; |
base = data.base; |
596 |
offset = data.offset; |
offset = data.offset; |
597 |
readonly = false; |
readonly = false; |
598 |
} |
} |
599 |
virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; } |
vmint evalInt() OVERRIDE { |
600 |
virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; } |
return (vmint)*(int32_t*)&(*(uint8_t**)base)[offset]; |
601 |
|
} |
602 |
|
void assign(vmint i) OVERRIDE { |
603 |
|
*(int32_t*)&(*(uint8_t**)base)[offset] = (int32_t)i; |
604 |
|
} |
605 |
|
bool isAssignable() const OVERRIDE { return !readonly; } |
606 |
}; |
}; |
607 |
|
|
608 |
/** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t). |
/** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t). |
611 |
* |
* |
612 |
* @b CAUTION: You may only use this class for pointing to C/C++ variables |
* @b CAUTION: You may only use this class for pointing to C/C++ variables |
613 |
* of type "int8_t" (8 bit integer). If the C/C++ int variable you want to |
* of type "int8_t" (8 bit integer). If the C/C++ int variable you want to |
614 |
* reference is an "int" type (which is 32 bit on most systems), then you |
* reference is not exactly 8 bit in size then you @b must respectively use |
615 |
* @b must use VMIntRelPtr instead! |
* either VMInt32RelPtr for native 32 bit variables or VMInt64RelPtrl for |
616 |
|
* native 64 bit variables instead! |
617 |
* |
* |
618 |
* For efficiency reasons the actual native C/C++ int variable is referenced |
* For efficiency reasons the actual native C/C++ int variable is referenced |
619 |
* by two components here. The actual native int C/C++ variable in memory |
* by two components here. The actual native int C/C++ variable in memory |
625 |
* |
* |
626 |
* Refer to DECLARE_VMINT() for example code. |
* Refer to DECLARE_VMINT() for example code. |
627 |
* |
* |
628 |
* @see VMIntRelPtr, DECLARE_VMINT() |
* @see VMIntRel32Ptr, VMIntRel64Ptr, DECLARE_VMINT() |
629 |
*/ |
*/ |
630 |
struct VMInt8RelPtr : VMIntRelPtr { |
struct VMInt8RelPtr : VMRelPtr, VMIntPtr { |
631 |
VMInt8RelPtr() : VMIntRelPtr() {} |
VMInt8RelPtr() { |
632 |
VMInt8RelPtr(const VMRelPtr& data) : VMIntRelPtr(data) {} |
base = NULL; |
633 |
virtual int evalInt() OVERRIDE { |
offset = 0; |
634 |
return *(uint8_t*)&(*(uint8_t**)base)[offset]; |
readonly = false; |
635 |
|
} |
636 |
|
VMInt8RelPtr(const VMRelPtr& data) { |
637 |
|
base = data.base; |
638 |
|
offset = data.offset; |
639 |
|
readonly = false; |
640 |
|
} |
641 |
|
vmint evalInt() OVERRIDE { |
642 |
|
return (vmint)*(uint8_t*)&(*(uint8_t**)base)[offset]; |
643 |
} |
} |
644 |
virtual void assign(int i) OVERRIDE { |
void assign(vmint i) OVERRIDE { |
645 |
*(uint8_t*)&(*(uint8_t**)base)[offset] = i; |
*(uint8_t*)&(*(uint8_t**)base)[offset] = (uint8_t)i; |
646 |
} |
} |
647 |
|
bool isAssignable() const OVERRIDE { return !readonly; } |
648 |
}; |
}; |
649 |
|
|
650 |
|
/** @brief Pointer to built-in VM integer variable (of C/C++ type vmint). |
651 |
|
* |
652 |
|
* Use this typedef if the native variable to be pointed to is using the |
653 |
|
* typedef vmint. If the native C/C++ variable to be pointed to is using |
654 |
|
* another C/C++ type then better use one of VMInt64RelPtr or VMInt32RelPtr |
655 |
|
* instead. |
656 |
|
*/ |
657 |
|
typedef VMInt64RelPtr VMIntRelPtr; |
658 |
|
|
659 |
#if HAVE_CXX_EMBEDDED_PRAGMA_DIAGNOSTICS |
#if HAVE_CXX_EMBEDDED_PRAGMA_DIAGNOSTICS |
660 |
# define COMPILER_DISABLE_OFFSETOF_WARNING \ |
# define COMPILER_DISABLE_OFFSETOF_WARNING \ |
661 |
_Pragma("GCC diagnostic push") \ |
_Pragma("GCC diagnostic push") \ |
668 |
#endif |
#endif |
669 |
|
|
670 |
/** |
/** |
671 |
* Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr |
* Convenience macro for initializing VMInt64RelPtr, VMInt32RelPtr and |
672 |
* structures. Usage example: |
* VMInt8RelPtr structures. Usage example: |
673 |
* @code |
* @code |
674 |
* struct Foo { |
* struct Foo { |
675 |
* uint8_t a; // native representation of a built-in integer script variable |
* uint8_t a; // native representation of a built-in integer script variable |
676 |
* int b; // native representation of another built-in integer script variable |
* int64_t b; // native representation of another built-in integer script variable |
677 |
* int c; // native representation of another built-in integer script variable |
* int64_t c; // native representation of another built-in integer script variable |
678 |
* uint8_t d; // native representation of another built-in integer script variable |
* uint8_t d; // native representation of another built-in integer script variable |
679 |
* }; |
* }; |
680 |
* |
* |
685 |
* Foo* pFoo; |
* Foo* pFoo; |
686 |
* |
* |
687 |
* VMInt8RelPtr varA = DECLARE_VMINT(pFoo, class Foo, a); |
* VMInt8RelPtr varA = DECLARE_VMINT(pFoo, class Foo, a); |
688 |
* VMIntRelPtr varB = DECLARE_VMINT(pFoo, class Foo, b); |
* VMInt64RelPtr varB = DECLARE_VMINT(pFoo, class Foo, b); |
689 |
* VMIntRelPtr varC = DECLARE_VMINT(pFoo, class Foo, c); |
* VMInt64RelPtr varC = DECLARE_VMINT(pFoo, class Foo, c); |
690 |
* VMInt8RelPtr varD = DECLARE_VMINT(pFoo, class Foo, d); |
* VMInt8RelPtr varD = DECLARE_VMINT(pFoo, class Foo, d); |
691 |
* |
* |
692 |
* pFoo = &foo1; |
* pFoo = &foo1; |
721 |
) \ |
) \ |
722 |
|
|
723 |
/** |
/** |
724 |
* Same as DECLARE_VMINT(), but this one defines the VMIntRelPtr and |
* Same as DECLARE_VMINT(), but this one defines the VMInt64RelPtr, |
725 |
* VMInt8RelPtr structures to be of read-only type. That means the script |
* VMInt32RelPtr and VMInt8RelPtr structures to be of read-only type. |
726 |
* parser will abort any script at parser time if the script is trying to |
* That means the script parser will abort any script at parser time if the |
727 |
* modify such a read-only built-in variable. |
* script is trying to modify such a read-only built-in variable. |
728 |
* |
* |
729 |
* @b NOTE: this is only intended for built-in read-only variables that |
* @b NOTE: this is only intended for built-in read-only variables that |
730 |
* may change during runtime! If your built-in variable's data is rather |
* may change during runtime! If your built-in variable's data is rather |
752 |
*/ |
*/ |
753 |
struct VMInt8Array { |
struct VMInt8Array { |
754 |
int8_t* data; |
int8_t* data; |
755 |
int size; |
vmint size; |
756 |
bool readonly; ///< Whether the array data may be modified or just be read. |
bool readonly; ///< Whether the array data may be modified or just be read. |
757 |
|
|
758 |
VMInt8Array() : data(NULL), size(0), readonly(false) {} |
VMInt8Array() : data(NULL), size(0), readonly(false) {} |
916 |
* Returns a variable name indexed map of all built-in script variables |
* Returns a variable name indexed map of all built-in script variables |
917 |
* which point to native "int" scalar (usually 32 bit) variables. |
* which point to native "int" scalar (usually 32 bit) variables. |
918 |
*/ |
*/ |
919 |
virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0; |
virtual std::map<String,VMIntPtr*> builtInIntVariables() = 0; |
920 |
|
|
921 |
/** |
/** |
922 |
* Returns a variable name indexed map of all built-in script integer |
* Returns a variable name indexed map of all built-in script integer |
928 |
* Returns a variable name indexed map of all built-in constant script |
* Returns a variable name indexed map of all built-in constant script |
929 |
* variables, which never change their value at runtime. |
* variables, which never change their value at runtime. |
930 |
*/ |
*/ |
931 |
virtual std::map<String,int> builtInConstIntVariables() = 0; |
virtual std::map<String,vmint> builtInConstIntVariables() = 0; |
932 |
|
|
933 |
/** |
/** |
934 |
* Returns a variable name indexed map of all built-in dynamic variables, |
* Returns a variable name indexed map of all built-in dynamic variables, |
977 |
* |
* |
978 |
* @see ScriptVM::exec() |
* @see ScriptVM::exec() |
979 |
*/ |
*/ |
980 |
virtual int suspensionTimeMicroseconds() const = 0; |
virtual vmint suspensionTimeMicroseconds() const = 0; |
981 |
|
|
982 |
/** |
/** |
983 |
* Causes all polyphonic variables to be reset to zero values. A |
* Causes all polyphonic variables to be reset to zero values. A |