From 80acfab92ae7bdb38609bb74565ccac5dd329a2b Mon Sep 17 00:00:00 2001 From: Mathnerd314 Date: Wed, 24 Dec 2008 00:59:35 +0000 Subject: [PATCH] Update Squirrel to 2.2.2 (although README says 2.2.1) SVN-Revision: 5824 --- src/squirrel/HISTORY | 15 ++++++++++++++- src/squirrel/README | 2 +- src/squirrel/include/sqstdio.h | 2 -- src/squirrel/include/squirrel.h | 8 +++++++- src/squirrel/squirrel/sqapi.cpp | 27 ++++++++++++++++++++++----- src/squirrel/squirrel/sqarray.h | 12 ++++++++++-- src/squirrel/squirrel/sqbaselib.cpp | 23 +++++++++++++++++------ src/squirrel/squirrel/sqclosure.h | 2 +- src/squirrel/squirrel/sqobject.cpp | 6 ++++-- src/squirrel/squirrel/sqvm.cpp | 29 ++++++++++++++++------------- src/squirrel/squirrel/sqvm.h | 11 +++++++---- 11 files changed, 99 insertions(+), 38 deletions(-) diff --git a/src/squirrel/HISTORY b/src/squirrel/HISTORY index 718834b89..7b918084c 100644 --- a/src/squirrel/HISTORY +++ b/src/squirrel/HISTORY @@ -1,4 +1,17 @@ -***version 2.2 stable*** +***version 2.2.2 stable*** +-fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident) +-fixed coroutine error propagation +-fixed lingering return value from native function (thx Tom Leonard) +-fixed a bug if array.sort() is given a bad sort function (thx Tom Leonard) +-fixed some minor api bug +-added sq_arrayremove() and sq_arrayinsert() + +***2008-05-16 *** +***version 2.2.1 stable*** +-fixed a tailcall bug + +***2008-02-17 *** +***version 2.2 stable *** -added _newslot metamethod in classes -added enums added constants -added sq_pushconsttable, sq_setconsttable diff --git a/src/squirrel/README b/src/squirrel/README index 759c6efba..5b335ae67 100644 --- a/src/squirrel/README +++ b/src/squirrel/README @@ -1,4 +1,4 @@ -The programming language SQUIRREL 2.2 stable +The programming language SQUIRREL 2.2.1 stable -------------------------------------------------- The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and diff --git a/src/squirrel/include/sqstdio.h b/src/squirrel/include/sqstdio.h index 1b753804c..2cb744bcf 100644 --- a/src/squirrel/include/sqstdio.h +++ b/src/squirrel/include/sqstdio.h @@ -7,8 +7,6 @@ #define SQSTD_STREAM_TYPE_TAG 0x80000000 struct SQStream { - virtual ~SQStream() {} - virtual SQInteger Read(void *buffer, SQInteger size) = 0; virtual SQInteger Write(void *buffer, SQInteger size) = 0; virtual SQInteger Flush() = 0; diff --git a/src/squirrel/include/squirrel.h b/src/squirrel/include/squirrel.h index d164400d1..8962eb103 100644 --- a/src/squirrel/include/squirrel.h +++ b/src/squirrel/include/squirrel.h @@ -39,6 +39,10 @@ extern "C" { #define SQUIRREL_API extern #endif +#if (defined(_WIN64) || defined(_LP64)) +#define _SQ64 +#endif + #ifdef _SQ64 #ifdef _MSC_VER typedef __int64 SQInteger; @@ -136,7 +140,7 @@ typedef char SQChar; #define MAX_CHAR 0xFF #endif -#define SQUIRREL_VERSION _SC("Squirrel 2.2 stable") +#define SQUIRREL_VERSION _SC("Squirrel 2.2.2 stable") #define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2008 Alberto Demichelis") #define SQUIRREL_AUTHOR _SC("Alberto Demichelis") @@ -342,6 +346,8 @@ SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx); +SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos); SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx); diff --git a/src/squirrel/squirrel/sqapi.cpp b/src/squirrel/squirrel/sqapi.cpp index ff461e77b..055b4b61a 100644 --- a/src/squirrel/squirrel/sqapi.cpp +++ b/src/squirrel/squirrel/sqapi.cpp @@ -288,11 +288,11 @@ SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) sq_aux_paramscheck(v,1); SQObjectPtr *arr; _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - if(_array(*arr)->Size() > 0) { + if(newsize >= 0) { _array(*arr)->Resize(newsize); return SQ_OK; } - return SQ_OK; + return sq_throwerror(v,_SC("negative size")); } @@ -316,6 +316,25 @@ SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) return SQ_OK; } +SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); +} + +SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); + v->Pop(); + return ret; +} + + void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) { SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func); @@ -963,10 +982,8 @@ SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseer v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval v->Pop(); } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_; - if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM)) + if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM)) { return SQ_ERROR; - if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) { - while (v->_top > 1) v->_stack[--v->_top] = _null_; } if(retval) v->Push(ret); diff --git a/src/squirrel/squirrel/sqarray.h b/src/squirrel/squirrel/sqarray.h index 451b07db8..5c2635207 100644 --- a/src/squirrel/squirrel/sqarray.h +++ b/src/squirrel/squirrel/sqarray.h @@ -61,14 +61,22 @@ public: void Extend(const SQArray *a); SQObjectPtr &Top(){return _values.top();} void Pop(){_values.pop_back(); ShrinkIfNeeded(); } - void Insert(const SQObject& idx,const SQObject &val){_values.insert((SQUnsignedInteger)tointeger(idx),val);} + bool Insert(SQInteger idx,const SQObject &val){ + if(idx < 0 || idx > (SQInteger)_values.size()) + return false; + _values.insert(idx,val); + return true; + } void ShrinkIfNeeded() { if(_values.size() <= _values.capacity()>>2) //shrink the array _values.shrinktofit(); } - void Remove(SQUnsignedInteger idx){ + bool Remove(SQInteger idx){ + if(idx < 0 || idx >= (SQInteger)_values.size()) + return false; _values.remove(idx); ShrinkIfNeeded(); + return true; } void Release() { diff --git a/src/squirrel/squirrel/sqbaselib.cpp b/src/squirrel/squirrel/sqbaselib.cpp index cda52dae7..821fec98e 100644 --- a/src/squirrel/squirrel/sqbaselib.cpp +++ b/src/squirrel/squirrel/sqbaselib.cpp @@ -436,7 +436,8 @@ static SQInteger array_insert(HSQUIRRELVM v) SQObject &o=stack_get(v,1); SQObject &idx=stack_get(v,2); SQObject &val=stack_get(v,3); - _array(o)->Insert(idx,val); + if(!_array(o)->Insert(tointeger(idx),val)) + return sq_throwerror(v,_SC("index out of range")); return 0; } @@ -482,7 +483,8 @@ bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b v->Push(a); v->Push(b); if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { - v->Raise_Error(_SC("compare func failed")); + if(!sq_isstring( v->_lasterror)) + v->Raise_Error(_SC("compare func failed")); return false; } sq_getinteger(v, -1, &ret); @@ -509,7 +511,11 @@ bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger f return false; } while( ret <= 0); do { - --j; + --j; + if ( j < 0 ) { + v->Raise_Error( _SC("Invalid qsort, probably compare function defect") ); + return false; + } if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret)) return false; } @@ -760,6 +766,7 @@ SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ static SQInteger thread_call(HSQUIRRELVM v) { + SQObjectPtr o = stack_get(v,1); if(type(o) == OT_THREAD) { SQInteger nparams = sq_gettop(v); @@ -768,8 +775,10 @@ static SQInteger thread_call(HSQUIRRELVM v) sq_move(_thread(o),v,i); if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) { sq_move(v,_thread(o),-1); + sq_pop(_thread(o),1); return 1; } + v->_lasterror = _thread(o)->_lasterror; return SQ_ERROR; } return sq_throwerror(v,_SC("wrong parameter")); @@ -796,14 +805,16 @@ static SQInteger thread_wakeup(HSQUIRRELVM v) if(wakeupret) { sq_move(thread,v,2); } - if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1,SQFalse))) { + if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQFalse))) { sq_move(v,thread,-1); - sq_pop(thread,1); + sq_pop(thread,1); //pop retval if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { - sq_pop(thread,1); + sq_settop(thread,1); //pop roottable } return 1; } + sq_settop(thread,1); + v->_lasterror = thread->_lasterror; return SQ_ERROR; } return sq_throwerror(v,_SC("wrong parameter")); diff --git a/src/squirrel/squirrel/sqclosure.h b/src/squirrel/squirrel/sqclosure.h index 8db7ca232..de70ee02e 100644 --- a/src/squirrel/squirrel/sqclosure.h +++ b/src/squirrel/squirrel/sqclosure.h @@ -45,7 +45,7 @@ struct SQGenerator : public CHAINABLE_OBJ { enum SQGeneratorState{eRunning,eSuspended,eDead}; private: - SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=_null_;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} + SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} public: static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); diff --git a/src/squirrel/squirrel/sqobject.cpp b/src/squirrel/squirrel/sqobject.cpp index 1e1a63872..59ebd4e61 100644 --- a/src/squirrel/squirrel/sqobject.cpp +++ b/src/squirrel/squirrel/sqobject.cpp @@ -117,6 +117,7 @@ bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { bool SQDelegable::SetDelegate(SQTable *mt) { SQTable *temp = mt; + if(temp == this) return false; while (temp) { if (temp->_delegate == this) return false; //cycle detected temp = temp->_delegate; @@ -143,7 +144,7 @@ bool SQGenerator::Yield(SQVM *v) for(SQInteger j = nvargs - 1; j >= 0; j--) { _vargsstack.push_back(v->_vargsstack[vargsbase+j]); } - _ci._generator=_null_; + _ci._generator=NULL; for(SQInteger i=0;i<_ci._etraps;i++) { _etraps.push_back(v->_etraps.top()); v->_etraps.pop_back(); @@ -162,7 +163,7 @@ bool SQGenerator::Resume(SQVM *v,SQInteger target) SQInteger oldstackbase=v->_stackbase; v->_stackbase = v->_top; v->ci->_target = (SQInt32)target; - v->ci->_generator = SQObjectPtr(this); + v->ci->_generator = this; v->ci->_vargs.size = (unsigned short)_vargsstack.size(); for(SQInteger i=0;i<_ci._etraps;i++) { @@ -496,6 +497,7 @@ void SQVM::Mark(SQCollectable **chain) SQSharedState::MarkObject(temp_reg, chain); for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain); + for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); END_MARK() } diff --git a/src/squirrel/squirrel/sqvm.cpp b/src/squirrel/squirrel/sqvm.cpp index 4e96fbb8f..7cadcafcb 100644 --- a/src/squirrel/squirrel/sqvm.cpp +++ b/src/squirrel/squirrel/sqvm.cpp @@ -99,6 +99,7 @@ void SQVM::Finalize() _errorhandler = _null_; _debughook = _null_; temp_reg = _null_; + _callstackdata.resize(0); SQInteger size=_stack.size(); for(SQInteger i=0;i_gc_chain,this); } @@ -282,8 +283,10 @@ bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) _stack.resize(stacksize); //_callsstack.reserve(4); _alloccallsstacksize = 4; + _callstackdata.resize(_alloccallsstacksize); _callsstacksize = 0; - _callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo)); + _callsstack = &_callstackdata[0]; + //_callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo)); _stackbase = 0; _top = 0; if(!friendvm) @@ -338,6 +341,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege if (!tailcall) { CallInfo lc; + lc._generator = NULL; lc._etraps = 0; lc._prevstkbase = (SQInt32) ( stackbase - _stackbase ); lc._target = (SQInt32) target; @@ -351,8 +355,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege } ci->_vargs.size = (SQInt32)(nargs - paramssize); ci->_vargs.base = (SQInt32)(_vargsstack.size()-(ci->_vargs.size)); - ci->_closure._unVal.pClosure = closure; - ci->_closure._type = OT_CLOSURE; + ci->_closure = closure; ci->_literals = func->_literals; ci->_ip = func->_instructions; //grows the stack if needed @@ -826,8 +829,8 @@ common_call: case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue; case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; case _OP_RETURN: - if(type((ci)->_generator) == OT_GENERATOR) { - _generator((ci)->_generator)->Kill(); + if(ci->_generator) { + ci->_generator->Kill(); } if(Return(arg0, arg1, temp_reg)){ assert(traps==0); @@ -893,9 +896,9 @@ common_call: continue; } case _OP_YIELD:{ - if(type(ci->_generator) == OT_GENERATOR) { + if(ci->_generator) { if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); - _GUARD(_generator(ci->_generator)->Yield(this)); + _GUARD(ci->_generator->Yield(this)); traps -= ci->_etraps; if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg; } @@ -989,7 +992,7 @@ exception_trap: //if is a native closure if(type(ci->_closure) != OT_CLOSURE && n) break; - if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill(); + if(ci->_generator) ci->_generator->Kill(); PopVarArgs(ci->_vargs); POP_CALLINFO(this); n++; @@ -1003,7 +1006,7 @@ exception_trap: //remove call stack until a C function is found or the cstack is empty if(ci) do { SQBool exitafterthisone = ci->_root; - if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill(); + if(ci->_generator) ci->_generator->Kill(); _stackbase -= ci->_prevstkbase; _top = _stackbase + ci->_prevtop; PopVarArgs(ci->_vargs); @@ -1076,9 +1079,9 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb SQInteger oldstackbase = _stackbase; _top = stackbase + nargs; CallInfo lci; + lci._closure = nclosure; + lci._generator = NULL; lci._etraps = 0; - lci._closure._unVal.pNativeClosure = nclosure; - lci._closure._type = OT_NATIVECLOSURE; lci._prevstkbase = (SQInt32) (stackbase - _stackbase); lci._ncalls = 1; lci._prevtop = (SQInt32) (oldtop - oldstackbase); @@ -1107,7 +1110,7 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb return false; } - if (ret != 0){ retval = TOP(); } + if (ret != 0){ retval = TOP(); TOP().Null(); } else { retval = _null_; } _stackbase = oldstackbase; _top = oldtop; diff --git a/src/squirrel/squirrel/sqvm.h b/src/squirrel/squirrel/sqvm.h index 80bc594ca..b9db81751 100644 --- a/src/squirrel/squirrel/sqvm.h +++ b/src/squirrel/squirrel/sqvm.h @@ -37,11 +37,11 @@ struct SQVM : public CHAINABLE_OBJ }; struct CallInfo{ - CallInfo() { _generator._type = OT_NULL;} + //CallInfo() { _generator._type = OT_NULL;} SQInstruction *_ip; SQObjectPtr *_literals; - SQObject _closure; - SQObject _generator; + SQObjectPtr _closure; + SQGenerator *_generator; SQInt32 _etraps; SQInt32 _prevstkbase; SQInt32 _prevtop; @@ -118,7 +118,8 @@ public: void Finalize(); void GrowCallStack() { SQInteger newsize = _alloccallsstacksize*2; - _callsstack = (CallInfo*)sq_realloc(_callsstack,_alloccallsstacksize*sizeof(CallInfo),newsize*sizeof(CallInfo)); + _callstackdata.resize(newsize); + _callsstack = &_callstackdata[0]; _alloccallsstacksize = newsize; } void Release(){ sq_delete(this,SQVM); } //does nothing @@ -151,6 +152,7 @@ public: CallInfo* _callsstack; SQInteger _callsstacksize; SQInteger _alloccallsstacksize; + sqvector _callstackdata; ExceptionsTraps _etraps; CallInfo *ci; @@ -193,6 +195,7 @@ inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v-> #define POP_CALLINFO(v){ \ v->_callsstacksize--; \ + v->ci->_closure.Null(); \ if(v->_callsstacksize) \ v->ci = &v->_callsstack[v->_callsstacksize-1] ; \ else \ -- 2.11.0