diff options
-rw-r--r-- | src/3rdparty/squirrel/COMPILE | 2 | ||||
-rw-r--r-- | src/3rdparty/squirrel/COPYRIGHT | 2 | ||||
-rw-r--r-- | src/3rdparty/squirrel/HISTORY | 14 | ||||
-rw-r--r-- | src/3rdparty/squirrel/README | 2 | ||||
-rw-r--r-- | src/3rdparty/squirrel/include/sqstdstring.h | 2 | ||||
-rw-r--r-- | src/3rdparty/squirrel/include/squirrel.h | 34 | ||||
-rw-r--r-- | src/3rdparty/squirrel/sq/sq.c | 3 | ||||
-rw-r--r-- | src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp | 5 | ||||
-rw-r--r-- | src/3rdparty/squirrel/sqstdlib/sqstdstring.cpp | 25 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqapi.cpp | 6 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqbaselib.cpp | 5 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqcompiler.cpp | 17 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqdebug.cpp | 17 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqfuncstate.cpp | 2 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqobject.h | 24 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqvm.cpp | 49 | ||||
-rw-r--r-- | src/3rdparty/squirrel/squirrel/sqvm.h | 3 |
17 files changed, 177 insertions, 35 deletions
diff --git a/src/3rdparty/squirrel/COMPILE b/src/3rdparty/squirrel/COMPILE index 53022f4c8..971fb653d 100644 --- a/src/3rdparty/squirrel/COMPILE +++ b/src/3rdparty/squirrel/COMPILE @@ -1,4 +1,4 @@ -Squirrel 2.2.1 stable +Squirrel 2.2.3 stable -------------------------------------------------------- What is in this distribution? diff --git a/src/3rdparty/squirrel/COPYRIGHT b/src/3rdparty/squirrel/COPYRIGHT index 03a73fc56..161551bf8 100644 --- a/src/3rdparty/squirrel/COPYRIGHT +++ b/src/3rdparty/squirrel/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright (c) 2003-2008 Alberto Demichelis +Copyright (c) 2003-2009 Alberto Demichelis This software is provided 'as-is', without any express or implied warranty. In no event will the diff --git a/src/3rdparty/squirrel/HISTORY b/src/3rdparty/squirrel/HISTORY index 3717ae445..2dbc70b5b 100644 --- a/src/3rdparty/squirrel/HISTORY +++ b/src/3rdparty/squirrel/HISTORY @@ -1,3 +1,17 @@ +***version 2.2.3 stable*** +-added sq_getfunctioninfo +-added compile time flag SQUSEDOUBLE to use double precision floats +-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds +-sq_wakeupvm can now resume the vm with an exception +-added sqstd_format +-generators can now be instantiated by calling sq_call() or closure.call() +-fixed a bug in sqstd_printcallstack(thx takayuki_h) +-fixed modulo by zero(thx jup) +-fixed negative enums and constants +-fixed generator crash bug if invoked as tail call (thx Mr.Accident) +-fixed some minor bug + +***2008-09-24 *** ***version 2.2.2 stable*** -fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident) -fixed coroutine error propagation diff --git a/src/3rdparty/squirrel/README b/src/3rdparty/squirrel/README index e48108f51..810103cef 100644 --- a/src/3rdparty/squirrel/README +++ b/src/3rdparty/squirrel/README @@ -1,4 +1,4 @@ -The programming language SQUIRREL 2.2.1 stable +The programming language SQUIRREL 2.2.3 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/3rdparty/squirrel/include/sqstdstring.h b/src/3rdparty/squirrel/include/sqstdstring.h index 72f30b4ad..3c3bce826 100644 --- a/src/3rdparty/squirrel/include/sqstdstring.h +++ b/src/3rdparty/squirrel/include/sqstdstring.h @@ -22,6 +22,8 @@ SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,co SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp); SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp); +SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output); + SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v); #ifdef __cplusplus diff --git a/src/3rdparty/squirrel/include/squirrel.h b/src/3rdparty/squirrel/include/squirrel.h index 5623760fa..806454721 100644 --- a/src/3rdparty/squirrel/include/squirrel.h +++ b/src/3rdparty/squirrel/include/squirrel.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2008 Alberto Demichelis +Copyright (c) 2003-2009 Alberto Demichelis This software is provided 'as-is', without any express or implied warranty. In no event will the @@ -68,7 +68,24 @@ typedef unsigned int SQHash; /*should be the same size of a pointer*/ #endif +#ifdef SQUSEDOUBLE +typedef double SQFloat; +#else typedef float SQFloat; +#endif + +#if defined(SQUSEDOUBLE) && !defined(_SQ64) +#ifdef _MSC_VER +typedef __int64 SQRawObjectVal; //must be 64bits +#else +typedef long SQRawObjectVal; //must be 64bits +#endif +#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } +#else +typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise +#define SQ_OBJECT_RAWINIT() +#endif + typedef void* SQUserPointer; typedef SQUnsignedInteger SQBool; typedef SQInteger SQRESULT; @@ -159,8 +176,8 @@ typedef char SQChar; #define MAX_CHAR 0xFF #endif -#define SQUIRREL_VERSION _SC("Squirrel 2.2.2 stable - With custom OpenTTD modifications") -#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2008 Alberto Demichelis") +#define SQUIRREL_VERSION _SC("Squirrel 2.2.3 stable - With custom OpenTTD modifications") +#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2009 Alberto Demichelis") #define SQUIRREL_AUTHOR _SC("Alberto Demichelis") #define SQ_VMSTATE_IDLE 0 @@ -240,6 +257,7 @@ typedef union tagSQObjectValue struct SQClass *pClass; struct SQInstance *pInstance; struct SQWeakRef *pWeakRef; + SQRawObjectVal raw; }SQObjectValue; @@ -274,6 +292,13 @@ typedef struct tagSQRegFunction{ const SQChar *typemask; }SQRegFunction; +typedef struct tagSQFunctionInfo { + SQUserPointer funcid; + const SQChar *name; + const SQChar *source; +}SQFunctionInfo; + + /*vm*/ SQUIRREL_API bool sq_can_suspend(HSQUIRRELVM v); SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); @@ -286,7 +311,7 @@ SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc); SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v); SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); SQUIRREL_API bool sq_resumecatch(HSQUIRRELVM v, int suspend = -1); -SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror); SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v); /*compiler*/ @@ -337,6 +362,7 @@ SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer ty SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag); SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); +SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi); SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name); SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); diff --git a/src/3rdparty/squirrel/sq/sq.c b/src/3rdparty/squirrel/sq/sq.c index dc24b372c..0a4e48f14 100644 --- a/src/3rdparty/squirrel/sq/sq.c +++ b/src/3rdparty/squirrel/sq/sq.c @@ -59,6 +59,9 @@ void printfunc(HSQUIRRELVM v,const SQChar *s,...) void PrintVersionInfos() { scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,sizeof(SQInteger)*8); + if(sizeof(SQFloat) != sizeof(float)) { + scfprintf(stdout,_SC("[%d bits floats]\n"),sizeof(SQFloat)*8); + } } void PrintUsage() diff --git a/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp b/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp index 65c9070b3..e1f93cbf7 100644 --- a/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp +++ b/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp @@ -9,6 +9,7 @@ void sqstd_printcallstack(HSQUIRRELVM v) if(pf) { SQStackInfos si; SQInteger i; + SQBool b; SQFloat f; const SQChar *s; SQInteger level=1; //1 is to skip this function that is level 0 @@ -83,8 +84,8 @@ void sqstd_printcallstack(HSQUIRRELVM v) pf(v,_SC("[%s] WEAKREF\n"),name); break; case OT_BOOL:{ - sq_getinteger(v,-1,&i); - pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false")); + sq_getbool(v,-1,&b); + pf(v,_SC("[%s] %s\n"),name,b?_SC("true"):_SC("false")); } break; default: assert(0); break; diff --git a/src/3rdparty/squirrel/sqstdlib/sqstdstring.cpp b/src/3rdparty/squirrel/sqstdlib/sqstdstring.cpp index 00b1667e0..681029aa7 100644 --- a/src/3rdparty/squirrel/sqstdlib/sqstdstring.cpp +++ b/src/3rdparty/squirrel/sqstdlib/sqstdstring.cpp @@ -79,15 +79,16 @@ static void _append_string(SQInteger &i, SQChar *dest, SQInteger allocated, cons va_end(va); } -static SQInteger _string_format(HSQUIRRELVM v) + +SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) { const SQChar *format; SQChar *dest; SQChar fmt[MAX_FORMAT_LEN]; - sq_getstring(v,2,&format); - SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar); + sq_getstring(v,nformatstringidx,&format); + SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar); dest = sq_getscratchpad(v,allocated); - SQInteger n = 0,i = 0, nparam = 3, w = 0; + SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; while(format[n] != '\0') { if(format[n] != '%') { assert(i < allocated); @@ -132,7 +133,7 @@ static SQInteger _string_format(HSQUIRRELVM v) return sq_throwerror(v,_SC("invalid format")); } n++; - allocated += addlen; + allocated += addlen + sizeof(SQChar); dest = sq_getscratchpad(v,allocated); switch(valtype) { case 's': _append_string(i,dest,allocated,fmt,ts); break; @@ -142,7 +143,19 @@ static SQInteger _string_format(HSQUIRRELVM v) nparam ++; } } - sq_pushstring(v,dest,i); + *outlen = i; + dest[i] = '\0'; + *output = dest; + return SQ_OK; +} + +static SQInteger _string_format(HSQUIRRELVM v) +{ + SQChar *dest = NULL; + SQInteger length = 0; + if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) + return -1; + sq_pushstring(v,dest,length); return 1; } diff --git a/src/3rdparty/squirrel/squirrel/sqapi.cpp b/src/3rdparty/squirrel/squirrel/sqapi.cpp index 647d1b4ee..1e8b456f6 100644 --- a/src/3rdparty/squirrel/squirrel/sqapi.cpp +++ b/src/3rdparty/squirrel/squirrel/sqapi.cpp @@ -984,7 +984,7 @@ SQRESULT sq_suspendvm(HSQUIRRELVM v) return v->Suspend(); } -SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror) +SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) { SQObjectPtr ret; if(!v->_suspended) @@ -994,8 +994,10 @@ SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseer v->Pop(); } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_; v->_can_suspend = false; - if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM)) { + if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : 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/3rdparty/squirrel/squirrel/sqbaselib.cpp b/src/3rdparty/squirrel/squirrel/sqbaselib.cpp index 312e2f7ff..aa0f67ed2 100644 --- a/src/3rdparty/squirrel/squirrel/sqbaselib.cpp +++ b/src/3rdparty/squirrel/squirrel/sqbaselib.cpp @@ -277,6 +277,9 @@ void sq_base_register(HSQUIRRELVM v) sq_pushstring(v,_SC("_intsize_"),-1); sq_pushinteger(v,sizeof(SQInteger)); sq_createslot(v,-3); + sq_pushstring(v,_SC("_floatsize_"),-1); + sq_pushinteger(v,sizeof(SQFloat)); + sq_createslot(v,-3); sq_pop(v,1); } @@ -815,7 +818,7 @@ static SQInteger thread_wakeup(HSQUIRRELVM v) if(wakeupret) { sq_move(thread,v,2); } - if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQFalse))) { + if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { sq_move(v,thread,-1); sq_pop(thread,1); //pop retval if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { diff --git a/src/3rdparty/squirrel/squirrel/sqcompiler.cpp b/src/3rdparty/squirrel/squirrel/sqcompiler.cpp index 6839e922b..6c07d8103 100644 --- a/src/3rdparty/squirrel/squirrel/sqcompiler.cpp +++ b/src/3rdparty/squirrel/squirrel/sqcompiler.cpp @@ -1110,6 +1110,23 @@ public: case TK_STRING_LITERAL: val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); break; + case '-': + Lex(); + switch(_token) + { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = -_lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = -_lex._fvalue; + break; + default: + Error(_SC("scalar expected : integer,float")); + val._type = OT_NULL; // Silent compile-warning + } + break; default: Error(_SC("scalar expected : integer,float or string")); val._type = OT_NULL; // Silent compile-warning diff --git a/src/3rdparty/squirrel/squirrel/sqdebug.cpp b/src/3rdparty/squirrel/squirrel/sqdebug.cpp index 0b0964ceb..055762651 100644 --- a/src/3rdparty/squirrel/squirrel/sqdebug.cpp +++ b/src/3rdparty/squirrel/squirrel/sqdebug.cpp @@ -9,6 +9,23 @@ #include "sqclosure.h" #include "sqstring.h" +SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + if(sq_isclosure(ci._closure)) { + SQClosure *c = _closure(ci._closure); + SQFunctionProto *proto = _funcproto(c->_function); + fi->funcid = proto; + fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); + fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); + return SQ_OK; + } + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) { SQInteger cssize = v->_callsstacksize; diff --git a/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp b/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp index 8d536fdbb..b4f354173 100644 --- a/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp +++ b/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp @@ -86,7 +86,7 @@ void DumpLiteral(SQObjectPtr &o) case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break; #endif case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; - default: scprintf(_SC("(%s %p)"),GetTypeName(o),_rawval(o));break; break; //shut up compiler + default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler } } diff --git a/src/3rdparty/squirrel/squirrel/sqobject.h b/src/3rdparty/squirrel/squirrel/sqobject.h index 7deeafb87..02d920e4a 100644 --- a/src/3rdparty/squirrel/squirrel/sqobject.h +++ b/src/3rdparty/squirrel/squirrel/sqobject.h @@ -117,7 +117,7 @@ struct SQObjectPtr; #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) #define _weakref(obj) ((obj)._unVal.pWeakRef) #define _refcounted(obj) ((obj)._unVal.pRefCounted) -#define _rawval(obj) ((obj)._unVal.pRefCounted) +#define _rawval(obj) ((obj)._unVal.raw) #define _stringval(obj) (obj)._unVal.pString->_val #define _userdataval(obj) (obj)._unVal.pUserData->_val @@ -130,23 +130,27 @@ struct SQObjectPtr : public SQObject { SQObjectPtr() { + SQ_OBJECT_RAWINIT() _type=OT_NULL; _unVal.pUserPointer=NULL; } SQObjectPtr(const SQObjectPtr &o) { + SQ_OBJECT_RAWINIT() _type=o._type; _unVal=o._unVal; __AddRef(_type,_unVal); } SQObjectPtr(const SQObject &o) { + SQ_OBJECT_RAWINIT() _type=o._type; _unVal=o._unVal; __AddRef(_type,_unVal); } SQObjectPtr(SQTable *pTable) { + SQ_OBJECT_RAWINIT() _type=OT_TABLE; _unVal.pTable=pTable; assert(_unVal.pTable); @@ -154,6 +158,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQClass *pClass) { + SQ_OBJECT_RAWINIT() _type=OT_CLASS; _unVal.pClass=pClass; assert(_unVal.pClass); @@ -161,6 +166,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQInstance *pInstance) { + SQ_OBJECT_RAWINIT() _type=OT_INSTANCE; _unVal.pInstance=pInstance; assert(_unVal.pInstance); @@ -168,6 +174,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQArray *pArray) { + SQ_OBJECT_RAWINIT() _type=OT_ARRAY; _unVal.pArray=pArray; assert(_unVal.pArray); @@ -175,6 +182,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQClosure *pClosure) { + SQ_OBJECT_RAWINIT() _type=OT_CLOSURE; _unVal.pClosure=pClosure; assert(_unVal.pClosure); @@ -182,6 +190,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQGenerator *pGenerator) { + SQ_OBJECT_RAWINIT() _type=OT_GENERATOR; _unVal.pGenerator=pGenerator; assert(_unVal.pGenerator); @@ -189,6 +198,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQNativeClosure *pNativeClosure) { + SQ_OBJECT_RAWINIT() _type=OT_NATIVECLOSURE; _unVal.pNativeClosure=pNativeClosure; assert(_unVal.pNativeClosure); @@ -196,6 +206,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQString *pString) { + SQ_OBJECT_RAWINIT() _type=OT_STRING; _unVal.pString=pString; assert(_unVal.pString); @@ -203,6 +214,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQUserData *pUserData) { + SQ_OBJECT_RAWINIT() _type=OT_USERDATA; _unVal.pUserData=pUserData; assert(_unVal.pUserData); @@ -210,6 +222,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQVM *pThread) { + SQ_OBJECT_RAWINIT() _type=OT_THREAD; _unVal.pThread=pThread; assert(_unVal.pThread); @@ -217,6 +230,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQWeakRef *pWeakRef) { + SQ_OBJECT_RAWINIT() _type=OT_WEAKREF; _unVal.pWeakRef=pWeakRef; assert(_unVal.pWeakRef); @@ -224,6 +238,7 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQFunctionProto *pFunctionProto) { + SQ_OBJECT_RAWINIT() _type=OT_FUNCPROTO; _unVal.pFunctionProto=pFunctionProto; assert(_unVal.pFunctionProto); @@ -231,24 +246,25 @@ struct SQObjectPtr : public SQObject } SQObjectPtr(SQInteger nInteger) { - _unVal.pUserPointer=NULL; + SQ_OBJECT_RAWINIT() _type=OT_INTEGER; _unVal.nInteger=nInteger; } SQObjectPtr(SQFloat fFloat) { - _unVal.pUserPointer=NULL; + SQ_OBJECT_RAWINIT() _type=OT_FLOAT; _unVal.fFloat=fFloat; } SQObjectPtr(bool bBool) { - _unVal.pUserPointer=NULL; + SQ_OBJECT_RAWINIT() _type = OT_BOOL; _unVal.nInteger = bBool?1:0; } SQObjectPtr(SQUserPointer pUserPointer) { + SQ_OBJECT_RAWINIT() _type=OT_USERPOINTER; _unVal.pUserPointer=pUserPointer; } diff --git a/src/3rdparty/squirrel/squirrel/sqvm.cpp b/src/3rdparty/squirrel/squirrel/sqvm.cpp index 10edc5970..c2ca7e19c 100644 --- a/src/3rdparty/squirrel/squirrel/sqvm.cpp +++ b/src/3rdparty/squirrel/squirrel/sqvm.cpp @@ -17,6 +17,21 @@ #define TOP() (_stack._vals[_top-1]) +#define CLEARSTACK(_last_top) { if((_last_top) >= _top) ClearStack(_last_top); } +void SQVM::ClearStack(SQInteger last_top) +{ + SQObjectType tOldType; + SQObjectValue unOldVal; + while (last_top >= _top) { + SQObjectPtr &o = _stack._vals[last_top--]; + tOldType = o._type; + unOldVal = o._unVal; + o._type = OT_NULL; + o._unVal.pUserPointer = NULL; + __Release(tOldType,unOldVal); + } +} + bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) { SQInteger res; @@ -50,7 +65,9 @@ bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1, res = i1 / i2; break; case '*': res = i1 * i2; break; - case '%': res = i1 % i2; break; + case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } + res = i1 % i2; + break; default: res = 0xDEADBEEF; } trg = res; @@ -288,12 +305,10 @@ void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) { _stack.resize(stacksize); - //_callsstack.reserve(4); _alloccallsstacksize = 4; _callstackdata.resize(_alloccallsstacksize); _callsstacksize = 0; _callsstack = &_callstackdata[0]; - //_callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo)); _stackbase = 0; _top = 0; if(!friendvm) @@ -672,20 +687,34 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn bool ct_tailcall; switch(et) { - case ET_CALL: - if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) { + case ET_CALL: { + SQInteger last_top = _top; + temp_reg = closure; + if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { //call the handler if there are no calls in the stack, if not relies on the previous node if(ci == NULL) CallErrorHandler(_lasterror); return false; } + if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) { + //SQFunctionProto *f = _funcproto(_closure(temp_reg)->_function); + SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg)); + _GUARD(gen->Yield(this)); + Return(1, ci->_target, temp_reg); + outres = gen; + CLEARSTACK(last_top); + return true; + } ci->_root = SQTrue; + } break; case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break; case ET_RESUME_VM: + case ET_RESUME_THROW_VM: traps = _suspended_traps; ci->_root = _suspended_root; ci->_vargs = _suspend_varargs; _suspended = SQFalse; + if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } break; case ET_RESUME_OPENTTD: traps = _suspended_traps; @@ -716,7 +745,7 @@ exception_restore: case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; case _OP_TAILCALL: temp_reg = STK(arg1); - if (type(temp_reg) == OT_CLOSURE){ + if (type(temp_reg) == OT_CLOSURE && !_funcproto(_closure(temp_reg)->_function)->_bgenerator){ ct_tailcall = true; if(ci->_vargs.size) PopVarArgs(ci->_vargs); for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); @@ -741,7 +770,7 @@ common_call: _GUARD(gen->Yield(this)); Return(1, ct_target, clo); STK(ct_target) = gen; - while (last_top >= _top) _stack._vals[last_top--].Null(); + CLEARSTACK(last_top); continue; } } @@ -1022,7 +1051,7 @@ exception_trap: _stackbase = et._stackbase; _stack._vals[_stackbase+et._extarget] = currerror; _etraps.pop_back(); traps--; ci->_etraps--; - while(last_top >= _top) _stack._vals[last_top--].Null(); + CLEARSTACK(last_top); goto exception_restore; } //if is a native closure @@ -1050,7 +1079,7 @@ exception_trap: if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break; } while(_callsstacksize); - while(last_top >= _top) _stack._vals[last_top--].Null(); + CLEARSTACK(last_top); } _lasterror = currerror; return false; @@ -1062,8 +1091,6 @@ bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr { inst = theclass->CreateInstance(); if(!theclass->Get(_ss(this)->_constructoridx,constructor)) { - //if(!Call(constr,nargs,stackbase,constr,false)) - // return false; constructor = _null_; } return true; diff --git a/src/3rdparty/squirrel/squirrel/sqvm.h b/src/3rdparty/squirrel/squirrel/sqvm.h index 18c8681e7..7ba404564 100644 --- a/src/3rdparty/squirrel/squirrel/sqvm.h +++ b/src/3rdparty/squirrel/squirrel/sqvm.h @@ -53,7 +53,7 @@ struct SQVM : public CHAINABLE_OBJ typedef sqvector<CallInfo> CallInfoVec; public: - enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_OPENTTD }; + enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_THROW_VM, ET_RESUME_OPENTTD }; SQVM(SQSharedState *ss); ~SQVM(); bool Init(SQVM *friendvm, SQInteger stacksize); @@ -108,6 +108,7 @@ public: _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix); void PopVarArgs(VarArgs &vargs); + void ClearStack(SQInteger last_top); #ifdef _DEBUG_DUMP void dumpstack(SQInteger stackbase=-1, bool dumpall = false); #endif |