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
SpiderScript - Moved header to directory, ready to remove from tree
[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
780bee5
..
9de7281
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;
@@
-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:
@@
-105,6
+105,7
@@
tSpiderValue *Bytecode_int_GetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *tmp)
tmp = malloc(sizeof(tSpiderValue));
tmp->ReferenceCount = 1;
} else {
+ // Stops a stack value from having free() called on it
tmp->ReferenceCount = 2;
}
break;
@@
-222,7
+223,10
@@
void Bytecode_int_PrintStackValue(tBC_StackEnt *Ent)
printf("Obj %p", Ent->Object);
break;
default:
- printf("*%p", Ent->Reference);
+ if( Ent->Reference )
+ printf("*%p (%i refs)", Ent->Reference, Ent->Reference->ReferenceCount);
+ else
+ printf("NULL");
break;
}
}
@@
-272,11
+276,14
@@
tSpiderValue *Bytecode_ExecuteFunction(tSpiderScript *Script, tScript_Function *
return NULL;
}
free(stack);
+
ret = Bytecode_int_GetSpiderValue(&val, &tmpsval);
// Ensure it's a heap value
if(ret == &tmpsval) {
ret = malloc(sizeof(tSpiderValue));
memcpy(ret, &tmpsval, sizeof(tSpiderValue));
+ // Set to 2 in _GetSpiderValue, so stack doesn't have free() called
+ ret->ReferenceCount = 1;
}
return ret;
@@
-303,6
+310,135
@@
tSpiderNamespace *Bytecode_int_ResolveNamespace(tSpiderNamespace *Start, const c
return ns;
}
+/**
+ * \brief Call an external function (may recurse into Bytecode_ExecuteFunction, but may not)
+ */
+int Bytecode_int_CallExternFunction(tSpiderScript *Script, tBC_Stack *Stack, tSpiderNamespace *DefaultNS, tBC_Op *op )
+{
+ const char *name = OP_STRING(op);
+ int arg_count = OP_INDX(op);
+ int i, ret = 0;
+ tSpiderValue *args[arg_count];
+ tSpiderValue *rv;
+ tBC_StackEnt val1;
+ const char *namespaces[] = {NULL}; // TODO: Default/imported namespaces
+
+ DEBUG_F("CALL (general) %s %i args\n", name, arg_count);
+
+ // Read arguments
+ for( i = arg_count; i --; )
+ {
+ GET_STACKVAL(val1);
+ args[i] = Bytecode_int_GetSpiderValue(&val1, NULL);
+ Bytecode_int_DerefStackValue(&val1);
+ }
+
+ // Call the function etc.
+ if( op->Operation == BC_OP_CALLFUNCTION )
+ {
+ rv = SpiderScript_ExecuteFunction(Script, name, namespaces, arg_count, args, &op->CacheEnt);
+ }
+ else if( op->Operation == BC_OP_CREATEOBJ )
+ {
+ rv = SpiderScript_CreateObject(Script, name, namespaces, 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 && val1.Reference->Type == SS_DATATYPE_OBJECT)
+ obj = val1.Reference->Object;
+ else {
+ // Error
+ AST_RuntimeError(NULL, "OP_CALLMETHOD on non object");
+ return -1;
+ }
+ 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");
+ return -1;
+ }
+ // Clean up args
+ for( i = arg_count; i --; )
+ SpiderScript_DereferenceValue(args[i]);
+ // Get and push return
+ Bytecode_int_SetSpiderValue(&val1, rv);
+ PUT_STACKVAL(val1);
+ // Deref return
+ SpiderScript_DereferenceValue(rv);
+
+ #if 0
+ if(!rv) {
+ printf("%s returned NULL\n", name);
+ }
+ if( rv && rv != ERRPTR && rv->ReferenceCount != 1 ) {
+ printf("Return value from %s reference count fail (%i)\n",
+ name, rv->ReferenceCount);
+ }
+ #endif
+
+ return 0;
+}
+
+int Bytecode_int_LocalBinOp_Integer(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
+{
+ switch(Operation)
+ {
+ case BC_OP_ADD: Val1->Integer = Val1->Integer + Val2->Integer; break;
+ case BC_OP_SUBTRACT: Val1->Integer = Val1->Integer - Val2->Integer; break;
+ case BC_OP_MULTIPLY: Val1->Integer = Val1->Integer * Val2->Integer; break;
+ case BC_OP_DIVIDE: Val1->Integer = Val1->Integer / Val2->Integer; break;
+
+ case BC_OP_EQUALS: Val1->Integer = (Val1->Integer == Val2->Integer); break;
+ case BC_OP_NOTEQUALS: Val1->Integer = (Val1->Integer != Val2->Integer); break;
+ case BC_OP_LESSTHAN: Val1->Integer = (Val1->Integer < Val2->Integer); break;
+ case BC_OP_LESSTHANOREQUAL: Val1->Integer = (Val1->Integer <= Val2->Integer); break;
+ case BC_OP_GREATERTHAN: Val1->Integer = (Val1->Integer > Val2->Integer); break;
+ case BC_OP_GREATERTHANOREQUAL: Val1->Integer = (Val1->Integer >= Val2->Integer); break;
+
+ case BC_OP_BITAND: Val1->Integer = Val1->Integer & Val2->Integer; break;
+ case BC_OP_BITOR: Val1->Integer = Val1->Integer | Val2->Integer; break;
+ case BC_OP_BITXOR: Val1->Integer = Val1->Integer ^ Val2->Integer; break;
+ case BC_OP_MODULO: Val1->Integer = Val1->Integer % Val2->Integer; break;
+ default: AST_RuntimeError(NULL, "Invalid operation on datatype Integer"); return -1;
+ }
+ return 0;
+}
+
+int Bytecode_int_LocalBinOp_Real(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
+{
+ switch(Operation)
+ {
+ // Real = Real OP Real
+ case BC_OP_ADD: Val1->Real = Val1->Real + Val2->Real; return 0;
+ case BC_OP_SUBTRACT: Val1->Real = Val1->Real - Val2->Real; return 0;
+ case BC_OP_MULTIPLY: Val1->Real = Val1->Real * Val2->Real; return 0;
+ case BC_OP_DIVIDE: Val1->Real = Val1->Real / Val2->Real; return 0;
+
+ // Bool/Integer = Real OP Real
+ case BC_OP_EQUALS: Val1->Integer = (Val1->Real == Val2->Real); break;
+ case BC_OP_NOTEQUALS: Val1->Integer = (Val1->Real != Val2->Real); break;
+ case BC_OP_LESSTHAN: Val1->Integer = (Val1->Real < Val2->Real); break;
+ case BC_OP_LESSTHANOREQUAL: Val1->Integer = (Val1->Real <= Val2->Real); break;
+ case BC_OP_GREATERTHAN: Val1->Integer = (Val1->Real > Val2->Real); break;
+ case BC_OP_GREATERTHANOREQUAL: Val1->Integer = (Val1->Real >= Val2->Real); break;
+
+ default: AST_RuntimeError(NULL, "Invalid operation on datatype Real"); return -1;
+ }
+ Val1->Type = SS_DATATYPE_INTEGER; // Becomes logical
+ return 0;
+}
+
#define STATE_HDR() DEBUG_F("%p %2i ", op, Stack->EntryCount)
/**
@@
-326,6
+462,7
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
// Pop off arguments
if( ArgCount > Fcn->ArgumentCount ) return -1;
DEBUG_F("Fcn->ArgumentCount = %i\n", Fcn->ArgumentCount);
+ // - Handle optional arguments
for( i = Fcn->ArgumentCount; i > ArgCount; )
{
i --;
@@
-359,7
+496,6
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
// Jumps
case BC_OP_JUMP:
STATE_HDR();
- // NOTE: Evil, all jumps are off by -1, so fix that
jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
DEBUG_F("JUMP #%i %p\n", OP_INDX(op), jmp_target);
nextop = jmp_target;
@@
-412,29
+548,119
@@
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)]);
+ // Remove whatever was in there before
+ DEBUG_F("[Deref "); PRINT_STACKVAL(local_vars[slot]); DEBUG_F("] ");
+ Bytecode_int_DerefStackValue( &local_vars[slot] );
+ // Place new in
+ GET_STACKVAL(local_vars[slot]);
+ PRINT_STACKVAL(local_vars[slot]);
DEBUG_F("\n");
+ } break;
+
+ // Array index (get or set)
+ case BC_OP_INDEX:
+ case BC_OP_SETINDEX:
+ STATE_HDR();
+ GET_STACKVAL(val1); // Index
+ // TODO: Check that index is an integer
+ if( val1.Type != SS_DATATYPE_INTEGER ) {
+ nextop = NULL;
+ break;
+ }
+
+ // Get array as raw spider value
+ GET_STACKVAL(val2); // Array
+ pval1 = Bytecode_int_GetSpiderValue(&val2, &tmpVal1);
+ Bytecode_int_DerefStackValue(&val2);
+
+ if( op->Operation == BC_OP_SETINDEX ) {
+ GET_STACKVAL(val2);
+ pval2 = Bytecode_int_GetSpiderValue(&val2, NULL);
+ Bytecode_int_DerefStackValue(&val2);
+
+ DEBUG_F("SETINDEX %i ", val1.Integer); PRINT_STACKVAL(val2); DEBUG_F("\n");
+
+ ret_val = AST_ExecuteNode_Index(Script, NULL, pval1, val1.Integer, pval2);
+ if(ret_val == ERRPTR) { nextop = NULL; break; }
+ SpiderScript_DereferenceValue(pval2);
+ }
+ else {
+ DEBUG_F("INDEX %i ", val1.Integer);
+ ret_val = AST_ExecuteNode_Index(Script, NULL, pval1, val1.Integer, ERRPTR);
+ if(ret_val == ERRPTR) { nextop = NULL; break; }
+
+ Bytecode_int_SetSpiderValue(&val1, ret_val);
+ SpiderScript_DereferenceValue(ret_val);
+ PUT_STACKVAL(val1);
+
+ DEBUG_F("[Got "); PRINT_STACKVAL(val1); DEBUG_F("]\n");
+
+ }
+ // Dereference the array (or object, ...)
+ if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
+ break;
+
+ // Object element (get or set)
+ case BC_OP_ELEMENT:
+ case BC_OP_SETELEMENT:
+ STATE_HDR();
+
+ GET_STACKVAL(val1);
+ // - Integers/Reals can't have elements :)
+ if( val1.Type != ET_REFERENCE ) {
+ nextop = NULL;
+ break;
+ }
+
+ pval1 = Bytecode_int_GetSpiderValue(&val1, NULL);
+ Bytecode_int_DerefStackValue(&val1);
+
+ if( op->Operation == BC_OP_SETELEMENT ) {
+ GET_STACKVAL(val2);
+ pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
+ Bytecode_int_DerefStackValue(&val2);
+
+ DEBUG_F("SETELEMENT %s ", OP_STRING(op)); PRINT_STACKVAL(val2); DEBUG_F("\n");
+
+ ret_val = AST_ExecuteNode_Element(Script, NULL, pval1, OP_STRING(op), pval2);
+ if(ret_val == ERRPTR) { nextop = NULL; break; }
+
+ if(pval2 != &tmpVal2) SpiderScript_DereferenceValue(pval2);
+ }
+ else {
+ DEBUG_F("ELEMENT %s ", OP_STRING(op));
+
+ ret_val = AST_ExecuteNode_Element(Script, NULL, pval1, OP_STRING(op), ERRPTR);
+ if(ret_val == ERRPTR) { nextop = NULL; break; }
+
+ Bytecode_int_SetSpiderValue(&val2, ret_val);
+ SpiderScript_DereferenceValue(ret_val);
+ PUT_STACKVAL(val2);
+
+ DEBUG_F("[Got "); PRINT_STACKVAL(val2); DEBUG_F("]\n");
+ }
+
+ SpiderScript_DereferenceValue(pval1);
break;
// Constants:
@@
-459,6
+685,13
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
val1.Reference = SpiderScript_CreateString(OP_INDX(op), OP_STRING(op));
PUT_STACKVAL(val1);
break;
+ case BC_OP_LOADNULL:
+ STATE_HDR();
+ DEBUG_F("LOADNULL\n");
+ val1.Type = ET_REFERENCE;
+ val1.Reference = NULL;
+ PUT_STACKVAL(val1);
+ break;
case BC_OP_CAST:
STATE_HDR();
@@
-469,25
+702,26
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
PUT_STACKVAL(val1);
break;
}
- switch(val2.Type * 100 + val1.Type )
- {
- case SS_DATATYPE_INTEGER*100 + SS_DATATYPE_REAL:
+ if( val2.Type == SS_DATATYPE_INTEGER && val1.Type == SS_DATATYPE_REAL ) {
val2.Integer = val1.Real;
- PUT_STACKVAL(val2);
- break;
- case SS_DATATYPE_REAL*100 + SS_DATATYPE_INTEGER:
+ }
+ else if( val2.Type == SS_DATATYPE_REAL && val2.Type == SS_DATATYPE_INTEGER ) {
val2.Real = val1.Integer;
- PUT_STACKVAL(val2);
- break;
- default: {
+ }
+ else {
pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
pval2 = SpiderScript_CastValueTo(val2.Type, pval1);
- if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
+
Bytecode_int_SetSpiderValue(&val2, pval2);
SpiderScript_DereferenceValue(pval2);
- PUT_STACKVAL(val2);
- } break;
+
+ if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
+ Bytecode_int_DerefStackValue(&val1);
+// printf("CAST (%x->%x) - Original %i references remaining\n",
+// pval1->Type, OP_INDX(op),
+// pval1->ReferenceCount);
}
+ PUT_STACKVAL(val2);
break;
case BC_OP_DUPSTACK:
@@
-519,11
+753,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
+835,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:
@@
-613,36
+852,36
@@
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;\
+ DEBUG_F(" ("); PRINT_STACKVAL(val1); DEBUG_F(")");
+ DEBUG_F(" ("); PRINT_STACKVAL(val2); DEBUG_F(")\n");
+
+ // Perform integer operations locally
+ if( val1.Type == SS_DATATYPE_INTEGER && val2.Type == SS_DATATYPE_INTEGER )
+ {
+ if( Bytecode_int_LocalBinOp_Integer(op->Operation, &val1, &val2) ) {
+ nextop = NULL;
+ break;
+ }
+ PUT_STACKVAL(val1);
+ break;
}
- PERFORM_NUM_OP(SS_DATATYPE_INTEGER, Integer);
- PERFORM_NUM_OP(SS_DATATYPE_REAL, Real);
+ if(val1. Type == SS_DATATYPE_REAL && val2.Type == SS_DATATYPE_REAL )
+ {
+ if( Bytecode_int_LocalBinOp_Real(op->Operation, &val1, &val2) ) {
+ nextop = NULL;
+ break;
+ }
+ PUT_STACKVAL(val1);
+ break;
+ }
pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
Bytecode_int_DerefStackValue(&val1);
Bytecode_int_DerefStackValue(&val2);
+ // Hand to AST execution code
ret_val = AST_ExecuteNode_BinOp(Script, NULL, ast_op, pval1, pval2);
if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1);
if(pval2 != &tmpVal2) SpiderScript_DereferenceValue(pval2);
@@
-660,16
+899,15
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
// Functions etc
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);
-
+ case BC_OP_CALLMETHOD:
STATE_HDR();
- DEBUG_F("CALL FUNCTION %s %i args\n", name, arg_count);
if( op->Operation == BC_OP_CALLFUNCTION )
{
+ tScript_Function *fcn = NULL;
+ const char *name = OP_STRING(op);
+ int arg_count = OP_INDX(op);
+ DEBUG_F("CALL (local) %s %i args\n", name, arg_count);
// Check current script functions (for fast call)
for(fcn = Script->Functions; fcn; fcn = fcn->Next)
{
@@
-684,82
+922,17
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
break;
}
}
-
+
// Slower call
- {
- tSpiderNamespace *ns = NULL;
- tSpiderValue *args[arg_count];
- tSpiderValue *rv;
- // Read arguments
- for( i = arg_count; i --; )
- {
- GET_STACKVAL(val1);
- args[i] = Bytecode_int_GetSpiderValue(&val1, NULL);
- Bytecode_int_DerefStackValue(&val1);
- }
-
- // 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);
- }
- }
-
- // 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;
- break;
- }
- // Clean up args
- for( i = arg_count; i --; )
- SpiderScript_DereferenceValue(args[i]);
- // Get and push return
- Bytecode_int_SetSpiderValue(&val1, rv);
- PUT_STACKVAL(val1);
- // Deref return
- SpiderScript_DereferenceValue(rv);
+ if( Bytecode_int_CallExternFunction( Script, Stack, default_namespace, op ) ) {
+ nextop = NULL;
+ break;
}
-
}
break;
+ break;
case BC_OP_RETURN:
STATE_HDR();
+
DEBUG_F("RETURN\n");
nextop = NULL;
break;
@@
-780,22
+953,29
@@
int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
{
if( local_vars[i].Type != ET_NULL )
{
+ DEBUG_F("Var %i - ", i);
+ PRINT_STACKVAL(local_vars[i]);
Bytecode_int_DerefStackValue(&local_vars[i]);
+ DEBUG_F("\n");
}
+ else
+ DEBUG_F("Var %i - empty\n", i);
}
// - Restore stack
-// printf("TODO: Roll back stack\n");
if( Stack->Entries[Stack->EntryCount - 1].Type == ET_FUNCTION_START )
Stack->EntryCount --;
else
{
+ int n_rolled = 1;
GET_STACKVAL(val1);
while( Stack->EntryCount && Stack->Entries[ --Stack->EntryCount ].Type != ET_FUNCTION_START )
{
Bytecode_int_DerefStackValue( &Stack->Entries[Stack->EntryCount] );
+ n_rolled ++;
}
PUT_STACKVAL(val1);
+ DEBUG_F("Rolled back %i entries\n", n_rolled);
}
UCC
git Repository :: git.ucc.asn.au