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 This file contains the definitions of the core objects that implement the class system.
23 
24 */
25 
26 #pragma once
27 
28 #include "PyrObject.h"
29 #include "VMGlobals.h"
30 
31 #define classClassNumInstVars 19
32 
33 enum { classIsIntrinsic = 1, classHasIndexableInstances = 2 };
34 
35 struct PyrClass : public PyrObjectHdr {
36     PyrSlot name;
37     PyrSlot nextclass;
38     PyrSlot superclass;
39     PyrSlot subclasses;
40     PyrSlot methods;
41 
42     PyrSlot instVarNames;
43     PyrSlot classVarNames;
44     PyrSlot iprototype; // instance prototype
45     PyrSlot cprototype; // class var prototype
46 
47     PyrSlot constNames;
48     PyrSlot constValues; // const values
49 
50     PyrSlot instanceFormat;
51     PyrSlot instanceFlags;
52     PyrSlot classIndex;
53     PyrSlot classFlags;
54     PyrSlot maxSubclassIndex; // used by isKindOf
55     PyrSlot filenameSym;
56     PyrSlot charPos;
57     PyrSlot classVarIndex;
58 };
59 
60 
isKindOf(PyrObjectHdr * obj,struct PyrClass * testclass)61 inline bool isKindOf(PyrObjectHdr* obj, struct PyrClass* testclass) {
62     int objClassIndex = slotRawInt(&obj->classptr->classIndex);
63     return objClassIndex >= slotRawInt(&testclass->classIndex)
64         && objClassIndex <= slotRawInt(&testclass->maxSubclassIndex);
65 }
66 
isKindOfSlot(PyrSlot * slot,struct PyrClass * testclass)67 inline bool isKindOfSlot(PyrSlot* slot, struct PyrClass* testclass) {
68     return IsObj(slot) && isKindOf(slotRawObject(slot), testclass);
69 }
70 
71 /*
72     operations on class:
73     numInstVars()
74     numClassVars()
75 
76 */
77 
78 struct PyrFrame : public PyrObjectHdr {
79     PyrSlot method;
80     PyrSlot caller;
81     PyrSlot context;
82     PyrSlot homeContext;
83     PyrSlot ip;
84     PyrSlot vars[1];
85 };
86 
87 #define FRAMESIZE 5
88 
89 struct PyrProcess : public PyrObjectHdr {
90     PyrSlot classVars;
91     PyrSlot interpreter;
92     PyrSlot curThread, mainThread;
93     PyrSlot sysSchedulerQueue;
94     PyrSlot nowExecutingPath;
95 };
96 
97 
98 enum { tInit, tStart, tReady, tRunning, tSleeping, tSuspended, tDone };
99 
100 struct PyrThread : public PyrObjectHdr {
101     PyrSlot state, func, stack, method, block, frame, ip, sp;
102     PyrSlot numpop, receiver, numArgsPushed;
103     PyrSlot parent, terminalValue;
104     PyrSlot primitiveError;
105     PyrSlot primitiveIndex;
106     PyrSlot randData;
107     PyrSlot beats, seconds, clock, nextBeat, endBeat, endValue;
108     PyrSlot environment;
109     PyrSlot exceptionHandler;
110     PyrSlot threadPlayer;
111     PyrSlot executingPath;
112     PyrSlot oldExecutingPath;
113     PyrSlot stackSize;
114 };
115 
116 #define EVALSTACKDEPTH 512
117 
118 
119 struct PyrMethodRaw {
120 #ifdef PYR_SLOTS_GENERIC
121     long padding; // used for the tag in the generic pyrslot implementation
122 #endif
123     unsigned short unused1;
124     unsigned short specialIndex;
125     unsigned short methType;
126     unsigned short frameSize;
127 
128 #ifdef PYR_SLOTS_GENERIC
129     long padding2; // used for the tag in generic pyrslot implementation, second slot
130 #endif
131 
132     unsigned char unused2;
133     unsigned char numargs;
134     unsigned char varargs;
135     unsigned char numvars;
136     unsigned char numtemps;
137     unsigned char needsHeapContext;
138     unsigned char popSize;
139     unsigned char posargs;
140 };
141 
142 
143 #define METHRAW(obj) ((PyrMethodRaw*)&(((PyrBlock*)obj)->rawData1))
144 
145 struct PyrBlock : public PyrObjectHdr {
146     PyrSlot rawData1;
147     PyrSlot rawData2;
148     PyrSlot code; // byte codes, nil if inlined
149     PyrSlot selectors; // method selectors, class names, closures table
150     PyrSlot constants; // floating point constants table (to alleviate the literal table problem)
151     PyrSlot prototypeFrame; // prototype of an activation frame
152     PyrSlot contextDef; // ***defining block context
153     PyrSlot argNames; // ***arguments to block
154     PyrSlot varNames; // ***variables in block
155     PyrSlot sourceCode; // source code if it is a closed function.
156 };
157 
158 struct PyrMethod : public PyrBlock {
159     PyrSlot ownerclass;
160     PyrSlot name;
161     PyrSlot primitiveName;
162     PyrSlot filenameSym;
163     PyrSlot charPos;
164     // PyrSlot byteMeter;
165     // PyrSlot callMeter;
166 };
167 
168 enum {
169     methNormal = 0,
170     methReturnSelf,
171     methReturnLiteral,
172     methReturnArg,
173     methReturnInstVar,
174     methAssignInstVar,
175     methReturnClassVar,
176     methAssignClassVar,
177     methRedirect,
178     methRedirectSuper,
179     methForwardInstVar,
180     methForwardClassVar,
181     methPrimitive,
182     methBlock
183 };
184 
185 struct PyrClosure : public PyrObjectHdr {
186     PyrSlot block;
187     PyrSlot context;
188 };
189 
190 struct PyrInterpreter : public PyrObjectHdr {
191     PyrSlot cmdLine, context;
192     PyrSlot a, b, c, d, e, f, g, h, i, j;
193     PyrSlot k, l, m, n, o, p, q, r, s, t;
194     PyrSlot u, v, w, x, y, z;
195     PyrSlot codeDump, preProcessor;
196 };
197 
198 /* special values */
199 enum {
200     svNil,
201     svFalse,
202     svTrue,
203     svNegOne,
204     svZero,
205     svOne,
206     svTwo,
207     svFHalf,
208     svFNegOne,
209     svFZero,
210     svFOne,
211     svFTwo,
212     svInf,
213 
214     svNumSpecialValues
215 };
216 
217 extern PyrSlot gSpecialValues[svNumSpecialValues];
218 
219 extern PyrMethod* gNullMethod; // used to fill row table
220 
221 PyrObject* instantiateObject(class PyrGC* gc, PyrClass* classobj, int size, bool fill, bool collect);
222 
223 PyrObject* newPyrObject(class PyrGC* gc, size_t inNumBytes, int inFlags, int inFormat, bool inCollect);
224 PyrString* newPyrString(class PyrGC* gc, const char* s, int flags, bool collect);
225 PyrString* newPyrStringN(class PyrGC* gc, int size, int flags, bool collect);
226 PyrObject* newPyrArray(class PyrGC* gc, int size, int flags, bool collect);
227 PyrSymbolArray* newPyrSymbolArray(class PyrGC* gc, int size, int flags, bool collect);
228 PyrInt8Array* newPyrInt8Array(class PyrGC* gc, int size, int flags, bool collect);
229 PyrInt32Array* newPyrInt32Array(class PyrGC* gc, int size, int flags, bool collect);
230 PyrDoubleArray* newPyrDoubleArray(class PyrGC* gc, int size, int flags, bool collect);
231 
232 PyrObject* copyObject(class PyrGC* gc, PyrObject* inobj, bool collect);
233 PyrObject* copyObjectRange(class PyrGC* gc, PyrObject* inobj, int start, int end, bool collect);
234