SpiderScript - Bugfixing, most bytecode runs now
authorJohn Hodge <[email protected]>
Wed, 21 Sep 2011 04:20:02 +0000 (12:20 +0800)
committerJohn Hodge <[email protected]>
Wed, 21 Sep 2011 04:20:02 +0000 (12:20 +0800)
Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h
Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h
Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c

index 6b7e038..7c1398e 100644 (file)
@@ -94,11 +94,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
        tAST_Node       *node;
         int    ret = 0;
         int    i, op = 0;
+        int    bAddedValue = 1;
        
        switch(Node->Type)
        {
        // No Operation
        case NODETYPE_NOP:
+               bAddedValue = 0;
                break;
        
        // Code block
@@ -117,6 +119,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                        }
                }
                Bytecode_AppendLeaveContext(Block->Handle);     // Leave this context
+               bAddedValue = 0;
                break;
        
        // Assignment
@@ -126,8 +129,6 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                        AST_RuntimeError(Node, "LVALUE of assignment is not a variable");
                        return -1;
                }
-               ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
-               if(ret) return ret;
                
                // Perform assignment operation
                if( Node->Assign.Operation != NODETYPE_NOP )
@@ -135,6 +136,8 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                        
                        ret = BC_Variable_GetValue(Block, Node->Assign.Dest);
                        if(ret) return ret;
+                       ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
+                       if(ret) return ret;
                        switch(Node->Assign.Operation)
                        {
                        // General Binary Operations
@@ -157,11 +160,17 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                        printf("assign, op = %i\n", op);
                        Bytecode_AppendBinOp(Block->Handle, op);
                }
+               else
+               {
+                       ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
+                       if(ret) return ret;
+               }
                
                if( bKeepValue )
                        Bytecode_AppendDuplicate(Block->Handle);
                // Set the variable value
                ret = BC_Variable_SetValue( Block, Node->Assign.Dest );
+               bAddedValue = 0;
                break;
        
        // Post increment/decrement
@@ -269,6 +278,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
 
                // End
                Bytecode_SetLabel(Block->Handle, if_end);
+               bAddedValue = 0;
                } break;
        
        // Loop
@@ -327,6 +337,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                Block->BreakTarget = saved_break;
                Block->ContinueTarget = saved_continue;
                Block->Tag = saved_tag;
+               bAddedValue = 0;
                } break;
        
        // Return
@@ -334,6 +345,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                ret = AST_ConvertNode(Block, Node->UniOp.Value, 1);
                if(ret) return ret;
                Bytecode_AppendReturn(Block->Handle);
+               bAddedValue = 0;
                break;
        
        case NODETYPE_BREAK:
@@ -348,6 +360,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                        Bytecode_AppendJump(Block->Handle, bi->BreakTarget);
                else
                        Bytecode_AppendJump(Block->Handle, bi->ContinueTarget);
+               bAddedValue = 0;
                } break;
        
        // Define a variable
@@ -361,6 +374,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                        if(ret) return ret;
                        Bytecode_AppendSaveVar(Block->Handle, Node->DefVar.Name);
                }
+               bAddedValue = 0;
                break;
        
        // Scope
@@ -466,10 +480,10 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                Bytecode_AppendBinOp(Block->Handle, op);
                break;
        
-       //default:
-       //      ret = NULL;
-       //      AST_RuntimeError(Node, "BUG - SpiderScript AST_ConvertNode Unimplemented %i", Node->Type);
-       //      break;
+       default:
+               ret = -1;
+               AST_RuntimeError(Node, "BUG - SpiderScript AST_ConvertNode Unimplemented %i", Node->Type);
+               break;
        }
 
        #if TRACE_NODE_RETURNS
@@ -481,6 +495,9 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
        }
        #endif
 
+       if( !bKeepValue && bAddedValue )
+               Bytecode_AppendDelete(Block->Handle);
+
        return ret;
 }
 
