Thanks Alberto!
What about making sq_getfreevariable also work for native closures?
Extending the current implementation would result in...
Code:
const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
{
SQObjectPtr &self=stack_get(v,idx);
const SQChar *name = NULL;
switch(type(self))
{
case OT_CLOSURE:{
SQClosure *clo = _closure(self);
SQFunctionProto *fp = clo->_function;
if(((SQUnsignedInteger)fp->_noutervalues) > nval) {
v->Push(*(_outer(clo->_outervalues[nval])->_valptr));
SQOuterVar &ov = fp->_outervalues[nval];
name = _stringval(ov._name);
}
}
break;
case OT_NATIVECLOSURE:
if(_nativeclosure(self)->_outervalues.size()>nval){
v->Push(_nativeclosure(self)->_outervalues[nval]);
_nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
}
break;
default:
break;
}
return name;
}
But here is the problem that error checking for native closures can't be done. Better would be to...
Code:
SQRESULT sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval, const SQChar** name)
{
SQObjectPtr &self=stack_get(v,idx);
switch(type(self))
{
case OT_CLOSURE:{
SQClosure *clo = _closure(self);
SQFunctionProto *fp = clo->_function;
if(((SQUnsignedInteger)fp->_noutervalues) > nval) {
v->Push(*(_outer(clo->_outervalues[nval])->_valptr));
SQOuterVar &ov = fp->_outervalues[nval];
if (name) {
*name = _stringval(ov._name);
}
}
else return sq_throwerror(v,_SC("invalid free var index"));
}
break;
case OT_NATIVECLOSURE:
if(_nativeclosure(self)->_outervalues.size()>nval){
v->Push(_nativeclosure(self)->_outervalues[nval]);
if (name) {
*name = NULL;
}
}
else return sq_throwerror(v,_SC("invalid free var index"));
break;
default:
return sq_aux_invalidtype(v,type(self));
}
return SQ_OK;
}
But changing the function signature of sq_getfreevariable will break any existing code that uses it currently. :/
However, if Squirrel 3.x is meant to break compatibility if needed, I think we should go with the second version. :)