this shouldn't be in svn
[supertux.git] / src / squirrel / squirrel / sqapi.cpp
index 638280f..b17bab9 100644 (file)
@@ -124,40 +124,26 @@ SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQCha
        return SQ_ERROR;\r
 }\r
 \r
-void sq_enabledebuginfo(HSQUIRRELVM v, SQBool debuginfo)\r
+void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)\r
 {\r
-       _ss(v)->_debuginfo = debuginfo?true:false;\r
+       _ss(v)->_debuginfo = enable?true:false;\r
+}\r
+\r
+void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)\r
+{\r
+       _ss(v)->_notifyallexceptions = enable?true:false;\r
 }\r
 \r
 void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)\r
 {\r
-       SQObjectPtr refs;\r
        if(!ISREFCOUNTED(type(*po))) return;\r
-       if(_table(_ss(v)->_refs_table)->Get(*po, refs)) {\r
-               refs = _integer(refs) + 1;\r
-       }\r
-       else{\r
-               refs = 1;\r
-       }\r
-       _table(_ss(v)->_refs_table)->NewSlot(*po, refs);\r
+       _ss(v)->_refs_table.AddRef(*po);\r
 }\r
 \r
 SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)\r
 {\r
-       SQObjectPtr refs;\r
        if(!ISREFCOUNTED(type(*po))) return SQTrue;\r
-       if(_table(_ss(v)->_refs_table)->Get(*po, refs)) {\r
-               SQInteger n = _integer(refs) - 1;\r
-               if(n <= 0) {\r
-                       _table(_ss(v)->_refs_table)->Remove(*po);\r
-                       sq_resetobject(po);\r
-               }\r
-               else {\r
-                       refs = n;_table(_ss(v)->_refs_table)->Set(*po, refs);\r
-                       return SQFalse;\r
-               }\r
-       }\r
-       return SQTrue;\r
+       return _ss(v)->_refs_table.Release(*po);\r
 }\r
 \r
 const SQChar *sq_objtostring(HSQOBJECT *o) \r
@@ -256,13 +242,13 @@ SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
        return SQ_OK;\r
 }\r
 \r
-SQInteger sq_instanceof(HSQUIRRELVM v)\r
+SQBool sq_instanceof(HSQUIRRELVM v)\r
 {\r
        SQObjectPtr &inst = stack_get(v,-1);\r
        SQObjectPtr &cl = stack_get(v,-2);\r
        if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)\r
                return sq_throwerror(v,_SC("invalid param type"));\r
-       return _instance(inst)->InstanceOf(_class(cl))?1:0;\r
+       return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;\r
 }\r
 \r
 SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)\r
@@ -377,6 +363,34 @@ SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *ty
        return SQ_OK;\r
 }\r
 \r
+SQRESULT sq_bindenv(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
+    SQObjectPtr &env = stack_get(v,-1);\r
+       if(!sq_istable(env) &&\r
+               !sq_isclass(env) &&\r
+               !sq_isinstance(env))\r
+               return sq_throwerror(v,_SC("invalid environment"));\r
+       SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));\r
+       SQObjectPtr ret;\r
+       if(sq_isclosure(o)) {\r
+               SQClosure *c = _closure(o)->Clone();\r
+               c->_env = w;\r
+               ret = c;\r
+       }\r
+       else { //then must be a native closure\r
+               SQNativeClosure *c = _nativeclosure(o)->Clone();\r
+               c->_env = w;\r
+               ret = c;\r
+       }\r
+       v->Pop();\r
+       v->Push(ret);\r
+       return SQ_OK;\r
+}\r
+\r
 void sq_pushroottable(HSQUIRRELVM v)\r
 {\r
        v->Push(v->_roottable);\r
@@ -426,6 +440,12 @@ void sq_tostring(HSQUIRRELVM v,SQInteger idx)
        v->Push(res);\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
+}\r
+\r
 SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)\r
 {\r
        SQObjectPtr &o = stack_get(v, idx);\r
@@ -608,19 +628,32 @@ SQInteger sq_cmp(HSQUIRRELVM v)
        return res;\r
 }\r
 \r
-SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx)\r
+SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)\r
 {\r
        sq_aux_paramscheck(v, 3);\r
        SQObjectPtr &self = stack_get(v, idx);\r
        if(type(self) == OT_TABLE || type(self) == OT_CLASS) {\r
                SQObjectPtr &key = v->GetUp(-2);\r
                if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
-               v->NewSlot(self, key, v->GetUp(-1));\r
+               v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);\r
                v->Pop(2);\r
        }\r
        return SQ_OK;\r
 }\r
 \r
+/*SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx)\r
+{\r
+       sq_aux_paramscheck(v, 3);\r
+       SQObjectPtr &self = stack_get(v, idx);\r
+       if(type(self) == OT_TABLE || type(self) == OT_CLASS) {\r
+               SQObjectPtr &key = v->GetUp(-2);\r
+               if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
+               v->NewSlot(self, key, v->GetUp(-1));\r
+               v->Pop(2);\r
+       }\r
+       return SQ_OK;\r
+}*/\r
+\r
 SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)\r
 {\r
        sq_aux_paramscheck(v, 2);\r
@@ -658,7 +691,7 @@ SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
                return SQ_OK;\r
        break;\r
        case OT_CLASS:\r
-               _class(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));\r
+               _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);\r
                v->Pop(2);\r
                return SQ_OK;\r
        break;\r