index 54835ae..b089b9a 100644 (file)
@@ -395,6 +395,8 @@ void Bytecode_AppendCast(tBC_Function *Handle, int 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)
@@ -414,7 +416,7 @@ void Bytecode_AppendLeaveContext(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)
index 955049b..0d901eb 100644 (file)
@@ -67,6 +67,7 @@ extern void   Bytecode_AppendBinOp(tBC_Function *Handle, int Operation);
 extern void    Bytecode_AppendUniOp(tBC_Function *Handle, int Operation);
 extern void    Bytecode_AppendCast(tBC_Function *Handlde, int Type);
 extern void    Bytecode_AppendDuplicate(tBC_Function *Handlde);
+extern void    Bytecode_AppendDelete(tBC_Function *Handle);
 // - Context
 //   TODO: Are contexts needed? Should variables be allocated like labels?
 extern void    Bytecode_AppendEnterContext(tBC_Function *Handle);
index 1d15c59..59c58be 100644 (file)
@@ -24,38 +24,39 @@ enum eBC_Ops
        BC_OP_LOADSTR,
 
        BC_OP_DUPSTACK, // = 13
+       BC_OP_DELSTACK, // 
        BC_OP_CAST,     //
        
-       BC_OP_ELEMENT,  // = 15
+       BC_OP_ELEMENT,  // = 16
        BC_OP_INDEX,
 
-       BC_OP_ENTERCONTEXT,     // = 17
+       BC_OP_ENTERCONTEXT,     // = 18
        BC_OP_LEAVECONTEXT,
        BC_OP_DEFINEVAR,
 
        // Operations
-       BC_OP_LOGICNOT, // 20
+       BC_OP_LOGICNOT, // 21
        BC_OP_LOGICAND,
        BC_OP_LOGICOR,
        BC_OP_LOGICXOR,
 
-       BC_OP_BITNOT,   // 24
+       BC_OP_BITNOT,   // 25
        BC_OP_BITAND,
        BC_OP_BITOR,
        BC_OP_BITXOR,
 
-       BC_OP_BITSHIFTLEFT,     // 28
+       BC_OP_BITSHIFTLEFT,     // 29
        BC_OP_BITSHIFTRIGHT,
        BC_OP_BITROTATELEFT,
 
-       BC_OP_NEG,      // 31
+       BC_OP_NEG,      // 32
        BC_OP_ADD,
        BC_OP_SUBTRACT,
        BC_OP_MULTIPLY,
        BC_OP_DIVIDE,
        BC_OP_MODULO,
 
-       BC_OP_EQUALS,   // 37
+       BC_OP_EQUALS,   // 38
        BC_OP_NOTEQUALS,
        BC_OP_LESSTHAN,
        BC_OP_LESSTHANOREQUAL,
index 1a74d4c..50e2f4f 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include "ast.h"
+#include <inttypes.h>
 
-//#define DEBUG_F(v...)        printf(v)
-#define DEBUG_F(v...)
+#define TRACE  0
+
+#if TRACE
+# define DEBUG_F(v...) printf(v)
+#else
+# define DEBUG_F(v...)
+#endif
 
 // === IMPORTS ===
 extern void    AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
@@ -123,6 +129,7 @@ tSpiderValue *Bytecode_int_GetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *tmp)
                AST_RuntimeError(NULL, "_GetSpiderValue on ET_FUNCTION_START");
                return NULL;
        default:
+               SpiderScript_ReferenceValue(Ent->Reference);
                return Ent->Reference;
        }
 }
@@ -169,13 +176,51 @@ void Bytecode_int_DerefStackValue(tBC_StackEnt *Ent)
                break;
        }
 }
