3 * by John Hodge (thePowersGang)
20 # define DEBUG_F(v...) printf(v)
22 # define DEBUG_F(v...)
26 extern void AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
29 typedef struct sBC_StackEnt tBC_StackEnt;
30 typedef struct sBC_Stack tBC_Stack;
32 enum eBC_StackEntTypes
34 ET_NULL, // Start of the stack
36 ET_FUNCTION_START = NUM_SS_DATATYPES,
37 ET_REFERENCE // Reference to a tSpiderValue
46 tSpiderValue *Reference; // Used for everything else
47 tSpiderObject *Object;
48 tSpiderNamespace *Namespace;
56 tBC_StackEnt Entries[];
60 tSpiderValue *Bytecode_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Args);
61 int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, tBC_Stack *Stack, int ArgCount);
64 int Bytecode_int_StackPop(tBC_Stack *Stack, tBC_StackEnt *Dest)
66 if( Stack->EntryCount == 0 ) return 1;
68 *Dest = Stack->Entries[Stack->EntryCount];
72 int Bytecode_int_StackPush(tBC_Stack *Stack, tBC_StackEnt *Src)
74 if( Stack->EntryCount == Stack->EntrySpace ) return 1;
75 Stack->Entries[Stack->EntryCount] = *Src;
80 int Bytecode_int_IsStackEntTrue(tBC_StackEnt *Ent)
84 case SS_DATATYPE_INTEGER:
85 return !!Ent->Integer;
86 case SS_DATATYPE_REAL:
87 return !(-.5f < Ent->Real && Ent->Real < 0.5f);
88 case SS_DATATYPE_OBJECT:
89 return Ent->Object != NULL;
90 case ET_FUNCTION_START:
93 return SpiderScript_IsValueTrue(Ent->Reference);
97 tSpiderValue *Bytecode_int_GetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *tmp)
101 case SS_DATATYPE_INTEGER:
102 case SS_DATATYPE_REAL:
103 case SS_DATATYPE_OBJECT:
105 tmp = malloc(sizeof(tSpiderValue));
106 tmp->ReferenceCount = 1;
108 tmp->ReferenceCount = 2;
116 case SS_DATATYPE_INTEGER:
117 tmp->Type = SS_DATATYPE_INTEGER;
118 tmp->Integer = Ent->Integer;
120 case SS_DATATYPE_REAL:
121 tmp->Type = SS_DATATYPE_REAL;
122 tmp->Real = Ent->Real;
124 case SS_DATATYPE_OBJECT:
125 tmp->Type = SS_DATATYPE_OBJECT;
126 tmp->Object = Ent->Object;
128 case ET_FUNCTION_START:
129 AST_RuntimeError(NULL, "_GetSpiderValue on ET_FUNCTION_START");
132 SpiderScript_ReferenceValue(Ent->Reference);
133 return Ent->Reference;
137 void Bytecode_int_SetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *Value)
140 Ent->Type = ET_REFERENCE;
141 Ent->Reference = NULL;
146 case SS_DATATYPE_INTEGER:
147 Ent->Type = SS_DATATYPE_INTEGER;
148 Ent->Integer = Value->Integer;
150 case SS_DATATYPE_REAL:
151 Ent->Type = SS_DATATYPE_REAL;
152 Ent->Real = Value->Real;
154 case SS_DATATYPE_OBJECT:
155 Ent->Type = SS_DATATYPE_OBJECT;
156 Ent->Object = Value->Object;
157 Ent->Object->ReferenceCount ++;
160 SpiderScript_ReferenceValue(Value);
161 Ent->Type = ET_REFERENCE;
162 Ent->Reference = Value;
167 void Bytecode_int_DerefStackValue(tBC_StackEnt *Ent)
171 case SS_DATATYPE_INTEGER:
172 case SS_DATATYPE_REAL:
174 case SS_DATATYPE_OBJECT:
176 Ent->Object->ReferenceCount --;
177 if(Ent->Object->ReferenceCount == 0) {
178 Ent->Object->Type->Destructor( Ent->Object );
180 // printf("Object %p derefed (obj refcount = %i)\n", Ent->Object, Ent->Object->ReferenceCount);
186 SpiderScript_DereferenceValue(Ent->Reference);
187 Ent->Reference = NULL;
191 void Bytecode_int_RefStackValue(tBC_StackEnt *Ent)
195 case SS_DATATYPE_INTEGER:
196 case SS_DATATYPE_REAL:
198 case SS_DATATYPE_OBJECT:
200 Ent->Object->ReferenceCount ++;
201 // printf("Object %p referenced (count = %i)\n", Ent->Object, Ent->Object->ReferenceCount);
206 SpiderScript_ReferenceValue(Ent->Reference);
211 void Bytecode_int_PrintStackValue(tBC_StackEnt *Ent)
215 case SS_DATATYPE_INTEGER:
216 printf("0x%"PRIx64, Ent->Integer);
218 case SS_DATATYPE_REAL:
219 printf("%lf", Ent->Real);
221 case SS_DATATYPE_OBJECT:
222 printf("Obj %p", Ent->Object);
225 printf("*%p", Ent->Reference);
231 # define PRINT_STACKVAL(val) Bytecode_int_PrintStackValue(&val)
233 # define PRINT_STACKVAL(val)
236 #define GET_STACKVAL(dst) if((ret = Bytecode_int_StackPop(Stack, &dst))) { \
237 AST_RuntimeError(NULL, "Stack pop failed, empty stack");\
240 #define PUT_STACKVAL(src) if((ret = Bytecode_int_StackPush(Stack, &src))) { \
241 AST_RuntimeError(NULL, "Stack push failed, full stack");\
244 #define OP_INDX(op_ptr) ((op_ptr)->Content.StringInt.Integer)
245 #define OP_STRING(op_ptr) ((op_ptr)->Content.StringInt.String)
247 tSpiderValue *Bytecode_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Args)
249 const int stack_size = 100;
250 tSpiderValue *ret, tmpsval;
255 stack = malloc(sizeof(tBC_Stack) + stack_size*sizeof(tBC_StackEnt));
256 stack->EntrySpace = stack_size;
257 stack->EntryCount = 0;
259 // Push arguments in order (so top is last arg)
260 for( i = 0; i < NArguments; i ++ )
262 Bytecode_int_SetSpiderValue(&val, Args[i]);
263 Bytecode_int_StackPush(stack, &val);
267 Bytecode_int_ExecuteFunction(Script, Fcn, stack, NArguments);
270 if( Bytecode_int_StackPop(stack, &val) ) {
275 ret = Bytecode_int_GetSpiderValue(&val, &tmpsval);
276 // Ensure it's a heap value
277 if(ret == &tmpsval) {
278 ret = malloc(sizeof(tSpiderValue));
279 memcpy(ret, &tmpsval, sizeof(tSpiderValue));
285 tSpiderNamespace *Bytecode_int_ResolveNamespace(tSpiderNamespace *Start, const char *Name, const char **FinalName)
288 tSpiderNamespace *ns = Start;
289 while( (pos = strchr(Name, BC_NS_SEPARATOR)) )
291 int len = pos - Name;
292 for( ns = ns->FirstChild; ns; ns = ns->Next )
294 if(memcmp(ns->Name, Name, len) == 0 && ns->Name[len] == 0)
302 if(FinalName) *FinalName = Name;
307 * \brief Call an external function (may recurse into Bytecode_ExecuteFunction, but may not)
309 int Bytecode_int_CallExternFunction(tSpiderScript *Script, tBC_Stack *Stack, tSpiderNamespace *DefaultNS, tBC_Op *op )
311 const char *name = OP_STRING(op);
312 int arg_count = OP_INDX(op);
314 tSpiderNamespace *ns = NULL;
315 tSpiderValue *args[arg_count];
319 DEBUG_F("CALL (general) %s %i args\n", name, arg_count);
322 for( i = arg_count; i --; )
325 args[i] = Bytecode_int_GetSpiderValue(&val1, NULL);
326 Bytecode_int_DerefStackValue(&val1);
329 // Resolve namespace into pointer
330 if( op->Operation != BC_OP_CALLMETHOD ) {
331 const char *name_orig = name;
332 if( name[0] == BC_NS_SEPARATOR ) {
334 ns = Bytecode_int_ResolveNamespace(&Script->Variant->RootNamespace, name, &name);
337 // TODO: Support multiple default namespaces
338 ns = Bytecode_int_ResolveNamespace(DefaultNS, name, &name);
341 AST_RuntimeError(NULL, "Namespace '%s' not found in '%s'", name, name_orig);
346 // Call the function etc.
347 if( op->Operation == BC_OP_CALLFUNCTION )
349 rv = SpiderScript_ExecuteFunction(Script, ns, name, arg_count, args);
351 else if( op->Operation == BC_OP_CREATEOBJ )
353 rv = SpiderScript_CreateObject(Script, ns, name, arg_count, args);
355 else if( op->Operation == BC_OP_CALLMETHOD )
360 if(val1.Type == SS_DATATYPE_OBJECT)
362 else if(val1.Type == ET_REFERENCE && val1.Reference && val1.Reference->Type == SS_DATATYPE_OBJECT)
363 obj = val1.Reference->Object;
366 AST_RuntimeError(NULL, "OP_CALLMETHOD on non object");
369 rv = SpiderScript_ExecuteMethod(Script, obj, name, arg_count, args);
370 Bytecode_int_DerefStackValue(&val1);
374 AST_RuntimeError(NULL, "BUG - Unknown operation for CALL/CREATEOBJ (%i)", op->Operation);
378 AST_RuntimeError(NULL, "SpiderScript_ExecuteFunction returned ERRPTR");
382 for( i = arg_count; i --; )
383 SpiderScript_DereferenceValue(args[i]);
384 // Get and push return
385 Bytecode_int_SetSpiderValue(&val1, rv);
388 SpiderScript_DereferenceValue(rv);
393 int Bytecode_int_LocalBinOp_Integer(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
397 case BC_OP_ADD: Val1->Integer = Val1->Integer + Val2->Integer; break;
398 case BC_OP_SUBTRACT: Val1->Integer = Val1->Integer - Val2->Integer; break;
399 case BC_OP_MULTIPLY: Val1->Integer = Val1->Integer * Val2->Integer; break;
400 case BC_OP_DIVIDE: Val1->Integer = Val1->Integer / Val2->Integer; break;
402 case BC_OP_EQUALS: Val1->Integer = (Val1->Integer == Val2->Integer); break;
403 case BC_OP_NOTEQUALS: Val1->Integer = (Val1->Integer != Val2->Integer); break;
404 case BC_OP_LESSTHAN: Val1->Integer = (Val1->Integer < Val2->Integer); break;
405 case BC_OP_LESSTHANOREQUAL: Val1->Integer = (Val1->Integer <= Val2->Integer); break;
406 case BC_OP_GREATERTHAN: Val1->Integer = (Val1->Integer > Val2->Integer); break;
407 case BC_OP_GREATERTHANOREQUAL: Val1->Integer = (Val1->Integer >= Val2->Integer); break;
409 case BC_OP_BITAND: Val1->Integer = Val1->Integer & Val2->Integer; break;
410 case BC_OP_BITOR: Val1->Integer = Val1->Integer | Val2->Integer; break;
411 case BC_OP_BITXOR: Val1->Integer = Val1->Integer ^ Val2->Integer; break;
412 case BC_OP_MODULO: Val1->Integer = Val1->Integer % Val2->Integer; break;
413 default: AST_RuntimeError(NULL, "Invalid operation on datatype %i", Val1->Type); return -1;
418 int Bytecode_int_LocalBinOp_Real(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
422 case BC_OP_ADD: Val1->Real = Val1->Real + Val2->Real; return 0;
423 case BC_OP_SUBTRACT: Val1->Real = Val1->Real - Val2->Real; return 0;
424 case BC_OP_MULTIPLY: Val1->Real = Val1->Real * Val2->Real; return 0;
425 case BC_OP_DIVIDE: Val1->Real = Val1->Real / Val2->Real; return 0;
427 case BC_OP_EQUALS: Val1->Integer = (Val1->Real == Val2->Real); break;
428 case BC_OP_NOTEQUALS: Val1->Integer = (Val1->Real != Val2->Real); break;
429 case BC_OP_LESSTHAN: Val1->Integer = (Val1->Real < Val2->Real); break;
430 case BC_OP_LESSTHANOREQUAL: Val1->Integer = (Val1->Real <= Val2->Real); break;
431 case BC_OP_GREATERTHAN: Val1->Integer = (Val1->Real > Val2->Real); break;
432 case BC_OP_GREATERTHANOREQUAL: Val1->Integer = (Val1->Real >= Val2->Real); break;
434 default: AST_RuntimeError(NULL, "Invalid operation on datatype %i", Val1->Type); return -1;
436 Val1->Type = SS_DATATYPE_INTEGER; // Becomes logical
440 #define STATE_HDR() DEBUG_F("%p %2i ", op, Stack->EntryCount)
443 * \brief Execute a bytecode function with a stack
445 int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, tBC_Stack *Stack, int ArgCount)
449 tBC_StackEnt val1, val2;
450 int local_var_count = Fcn->BCFcn->MaxVariableCount;
451 tBC_StackEnt local_vars[local_var_count]; // Includes arguments
452 tSpiderValue tmpVal1, tmpVal2; // temp storage
453 tSpiderValue *pval1, *pval2, *ret_val;
454 tSpiderNamespace *default_namespace = &Script->Variant->RootNamespace;
456 // Initialise local vars
457 for( i = 0; i < local_var_count; i ++ )
458 local_vars[i].Type = ET_NULL;
461 if( ArgCount > Fcn->ArgumentCount ) return -1;
462 DEBUG_F("Fcn->ArgumentCount = %i\n", Fcn->ArgumentCount);
463 // - Handle optional arguments
464 for( i = Fcn->ArgumentCount; i > ArgCount; )
467 local_vars[i].Integer = 0;
468 local_vars[i].Type = Fcn->Arguments[i].Type;
472 GET_STACKVAL(local_vars[i]);
473 // TODO: Type checks / enforcing
477 memset(&val1, 0, sizeof(val1));
478 val1.Type = ET_FUNCTION_START;
482 op = Fcn->BCFcn->Operations;
485 const char *opstr = "";
486 tBC_Op *nextop = op->Next, *jmp_target;
488 switch(op->Operation)
497 // NOTE: Evil, all jumps are off by -1, so fix that
498 jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
499 DEBUG_F("JUMP #%i %p\n", OP_INDX(op), jmp_target);
504 jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
505 DEBUG_F("JUMPIF #%i %p\n", OP_INDX(op), jmp_target);
507 if( Bytecode_int_IsStackEntTrue(&val1) )
510 case BC_OP_JUMPIFNOT:
512 jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
513 DEBUG_F("JUMPIFNOT #%i %p\n", OP_INDX(op), jmp_target);
515 if( !Bytecode_int_IsStackEntTrue(&val1) )
520 case BC_OP_DEFINEVAR: {
522 type = OP_INDX(op) & 0xFFFF;
523 slot = OP_INDX(op) >> 16;
524 if(slot < 0 || slot >= local_var_count) {
525 DEBUG_F("ERROR: slot %i out of range (max %i)\n", slot, local_var_count);
529 DEBUG_F("DEFVAR %i of type %i\n", slot, type);
530 if( local_vars[slot].Type != ET_NULL ) {
531 Bytecode_int_DerefStackValue( &local_vars[slot] );
532 local_vars[slot].Type = ET_NULL;
534 memset(&local_vars[slot], 0, sizeof(local_vars[0]));
535 local_vars[slot].Type = type;
538 // Enter/Leave context
540 case BC_OP_ENTERCONTEXT:
542 DEBUG_F("ENTERCONTEXT\n");
544 case BC_OP_LEAVECONTEXT:
546 DEBUG_F("LEAVECONTEXT\n");
550 case BC_OP_LOADVAR: {
551 int slot = OP_INDX(op);
553 DEBUG_F("LOADVAR %i ", slot);
554 if( slot < 0 || slot >= local_var_count ) {
555 AST_RuntimeError(NULL, "Loading from invalid slot %i", slot);
558 DEBUG_F("("); PRINT_STACKVAL(local_vars[slot]); DEBUG_F(")\n");
559 PUT_STACKVAL(local_vars[slot]);
560 Bytecode_int_RefStackValue( &local_vars[slot] );
562 case BC_OP_SAVEVAR: {
563 int slot = OP_INDX(op);
565 DEBUG_F("SAVEVAR %i = ", slot);
566 if( slot < 0 || slot >= local_var_count ) {
567 AST_RuntimeError(NULL, "Loading from invalid slot %i", slot);
570 DEBUG_F("[Deref "); PRINT_STACKVAL(local_vars[slot]); DEBUG_F("] ");
571 Bytecode_int_DerefStackValue( &local_vars[slot] );
572 GET_STACKVAL(local_vars[slot]);
573 PRINT_STACKVAL(local_vars[slot]);
580 DEBUG_F("LOADINT 0x%lx\n", op->Content.Integer);
581 val1.Type = SS_DATATYPE_INTEGER;
582 val1.Integer = op->Content.Integer;
587 DEBUG_F("LOADREAL %lf\n", op->Content.Real);
588 val1.Type = SS_DATATYPE_REAL;
589 val1.Real = op->Content.Real;
594 DEBUG_F("LOADSTR %i \"%s\"\n", OP_INDX(op), OP_STRING(op));
595 val1.Type = SS_DATATYPE_STRING;
596 val1.Reference = SpiderScript_CreateString(OP_INDX(op), OP_STRING(op));
602 val2.Type = OP_INDX(op);
603 DEBUG_F("CAST to %i\n", val2.Type);
605 if(val1.Type == val2.Type) {
609 switch(val2.Type * 100 + val1.Type )
611 case SS_DATATYPE_INTEGER*100 + SS_DATATYPE_REAL:
612 val2.Integer = val1.Real;
615 case SS_DATATYPE_REAL*100 + SS_DATATYPE_INTEGER:
616 val2.Real = val1.Integer;
620 pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
621 pval2 = SpiderScript_CastValueTo(val2.Type, pval1);
622 if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
623 Bytecode_int_SetSpiderValue(&val2, pval2);
624 SpiderScript_DereferenceValue(pval2);
632 DEBUG_F("DUPSTACK ");
634 PRINT_STACKVAL(val1);
638 Bytecode_int_RefStackValue(&val1);
641 // Discard the top item from the stack
644 DEBUG_F("DELSTACK\n");
651 DEBUG_F("LOGICNOT\n");
654 val2.Type = SS_DATATYPE_INTEGER;
655 val2.Integer = !Bytecode_int_IsStackEntTrue(&val1);
656 Bytecode_int_StackPush(Stack, &val2);
657 Bytecode_int_DerefStackValue(&val1);
661 if(!ast_op) ast_op = NODETYPE_BWNOT, opstr = "BITNOT";
663 if(!ast_op) ast_op = NODETYPE_NEGATE, opstr = "NEG";
666 DEBUG_F("%s\n", opstr);
669 pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
670 Bytecode_int_DerefStackValue(&val1);
672 ret_val = AST_ExecuteNode_UniOp(Script, NULL, ast_op, pval1);
673 if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
674 Bytecode_int_SetSpiderValue(&val1, ret_val);
675 if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
676 Bytecode_int_StackPush(Stack, &val1);
682 if(!ast_op) ast_op = NODETYPE_LOGICALAND, opstr = "LOGICAND";
684 if(!ast_op) ast_op = NODETYPE_LOGICALOR, opstr = "LOGICOR";
686 if(!ast_op) ast_op = NODETYPE_LOGICALXOR, opstr = "LOGICXOR";
689 DEBUG_F("%s\n", opstr);
694 switch(op->Operation)
697 i = Bytecode_int_IsStackEntTrue(&val1) && Bytecode_int_IsStackEntTrue(&val2);
700 i = Bytecode_int_IsStackEntTrue(&val1) || Bytecode_int_IsStackEntTrue(&val2);
703 i = Bytecode_int_IsStackEntTrue(&val1) ^ Bytecode_int_IsStackEntTrue(&val2);
706 Bytecode_int_DerefStackValue(&val1);
707 Bytecode_int_DerefStackValue(&val2);
709 val1.Type = SS_DATATYPE_INTEGER;
711 Bytecode_int_StackPush(Stack, &val1);
715 if(!ast_op) ast_op = NODETYPE_BWAND, opstr = "BITAND";
717 if(!ast_op) ast_op = NODETYPE_BWOR, opstr = "BITOR";
719 if(!ast_op) ast_op = NODETYPE_BWXOR, opstr = "BITXOR";
721 case BC_OP_BITSHIFTLEFT:
722 if(!ast_op) ast_op = NODETYPE_BITSHIFTLEFT, opstr = "BITSHIFTLEFT";
723 case BC_OP_BITSHIFTRIGHT:
724 if(!ast_op) ast_op = NODETYPE_BITSHIFTRIGHT, opstr = "BITSHIFTRIGHT";
725 case BC_OP_BITROTATELEFT:
726 if(!ast_op) ast_op = NODETYPE_BITROTATELEFT, opstr = "BITROTATELEFT";
729 if(!ast_op) ast_op = NODETYPE_ADD, opstr = "ADD";
731 if(!ast_op) ast_op = NODETYPE_SUBTRACT, opstr = "SUBTRACT";
733 if(!ast_op) ast_op = NODETYPE_MULTIPLY, opstr = "MULTIPLY";
735 if(!ast_op) ast_op = NODETYPE_DIVIDE, opstr = "DIVIDE";
737 if(!ast_op) ast_op = NODETYPE_MODULO, opstr = "MODULO";
740 if(!ast_op) ast_op = NODETYPE_EQUALS, opstr = "EQUALS";
741 case BC_OP_NOTEQUALS:
742 if(!ast_op) ast_op = NODETYPE_NOTEQUALS, opstr = "NOTEQUALS";
744 if(!ast_op) ast_op = NODETYPE_LESSTHAN, opstr = "LESSTHAN";
745 case BC_OP_LESSTHANOREQUAL:
746 if(!ast_op) ast_op = NODETYPE_LESSTHANEQUAL, opstr = "LESSTHANOREQUAL";
747 case BC_OP_GREATERTHAN:
748 if(!ast_op) ast_op = NODETYPE_GREATERTHAN, opstr = "GREATERTHAN";
749 case BC_OP_GREATERTHANOREQUAL:
750 if(!ast_op) ast_op = NODETYPE_GREATERTHANEQUAL, opstr = "GREATERTHANOREQUAL";
753 DEBUG_F("BINOP %i %s (bc %i)\n", ast_op, opstr, op->Operation);
755 GET_STACKVAL(val2); // Right
756 GET_STACKVAL(val1); // Left
758 DEBUG_F(" ("); PRINT_STACKVAL(val1); DEBUG_F(")");
759 DEBUG_F(" ("); PRINT_STACKVAL(val2); DEBUG_F(")\n");
761 // Perform integer operations locally
762 if( val1.Type == SS_DATATYPE_INTEGER && val2.Type == SS_DATATYPE_INTEGER )
764 if( Bytecode_int_LocalBinOp_Integer(op->Operation, &val1, &val2) ) {
772 if(val1. Type == SS_DATATYPE_REAL && val2.Type == SS_DATATYPE_REAL )
774 if( Bytecode_int_LocalBinOp_Real(op->Operation, &val1, &val2) ) {
782 pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
783 pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
784 Bytecode_int_DerefStackValue(&val1);
785 Bytecode_int_DerefStackValue(&val2);
787 // Hand to AST execution code
788 ret_val = AST_ExecuteNode_BinOp(Script, NULL, ast_op, pval1, pval2);
789 if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
790 if(pval2 != &tmpVal2) SpiderScript_DereferenceValue(pval2);
792 if(ret_val == ERRPTR) {
793 AST_RuntimeError(NULL, "_BinOp returned ERRPTR");
797 Bytecode_int_SetSpiderValue(&val1, ret_val);
798 if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
803 case BC_OP_CREATEOBJ:
804 case BC_OP_CALLFUNCTION:
805 case BC_OP_CALLMETHOD:
808 if( op->Operation == BC_OP_CALLFUNCTION )
810 tScript_Function *fcn = NULL;
811 const char *name = OP_STRING(op);
812 int arg_count = OP_INDX(op);
813 DEBUG_F("CALL (local) %s %i args\n", name, arg_count);
814 // Check current script functions (for fast call)
815 for(fcn = Script->Functions; fcn; fcn = fcn->Next)
817 if(strcmp(name, fcn->Name) == 0) {
821 if(fcn && fcn->BCFcn)
823 DEBUG_F(" - Fast call\n");
824 Bytecode_int_ExecuteFunction(Script, fcn, Stack, arg_count);
830 if( Bytecode_int_CallExternFunction( Script, Stack, default_namespace, op ) ) {
846 AST_RuntimeError(NULL, "Unknown operation %i\n", op->Operation);
854 // - Delete local vars
855 for( i = 0; i < local_var_count; i ++ )
857 if( local_vars[i].Type != ET_NULL )
859 Bytecode_int_DerefStackValue(&local_vars[i]);
864 if( Stack->Entries[Stack->EntryCount - 1].Type == ET_FUNCTION_START )
865 Stack->EntryCount --;
870 while( Stack->EntryCount && Stack->Entries[ --Stack->EntryCount ].Type != ET_FUNCTION_START )
872 Bytecode_int_DerefStackValue( &Stack->Entries[Stack->EntryCount] );
876 DEBUG_F("Rolled back %i entried\n", n_rolled);