Update to Squirrel 3.0.6
[supertux.git] / external / squirrel / squirrel / sqapi.cpp
old mode 100755 (executable)
new mode 100644 (file)
index a629909..5b1d872
@@ -31,11 +31,6 @@ bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPt
        if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\\r
 }              \r
 \r
-SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)\r
-{\r
-       v->_lasterror = e;\r
-       return SQ_ERROR;\r
-}\r
 \r
 SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)\r
 {\r
@@ -98,11 +93,20 @@ void sq_seterrorhandler(HSQUIRRELVM v)
        }\r
 }\r
 \r
+void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook)\r
+{\r
+       v->_debughook_native = hook;\r
+       v->_debughook_closure.Null();\r
+       v->_debughook = hook?true:false;\r
+}\r
+\r
 void sq_setdebughook(HSQUIRRELVM v)\r
 {\r
        SQObject o = stack_get(v,-1);\r
        if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {\r
-               v->_debughook = o;\r
+               v->_debughook_closure = o;\r
+               v->_debughook_native = NULL;\r
+               v->_debughook = !sq_isnull(o);\r
                v->Pop();\r
        }\r
 }\r
@@ -114,14 +118,23 @@ void sq_close(HSQUIRRELVM v)
        sq_delete(ss, SQSharedState);\r
 }\r
 \r
+SQInteger sq_getversion()\r
+{\r
+       return SQUIRREL_VERSION_NUMBER;\r
+}\r
+\r
 SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)\r
 {\r
        SQObjectPtr o;\r
+#ifndef NO_COMPILER\r
        if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {\r
                v->Push(SQClosure::Create(_ss(v), _funcproto(o)));\r
                return SQ_OK;\r
        }\r
        return SQ_ERROR;\r
+#else\r
+       return sq_throwerror(v,_SC("this is a no compiler build"));\r
+#endif\r
 }\r
 \r
 void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)\r
@@ -144,18 +157,29 @@ void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
 #endif\r
 }\r
 \r
+SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po)\r
+{\r
+       if(!ISREFCOUNTED(type(*po))) return 0;\r
+#ifdef NO_GARBAGE_COLLECTOR\r
+   return po->_unVal.pRefCounted->_uiRef; \r
+#else\r
+   return _ss(v)->_refs_table.GetRefCount(*po); \r
+#endif \r
+}\r
+\r
 SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)\r
 {\r
        if(!ISREFCOUNTED(type(*po))) return SQTrue;\r
 #ifdef NO_GARBAGE_COLLECTOR\r
+       bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse;\r
        __Release(po->_type,po->_unVal);\r
-       return SQFalse; //the ret val doesn't work(and cannot be fixed)\r
+       return ret; //the ret val doesn't work(and cannot be fixed)\r
 #else\r
        return _ss(v)->_refs_table.Release(*po);\r
 #endif\r
 }\r
 \r
-const SQChar *sq_objtostring(HSQOBJECT *o) \r
+const SQChar *sq_objtostring(const HSQOBJECT *o) \r
 {\r
        if(sq_type(*o) == OT_STRING) {\r
                return _stringval(*o);\r
@@ -163,7 +187,7 @@ const SQChar *sq_objtostring(HSQOBJECT *o)
        return NULL;\r
 }\r
 \r
-SQInteger sq_objtointeger(HSQOBJECT *o) \r
+SQInteger sq_objtointeger(const HSQOBJECT *o) \r
 {\r
        if(sq_isnumeric(*o)) {\r
                return tointeger(*o);\r
@@ -171,7 +195,7 @@ SQInteger sq_objtointeger(HSQOBJECT *o)
        return 0;\r
 }\r
 \r
-SQFloat sq_objtofloat(HSQOBJECT *o) \r
+SQFloat sq_objtofloat(const HSQOBJECT *o) \r
 {\r
        if(sq_isnumeric(*o)) {\r
                return tofloat(*o);\r
@@ -179,7 +203,7 @@ SQFloat sq_objtofloat(HSQOBJECT *o)
        return 0;\r
 }\r
 \r
-SQBool sq_objtobool(HSQOBJECT *o) \r
+SQBool sq_objtobool(const HSQOBJECT *o) \r
 {\r
        if(sq_isbool(*o)) {\r
                return _integer(*o);\r
@@ -187,16 +211,24 @@ SQBool sq_objtobool(HSQOBJECT *o)
        return SQFalse;\r
 }\r
 \r
+SQUserPointer sq_objtouserpointer(const HSQOBJECT *o)\r
+{\r
+       if(sq_isuserpointer(*o)) {\r
+               return _userpointer(*o);\r
+       }\r
+       return 0;\r
+}\r
+\r
 void sq_pushnull(HSQUIRRELVM v)\r
 {\r
-       v->Push(_null_);\r
+       v->PushNull();\r
 }\r
 \r
 void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)\r
 {\r
        if(s)\r
                v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));\r
-       else v->Push(_null_);\r
+       else v->PushNull();\r
 }\r
 \r
 void sq_pushinteger(HSQUIRRELVM v,SQInteger n)\r
@@ -223,7 +255,7 @@ SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
 {\r
        SQUserData *ud = SQUserData::Create(_ss(v), size);\r
        v->Push(ud);\r
-       return ud->_val;\r
+       return (SQUserPointer)sq_aligning(ud + 1);\r
 }\r
 \r
 void sq_newtable(HSQUIRRELVM v)\r
@@ -231,6 +263,11 @@ void sq_newtable(HSQUIRRELVM v)
        v->Push(SQTable::Create(_ss(v), 0));    \r
 }\r
 \r