+void Bytecode_int_RefStackValue(tBC_StackEnt *Ent)
+{
+       switch(Ent->Type)
+       {
+       case SS_DATATYPE_INTEGER:
+       case SS_DATATYPE_REAL:
+       case SS_DATATYPE_OBJECT:
+               break;
+       default:
+               SpiderScript_ReferenceValue(Ent->Reference);
+               break;
+       }
+}
+
+void Bytecode_int_PrintStackValue(tBC_StackEnt *Ent)
+{
+       switch(Ent->Type)
+       {
+       case SS_DATATYPE_INTEGER:
+               printf("0x%"PRIx64, Ent->Integer);
+               break;
+       case SS_DATATYPE_REAL:
+               printf("%lf", Ent->Real);
+               break;
+       case SS_DATATYPE_OBJECT:
+               printf("Obj %p", Ent->Object);
+               break;
+       default:
+               printf("*%p", Ent->Reference);
+               break;
+       }
+}
+
+#if TRACE
+# define PRINT_STACKVAL(val)   Bytecode_int_PrintStackValue(&val)
+#else
+# define PRINT_STACKVAL(val)
+#endif
 
 #define GET_STACKVAL(dst)      if((ret = Bytecode_int_StackPop(Stack, &dst))) { \
        AST_RuntimeError(NULL, "Stack pop failed, empty stack");\
        return ret; \
 }
 #define PUT_STACKVAL(src)      if((ret = Bytecode_int_StackPush(Stack, &src))) { \
-       AST_RuntimeError(NULL, "Stack pop failed, empty stack");\
+       AST_RuntimeError(NULL, "Stack push failed, full stack");\
        return ret; \
 }
 #define OP_INDX(op_ptr)        ((op_ptr)->Content.StringInt.Integer)
@@ -255,6 +300,10 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
        tSpiderValue    tmpVal1, tmpVal2;       // temp storage
        tSpiderValue    *pval1, *pval2, *ret_val;
        tSpiderNamespace        *default_namespace = &Script->Variant->RootNamespace;
+
+       // Initialise local vars
+       for( i = 0; i < local_var_count; i ++ )
+               local_vars[i].Type = ET_NULL;
        
        // Pop off arguments
        if( ArgCount > Fcn->ArgumentCount )     return -1;
@@ -323,6 +372,10 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                        }
                        STATE_HDR();
                        DEBUG_F("DEFVAR %i of type %i\n", slot, type);
+                       if( local_vars[slot].Type != ET_NULL ) {
+                               Bytecode_int_DerefStackValue( &local_vars[slot] );
+                               local_vars[slot].Type = ET_NULL;
+                       }
                        memset(&local_vars[slot], 0, sizeof(local_vars[0]));
                        local_vars[slot].Type = type;
                        } break;
@@ -341,21 +394,24 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                // Variables
                case BC_OP_LOADVAR:
                        STATE_HDR();
-                       DEBUG_F("LOADVAR %i\n", OP_INDX(op));
+                       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));
                                return -1;
                        }
+                       DEBUG_F("("); PRINT_STACKVAL(local_vars[OP_INDX(op)]); DEBUG_F(")\n");
                        PUT_STACKVAL(local_vars[OP_INDX(op)]);
-//                     DUMP_STACKVAL(local_vars[OP_INDX(op)]);
+                       Bytecode_int_RefStackValue( &local_vars[OP_INDX(op)] );
                        break;
                case BC_OP_SAVEVAR:
                        STATE_HDR();
-                       DEBUG_F("SAVEVAR %i\n", OP_INDX(op));
+                       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));
                                return -1;
                        }
+                       PRINT_STACKVAL(local_vars[OP_INDX(op)]);
+                       DEBUG_F("\n");
                        GET_STACKVAL(local_vars[OP_INDX(op)]);
                        break;
 
@@ -398,7 +454,7 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                                PUT_STACKVAL(val2);
                                break;
                        case SS_DATATYPE_REAL*100 + SS_DATATYPE_INTEGER:
