Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: e28db25801
Fetching contributors…

Cannot retrieve contributors at this time

206 lines (170 sloc) 4.968 kB
/*
SuperCollider real time audio synthesis system
Copyright (c) 2002 James McCartney. All rights reserved.
http://www.audiosynth.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <string.h>
#include "SCBase.h"
#include "InitAlloc.h"
#include "ByteCodeArray.h"
#include "Opcodes.h"
ByteCodes gCompilingByteCodes;
long totalByteCodes = 0;
void initByteCodes()
{
if (gCompilingByteCodes) {
freeByteCodes(gCompilingByteCodes);
gCompilingByteCodes = NULL;
}
}
int compileOpcode(long opcode, long operand1)
{
int retc;
if (operand1 <= 15) {
compileByte((opcode<<4) | operand1);
retc = 1;
} else {
compileByte(opcode);
compileByte(operand1);
if (opcode == opSendMsg || opcode == opSendSpecialMsg || opcode == opSendSuper) {
// these expect numKeyArgsPushed to be passed.
compileByte(0);
}
retc = 2;
}
return retc;
}
void compileJump(long opcode, long jumplen)
{
compileByte((opSpecialOpcode<<4) | opcode);
compileByte((jumplen >> 8) & 0xFF);
compileByte(jumplen & 0xFF);
}
void compileByte(long byte)
{
if (gCompilingByteCodes == NULL) {
gCompilingByteCodes = allocByteCodes();
}
if ((gCompilingByteCodes->ptr - gCompilingByteCodes->bytes)
>= gCompilingByteCodes->size) {
reallocByteCodes(gCompilingByteCodes);
}
totalByteCodes++;
*gCompilingByteCodes->ptr++ = byte;
}
int compileNumber(unsigned long value)
{
compileByte((value >> 24) & 0xFF);
compileByte((value >> 16) & 0xFF);
compileByte((value >> 8) & 0xFF);
compileByte(value & 0xFF);
return 4;
}
int compileNumber24(unsigned long value)
{
compileByte((value >> 16) & 0xFF);
compileByte((value >> 8) & 0xFF);
compileByte(value & 0xFF);
return 4;
}
void compileAndFreeByteCodes(ByteCodes byteCodes)
{
compileByteCodes(byteCodes);
freeByteCodes(byteCodes);
}
void copyByteCodes(Byte *dest, ByteCodes byteCodes)
{
memcpy(dest, byteCodes->bytes, byteCodeLength(byteCodes));
}
ByteCodes getByteCodes()
{
ByteCodes curByteCodes;
curByteCodes = gCompilingByteCodes;
gCompilingByteCodes = NULL;
return curByteCodes;
}
ByteCodes saveByteCodeArray()
{
ByteCodes curByteCodes;
curByteCodes = gCompilingByteCodes;
gCompilingByteCodes = NULL;
return curByteCodes;
}
void restoreByteCodeArray(ByteCodes byteCodes)
{
gCompilingByteCodes = byteCodes;
}
size_t byteCodeLength(ByteCodes byteCodes)
{
if (!byteCodes) return 0;
return (byteCodes->ptr - byteCodes->bytes);
}
/***********************************************************************
*
* Internal routines.
*
***********************************************************************/
void compileByteCodes(ByteCodes byteCodes)
{
Byte *ptr;
int i;
if (byteCodes == NULL) return;
//postfl("[%d]\n", byteCodes->ptr - byteCodes->bytes);
for (i=0, ptr = byteCodes->bytes; ptr < byteCodes->ptr; ptr++, ++i) {
compileByte(*ptr);
//postfl("%02X ", *ptr);
//if ((i & 15) == 15) postfl("\n");
}
//postfl("\n\n");
}
ByteCodes allocByteCodes()
{
ByteCodes newByteCodes;
// pyrmalloc: I think that all bytecodes are copied to objects
// lifetime: kill after compile
newByteCodes = (ByteCodes)pyr_pool_compile->Alloc(sizeof(ByteCodeArray));
MEMFAIL(newByteCodes);
newByteCodes->bytes = (Byte *)pyr_pool_compile->Alloc(BYTE_CODE_CHUNK_SIZE);
MEMFAIL(newByteCodes->bytes);
newByteCodes->ptr = newByteCodes->bytes;
newByteCodes->size = BYTE_CODE_CHUNK_SIZE;
//postfl("allocByteCodes %0X\n", newByteCodes);
return newByteCodes;
}
void reallocByteCodes(ByteCodes byteCodes)
{
Byte *newBytes;
if (byteCodes->size != (byteCodes->ptr - byteCodes->bytes)) {
error("reallocByteCodes called with size != byteCode len");
}
size_t newLen = byteCodes->size << 1;
// pyrmalloc: I think that all bytecodes are copied to objects
// lifetime: kill after compile
newBytes = (Byte *)pyr_pool_compile->Alloc(newLen);
MEMFAIL(newBytes);
memcpy(newBytes, byteCodes->bytes, byteCodes->size);
pyr_pool_compile->Free(byteCodes->bytes);
byteCodes->bytes = newBytes;
byteCodes->ptr = newBytes + byteCodes->size;
byteCodes->size = newLen;
}
void freeByteCodes(ByteCodes byteCodes)
{
//postfl("freeByteCodes %0X\n", byteCodes);
if (byteCodes != NULL) {
pyr_pool_compile->Free(byteCodes->bytes);
pyr_pool_compile->Free(byteCodes);
}
}
Jump to Line
Something went wrong with that request. Please try again.