// === STRUCTURES ===
// === PROTOTYPES ===
-tBC_Op *Bytecode_int_AllocateOp(int Operation);
+tBC_Op *Bytecode_int_AllocateOp(int Operation, int ExtraBytes);
int Bytecode_int_AddVariable(tBC_Function *Handle, const char *Name);
// === GLOBALS ===
// === CODE ===
-tBC_Op *Bytecode_int_AllocateOp(int Operation)
+tBC_Op *Bytecode_int_AllocateOp(int Operation, int ExtraBytes)
{
tBC_Op *ret;
- ret = malloc(sizeof(tBC_Op));
+ ret = malloc(sizeof(tBC_Op) + ExtraBytes);
if(!ret) return NULL;
ret->Next = NULL;
ret->Operation = Operation;
ret->bUseInteger = 0;
+ ret->bUseString = (ExtraBytes > 0);
+ ret->CacheEnt = NULL;
return ret;
}
}
len += 4;
}
-
+
+ void _put_index(uint32_t value)
+ {
+ if( !Output && !value ) {
+ len += 5;
+ return ;
+ }
+ if( value < 0x8000 ) {
+ _put_byte(value >> 8);
+ _put_byte(value & 0xFF);
+ }
+ else if( value < 0x400000 ) {
+ _put_byte( (value >> 16) | 0x80 );
+ _put_byte(value >> 8);
+ _put_byte(value & 0xFF);
+ }
+ else {
+ _put_byte( 0xC0 );
+ _put_byte(value >> 24);
+ _put_byte(value >> 16);
+ _put_byte(value >> 8 );
+ _put_byte(value & 0xFF);
+ }
+ }
+
void _put_qword(uint64_t value)
{
- _put_dword(value & 0xFFFFFFFF);
- _put_dword(value >> 32);
+ if( value < 0x80 ) { // 7 bits into 1 byte
+ _put_byte(value);
+ }
+ else if( !(value >> (8+6)) ) { // 14 bits packed into 2 bytes
+ _put_byte( 0x80 | ((value >> 8) & 0x3F) );
+ _put_byte( value & 0xFF );
+ }
+ else if( !(value >> (32+5)) ) { // 37 bits into 5 bytes
+ _put_byte( 0xC0 | ((value >> 32) & 0x1F) );
+ _put_dword(value & 0xFFFFFFFF);
+ }
+ else {
+ _put_byte( 0xE0 ); // 64 (actually 68) bits into 9 bytes
+ _put_dword(value & 0xFFFFFFFF);
+ _put_dword(value >> 32);
+ }
}
void _put_double(double value)
}
// TODO: Relocations
- _put_dword(strIdx);
+ _put_index(strIdx);
}
for( op = Function->Operations; op; op = op->Next, idx ++ )
case BC_OP_JUMPIF:
case BC_OP_JUMPIFNOT:
// TODO: Relocations?
- _put_dword( LabelOffsets[op->Content.StringInt.Integer] );
+ _put_index( LabelOffsets[op->Content.StringInt.Integer] );
break;
// Special case for inline values
case BC_OP_LOADINT:
break;
// Everthing else just gets handled nicely
default:
- if( op->Content.StringInt.String )
+ if( op->bUseString )
_put_string(op->Content.StringInt.String, strlen(op->Content.StringInt.String));
if( op->bUseInteger )
- _put_dword(op->Content.StringInt.Integer);
+ _put_index(op->Content.StringInt.Integer);
break;
}
}
len = Bytecode_int_Serialize(Function, NULL, label_offsets, Strings);
code = malloc(len);
-
- Bytecode_int_Serialize(Function, code, label_offsets, Strings);
+
+ // Update length to the correct length (may decrease due to encoding)
+ len = Bytecode_int_Serialize(Function, code, label_offsets, Strings);
free(label_offsets);
// Get max count (used when executing to get the frame size)
if(Handle->VariableCount - Handle->CurContextDepth >= Handle->MaxVariableCount)
Handle->MaxVariableCount = Handle->VariableCount - Handle->CurContextDepth;
- return Handle->VariableCount - 1;
+// printf("_AddVariable: %s given %i\n", Name, Handle->VariableCount - Handle->CurContextDepth - 1);
+ return Handle->VariableCount - Handle->CurContextDepth - 1;
}
int Bytecode_int_GetVarIndex(tBC_Function *Handle, const char *Name)
{
- int i;
+ int i, context_depth = Handle->CurContextDepth;
// Get the start of this context
for( i = Handle->VariableCount; i --; )
{
- if( Handle->VariableNames[i] && strcmp(Name, Handle->VariableNames[i]) == 0 )
- return i;
+ if( !Handle->VariableNames[i] ) {
+ context_depth --;
+ continue ;
+ }
+ if( strcmp(Name, Handle->VariableNames[i]) == 0 )
+ return i - context_depth;
}
return -1;
}
#define DEF_BC_NONE(_op) { \
- tBC_Op *op = Bytecode_int_AllocateOp(_op); \
+ tBC_Op *op = Bytecode_int_AllocateOp(_op, 0); \
op->Content.Integer = 0; \
op->bUseInteger = 0; \
Bytecode_int_AppendOp(Handle, op);\
}
+#define DEF_BC_INT(_op, _int) {\
+ tBC_Op *op = Bytecode_int_AllocateOp(_op, 0);\
+ op->Content.StringInt.Integer = _int;\
+ op->bUseInteger = 1;\
+ op->bUseString = 0;\
+ Bytecode_int_AppendOp(Handle, op);\
+}
+
#define DEF_BC_STRINT(_op, _str, _int) { \
- tBC_Op *op = Bytecode_int_AllocateOp(_op);\
+ tBC_Op *op = Bytecode_int_AllocateOp(_op, strlen(_str));\
op->Content.StringInt.Integer = _int;\
- op->Content.StringInt.String = _str;\
+ strcpy(op->Content.StringInt.String, _str);\
op->bUseInteger = 1;\
+ op->bUseString = 1;\
Bytecode_int_AppendOp(Handle, op);\
}
#define DEF_BC_STR(_op, _str) {\
- tBC_Op *op = Bytecode_int_AllocateOp(_op);\
- op->Content.StringInt.String = _str;\
+ tBC_Op *op = Bytecode_int_AllocateOp(_op, strlen(_str));\
+ strcpy(op->Content.StringInt.String, _str);\
op->bUseInteger = 0;\
Bytecode_int_AppendOp(Handle, op);\
}
// --- Flow Control
void Bytecode_AppendJump(tBC_Function *Handle, int Label)
- DEF_BC_STRINT(BC_OP_JUMP, NULL, Label)
+ DEF_BC_INT(BC_OP_JUMP, Label)
void Bytecode_AppendCondJump(tBC_Function *Handle, int Label)
- DEF_BC_STRINT(BC_OP_JUMPIF, NULL, Label)
+ DEF_BC_INT(BC_OP_JUMPIF, Label)
+void Bytecode_AppendCondJumpNot(tBC_Function *Handle, int Label)
+ DEF_BC_INT(BC_OP_JUMPIFNOT, Label)
void Bytecode_AppendReturn(tBC_Function *Handle)
DEF_BC_NONE(BC_OP_RETURN);
// --- Variables
void Bytecode_AppendLoadVar(tBC_Function *Handle, const char *Name)
- DEF_BC_STRINT(BC_OP_LOADVAR, NULL, Bytecode_int_GetVarIndex(Handle, Name))
+ DEF_BC_INT(BC_OP_LOADVAR, Bytecode_int_GetVarIndex(Handle, Name))
// DEF_BC_STR(BC_OP_LOADVAR, Name)
void Bytecode_AppendSaveVar(tBC_Function *Handle, const char *Name) // (Obj->)?var =
- DEF_BC_STRINT(BC_OP_SAVEVAR, NULL, Bytecode_int_GetVarIndex(Handle, Name))
+ DEF_BC_INT(BC_OP_SAVEVAR, Bytecode_int_GetVarIndex(Handle, Name))
// DEF_BC_STR(BC_OP_SAVEVAR, Name)
// --- Constants
void Bytecode_AppendConstInt(tBC_Function *Handle, uint64_t Value)
{
- tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADINT);
+ tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADINT, 0);
op->Content.Integer = Value;
Bytecode_int_AppendOp(Handle, op);
}
void Bytecode_AppendConstReal(tBC_Function *Handle, double Value)
{
- tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADREAL);
+ tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADREAL, 0);
op->Content.Real = Value;
Bytecode_int_AppendOp(Handle, op);
}
void Bytecode_AppendConstString(tBC_Function *Handle, const void *Data, size_t Length)
- DEF_BC_STRINT(BC_OP_LOADSTR, Data, Length)
+{
+ tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADSTR, Length+1);
+ op->Content.StringInt.Integer = Length;
+ memcpy(op->Content.StringInt.String, Data, Length);
+ op->Content.StringInt.String[Length] = 0;
+ Bytecode_int_AppendOp(Handle, op);
+}
+void Bytecode_AppendConstNull(tBC_Function *Handle)
+ DEF_BC_NONE(BC_OP_LOADNULL)
// --- Indexing / Scoping
-void Bytecode_AppendSubNamespace(tBC_Function *Handle, const char *Name)
- DEF_BC_STR(BC_OP_SCOPE, Name)
void Bytecode_AppendElement(tBC_Function *Handle, const char *Name)
DEF_BC_STR(BC_OP_ELEMENT, Name)
+void Bytecode_AppendSetElement(tBC_Function *Handle, const char *Name)
+ DEF_BC_STR(BC_OP_SETELEMENT, Name)
void Bytecode_AppendIndex(tBC_Function *Handle)
DEF_BC_NONE(BC_OP_INDEX)
+void Bytecode_AppendSetIndex(tBC_Function *Handle)
+ DEF_BC_NONE(BC_OP_SETINDEX);
void Bytecode_AppendCreateObj(tBC_Function *Handle, const char *Name, int ArgumentCount)
DEF_BC_STRINT(BC_OP_CREATEOBJ, Name, ArgumentCount)
void Bytecode_AppendUniOp(tBC_Function *Handle, int Operation)
DEF_BC_NONE(Operation)
void Bytecode_AppendCast(tBC_Function *Handle, int Type)
- DEF_BC_STRINT(BC_OP_CAST, NULL, Type)
+ DEF_BC_INT(BC_OP_CAST, Type)
+void Bytecode_AppendDuplicate(tBC_Function *Handle)
+ DEF_BC_NONE(BC_OP_DUPSTACK);
+void Bytecode_AppendDelete(tBC_Function *Handle)
+ DEF_BC_NONE(BC_OP_DELSTACK);
// Does some bookeeping to allocate variable slots at compile time
void Bytecode_AppendEnterContext(tBC_Function *Handle)
Handle->CurContextDepth --;
Handle->VariableCount = i;
- DEF_BC_NONE(BC_OP_LEAVECONTEXT)
+ DEF_BC_NONE(BC_OP_LEAVECONTEXT);
}
//void Bytecode_AppendImportNamespace(tBC_Function *Handle, const char *Name);
// DEF_BC_STRINT(BC_OP_IMPORTNS, Name, 0)
#endif
i = Bytecode_int_AddVariable(Handle, Name);
-
+// printf("Variable %s given slot %i\n", Name, i);
+
DEF_BC_STRINT(BC_OP_DEFINEVAR, Name, (Type&0xFFFF) | (i << 16))
}