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) ) {
276 ret = Bytecode_int_GetSpiderValue(&val, &tmpsval);
277 // Ensure it's a heap value
278 if(ret == &tmpsval) {
279 ret = malloc(sizeof(tSpiderValue));
280 memcpy(ret, &tmpsval, sizeof(tSpiderValue));
286 tSpiderNamespace *Bytecode_int_ResolveNamespace(tSpiderNamespace *Start, const char *Name, const char **FinalName)
289 tSpiderNamespace *ns = Start;
290 while( (pos = strchr(Name, BC_NS_SEPARATOR)) )
292 int len = pos - Name;
293 for( ns = ns->FirstChild; ns; ns = ns->Next )
295 if(memcmp(ns->Name, Name, len) == 0 && ns->Name[len] == 0)
303 if(FinalName) *FinalName = Name;
308 * \brief Call an external function (may recurse into Bytecode_ExecuteFunction, but may not)
310 int Bytecode_int_CallExternFunction(tSpiderScript *Script, tBC_Stack *Stack, tSpiderNamespace *DefaultNS, tBC_Op *op )
312 const char *name = OP_STRING(op);
313 int arg_count = OP_INDX(op);
315 tSpiderValue *args[arg_count];
318 const char *namespaces[] = {NULL}; // TODO: Default/imported namespaces
320 DEBUG_F("CALL (general) %s %i args\n", name, arg_count);
323 for( i = arg_count; i --; )
326 args[i] = Bytecode_int_GetSpiderValue(&val1, NULL);
327 Bytecode_int_DerefStackValue(&val1);
330 // Call the function etc.
331 if( op->Operation == BC_OP_CALLFUNCTION )
333 rv = SpiderScript_ExecuteFunction(Script, name, namespaces, arg_count, args, &op->CacheEnt);
335 else if( op->Operation == BC_OP_CREATEOBJ )
337 rv = SpiderScript_CreateObject(Script, name, namespaces, arg_count, args);
339 else if( op->Operation == BC_OP_CALLMETHOD )
344 if(val1.Type == SS_DATATYPE_OBJECT)
346 else if(val1.Type == ET_REFERENCE && val1.Reference && val1.Reference->Type == SS_DATATYPE_OBJECT)
347 obj = val1.Reference->Object;
350 AST_RuntimeError(NULL, "OP_CALLMETHOD on non object");
353 rv = SpiderScript_ExecuteMethod(Script, obj, name, arg_count, args);
354 Bytecode_int_DerefStackValue(&val1);
358 AST_RuntimeError(NULL, "BUG - Unknown operation for CALL/CREATEOBJ (%i)", op->Operation);
362 AST_RuntimeError(NULL, "SpiderScript_ExecuteFunction returned ERRPTR");
366 for( i = arg_count; i --; )
367 SpiderScript_DereferenceValue(args[i]);
368 // Get and push return
369 Bytecode_int_SetSpiderValue(&val1, rv);
372 SpiderScript_DereferenceValue(rv);
377 int Bytecode_int_LocalBinOp_Integer(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
381 case BC_OP_ADD: Val1->Integer = Val1->Integer + Val2->Integer; break;
382 case BC_OP_SUBTRACT: Val1->Integer = Val1->Integer - Val2->Integer; break;
383 case BC_OP_MULTIPLY: Val1->Integer = Val1->Integer * Val2->Integer; break;
384 case BC_OP_DIVIDE: Val1->Integer = Val1->Integer / Val2->Integer; break;
386 case BC_OP_EQUALS: Val1->Integer = (Val1->Integer == Val2->Integer); break;
387 case BC_OP_NOTEQUALS: Val1->Integer = (Val1->Integer != Val2->Integer); break;
388 case BC_OP_LESSTHAN: Val1->Integer = (Val1->Integer < Val2->Integer); break;
389 case BC_OP_LESSTHANOREQUAL: Val1->Integer = (Val1->Integer <= Val2->Integer); break;
390 case BC_OP_GREATERTHAN: Val1->Integer = (Val1->Integer > Val2->Integer); break;
391 case BC_OP_GREATERTHANOREQUAL: Val1->Integer = (Val1->Integer >= Val2->Integer); break;
393 case BC_OP_BITAND: Val1->Integer = Val1->Integer & Val2->Integer; break;
394 case BC_OP_BITOR: Val1->Integer = Val1->Integer | Val2->Integer; break;
395 case BC_OP_BITXOR: Val1->Integer = Val1->Integer ^ Val2->Integer; break;
396 case BC_OP_MODULO: Val1->Integer = Val1->Integer % Val2->Integer; break;
397 default: AST_RuntimeError(NULL, "Invalid operation on datatype Integer"); return -1;
402 int Bytecode_int_LocalBinOp_Real(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
406 case BC_OP_ADD: Val1->Real = Val1->Real + Val2->Real; return 0;
407 case BC_OP_SUBTRACT: Val1->Real = Val1->Real - Val2->Real; return 0;
408 case BC_OP_MULTIPLY: Val1->Real = Val1->Real * Val2->Real; return 0;
409 case BC_OP_DIVIDE: Val1->Real = Val1->Real / Val2->Real; return 0;
411 case BC_OP_EQUALS: Val1->Integer = (Val1->Real == Val2->Real); break;
412 case BC_OP_NOTEQUALS: Val1->Integer = (Val1->Real != Val2->Real); break;
413 case BC_OP_LESSTHAN: Val1->Integer = (Val1->Real < Val2->Real); break;
414 case BC_OP_LESSTHANOREQUAL: Val1->Integer = (Val1->Real <= Val2->Real); break;
415 case BC_OP_GREATERTHAN: Val1->Integer = (Val1->Real > Val2->Real); break;
416 case BC_OP_GREATERTHANOREQUAL: Val1->Integer = (Val1->Real >= Val2->Real); break;
418 default: AST_RuntimeError(NULL, "Invalid operation on datatype Real"); return -1;
420 Val1->Type = SS_DATATYPE_INTEGER; // Becomes logical
424 #define STATE_HDR() DEBUG_F("%p %2i ", op, Stack->EntryCount)
427 * \brief Execute a bytecode function with a stack
429 int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, tBC_Stack *Stack, int ArgCount)
433 tBC_StackEnt val1, val2;
434 int local_var_count = Fcn->BCFcn->MaxVariableCount;
435 tBC_StackEnt local_vars[local_var_count]; // Includes arguments
436 tSpiderValue tmpVal1, tmpVal2; // temp storage
437 tSpiderValue *pval1, *pval2, *ret_val;
438 tSpiderNamespace *default_namespace = &Script->Variant->RootNamespace;
440 // Initialise local vars
441 for( i = 0; i < local_var_count; i ++ )
442 local_vars[i].Type = ET_NULL;
445 if( ArgCount > Fcn->ArgumentCount ) return -1;
446 DEBUG_F("Fcn->ArgumentCount = %i\n", Fcn->ArgumentCount);
447 // - Handle optional arguments
448 for( i = Fcn->ArgumentCount; i > ArgCount; )
451 local_vars[i].Integer = 0;
452 local_vars[i].Type = Fcn->Arguments[i].Type;
456 GET_STACKVAL(local_vars[i]);
457 // TODO: Type checks / enforcing
461 memset(&val1, 0, sizeof(val1));
462 val1.Type = ET_FUNCTION_START;
466 op = Fcn->BCFcn->Operations;
469 const char *opstr = "";
470 tBC_Op *nextop = op->Next, *jmp_target;
472 switch(op->Operation)
481 jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
482 DEBUG_F("JUMP #%i %p\n", OP_INDX(op), jmp_target);
487 jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
488 DEBUG_F("JUMPIF #%i %p\n", OP_INDX(op), jmp_target);
490 if( Bytecode_int_IsStackEntTrue(&val1) )
493 case BC_OP_JUMPIFNOT:
495 jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
496 DEBUG_F("JUMPIFNOT #%i %p\n", OP_INDX(op), jmp_target);
498 if( !Bytecode_int_IsStackEntTrue(&val1) )
503 case BC_OP_DEFINEVAR: {
505 type = OP_INDX(op) & 0xFFFF;
506 slot = OP_INDX(op) >> 16;
507 if(slot < 0 || slot >= local_var_count) {
508 DEBUG_F("ERROR: slot %i out of range (max %i)\n", slot, local_var_count);
512 DEBUG_F("DEFVAR %i of type %i\n", slot, type);
513 if( local_vars[slot].Type != ET_NULL ) {
514 Bytecode_int_DerefStackValue( &local_vars[slot] );
515 local_vars[slot].Type = ET_NULL;
517 memset(&local_vars[slot], 0, sizeof(local_vars[0]));
518 local_vars[slot].Type = type;
521 // Enter/Leave context
523 case BC_OP_ENTERCONTEXT:
525 DEBUG_F("ENTERCONTEXT\n");
527 case BC_OP_LEAVECONTEXT:
529 DEBUG_F("LEAVECONTEXT\n");
533 case BC_OP_LOADVAR: {
534 int slot = OP_INDX(op);
536 DEBUG_F("LOADVAR %i ", slot);
537 if( slot < 0 || slot >= local_var_count ) {
538 AST_RuntimeError(NULL, "Loading from invalid slot %i", slot);
541 DEBUG_F("("); PRINT_STACKVAL(local_vars[slot]); DEBUG_F(")\n");
542 PUT_STACKVAL(local_vars[slot]);
543 Bytecode_int_RefStackValue( &local_vars[slot] );
545 case BC_OP_SAVEVAR: {
546 int slot = OP_INDX(op);
548 DEBUG_F("SAVEVAR %i = ", slot);
549 if( slot < 0 || slot >= local_var_count ) {
550 AST_RuntimeError(NULL, "Loading from invalid slot %i", slot);
553 DEBUG_F("[Deref "); PRINT_STACKVAL(local_vars[slot]); DEBUG_F("] ");
554 Bytecode_int_DerefStackValue( &local_vars[slot] );
555 GET_STACKVAL(local_vars[slot]);
556 PRINT_STACKVAL(local_vars[slot]);
563 DEBUG_F("LOADINT 0x%lx\n", op->Content.Integer);
564 val1.Type = SS_DATATYPE_INTEGER;
565 val1.Integer = op->Content.Integer;
570 DEBUG_F("LOADREAL %lf\n", op->Content.Real);
571 val1.Type = SS_DATATYPE_REAL;
572 val1.Real = op->Content.Real;
577 DEBUG_F("LOADSTR %i \"%s\"\n", OP_INDX(op), OP_STRING(op));
578 val1.Type = SS_DATATYPE_STRING;
579 val1.Reference = SpiderScript_CreateString(OP_INDX(op), OP_STRING(op));
584 DEBUG_F("LOADNULL\n");
585 val1.Type = ET_REFERENCE;
586 val1.Reference = NULL;
592 val2.Type = OP_INDX(op);
593 DEBUG_F("CAST to %i\n", val2.Type);
595 if(val1.Type == val2.Type) {
599 switch(val2.Type * 100 + val1.Type )
601 case SS_DATATYPE_INTEGER*100 + SS_DATATYPE_REAL:
602 val2.Integer = val1.Real;
605 case SS_DATATYPE_REAL*100 + SS_DATATYPE_INTEGER:
606 val2.Real = val1.Integer;
610 pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
611 pval2 = SpiderScript_CastValueTo(val2.Type, pval1);
612 if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
613 Bytecode_int_SetSpiderValue(&val2, pval2);
614 SpiderScript_DereferenceValue(pval2);
622 DEBUG_F("DUPSTACK ");
624 PRINT_STACKVAL(val1);
628 Bytecode_int_RefStackValue(&val1);
631 // Discard the top item from the stack
634 DEBUG_F("DELSTACK\n");
641 DEBUG_F("LOGICNOT\n");
644 val2.Type = SS_DATATYPE_INTEGER;
645 val2.Integer = !Bytecode_int_IsStackEntTrue(&val1);
646 Bytecode_int_StackPush(Stack, &val2);
647 Bytecode_int_DerefStackValue(&val1);
651 if(!ast_op) ast_op = NODETYPE_BWNOT, opstr = "BITNOT";
653 if(!ast_op) ast_op = NODETYPE_NEGATE, opstr = "NEG";
656 DEBUG_F("%s\n", opstr);
659 pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
660 Bytecode_int_DerefStackValue(&val1);
662 ret_val = AST_ExecuteNode_UniOp(Script, NULL, ast_op, pval1);
663 if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
664 Bytecode_int_SetSpiderValue(&val1, ret_val);
665 if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
666 Bytecode_int_StackPush(Stack, &val1);
672 if(!ast_op) ast_op = NODETYPE_LOGICALAND, opstr = "LOGICAND";
674 if(!ast_op) ast_op = NODETYPE_LOGICALOR, opstr = "LOGICOR";
676 if(!ast_op) ast_op = NODETYPE_LOGICALXOR, opstr = "LOGICXOR";
679 DEBUG_F("%s\n", opstr);
684 switch(op->Operation)
687 i = Bytecode_int_IsStackEntTrue(&val1) && Bytecode_int_IsStackEntTrue(&val2);
690 i = Bytecode_int_IsStackEntTrue(&val1) || Bytecode_int_IsStackEntTrue(&val2);
693 i = Bytecode_int_IsStackEntTrue(&val1) ^ Bytecode_int_IsStackEntTrue(&val2);
696 Bytecode_int_DerefStackValue(&val1);
697 Bytecode_int_DerefStackValue(&val2);
699 val1.Type = SS_DATATYPE_INTEGER;
701 Bytecode_int_StackPush(Stack, &val1);
705 if(!ast_op) ast_op = NODETYPE_BWAND, opstr = "BITAND";
707 if(!ast_op) ast_op = NODETYPE_BWOR, opstr = "BITOR";
709 if(!ast_op) ast_op = NODETYPE_BWXOR, opstr = "BITXOR";
711 case BC_OP_BITSHIFTLEFT:
712 if(!ast_op) ast_op = NODETYPE_BITSHIFTLEFT, opstr = "BITSHIFTLEFT";
713 case BC_OP_BITSHIFTRIGHT:
714 if(!ast_op) ast_op = NODETYPE_BITSHIFTRIGHT, opstr = "BITSHIFTRIGHT";
715 case BC_OP_BITROTATELEFT:
716 if(!ast_op) ast_op = NODETYPE_BITROTATELEFT, opstr = "BITROTATELEFT";
719 if(!ast_op) ast_op = NODETYPE_ADD, opstr = "ADD";
721 if(!ast_op) ast_op = NODETYPE_SUBTRACT, opstr = "SUBTRACT";
723 if(!ast_op) ast_op = NODETYPE_MULTIPLY, opstr = "MULTIPLY";
725 if(!ast_op) ast_op = NODETYPE_DIVIDE, opstr = "DIVIDE";
727 if(!ast_op) ast_op = NODETYPE_MODULO, opstr = "MODULO";
730 if(!ast_op) ast_op = NODETYPE_EQUALS, opstr = "EQUALS";
731 case BC_OP_NOTEQUALS:
732 if(!ast_op) ast_op = NODETYPE_NOTEQUALS, opstr = "NOTEQUALS";
734 if(!ast_op) ast_op = NODETYPE_LESSTHAN, opstr = "LESSTHAN";
735 case BC_OP_LESSTHANOREQUAL:
736 if(!ast_op) ast_op = NODETYPE_LESSTHANEQUAL, opstr = "LESSTHANOREQUAL";
737 case BC_OP_GREATERTHAN:
738 if(!ast_op) ast_op = NODETYPE_GREATERTHAN, opstr = "GREATERTHAN";
739 case BC_OP_GREATERTHANOREQUAL:
740 if(!ast_op) ast_op = NODETYPE_GREATERTHANEQUAL, opstr = "GREATERTHANOREQUAL";
743 DEBUG_F("BINOP %i %s (bc %i)\n", ast_op, opstr, op->Operation);
745 GET_STACKVAL(val2); // Right
746 GET_STACKVAL(val1); // Left
748 DEBUG_F(" ("); PRINT_STACKVAL(val1); DEBUG_F(")");
749 DEBUG_F(" ("); PRINT_STACKVAL(val2); DEBUG_F(")\n");
751 // Perform integer operations locally
752 if( val1.Type == SS_DATATYPE_INTEGER && val2.Type == SS_DATATYPE_INTEGER )
754 if( Bytecode_int_LocalBinOp_Integer(op->Operation, &val1, &val2) ) {
762 if(val1. Type == SS_DATATYPE_REAL && val2.Type == SS_DATATYPE_REAL )
764 if( Bytecode_int_LocalBinOp_Real(op->Operation, &val1, &val2) ) {
772 pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
773 pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
774 Bytecode_int_DerefStackValue(&val1);
775 Bytecode_int_DerefStackValue(&val2);
777 // Hand to AST execution code
778 ret_val = AST_ExecuteNode_BinOp(Script, NULL, ast_op, pval1, pval2);
779 if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
780 if(pval2 != &tmpVal2) SpiderScript_DereferenceValue(pval2);
782 if(ret_val == ERRPTR) {
783 AST_RuntimeError(NULL, "_BinOp returned ERRPTR");
787 Bytecode_int_SetSpiderValue(&val1, ret_val);
788 if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
793 case BC_OP_CREATEOBJ:
794 case BC_OP_CALLFUNCTION:
795 case BC_OP_CALLMETHOD:
798 if( op->Operation == BC_OP_CALLFUNCTION )
800 tScript_Function *fcn = NULL;
801 const char *name = OP_STRING(op);
802 int arg_count = OP_INDX(op);
803 DEBUG_F("CALL (local) %s %i args\n", name, arg_count);
804 // Check current script functions (for fast call)
805 for(fcn = Script->Functions; fcn; fcn = fcn->Next)
807 if(strcmp(name, fcn->Name) == 0) {
811 if(fcn && fcn->BCFcn)
813 DEBUG_F(" - Fast call\n");
814 Bytecode_int_ExecuteFunction(Script, fcn, Stack, arg_count);
820 if( Bytecode_int_CallExternFunction( Script, Stack, default_namespace, op ) ) {
836 AST_RuntimeError(NULL, "Unknown operation %i\n", op->Operation);
844 // - Delete local vars
845 for( i = 0; i < local_var_count; i ++ )
847 if( local_vars[i].Type != ET_NULL )
849 Bytecode_int_DerefStackValue(&local_vars[i]);
854 if( Stack->Entries[Stack->EntryCount - 1].Type == ET_FUNCTION_START )
855 Stack->EntryCount --;
860 while( Stack->EntryCount && Stack->Entries[ --Stack->EntryCount ].Type != ET_FUNCTION_START )
862 Bytecode_int_DerefStackValue( &Stack->Entries[Stack->EntryCount] );
866 DEBUG_F("Rolled back %i entries\n", n_rolled);