From eb4c8443d15d5ad31b2dfa494d9828992ba38db6 Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Wed, 2 Apr 2008 18:13:45 +0000 Subject: [PATCH] Upgraded to Squirrel 2.2 SVN-Revision: 5382 --- src/squirrel/COPYRIGHT | 2 +- src/squirrel/HISTORY | 10 +++ src/squirrel/README | 4 +- src/squirrel/include/sqstdio.h | 4 -- src/squirrel/include/squirrel.h | 11 ++-- src/squirrel/sqstdlib/sqstdaux.cpp | 2 +- src/squirrel/sqstdlib/sqstdio.cpp | 2 +- src/squirrel/sqstdlib/sqstdmath.cpp | 3 +- src/squirrel/sqstdlib/sqstdstring.cpp | 2 +- src/squirrel/squirrel/sqapi.cpp | 22 ++++++- src/squirrel/squirrel/sqbaselib.cpp | 32 +++++++-- src/squirrel/squirrel/sqclosure.h | 2 + src/squirrel/squirrel/sqcompiler.cpp | 120 +++++++++++++++++++++++++++++++++- src/squirrel/squirrel/sqcompiler.h | 2 + src/squirrel/squirrel/sqfuncproto.h | 15 +++-- src/squirrel/squirrel/sqfuncstate.cpp | 23 ++++++- src/squirrel/squirrel/sqfuncstate.h | 5 ++ src/squirrel/squirrel/sqlexer.cpp | 42 ++++++++++-- src/squirrel/squirrel/sqlexer.h | 2 +- src/squirrel/squirrel/sqobject.cpp | 54 ++++++++++++++- src/squirrel/squirrel/sqobject.h | 3 + src/squirrel/squirrel/sqstate.cpp | 53 ++++++++------- src/squirrel/squirrel/sqstate.h | 1 + src/squirrel/squirrel/sqvm.cpp | 104 +++++++++++++---------------- src/squirrel/squirrel/sqvm.h | 2 - 25 files changed, 396 insertions(+), 126 deletions(-) diff --git a/src/squirrel/COPYRIGHT b/src/squirrel/COPYRIGHT index 31e565af7..8bd208195 100644 --- a/src/squirrel/COPYRIGHT +++ b/src/squirrel/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright (c) 2003-2007 Alberto Demichelis +Copyright (c) 2003-2008 Alberto Demichelis This software is provided 'as-is', without any express or implied warranty. In no event will the diff --git a/src/squirrel/HISTORY b/src/squirrel/HISTORY index a76d0ff6d..718834b89 100644 --- a/src/squirrel/HISTORY +++ b/src/squirrel/HISTORY @@ -1,3 +1,13 @@ +***version 2.2 stable*** +-added _newslot metamethod in classes +-added enums added constants +-added sq_pushconsttable, sq_setconsttable +-added default param +-added octal literals(thx Dinosaur) +-fixed debug hook, 'calls' and 'returns' are properly notified in the same number. +-fixed a coroutine bug + +***2007-07-29 *** ***version 2.1.2 stable*** -new behaviour for generators iteration using foreach now when a generator is iterated by foreach the value returned by a 'return val' statement diff --git a/src/squirrel/README b/src/squirrel/README index 3d984d9ee..759c6efba 100644 --- a/src/squirrel/README +++ b/src/squirrel/README @@ -1,4 +1,4 @@ -The programming language SQUIRREL 2.1.2 stable +The programming language SQUIRREL 2.2 stable -------------------------------------------------- The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and @@ -16,7 +16,7 @@ Feedback and suggestions are appreciated project page - http://www.squirrel-lang.org community forums - http://www.squirrel-lang.org/Forums wiki - http://wiki.squirrel-lang.org -author - alberto@ademichelis.com +author - alberto@demichelis.net END OF README diff --git a/src/squirrel/include/sqstdio.h b/src/squirrel/include/sqstdio.h index 6da1872e7..2cb744bcf 100644 --- a/src/squirrel/include/sqstdio.h +++ b/src/squirrel/include/sqstdio.h @@ -7,10 +7,6 @@ #define SQSTD_STREAM_TYPE_TAG 0x80000000 struct SQStream { - - // [SuperTux] Added virtual destructor to avoid compiler warnings - 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 515031210..d164400d1 100644 --- a/src/squirrel/include/squirrel.h +++ b/src/squirrel/include/squirrel.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2007 Alberto Demichelis +Copyright (c) 2003-2008 Alberto Demichelis This software is provided 'as-is', without any express or implied warranty. In no event will the @@ -57,6 +57,7 @@ typedef unsigned int SQUnsignedInteger; typedef unsigned int SQHash; /*should be the same size of a pointer*/ #endif + typedef float SQFloat; typedef void* SQUserPointer; typedef SQUnsignedInteger SQBool; @@ -65,7 +66,6 @@ typedef SQInteger SQRESULT; #define SQTrue (1) #define SQFalse (0) - struct SQVM; struct SQTable; struct SQArray; @@ -136,8 +136,8 @@ typedef char SQChar; #define MAX_CHAR 0xFF #endif -#define SQUIRREL_VERSION _SC("Squirrel 2.1.2 stable") -#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2007 Alberto Demichelis") +#define SQUIRREL_VERSION _SC("Squirrel 2.2 stable") +#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2008 Alberto Demichelis") #define SQUIRREL_AUTHOR _SC("Alberto Demichelis") #define SQ_VMSTATE_IDLE 0 @@ -316,6 +316,7 @@ SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedIn 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_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize); SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase); SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx); @@ -327,7 +328,9 @@ SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t); /*object manipulation*/ SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v); SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v); SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); diff --git a/src/squirrel/sqstdlib/sqstdaux.cpp b/src/squirrel/sqstdlib/sqstdaux.cpp index 6d3ea31a7..f02471359 100644 --- a/src/squirrel/sqstdlib/sqstdaux.cpp +++ b/src/squirrel/sqstdlib/sqstdaux.cpp @@ -65,7 +65,7 @@ void sqstd_printcallstack(HSQUIRRELVM v) pf(v,_SC("[%s] NATIVECLOSURE\n"),name); break; case OT_GENERATOR: - pf(v,_SC("[%s] NATIVECLOSURE\n"),name); + pf(v,_SC("[%s] GENERATOR\n"),name); break; case OT_USERDATA: pf(v,_SC("[%s] USERDATA\n"),name); diff --git a/src/squirrel/sqstdlib/sqstdio.cpp b/src/squirrel/sqstdlib/sqstdio.cpp index 81ed73278..4a0a18400 100644 --- a/src/squirrel/sqstdlib/sqstdio.cpp +++ b/src/squirrel/sqstdlib/sqstdio.cpp @@ -9,7 +9,7 @@ //basic API SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) { -#ifndef _UNICODE +#ifndef SQUNICODE return (SQFILE)fopen(filename,mode); #else return (SQFILE)_wfopen(filename,mode); diff --git a/src/squirrel/sqstdlib/sqstdmath.cpp b/src/squirrel/sqstdlib/sqstdmath.cpp index 2ad9f028f..69c46f516 100644 --- a/src/squirrel/sqstdlib/sqstdmath.cpp +++ b/src/squirrel/sqstdlib/sqstdmath.cpp @@ -22,7 +22,8 @@ static SQInteger math_srand(HSQUIRRELVM v) { SQInteger i; - if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param")); + if(SQ_FAILED(sq_getinteger(v,2,&i))) + return sq_throwerror(v,_SC("invalid param")); srand((unsigned int)i); return 0; } diff --git a/src/squirrel/sqstdlib/sqstdstring.cpp b/src/squirrel/sqstdlib/sqstdstring.cpp index 31735e133..58e935fa8 100644 --- a/src/squirrel/sqstdlib/sqstdstring.cpp +++ b/src/squirrel/sqstdlib/sqstdstring.cpp @@ -7,7 +7,7 @@ #include #include -#ifdef _UNICODE +#ifdef SQUNICODE #define scstrchr wcschr #define scsnprintf wsnprintf #define scatoi _wtoi diff --git a/src/squirrel/squirrel/sqapi.cpp b/src/squirrel/squirrel/sqapi.cpp index d6b08a7b9..ff461e77b 100644 --- a/src/squirrel/squirrel/sqapi.cpp +++ b/src/squirrel/squirrel/sqapi.cpp @@ -425,6 +425,11 @@ void sq_pushregistrytable(HSQUIRRELVM v) v->Push(_ss(v)->_registry); } +void sq_pushconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); +} + SQRESULT sq_setroottable(HSQUIRRELVM v) { SQObject o = stack_get(v, -1); @@ -436,6 +441,17 @@ SQRESULT sq_setroottable(HSQUIRRELVM v) return sq_throwerror(v, _SC("ivalid type")); } +SQRESULT sq_setconsttable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o)) { + _ss(v)->_consts = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type, expected table")); +} + void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) { v->_foreignptr = p; @@ -635,7 +651,7 @@ void sq_settop(HSQUIRRELVM v, SQInteger newtop) if(top > newtop) sq_pop(v, top - newtop); else - while(top < newtop) sq_pushnull(v); + while(top++ < newtop) sq_pushnull(v); } void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) @@ -916,7 +932,9 @@ SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) { SQObjectPtr res; if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ - v->Pop(params);//pop closure and args + if(!v->_suspended) { + v->Pop(params);//pop closure and args + } if(retval){ v->Push(res); return SQ_OK; } diff --git a/src/squirrel/squirrel/sqbaselib.cpp b/src/squirrel/squirrel/sqbaselib.cpp index ee49b2d17..cda52dae7 100644 --- a/src/squirrel/squirrel/sqbaselib.cpp +++ b/src/squirrel/squirrel/sqbaselib.cpp @@ -49,6 +49,13 @@ static SQInteger base_getroottable(HSQUIRRELVM v) return 1; } +static SQInteger base_getconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); + return 1; +} + + static SQInteger base_setroottable(HSQUIRRELVM v) { SQObjectPtr &o=stack_get(v,2); @@ -57,6 +64,14 @@ static SQInteger base_setroottable(HSQUIRRELVM v) return 1; } +static SQInteger base_setconsttable(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + static SQInteger base_seterrorhandler(HSQUIRRELVM v) { sq_seterrorhandler(v); @@ -215,6 +230,8 @@ static SQRegFunction base_funcs[]={ {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, {_SC("getroottable"),base_getroottable,1, NULL}, {_SC("setroottable"),base_setroottable,2, NULL}, + {_SC("getconsttable"),base_getconsttable,1, NULL}, + {_SC("setconsttable"),base_setconsttable,2, NULL}, {_SC("assert"),base_assert,2, NULL}, {_SC("print"),base_print,2, NULL}, {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, @@ -525,9 +542,11 @@ static SQInteger array_slice(HSQUIRRELVM v) SQInteger sidx,eidx; SQObjectPtr o; if(get_slice_params(v,sidx,eidx,o)==-1)return -1; - if(sidx<0)sidx=_array(o)->Size()+sidx; - if(eidx<0)eidx=_array(o)->Size()+eidx; + SQInteger alen = _array(o)->Size(); + if(sidx < 0)sidx = alen + sidx; + if(eidx < 0)eidx = alen + eidx; if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > alen)return sq_throwerror(v,_SC("slice out of range")); SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); SQObjectPtr t; SQInteger count=0; @@ -565,10 +584,11 @@ static SQInteger string_slice(HSQUIRRELVM v) SQInteger sidx,eidx; SQObjectPtr o; if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; - if(sidx<0)sidx=_string(o)->_len+sidx; - if(eidx<0)eidx=_string(o)->_len+eidx; - if(eidx_len; + if(sidx < 0)sidx = slen + sidx; + if(eidx < 0)eidx = slen + eidx; + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > slen) return sq_throwerror(v,_SC("slice out of range")); v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); return 1; } diff --git a/src/squirrel/squirrel/sqclosure.h b/src/squirrel/squirrel/sqclosure.h index 1c9eaa94a..8db7ca232 100644 --- a/src/squirrel/squirrel/sqclosure.h +++ b/src/squirrel/squirrel/sqclosure.h @@ -22,6 +22,7 @@ public: SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function)); ret->_env = _env; ret->_outervalues.copy(_outervalues); + ret->_defaultparams.copy(_defaultparams); return ret; } ~SQClosure() @@ -37,6 +38,7 @@ public: SQObjectPtr _env; SQObjectPtr _function; SQObjectPtrVec _outervalues; + SQObjectPtrVec _defaultparams; }; ////////////////////////////////////////////// struct SQGenerator : public CHAINABLE_OBJ diff --git a/src/squirrel/squirrel/sqcompiler.cpp b/src/squirrel/squirrel/sqcompiler.cpp index 7137c535c..5c468e1b0 100644 --- a/src/squirrel/squirrel/sqcompiler.cpp +++ b/src/squirrel/squirrel/sqcompiler.cpp @@ -11,6 +11,7 @@ #include "sqfuncstate.h" #include "sqlexer.h" #include "sqvm.h" +#include "sqtable.h" #define DEREF_NO_DEREF -1 #define DEREF_FIELD -2 @@ -258,6 +259,9 @@ public: case TK_CLASS: ClassStatement(); break; + case TK_ENUM: + EnumStatement(); + break; case _SC('{'):{ SQInteger stacksize = _fs->GetStackSize(); Lex(); @@ -274,6 +278,19 @@ public: CommaExpr(); _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); break; + case TK_CONST: + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect('='); + SQObject val = ExpectScalar(); + OptionalSemicolon(); + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(strongid,SQObjectPtr(val)); + strongid.Null(); + } + break; default: CommaExpr(); _fs->PopTarget(); @@ -599,6 +616,7 @@ public: case TK_THIS:{ _exst._freevar = false; SQObject id; + SQObject constant; switch(_token) { case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; case TK_THIS: id = _fs->CreateString(_SC("this")); break; @@ -612,13 +630,43 @@ public: _exst._deref = _fs->PushTarget(); _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos); _exst._freevar = true; - } else { + } + else if(_fs->IsConstant(id,constant)) { //line 634 + SQObjectPtr constval; + SQObject constid; + if(type(constant) == OT_TABLE) { + Expect('.'); constid = Expect(TK_IDENTIFIER); + if(!_table(constant)->Get(constid,constval)) { + constval.Null(); + Error(_SC("invalid constant [%s.%s]"), _stringval(id),_stringval(constid)); + } + } + else { + constval = constant; + } + _exst._deref = _fs->PushTarget(); + SQObjectType ctype = type(constval); + if(ctype == OT_INTEGER && (_integer(constval) & (~0x7FFFFFFF)) == 0) { + _fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval)); + } + else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) { + SQFloat f = _float(constval); + _fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f)); + } + else { + _fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval)); + } + + _exst._freevar = true; + } + else { _fs->PushTarget(0); _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); if(NeedGet()) Emit2ArgsOP(_OP_GET); _exst._deref = DEREF_FIELD; } } + else{ _fs->PushTarget(pos); _exst._deref = pos; @@ -1038,6 +1086,62 @@ public: } else Error(_SC("cannot create a class in a local with the syntax(class )")); } + SQObject ExpectScalar() + { + SQObject val; + 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; + case TK_STRING_LITERAL: + val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + default: + Error(_SC("scalar expected : integer,float or string")); + } + Lex(); + return val; + } + void EnumStatement() + { + + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect(_SC('{')); + + SQObject table = _fs->CreateTable(); + SQInteger nval = 0; + while(_token != _SC('}')) { + SQObject key = Expect(TK_IDENTIFIER); + SQObject val; + if(_token == _SC('=')) { + Lex(); + val = ExpectScalar(); + } + else { + val._type = OT_INTEGER; + val._unVal.nInteger = nval++; + } + _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); + if(_token == ',') Lex(); + } + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + /*SQObjectPtr dummy; + if(enums->Get(strongid,dummy)) { + dummy.Null(); strongid.Null(); + Error(_SC("enumeration already exists")); + }*/ + enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); + strongid.Null(); + Lex(); + + } void TryCatchStatement() { SQObject exid; @@ -1131,8 +1235,10 @@ public: SQObject paramname; funcstate->AddParameter(_fs->CreateString(_SC("this"))); funcstate->_sourcename = _sourcename; + SQInteger defparams = 0; while(_token!=_SC(')')) { if(_token == TK_VARPARAMS) { + if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); funcstate->_varparams = true; Lex(); if(_token != _SC(')')) Error(_SC("expected ')'")); @@ -1141,11 +1247,23 @@ public: else { paramname = Expect(TK_IDENTIFIER); funcstate->AddParameter(paramname); + if(_token == _SC('=')) { + Lex(); + Expression(); + funcstate->AddDefaultParam(_fs->TopTarget()); + defparams++; + } + else { + if(defparams > 0) Error(_SC("expected '='")); + } if(_token == _SC(',')) Lex(); else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); } } Expect(_SC(')')); + for(SQInteger n = 0; n < defparams; n++) { + _fs->PopTarget(); + } //outer values if(_token == _SC(':')) { Lex(); Expect(_SC('(')); diff --git a/src/squirrel/squirrel/sqcompiler.h b/src/squirrel/squirrel/sqcompiler.h index ed2a89baa..dd55888b6 100644 --- a/src/squirrel/squirrel/sqcompiler.h +++ b/src/squirrel/squirrel/sqcompiler.h @@ -68,6 +68,8 @@ struct SQVM; #define TK_ATTR_OPEN 320 #define TK_ATTR_CLOSE 321 #define TK_STATIC 322 +#define TK_ENUM 323 +#define TK_CONST 324 typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); diff --git a/src/squirrel/squirrel/sqfuncproto.h b/src/squirrel/squirrel/sqfuncproto.h index 367b8183b..6092dbe30 100644 --- a/src/squirrel/squirrel/sqfuncproto.h +++ b/src/squirrel/squirrel/sqfuncproto.h @@ -53,11 +53,11 @@ typedef sqvector SQOuterVarVec; typedef sqvector SQLocalVarInfoVec; typedef sqvector SQLineInfoVec; -#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf) (sizeof(SQFunctionProto) \ +#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ - +(localinf*sizeof(SQLocalVarInfo))) + +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) #define _CONSTRUCT_VECTOR(type,size,ptr) { \ for(SQInteger n = 0; n < size; n++) { \ @@ -80,11 +80,11 @@ public: static SQFunctionProto *Create(SQInteger ninstructions, SQInteger nliterals,SQInteger nparameters, SQInteger nfunctions,SQInteger noutervalues, - SQInteger nlineinfos,SQInteger nlocalvarinfos) + SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) { SQFunctionProto *f; //I compact the whole class and members in a single memory allocation - f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos)); + f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); new (f) SQFunctionProto; f->_ninstructions = ninstructions; f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; @@ -99,6 +99,8 @@ public: f->_nlineinfos = nlineinfos; f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; f->_nlocalvarinfos = nlocalvarinfos; + f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; + f->_ndefaultparams = ndefaultparams; _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); @@ -115,7 +117,7 @@ public: _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); - SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos); + SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); this->~SQFunctionProto(); sq_vm_free(this,size); } @@ -147,6 +149,9 @@ public: SQInteger _noutervalues; SQOuterVar *_outervalues; + + SQInteger _ndefaultparams; + SQInteger *_defaultparams; SQInteger _ninstructions; SQInstruction _instructions[1]; diff --git a/src/squirrel/squirrel/sqfuncstate.cpp b/src/squirrel/squirrel/sqfuncstate.cpp index 962a6cd7a..d8354b004 100644 --- a/src/squirrel/squirrel/sqfuncstate.cpp +++ b/src/squirrel/squirrel/sqfuncstate.cpp @@ -80,7 +80,8 @@ void DumpLiteral(SQObjectPtr &o) case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break; - default: assert(0); break; //shut up compiler + 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 } } @@ -310,6 +311,16 @@ void SQFuncState::SetStackSize(SQInteger n) } } +bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) +{ + SQObjectPtr val; + if(_table(_sharedstate->_consts)->Get(name,val)) { + e = val; + return true; + } + return false; +} + bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) { if(stkpos>=_vlocals.size())return false; @@ -492,11 +503,18 @@ SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) return ns; } +SQObject SQFuncState::CreateTable() +{ + SQObjectPtr nt(SQTable::Create(_sharedstate,0)); + _table(_strings)->NewSlot(nt,(SQInteger)1); + return nt; +} + SQFunctionProto *SQFuncState::BuildProto() { SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(), _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), - _lineinfos.size(),_localvarinfos.size()); + _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); SQObjectPtr refidx,key,val; SQInteger idx; @@ -516,6 +534,7 @@ SQFunctionProto *SQFuncState::BuildProto() for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no]; for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no]; + for(SQUnsignedInteger no = 0; no < _defaultparams.size(); no++) f->_defaultparams[no] = _defaultparams[no]; memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); diff --git a/src/squirrel/squirrel/sqfuncstate.h b/src/squirrel/squirrel/sqfuncstate.h index 96eb5520b..c0bf1e5e9 100644 --- a/src/squirrel/squirrel/sqfuncstate.h +++ b/src/squirrel/squirrel/sqfuncstate.h @@ -22,6 +22,8 @@ struct SQFuncState void PopInstructions(SQInteger size){for(SQInteger i=0;i= _SC('0') && c <= _SC('7'); } + +void LexOctal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); + else { assert(0); } + } +} + SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } + + #define MAX_HEX_DIGITS (sizeof(SQInteger)*2) SQInteger SQLexer::ReadNumber() { @@ -380,18 +396,29 @@ SQInteger SQLexer::ReadNumber() #define TFLOAT 2 #define THEX 3 #define TSCIENTIFIC 4 +#define TOCTAL 5 SQInteger type = TINT, firstchar = CUR_CHAR; SQChar *sTemp; INIT_TEMP_STRING(); NEXT(); - if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) { - NEXT(); - type = THEX; - while(isxdigit(CUR_CHAR)) { - APPEND_CHAR(CUR_CHAR); + if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { + if(scisodigit(CUR_CHAR)) { + type = TOCTAL; + while(scisodigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); + } + else { NEXT(); + type = THEX; + while(isxdigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); } - if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); } else { APPEND_CHAR((int)firstchar); @@ -425,6 +452,9 @@ SQInteger SQLexer::ReadNumber() case THEX: LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; + case TOCTAL: + LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; } return 0; } diff --git a/src/squirrel/squirrel/sqlexer.h b/src/squirrel/squirrel/sqlexer.h index 52993e59a..eb3bc8737 100644 --- a/src/squirrel/squirrel/sqlexer.h +++ b/src/squirrel/squirrel/sqlexer.h @@ -2,7 +2,7 @@ #ifndef _SQLEXER_H_ #define _SQLEXER_H_ -#ifdef _UNICODE +#ifdef SQUNICODE typedef SQChar LexChar; #else typedef unsigned char LexChar; diff --git a/src/squirrel/squirrel/sqobject.cpp b/src/squirrel/squirrel/sqobject.cpp index 7bfc19de3..1e1a63872 100644 --- a/src/squirrel/squirrel/sqobject.cpp +++ b/src/squirrel/squirrel/sqobject.cpp @@ -11,6 +11,40 @@ #include "sqclass.h" #include "sqclosure.h" + +const SQChar *IdType2Name(SQObjectType type) +{ + switch(_RAW_TYPE(type)) + { + case _RT_NULL:return _SC("null"); + case _RT_INTEGER:return _SC("integer"); + case _RT_FLOAT:return _SC("float"); + case _RT_BOOL:return _SC("bool"); + case _RT_STRING:return _SC("string"); + case _RT_TABLE:return _SC("table"); + case _RT_ARRAY:return _SC("array"); + case _RT_GENERATOR:return _SC("generator"); + case _RT_CLOSURE: + case _RT_NATIVECLOSURE: + return _SC("function"); + case _RT_USERDATA: + case _RT_USERPOINTER: + return _SC("userdata"); + case _RT_THREAD: return _SC("thread"); + case _RT_FUNCPROTO: return _SC("function"); + case _RT_CLASS: return _SC("class"); + case _RT_INSTANCE: return _SC("instance"); + case _RT_WEAKREF: return _SC("weakref"); + default: + return NULL; + } +} + +const SQChar *GetTypeName(const SQObjectPtr &obj1) +{ + return IdType2Name(type(obj1)); +} + SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) { SQString *str=ADD_STRING(ss,s,len); @@ -148,6 +182,9 @@ bool SQGenerator::Resume(SQVM *v,SQInteger target) v->ci->_prevtop = (SQInt32)prevtop; v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase); _state=eRunning; + if (type(v->_debughook) != OT_NULL && _rawval(v->_debughook) != _rawval(v->ci->_closure)) + v->CallDebugHook(_SC('c')); + return true; } @@ -301,6 +338,7 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) SQInteger i,nliterals = _nliterals,nparameters = _nparameters; SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; + SQInteger ndefaultparams = _ndefaultparams; _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteObject(v,up,write,_sourcename)); _CHECK_IO(WriteObject(v,up,write,_name)); @@ -310,6 +348,7 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); + _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); @@ -342,6 +381,9 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams)); + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); @@ -358,7 +400,7 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr { SQInteger i, nliterals,nparameters; SQInteger noutervalues ,nlocalvarinfos ; - SQInteger nlineinfos,ninstructions ,nfunctions ; + SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; SQObjectPtr sourcename, name; SQObjectPtr o; _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); @@ -371,10 +413,13 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); + _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); + - SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos); + SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters, + nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); SQObjectPtr proto = f; //gets a ref in case of failure f->_sourcename = sourcename; f->_name = name; @@ -415,6 +460,9 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); @@ -425,6 +473,7 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); + ret = f; return true; } @@ -513,6 +562,7 @@ void SQClosure::Mark(SQCollectable **chain) { START_MARK() for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain); + for(SQUnsignedInteger i = 0; i < _defaultparams.size(); i++) SQSharedState::MarkObject(_defaultparams[i], chain); END_MARK() } diff --git a/src/squirrel/squirrel/sqobject.h b/src/squirrel/squirrel/sqobject.h index 02d59678e..271bf41df 100644 --- a/src/squirrel/squirrel/sqobject.h +++ b/src/squirrel/squirrel/sqobject.h @@ -344,6 +344,9 @@ struct SQDelegable : public CHAINABLE_OBJ { SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); typedef sqvector SQObjectPtrVec; typedef sqvector SQIntVec; +const SQChar *GetTypeName(const SQObjectPtr &obj1); +const SQChar *IdType2Name(SQObjectType type); + #endif //_SQOBJECT_H_ diff --git a/src/squirrel/squirrel/sqstate.cpp b/src/squirrel/squirrel/sqstate.cpp index 150bb56e8..4a25ae177 100644 --- a/src/squirrel/squirrel/sqstate.cpp +++ b/src/squirrel/squirrel/sqstate.cpp @@ -145,26 +145,28 @@ void SQSharedState::Init() _constructoridx = SQString::Create(this,_SC("constructor")); _registry = SQTable::Create(this,0); - _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz); - _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz); - _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz); - _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz); - _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz); - _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz); - _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz); - _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz); - _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz); - _weakref_default_delegate=CreateDefaultDelegate(this,_weakref_default_delegate_funcz); + _consts = SQTable::Create(this,0); + _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); + _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); + _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); + _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); + _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); + _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); + _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); + _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); + _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); + _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); } SQSharedState::~SQSharedState() { _constructoridx = _null_; - _refs_table.Finalize(); _table(_registry)->Finalize(); + _table(_consts)->Finalize(); _table(_metamethodsmap)->Finalize(); _registry = _null_; + _consts = _null_; _metamethodsmap = _null_; while(!_systemstrings->empty()) { _systemstrings->back()=_null_; @@ -172,24 +174,24 @@ SQSharedState::~SQSharedState() } _thread(_root_vm)->Finalize(); _root_vm = _null_; - _table_default_delegate=_null_; - _array_default_delegate=_null_; - _string_default_delegate=_null_; - _number_default_delegate=_null_; - _closure_default_delegate=_null_; - _generator_default_delegate=_null_; - _thread_default_delegate=_null_; - _class_default_delegate=_null_; - _instance_default_delegate=_null_; - _weakref_default_delegate=_null_; - + _table_default_delegate = _null_; + _array_default_delegate = _null_; + _string_default_delegate = _null_; + _number_default_delegate = _null_; + _closure_default_delegate = _null_; + _generator_default_delegate = _null_; + _thread_default_delegate = _null_; + _class_default_delegate = _null_; + _instance_default_delegate = _null_; + _weakref_default_delegate = _null_; + _refs_table.Finalize(); #ifndef NO_GARBAGE_COLLECTOR - SQCollectable *t=_gc_chain; - SQCollectable *nx=NULL; + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; while(t) { t->_uiRef++; t->Finalize(); - nx=t->_next; + nx = t->_next; if(--t->_uiRef == 0) t->Release(); t=nx; @@ -249,6 +251,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm) SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed(); _refs_table.Mark(&tchain); MarkObject(_registry,&tchain); + MarkObject(_consts,&tchain); MarkObject(_metamethodsmap,&tchain); MarkObject(_table_default_delegate,&tchain); MarkObject(_array_default_delegate,&tchain); diff --git a/src/squirrel/squirrel/sqstate.h b/src/squirrel/squirrel/sqstate.h index fb6766510..a0b739c3e 100644 --- a/src/squirrel/squirrel/sqstate.h +++ b/src/squirrel/squirrel/sqstate.h @@ -73,6 +73,7 @@ public: StringTable *_stringtable; RefTable _refs_table; SQObjectPtr _registry; + SQObjectPtr _consts; SQObjectPtr _constructoridx; #ifndef NO_GARBAGE_COLLECTOR SQCollectable *_gc_chain; diff --git a/src/squirrel/squirrel/sqvm.cpp b/src/squirrel/squirrel/sqvm.cpp index 25ebcf984..4e96fbb8f 100644 --- a/src/squirrel/squirrel/sqvm.cpp +++ b/src/squirrel/squirrel/sqvm.cpp @@ -267,39 +267,6 @@ bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr & return true; } -const SQChar *IdType2Name(SQObjectType type) -{ - switch(_RAW_TYPE(type)) - { - case _RT_NULL:return _SC("null"); - case _RT_INTEGER:return _SC("integer"); - case _RT_FLOAT:return _SC("float"); - case _RT_BOOL:return _SC("bool"); - case _RT_STRING:return _SC("string"); - case _RT_TABLE:return _SC("table"); - case _RT_ARRAY:return _SC("array"); - case _RT_GENERATOR:return _SC("generator"); - case _RT_CLOSURE: - case _RT_NATIVECLOSURE: - return _SC("function"); - case _RT_USERDATA: - case _RT_USERPOINTER: - return _SC("userdata"); - case _RT_THREAD: return _SC("thread"); - case _RT_FUNCPROTO: return _SC("function"); - case _RT_CLASS: return _SC("class"); - case _RT_INSTANCE: return _SC("instance"); - case _RT_WEAKREF: return _SC("weakref"); - default: - return NULL; - } -} - -const SQChar *GetTypeName(const SQObjectPtr &obj1) -{ - return IdType2Name(type(obj1)); -} - void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) { if(is_delegable(obj1) && _delegable(obj1)->_delegate) { @@ -333,16 +300,22 @@ bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) extern SQInstructionDesc g_InstrDesc[]; -bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall) +bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) { SQFunctionProto *func = _funcproto(closure->_function); const SQInteger paramssize = func->_nparameters; const SQInteger newtop = stackbase + func->_stacksize; - - + SQInteger nargs = args; if (paramssize != nargs) { - if(func->_varparams) + SQInteger ndef = func->_ndefaultparams; + if(ndef && nargs < paramssize) { + SQInteger diff = paramssize - nargs; + for(SQInteger n = ndef - diff; n < ndef; n++) { + _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; + } + } + else if(func->_varparams) { if (nargs < paramssize) { Raise_Error(_SC("wrong number of parameters")); @@ -377,7 +350,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteg ci->_ncalls++; } ci->_vargs.size = (SQInt32)(nargs - paramssize); - ci->_vargs.base = (SQInt32) (_vargsstack.size()-(ci->_vargs.size)); + ci->_vargs.base = (SQInt32)(_vargsstack.size()-(ci->_vargs.size)); ci->_closure._unVal.pClosure = closure; ci->_closure._type = OT_CLOSURE; ci->_literals = func->_literals; @@ -389,6 +362,8 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteg _top = newtop; _stackbase = stackbase; + if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) + CallDebugHook(_SC('c')); return true; } @@ -579,6 +554,14 @@ bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) } } } + SQInteger ndefparams; + if((ndefparams = func->_ndefaultparams)) { + closure->_defaultparams.reserve(ndefparams); + for(SQInteger i = 0; i < ndefparams; i++) { + SQInteger spos = func->_defaultparams[i]; + closure->_defaultparams.push_back(_stack._vals[_stackbase + spos]); + } + } target = closure; return true; @@ -730,46 +713,41 @@ exception_restore: ct_stackbase = _stackbase+arg2; common_call: + SQObjectPtr clo = temp_reg; SQInteger last_top = _top; - switch (type(temp_reg)) { + switch (type(clo)) { case OT_CLOSURE:{ - _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_stackbase, ct_tailcall)); - if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) { - SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg)); + _GUARD(StartCall(_closure(clo), ct_target, arg3, ct_stackbase, ct_tailcall)); + if (_funcproto(_closure(clo)->_function)->_bgenerator) { + SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(clo)); _GUARD(gen->Yield(this)); - Return(1, ct_target, temp_reg); - - - - + Return(1, ct_target, clo); STK(ct_target) = gen; while (last_top >= _top) _stack._vals[last_top--].Null(); continue; } - if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) - CallDebugHook(_SC('c')); } continue; case OT_NATIVECLOSURE: { bool suspend; - _GUARD(CallNative(_nativeclosure(temp_reg), arg3, ct_stackbase, temp_reg,suspend)); + _GUARD(CallNative(_nativeclosure(clo), arg3, ct_stackbase, clo,suspend)); if(suspend){ _suspended = SQTrue; _suspended_target = ct_target; _suspended_root = ci->_root; _suspended_traps = traps; _suspend_varargs = ci->_vargs; - outres = temp_reg; + outres = clo; return true; } if(ct_target != -1) { //skip return value for constructors - STK(ct_target) = temp_reg; + STK(ct_target) = clo; } } continue; case OT_CLASS:{ SQObjectPtr inst; - _GUARD(CreateClassInstance(_class(temp_reg),inst,temp_reg)); + _GUARD(CreateClassInstance(_class(clo),inst,temp_reg)); STK(ct_target) = inst; ct_target = -1; //fakes return value target so that is not overwritten by the constructor if(type(temp_reg) != OT_NULL) { @@ -782,17 +760,17 @@ common_call: case OT_USERDATA: case OT_INSTANCE: { - Push(temp_reg); + Push(clo); for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); - if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){ - STK(ct_target) = temp_reg; + if (_delegable(clo) && CallMetaMethod(_delegable(clo), MT_CALL, arg3+1, clo)){ + STK(ct_target) = clo; break; } - Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg)); + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); SQ_THROW(); } default: - Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg)); + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); SQ_THROW(); } } @@ -1316,6 +1294,14 @@ bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObject if(rawcall) _table(self)->NewSlot(key,val); //cannot fail break;} + case OT_INSTANCE: { + SQObjectPtr res; + Push(self);Push(key);Push(val); + if(!CallMetaMethod(_instance(self),MT_NEWSLOT,3,res)) { + Raise_Error(_SC("class instances do not support the new slot operator")); + return false; + } + break;} case OT_CLASS: if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { if(_class(self)->_locked) { @@ -1475,7 +1461,7 @@ void SQVM::dumpstack(SQInteger stackbase,bool dumpall) case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; - case OT_GENERATOR: scprintf(_SC("GENERATOR"));break; + case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; diff --git a/src/squirrel/squirrel/sqvm.h b/src/squirrel/squirrel/sqvm.h index 89710ffd5..80bc594ca 100644 --- a/src/squirrel/squirrel/sqvm.h +++ b/src/squirrel/squirrel/sqvm.h @@ -173,8 +173,6 @@ struct AutoDec{ }; inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} -const SQChar *GetTypeName(const SQObjectPtr &obj1); -const SQChar *IdType2Name(SQObjectType type); #define _ss(_vm_) (_vm_)->_sharedstate -- 2.11.0