/[svn]/linuxsampler/trunk/src/scriptvm/ScriptVM.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/ScriptVM.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2581 by schoenebeck, Fri May 30 12:48:05 2014 UTC revision 2942 by schoenebeck, Wed Jul 13 15:51:06 2016 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck   * Copyright (c) 2014 - 2016 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 9  Line 9 
9    
10  #include "ScriptVM.h"  #include "ScriptVM.h"
11    
12    #include <string.h>
13    #include <assert.h>
14  #include "../common/global_private.h"  #include "../common/global_private.h"
15  #include "tree.h"  #include "tree.h"
16    #include "CoreVMFunctions.h"
17    #include "CoreVMDynVars.h"
18    #include "editor/NkspScanner.h"
19    
20  #define DEBUG_SCRIPTVM_CORE 0  #define DEBUG_SCRIPTVM_CORE 0
21    
# Line 87  namespace LinuxSampler { Line 92  namespace LinuxSampler {
92          return max;          return max;
93      }      }
94    
95      ScriptVM::ScriptVM() : fnWait(this) {      ScriptVM::ScriptVM() : m_eventHandler(NULL), m_parserContext(NULL) {
96          m_context = new ParserContext(this);          m_fnMessage = new CoreVMFunction_message;
97            m_fnExit = new CoreVMFunction_exit;
98            m_fnWait = new CoreVMFunction_wait(this);
99            m_fnAbs = new CoreVMFunction_abs;
100            m_fnRandom = new CoreVMFunction_random;
101            m_fnNumElements = new CoreVMFunction_num_elements;
102            m_varRealTimer = new CoreVMDynVar_NKSP_REAL_TIMER;
103            m_varPerfTimer = new CoreVMDynVar_NKSP_PERF_TIMER;
104      }      }
105    
106      ScriptVM::~ScriptVM() {      ScriptVM::~ScriptVM() {
107          if (m_context) {          delete m_fnMessage;
108              if (m_context->globalIntMemory) {          delete m_fnExit;
109                  delete m_context->globalIntMemory;          delete m_fnWait;
110                  m_context->globalIntMemory = NULL;          delete m_fnAbs;
111              }          delete m_fnRandom;
112              delete m_context;          delete m_fnNumElements;
113          }          delete m_varRealTimer;
114            delete m_varPerfTimer;
115      }      }
116    
117      void ScriptVM::loadScript(const String& s) {      VMParserContext* ScriptVM::loadScript(const String& s) {
118          std::istringstream iss(s);          std::istringstream iss(s);
119          loadScript(&iss);          return loadScript(&iss);
120      }      }
121            
122      void ScriptVM::loadScript(std::istream* is) {      VMParserContext* ScriptVM::loadScript(std::istream* is) {
123          m_context->createScanner(is);          ParserContext* context = new ParserContext(this);
124          InstrScript_parse(m_context);          //printf("parserCtx=0x%lx\n", (uint64_t)context);
125          std::cout << "Allocating " << m_context->globalIntVarCount * sizeof(int) << " bytes of global int VM memory.\n";  
126          std::cout << "Allocating " << m_context->globalStrVarCount << " of global VM string variables.\n";          context->registerBuiltInConstIntVariables( builtInConstIntVariables() );
127          if (!m_context->globalIntMemory)          context->registerBuiltInIntVariables( builtInIntVariables() );
128              m_context->globalIntMemory = new ArrayList<int>();          context->registerBuiltInIntArrayVariables( builtInIntArrayVariables() );
129          if (!m_context->globalStrMemory)          context->registerBuiltInDynVariables( builtInDynamicVariables() );
130              m_context->globalStrMemory = new ArrayList<String>();  
131          m_context->globalIntMemory->resize(m_context->globalIntVarCount);          context->createScanner(is);
132          m_context->globalStrMemory->resize(m_context->globalStrVarCount);  
133      }          InstrScript_parse(context);
134            dmsg(2,("Allocating %ld bytes of global int VM memory.\n", long(context->globalIntVarCount * sizeof(int))));
135      std::vector<ParserIssue> ScriptVM::issues() const {          dmsg(2,("Allocating %d of global VM string variables.\n", context->globalStrVarCount));
136          return m_context->issues;          if (!context->globalIntMemory)
137      }              context->globalIntMemory = new ArrayList<int>();
138            if (!context->globalStrMemory)
139                context->globalStrMemory = new ArrayList<String>();
140            context->globalIntMemory->resize(context->globalIntVarCount);
141            memset(&((*context->globalIntMemory)[0]), 0, context->globalIntVarCount * sizeof(int));
142            
143            context->globalStrMemory->resize(context->globalStrVarCount);
144    
145      std::vector<ParserIssue> ScriptVM::errors() const {          context->destroyScanner();
         return m_context->errors;  
     }  
146    
147      std::vector<ParserIssue> ScriptVM::warnings() const {          return context;
         return m_context->warnings;  
148      }      }
149    
150      void ScriptVM::dumpParsedScript() {      void ScriptVM::dumpParsedScript(VMParserContext* context) {
151          if (!m_context) {          ParserContext* ctx = dynamic_cast<ParserContext*>(context);
152            if (!ctx) {
153              std::cerr << "No VM context. So nothing to dump.\n";              std::cerr << "No VM context. So nothing to dump.\n";
154              return;              return;
155          }          }
156          if (!m_context->handlers) {          if (!ctx->handlers) {
157              std::cerr << "No event handlers defined in script. So nothing to dump.\n";              std::cerr << "No event handlers defined in script. So nothing to dump.\n";
158              return;              return;
159          }          }
160          if (!m_context->globalIntMemory) {          if (!ctx->globalIntMemory) {
161              std::cerr << "Internal error: no global memory assigend to script VM.\n";              std::cerr << "Internal error: no global memory assigend to script VM.\n";
162              return;              return;
163          }          }
164          m_context->handlers->dump();          ctx->handlers->dump();
165        }
166    
167        VMExecContext* ScriptVM::createExecContext(VMParserContext* parserContext) {
168            ParserContext* parserCtx = dynamic_cast<ParserContext*>(parserContext);
169            ExecContext* execCtx = new ExecContext();
170            
171            if (parserCtx->requiredMaxStackSize < 0) {
172                 parserCtx->requiredMaxStackSize =
173                    _requiredMaxStackSizeFor(&*parserCtx->handlers);
174            }
175            execCtx->stack.resize(parserCtx->requiredMaxStackSize);
176            dmsg(2,("Created VM exec context with %ld bytes VM stack size.\n",
177                    long(parserCtx->requiredMaxStackSize * sizeof(ExecContext::StackFrame))));
178            //printf("execCtx=0x%lx\n", (uint64_t)execCtx);
179            const int polySize = parserCtx->polyphonicIntVarCount;
180            execCtx->polyphonicIntMemory.resize(polySize);
181            memset(&execCtx->polyphonicIntMemory[0], 0, polySize * sizeof(int));
182    
183            dmsg(2,("Allocated %ld bytes polyphonic memory.\n", long(polySize * sizeof(int))));
184            return execCtx;
185        }
186    
187        std::vector<VMSourceToken> ScriptVM::syntaxHighlighting(const String& s) {
188            std::istringstream iss(s);
189            return syntaxHighlighting(&iss);
190      }      }
191    
192      VMExecContext* ScriptVM::createExecContext() {      std::vector<VMSourceToken> ScriptVM::syntaxHighlighting(std::istream* is) {
193          ExecContext* ctx = new ExecContext();          NkspScanner scanner(is);
194          const int stackSize = _requiredMaxStackSizeFor(&*m_context->handlers);          std::vector<SourceToken> tokens = scanner.tokens();
195          ctx->stack.resize(stackSize);          std::vector<VMSourceToken> result;
196          std::cout << "Created VM exec context with "          result.resize(tokens.size());
197                    << stackSize * sizeof(ExecContext::StackFrame)          for (int i = 0; i < tokens.size(); ++i) {
198                    << " bytes VM stack size.\n";              SourceToken* st = new SourceToken;
199          const int polySize = m_context->polyphonicIntVarCount;              *st = tokens[i];
200          ctx->polyphonicIntMemory.resize(polySize);              result[i] = VMSourceToken(st);
201          std::cout << "Allocated " << polySize * sizeof(int)          }
202                    << " bytes polyphonic memory.\n";          return result;
         return ctx;  
     }  
   
     VMEventHandler* ScriptVM::eventHandler(uint index) {  
         if (!m_context) return NULL;  
         if (!m_context->handlers) return NULL;  
         return m_context->handlers->eventHandler(index);  
     }  
   
     VMEventHandler* ScriptVM::eventHandlerByName(const String& name) {  
         if (!m_context) return NULL;  
         if (!m_context->handlers) return NULL;  
         return m_context->handlers->eventHandlerByName(name);  
203      }      }
204    
205      VMFunction* ScriptVM::functionByName(const String& name) {      VMFunction* ScriptVM::functionByName(const String& name) {
206          if (name == "message") return &fnMessage;          if (name == "message") return m_fnMessage;
207          else if (name == "exit") return &fnExit;          else if (name == "exit") return m_fnExit;
208          else if (name == "wait") return &fnWait;          else if (name == "wait") return m_fnWait;
209            else if (name == "abs") return m_fnAbs;
210            else if (name == "random") return m_fnRandom;
211            else if (name == "num_elements") return m_fnNumElements;
212          return NULL;          return NULL;
213      }      }
214        
215        std::map<String,VMIntRelPtr*> ScriptVM::builtInIntVariables() {
216            return std::map<String,VMIntRelPtr*>();
217        }
218    
219        std::map<String,VMInt8Array*> ScriptVM::builtInIntArrayVariables() {
220            return std::map<String,VMInt8Array*>();
221        }
222    
223        std::map<String,VMDynVar*> ScriptVM::builtInDynamicVariables() {
224            std::map<String,VMDynVar*> m;
225    
226            m["$NKSP_PERF_TIMER"] = m_varPerfTimer;
227            m["$NKSP_REAL_TIMER"] = m_varRealTimer;
228            m["$KSP_TIMER"] = m_varRealTimer;
229    
230            return m;
231        }
232    
233        std::map<String,int> ScriptVM::builtInConstIntVariables() {
234            return std::map<String,int>();
235        }
236    
237        VMEventHandler* ScriptVM::currentVMEventHandler() {
238            return m_eventHandler;
239        }
240    
241        VMParserContext* ScriptVM::currentVMParserContext() {
242            return m_parserContext;
243        }
244    
245      VMExecContext* ScriptVM::currentVMExecContext() {      VMExecContext* ScriptVM::currentVMExecContext() {
246          if (!m_context) return NULL;          if (!m_parserContext) return NULL;
247          return m_context->execContext;          return m_parserContext->execContext;
248      }      }
249    
250      VMExecStatus_t ScriptVM::exec(VMEventHandler* handler, VMExecContext* execContex) {      VMExecStatus_t ScriptVM::exec(VMParserContext* parserContext, VMExecContext* execContex, VMEventHandler* handler) {
251          if (!m_context) {          m_parserContext = dynamic_cast<ParserContext*>(parserContext);
252              std::cerr << "No VM parser context. Did you load a script?.\n";          if (!m_parserContext) {
253                std::cerr << "No VM parser context provided. Did you load a script?.\n";
254              return VMExecStatus_t(VM_EXEC_NOT_RUNNING | VM_EXEC_ERROR);              return VMExecStatus_t(VM_EXEC_NOT_RUNNING | VM_EXEC_ERROR);
255          }          }
256    
257            // a ParserContext object is always tied to exactly one ScriptVM object
258            assert(m_parserContext->functionProvider == this);
259    
260          ExecContext* ctx = dynamic_cast<ExecContext*>(execContex);          ExecContext* ctx = dynamic_cast<ExecContext*>(execContex);
261          if (!ctx) {          if (!ctx) {
262              std::cerr << "Invalid VM exec context.\n";              std::cerr << "Invalid VM exec context.\n";
# Line 198  namespace LinuxSampler { Line 264  namespace LinuxSampler {
264          }          }
265          EventHandler* h = dynamic_cast<EventHandler*>(handler);          EventHandler* h = dynamic_cast<EventHandler*>(handler);
266          if (!h) return VM_EXEC_NOT_RUNNING;          if (!h) return VM_EXEC_NOT_RUNNING;
267            m_eventHandler = handler;
268    
269          m_context->execContext = ctx;          m_parserContext->execContext = ctx;
270    
271          ctx->status = VM_EXEC_RUNNING;          ctx->status = VM_EXEC_RUNNING;
272          StmtFlags_t flags = STMT_SUCCESS;          StmtFlags_t flags = STMT_SUCCESS;
# Line 293  namespace LinuxSampler { Line 360  namespace LinuxSampler {
360              ctx->reset();              ctx->reset();
361          }          }
362    
363          m_context->execContext = NULL;          m_eventHandler = NULL;
364            m_parserContext->execContext = NULL;
365            m_parserContext = NULL;
366          return ctx->status;          return ctx->status;
367      }      }
368    

Legend:
Removed from v.2581  
changed lines
  Added in v.2942

  ViewVC Help
Powered by ViewVC