--- linuxsampler/trunk/src/scriptvm/CoreVMFunctions.cpp 2017/05/26 18:55:45 3222 +++ linuxsampler/trunk/src/scriptvm/CoreVMFunctions.cpp 2019/08/23 11:44:00 3561 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Christian Schoenebeck + * Copyright (c) 2014-2019 Christian Schoenebeck * * http://www.linuxsampler.org * @@ -15,6 +15,7 @@ #include #include "tree.h" #include "ScriptVM.h" +#include "../common/RTMath.h" namespace LinuxSampler { @@ -34,13 +35,13 @@ /////////////////////////////////////////////////////////////////////////// // class VMIntResultFunction -VMFnResult* VMIntResultFunction::errorResult(int i) { +VMFnResult* VMIntResultFunction::errorResult(vmint i) { result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); result.value = i; return &result; } -VMFnResult* VMIntResultFunction::successResult(int i) { +VMFnResult* VMIntResultFunction::successResult(vmint i) { result.flags = STMT_SUCCESS; result.value = i; return &result; @@ -64,22 +65,24 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: message() -bool CoreVMFunction_message::acceptsArgType(int iArg, ExprType_t type) const { +bool CoreVMFunction_message::acceptsArgType(vmint iArg, ExprType_t type) const { return type == INT_EXPR || type == STRING_EXPR; } VMFnResult* CoreVMFunction_message::exec(VMFnArgs* args) { if (!args->argsCount()) return errorResult(); + uint64_t usecs = RTMath::unsafeMicroSeconds(RTMath::real_clock); + VMStringExpr* strExpr = dynamic_cast(args->arg(0)); if (strExpr) { - std::cout << "[ScriptVM] " << strExpr->evalStr() << "\n"; + printf("[ScriptVM %.3f] %s\n", usecs/1000000.f, strExpr->evalStr().c_str()); return successResult(); } VMIntExpr* intExpr = dynamic_cast(args->arg(0)); if (intExpr) { - std::cout << "[ScriptVM] " << intExpr->evalInt() << "\n"; + printf("[ScriptVM %.3f] %lld\n", usecs/1000000.f, (int64_t)intExpr->evalInt()); return successResult(); } @@ -89,18 +92,53 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: exit() +vmint CoreVMFunction_exit::maxAllowedArgs() const { + return (vm->isExitResultEnabled()) ? 1 : 0; +} + +bool CoreVMFunction_exit::acceptsArgType(vmint iArg, ExprType_t type) const { + if (!vm->isExitResultEnabled()) return false; + return type == INT_EXPR || type == STRING_EXPR; +} + VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) { this->result.flags = STMT_ABORT_SIGNALLED; + if (vm->isExitResultEnabled() && args->argsCount()) { + ExecContext* ctx = dynamic_cast(vm->currentVMExecContext()); + switch (args->arg(0)->exprType()) { + case INT_EXPR: + ctx->exitRes.intLiteral.value = args->arg(0)->asInt()->evalInt(); + ctx->exitRes.value = &ctx->exitRes.intLiteral; + break; + case STRING_EXPR: + ctx->exitRes.stringLiteral.value = args->arg(0)->asString()->evalStr(); + ctx->exitRes.value = &ctx->exitRes.stringLiteral; + break; + default: + ; // noop - just to shut up the compiler + } + } return &result; } /////////////////////////////////////////////////////////////////////////// // built-in script function: wait() +bool CoreVMFunction_wait::acceptsArgUnitType(vmint iArg, StdUnit_t type) const { + if (iArg == 0) + return type == VM_NO_UNIT || type == VM_SECOND; + else + return type == VM_NO_UNIT; +} + +bool CoreVMFunction_wait::acceptsArgUnitPrefix(vmint iArg) const { + return iArg == 0; +} + VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) { ExecContext* ctx = dynamic_cast(vm->currentVMExecContext()); VMIntExpr* expr = dynamic_cast(args->arg(0)); - int us = expr->evalInt(); + vmint us = expr->evalInt(VM_MICRO); if (us < 0) { wrnMsg("wait(): argument may not be negative! Aborting script!"); this->result.flags = STMT_ABORT_SIGNALLED; @@ -117,7 +155,7 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: abs() -bool CoreVMFunction_abs::acceptsArgType(int iArg, ExprType_t type) const { +bool CoreVMFunction_abs::acceptsArgType(vmint iArg, ExprType_t type) const { return type == INT_EXPR; } @@ -128,13 +166,13 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: random() -bool CoreVMFunction_random::acceptsArgType(int iArg, ExprType_t type) const { +bool CoreVMFunction_random::acceptsArgType(vmint iArg, ExprType_t type) const { return type == INT_EXPR; } VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) { - int iMin = args->arg(0)->asInt()->evalInt(); - int iMax = args->arg(1)->asInt()->evalInt(); + vmint iMin = args->arg(0)->asInt()->evalInt(); + vmint iMax = args->arg(1)->asInt()->evalInt(); float f = float(::rand()) / float(RAND_MAX); return successResult( iMin + roundf( f * float(iMax - iMin) ) @@ -144,7 +182,7 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: num_elements() -bool CoreVMFunction_num_elements::acceptsArgType(int iArg, ExprType_t type) const { +bool CoreVMFunction_num_elements::acceptsArgType(vmint iArg, ExprType_t type) const { return type == INT_ARR_EXPR; } @@ -160,7 +198,7 @@ VMIntExpr* in = dynamic_cast(arg); VMVariable* out = dynamic_cast(arg); if (!in || !out) successResult(0); - int i = in->evalInt() + 1; + vmint i = in->evalInt() + 1; IntLiteral tmp(i); out->assignExpr(&tmp); return successResult(i); @@ -174,7 +212,7 @@ VMIntExpr* in = dynamic_cast(arg); VMVariable* out = dynamic_cast(arg); if (!in || !out) successResult(0); - int i = in->evalInt() - 1; + vmint i = in->evalInt() - 1; IntLiteral tmp(i); out->assignExpr(&tmp); return successResult(i); @@ -184,11 +222,11 @@ // built-in script function: in_range() VMFnResult* CoreVMFunction_in_range::exec(VMFnArgs* args) { - int i = args->arg(0)->asInt()->evalInt(); - int lo = args->arg(1)->asInt()->evalInt(); - int hi = args->arg(2)->asInt()->evalInt(); + vmint i = args->arg(0)->asInt()->evalInt(); + vmint lo = args->arg(1)->asInt()->evalInt(); + vmint hi = args->arg(2)->asInt()->evalInt(); if (lo > hi) { // swap lo and hi - int tmp = lo; + vmint tmp = lo; lo = hi; hi = tmp; } @@ -199,8 +237,8 @@ // built-in script function: sh_left() VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) { - int i = args->arg(0)->asInt()->evalInt(); - int n = args->arg(1)->asInt()->evalInt(); + vmint i = args->arg(0)->asInt()->evalInt(); + vmint n = args->arg(1)->asInt()->evalInt(); return successResult(i << n); } @@ -208,8 +246,8 @@ // built-in script function: sh_right() VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) { - int i = args->arg(0)->asInt()->evalInt(); - int n = args->arg(1)->asInt()->evalInt(); + vmint i = args->arg(0)->asInt()->evalInt(); + vmint n = args->arg(1)->asInt()->evalInt(); return successResult(i >> n); } @@ -217,8 +255,8 @@ // built-in script function: min() VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) { - int l = args->arg(0)->asInt()->evalInt(); - int r = args->arg(1)->asInt()->evalInt(); + vmint l = args->arg(0)->asInt()->evalInt(); + vmint r = args->arg(1)->asInt()->evalInt(); return successResult(l < r ? l : r); } @@ -226,8 +264,8 @@ // built-in script function: max() VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) { - int l = args->arg(0)->asInt()->evalInt(); - int r = args->arg(1)->asInt()->evalInt(); + vmint l = args->arg(0)->asInt()->evalInt(); + vmint r = args->arg(1)->asInt()->evalInt(); return successResult(l > r ? l : r); } @@ -241,8 +279,8 @@ wrnMsg("array_equal(): the two arrays differ in size"); return successResult(0); // false } - const int n = l->arraySize(); - for (int i = 0; i < n; ++i) + const vmint n = l->arraySize(); + for (vmint i = 0; i < n; ++i) if (l->evalIntElement(i) != r->evalIntElement(i)) return successResult(0); // false return successResult(1); // true @@ -251,11 +289,11 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: search() -ExprType_t CoreVMFunction_search::argType(int iArg) const { +ExprType_t CoreVMFunction_search::argType(vmint iArg) const { return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR; } -bool CoreVMFunction_search::acceptsArgType(int iArg, ExprType_t type) const { +bool CoreVMFunction_search::acceptsArgType(vmint iArg, ExprType_t type) const { if (iArg == 0) return type == INT_ARR_EXPR; else @@ -264,9 +302,9 @@ VMFnResult* CoreVMFunction_search::exec(VMFnArgs* args) { VMIntArrayExpr* a = args->arg(0)->asIntArray(); - const int needle = args->arg(1)->asInt()->evalInt(); - const int n = a->arraySize(); - for (int i = 0; i < n; ++i) + const vmint needle = args->arg(1)->asInt()->evalInt(); + const vmint n = a->arraySize(); + for (vmint i = 0; i < n; ++i) if (a->evalIntElement(i) == needle) return successResult(i); return successResult(-1); // not found @@ -275,11 +313,11 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: sort() -ExprType_t CoreVMFunction_sort::argType(int iArg) const { +ExprType_t CoreVMFunction_sort::argType(vmint iArg) const { return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR; } -bool CoreVMFunction_sort::acceptsArgType(int iArg, ExprType_t type) const { +bool CoreVMFunction_sort::acceptsArgType(vmint iArg, ExprType_t type) const { if (iArg == 0) return type == INT_ARR_EXPR; else @@ -288,7 +326,7 @@ struct ArrElemPOD { VMIntArrayExpr* m_array; - int m_index; + vmint m_index; }; static inline void swap(class ArrElemRef a, class ArrElemRef b); @@ -299,7 +337,7 @@ m_array = NULL; m_index = 0; } - ArrElemRef(VMIntArrayExpr* a, int index) { + ArrElemRef(VMIntArrayExpr* a, vmint index) { m_array = a; m_index = index; } @@ -307,7 +345,7 @@ setValue(e.getValue()); return *this; } - inline ArrElemRef& operator=(int val) { + inline ArrElemRef& operator=(vmint val) { setValue(val); return *this; } @@ -316,13 +354,13 @@ return true; return getValue() == e.getValue(); } - inline bool operator==(int val) const { + inline bool operator==(vmint val) const { return getValue() == val; } inline bool operator!=(const ArrElemRef& e) const { return !(operator==(e)); } - inline bool operator!=(int val) const { + inline bool operator!=(vmint val) const { return !(operator==(val)); } inline bool operator<(const ArrElemRef& e) const { @@ -330,7 +368,7 @@ return false; return getValue() < e.getValue(); } - inline bool operator<(int val) const { + inline bool operator<(vmint val) const { return getValue() < val; } inline bool operator>(const ArrElemRef& e) const { @@ -338,7 +376,7 @@ return false; return getValue() > e.getValue(); } - inline bool operator>(int val) const { + inline bool operator>(vmint val) const { return getValue() > val; } inline bool operator<=(const ArrElemRef& e) const { @@ -346,7 +384,7 @@ return true; return getValue() <= e.getValue(); } - inline bool operator<=(int val) const { + inline bool operator<=(vmint val) const { return getValue() <= val; } inline bool operator>=(const ArrElemRef& e) const { @@ -354,17 +392,17 @@ return true; return getValue() >= e.getValue(); } - inline bool operator>=(int val) const { + inline bool operator>=(vmint val) const { return getValue() >= val; } - inline operator int() const { + inline operator vmint() const { return getValue(); } protected: - inline int getValue() const { + inline vmint getValue() const { return m_array->evalIntElement(m_index); } - inline void setValue(int value) { + inline void setValue(vmint value) { m_array->assignIntElement(m_index, value); } @@ -377,7 +415,7 @@ m_array = NULL; m_index = 0; } - ArrElemPtr(VMIntArrayExpr* a, int index) { + ArrElemPtr(VMIntArrayExpr* a, vmint index) { m_array = a; m_index = index; } @@ -387,8 +425,8 @@ }; static inline void swap(ArrElemRef a, ArrElemRef b) { - int valueA = a.getValue(); - int valueB = b.getValue(); + vmint valueA = a.getValue(); + vmint valueB = b.getValue(); a.setValue(valueB); b.setValue(valueA); } @@ -396,12 +434,12 @@ class ArrExprIter : public ArrElemPOD { public: typedef std::random_access_iterator_tag iterator_category; - typedef int value_type; + typedef vmint value_type; typedef ssize_t difference_type; typedef ArrElemPtr pointer; typedef ArrElemRef reference; - ArrExprIter(VMIntArrayExpr* a, int index) { + ArrExprIter(VMIntArrayExpr* a, vmint index) { m_array = a; m_index = index; } @@ -426,6 +464,14 @@ --m_index; return it; } + inline ArrExprIter& operator+=(difference_type d) { + m_index += d; + return *this; + } + inline ArrExprIter& operator-=(difference_type d) { + m_index -= d; + return *this; + } inline bool operator==(const ArrExprIter& other) const { return m_index == other.m_index; } @@ -462,7 +508,7 @@ }; struct DescArrExprSorter { - inline bool operator()(const int& a, const int& b) const { + inline bool operator()(const vmint& a, const vmint& b) const { return a > b; } }; @@ -471,7 +517,7 @@ VMIntArrayExpr* a = args->arg(0)->asIntArray(); bool bAscending = (args->argsCount() < 2) ? true : !args->arg(1)->asInt()->evalInt(); - int n = a->arraySize(); + vmint n = a->arraySize(); ArrExprIter itBegin(a, 0); ArrExprIter itEnd(a, n); if (bAscending) {