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:
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);
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_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)
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)