+void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity)\r
+{\r
+       v->Push(SQTable::Create(_ss(v), initialcapacity));      \r
+}\r
+\r
 void sq_newarray(HSQUIRRELVM v,SQInteger size)\r
 {\r
        v->Push(SQArray::Create(_ss(v), size)); \r
@@ -266,7 +303,7 @@ SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
        SQObjectPtr *arr;\r
        _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);\r
        _array(*arr)->Append(v->GetUp(-1));\r
-       v->Pop(1);\r
+       v->Pop();\r
        return SQ_OK;\r
 }\r
 \r
@@ -334,13 +371,12 @@ SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos)
        return ret;\r
 }\r
 \r
-\r
 void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)\r
 {\r
-       SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);\r
+       SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars);\r
        nc->_nparamscheck = 0;\r
        for(SQUnsignedInteger i = 0; i < nfreevars; i++) {\r
-               nc->_outervalues.push_back(v->Top());\r
+               nc->_outervalues[i] = v->Top();\r
                v->Pop();\r
        }\r
        v->Push(SQObjectPtr(nc));       \r
@@ -349,11 +385,18 @@ void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
 SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)\r
 {\r
        SQObject o = stack_get(v, idx);\r
-       if(sq_isclosure(o)) {\r
+       if(type(o) == OT_CLOSURE) {\r
                SQClosure *c = _closure(o);\r
-               SQFunctionProto *proto = _funcproto(c->_function);\r
+               SQFunctionProto *proto = c->_function;\r
                *nparams = (SQUnsignedInteger)proto->_nparameters;\r
-        *nfreevars = (SQUnsignedInteger)c->_outervalues.size();\r
+               *nfreevars = (SQUnsignedInteger)proto->_noutervalues;\r
+               return SQ_OK;\r
+       }\r
+       else if(type(o) == OT_NATIVECLOSURE)\r
+       {\r
+               SQNativeClosure *c = _nativeclosure(o);\r
+               *nparams = (SQUnsignedInteger)c->_nparamscheck;\r
+               *nfreevars = c->_noutervalues;\r
                return SQ_OK;\r
        }\r
        return sq_throwerror(v,_SC("the object is not a closure"));\r
@@ -403,16 +446,24 @@ SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
                !sq_isclass(env) &&\r
                !sq_isinstance(env))\r
                return sq_throwerror(v,_SC("invalid environment"));\r
-       SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));\r
+       SQWeakRef *w = _refcounted(env)->GetWeakRef(type(env));\r
        SQObjectPtr ret;\r
        if(sq_isclosure(o)) {\r
                SQClosure *c = _closure(o)->Clone();\r
+               __ObjRelease(c->_env);\r
                c->_env = w;\r
+               __ObjAddRef(c->_env);\r
+               if(_closure(o)->_base) {\r
+                       c->_base = _closure(o)->_base;\r
+                       __ObjAddRef(c->_base);\r
+               }\r
                ret = c;\r
        }\r
        else { //then must be a native closure\r
                SQNativeClosure *c = _nativeclosure(o)->Clone();\r
+               __ObjRelease(c->_env);\r
                c->_env = w;\r
+               __ObjAddRef(c->_env);\r
                ret = c;\r
        }\r
        v->Pop();\r
