Usermode/libspiderscript - Fixing a multitude of bugs
[tpg/acess2.git] / Usermode / Libraries / libspiderscript.so_src / exec_bytecode.c
index 9dabeff..d12cb73 100644 (file)
@@ -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;
@@ -84,7 +84,7 @@ int Bytecode_int_IsStackEntTrue(tBC_StackEnt *Ent)
        case SS_DATATYPE_INTEGER:
                return !!Ent->Integer;
        case SS_DATATYPE_REAL:
-               return (-.5f < Ent->Real && Ent->Real < 0.5f);
+               return !(-.5f < Ent->Real && Ent->Real < 0.5f);
        case SS_DATATYPE_OBJECT:
                return Ent->Object != NULL;
        case ET_FUNCTION_START:
@@ -412,30 +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;
                        }
-                       DEBUG_F("[Deref "); PRINT_STACKVAL(local_vars[OP_INDX(op)]); DEBUG_F("] ");
-                       Bytecode_int_DerefStackValue( &local_vars[OP_INDX(op)] );
-                       GET_STACKVAL(local_vars[OP_INDX(op)]);
-                       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");
-                       break;
+                       break;
 
                // Constants:
                case BC_OP_LOADINT:
@@ -519,11 +521,14 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                        Bytecode_int_StackPush(Stack, &val2);
                        Bytecode_int_DerefStackValue(&val1);
                        break;
+               
                case BC_OP_BITNOT:
-                       if(!ast_op)     ast_op = NODETYPE_BWNOT;
+                       if(!ast_op)     ast_op = NODETYPE_BWNOT,        opstr = "BITNOT";
+               case BC_OP_NEG:
+                       if(!ast_op)     ast_op = NODETYPE_NEGATE,       opstr = "NEG";
 
                        STATE_HDR();
-                       DEBUG_F("UNIOP %i\n", ast_op);
+                       DEBUG_F("%s\n", opstr);
 
                        GET_STACKVAL(val1);
                        pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
@@ -598,6 +603,8 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
 
                case BC_OP_EQUALS:
                        if(!ast_op)     ast_op = NODETYPE_EQUALS,       opstr = "EQUALS";
+               case BC_OP_NOTEQUALS:
+                       if(!ast_op)     ast_op = NODETYPE_NOTEQUALS,    opstr = "NOTEQUALS";
                case BC_OP_LESSTHAN:
                        if(!ast_op)     ast_op = NODETYPE_LESSTHAN,     opstr = "LESSTHAN";
                case BC_OP_LESSTHANOREQUAL:
@@ -612,6 +619,38 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
 
                        GET_STACKVAL(val2);     // Right
                        GET_STACKVAL(val1);     // Left
+
+                       DEBUG_F(" ("); PRINT_STACKVAL(val1); DEBUG_F(")");
+                       DEBUG_F(" ("); PRINT_STACKVAL(val2); DEBUG_F(")\n");
+
+                       #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.Type=SS_DATATYPE_INTEGER; val1.Integer = (val1._field == val2._field);     break; \
+                               case BC_OP_NOTEQUALS:   val1.Type=SS_DATATYPE_INTEGER; val1.Integer = (val1._field != val2._field);     break; \
+                               case BC_OP_LESSTHAN:    val1.Type=SS_DATATYPE_INTEGER; val1.Integer = val1._field < val2._field;        break; \
+                               case BC_OP_LESSTHANOREQUAL:     val1.Type=SS_DATATYPE_INTEGER; val1.Integer = val1._field <= val2._field;       break; \
+                               case BC_OP_GREATERTHAN: val1.Type=SS_DATATYPE_INTEGER; val1.Integer = val1._field > val2._field;        break; \
+                               case BC_OP_GREATERTHANOREQUAL:  val1.Type=SS_DATATYPE_INTEGER; val1.Integer = 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;\
+                               }\
+                               DEBUG_F(" - Fast local op\n");\
+                               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);
@@ -700,7 +739,7 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                                        
                                        if(val1.Type == SS_DATATYPE_OBJECT)
                                                obj = val1.Object;
-                                       else if(val1.Type == ET_REFERENCE && val1.Reference->Type == SS_DATATYPE_OBJECT)
+                                       else if(val1.Type == ET_REFERENCE && val1.Reference && val1.Reference->Type == SS_DATATYPE_OBJECT)
                                                obj = val1.Reference->Object;
                                        else {
                                                // Error

UCC git Repository :: git.ucc.asn.au