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
}\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
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
#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
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
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
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
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
{\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
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
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
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
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
!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
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
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
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
}\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
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
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
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
_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
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
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
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
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
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
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
{\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
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
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
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
#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
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
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
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
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
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