From 5c859fb5aa148116615e9830160905a8ad3facaf Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Fri, 26 Oct 2018 21:51:48 +0300 Subject: [PATCH] Implement new Squirrel API functions to get a native closure pointer and an alternative function to pop the closure before pushing the free variable. --- external/Squirrel/sqapi.cpp | 32 ++++++++++++++++++++++++++------ include/squirrel.h | 2 ++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/external/Squirrel/sqapi.cpp b/external/Squirrel/sqapi.cpp index 7af6a1e5..5b5daa61 100644 --- a/external/Squirrel/sqapi.cpp +++ b/external/Squirrel/sqapi.cpp @@ -424,6 +424,17 @@ SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) } return sq_throwerror(v,_SC("the object is not a nativeclosure")); } +SQRESULT sq_getnativeclosurepointer(HSQUIRRELVM v,SQInteger idx,SQFUNCTION *f) +{ + SQObject o = stack_get(v, idx); + if(sq_type(o) == OT_NATIVECLOSURE) + { + SQNativeClosure *c = _nativeclosure(o); + if (f) *f = c->_function; + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a native closure")); +} SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) { @@ -1321,9 +1332,10 @@ SQRESULT sq_getcallee(HSQUIRRELVM v) return sq_throwerror(v,_SC("no closure in the calls stack")); } -const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +static const SQChar *sq_getfreevariable_(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval, bool pop=false) { - SQObjectPtr &self=stack_get(v,idx); + SQObjectPtr self=stack_get(v,idx); + if (pop) v->Pop(); const SQChar *name = NULL; switch(sq_type(self)) { @@ -1335,21 +1347,29 @@ const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger n SQOuterVar &ov = fp->_outervalues[nval]; name = _stringval(ov._name); } - } - break; + } break; case OT_NATIVECLOSURE:{ SQNativeClosure *clo = _nativeclosure(self); if(clo->_noutervalues > nval) { v->Push(clo->_outervalues[nval]); name = _SC("@NATIVE"); } - } - break; + } break; default: break; //shutup compiler } return name; } +const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + return sq_getfreevariable_(v,idx,nval,false); +} + +const SQChar *sq_getonefreevariable(HSQUIRRELVM v,SQUnsignedInteger nval) +{ + return sq_getfreevariable_(v,-1,nval,true); +} + SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) { SQObjectPtr &self=stack_get(v,idx); diff --git a/include/squirrel.h b/include/squirrel.h index 1e0944fc..419f7875 100644 --- a/include/squirrel.h +++ b/include/squirrel.h @@ -281,6 +281,7 @@ SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctio SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQInteger *nparams,SQInteger *nfreevars); SQUIRREL_API SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name); +SQUIRREL_API SQRESULT sq_getnativeclosurepointer(HSQUIRRELVM v,SQInteger idx,SQFUNCTION *f); SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize); @@ -330,6 +331,7 @@ SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror); SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx); SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v); SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API const SQChar *sq_getonefreevariable(HSQUIRRELVM v,SQUnsignedInteger nval); SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err); SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v); SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);