@@ -732,15 +765,15 @@ SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
        case OT_TABLE:\r
                if(!_table(self)->_delegate)break;\r
                v->Push(SQObjectPtr(_table(self)->_delegate));\r
-               return SQ_OK;\r
                break;\r
        case OT_USERDATA:\r
                if(!_userdata(self)->_delegate)break;\r
                v->Push(SQObjectPtr(_userdata(self)->_delegate));\r
-               return SQ_OK;\r
                break;\r
+       default: return sq_throwerror(v,_SC("wrong type")); break;\r
        }\r
-       return sq_throwerror(v,_SC("wrong type"));\r
+       return SQ_OK;\r
+       \r
 }\r
 \r
 SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)\r
@@ -801,7 +834,7 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
                        return NULL;\r
                SQClosure *c=_closure(ci._closure);\r
                SQFunctionProto *func=_funcproto(c->_function);\r
-               return func->GetLocal(v,stackbase,idx,(ci._ip-func->_instructions._vals)-1);\r
+               return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions._vals)-1);\r
        }\r
        return NULL;\r
 }\r
@@ -839,11 +872,11 @@ void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
        }\r
 }\r
 \r
-SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval)\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),SQVM::ET_RESUME_GENERATOR))\r
+               if(!v->Execute(v->GetUp(-2),v->_top,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
@@ -852,10 +885,10 @@ SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval)
        return sq_throwerror(v,_SC("only generators can be resumed"));\r
 }\r
 \r
-SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval)\r
+SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)\r
 {\r
        SQObjectPtr res;\r
-       if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res)){\r
+       if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){\r
                v->Pop(params);//pop closure and args\r
                if(retval){\r
                        v->Push(res); return SQ_OK;\r
@@ -876,7 +909,7 @@ SQRESULT sq_suspendvm(HSQUIRRELVM v)
        return v->Suspend();\r
 }\r
 \r
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval)\r
+SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror)\r
 {\r
        SQObjectPtr ret;\r
        if(!v->_suspended)\r
@@ -885,7 +918,7 @@ SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval)
                v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval\r
                v->Pop();\r
        } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;\r
-       if(!v->Execute(_null_,v->_top,-1,-1,ret,SQVM::ET_RESUME_VM))\r
+       if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,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
@@ -900,12 +933,10 @@ void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
        if(sq_gettop(v) >= 1){\r
                SQObjectPtr &ud=stack_get(v,idx);\r
                switch( type(ud) ) {\r
-               case OT_USERDATA:\r
-                       _userdata(ud)->_hook = hook;\r
-                       break;\r
-               case OT_INSTANCE:\r
-                       _instance(ud)->_hook = hook;\r
-                       break;\r
+               case OT_USERDATA:       _userdata(ud)->_hook = hook;    break;\r
+               case OT_INSTANCE:       _instance(ud)->_hook = hook;    break;\r
+               case OT_CLASS:          _class(ud)->_hook = hook;               break;\r
+               default: break; //shutup compiler\r
                }\r
        }\r
 }\r
@@ -919,7 +950,6 @@ SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
 {\r
        SQObjectPtr *o = NULL;\r
        _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);\r
-       SQClosure *c=_closure(*o);\r
        unsigned short tag = SQ_BYTECODE_STREAM_TAG;\r
        if(w(up,&tag,2) != 2)\r
                return sq_throwerror(v,_SC("io error"));\r
@@ -1027,7 +1057,7 @@ SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
        if(type(key) == OT_NULL) {\r
                attrs = _class(*o)->_attributes;\r
                v->Pop();\r
-               v->Push(attrs);\r
+               v->Push(attrs); \r
                return SQ_OK;\r
        }\r
        else if(_class(*o)->GetAttributes(key,attrs)) {\r
@@ -1038,6 +1068,17 @@ SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
        return sq_throwerror(v,_SC("wrong index"));\r
 }\r
 \r
+SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
+       if(_class(*o)->_base)\r
+               v->Push(SQObjectPtr(_class(*o)->_base));\r
+       else\r
+               v->Push(_null_);\r
+       return SQ_OK;\r
+}\r
+\r
 SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr *o = NULL;\r
@@ -1074,6 +1115,25 @@ SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
        return SQ_OK;\r
 }\r
 \r
+SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)\r
+{\r
+       SQSharedState *ss = _ss(v);\r
+       switch(t) {\r
+       case OT_TABLE: v->Push(ss->_table_default_delegate); break;\r
+       case OT_ARRAY: v->Push(ss->_array_default_delegate); break;\r
+       case OT_STRING: v->Push(ss->_string_default_delegate); break;\r
+       case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;\r
+       case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;\r
+       case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;\r
+       case OT_THREAD: v->Push(ss->_thread_default_delegate); break;\r
+       case OT_CLASS: v->Push(ss->_class_default_delegate); break;\r
+       case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;\r
+       case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;\r
+       default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
 SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)\r
 {\r
        SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;\r