supernova: fix for small audio vector sizes
[supercollider.git] / lang / LangSource / ByteCodeArray.cpp
blob6b583a24f6e3b3dc78a1648556d7e9785d11abe8
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
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.
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.
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
21 #include <stdlib.h>
22 #include <string.h>
23 #include "SCBase.h"
24 #include "InitAlloc.h"
25 #include "ByteCodeArray.h"
26 #include "Opcodes.h"
28 ByteCodes gCompilingByteCodes;
29 long totalByteCodes = 0;
31 void initByteCodes()
33 if (gCompilingByteCodes) {
34 freeByteCodes(gCompilingByteCodes);
35 gCompilingByteCodes = NULL;
39 int compileOpcode(long opcode, long operand1)
41 int retc;
42 if (operand1 <= 15) {
43 compileByte((opcode<<4) | operand1);
44 retc = 1;
45 } else {
46 compileByte(opcode);
47 compileByte(operand1);
48 if (opcode == opSendMsg || opcode == opSendSpecialMsg || opcode == opSendSuper) {
49 // these expect numKeyArgsPushed to be passed.
50 compileByte(0);
52 retc = 2;
54 return retc;
57 void compileJump(long opcode, long jumplen)
59 compileByte((opSpecialOpcode<<4) | opcode);
60 compileByte((jumplen >> 8) & 0xFF);
61 compileByte(jumplen & 0xFF);
64 void compileByte(long byte)
66 if (gCompilingByteCodes == NULL) {
67 gCompilingByteCodes = allocByteCodes();
70 if ((gCompilingByteCodes->ptr - gCompilingByteCodes->bytes)
71 >= gCompilingByteCodes->size) {
72 reallocByteCodes(gCompilingByteCodes);
74 totalByteCodes++;
75 *gCompilingByteCodes->ptr++ = byte;
78 int compileNumber(unsigned long value)
80 compileByte((value >> 24) & 0xFF);
81 compileByte((value >> 16) & 0xFF);
82 compileByte((value >> 8) & 0xFF);
83 compileByte(value & 0xFF);
84 return 4;
87 int compileNumber24(unsigned long value)
89 compileByte((value >> 16) & 0xFF);
90 compileByte((value >> 8) & 0xFF);
91 compileByte(value & 0xFF);
92 return 4;
95 void compileAndFreeByteCodes(ByteCodes byteCodes)
97 compileByteCodes(byteCodes);
98 freeByteCodes(byteCodes);
101 void copyByteCodes(Byte *dest, ByteCodes byteCodes)
103 memcpy(dest, byteCodes->bytes, byteCodeLength(byteCodes));
106 ByteCodes getByteCodes()
108 ByteCodes curByteCodes;
110 curByteCodes = gCompilingByteCodes;
111 gCompilingByteCodes = NULL;
113 return curByteCodes;
116 ByteCodes saveByteCodeArray()
118 ByteCodes curByteCodes;
120 curByteCodes = gCompilingByteCodes;
121 gCompilingByteCodes = NULL;
123 return curByteCodes;
126 void restoreByteCodeArray(ByteCodes byteCodes)
128 gCompilingByteCodes = byteCodes;
131 int byteCodeLength(ByteCodes byteCodes)
133 if (!byteCodes) return 0;
134 return (byteCodes->ptr - byteCodes->bytes);
137 /***********************************************************************
139 * Internal routines.
141 ***********************************************************************/
143 void compileByteCodes(ByteCodes byteCodes)
145 Byte *ptr;
146 int i;
148 if (byteCodes == NULL) return;
150 //postfl("[%d]\n", byteCodes->ptr - byteCodes->bytes);
151 for (i=0, ptr = byteCodes->bytes; ptr < byteCodes->ptr; ptr++, ++i) {
152 compileByte(*ptr);
154 //postfl("%02X ", *ptr);
155 //if ((i & 15) == 15) postfl("\n");
157 //postfl("\n\n");
160 ByteCodes allocByteCodes()
162 ByteCodes newByteCodes;
164 // pyrmalloc: I think that all bytecodes are copied to objects
165 // lifetime: kill after compile
166 newByteCodes = (ByteCodes)pyr_pool_compile->Alloc(sizeof(ByteCodeArray));
167 MEMFAIL(newByteCodes);
168 newByteCodes->bytes = (Byte *)pyr_pool_compile->Alloc(BYTE_CODE_CHUNK_SIZE);
169 MEMFAIL(newByteCodes->bytes);
170 newByteCodes->ptr = newByteCodes->bytes;
171 newByteCodes->size = BYTE_CODE_CHUNK_SIZE;
172 //postfl("allocByteCodes %0X\n", newByteCodes);
173 return newByteCodes;
176 void reallocByteCodes(ByteCodes byteCodes)
178 Byte *newBytes;
179 int newLen;
181 if (byteCodes->size != (byteCodes->ptr - byteCodes->bytes)) {
182 error("reallocByteCodes called with size != byteCode len");
185 newLen = byteCodes->size << 1;
186 // pyrmalloc: I think that all bytecodes are copied to objects
187 // lifetime: kill after compile
188 newBytes = (Byte *)pyr_pool_compile->Alloc(newLen);
189 MEMFAIL(newBytes);
190 memcpy(newBytes, byteCodes->bytes, byteCodes->size);
191 pyr_pool_compile->Free(byteCodes->bytes);
193 byteCodes->bytes = newBytes;
194 byteCodes->ptr = newBytes + byteCodes->size;
195 byteCodes->size = newLen;
199 void freeByteCodes(ByteCodes byteCodes)
201 //postfl("freeByteCodes %0X\n", byteCodes);
202 if (byteCodes != NULL) {
203 pyr_pool_compile->Free(byteCodes->bytes);
204 pyr_pool_compile->Free(byteCodes);