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 PyrObject represents the structure of all SC Objects.
23 
24 */
25 
26 #pragma once
27 
28 #include "PyrSlot.h"
29 
30 #include <vector>
31 
32 /* special gc colors */
33 enum {
34     obj_permanent = 1, // sent to gc->New as a flag
35     obj_gcmarker = 2 // gc treadmill marker
36 };
37 
38 /* obj flag fields */
39 enum { obj_inaccessible = 4, obj_immutable = 16, obj_marked = 128 };
40 
41 /* format types : */
42 enum {
43     obj_notindexed,
44     obj_slot,
45     obj_double,
46     obj_float,
47     obj_int32,
48     obj_int16,
49     obj_int8,
50     obj_char,
51     obj_symbol,
52 
53     NUMOBJFORMATS
54 };
55 
56 
57 /*
58     PyrObjectHdr : object header fields
59     prev, next : pointers in the GC treadmill
60     classptr : pointer to the object's class
61     size : number of slots or indexable elements.
62 
63     obj_format : what kind of data this object holds
64     obj_sizeclass : power of two size class of the object
65     obj_flags :
66         immutable : set if object may not be updated.
67         finalize : set if object requires finalization.
68         marked : used by garbage collector debug sanity check. may be used by primitives but must be cleared before
69    exiting primitive. gc_color : GC color : black, grey, white, free, permanent scratch1 : undefined value. may be used
70    within primitives as a temporary scratch value.
71 */
72 
73 struct PyrObjectHdr {
74     struct PyrObjectHdr *prev, *next;
75     struct PyrClass* classptr;
76     int size;
77 
78     unsigned char obj_format;
79     unsigned char obj_sizeclass;
80     unsigned char obj_flags;
81     unsigned char gc_color;
82 
83     int scratch1;
84 
SizeClassPyrObjectHdr85     int SizeClass() { return obj_sizeclass; }
86 
SetMarkPyrObjectHdr87     void SetMark() { obj_flags |= obj_marked; }
ClearMarkPyrObjectHdr88     void ClearMark() { obj_flags &= ~obj_marked; }
IsMarkedPyrObjectHdr89     bool IsMarked() const { return obj_flags & obj_marked; }
IsPermanentPyrObjectHdr90     bool IsPermanent() const { return gc_color == obj_permanent; }
IsImmutablePyrObjectHdr91     bool IsImmutable() const { return obj_flags & obj_immutable; }
IsMutablePyrObjectHdr92     bool IsMutable() const { return !IsImmutable(); }
93 };
94 
95 struct PyrObject : public PyrObjectHdr {
96     PyrSlot slots[1];
97 };
98 
99 struct PyrList : public PyrObjectHdr {
100     PyrSlot array;
101 };
102 
103 struct PyrDoubleArray : public PyrObjectHdr {
104     double d[1];
105 };
106 
107 struct PyrFloatArray : public PyrObjectHdr {
108     float f[1];
109 };
110 
111 struct PyrInt32Array : public PyrObjectHdr {
112     uint32 i[1];
113 };
114 
115 struct PyrInt16Array : public PyrObjectHdr {
116     uint16 i[1];
117 };
118 
119 struct PyrInt8Array : public PyrObjectHdr {
120     uint8 b[1];
121 };
122 
123 struct PyrString : public PyrObjectHdr {
124     char s[1];
125 };
126 
127 struct PyrSymbolArray : public PyrObjectHdr {
128     PyrSymbol* symbols[1];
129 };
130 
131 extern struct PyrClass* class_object;
132 extern struct PyrClass* class_array;
133 extern struct PyrClass *class_list, *class_method, *class_fundef, *class_frame, *class_class;
134 extern struct PyrClass *class_symbol, *class_nil;
135 extern struct PyrClass *class_boolean, *class_true, *class_false;
136 extern struct PyrClass *class_int, *class_char, *class_float, *class_complex;
137 extern struct PyrClass* class_rawptr;
138 extern struct PyrClass* class_string;
139 extern struct PyrClass *class_magnitude, *class_number, *class_collection;
140 extern struct PyrClass* class_sequenceable_collection;
141 extern struct PyrClass* class_arrayed_collection;
142 extern struct PyrClass* class_simple_number;
143 extern struct PyrClass* class_signal;
144 extern struct PyrClass* class_wavetable;
145 extern struct PyrClass* class_rawarray;
146 extern struct PyrClass* class_int8array;
147 extern struct PyrClass* class_int16array;
148 extern struct PyrClass* class_int32array;
149 extern struct PyrClass* class_symbolarray;
150 extern struct PyrClass* class_floatarray;
151 extern struct PyrClass* class_doublearray;
152 extern struct PyrClass *class_func, *class_absfunc;
153 extern struct PyrClass* class_stream;
154 extern struct PyrClass* class_process;
155 extern struct PyrClass* class_interpreter;
156 extern struct PyrClass* class_thread;
157 extern struct PyrClass* class_routine;
158 extern struct PyrClass* class_finalizer;
159 extern struct PyrClass* class_server_shm_interface;
160 
161 extern PyrSymbol* s_none;
162 extern PyrSymbol* s_object;
163 extern PyrSymbol* s_bag;
164 extern PyrSymbol* s_set;
165 extern PyrSymbol* s_identityset;
166 extern PyrSymbol* s_dictionary;
167 extern PyrSymbol* s_identitydictionary;
168 extern PyrSymbol* s_linkedlist;
169 extern PyrSymbol* s_sortedlist;
170 extern PyrSymbol* s_array;
171 extern PyrSymbol *s_list, *s_method, *s_fundef, *s_frame, *s_class;
172 extern PyrSymbol *s_symbol, *s_nil;
173 extern PyrSymbol *s_boolean, *s_true, *s_false;
174 extern PyrSymbol *s_int, *s_char, *s_color, *s_float, *s_complex;
175 extern PyrSymbol* s_rawptr;
176 extern PyrSymbol* s_string;
177 extern PyrSymbol *s_magnitude, *s_number, *s_collection;
178 extern PyrSymbol* s_ordered_collection;
179 extern PyrSymbol* s_sequenceable_collection;
180 extern PyrSymbol* s_arrayed_collection;
181 extern PyrSymbol* s_simple_number;
182 extern PyrSymbol* s_signal;
183 extern PyrSymbol* s_wavetable;
184 extern PyrSymbol* s_int8array;
185 extern PyrSymbol* s_int16array;
186 extern PyrSymbol* s_int32array;
187 extern PyrSymbol* s_symbolarray;
188 extern PyrSymbol* s_floatarray;
189 extern PyrSymbol* s_doublearray;
190 extern PyrSymbol* s_rect;
191 extern PyrSymbol* s_stream;
192 extern PyrSymbol* s_process;
193 extern PyrSymbol* s_main;
194 extern PyrSymbol* s_thread;
195 extern PyrSymbol* s_routine;
196 extern PyrSymbol* s_env;
197 
198 extern PyrSymbol *s_run, *s_stop, *s_tick;
199 extern PyrSymbol* s_next;
200 extern PyrSymbol* s_at;
201 extern PyrSymbol* s_put;
202 extern PyrSymbol *s_series, *s_copyseries, *s_putseries;
203 extern PyrSymbol* s_value;
204 extern PyrSymbol* s_performList;
205 extern PyrSymbol* s_superPerformList;
206 extern PyrSymbol *s_new, *s_ref;
207 extern PyrSymbol *s_synth, *s_environment, *s_event;
208 extern PyrSymbol* s_interpreter;
209 extern PyrSymbol* s_finalizer;
210 extern PyrSymbol* s_awake;
211 extern PyrSymbol* s_systemclock;
212 extern PyrSymbol* s_server_shm_interface;
213 extern PyrSymbol *s_interpretCmdLine, *s_interpretPrintCmdLine;
214 
215 
216 extern int gFormatElemSize[NUMOBJFORMATS];
217 extern int gFormatElemCapc[NUMOBJFORMATS];
218 extern int gFormatElemTag[NUMOBJFORMATS];
219 
220 void dumpObject(PyrObject* obj);
221 void dumpObjectSlot(PyrSlot* slot);
222 
223 bool respondsTo(PyrSlot* slot, PyrSymbol* selector);
224 bool isSubclassOf(struct PyrClass* classobj, struct PyrClass* testclass);
225 
226 extern struct PyrClass* gTagClassTable[16];
227 
classOfSlot(PyrSlot * slot)228 inline struct PyrClass* classOfSlot(PyrSlot* slot) {
229     PyrClass* classobj;
230     int tag;
231     if (IsFloat(slot))
232         classobj = class_float;
233     else if ((tag = GetTag(slot) & 0xF) == 1)
234         classobj = slotRawObject(slot)->classptr;
235     else
236         classobj = gTagClassTable[tag];
237 
238     return classobj;
239 }
240 
241 typedef int (*ObjFuncPtr)(struct VMGlobals*, struct PyrObject*);
242 
243 void stringFromPyrString(PyrString* obj, char* str, int maxlength);
244 void pstringFromPyrString(PyrString* obj, unsigned char* str, int maxlength);
245 
246 int instVarOffset(const char* classname, const char* instvarname);
247 int classVarOffset(const char* classname, const char* classvarname, PyrClass** classobj);
248 
249 void fillSlots(PyrSlot* slot, int size, PyrSlot* fillslot);
250 void nilSlots(PyrSlot* slot, int size);
251 void zeroSlots(PyrSlot* slot, int size);
252 
253 int calcHash(PyrSlot* a);
254 int getIndexedFloat(struct PyrObject* obj, int index, float* value);
255 int getIndexedDouble(struct PyrObject* obj, int index, double* value);
256 
getIndexedVal(struct PyrObject * obj,int index,float * value)257 inline int getIndexedVal(struct PyrObject* obj, int index, float* value) { return getIndexedFloat(obj, index, value); }
258 
getIndexedVal(struct PyrObject * obj,int index,double * value)259 inline int getIndexedVal(struct PyrObject* obj, int index, double* value) {
260     return getIndexedDouble(obj, index, value);
261 }
262 
263 void getIndexedSlot(struct PyrObject* obj, PyrSlot* a, int index);
264 int putIndexedSlot(struct VMGlobals* g, struct PyrObject* obj, PyrSlot* c, int index);
265 int putIndexedFloat(PyrObject* obj, double val, int index);
266 
ARRAYMAXINDEXSIZE(PyrObjectHdr * obj)267 inline long ARRAYMAXINDEXSIZE(PyrObjectHdr* obj) { return (1L << obj->obj_sizeclass); }
268 
MAXINDEXSIZE(PyrObjectHdr * obj)269 inline long MAXINDEXSIZE(PyrObjectHdr* obj) { return ((1L << obj->obj_sizeclass) * gFormatElemCapc[obj->obj_format]); }
270 
271 std::tuple<int, std::vector<std::string>> PyrCollToVectorStdString(PyrObject* coll);
272 
273 void InstallFinalizer(VMGlobals* g, PyrObject* inObj, int slotIndex, ObjFuncPtr inFunc);
274