@@ -420,6 +471,22 @@ SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
        return SQ_OK;\r
 }\r
 \r
+SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &o = stack_get(v,idx);\r
+       if(!sq_isnativeclosure(o) &&\r
+               !sq_isclosure(o))\r
+               return sq_throwerror(v,_SC("the target is not a closure"));\r
+       if(sq_isnativeclosure(o))\r
+       {\r
+               v->Push(_nativeclosure(o)->_name);\r
+       }\r
+       else { //closure\r
+               v->Push(_closure(o)->_function->_name);\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
 SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObject &o=stack_get(v,idx);\r
@@ -491,19 +558,32 @@ SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
        return type(stack_get(v, idx));\r
 }\r
 \r
+SQRESULT sq_typeof(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &o = stack_get(v, idx);\r
+       SQObjectPtr res;\r
+       if(!v->TypeOf(o,res)) {\r
+               return SQ_ERROR;\r
+       }\r
+       v->Push(res);\r
+       return SQ_OK;\r
+}\r
 \r
-void sq_tostring(HSQUIRRELVM v,SQInteger idx)\r
+SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr &o = stack_get(v, idx);\r
        SQObjectPtr res;\r
-       v->ToString(o,res);\r
+       if(!v->ToString(o,res)) {\r
+               return SQ_ERROR;\r
+       }\r
        v->Push(res);\r
+       return SQ_OK;\r
 }\r
 \r
 void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)\r
 {\r
        SQObjectPtr &o = stack_get(v, idx);\r
-       *b = v->IsFalse(o)?SQFalse:SQTrue;\r
+       *b = SQVM::IsFalse(o)?SQFalse:SQTrue;\r
 }\r
 \r
 SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)\r
@@ -555,10 +635,10 @@ SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
 SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr &o = stack_get(v,idx);\r
-       v->Push(_null_);\r
+       v->PushNull();\r
        if(!v->Clone(o, stack_get(v, -1))){\r
                v->Pop();\r
-               return sq_aux_invalidtype(v, type(o));\r
+               return SQ_ERROR;\r
        }\r
        return SQ_OK;\r
 }\r
@@ -579,6 +659,12 @@ SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
        }\r
 }\r
 \r
+SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx)\r
+{\r
+       SQObjectPtr &o = stack_get(v, idx);\r
+       return HashObj(o);\r
+}\r
+\r
 SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)\r
 {\r
        SQObjectPtr *o = NULL;\r
@@ -599,7 +685,7 @@ SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
        return SQ_OK;\r
 }\r
 \r
-SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)\r
+SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag)\r
 {\r
   switch(type(*o)) {\r
     case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;\r
@@ -722,27 +808,31 @@ SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
        if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
        SQObjectPtr res;\r
        if(!v->DeleteSlot(*self, key, res)){\r
+               v->Pop();\r
                return SQ_ERROR;\r
        }\r
        if(pushval)     v->GetUp(-1) = res;\r
-       else v->Pop(1);\r
+       else v->Pop();\r
        return SQ_OK;\r
 }\r
 \r
 SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr &self = stack_get(v, idx);\r
-       if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {\r
+       if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) {\r
                v->Pop(2);\r
                return SQ_OK;\r
        }\r
-       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;\r
+       return SQ_ERROR;\r
 }\r
 \r
 SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr &self = stack_get(v, idx);\r
-       if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));\r
+       if(type(v->GetUp(-2)) == OT_NULL) {\r
+               v->Pop(2);\r
+               return sq_throwerror(v, _SC("null key"));\r
+       }\r
        switch(type(self)) {\r
        case OT_TABLE:\r
                _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));\r
@@ -773,6 +863,26 @@ SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
        v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;\r
 }\r
 \r
+SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)\r
+{\r
+       SQObjectPtr &self = stack_get(v, idx);\r
+       if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes"));\r
+       if(type(v->GetUp(-3)) == OT_NULL) return sq_throwerror(v, _SC("null key"));\r
+       if(!v->NewSlotA(self,v->GetUp(-3),v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false))\r
+               return SQ_ERROR;\r
+       return SQ_OK; \r
+}\r
+\r
+SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)\r
+{\r
+       SQObjectPtr &self = stack_get(v, idx);\r
+       if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes"));\r
+       if(type(v->GetUp(-3)) == OT_NULL) return sq_throwerror(v, _SC("null key"));\r
+       if(!v->NewSlotA(self,v->GetUp(-3),v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true))\r
+               return SQ_ERROR;\r
+       return SQ_OK; \r
+}\r
+\r
 SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr &self = stack_get(v, idx);\r
