1
0
Fork 0

(svn r17195) -Update: squirrel to 2.2.3 stable

release/1.0
yexo 2009-08-15 21:21:52 +00:00
parent 75f8a9db0a
commit 03d711add3
17 changed files with 177 additions and 35 deletions

View File

@ -1,4 +1,4 @@
Squirrel 2.2.1 stable Squirrel 2.2.3 stable
-------------------------------------------------------- --------------------------------------------------------
What is in this distribution? What is in this distribution?

View File

@ -1,4 +1,4 @@
Copyright (c) 2003-2008 Alberto Demichelis Copyright (c) 2003-2009 Alberto Demichelis
This software is provided 'as-is', without any This software is provided 'as-is', without any
express or implied warranty. In no event will the express or implied warranty. In no event will the

View File

@ -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*** ***version 2.2.2 stable***
-fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident) -fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident)
-fixed coroutine error propagation -fixed coroutine error propagation

View File

@ -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 The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and

View File

@ -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 SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp); 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); SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2003-2008 Alberto Demichelis Copyright (c) 2003-2009 Alberto Demichelis
This software is provided 'as-is', without any This software is provided 'as-is', without any
express or implied warranty. In no event will the 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 #endif
#ifdef SQUSEDOUBLE
typedef double SQFloat;
#else
typedef float SQFloat; 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 void* SQUserPointer;
typedef SQUnsignedInteger SQBool; typedef SQUnsignedInteger SQBool;
typedef SQInteger SQRESULT; typedef SQInteger SQRESULT;
@ -159,8 +176,8 @@ typedef char SQChar;
#define MAX_CHAR 0xFF #define MAX_CHAR 0xFF
#endif #endif
#define SQUIRREL_VERSION _SC("Squirrel 2.2.2 stable - With custom OpenTTD modifications") #define SQUIRREL_VERSION _SC("Squirrel 2.2.3 stable - With custom OpenTTD modifications")
#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2008 Alberto Demichelis") #define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2009 Alberto Demichelis")
#define SQUIRREL_AUTHOR _SC("Alberto Demichelis") #define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
#define SQ_VMSTATE_IDLE 0 #define SQ_VMSTATE_IDLE 0
@ -240,6 +257,7 @@ typedef union tagSQObjectValue
struct SQClass *pClass; struct SQClass *pClass;
struct SQInstance *pInstance; struct SQInstance *pInstance;
struct SQWeakRef *pWeakRef; struct SQWeakRef *pWeakRef;
SQRawObjectVal raw;
}SQObjectValue; }SQObjectValue;
@ -274,6 +292,13 @@ typedef struct tagSQRegFunction{
const SQChar *typemask; const SQChar *typemask;
}SQRegFunction; }SQRegFunction;
typedef struct tagSQFunctionInfo {
SQUserPointer funcid;
const SQChar *name;
const SQChar *source;
}SQFunctionInfo;
/*vm*/ /*vm*/
SQUIRREL_API bool sq_can_suspend(HSQUIRRELVM v); SQUIRREL_API bool sq_can_suspend(HSQUIRRELVM v);
SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); 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 SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
SQUIRREL_API bool sq_resumecatch(HSQUIRRELVM v, int suspend = -1); 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); SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
/*compiler*/ /*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 SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); 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_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_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);

View File

@ -59,6 +59,9 @@ void printfunc(HSQUIRRELVM v,const SQChar *s,...)
void PrintVersionInfos() void PrintVersionInfos()
{ {
scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,sizeof(SQInteger)*8); 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() void PrintUsage()

View File

@ -9,6 +9,7 @@ void sqstd_printcallstack(HSQUIRRELVM v)
if(pf) { if(pf) {
SQStackInfos si; SQStackInfos si;
SQInteger i; SQInteger i;
SQBool b;
SQFloat f; SQFloat f;
const SQChar *s; const SQChar *s;
SQInteger level=1; //1 is to skip this function that is level 0 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); pf(v,_SC("[%s] WEAKREF\n"),name);
break; break;
case OT_BOOL:{ case OT_BOOL:{
sq_getinteger(v,-1,&i); sq_getbool(v,-1,&b);
pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false")); pf(v,_SC("[%s] %s\n"),name,b?_SC("true"):_SC("false"));
} }
break; break;
default: assert(0); break; default: assert(0); break;

View File

@ -79,15 +79,16 @@ static void _append_string(SQInteger &i, SQChar *dest, SQInteger allocated, cons
va_end(va); va_end(va);
} }
static SQInteger _string_format(HSQUIRRELVM v)
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{ {
const SQChar *format; const SQChar *format;
SQChar *dest; SQChar *dest;
SQChar fmt[MAX_FORMAT_LEN]; SQChar fmt[MAX_FORMAT_LEN];
sq_getstring(v,2,&format); sq_getstring(v,nformatstringidx,&format);
SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar); SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
dest = sq_getscratchpad(v,allocated); 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') { while(format[n] != '\0') {
if(format[n] != '%') { if(format[n] != '%') {
assert(i < allocated); assert(i < allocated);
@ -132,7 +133,7 @@ static SQInteger _string_format(HSQUIRRELVM v)
return sq_throwerror(v,_SC("invalid format")); return sq_throwerror(v,_SC("invalid format"));
} }
n++; n++;
allocated += addlen; allocated += addlen + sizeof(SQChar);
dest = sq_getscratchpad(v,allocated); dest = sq_getscratchpad(v,allocated);
switch(valtype) { switch(valtype) {
case 's': _append_string(i,dest,allocated,fmt,ts); break; case 's': _append_string(i,dest,allocated,fmt,ts); break;
@ -142,7 +143,19 @@ static SQInteger _string_format(HSQUIRRELVM v)
nparam ++; 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; return 1;
} }

View File

@ -984,7 +984,7 @@ SQRESULT sq_suspendvm(HSQUIRRELVM v)
return v->Suspend(); 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; SQObjectPtr ret;
if(!v->_suspended) if(!v->_suspended)
@ -994,8 +994,10 @@ SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseer
v->Pop(); v->Pop();
} else v->GetAt(v->_stackbase+v->_suspended_target)=_null_; } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
v->_can_suspend = false; 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; return SQ_ERROR;
if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {
while (v->_top > 1) v->_stack[--v->_top] = _null_;
} }
if(retval) if(retval)
v->Push(ret); v->Push(ret);

View File

@ -277,6 +277,9 @@ void sq_base_register(HSQUIRRELVM v)
sq_pushstring(v,_SC("_intsize_"),-1); sq_pushstring(v,_SC("_intsize_"),-1);
sq_pushinteger(v,sizeof(SQInteger)); sq_pushinteger(v,sizeof(SQInteger));
sq_createslot(v,-3); sq_createslot(v,-3);
sq_pushstring(v,_SC("_floatsize_"),-1);
sq_pushinteger(v,sizeof(SQFloat));
sq_createslot(v,-3);
sq_pop(v,1); sq_pop(v,1);
} }
@ -815,7 +818,7 @@ static SQInteger thread_wakeup(HSQUIRRELVM v)
if(wakeupret) { if(wakeupret) {
sq_move(thread,v,2); 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_move(v,thread,-1);
sq_pop(thread,1); //pop retval sq_pop(thread,1); //pop retval
if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {

View File

@ -1110,6 +1110,23 @@ public:
case TK_STRING_LITERAL: case TK_STRING_LITERAL:
val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
break; 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: default:
Error(_SC("scalar expected : integer,float or string")); Error(_SC("scalar expected : integer,float or string"));
val._type = OT_NULL; // Silent compile-warning val._type = OT_NULL; // Silent compile-warning

View File

@ -9,6 +9,23 @@
#include "sqclosure.h" #include "sqclosure.h"
#include "sqstring.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) SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
{ {
SQInteger cssize = v->_callsstacksize; SQInteger cssize = v->_callsstacksize;

View File

@ -86,7 +86,7 @@ void DumpLiteral(SQObjectPtr &o)
case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break; case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
#endif #endif
case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; 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
} }
} }

View File

@ -117,7 +117,7 @@ struct SQObjectPtr;
#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
#define _weakref(obj) ((obj)._unVal.pWeakRef) #define _weakref(obj) ((obj)._unVal.pWeakRef)
#define _refcounted(obj) ((obj)._unVal.pRefCounted) #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 _stringval(obj) (obj)._unVal.pString->_val
#define _userdataval(obj) (obj)._unVal.pUserData->_val #define _userdataval(obj) (obj)._unVal.pUserData->_val
@ -130,23 +130,27 @@ struct SQObjectPtr : public SQObject
{ {
SQObjectPtr() SQObjectPtr()
{ {
SQ_OBJECT_RAWINIT()
_type=OT_NULL; _type=OT_NULL;
_unVal.pUserPointer=NULL; _unVal.pUserPointer=NULL;
} }
SQObjectPtr(const SQObjectPtr &o) SQObjectPtr(const SQObjectPtr &o)
{ {
SQ_OBJECT_RAWINIT()
_type=o._type; _type=o._type;
_unVal=o._unVal; _unVal=o._unVal;
__AddRef(_type,_unVal); __AddRef(_type,_unVal);
} }
SQObjectPtr(const SQObject &o) SQObjectPtr(const SQObject &o)
{ {
SQ_OBJECT_RAWINIT()
_type=o._type; _type=o._type;
_unVal=o._unVal; _unVal=o._unVal;
__AddRef(_type,_unVal); __AddRef(_type,_unVal);
} }
SQObjectPtr(SQTable *pTable) SQObjectPtr(SQTable *pTable)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_TABLE; _type=OT_TABLE;
_unVal.pTable=pTable; _unVal.pTable=pTable;
assert(_unVal.pTable); assert(_unVal.pTable);
@ -154,6 +158,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQClass *pClass) SQObjectPtr(SQClass *pClass)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_CLASS; _type=OT_CLASS;
_unVal.pClass=pClass; _unVal.pClass=pClass;
assert(_unVal.pClass); assert(_unVal.pClass);
@ -161,6 +166,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQInstance *pInstance) SQObjectPtr(SQInstance *pInstance)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_INSTANCE; _type=OT_INSTANCE;
_unVal.pInstance=pInstance; _unVal.pInstance=pInstance;
assert(_unVal.pInstance); assert(_unVal.pInstance);
@ -168,6 +174,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQArray *pArray) SQObjectPtr(SQArray *pArray)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_ARRAY; _type=OT_ARRAY;
_unVal.pArray=pArray; _unVal.pArray=pArray;
assert(_unVal.pArray); assert(_unVal.pArray);
@ -175,6 +182,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQClosure *pClosure) SQObjectPtr(SQClosure *pClosure)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_CLOSURE; _type=OT_CLOSURE;
_unVal.pClosure=pClosure; _unVal.pClosure=pClosure;
assert(_unVal.pClosure); assert(_unVal.pClosure);
@ -182,6 +190,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQGenerator *pGenerator) SQObjectPtr(SQGenerator *pGenerator)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_GENERATOR; _type=OT_GENERATOR;
_unVal.pGenerator=pGenerator; _unVal.pGenerator=pGenerator;
assert(_unVal.pGenerator); assert(_unVal.pGenerator);
@ -189,6 +198,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQNativeClosure *pNativeClosure) SQObjectPtr(SQNativeClosure *pNativeClosure)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_NATIVECLOSURE; _type=OT_NATIVECLOSURE;
_unVal.pNativeClosure=pNativeClosure; _unVal.pNativeClosure=pNativeClosure;
assert(_unVal.pNativeClosure); assert(_unVal.pNativeClosure);
@ -196,6 +206,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQString *pString) SQObjectPtr(SQString *pString)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_STRING; _type=OT_STRING;
_unVal.pString=pString; _unVal.pString=pString;
assert(_unVal.pString); assert(_unVal.pString);
@ -203,6 +214,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQUserData *pUserData) SQObjectPtr(SQUserData *pUserData)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_USERDATA; _type=OT_USERDATA;
_unVal.pUserData=pUserData; _unVal.pUserData=pUserData;
assert(_unVal.pUserData); assert(_unVal.pUserData);
@ -210,6 +222,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQVM *pThread) SQObjectPtr(SQVM *pThread)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_THREAD; _type=OT_THREAD;
_unVal.pThread=pThread; _unVal.pThread=pThread;
assert(_unVal.pThread); assert(_unVal.pThread);
@ -217,6 +230,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQWeakRef *pWeakRef) SQObjectPtr(SQWeakRef *pWeakRef)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_WEAKREF; _type=OT_WEAKREF;
_unVal.pWeakRef=pWeakRef; _unVal.pWeakRef=pWeakRef;
assert(_unVal.pWeakRef); assert(_unVal.pWeakRef);
@ -224,6 +238,7 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQFunctionProto *pFunctionProto) SQObjectPtr(SQFunctionProto *pFunctionProto)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_FUNCPROTO; _type=OT_FUNCPROTO;
_unVal.pFunctionProto=pFunctionProto; _unVal.pFunctionProto=pFunctionProto;
assert(_unVal.pFunctionProto); assert(_unVal.pFunctionProto);
@ -231,24 +246,25 @@ struct SQObjectPtr : public SQObject
} }
SQObjectPtr(SQInteger nInteger) SQObjectPtr(SQInteger nInteger)
{ {
_unVal.pUserPointer=NULL; SQ_OBJECT_RAWINIT()
_type=OT_INTEGER; _type=OT_INTEGER;
_unVal.nInteger=nInteger; _unVal.nInteger=nInteger;
} }
SQObjectPtr(SQFloat fFloat) SQObjectPtr(SQFloat fFloat)
{ {
_unVal.pUserPointer=NULL; SQ_OBJECT_RAWINIT()
_type=OT_FLOAT; _type=OT_FLOAT;
_unVal.fFloat=fFloat; _unVal.fFloat=fFloat;
} }
SQObjectPtr(bool bBool) SQObjectPtr(bool bBool)
{ {
_unVal.pUserPointer=NULL; SQ_OBJECT_RAWINIT()
_type = OT_BOOL; _type = OT_BOOL;
_unVal.nInteger = bBool?1:0; _unVal.nInteger = bBool?1:0;
} }
SQObjectPtr(SQUserPointer pUserPointer) SQObjectPtr(SQUserPointer pUserPointer)
{ {
SQ_OBJECT_RAWINIT()
_type=OT_USERPOINTER; _type=OT_USERPOINTER;
_unVal.pUserPointer=pUserPointer; _unVal.pUserPointer=pUserPointer;
} }

View File

@ -17,6 +17,21 @@
#define TOP() (_stack._vals[_top-1]) #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) bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
{ {
SQInteger res; SQInteger res;
@ -50,7 +65,9 @@ bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,
res = i1 / i2; res = i1 / i2;
break; break;
case '*': 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; default: res = 0xDEADBEEF;
} }
trg = res; trg = res;
@ -288,12 +305,10 @@ void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
{ {
_stack.resize(stacksize); _stack.resize(stacksize);
//_callsstack.reserve(4);
_alloccallsstacksize = 4; _alloccallsstacksize = 4;
_callstackdata.resize(_alloccallsstacksize); _callstackdata.resize(_alloccallsstacksize);
_callsstacksize = 0; _callsstacksize = 0;
_callsstack = &_callstackdata[0]; _callsstack = &_callstackdata[0];
//_callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo));
_stackbase = 0; _stackbase = 0;
_top = 0; _top = 0;
if(!friendvm) if(!friendvm)
@ -672,20 +687,34 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn
bool ct_tailcall; bool ct_tailcall;
switch(et) { switch(et) {
case ET_CALL: case ET_CALL: {
if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) { 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 //call the handler if there are no calls in the stack, if not relies on the previous node
if(ci == NULL) CallErrorHandler(_lasterror); if(ci == NULL) CallErrorHandler(_lasterror);
return false; 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; ci->_root = SQTrue;
}
break; break;
case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break; case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
case ET_RESUME_VM: case ET_RESUME_VM:
case ET_RESUME_THROW_VM:
traps = _suspended_traps; traps = _suspended_traps;
ci->_root = _suspended_root; ci->_root = _suspended_root;
ci->_vargs = _suspend_varargs; ci->_vargs = _suspend_varargs;
_suspended = SQFalse; _suspended = SQFalse;
if(et == ET_RESUME_THROW_VM) { SQ_THROW(); }
break; break;
case ET_RESUME_OPENTTD: case ET_RESUME_OPENTTD:
traps = _suspended_traps; traps = _suspended_traps;
@ -716,7 +745,7 @@ exception_restore:
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
case _OP_TAILCALL: case _OP_TAILCALL:
temp_reg = STK(arg1); 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; ct_tailcall = true;
if(ci->_vargs.size) PopVarArgs(ci->_vargs); if(ci->_vargs.size) PopVarArgs(ci->_vargs);
for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
@ -741,7 +770,7 @@ common_call:
_GUARD(gen->Yield(this)); _GUARD(gen->Yield(this));
Return(1, ct_target, clo); Return(1, ct_target, clo);
STK(ct_target) = gen; STK(ct_target) = gen;
while (last_top >= _top) _stack._vals[last_top--].Null(); CLEARSTACK(last_top);
continue; continue;
} }
} }
@ -1022,7 +1051,7 @@ exception_trap:
_stackbase = et._stackbase; _stackbase = et._stackbase;
_stack._vals[_stackbase+et._extarget] = currerror; _stack._vals[_stackbase+et._extarget] = currerror;
_etraps.pop_back(); traps--; ci->_etraps--; _etraps.pop_back(); traps--; ci->_etraps--;
while(last_top >= _top) _stack._vals[last_top--].Null(); CLEARSTACK(last_top);
goto exception_restore; goto exception_restore;
} }
//if is a native closure //if is a native closure
@ -1050,7 +1079,7 @@ exception_trap:
if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break; if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
} while(_callsstacksize); } while(_callsstacksize);
while(last_top >= _top) _stack._vals[last_top--].Null(); CLEARSTACK(last_top);
} }
_lasterror = currerror; _lasterror = currerror;
return false; return false;
@ -1062,8 +1091,6 @@ bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr
{ {
inst = theclass->CreateInstance(); inst = theclass->CreateInstance();
if(!theclass->Get(_ss(this)->_constructoridx,constructor)) { if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
//if(!Call(constr,nargs,stackbase,constr,false))
// return false;
constructor = _null_; constructor = _null_;
} }
return true; return true;

View File

@ -53,7 +53,7 @@ struct SQVM : public CHAINABLE_OBJ
typedef sqvector<CallInfo> CallInfoVec; typedef sqvector<CallInfo> CallInfoVec;
public: 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(SQSharedState *ss);
~SQVM(); ~SQVM();
bool Init(SQVM *friendvm, SQInteger stacksize); 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 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); _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
void PopVarArgs(VarArgs &vargs); void PopVarArgs(VarArgs &vargs);
void ClearStack(SQInteger last_top);
#ifdef _DEBUG_DUMP #ifdef _DEBUG_DUMP
void dumpstack(SQInteger stackbase=-1, bool dumpall = false); void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
#endif #endif