-                               val2.Integer = val1.Real;
+                               val2.Real = val1.Integer;
                                PUT_STACKVAL(val2);
                                break;
                        default: {
@@ -414,10 +470,20 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
 
                case BC_OP_DUPSTACK:
                        STATE_HDR();
-                       DEBUG_F("DUPSTACK\n");
+                       DEBUG_F("DUPSTACK ");
                        GET_STACKVAL(val1);
+                       PRINT_STACKVAL(val1);
+                       DEBUG_F("\n");
                        PUT_STACKVAL(val1);
                        PUT_STACKVAL(val1);
+                       Bytecode_int_RefStackValue(&val1);
+                       break;
+
+               // Discard the top item from the stack
+               case BC_OP_DELSTACK:
+                       STATE_HDR();
+                       DEBUG_F("DELSTACK\n");
+                       GET_STACKVAL(val1);
                        break;
 
                // Unary Operations
@@ -439,6 +505,8 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
 
                        GET_STACKVAL(val1);
                        pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
+                       Bytecode_int_DerefStackValue(&val1);                    
+
                        ret_val = AST_ExecuteNode_UniOp(Script, NULL, ast_op, pval1);
                        if(pval1 != &tmpVal1)   SpiderScript_DereferenceValue(pval1);
                        Bytecode_int_SetSpiderValue(&val1, ret_val);
@@ -494,16 +562,19 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                        STATE_HDR();
                        DEBUG_F("BINOP %i %s (bc %i)\n", ast_op, opstr, op->Operation);
 
-                       GET_STACKVAL(val2);
-                       GET_STACKVAL(val1);
+                       GET_STACKVAL(val2);     // Right
+                       GET_STACKVAL(val1);     // Left
                        pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
                        pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
+                       Bytecode_int_DerefStackValue(&val1);
+                       Bytecode_int_DerefStackValue(&val2);
+
                        ret_val = AST_ExecuteNode_BinOp(Script, NULL, ast_op, pval1, pval2);
                        if(pval1 != &tmpVal1)   SpiderScript_DereferenceValue(pval1);
                        if(pval2 != &tmpVal2)   SpiderScript_DereferenceValue(pval2);
                        Bytecode_int_SetSpiderValue(&val1, ret_val);
                        if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
-                       Bytecode_int_StackPush(Stack, &val1);
+                       PUT_STACKVAL(val1);
                        break;
 
                // Functions etc
@@ -539,6 +610,7 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                                {
                                        GET_STACKVAL(val1);
                                        args[i] = Bytecode_int_GetSpiderValue(&val1, NULL);
+                                       Bytecode_int_DerefStackValue(&val1);
                                }
                                
                                if( name[0] == BC_NS_SEPARATOR ) {
@@ -585,14 +657,27 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
        
        // Clean up
        // - Delete local vars
-       printf("TODO: Clean up local vars\n");
+       for( i = 0; i < local_var_count; i ++ )
+       {
+               if( local_vars[i].Type != ET_NULL )
+               {
+                       Bytecode_int_DerefStackValue(&local_vars[i]);
+               }
+       }
        
        // - Restore stack
 //     printf("TODO: Roll back stack\n");
-//     while( Stack->EntryCount && Stack->Entries[ --Stack->EntryCount ].Type != ET_FUNCTION_START )
-//     {
-//             Bytecode_int_DerefStackValue( &Stack->Entries[Stack->EntryCount] );
-//     }
+       if( Stack->Entries[Stack->EntryCount - 1].Type == ET_FUNCTION_START )
+               Stack->EntryCount --;
+       else
+       {
+               GET_STACKVAL(val1);
+               while( Stack->EntryCount && Stack->Entries[ --Stack->EntryCount ].Type != ET_FUNCTION_START )
+               {
+                       Bytecode_int_DerefStackValue( &Stack->Entries[Stack->EntryCount] );
+               }
+               PUT_STACKVAL(val1);
+       }
        
 
        return 0;

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