@@ -811,9 +921,9 @@ SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
                _table(*self)->Remove(key);\r
        }\r
        if(pushval != 0)\r
-               if(pushval)     v->GetUp(-1) = t;\r
+               v->GetUp(-1) = t;\r
        else\r
-               v->Pop(1);\r
+               v->Pop();\r
        return SQ_OK;\r
 }\r
 \r
@@ -824,7 +934,7 @@ SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
        case OT_TABLE:\r
        case OT_USERDATA:\r
                if(!_delegable(self)->_delegate){\r
-                       v->Push(_null_);\r
+                       v->PushNull();\r
                        break;\r
                }\r
                v->Push(SQObjectPtr(_delegable(self)->_delegate));\r
@@ -838,10 +948,10 @@ SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
 SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr &self=stack_get(v,idx);\r
-       if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))\r
+       if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,DONT_FALL_BACK))\r
                return SQ_OK;\r
-       v->Pop(1);\r
-       return sq_throwerror(v,_SC("the index doesn't exist"));\r
+       v->Pop();\r
+       return SQ_ERROR;\r
 }\r
 \r
 SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)\r
@@ -860,15 +970,24 @@ SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
                if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))\r
                        return SQ_OK;\r
                break;\r
-       case OT_ARRAY:\r
-               if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))\r
-                       return SQ_OK;\r
+       case OT_ARRAY:{\r
+               SQObjectPtr& key = v->GetUp(-1);\r
+               if(sq_isnumeric(key)){\r
+                       if(_array(self)->Get(tointeger(key),v->GetUp(-1))) {\r
+                               return SQ_OK;\r
+                       }\r
+               }\r
+               else {\r
+                       v->Pop();\r
+                       return sq_throwerror(v,_SC("invalid index type for an array"));\r
+               }\r
+                                 }\r
                break;\r
        default:\r
-               v->Pop(1);\r
+               v->Pop();\r
                return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));\r
        }       \r
-       v->Pop(1);\r
+       v->Pop();\r
        return sq_throwerror(v,_SC("the index doesn't exist"));\r
 }\r
 \r
@@ -892,9 +1011,9 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
                if(type(ci._closure)!=OT_CLOSURE)\r
                        return NULL;\r
                SQClosure *c=_closure(ci._closure);\r
-               SQFunctionProto *func=_funcproto(c->_function);\r
+               SQFunctionProto *func=c->_function;\r
                if(func->_noutervalues > (SQInteger)idx) {\r
-                       v->Push(c->_outervalues[idx]);\r
+                       v->Push(*_outer(c->_outervalues[idx])->_valptr);\r
                        return _stringval(func->_outervalues[idx]._name);\r
                }\r
                idx -= func->_noutervalues;\r
@@ -916,12 +1035,20 @@ void sq_resetobject(HSQOBJECT *po)
 SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)\r
 {\r
        v->_lasterror=SQString::Create(_ss(v),err);\r
-       return -1;\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQRESULT sq_throwobject(HSQUIRRELVM v)\r
+{\r
+       v->_lasterror = v->GetUp(-1);\r
+       v->Pop();\r
+       return SQ_ERROR;\r
 }\r
 \r
+\r
 void sq_reseterror(HSQUIRRELVM v)\r
 {\r
-       v->_lasterror = _null_;\r
+       v->_lasterror.Null();\r
 }\r
 \r
 void sq_getlasterror(HSQUIRRELVM v)\r
@@ -929,18 +1056,22 @@ void sq_getlasterror(HSQUIRRELVM v)
        v->Push(v->_lasterror);\r
 }\r
 \r
-void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)\r
+SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize)\r
 {\r
        if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {\r
+               if(v->_nmetamethodscall) {\r
+                       return sq_throwerror(v,_SC("cannot resize stack while in  a metamethod"));\r
+               }\r
                v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));\r
        }\r
