git.ucc.asn.au
/
tpg
/
acess2.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
Fixes to MakeReleaseSet script
[tpg/acess2.git]
/
Usermode
/
Libraries
/
libspiderscript.so_src
/
exec_bytecode.c
diff --git
a/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c
b/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c
index
50e2f4f
..
4673bd2
100644
(file)
--- a/
Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c
+++ b/
Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c
@@
-41,8
+41,8
@@
struct sBC_StackEnt
{
uint8_t Type;
union {
-
uint64_t
Integer;
- double
Real;
+
int64_t
Integer;
+ double Real;
tSpiderValue *Reference; // Used for everything else
tSpiderObject *Object;
tSpiderNamespace *Namespace;
@@
-154,6
+154,7
@@
void Bytecode_int_SetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *Value)
case SS_DATATYPE_OBJECT:
Ent->Type = SS_DATATYPE_OBJECT;
Ent->Object = Value->Object;
+ Ent->Object->ReferenceCount ++;
break;
default:
SpiderScript_ReferenceValue(Value);
@@
-169,10
+170,21
@@
void Bytecode_int_DerefStackValue(tBC_StackEnt *Ent)
{
case SS_DATATYPE_INTEGER:
case SS_DATATYPE_REAL:
+ break;
case SS_DATATYPE_OBJECT:
+ if(Ent->Object) {
+ Ent->Object->ReferenceCount --;
+ if(Ent->Object->ReferenceCount == 0) {
+ Ent->Object->Type->Destructor( Ent->Object );
+ }
+// printf("Object %p derefed (obj refcount = %i)\n", Ent->Object, Ent->Object->ReferenceCount);
+ }
+ Ent->Object = NULL;
break;
default:
- SpiderScript_DereferenceValue(Ent->Reference);
+ if(Ent->Reference)
+ SpiderScript_DereferenceValue(Ent->Reference);
+ Ent->Reference = NULL;
break;
}
}
@@
-182,10
+194,16
@@
void Bytecode_int_RefStackValue(tBC_StackEnt *Ent)
{
case SS_DATATYPE_INTEGER:
case SS_DATATYPE_REAL:
+ break;
case SS_DATATYPE_OBJECT:
+ if(Ent->Object) {
+ Ent->Object->ReferenceCount ++;
+// printf("Object %p referenced (count = %i)\n", Ent->Object, Ent->Object->ReferenceCount);
+ }
break;
default:
- SpiderScript_ReferenceValue(Ent->Reference);
+ if(Ent->Reference)
+ SpiderScript_ReferenceValue(Ent->Reference);
break;
}
}
@@
-335,6
+353,8
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
switch(op->Operation)
{
case BC_OP_NOP:
+ STATE_HDR();
+ DEBUG_F("NOP\n");
break;
// Jumps
case BC_OP_JUMP:
@@
-392,28
+412,32
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
break;
// Variables
- case BC_OP_LOADVAR:
+ case BC_OP_LOADVAR: {
+ int slot = OP_INDX(op);
STATE_HDR();
- DEBUG_F("LOADVAR %i ",
OP_INDX(op)
);
- if(
OP_INDX(op) < 0 || OP_INDX(op)
>= local_var_count ) {
- AST_RuntimeError(NULL, "Loading from invalid slot %i",
OP_INDX(op)
);
+ DEBUG_F("LOADVAR %i ",
slot
);
+ if(
slot < 0 || slot
>= local_var_count ) {
+ AST_RuntimeError(NULL, "Loading from invalid slot %i",
slot
);
return -1;
}
- DEBUG_F("("); PRINT_STACKVAL(local_vars[OP_INDX(op)]); DEBUG_F(")\n");
- PUT_STACKVAL(local_vars[OP_INDX(op)]);
- Bytecode_int_RefStackValue( &local_vars[OP_INDX(op)] );
- break;
- case BC_OP_SAVEVAR:
+ DEBUG_F("("); PRINT_STACKVAL(local_vars[slot]); DEBUG_F(")\n");
+ PUT_STACKVAL(local_vars[slot]);
+ Bytecode_int_RefStackValue( &local_vars[slot] );
+ } break;
+ case BC_OP_SAVEVAR: {
+ int slot = OP_INDX(op);
STATE_HDR();
- DEBUG_F("SAVEVAR %i = ",
OP_INDX(op)
);
- if(
OP_INDX(op) < 0 || OP_INDX(op)
>= local_var_count ) {
- AST_RuntimeError(NULL, "Loading from invalid slot %i",
OP_INDX(op)
);
+ DEBUG_F("SAVEVAR %i = ",
slot
);
+ if(
slot < 0 || slot
>= local_var_count ) {
+ AST_RuntimeError(NULL, "Loading from invalid slot %i",
slot
);
return -1;
}
- PRINT_STACKVAL(local_vars[OP_INDX(op)]);
+ DEBUG_F("[Deref "); PRINT_STACKVAL(local_vars[slot]); DEBUG_F("] ");
+ Bytecode_int_DerefStackValue( &local_vars[slot] );
+ GET_STACKVAL(local_vars[slot]);
+ PRINT_STACKVAL(local_vars[slot]);
DEBUG_F("\n");
- GET_STACKVAL(local_vars[OP_INDX(op)]);
- break;
+ } break;
// Constants:
case BC_OP_LOADINT:
@@
-522,6
+546,32
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
if(!ast_op) ast_op = NODETYPE_LOGICALOR, opstr = "LOGICOR";
case BC_OP_LOGICXOR:
if(!ast_op) ast_op = NODETYPE_LOGICALXOR, opstr = "LOGICXOR";
+
+ STATE_HDR();
+ DEBUG_F("%s\n", opstr);
+
+ GET_STACKVAL(val1);
+ GET_STACKVAL(val2);
+
+ switch(op->Operation)
+ {
+ case BC_OP_LOGICAND:
+ i = Bytecode_int_IsStackEntTrue(&val1) && Bytecode_int_IsStackEntTrue(&val2);
+ break;
+ case BC_OP_LOGICOR:
+ i = Bytecode_int_IsStackEntTrue(&val1) || Bytecode_int_IsStackEntTrue(&val2);
+ break;
+ case BC_OP_LOGICXOR:
+ i = Bytecode_int_IsStackEntTrue(&val1) ^ Bytecode_int_IsStackEntTrue(&val2);
+ break;
+ }
+ Bytecode_int_DerefStackValue(&val1);
+ Bytecode_int_DerefStackValue(&val2);
+
+ val1.Type = SS_DATATYPE_INTEGER;
+ val1.Integer = i;
+ Bytecode_int_StackPush(Stack, &val1);
+ break;
case BC_OP_BITAND:
if(!ast_op) ast_op = NODETYPE_BWAND, opstr = "BITAND";
@@
-564,6
+614,32
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
GET_STACKVAL(val2); // Right
GET_STACKVAL(val1); // Left
+
+ #define PERFORM_NUM_OP(_type, _field) if(val1.Type == _type && val1.Type == val2.Type) { \
+ switch(op->Operation) { \
+ case BC_OP_ADD: val1._field = val1._field + val2._field; break; \
+ case BC_OP_SUBTRACT: val1._field = val1._field - val2._field; break; \
+ case BC_OP_MULTIPLY: val1._field = val1._field * val2._field; break; \
+ case BC_OP_DIVIDE: val1._field = val1._field / val2._field; break; \
+ case BC_OP_EQUALS: val1._field = val1._field == val2._field; break; \
+ case BC_OP_LESSTHAN: val1._field = val1._field < val2._field; break; \
+ case BC_OP_LESSTHANOREQUAL: val1._field = val1._field <= val2._field; break; \
+ case BC_OP_GREATERTHAN: val1._field = val1._field > val2._field; break; \
+ case BC_OP_GREATERTHANOREQUAL: val1._field = val1._field >= val2._field; break; \
+ \
+ case BC_OP_BITAND: val1._field = (int64_t)val1._field & (int64_t)val2._field; break; \
+ case BC_OP_BITOR: val1._field = (int64_t)val1._field | (int64_t)val2._field; break; \
+ case BC_OP_BITXOR: val1._field = (int64_t)val1._field ^ (int64_t)val2._field; break; \
+ case BC_OP_MODULO: val1._field = (int64_t)val1._field % (int64_t)val2._field; break; \
+ default: AST_RuntimeError(NULL, "Invalid operation on datatype %i", _type); nextop = NULL; break;\
+ }\
+ PUT_STACKVAL(val1);\
+ break;\
+ }
+
+ PERFORM_NUM_OP(SS_DATATYPE_INTEGER, Integer);
+ PERFORM_NUM_OP(SS_DATATYPE_REAL, Real);
+
pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
Bytecode_int_DerefStackValue(&val1);
@@
-572,40
+648,51
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
ret_val = AST_ExecuteNode_BinOp(Script, NULL, ast_op, pval1, pval2);
if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
if(pval2 != &tmpVal2) SpiderScript_DereferenceValue(pval2);
+
+ if(ret_val == ERRPTR) {
+ AST_RuntimeError(NULL, "_BinOp returned ERRPTR");
+ nextop = NULL;
+ break;
+ }
Bytecode_int_SetSpiderValue(&val1, ret_val);
if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
PUT_STACKVAL(val1);
break;
// Functions etc
- case BC_OP_CALLFUNCTION: {
- tScript_Function *fcn;
+ case BC_OP_CREATEOBJ:
+ case BC_OP_CALLFUNCTION:
+ case BC_OP_CALLMETHOD: {
+ tScript_Function *fcn = NULL;
const char *name = OP_STRING(op);
int arg_count = OP_INDX(op);
STATE_HDR();
DEBUG_F("CALL FUNCTION %s %i args\n", name, arg_count);
- // Check current script functions (for fast call)
- for(fcn = Script->Functions; fcn; fcn = fcn->Next)
+ if( op->Operation == BC_OP_CALLFUNCTION )
{
- if(strcmp(name, fcn->Name) == 0) {
+ // Check current script functions (for fast call)
+ for(fcn = Script->Functions; fcn; fcn = fcn->Next)
+ {
+ if(strcmp(name, fcn->Name) == 0) {
+ break;
+ }
+ }
+ if(fcn && fcn->BCFcn)
+ {
+ DEBUG_F(" - Fast call\n");
+ Bytecode_int_ExecuteFunction(Script, fcn, Stack, arg_count);
break;
}
}
- if(fcn && fcn->BCFcn)
- {
- DEBUG_F(" - Fast call\n");
- Bytecode_int_ExecuteFunction(Script, fcn, Stack, arg_count);
- break;
- }
// Slower call
{
tSpiderNamespace *ns = NULL;
tSpiderValue *args[arg_count];
tSpiderValue *rv;
-// for( i = 0; i < arg_count; i ++ )
+ // Read arguments
for( i = arg_count; i --; )
{
GET_STACKVAL(val1);
@@
-613,16
+700,50
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
Bytecode_int_DerefStackValue(&val1);
}
- if( name[0] == BC_NS_SEPARATOR ) {
- name ++;
- ns = Bytecode_int_ResolveNamespace(&Script->Variant->RootNamespace, name, &name);
- }
- else {
- // TODO: Support multiple default namespaces
- ns = Bytecode_int_ResolveNamespace(default_namespace, name, &name);
+ // Resolve namespace into pointer
+ if( op->Operation != BC_OP_CALLMETHOD ) {
+ if( name[0] == BC_NS_SEPARATOR ) {
+ name ++;
+ ns = Bytecode_int_ResolveNamespace(&Script->Variant->RootNamespace, name, &name);
+ }
+ else {
+ // TODO: Support multiple default namespaces
+ ns = Bytecode_int_ResolveNamespace(default_namespace, name, &name);
+ }
}
- rv = SpiderScript_ExecuteFunction(Script, ns, name, arg_count, args);
+ // Call the function etc.
+ if( op->Operation == BC_OP_CALLFUNCTION )
+ {
+ rv = SpiderScript_ExecuteFunction(Script, ns, name, arg_count, args);
+ }
+ else if( op->Operation == BC_OP_CREATEOBJ )
+ {
+ rv = SpiderScript_CreateObject(Script, ns, name, arg_count, args);
+ }
+ else if( op->Operation == BC_OP_CALLMETHOD )
+ {
+ tSpiderObject *obj;
+ GET_STACKVAL(val1);
+
+ if(val1.Type == SS_DATATYPE_OBJECT)
+ obj = val1.Object;
+ else if(val1.Type == ET_REFERENCE && val1.Reference->Type == SS_DATATYPE_OBJECT)
+ obj = val1.Reference->Object;
+ else {
+ // Error
+ AST_RuntimeError(NULL, "OP_CALLMETHOD on non object");
+ nextop = NULL;
+ break;
+ }
+ rv = SpiderScript_ExecuteMethod(Script, obj, name, arg_count, args);
+ Bytecode_int_DerefStackValue(&val1);
+ }
+ else
+ {
+ AST_RuntimeError(NULL, "BUG - Unknown operation for CALL/CREATEOBJ (%i)", op->Operation);
+ rv = ERRPTR;
+ }
if(rv == ERRPTR) {
AST_RuntimeError(NULL, "SpiderScript_ExecuteFunction returned ERRPTR");
nextop = NULL;
@@
-648,7
+769,7
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
default:
// TODO:
STATE_HDR();
-
printf(
"Unknown operation %i\n", op->Operation);
+
AST_RuntimeError(NULL,
"Unknown operation %i\n", op->Operation);
nextop = NULL;
break;
}
UCC
git Repository :: git.ucc.asn.au