common: prevent buffer overflow
[supercollider.git] / include / lang / PyrSlot64.h
blob421b03d4411b6eb6cd14c3a87c820f82a9a179e5
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 Copyright (c) 2009 Tim Blechmann
5 http://www.audiosynth.com
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifndef _PYRSLOTGENERIC_H_
23 #define _PYRSLOTGENERIC_H_
25 // generic pyrslot implementation
26 #define PYR_SLOTS_GENERIC
28 #include "SC_Endian.h"
29 #include "SC_Types.h"
30 #include "PyrErrors.h"
32 #include <cstddef>
33 #include <cassert>
35 struct PyrSymbol;
37 enum {
38 tagNotInitialized, // uninitialized slots have a tag of 0
39 tagObj,
40 tagInt,
41 tagSym,
42 tagChar,
43 tagNil, // nil, false, and true are indicated by the tag alone.
44 tagFalse,
45 tagTrue,
46 tagPtr,
47 /* anything else is a double */
48 tagFloat,
49 tagUnused,
52 typedef struct pyrslot {
53 long tag;
55 union {
56 int64 c; /* char */
57 int64 i;
58 double f;
59 void *ptr;
60 struct PyrObject *o;
61 PyrSymbol *s;
62 struct PyrMethod *om;
63 struct PyrBlock *oblk;
64 struct PyrClass *oc;
65 struct PyrFrame *of;
66 struct PyrList *ol;
67 struct PyrString *os;
68 struct PyrInt8Array *ob;
69 struct PyrDoubleArray *od;
70 struct PyrSymbolArray *osym;
71 struct PyrProcess *op;
72 struct PyrThread *ot;
73 struct PyrInterpreter *oi;
74 } u;
75 } PyrSlot;
78 /* tag setter function */
79 inline int GetTag(PyrSlot* slot) { return slot->tag; }
81 /* tag checking functions */
82 inline bool IsObj(PyrSlot* slot) { return slot->tag == tagObj; }
83 inline bool NotObj(PyrSlot* slot) { return slot->tag != tagObj; }
85 inline bool IsNil(PyrSlot* slot) { return slot->tag == tagNil; }
86 inline bool NotNil(PyrSlot* slot) { return slot->tag != tagNil; }
88 inline bool IsFalse(PyrSlot* slot) { return slot->tag == tagFalse; }
89 inline bool IsTrue(PyrSlot* slot) { return slot->tag == tagTrue; }
91 inline bool IsSym(PyrSlot* slot) { return slot->tag == tagSym; }
92 inline bool NotSym(PyrSlot* slot) { return slot->tag != tagSym; }
94 inline bool IsChar(PyrSlot* slot) { return slot->tag == tagChar; }
95 inline bool NotChar(PyrSlot* slot) { return slot->tag != tagChar; }
97 inline bool IsInt(PyrSlot* slot) { return slot->tag == tagInt; }
98 inline bool NotInt(PyrSlot* slot) { return slot->tag != tagInt; }
100 inline bool IsFloat(PyrSlot* slot) { return slot->tag == tagFloat; }
101 inline bool NotFloat(PyrSlot* slot) { return slot->tag != tagFloat; }
103 inline bool IsPtr(PyrSlot* slot) { return slot->tag == tagPtr; }
104 inline bool NotPtr(PyrSlot* slot) { return slot->tag != tagPtr; }
107 /* setter functions */
108 inline void SetInt(PyrSlot* slot, int val) { slot->tag = tagInt; slot->u.i = val; }
109 inline void SetObject(PyrSlot* slot, struct PyrObjectHdr* val) { slot->tag = tagObj; slot->u.o = (struct PyrObject*)(val); }
110 inline void SetSymbol(PyrSlot* slot, PyrSymbol *val) { slot->tag = tagSym; slot->u.s = val; }
111 inline void SetChar(PyrSlot* slot, char val) { slot->tag = tagChar; slot->u.c = val; }
112 inline void SetPtr(PyrSlot* slot, void* val) { slot->tag = tagPtr; slot->u.ptr = (void*)val; }
114 inline void SetObjectOrNil(PyrSlot* slot, struct PyrObject* val)
116 if (val) {
117 slot->tag = tagObj;
118 slot->u.o = val;
119 } else {
120 slot->tag = tagNil;
121 slot->u.i = 0;
125 inline void SetTrue(PyrSlot* slot) { slot->tag = tagTrue; slot->u.i = 0; }
126 inline void SetFalse(PyrSlot* slot) { slot->tag = tagFalse; slot->u.i = 0; }
127 inline void SetBool(PyrSlot* slot, bool test) { slot->tag = (test ? tagTrue : tagFalse); slot->u.i = 0; }
128 inline void SetNil(PyrSlot* slot) { slot->tag = tagNil; slot->u.i = 0; }
129 inline void SetFloat(PyrSlot* slot, double val) { slot->tag = tagFloat; slot->u.f = val; }
132 /* raw setter functions, no typecheck */
133 inline void SetRawChar(PyrSlot* slot, int val) { assert(IsChar(slot)); slot->u.c = val; }
134 inline void SetRaw(PyrSlot* slot, int val) { assert(IsInt(slot)); slot->u.i = val; }
135 inline void SetRaw(PyrSlot* slot, long val) { assert(IsInt(slot)); slot->u.i = val; }
136 inline void SetRaw(PyrSlot* slot, PyrObject * val) { assert(IsObj(slot)); slot->u.o = val; }
137 inline void SetRaw(PyrSlot* slot, PyrSymbol * val) { assert(IsSym(slot)); slot->u.s = val; }
138 inline void SetRaw(PyrSlot* slot, void * val) { assert(IsPtr(slot)); slot->u.ptr = val; }
139 inline void SetRaw(PyrSlot* slot, double val) { assert(IsFloat(slot)); slot->u.f = val; }
140 inline void SetTagRaw(PyrSlot* slot, int tag) { slot->tag = tag; }
142 /* slot comparison */
143 inline bool SlotEq(PyrSlot* a, PyrSlot* b)
145 return (a->tag == b->tag) && (a->u.i == b->u.i);
148 /* extract numeric value */
149 template <typename numeric_type>
150 inline int slotVal(PyrSlot * slot, numeric_type *value)
152 if (IsFloat(slot)) {
153 *value = static_cast<numeric_type>(slot->u.f);
154 return errNone;
155 } else if (IsInt(slot)) {
156 *value = static_cast<numeric_type>(slot->u.i);
157 return errNone;
159 return errWrongType;
162 inline int slotFloatVal(PyrSlot *slot, float *value)
164 return slotVal<float>(slot, value);
167 inline int slotIntVal(PyrSlot *slot, int *value)
169 return slotVal<int>(slot, value);
172 inline int slotDoubleVal(PyrSlot *slot, double *value)
174 return slotVal<double>(slot, value);
177 /* get symbol */
178 inline int slotSymbolVal(PyrSlot *slot, PyrSymbol **symbol)
180 if (!IsSym(slot)) return errWrongType;
181 *symbol = slot->u.s;
182 return errNone;
185 /* raw access functions */
186 inline void* slotRawPtr(PyrSlot *slot)
188 assert(IsPtr(slot) || (slot->u.ptr == NULL && IsNil(slot)));
189 return slot->u.ptr;
192 inline PyrBlock* slotRawBlock(PyrSlot *slot)
194 return slot->u.oblk;
197 inline PyrSymbolArray* slotRawSymbolArray(PyrSlot *slot)
199 return slot->u.osym;
202 inline PyrDoubleArray* slotRawDoubleArray(PyrSlot *slot)
204 return slot->u.od;
207 inline PyrInt8Array* slotRawInt8Array(PyrSlot *slot)
209 return slot->u.ob;
212 inline PyrMethod* slotRawMethod(PyrSlot *slot)
214 return slot->u.om;
217 inline PyrThread* slotRawThread(PyrSlot *slot)
219 return slot->u.ot;
222 inline PyrString* slotRawString(PyrSlot *slot)
224 return slot->u.os;
227 inline PyrList* slotRawList(PyrSlot *slot)
229 return slot->u.ol;
232 inline PyrFrame* slotRawFrame(PyrSlot *slot)
234 return slot->u.of;
237 inline PyrClass* slotRawClass(PyrSlot *slot)
239 return slot->u.oc;
242 inline PyrInterpreter* slotRawInterpreter(PyrSlot *slot)
244 return slot->u.oi;
247 inline PyrSymbol* slotRawSymbol(PyrSlot *slot)
249 return slot->u.s;
252 inline int slotRawChar(PyrSlot *slot)
254 return slot->u.c;
257 inline int slotRawInt(PyrSlot *slot)
259 assert(IsInt(slot));
260 return slot->u.i;
263 inline double slotRawFloat(PyrSlot *slot)
265 return slot->u.f;
268 inline PyrObject* slotRawObject(PyrSlot *slot)
270 assert(IsObj(slot));
271 return slot->u.o;
274 /* slot copy functions */
275 inline void slotCopy(PyrSlot *dst, PyrSlot *src)
277 *dst = *src;
280 inline void slotCopy(PyrSlot *dst, PyrSlot *src, int num)
282 for (int i=0; i<num; ++i)
283 slotCopy(dst + i, src + i);
286 #endif