+       return SQ_OK;\r
 }\r
 \r
 SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)\r
 {\r
        if(type(v->GetUp(-1))==OT_GENERATOR){\r
-               v->Push(_null_); //retval\r
-               if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))\r
+               v->PushNull(); //retval\r
+               if(!v->Execute(v->GetUp(-2),0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))\r
                {v->Raise_Error(v->_lasterror); return SQ_ERROR;}\r
                if(!retval)\r
                        v->Pop();\r
@@ -953,6 +1084,7 @@ SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
 {\r
        SQObjectPtr res;\r
        if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){\r
+\r
                if(!v->_suspended) {\r
                        v->Pop(params);//pop closure and args\r
                }\r
@@ -980,14 +1112,16 @@ SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseer
        SQObjectPtr ret;\r
        if(!v->_suspended)\r
                return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));\r
+       SQInteger target = v->_suspended_target;\r
        if(wakeupret) {\r
-               v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval\r
+               if(target != -1) {\r
+                       v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval\r
+               }\r
                v->Pop();\r
-       } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;\r
-       if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM))\r
+       } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); }\r
+       SQObjectPtr dummy;\r
+       if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) {\r
                return SQ_ERROR;\r
-       if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {\r
-               while (v->_top > 1) v->_stack[--v->_top] = _null_;\r
        }\r
        if(retval)\r
                v->Push(ret);\r
@@ -1017,6 +1151,8 @@ SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
        SQObjectPtr *o = NULL;\r
        _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);\r
        unsigned short tag = SQ_BYTECODE_STREAM_TAG;\r
+       if(_closure(*o)->_function->_noutervalues) \r
+               return sq_throwerror(v,_SC("a closure with free valiables bound it cannot be serialized"));\r
        if(w(up,&tag,2) != 2)\r
                return sq_throwerror(v,_SC("io error"));\r
        if(!_closure(*o)->Save(v,up,w))\r
@@ -1044,6 +1180,16 @@ SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
        return _ss(v)->GetScratchPad(minsize);\r
 }\r
 \r
+SQRESULT sq_resurrectunreachable(HSQUIRRELVM v)\r
+{\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       _ss(v)->ResurrectUnreachable(v);\r
+       return SQ_OK;\r
+#else\r
+       return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build"));\r
+#endif\r
+}\r
+\r
 SQInteger sq_collectgarbage(HSQUIRRELVM v)\r
 {\r
 #ifndef NO_GARBAGE_COLLECTOR\r
@@ -1053,17 +1199,41 @@ SQInteger sq_collectgarbage(HSQUIRRELVM v)
 #endif\r
 }\r
 \r
+SQRESULT sq_getcallee(HSQUIRRELVM v)\r
+{\r
+       if(v->_callsstacksize > 1)\r
+       {\r
+               v->Push(v->_callsstack[v->_callsstacksize - 2]._closure);\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("no closure in the calls stack"));\r
+}\r
+\r
 const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)\r
 {\r
-       SQObjectPtr &self = stack_get(v,idx);\r
+       SQObjectPtr &self=stack_get(v,idx);\r
        const SQChar *name = NULL;\r
-       if(type(self) == OT_CLOSURE) {\r
-               if(_closure(self)->_outervalues.size()>nval) {\r
-                       v->Push(_closure(self)->_outervalues[nval]);\r
-                       SQFunctionProto *fp = _funcproto(_closure(self)->_function);\r
+       switch(type(self))\r
+       {\r
+       case OT_CLOSURE:{\r
+               SQClosure *clo = _closure(self);\r
+               SQFunctionProto *fp = clo->_function;\r
+               if(((SQUnsignedInteger)fp->_noutervalues) > nval) {\r
+                       v->Push(*(_outer(clo->_outervalues[nval])->_valptr));\r
                        SQOuterVar &ov = fp->_outervalues[nval];\r
                        name = _stringval(ov._name);\r
                }\r
+                                       }\r
+               break;\r
+       case OT_NATIVECLOSURE:{\r
+               SQNativeClosure *clo = _nativeclosure(self);\r
+               if(clo->_noutervalues > nval) {\r
+                       v->Push(clo->_outervalues[nval]);\r
+                       name = _SC("@NATIVE");\r
+               }\r
+                                                 }\r
+               break;\r
+       default: break; //shutup compiler\r
        }\r
        return name;\r
 }\r
@@ -1073,22 +1243,24 @@ SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
        SQObjectPtr &self=stack_get(v,idx);\r
        switch(type(self))\r
        {\r
-       case OT_CLOSURE:\r
-               if(_closure(self)->_outervalues.size()>nval){\r
-                       _closure(self)->_outervalues[nval]=stack_get(v,-1);\r
+       case OT_CLOSURE:{\r
+               SQFunctionProto *fp = _closure(self)->_function;\r
+               if(((SQUnsignedInteger)fp->_noutervalues) > nval){\r
+                       *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1);\r
                }\r
                else return sq_throwerror(v,_SC("invalid free var index"));\r
+                                       }\r
                break;\r
        case OT_NATIVECLOSURE:\r
-               if(_nativeclosure(self)->_outervalues.size()>nval){\r
-                       _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);\r
+               if(_nativeclosure(self)->_noutervalues > nval){\r
+                       _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1);\r
                }\r
                else return sq_throwerror(v,_SC("invalid free var index"));\r
                break;\r
        default:\r
                return sq_aux_invalidtype(v,type(self));\r
        }\r
-       v->Pop(1);\r
+       v->Pop();\r
        return SQ_OK;\r
 }\r
 \r
