summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryexo <yexo@openttd.org>2009-08-15 21:21:52 +0000
committeryexo <yexo@openttd.org>2009-08-15 21:21:52 +0000
commit03d711add39db01cde68821d879fe4da14db6300 (patch)
tree8cc353d66aadf9bf022d836d2358b7d70c9b655d
parent75f8a9db0adcb89a24f4624907298b87196ba26f (diff)
downloadopenttd-03d711add39db01cde68821d879fe4da14db6300.tar.xz
(svn r17195) -Update: squirrel to 2.2.3 stable
-rw-r--r--src/3rdparty/squirrel/COMPILE2
-rw-r--r--src/3rdparty/squirrel/COPYRIGHT2
-rw-r--r--src/3rdparty/squirrel/HISTORY14
-rw-r--r--src/3rdparty/squirrel/README2
-rw-r--r--src/3rdparty/squirrel/include/sqstdstring.h2
-rw-r--r--src/3rdparty/squirrel/include/squirrel.h34
-rw-r--r--src/3rdparty/squirrel/sq/sq.c3
-rw-r--r--src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp5
-rw-r--r--src/3rdparty/squirrel/sqstdlib/sqstdstring.cpp25
-rw-r--r--src/3rdparty/squirrel/squirrel/sqapi.cpp6
-rw-r--r--src/3rdparty/squirrel/squirrel/sqbaselib.cpp5
-rw-r--r--src/3rdparty/squirrel/squirrel/sqcompiler.cpp17
-rw-r--r--src/3rdparty/squirrel/squirrel/sqdebug.cpp17
-rw-r--r--src/3rdparty/squirrel/squirrel/sqfuncstate.cpp2
-rw-r--r--src/3rdparty/squirrel/squirrel/sqobject.h24
-rw-r--r--src/3rdparty/squirrel/squirrel/sqvm.cpp49
-rw-r--r--src/3rdparty/squirrel/squirrel/sqvm.h3
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