tmp = malloc(sizeof(tSpiderValue));
tmp->ReferenceCount = 1;
} else {
+ // Stops a stack value from having free() called on it
tmp->ReferenceCount = 2;
}
break;
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;
}
}
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;
const char *name = OP_STRING(op);
int arg_count = OP_INDX(op);
int i, ret = 0;
- tSpiderNamespace *ns = NULL;
tSpiderValue *args[arg_count];
tSpiderValue *rv;
- tBC_StackEnt val1;
+ tBC_StackEnt val1;
+ const char *namespaces[] = {NULL}; // TODO: Default/imported namespaces
DEBUG_F("CALL (general) %s %i args\n", name, arg_count);
Bytecode_int_DerefStackValue(&val1);
}
- // Resolve namespace into pointer
- if( op->Operation != BC_OP_CALLMETHOD ) {
- const char *name_orig = name;
- 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(DefaultNS, name, &name);
- }
- if( !ns ) {
- AST_RuntimeError(NULL, "Namespace '%s' not found in '%s'", name, name_orig);
- return -1;
- }
- }
-
// Call the function etc.
if( op->Operation == BC_OP_CALLFUNCTION )
{
- rv = SpiderScript_ExecuteFunction(Script, ns, name, arg_count, args);
+ rv = SpiderScript_ExecuteFunction(Script, name, namespaces, arg_count, args, &op->CacheEnt);
}
else if( op->Operation == BC_OP_CREATEOBJ )
{
- rv = SpiderScript_CreateObject(Script, ns, name, arg_count, args);
+ rv = SpiderScript_CreateObject(Script, name, namespaces, arg_count, args);
}
else if( op->Operation == BC_OP_CALLMETHOD )
{
PUT_STACKVAL(val1);
// Deref return
SpiderScript_DereferenceValue(rv);
-
- return ret;
+
+ #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)
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 %i", Val1->Type); return -1;
+ default: AST_RuntimeError(NULL, "Invalid operation on datatype Integer"); return -1;
}
return 0;
}
{
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_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 %i", Val1->Type); return -1;
+ default: AST_RuntimeError(NULL, "Invalid operation on datatype Real"); return -1;
}
Val1->Type = SS_DATATYPE_INTEGER; // Becomes logical
return 0;
// 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;
AST_RuntimeError(NULL, "Loading from invalid slot %i", slot);
return -1;
}
+ // 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:
case BC_OP_LOADINT:
STATE_HDR();
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();
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:
{
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
n_rolled ++;
}
PUT_STACKVAL(val1);
- DEBUG_F("Rolled back %i entried\n", n_rolled);
+ DEBUG_F("Rolled back %i entries\n", n_rolled);
}