@@ -1134,6 +1306,77 @@ SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
        return sq_throwerror(v,_SC("wrong index"));\r
 }\r
 \r
+SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
+       SQObjectPtr &key = stack_get(v,-1);\r
+       SQTable *m = _class(*o)->_members;\r
+       SQObjectPtr val;\r
+       if(m->Get(key,val)) {\r
+               handle->_static = _isfield(val) ? SQFalse : SQTrue;\r
+               handle->_index = _member_idx(val);\r
+               v->Pop();\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("wrong index"));\r
+}\r
+\r
+SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,const HSQMEMBERHANDLE *handle,SQObjectPtr *&val)\r
+{\r
+       switch(type(self)) {\r
+               case OT_INSTANCE: {\r
+                               SQInstance *i = _instance(self);\r
+                               if(handle->_static) {\r
+                                       SQClass *c = i->_class;\r
+                                       val = &c->_methods[handle->_index].val;\r
+                               }\r
+                               else {\r
+                                       val = &i->_values[handle->_index];\r
+                                       \r
+                               }\r
+                       }\r
+                       break;\r
+               case OT_CLASS: {\r
+                               SQClass *c = _class(self);\r
+                               if(handle->_static) {\r
+                                       val = &c->_methods[handle->_index].val;\r
+                               }\r
+                               else {\r
+                                       val = &c->_defaultvalues[handle->_index].val;\r
+                               }\r
+                       }\r
+                       break;\r
+               default:\r
+                       return sq_throwerror(v,_SC("wrong type(expected class or instance)"));\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle)\r
+{\r
+       SQObjectPtr &self = stack_get(v,idx);\r
+       SQObjectPtr *val = NULL;\r
+       if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) {\r
+               return SQ_ERROR;\r
+       }\r
+       v->Push(_realval(*val));\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle)\r
+{\r
+       SQObjectPtr &self = stack_get(v,idx);\r
+       SQObjectPtr &newval = stack_get(v,-1);\r
+       SQObjectPtr *val = NULL;\r
+       if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) {\r
+               return SQ_ERROR;\r
+       }\r
+       *val = newval;\r
+       v->Pop();\r
+       return SQ_OK;\r
+}\r
+\r
 SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr *o = NULL;\r
@@ -1141,7 +1384,7 @@ SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
        if(_class(*o)->_base)\r
                v->Push(SQObjectPtr(_class(*o)->_base));\r
        else\r
-               v->Push(_null_);\r
+               v->PushNull();\r
        return SQ_OK;\r
 }\r
 \r
@@ -1244,9 +1487,10 @@ void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
        dest->Push(stack_get(src,idx));\r
 }\r
 \r
-void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)\r
+void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc)\r
 {\r
        _ss(v)->_printfunc = printfunc;\r
+       _ss(v)->_errorfunc = errfunc;\r
 }\r
 \r
 SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)\r
@@ -1254,6 +1498,11 @@ SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
        return _ss(v)->_printfunc;\r
 }\r
 \r
+SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v)\r
+{\r
+       return _ss(v)->_errorfunc;\r
+}\r
+\r
 void *sq_malloc(SQUnsignedInteger size)\r
 {\r
        return SQ_MALLOC(size);\r