1 /*
2     SuperCollider real time audio synthesis system
3     Copyright (c) 2002 James McCartney. All rights reserved.
4     http://www.audiosynth.com
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19 */
20 /*
21 
22 Each virtual machine has a copy of VMGlobals, which contains the state of the virtual machine.
23 
24 */
25 
26 #pragma once
27 
28 #include "PyrSlot.h"
29 #include "SC_AllocPool.h"
30 #include "SC_RGen.h"
31 #include <setjmp.h>
32 #include <map>
33 
34 #define TAILCALLOPTIMIZE 1
35 
36 typedef void (*FifoMsgFunc)(struct VMGlobals*, struct FifoMsg*);
37 
38 struct FifoMsg {
FifoMsgFifoMsg39     FifoMsg(): func(0), dataPtr(0) { dataWord[0] = dataWord[1] = 0; }
40     void Perform(struct VMGlobals* g);
41     void Free(struct VMGlobals* g);
42 
43     FifoMsgFunc func;
44     void* dataPtr;
45     long dataWord[2];
46 };
47 
48 struct VMGlobals {
49     VMGlobals();
50 
51     // global context
52     class AllocPool* allocPool;
53     struct PyrProcess* process;
54     class SymbolTable* symbolTable;
55     class PyrGC* gc; // garbage collector for this process
56     PyrObject* classvars;
57 #if TAILCALLOPTIMIZE
58     int tailCall; // next byte code is a tail call.
59 #endif
60     bool canCallOS;
61 
62     // thread context
63     struct PyrThread* thread;
64     struct PyrMethod* method;
65     struct PyrBlock* block;
66     struct PyrFrame* frame;
67     struct PyrMethod* primitiveMethod;
68     unsigned char* ip; // current instruction pointer
69     PyrSlot* sp; // current stack ptr
70     PyrSlot* args;
71     PyrSlot receiver; // the receiver
72     PyrSlot result;
73     int numpop; // number of args to pop for primitive
74     long primitiveIndex;
75     RGen* rgen;
76     jmp_buf escapeInterpreter;
77 
78     // scratch context
79     long execMethod;
80 
81     // primitive exceptions
82     std::map<PyrThread*, std::pair<std::exception_ptr, PyrMethod*>> lastExceptions;
83 };
84 
Perform(struct VMGlobals * g)85 inline void FifoMsg::Perform(struct VMGlobals* g) { (func)(g, this); }
86 
Free(struct VMGlobals * g)87 inline void FifoMsg::Free(struct VMGlobals* g) { g->allocPool->Free(dataPtr); }
88 
89 extern VMGlobals gVMGlobals;
90 extern VMGlobals* gMainVMGlobals;
91 extern VMGlobals* gCompilingVMGlobals;
92