/[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 2879 by schoenebeck, Tue Apr 19 14:07:53 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    
# Line 87  namespace LinuxSampler { Line 89  namespace LinuxSampler {
89          return max;          return max;
90      }      }
91    
92      ScriptVM::ScriptVM() : fnWait(this) {      ScriptVM::ScriptVM() : m_eventHandler(NULL), m_parserContext(NULL), fnWait(this) {
         m_context = new ParserContext(this);  
93      }      }
94    
95      ScriptVM::~ScriptVM() {      ScriptVM::~ScriptVM() {
         if (m_context) {  
             if (m_context->globalIntMemory) {  
                 delete m_context->globalIntMemory;  
                 m_context->globalIntMemory = NULL;  
             }  
             delete m_context;  
         }  
96      }      }
97    
98      void ScriptVM::loadScript(const String& s) {      VMParserContext* ScriptVM::loadScript(const String& s) {
99          std::istringstream iss(s);          std::istringstream iss(s);
100          loadScript(&iss);          return loadScript(&iss);
101      }      }
102            
103      void ScriptVM::loadScript(std::istream* is) {      VMParserContext* ScriptVM::loadScript(std::istream* is) {
104          m_context->createScanner(is);          ParserContext* context = new ParserContext(this);
105          InstrScript_parse(m_context);          //printf("parserCtx=0x%lx\n", (uint64_t)context);
106          std::cout << "Allocating " << m_context->globalIntVarCount * sizeof(int) << " bytes of global int VM memory.\n";  
107          std::cout << "Allocating " << m_context->globalStrVarCount << " of global VM string variables.\n";          context->registerBuiltInConstIntVariables( builtInConstIntVariables() );
108          if (!m_context->globalIntMemory)          context->registerBuiltInIntVariables( builtInIntVariables() );
109              m_context->globalIntMemory = new ArrayList<int>();          context->registerBuiltInIntArrayVariables( builtInIntArrayVariables() );
110          if (!m_context->globalStrMemory)  
111              m_context->globalStrMemory = new ArrayList<String>();          context->createScanner(is);
112          m_context->globalIntMemory->resize(m_context->globalIntVarCount);  
113          m_context->globalStrMemory->resize(m_context->globalStrVarCount);          InstrScript_parse(context);
114      }          dmsg(2,("Allocating %ld bytes of global int VM memory.\n", long(context->globalIntVarCount * sizeof(int))));
115            dmsg(2,("Allocating %d of global VM string variables.\n", context->globalStrVarCount));
116            if (!context->globalIntMemory)
117                context->globalIntMemory = new ArrayList<int>();
118            if (!context->globalStrMemory)
119                context->globalStrMemory = new ArrayList<String>();
120            context->globalIntMemory->resize(context->globalIntVarCount);
121            memset(&((*context->globalIntMemory)[0]), 0, context->globalIntVarCount * sizeof(int));
122            
123            context->globalStrMemory->resize(context->globalStrVarCount);
124    
125      std::vector<ParserIssue> ScriptVM::issues() const {          context->destroyScanner();
         return m_context->issues;  
     }  
   
     std::vector<ParserIssue> ScriptVM::errors() const {  
         return m_context->errors;  
     }  
126    
127      std::vector<ParserIssue> ScriptVM::warnings() const {          return context;
         return m_context->warnings;  
128      }      }
129    
130      void ScriptVM::dumpParsedScript() {      void ScriptVM::dumpParsedScript(VMParserContext* context) {
131          if (!m_context) {          ParserContext* ctx = dynamic_cast<ParserContext*>(context);
132            if (!ctx) {
133              std::cerr << "No VM context. So nothing to dump.\n";              std::cerr << "No VM context. So nothing to dump.\n";
134              return;              return;
135          }          }
136          if (!m_context->handlers) {          if (!ctx->handlers) {
137              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";
138              return;              return;
139          }          }
140          if (!m_context->globalIntMemory) {          if (!ctx->globalIntMemory) {
141              std::cerr << "Internal error: no global memory assigend to script VM.\n";              std::cerr << "Internal error: no global memory assigend to script VM.\n";
142              return;              return;
143          }          }
144          m_context->handlers->dump();          ctx->handlers->dump();
145      }      }
146    
147      VMExecContext* ScriptVM::createExecContext() {      VMExecContext* ScriptVM::createExecContext(VMParserContext* parserContext) {
148          ExecContext* ctx = new ExecContext();          ParserContext* parserCtx = dynamic_cast<ParserContext*>(parserContext);
149          const int stackSize = _requiredMaxStackSizeFor(&*m_context->handlers);          ExecContext* execCtx = new ExecContext();
150          ctx->stack.resize(stackSize);          
151          std::cout << "Created VM exec context with "          if (parserCtx->requiredMaxStackSize < 0) {
152                    << stackSize * sizeof(ExecContext::StackFrame)               parserCtx->requiredMaxStackSize =
153                    << " bytes VM stack size.\n";                  _requiredMaxStackSizeFor(&*parserCtx->handlers);
154          const int polySize = m_context->polyphonicIntVarCount;          }
155          ctx->polyphonicIntMemory.resize(polySize);          execCtx->stack.resize(parserCtx->requiredMaxStackSize);
156          std::cout << "Allocated " << polySize * sizeof(int)          dmsg(2,("Created VM exec context with %ld bytes VM stack size.\n",
157                    << " bytes polyphonic memory.\n";                  long(parserCtx->requiredMaxStackSize * sizeof(ExecContext::StackFrame))));
158          return ctx;          //printf("execCtx=0x%lx\n", (uint64_t)execCtx);
159      }          const int polySize = parserCtx->polyphonicIntVarCount;
160            execCtx->polyphonicIntMemory.resize(polySize);
161      VMEventHandler* ScriptVM::eventHandler(uint index) {          memset(&execCtx->polyphonicIntMemory[0], 0, polySize * sizeof(int));
162          if (!m_context) return NULL;  
163          if (!m_context->handlers) return NULL;          dmsg(2,("Allocated %ld bytes polyphonic memory.\n", long(polySize * sizeof(int))));
164          return m_context->handlers->eventHandler(index);          return execCtx;
     }  
   
     VMEventHandler* ScriptVM::eventHandlerByName(const String& name) {  
         if (!m_context) return NULL;  
         if (!m_context->handlers) return NULL;  
         return m_context->handlers->eventHandlerByName(name);  
165      }      }
166    
167      VMFunction* ScriptVM::functionByName(const String& name) {      VMFunction* ScriptVM::functionByName(const String& name) {
168          if (name == "message") return &fnMessage;          if (name == "message") return &fnMessage;
169          else if (name == "exit") return &fnExit;          else if (name == "exit") return &fnExit;
170          else if (name == "wait") return &fnWait;          else if (name == "wait") return &fnWait;
171            else if (name == "abs") return &fnAbs;
172            else if (name == "random") return &fnRandom;
173            else if (name == "num_elements") return &fnNumElements;
174          return NULL;          return NULL;
175      }      }
176        
177        std::map<String,VMIntRelPtr*> ScriptVM::builtInIntVariables() {
178            return std::map<String,VMIntRelPtr*>();
179        }
180    
181        std::map<String,VMInt8Array*> ScriptVM::builtInIntArrayVariables() {
182            return std::map<String,VMInt8Array*>();
183        }
184    
185        std::map<String,int> ScriptVM::builtInConstIntVariables() {
186            return std::map<String,int>();
187        }
188    
189        VMEventHandler* ScriptVM::currentVMEventHandler() {
190            return m_eventHandler;
191        }
192    
193        VMParserContext* ScriptVM::currentVMParserContext() {
194            return m_parserContext;
195        }
196    
197      VMExecContext* ScriptVM::currentVMExecContext() {      VMExecContext* ScriptVM::currentVMExecContext() {
198          if (!m_context) return NULL;          if (!m_parserContext) return NULL;
199          return m_context->execContext;          return m_parserContext->execContext;
200      }      }
201    
202      VMExecStatus_t ScriptVM::exec(VMEventHandler* handler, VMExecContext* execContex) {      VMExecStatus_t ScriptVM::exec(VMParserContext* parserContext, VMExecContext* execContex, VMEventHandler* handler) {
203          if (!m_context) {          m_parserContext = dynamic_cast<ParserContext*>(parserContext);
204              std::cerr << "No VM parser context. Did you load a script?.\n";          if (!m_parserContext) {
205                std::cerr << "No VM parser context provided. Did you load a script?.\n";
206              return VMExecStatus_t(VM_EXEC_NOT_RUNNING | VM_EXEC_ERROR);              return VMExecStatus_t(VM_EXEC_NOT_RUNNING | VM_EXEC_ERROR);
207          }          }
208    
209            // a ParserContext object is always tied to exactly one ScriptVM object
210            assert(m_parserContext->functionProvider == this);
211    
212          ExecContext* ctx = dynamic_cast<ExecContext*>(execContex);          ExecContext* ctx = dynamic_cast<ExecContext*>(execContex);
213          if (!ctx) {          if (!ctx) {
214              std::cerr << "Invalid VM exec context.\n";              std::cerr << "Invalid VM exec context.\n";
# Line 198  namespace LinuxSampler { Line 216  namespace LinuxSampler {
216          }          }
217          EventHandler* h = dynamic_cast<EventHandler*>(handler);          EventHandler* h = dynamic_cast<EventHandler*>(handler);
218          if (!h) return VM_EXEC_NOT_RUNNING;          if (!h) return VM_EXEC_NOT_RUNNING;
219            m_eventHandler = handler;
220    
221          m_context->execContext = ctx;          m_parserContext->execContext = ctx;
222    
223          ctx->status = VM_EXEC_RUNNING;          ctx->status = VM_EXEC_RUNNING;
224          StmtFlags_t flags = STMT_SUCCESS;          StmtFlags_t flags = STMT_SUCCESS;
# Line 293  namespace LinuxSampler { Line 312  namespace LinuxSampler {
312              ctx->reset();              ctx->reset();
313          }          }
314    
315          m_context->execContext = NULL;          m_eventHandler = NULL;
316            m_parserContext->execContext = NULL;
317            m_parserContext = NULL;
318          return ctx->status;          return ctx->status;
319      }      }
320    

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

  ViewVC Help
Powered by ViewVC