From 566f8eb2da26d5a2bb4ed5798a5774499f2e511f Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Sat, 3 Nov 2007 16:15:20 +0000 Subject: [PATCH] Upgrade to Squirrel 2.1.2 - Added upstream COPYRIGHT, HISTORY - Kept one custom patch. SVN-Revision: 5175 --- src/squirrel/COPYRIGHT | 29 ++++ src/squirrel/HISTORY | 304 ++++++++++++++++++++++++++++++++ src/squirrel/README | 88 +++------- src/squirrel/include/sqstdblob.h | 1 + src/squirrel/include/sqstdio.h | 4 + src/squirrel/include/sqstdstring.h | 3 - src/squirrel/include/squirrel.h | 61 ++++--- src/squirrel/sqstdlib/sqstdaux.cpp | 4 +- src/squirrel/sqstdlib/sqstdblob.cpp | 2 +- src/squirrel/sqstdlib/sqstdio.cpp | 18 +- src/squirrel/sqstdlib/sqstdmath.cpp | 4 +- src/squirrel/sqstdlib/sqstdrex.cpp | 191 ++++++++++---------- src/squirrel/sqstdlib/sqstdstream.cpp | 4 +- src/squirrel/sqstdlib/sqstdstring.cpp | 12 +- src/squirrel/squirrel/sqapi.cpp | 116 ++++++++----- src/squirrel/squirrel/sqbaselib.cpp | 38 +++- src/squirrel/squirrel/sqclass.cpp | 28 +-- src/squirrel/squirrel/sqclass.h | 36 ++-- src/squirrel/squirrel/sqclosure.h | 12 +- src/squirrel/squirrel/sqcompiler.cpp | 81 +++++---- src/squirrel/squirrel/sqdebug.cpp | 4 +- src/squirrel/squirrel/sqfuncproto.h | 91 ++++++++-- src/squirrel/squirrel/sqfuncstate.cpp | 56 +++--- src/squirrel/squirrel/sqfuncstate.h | 1 + src/squirrel/squirrel/sqlexer.cpp | 26 +-- src/squirrel/squirrel/sqobject.cpp | 161 +++++++++-------- src/squirrel/squirrel/sqobject.h | 28 ++- src/squirrel/squirrel/sqopcodes.h | 134 +++++++------- src/squirrel/squirrel/sqpcheader.h | 2 +- src/squirrel/squirrel/sqstate.cpp | 149 ++++++++-------- src/squirrel/squirrel/sqstate.h | 26 +-- src/squirrel/squirrel/sqtable.cpp | 22 ++- src/squirrel/squirrel/sqtable.h | 12 +- src/squirrel/squirrel/squserdata.h | 2 +- src/squirrel/squirrel/squtils.h | 6 +- src/squirrel/squirrel/sqvm.cpp | 318 ++++++++++++++++++---------------- src/squirrel/squirrel/sqvm.h | 59 ++++--- 37 files changed, 1339 insertions(+), 794 deletions(-) create mode 100644 src/squirrel/COPYRIGHT create mode 100644 src/squirrel/HISTORY diff --git a/src/squirrel/COPYRIGHT b/src/squirrel/COPYRIGHT new file mode 100644 index 000000000..31e565af7 --- /dev/null +++ b/src/squirrel/COPYRIGHT @@ -0,0 +1,29 @@ +Copyright (c) 2003-2007 Alberto Demichelis + +This software is provided 'as-is', without any +express or implied warranty. In no event will the +authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software +for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject +to the following restrictions: + + 1. The origin of this software must not be + misrepresented; you must not claim that + you wrote the original software. If you + use this software in a product, an + acknowledgment in the product + documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly + marked as such, and must not be + misrepresented as being the original + software. + + 3. This notice may not be removed or + altered from any source distribution. +----------------------------------------------------- +END OF COPYRIGHT \ No newline at end of file diff --git a/src/squirrel/HISTORY b/src/squirrel/HISTORY new file mode 100644 index 000000000..a76d0ff6d --- /dev/null +++ b/src/squirrel/HISTORY @@ -0,0 +1,304 @@ +***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 +will terminate the iteration but will not be returned as foreach iteration +-added sq_setclassudsize() +-added sq_clear() +-added table.clear(), array.clear() +-fixed sq_cmp() (thx jyuill) +-fixed minor bugs + +***2006-08-21 *** +***version 2.1.1 stable*** +-vm refactoring +-optimized internal function memory layout +-new global symbol _version_ (is the version string) +-code size optimization for float literals(on 32bits float builts) +-now the raw ref API(sq_addref etc...) is fully reentrant. +-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB) +-improved C reference performances in NO_GARBAGE_COLLECTOR builds +-sq_getlocal() now enumerates also outer values. +-fixed regexp library for GCC users. + +***2006-03-19 *** +***version 2.1 stable*** +-added static class fields, new keyword static +-added 64bits architecture support +-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds +-added functions with fixed environment, closure.bindenv() built-in function +-all types except userdata and null implement the tostring() method +-string concatenation now invokes metamethod _tostring +-new metamethods for class objects _newmember and _inherited +-sq_call() sq_resume() sq_wakeupvm() have a new signature +-new C referencing implementation(scales more with the amount of references) +-refactored hash table +-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv() +-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot +-sq_setreleasehook() now also works for classes +-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob) +-fixed squirrel.h undeclared api calls +-fixed few minor bugs +-SQChar is now defined as wchar_t +-removed warning when building with -Wall -pedantic for GCC users +-added new std io function writeclosuretofile() +-added new std string functions strip(),rstrip(),lstrip() and split() +-regular expressions operators (+,*) now have more POSIX greedyness behaviour +-class constructors are now invoked as normal functions + +***2005-10-02 *** +***version 2.0.5 stable*** +-fixed some 64bits incompatibilities (thx sarge) +-fixed minor bug in the stdlib format() function (thx Rick) +-fixed a bug in dofile() that was preventing to compile empty files +-added new API sq_poptop() & sq_getfreevariable() +-some performance improvements + +***2005-08-14 *** +***version 2.0.4 stable*** +-weak references and related API calls +-added sq_objtobool() +-class instances memory policies improved(1 mem allocation for the whole instance) +-typetags are now declared as SQUserPointer instead of unsigned int +-first pass for 64bits compatibility +-fixed minor bug in the stdio stream +-fixed a bug in format() +-fixed bug in string.tointeger() and string.tofloat() + +***2005-06-24 *** +***version 2.0.3 stable*** +-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian +-sq_setparamscheck() : now typemesk can check for null +-added string escape sequence \xhhhh +-fixed some C++ standard incompatibilities + +***2005-05-15 *** +***version 2.0.2 stable*** +-performances improvements (expecially for GCC users) +-removed all dependencies from C++ exception handling +-various bugfixes + +***2005-04-12 *** +***version 2.0.1 stable*** +-various bugfixes +-sq_setparamscheck() now allows spaces in the typemask + +***2005-04-03 *** +***version 2.0 stable*** +-added API sq_gettypetag() +-added built-in function to the bool type(tointeger, tostring etc...) + +***2005-02-27 *** +***version 2.0 release candidate 1(RC 1)*** +-added API sq_reseterror() +-modified sq_release() +-now class instances can be cloned +-various bufixes + +***2005-01-26 *** +***version 2.0 beta 1*** +-added bool type +-class properties can be redefined in a derived class +-added ops *= /= and %= +-new syntax for class attributes declaration instead of ( and ) +-increased the max number of literals per function from 65535 to 16777215 +-now free variables have proper lexical scoping +-added API sq_createinstance(), sq_pushbool(), sq_getbool() +-added built-in function type() +-added built-in function obj.rawin(key) in table,class and instance +-sq_rawget() and sq_rawset() now work also on classes and instances +-the VM no longer uses C++ exception handling (more suitable for embedded devices) +-various bufixes + +***2004-12-21 *** +***version 2.0 alpha 2*** +-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table +-various bufixes +-added class level attributes + +***2004-12-12 *** +***version 2.0 alpha 1*** +-codebase branch from version 1.x +-added classes +-added functions with variable number of parameters(vargc & vargv and the ...) +-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while) +-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes() +-modified api sq_settypetag() + +***2004-11-01 *** +***version 1.0 stable*** +-fixed some minor bug +-improoved operator 'delete' performances +-added scientific notation for float numbers( eg. 2.e16 or 2.e-2) + +***2004-08-30 *** +***version 1.0 release candidate 2(RC 2)*** +-fixed bug in the vm(thx Pierre Renaux) +-fixed bug in the optimizer(thx Pierre Renaux) +-fixed some bug in the documentation(thx JD) +-added new api functions for raw object handling +-removed nested multiline comments +-reduced memory footprint in C references + +***2004-08-23 *** +***version 1.0 release candidate 1(RC 1)*** +-fixed division by zero +-the 'in' operator and obj.rawget() do not query the default delegate anymore +-added function sq_getprintfunc() +-added new standard library 'auxlib'(implements default error handlers) + +***2004-07-12 *** +***version 1.0 beta 4*** +-fixed a bug in the integer.tochar() built-in method +-fixed unary minus operator +-fixed bug in dofile() +-fixed inconsistency between != and == operators(on float/integer comparison) +-added javascript style unsigned right shift operator '>>>' +-added array(size) constructor built-in function +-array.resize(size,[fill]) built-in function accepts an optional 'fill' value +-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename() + +***2004-05-23 *** +***version 1.0 beta 3*** +-minor vm bug fixes +-string allocation is now faster +-tables and array memory usage is now less conservative(they shrink) +-added regular expression routines in the standard library +-The 'c' expression now accepts only 1 character(thx irbrian) +-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string") +-added new keyword 'parent' for accessing the delegate of tables and unserdata +-The metamethod '_clone' has been renamed '_cloned' +-the _delslot metamethod's behaviour and prototype have been changed +-new default function in the integer and float object 'tochar()' +-the built-in function chcode2string has been removed +-the default method [table].getdelegate() has been removed +-new api sq_rawdeleteslot() +-new table built-in method rawdelete(key) +-the dynamic mudule loading has been removed from the standard distribution +-some optimizations in the VM + +***2004-04-21 *** +***version 1.0 beta 2*** +-minor compiler/parser bug fixes +-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck() +-sq_setparamscheck allows to add automatic parameters type checking in native closures +-sq_compile() lost the lineinfo parameter +-new api sq_enabledebuginfo() globally sets compiler's debug info generation +-added consistency check on bytecode serialization +-fixed += operator, now works on strings like + +-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime +-added registry table +-new api call sq_pushregistrytable() +-added type tag to the userdata type sq_settypetag() +-sq_getuserdata now queries the userdata typetag +-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons +-new standard libraries(sqlibs are now obsolete) + +***2004-02-20 *** +***version 1.0 beta 1*** +-fixed a bug in the compiler (thanks Martin Kofler) +-fixed bug in the switch case statement +-fixed the _unm metamethod +-fixed minor bugs in the API +-fixed automatic stack resizing +-first beta version + first pass code clean up in the VM and base lib + first pass code coverege test has been done on VM and built-in lib +-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete) +-new api allows to specifiy a "print" function to output text(sq_printfunc) +-added some small optimizations +-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread") +-new built in functions have been added for manipulating the new "thread" type +-friend virtual machines share the same root table, error handler and debug hook by default +-new compile time options + +***2004-01-19 *** +***version 0.9 alpha*** +-fixed a garbage collection bug +-fixed some API bugs(thanks to Joshua Jensen) +-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled) +-new function parameters semantic, now passing a wrong number of parameters generates an exception +-native closures have now a built in parameter number checking +-sq_rawget and sq_rawset now work also on arrays +-sq_getsize now woks also on userdata +-the userdata release hook prototype is changed(now passes the size of the userdata) +-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen) +-faster compiler +-try/catch blocks do not cause any runtime memory allocation anymore + +***2003-12-06 *** +***version 0.8 alpha*** +-fixed a bug that was preventing to have callable userdata throught the metamethod _call +-fixed a garbage collection bug +-fixed == operator now can compare correctly different types +-new built in method getstackinfos(level) +-improoved line informations precision for the debug hook +-new api call sq_compilebuffer() +-new built-in api function compilestring() +-new syntactic sugar for function declarations inside tables +-the debug API has been finalized + +***2003-11-17 *** +***version 0.7 alpha*** +-fixed critical bug SQInteger the tail call system +-fixed bug in the continue statement code generation +-fixed func call param issue(thanks to Rewoonenco Andrew) +-added _delslot metamethod(thanks to Rewoonenco Andrew) +-new multiline string expression ( delimited by <[ and ]> ) +-normal strings ("") do not allow embedded new line anymore +-reduced vm memory footprint(C refs are shared between friend VMs) +-new api method sq_deleteslot() +-new debug hook event 'r' is triggered when a function returns + +***2003-11-04 *** +***version 0.6 alpha*** +-fixed switch statement(was executing the default case after a break) +-sq_call() doesn't pop the closure (just the params) +-the vm execution can be suspended from the C API anytime (micro-threads) +-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack() + +***2003-10-13 *** +***version 0.5 alpha*** +-fixed some minor bug +-tested with non ASCII identifiers in unicode mode(I've tried chinese chars) +-added built-in function string.find() +-the built-in function array.sort() optionally accepts a cmp(a,b) function +-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname) +-fixed some debug info imprecision + +***2003-10-01 *** +***version 0.4 alpha*** +-faster VM +-sq_call will pop arguments and closure also in case of failure +-fixed a bug in sq_remove +-now the VM detects delegation cycles(and throws an exception) +-new operators ++ and -- +-new operator ',' comma operator +-fixed some expression precedence issue +-fixed bug in sq_arraypop + +***2003-09-15 *** +***version 0.3 alpha*** +-fixed a bug in array::insert() +-optional Unicode core(define SQUNICODE or _UNICODE on Win32) +-sq_compiler uses a new reader function SQLEXREADFUNC +-the debug hook passes 'l' instead of 'line' for line callbacks + and 'c' instead of 'call' for call callbacks +-new array.extend() bulit-in function +-new API sq_clone() + +***2003-09-10 *** +***version 0.2 pre-alpha*** +-new completely reentrant VM (sq_open and sq_close are now obsolete) +-sq_newvm() has a new prototype +-allocators are now global and linked in the VM +-_newslot meta method added +-rawset creates a slot if doesn't exists +-the compiler error callback pass the vm handle(thanks Pierre Renaux) +-sq_setforeignptr() sq_getforeingptr() are now public +-sq_resume() now is possible to resume generators from C +-sq_getlasterror() retrieve the last thrown error +-improved docs + +***2003-09-06 *** +***version 0.1 pre-alpha*** +first release diff --git a/src/squirrel/README b/src/squirrel/README index d6c047157..3d984d9ee 100644 --- a/src/squirrel/README +++ b/src/squirrel/README @@ -1,66 +1,22 @@ -~~~~~~~~ -Squirrel -~~~~~~~~ - -This directory contains the SQUIRREL programming language as found on -http://www.squirrel-lang.org with some minor fixes to make it compile warning -free on 64bit architectures. - -Squirrel Copyright: -Copyright (c) 2003-2006 Alberto Demichelis - -This software is provided 'as-is', without any -express or implied warranty. In no event will the -authors be held liable for any damages arising from -the use of this software. - -Permission is granted to anyone to use this software -for any purpose, including commercial applications, -and to alter it and redistribute it freely, subject -to the following restrictions: - - 1. The origin of this software must not be - misrepresented; you must not claim that - you wrote the original software. If you - use this software in a product, an - acknowledgment in the product - documentation would be appreciated but is - not required. - - 2. Altered source versions must be plainly - marked as such, and must not be - misrepresented as being the original - software. - - 3. This notice may not be removed or - altered from any source distribution. ------------------------------------------------------ -END OF COPYRIGHT - - -~~~~~~~~~~~~~~~~~~~~~~~~ -Squirrel Remote Debugger -~~~~~~~~~~~~~~~~~~~~~~~~ - -The subdirectory sqdbg contains the sqdbg library by Alberto Demichelis. - -SQDBG License: - -This software is provided 'as-is', without any express or implied warranty. In -no event will the authors be held liable for any damages arising from the use -of this software. - -Permission is granted to anyone to use this software for any purpose, including -commercial applications, and to alter it and redistribute it freely, subject to -the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim -that you wrote the original software. If you use this software in a product, an -acknowledgment in the product documentation would be appreciated but is not -required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. - +The programming language SQUIRREL 2.1.2 stable + +-------------------------------------------------- +The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and +Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64). + +Has been tested with the following compilers: + MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits) + MinGW gcc 3.2 (mingw special 20020817-1) + Cygnus gcc 3.2 + Linux gcc 3.2.3 + Linux gcc 4.0.0 (x86 64bits) + + +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 + +END OF README + diff --git a/src/squirrel/include/sqstdblob.h b/src/squirrel/include/sqstdblob.h index e54d7bec5..1d9a4cdc3 100644 --- a/src/squirrel/include/sqstdblob.h +++ b/src/squirrel/include/sqstdblob.h @@ -17,3 +17,4 @@ SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v); #endif #endif /*_SQSTDBLOB_H_*/ + diff --git a/src/squirrel/include/sqstdio.h b/src/squirrel/include/sqstdio.h index c3137f19b..6da1872e7 100644 --- a/src/squirrel/include/sqstdio.h +++ b/src/squirrel/include/sqstdio.h @@ -7,7 +7,10 @@ #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; @@ -51,3 +54,4 @@ SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v); #endif #endif /*_SQSTDIO_H_*/ + diff --git a/src/squirrel/include/sqstdstring.h b/src/squirrel/include/sqstdstring.h index ab68d1683..72f30b4ad 100644 --- a/src/squirrel/include/sqstdstring.h +++ b/src/squirrel/include/sqstdstring.h @@ -6,9 +6,6 @@ extern "C" { #endif -//#define SQRex_True 1 -//#define SQRex_False 0 - typedef unsigned int SQRexBool; typedef struct SQRex SQRex; diff --git a/src/squirrel/include/squirrel.h b/src/squirrel/include/squirrel.h index 1a7efc566..515031210 100644 --- a/src/squirrel/include/squirrel.h +++ b/src/squirrel/include/squirrel.h @@ -1,30 +1,30 @@ /* -Copyright (c) 2003-2006 Alberto Demichelis +Copyright (c) 2003-2007 Alberto Demichelis -This software is provided 'as-is', without any -express or implied warranty. In no event will the -authors be held liable for any damages arising from +This software is provided 'as-is', without any +express or implied warranty. In no event will the +authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software -for any purpose, including commercial applications, -and to alter it and redistribute it freely, subject +Permission is granted to anyone to use this software +for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject to the following restrictions: - 1. The origin of this software must not be - misrepresented; you must not claim that - you wrote the original software. If you - use this software in a product, an - acknowledgment in the product - documentation would be appreciated but is + 1. The origin of this software must not be + misrepresented; you must not claim that + you wrote the original software. If you + use this software in a product, an + acknowledgment in the product + documentation would be appreciated but is not required. - 2. Altered source versions must be plainly - marked as such, and must not be - misrepresented as being the original + 2. Altered source versions must be plainly + marked as such, and must not be + misrepresented as being the original software. - 3. This notice may not be removed or + 3. This notice may not be removed or altered from any source distribution. */ @@ -49,8 +49,8 @@ typedef long SQInteger; typedef unsigned long SQUnsignedInteger; typedef unsigned long SQHash; /*should be the same size of a pointer*/ #endif -typedef int SQInt32; -#else +typedef int SQInt32; +#else typedef int SQInteger; typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ typedef unsigned int SQUnsignedInteger; @@ -85,9 +85,16 @@ struct SQDelegable; #endif #ifdef SQUNICODE +#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8 + #if defined(wchar_t) //this is if the compiler considers wchar_t as native type #define wchar_t unsigned short #endif + +#else +typedef unsigned short wchar_t; +#endif + typedef wchar_t SQChar; #define _SC(a) L##a #define scstrcmp wcscmp @@ -129,8 +136,8 @@ typedef char SQChar; #define MAX_CHAR 0xFF #endif -#define SQUIRREL_VERSION _SC("Squirrel 2.1 stable") -#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2006 Alberto Demichelis") +#define SQUIRREL_VERSION _SC("Squirrel 2.1.2 stable") +#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2007 Alberto Demichelis") #define SQUIRREL_AUTHOR _SC("Alberto Demichelis") #define SQ_VMSTATE_IDLE 0 @@ -215,8 +222,8 @@ typedef union tagSQObjectValue typedef struct tagSQObject { - SQObjectValue _unVal; SQObjectType _type; + SQObjectValue _unVal; }SQObject; typedef struct tagSQStackInfos{ @@ -321,8 +328,7 @@ SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t); SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); -/*SQUIRREL_API SQRESULT sq_createslot(HSQUIRRELVM v,SQInteger idx);*/ -SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); +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); SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); @@ -330,15 +336,16 @@ SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); -SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); -SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); +SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx); /*calls*/ SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror); diff --git a/src/squirrel/sqstdlib/sqstdaux.cpp b/src/squirrel/sqstdlib/sqstdaux.cpp index da014f50d..6d3ea31a7 100644 --- a/src/squirrel/sqstdlib/sqstdaux.cpp +++ b/src/squirrel/sqstdlib/sqstdaux.cpp @@ -12,7 +12,7 @@ void sqstd_printcallstack(HSQUIRRELVM v) SQFloat f; const SQChar *s; SQInteger level=1; //1 is to skip this function that is level 0 - const SQChar *name=0; + const SQChar *name=0; SQInteger seq=0; pf(v,_SC("\nCALLSTACK\n")); while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) @@ -80,7 +80,7 @@ void sqstd_printcallstack(HSQUIRRELVM v) pf(v,_SC("[%s] INSTANCE\n"),name); break; case OT_WEAKREF: - pf(v,_SC("[%s] INSTANCE\n"),name); + pf(v,_SC("[%s] WEAKREF\n"),name); break; case OT_BOOL:{ sq_getinteger(v,-1,&i); diff --git a/src/squirrel/sqstdlib/sqstdblob.cpp b/src/squirrel/sqstdlib/sqstdblob.cpp index ded369661..f1a9f003a 100644 --- a/src/squirrel/sqstdlib/sqstdblob.cpp +++ b/src/squirrel/sqstdlib/sqstdblob.cpp @@ -237,7 +237,6 @@ SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { sq_remove(v,-2); - sq_remove(v,-2); return blob->GetBuf(); } } @@ -249,3 +248,4 @@ SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) { return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); } + diff --git a/src/squirrel/sqstdlib/sqstdio.cpp b/src/squirrel/sqstdlib/sqstdio.cpp index ff995426e..81ed73278 100644 --- a/src/squirrel/sqstdlib/sqstdio.cpp +++ b/src/squirrel/sqstdlib/sqstdio.cpp @@ -72,7 +72,7 @@ struct SQFile : public SQStream { return false; } void Close() { - if(_handle && _owns) { + if(_handle && _owns) { sqstd_fclose(_handle); _handle = NULL; _owns = false; @@ -225,7 +225,7 @@ static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) if(c >= 0x80) { SQInteger tmp; SQInteger codelen = utf8_lengths[c>>4]; - if(codelen == 0) + if(codelen == 0) return 0; //"invalid UTF-8 stream"; tmp = c&byte_masks[codelen]; @@ -297,14 +297,14 @@ SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) //gotta swap the next 2 lines on BIG endian machines case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; - case 0xBBEF: - if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("io error")); + case 0xBBEF: + if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("io error")); } - if(uc != 0xBF) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("Unrecognozed ecoding")); + if(uc != 0xBF) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("Unrecognozed ecoding")); } func = _io_file_lexfeed_UTF8; break;//UTF-8 ; diff --git a/src/squirrel/sqstdlib/sqstdmath.cpp b/src/squirrel/sqstdlib/sqstdmath.cpp index 01a808adf..2ad9f028f 100644 --- a/src/squirrel/sqstdlib/sqstdmath.cpp +++ b/src/squirrel/sqstdlib/sqstdmath.cpp @@ -37,8 +37,8 @@ static SQInteger math_abs(HSQUIRRELVM v) { SQInteger n; sq_getinteger(v,2,&n); - sq_pushinteger(v,(SQInteger)abs((int)n)); - return 1; + sq_pushinteger(v,(SQInteger)abs((int)n)); + return 1; } SINGLE_ARG_FUNC(sqrt) diff --git a/src/squirrel/sqstdlib/sqstdrex.cpp b/src/squirrel/sqstdlib/sqstdrex.cpp index 59397a728..6f8d59ce9 100644 --- a/src/squirrel/sqstdlib/sqstdrex.cpp +++ b/src/squirrel/sqstdlib/sqstdrex.cpp @@ -24,28 +24,28 @@ static const SQChar *g_nnames[] = #endif -#define OP_GREEDY MAX_CHAR+1 // * + ? {n} -#define OP_OR MAX_CHAR+2 -#define OP_EXPR MAX_CHAR+3 //parentesis () -#define OP_NOCAPEXPR MAX_CHAR+4 //parentesis (?:) -#define OP_DOT MAX_CHAR+5 -#define OP_CLASS MAX_CHAR+6 -#define OP_CCLASS MAX_CHAR+7 -#define OP_NCLASS MAX_CHAR+8 //negates class the [^ -#define OP_RANGE MAX_CHAR+9 -#define OP_CHAR MAX_CHAR+10 -#define OP_EOL MAX_CHAR+11 -#define OP_BOL MAX_CHAR+12 -#define OP_WB MAX_CHAR+13 - -#define SQREX_SYMBOL_ANY_CHAR '.' -#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE '+' -#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE '*' -#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE '?' -#define SQREX_SYMBOL_BRANCH '|' -#define SQREX_SYMBOL_END_OF_STRING '$' -#define SQREX_SYMBOL_BEGINNING_OF_STRING '^' -#define SQREX_SYMBOL_ESCAPE_CHAR '\\' +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) + +#define SQREX_SYMBOL_ANY_CHAR ('.') +#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define SQREX_SYMBOL_BRANCH ('|') +#define SQREX_SYMBOL_END_OF_STRING ('$') +#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') typedef int SQRexNodeType; @@ -88,7 +88,8 @@ static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); } exp->_nodes[exp->_nsize++] = n; - return (SQInteger)exp->_nsize - 1; + SQInteger newid = exp->_nsize - 1; + return (SQInteger)newid; } static void sqstd_rex_error(SQRex *exp,const SQChar *error) @@ -98,23 +99,11 @@ static void sqstd_rex_error(SQRex *exp,const SQChar *error) } static void sqstd_rex_expect(SQRex *exp, SQInteger n){ - if((*exp->_p) != n) + if((*exp->_p) != n) sqstd_rex_error(exp, _SC("expected paren")); exp->_p++; } -/*static SQBool sqstd_rex_ischar(SQChar c) -{ - switch(c) { - case SQREX_SYMBOL_BRANCH:case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: - case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE:case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: - case SQREX_SYMBOL_BEGINNING_OF_STRING:case SQREX_SYMBOL_END_OF_STRING: - case SQREX_SYMBOL_ANY_CHAR:case SQREX_SYMBOL_ESCAPE_CHAR:case '(':case ')':case '[':case '{': case '}': - return SQFalse; - } - return SQTrue; -}*/ - static SQChar sqstd_rex_escapechar(SQRex *exp) { if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ @@ -140,6 +129,7 @@ static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) { + SQChar t; if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { exp->_p++; switch(*exp->_p) { @@ -148,30 +138,32 @@ static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); - case 'a': case 'A': case 'w': case 'W': case 's': case 'S': - case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': - case 'p': case 'P': case 'l': case 'u': + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': { - SQChar t = *exp->_p; - exp->_p++; + t = *exp->_p; exp->_p++; return sqstd_rex_charclass(exp,t); } - case 'b': + case 'b': case 'B': if(!isclass) { SQInteger node = sqstd_rex_newnode(exp,OP_WB); exp->_nodes[node].left = *exp->_p; - exp->_p++; + exp->_p++; return node; } //else default - default: return sqstd_rex_newnode(exp,(*exp->_p++)); + default: + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); } } else if(!scisprint(*exp->_p)) { - + sqstd_rex_error(exp,_SC("letter expected")); } - return sqstd_rex_newnode(exp,*exp->_p++); + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); } static SQInteger sqstd_rex_class(SQRex *exp) { @@ -181,18 +173,19 @@ static SQInteger sqstd_rex_class(SQRex *exp) ret = sqstd_rex_newnode(exp,OP_NCLASS); exp->_p++; }else ret = sqstd_rex_newnode(exp,OP_CLASS); - + if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); chain = ret; while(*exp->_p != ']' && exp->_p != exp->_eol) { - if(*exp->_p == '-' && first != -1){ + if(*exp->_p == '-' && first != -1){ SQInteger r; if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); r = sqstd_rex_newnode(exp,OP_RANGE); if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); exp->_nodes[r].left = exp->_nodes[first].type; - exp->_nodes[r].right = sqstd_rex_escapechar(exp); + SQInteger t = sqstd_rex_escapechar(exp); + exp->_nodes[r].right = t; exp->_nodes[chain].next = r; chain = r; first = -1; @@ -236,7 +229,7 @@ static SQInteger sqstd_rex_parsenumber(SQRex *exp) static SQInteger sqstd_rex_element(SQRex *exp) { - SQInteger ret; + SQInteger ret = -1; switch(*exp->_p) { case '(': { @@ -251,11 +244,12 @@ static SQInteger sqstd_rex_element(SQRex *exp) } else expr = sqstd_rex_newnode(exp,OP_EXPR); - exp->_nodes[expr].left = sqstd_rex_list(exp); + SQInteger newn = sqstd_rex_list(exp); + exp->_nodes[expr].left = newn; ret = expr; sqstd_rex_expect(exp,')'); - } - break; + } + break; case '[': exp->_p++; ret = sqstd_rex_class(exp); @@ -267,45 +261,53 @@ static SQInteger sqstd_rex_element(SQRex *exp) ret = sqstd_rex_charnode(exp,SQFalse); break; } - /* scope block */ - { - SQInteger op; - unsigned short p0 = 0, p1 = 0; - switch(*exp->_p){ - case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; goto __end; - case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; goto __end; - case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; goto __end; - case '{':{ + + + SQInteger op; + SQBool isgreedy = SQFalse; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; + case '{': exp->_p++; if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); p0 = (unsigned short)sqstd_rex_parsenumber(exp); + /*******************************/ switch(*exp->_p) { - case '}': - p1 = p0; exp->_p++; - goto __end; - case ',': - exp->_p++; - p1 = 0xFFFF; - if(isdigit(*exp->_p)){ - p1 = (unsigned short)sqstd_rex_parsenumber(exp); - } - sqstd_rex_expect(exp,'}'); - goto __end; - default: - sqstd_rex_error(exp,_SC(", or } expected")); + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)sqstd_rex_parsenumber(exp); } - } - __end: { - SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); - op = OP_GREEDY; - exp->_nodes[nnode].left = ret; - exp->_nodes[nnode].right = ((p0)<<16)|p1; - ret = nnode; + sqstd_rex_expect(exp,'}'); + break; + default: + sqstd_rex_error(exp,_SC(", or } expected")); } - } + /*******************************/ + isgreedy = SQTrue; + break; + } - if(*exp->_p != SQREX_SYMBOL_BRANCH && *exp->_p != ')' && *exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE && *exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE && *exp->_p != '\0') - exp->_nodes[ret].next = sqstd_rex_element(exp); + if(isgreedy) { + SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); + op = OP_GREEDY; + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + + if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + SQInteger nnode = sqstd_rex_element(exp); + exp->_nodes[ret].next = nnode; + } + return ret; } @@ -323,11 +325,12 @@ static SQInteger sqstd_rex_list(SQRex *exp) else ret = e; if(*exp->_p == SQREX_SYMBOL_BRANCH) { - SQInteger temp; + SQInteger temp,tright; exp->_p++; temp = sqstd_rex_newnode(exp,OP_OR); exp->_nodes[temp].left = ret; - exp->_nodes[temp].right = sqstd_rex_list(exp); + tright = sqstd_rex_list(exp); + exp->_nodes[temp].right = tright; ret = temp; } return ret; @@ -375,7 +378,7 @@ static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) { - + SQRexNodeType type = node->type; switch(type) { case OP_GREEDY: { @@ -419,7 +422,7 @@ static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar } } } - + if(s >= exp->_eol) break; } @@ -458,7 +461,7 @@ static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar exp->_matches[capture].begin = cur; exp->_currsubexp++; } - + do { SQRexNode *subnext = NULL; if(n->next != -1) { @@ -475,10 +478,10 @@ static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar } } while((n->next != -1) && (n = &exp->_nodes[n->next])); - if(capture != -1) + if(capture != -1) exp->_matches[capture].len = cur - exp->_matches[capture].begin; return cur; - } + } case OP_WB: if(str == exp->_bol && !isspace(*str) || (str == exp->_eol && !isspace(*(str-1))) @@ -533,7 +536,8 @@ SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) exp->_error = error; exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { - exp->_nodes[exp->_first].left=sqstd_rex_list(exp); + SQInteger res = sqstd_rex_list(exp); + exp->_nodes[exp->_first].left = res; if(*exp->_p!='\0') sqstd_rex_error(exp,_SC("unexpected character")); #ifdef _DEBUG @@ -630,3 +634,4 @@ SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) *subexp = exp->_matches[n]; return SQTrue; } + diff --git a/src/squirrel/sqstdlib/sqstdstream.cpp b/src/squirrel/sqstdlib/sqstdstream.cpp index b94ab5e94..4cd63da51 100644 --- a/src/squirrel/sqstdlib/sqstdstream.cpp +++ b/src/squirrel/sqstdlib/sqstdstream.cpp @@ -163,7 +163,7 @@ SQInteger _stream_writen(HSQUIRRELVM v) case 'f': { float f; sq_getfloat(v, 2, &tf); - f = tf; + f = (float)tf; self->Write(&f, sizeof(float)); } break; @@ -302,7 +302,7 @@ SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* } sq_createslot(v,-3); sq_pop(v,1); - + i = 0; while(globals[i].name!=0) { diff --git a/src/squirrel/sqstdlib/sqstdstring.cpp b/src/squirrel/sqstdlib/sqstdstring.cpp index d500012db..31735e133 100644 --- a/src/squirrel/sqstdlib/sqstdstring.cpp +++ b/src/squirrel/sqstdlib/sqstdstring.cpp @@ -44,7 +44,7 @@ static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, width = 0; if (src[n] == '.') { n++; - + wc = 0; while (scisdigit(src[n])) { swidth[wc] = src[n]; @@ -82,7 +82,7 @@ static SQInteger _string_format(HSQUIRRELVM v) } else if(format[n+1] == '%') { //handles %% dest[i++] = '%'; - n += 2; + n += 2; } else { n++; @@ -97,19 +97,19 @@ static SQInteger _string_format(HSQUIRRELVM v) SQFloat tf; switch(format[n]) { case 's': - if(SQ_FAILED(sq_getstring(v,nparam,&ts))) + if(SQ_FAILED(sq_getstring(v,nparam,&ts))) return sq_throwerror(v,_SC("string expected for the specified format")); addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); valtype = 's'; break; case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X': - if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) + if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) return sq_throwerror(v,_SC("integer expected for the specified format")); addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); valtype = 'i'; break; case 'f': case 'g': case 'G': case 'e': case 'E': - if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) + if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) return sq_throwerror(v,_SC("float expected for the specified format")); addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); valtype = 'f'; @@ -202,7 +202,7 @@ static SQInteger _string_split(HSQUIRRELVM v) #define SETUP_REX(v) \ SQRex *self = NULL; \ - sq_getinstanceup(v,1,(SQUserPointer *)&self,0); + sq_getinstanceup(v,1,(SQUserPointer *)&self,0); static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size) { diff --git a/src/squirrel/squirrel/sqapi.cpp b/src/squirrel/squirrel/sqapi.cpp index 8857c9af0..d6b08a7b9 100644 --- a/src/squirrel/squirrel/sqapi.cpp +++ b/src/squirrel/squirrel/sqapi.cpp @@ -29,7 +29,7 @@ bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPt #define sq_aux_paramscheck(v,count) \ { \ if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ -} +} SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e) { @@ -66,10 +66,10 @@ HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) SQSharedState *ss; SQVM *v; ss=_ss(friendvm); - + v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); new (v) SQVM(ss); - + if(v->Init(friendvm, initialstacksize)) { friendvm->Push(v); return v; @@ -83,8 +83,8 @@ SQInteger sq_getvmstate(HSQUIRRELVM v) { if(v->_suspended) return SQ_VMSTATE_SUSPENDED; - else { - if(v->_callsstack.size() != 0) return SQ_VMSTATE_RUNNING; + else { + if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; else return SQ_VMSTATE_IDLE; } } @@ -137,16 +137,25 @@ void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) { if(!ISREFCOUNTED(type(*po))) return; +#ifdef NO_GARBAGE_COLLECTOR + __AddRef(po->_type,po->_unVal); +#else _ss(v)->_refs_table.AddRef(*po); +#endif } SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) { if(!ISREFCOUNTED(type(*po))) return SQTrue; +#ifdef NO_GARBAGE_COLLECTOR + __Release(po->_type,po->_unVal); + return SQFalse; //the ret val doesn't work(and cannot be fixed) +#else return _ss(v)->_refs_table.Release(*po); +#endif } -const SQChar *sq_objtostring(HSQOBJECT *o) +const SQChar *sq_objtostring(HSQOBJECT *o) { if(sq_type(*o) == OT_STRING) { return _stringval(*o); @@ -154,7 +163,7 @@ const SQChar *sq_objtostring(HSQOBJECT *o) return NULL; } -SQInteger sq_objtointeger(HSQOBJECT *o) +SQInteger sq_objtointeger(HSQOBJECT *o) { if(sq_isnumeric(*o)) { return tointeger(*o); @@ -162,7 +171,7 @@ SQInteger sq_objtointeger(HSQOBJECT *o) return 0; } -SQFloat sq_objtofloat(HSQOBJECT *o) +SQFloat sq_objtofloat(HSQOBJECT *o) { if(sq_isnumeric(*o)) { return tofloat(*o); @@ -170,7 +179,7 @@ SQFloat sq_objtofloat(HSQOBJECT *o) return 0; } -SQBool sq_objtobool(HSQOBJECT *o) +SQBool sq_objtobool(HSQOBJECT *o) { if(sq_isbool(*o)) { return _integer(*o); @@ -219,12 +228,12 @@ SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) void sq_newtable(HSQUIRRELVM v) { - v->Push(SQTable::Create(_ss(v), 0)); + v->Push(SQTable::Create(_ss(v), 0)); } void sq_newarray(HSQUIRRELVM v,SQInteger size) { - v->Push(SQArray::Create(_ss(v), size)); + v->Push(SQArray::Create(_ss(v), size)); } SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) @@ -238,7 +247,7 @@ SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) } SQClass *newclass = SQClass::Create(_ss(v), baseclass); if(baseclass) v->Pop(); - v->Push(newclass); + v->Push(newclass); return SQ_OK; } @@ -286,6 +295,7 @@ SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) return SQ_OK; } + SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) { sq_aux_paramscheck(v, 1); @@ -314,7 +324,7 @@ void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) nc->_outervalues.push_back(v->Top()); v->Pop(); } - v->Push(SQObjectPtr(nc)); + v->Push(SQObjectPtr(nc)); } SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars) @@ -323,7 +333,7 @@ SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparam if(sq_isclosure(o)) { SQClosure *c = _closure(o); SQFunctionProto *proto = _funcproto(c->_function); - *nparams = (SQUnsignedInteger)proto->_parameters.size(); + *nparams = (SQUnsignedInteger)proto->_nparameters; *nfreevars = (SQUnsignedInteger)c->_outervalues.size(); return SQ_OK; } @@ -391,6 +401,20 @@ SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) return SQ_OK; } +SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + switch(type(o)) { + case OT_TABLE: _table(o)->Clear(); break; + case OT_ARRAY: _array(o)->Resize(0); break; + default: + return sq_throwerror(v, _SC("clear only works on table and array")); + break; + + } + return SQ_OK; +} + void sq_pushroottable(HSQUIRRELVM v) { v->Push(v->_roottable); @@ -432,6 +456,7 @@ SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) return type(stack_get(v, idx)); } + void sq_tostring(HSQUIRRELVM v,SQInteger idx) { SQObjectPtr &o = stack_get(v, idx); @@ -572,6 +597,16 @@ SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) return SQ_OK; } +SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); + if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); + _class(o)->_udsize = udsize; + return SQ_OK; +} + + SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag) { SQObjectPtr &o = stack_get(v,idx); @@ -641,19 +676,6 @@ SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) return SQ_OK; } -/*SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx) -{ - sq_aux_paramscheck(v, 3); - SQObjectPtr &self = stack_get(v, idx); - if(type(self) == OT_TABLE || type(self) == OT_CLASS) { - SQObjectPtr &key = v->GetUp(-2); - if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); - v->NewSlot(self, key, v->GetUp(-1)); - v->Pop(2); - } - return SQ_OK; -}*/ - SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) { sq_aux_paramscheck(v, 2); @@ -709,7 +731,7 @@ SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) break; default: v->Pop(2); - return sq_throwerror(v, _SC("rawset works only on array/table/calsse and instance")); + return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); } v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; } @@ -763,17 +785,17 @@ SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) SQObjectPtr &self=stack_get(v,idx); switch(type(self)){ case OT_TABLE: - if(!_table(self)->_delegate)break; - v->Push(SQObjectPtr(_table(self)->_delegate)); - break; case OT_USERDATA: - if(!_userdata(self)->_delegate)break; - v->Push(SQObjectPtr(_userdata(self)->_delegate)); + if(!_delegable(self)->_delegate){ + v->Push(_null_); + break; + } + v->Push(SQObjectPtr(_delegable(self)->_delegate)); break; default: return sq_throwerror(v,_SC("wrong type")); break; } return SQ_OK; - + } SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) @@ -808,7 +830,7 @@ SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) default: v->Pop(1); return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); - } + } v->Pop(1); return sq_throwerror(v,_SC("the index doesn't exist")); } @@ -821,7 +843,7 @@ SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) { - SQUnsignedInteger cstksize=v->_callsstack.size(); + SQUnsignedInteger cstksize=v->_callsstacksize; SQUnsignedInteger lvl=(cstksize-level)-1; SQInteger stackbase=v->_stackbase; if(lvl_function); - return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions._vals)-1); + if(func->_noutervalues > (SQInteger)idx) { + v->Push(c->_outervalues[idx]); + return _stringval(func->_outervalues[idx]._name); + } + idx -= func->_noutervalues; + return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); } return NULL; } @@ -960,14 +987,14 @@ SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) { - SQObjectPtr func=SQFunctionProto::Create(); - SQObjectPtr closure=SQClosure::Create(_ss(v),_funcproto(func)); + SQObjectPtr closure; + unsigned short tag; if(r(up,&tag,2) != 2) return sq_throwerror(v,_SC("io error")); if(tag != SQ_BYTECODE_STREAM_TAG) return sq_throwerror(v,_SC("invalid stream")); - if(!_closure(closure)->Load(v,up,r)) + if(!SQClosure::Load(v,up,r,closure)) return SQ_ERROR; v->Push(closure); return SQ_OK; @@ -1057,7 +1084,7 @@ SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) if(type(key) == OT_NULL) { attrs = _class(*o)->_attributes; v->Pop(); - v->Push(attrs); + v->Push(attrs); return SQ_OK; } else if(_class(*o)->GetAttributes(key,attrs)) { @@ -1140,10 +1167,10 @@ SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) if(type(o) == OT_GENERATOR) { return sq_throwerror(v,_SC("cannot iterate a generator")); } - bool finished; - if(!v->FOREACH_OP(o,realkey,val,refpos,0,finished)) + int faketojump; + if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) return SQ_ERROR; - if(!finished) { + if(faketojump != 666) { v->Push(realkey); v->Push(val); return SQ_OK; @@ -1197,6 +1224,7 @@ void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) { return SQ_REALLOC(p,oldsize,newsize); } + void sq_free(void *p,SQUnsignedInteger size) { SQ_FREE(p,size); diff --git a/src/squirrel/squirrel/sqbaselib.cpp b/src/squirrel/squirrel/sqbaselib.cpp index cc8b3682e..ee49b2d17 100644 --- a/src/squirrel/squirrel/sqbaselib.cpp +++ b/src/squirrel/squirrel/sqbaselib.cpp @@ -30,6 +30,11 @@ bool str2num(const SQChar *s,SQObjectPtr &res) } } +static SQInteger base_dummy(HSQUIRRELVM v) +{ + return 0; +} + #ifndef NO_GARBAGE_COLLECTOR static SQInteger base_collectgarbage(HSQUIRRELVM v) { @@ -217,6 +222,7 @@ static SQRegFunction base_funcs[]={ {_SC("suspend"),base_suspend,-1, NULL}, {_SC("array"),base_array,-2, _SC(".n")}, {_SC("type"),base_type,2, NULL}, + {_SC("dummy"),base_dummy,0,NULL}, #ifndef NO_GARBAGE_COLLECTOR {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")}, #endif @@ -235,6 +241,9 @@ void sq_base_register(HSQUIRRELVM v) sq_createslot(v,-3); i++; } + sq_pushstring(v,_SC("_version_"),-1); + sq_pushstring(v,SQUIRREL_VERSION,-1); + sq_createslot(v,-3); sq_pushstring(v,_SC("_charsize_"),-1); sq_pushinteger(v,sizeof(SQChar)); sq_createslot(v,-3); @@ -312,6 +321,12 @@ static SQInteger obj_delegate_weakref(HSQUIRRELVM v) return 1; } +static SQInteger obj_clear(HSQUIRRELVM v) +{ + return sq_clear(v,-1); +} + + static SQInteger number_delegate_tochar(HSQUIRRELVM v) { SQObject &o=stack_get(v,1); @@ -353,6 +368,7 @@ static SQInteger table_rawget(HSQUIRRELVM v) return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; } + SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ {_SC("len"),default_delegate_len,1, _SC("t")}, {_SC("rawget"),table_rawget,2, _SC("t")}, @@ -361,6 +377,7 @@ SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ {_SC("rawin"),container_rawexists,2, _SC("t")}, {_SC("weakref"),obj_delegate_weakref,1, NULL }, {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, {0,0} }; @@ -468,14 +485,14 @@ bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger f i = l; j = r+1; while(1){ SQInteger ret; - do { - ++i; + do { + ++i; if(i > r) break; if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret)) return false; } while( ret <= 0); do { - --j; + --j; if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret)) return false; } @@ -510,7 +527,7 @@ static SQInteger array_slice(HSQUIRRELVM v) 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; - if(eidx <= sidx)return sq_throwerror(v,_SC("wrong indexes")); + if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); SQObjectPtr t; SQInteger count=0; @@ -520,7 +537,7 @@ static SQInteger array_slice(HSQUIRRELVM v) } v->Push(arr); return 1; - + } SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ @@ -538,6 +555,7 @@ SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ {_SC("slice"),array_slice,-1, _SC("ann")}, {_SC("weakref"),obj_delegate_weakref,1, NULL }, {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, {0,0} }; @@ -653,9 +671,9 @@ static SQInteger closure_getinfos(HSQUIRRELVM v) { SQTable *res = SQTable::Create(_ss(v),4); if(type(o) == OT_CLOSURE) { SQFunctionProto *f = _funcproto(_closure(o)->_function); - SQInteger nparams = f->_parameters.size() + (f->_varparams?1:0); + SQInteger nparams = f->_nparameters + (f->_varparams?1:0); SQObjectPtr params = SQArray::Create(_ss(v),nparams); - for(SQUnsignedInteger n = 0; n_parameters.size(); n++) { + for(SQInteger n = 0; n_nparameters; n++) { _array(params)->Set((SQInteger)n,f->_parameters[n]); } if(f->_varparams) { @@ -667,7 +685,7 @@ static SQInteger closure_getinfos(HSQUIRRELVM v) { res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); } - else { //OT_NATIVECLOSURE + else { //OT_NATIVECLOSURE SQNativeClosure *nc = _nativeclosure(o); res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); @@ -753,7 +771,7 @@ static SQInteger thread_wakeup(HSQUIRRELVM v) break; } } - + SQInteger wakeupret = sq_gettop(v)>1?1:0; if(wakeupret) { sq_move(thread,v,2); @@ -858,3 +876,5 @@ SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, {0,0} }; + + diff --git a/src/squirrel/squirrel/sqclass.cpp b/src/squirrel/squirrel/sqclass.cpp index 405c737a7..309036a35 100644 --- a/src/squirrel/squirrel/sqclass.cpp +++ b/src/squirrel/squirrel/sqclass.cpp @@ -12,6 +12,7 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base) _base = base; _typetag = 0; _hook = NULL; + _udsize = 0; _metamethods.resize(MT_LAST); //size it to max size if(_base) { _defaultvalues.copy(base->_defaultvalues); @@ -26,7 +27,7 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base) ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); } -void SQClass::Finalize() { +void SQClass::Finalize() { _attributes = _null_; _defaultvalues.resize(0); _methods.resize(0); @@ -46,7 +47,7 @@ SQClass::~SQClass() bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) { SQObjectPtr temp; - if(_locked) + if(_locked) return false; //the class already has an instance so cannot be modified if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value { @@ -55,13 +56,13 @@ bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr } if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) { SQInteger mmidx; - if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && + if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { _metamethods[mmidx] = val; - } + } else { if(type(temp) == OT_NULL) { - SQClassMemeber m; + SQClassMember m; m.val = val; _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); _methods.push_back(m); @@ -72,7 +73,7 @@ bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr } return true; } - SQClassMemeber m; + SQClassMember m; m.val = val; _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); _defaultvalues.push_back(m); @@ -139,8 +140,8 @@ SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) { _memsize = memsize; _class = c; - _nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger n = 0; n < _nvalues; n++) { + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); } Init(ss); @@ -150,17 +151,18 @@ SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) { _memsize = memsize; _class = i->_class; - _nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger n = 0; n < _nvalues; n++) { + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { new (&_values[n]) SQObjectPtr(i->_values[n]); } Init(ss); } -void SQInstance::Finalize() +void SQInstance::Finalize() { + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); __ObjRelease(_class); - for(SQUnsignedInteger i = 0; i < _nvalues; i++) { + for(SQUnsignedInteger i = 0; i < nvalues; i++) { _values[i] = _null_; } } @@ -168,7 +170,7 @@ void SQInstance::Finalize() SQInstance::~SQInstance() { REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); - Finalize(); + if(_class){ Finalize(); } //if _class is null it was already finalized by the GC } bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) diff --git a/src/squirrel/squirrel/sqclass.h b/src/squirrel/squirrel/sqclass.h index a451eede5..4faff8395 100644 --- a/src/squirrel/squirrel/sqclass.h +++ b/src/squirrel/squirrel/sqclass.h @@ -4,9 +4,9 @@ struct SQInstance; -struct SQClassMemeber { - SQClassMemeber(){} - SQClassMemeber(const SQClassMemeber &o) { +struct SQClassMember { + SQClassMember(){} + SQClassMember(const SQClassMember &o) { val = o.val; attrs = o.attrs; } @@ -14,7 +14,7 @@ struct SQClassMemeber { SQObjectPtr attrs; }; -typedef sqvector SQClassMemeberVec; +typedef sqvector SQClassMemberVec; #define MEMBER_TYPE_METHOD 0x01000000 #define MEMBER_TYPE_FIELD 0x02000000 @@ -53,9 +53,9 @@ public: bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); void Lock() { _locked = true; if(_base) _base->Lock(); } - void Release() { + void Release() { if (_hook) { _hook(_typetag,0);} - sq_delete(this, SQClass); + sq_delete(this, SQClass); } void Finalize(); #ifndef NO_GARBAGE_COLLECTOR @@ -65,28 +65,33 @@ public: SQInstance *CreateInstance(); SQTable *_members; SQClass *_base; - SQClassMemeberVec _defaultvalues; - SQClassMemeberVec _methods; + SQClassMemberVec _defaultvalues; + SQClassMemberVec _methods; SQObjectPtrVec _metamethods; SQObjectPtr _attributes; SQUserPointer _typetag; SQRELEASEHOOK _hook; bool _locked; + SQInteger _udsize; }; #define calcinstancesize(_theclass_) \ - (sizeof(SQInstance)+(sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))) -struct SQInstance : public SQDelegable + (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))) + +struct SQInstance : public SQDelegable { void Init(SQSharedState *ss); SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); public: static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { - + SQInteger size = calcinstancesize(theclass); SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); new (newinst) SQInstance(ss, theclass,size); + if(theclass->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); + } return newinst; } SQInstance *Clone(SQSharedState *ss) @@ -94,6 +99,9 @@ public: SQInteger size = calcinstancesize(_class); SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); new (newinst) SQInstance(ss, this,size); + if(_class->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); + } return newinst; } ~SQInstance(); @@ -119,13 +127,16 @@ public: return false; } void Release() { + _uiRef++; if (_hook) { _hook(_userpointer,0);} + _uiRef--; + if(_uiRef > 0) return; SQInteger size = _memsize; this->~SQInstance(); SQ_FREE(this, size); } void Finalize(); -#ifndef NO_GARBAGE_COLLECTOR +#ifndef NO_GARBAGE_COLLECTOR void Mark(SQCollectable ** ); #endif bool InstanceOf(SQClass *trg); @@ -134,7 +145,6 @@ public: SQClass *_class; SQUserPointer _userpointer; SQRELEASEHOOK _hook; - SQUnsignedInteger _nvalues; SQInteger _memsize; SQObjectPtr _values[1]; }; diff --git a/src/squirrel/squirrel/sqclosure.h b/src/squirrel/squirrel/sqclosure.h index d8dc90aef..1c9eaa94a 100644 --- a/src/squirrel/squirrel/sqclosure.h +++ b/src/squirrel/squirrel/sqclosure.h @@ -29,7 +29,7 @@ public: REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); - bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); #ifndef NO_GARBAGE_COLLECTOR void Mark(SQCollectable **chain); void Finalize(){_outervalues.resize(0); } @@ -39,7 +39,7 @@ public: SQObjectPtrVec _outervalues; }; ////////////////////////////////////////////// -struct SQGenerator : public CHAINABLE_OBJ +struct SQGenerator : public CHAINABLE_OBJ { enum SQGeneratorState{eRunning,eSuspended,eDead}; private: @@ -92,7 +92,7 @@ public: ret->_env = _env; ret->_name = _name; ret->_outervalues.copy(_outervalues); - ret->_typecheck = _typecheck; + ret->_typecheck.copy(_typecheck); ret->_nparamscheck = _nparamscheck; return ret; } @@ -107,12 +107,12 @@ public: void Mark(SQCollectable **chain); void Finalize(){_outervalues.resize(0);} #endif + SQInteger _nparamscheck; + SQIntVec _typecheck; + SQObjectPtrVec _outervalues; SQObjectPtr _env; SQFUNCTION _function; SQObjectPtr _name; - SQObjectPtrVec _outervalues; - SQIntVec _typecheck; - SQInteger _nparamscheck; }; diff --git a/src/squirrel/squirrel/sqcompiler.cpp b/src/squirrel/squirrel/sqcompiler.cpp index a6bab092c..7137c535c 100644 --- a/src/squirrel/squirrel/sqcompiler.cpp +++ b/src/squirrel/squirrel/sqcompiler.cpp @@ -87,7 +87,7 @@ public: } SQObject Expect(SQInteger tok) { - + if(_token != tok) { if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { //ret = SQString::Create(_ss(_vm),_SC("constructor")); @@ -212,7 +212,7 @@ public: SQOpcode op; if(_token == TK_RETURN) { op = _OP_RETURN; - + } else { op = _OP_YIELD; @@ -227,11 +227,11 @@ public: _fs->_returnexp = retexp; _fs->AddInstruction(op, 1, _fs->PopTarget()); } - else{ + else{ if(op == _OP_RETURN && _fs->_traps > 0) _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); _fs->_returnexp = -1; - _fs->AddInstruction(op, 0xFF); + _fs->AddInstruction(op, 0xFF); } break;} case TK_BREAK: @@ -472,7 +472,7 @@ public: case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break; - default: return; + default: return; } } void ShiftExp() @@ -482,7 +482,7 @@ public: case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; - default: return; + default: return; } } void PlusExp() @@ -494,7 +494,7 @@ public: default: return; } } - + void MultExp() { PrefixedExpr(); @@ -512,7 +512,7 @@ public: switch(_token) { case _SC('.'): { pos = -1; - Lex(); + Lex(); if(_token == TK_PARENT) { Lex(); if(!NeedGet()) @@ -530,7 +530,7 @@ public: break; case _SC('['): if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration")); - Lex(); Expression(); Expect(_SC(']')); + Lex(); Expression(); Expect(_SC(']')); pos = -1; if(NeedGet()) Emit2ArgsOP(_OP_GET); _exst._deref = DEREF_FIELD; @@ -538,7 +538,7 @@ public: break; case TK_MINUSMINUS: case TK_PLUSPLUS: - if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { + if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { SQInteger tok = _token; Lex(); if(pos < 0) Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1); @@ -546,11 +546,11 @@ public: SQInteger src = _fs->PopTarget(); _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1); } - + } return; - break; - case _SC('('): + break; + case _SC('('): { if(_exst._deref != DEREF_NO_DEREF) { if(pos<0) { @@ -582,7 +582,7 @@ public: case TK_STRING_LITERAL: { //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1)); _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); - Lex(); + Lex(); } break; case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break; @@ -610,7 +610,7 @@ public: //checks if is a free variable if((pos = _fs->GetOuterVariable(id)) != -1) { _exst._deref = _fs->PushTarget(); - _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos); + _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos); _exst._freevar = true; } else { _fs->PushTarget(0); @@ -633,7 +633,7 @@ public: _token = _SC('.'); //hack return -1; break; - case TK_NULL: + case TK_NULL: _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); Lex(); break; @@ -648,7 +648,12 @@ public: } break; case TK_FLOAT: - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue)); + if(sizeof(SQFloat) == sizeof(SQInt32)) { + _fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue)); + } + else { + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue)); + } Lex(); break; case TK_TRUE: case TK_FALSE: @@ -660,7 +665,7 @@ public: SQInteger apos = _fs->GetCurrentPos(),key = 0; Lex(); while(_token != _SC(']')) { - Expression(); + Expression(); if(_token == _SC(',')) Lex(); SQInteger val = _fs->PopTarget(); SQInteger array = _fs->TopTarget(); @@ -684,7 +689,7 @@ public: case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break; case TK_RESUME : UnaryOP(_OP_RESUME); break; case TK_CLONE : UnaryOP(_OP_CLONE); break; - case TK_MINUSMINUS : + case TK_MINUSMINUS : case TK_PLUSPLUS :PrefixIncDec(_token); break; case TK_DELETE : DeleteExpr(); break; case TK_DELEGATE : DelegateExpr(); break; @@ -709,16 +714,16 @@ public: } return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('['))); } - + void FunctionCallArgs() { SQInteger nargs = 1;//this while(_token != _SC(')')) { Expression(true); MoveIfCurrentTargetIsLocal(); - nargs++; - if(_token == _SC(',')){ - Lex(); + nargs++; + if(_token == _SC(',')){ + Lex(); if(_token == ')') Error(_SC("expression expected, found ')'")); } } @@ -731,7 +736,7 @@ public: void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}') { SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; - + while(_token != terminator) { bool hasattrs = false; bool isstatic = false; @@ -799,7 +804,7 @@ public: } _fs->PopTarget(); _fs->PushLocalVariable(varname); - + } while(_token == _SC(',')); } void IfStatement() @@ -810,11 +815,11 @@ public: _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); SQInteger jnepos = _fs->GetCurrentPos(); SQInteger stacksize = _fs->GetStackSize(); - + Statement(); // if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon(); - + CleanStack(stacksize); SQInteger endifblock = _fs->GetCurrentPos(); if(_token == TK_ELSE){ @@ -835,18 +840,18 @@ public: SQInteger stacksize = _fs->GetStackSize(); jmppos = _fs->GetCurrentPos(); Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - + BEGIN_BREAKBLE_BLOCK(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); stacksize = _fs->GetStackSize(); - + Statement(); - + CleanStack(stacksize); _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); - + END_BREAKBLE_BLOCK(jmppos); } void DoWhileStatement() @@ -905,7 +910,7 @@ public: _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); CleanStack(stacksize); - + END_BREAKBLE_BLOCK(continuetrg); } void ForEachStatement() @@ -920,7 +925,7 @@ public: idxname = _fs->CreateString(_SC("@INDEX@")); } Expect(TK_IN); - + //save the stack size SQInteger stacksize = _fs->GetStackSize(); //put the table in the stack(evaluate the table expression) @@ -938,11 +943,13 @@ public: SQInteger jmppos = _fs->GetCurrentPos(); _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); SQInteger foreachpos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); //generate the statement code BEGIN_BREAKBLE_BLOCK() Statement(); _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); //restore the local variable stack(remove index,val and ref idx) CleanStack(stacksize); END_BREAKBLE_BLOCK(foreachpos - 1); @@ -993,7 +1000,7 @@ public: __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); _fs->_breaktargets.pop_back(); - + } void FunctionStatement() { @@ -1002,7 +1009,7 @@ public: _fs->PushTarget(0); _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); - + while(_token == TK_DOUBLE_COLON) { Lex(); id = Expect(TK_IDENTIFIER); @@ -1118,7 +1125,7 @@ public: } void CreateFunction(SQObject &name) { - + SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); funcstate->_name = name; SQObject paramname; @@ -1151,7 +1158,7 @@ public: } Lex(); } - + SQFuncState *currchunk = _fs; _fs = funcstate; Statement(); diff --git a/src/squirrel/squirrel/sqdebug.cpp b/src/squirrel/squirrel/sqdebug.cpp index 96da72d2d..40e0c9b99 100644 --- a/src/squirrel/squirrel/sqdebug.cpp +++ b/src/squirrel/squirrel/sqdebug.cpp @@ -10,7 +10,7 @@ SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) { - SQInteger cssize = v->_callsstack.size(); + SQInteger cssize = v->_callsstacksize; if (cssize > level) { memset(si, 0, sizeof(SQStackInfos)); SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; @@ -85,7 +85,7 @@ void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) { SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); - SQInteger found = 0; + SQInteger found = 0; for(SQInteger i=0; i<16; i++) { SQInteger mask = 0x00000001 << i; diff --git a/src/squirrel/squirrel/sqfuncproto.h b/src/squirrel/squirrel/sqfuncproto.h index 6444fbfc3..367b8183b 100644 --- a/src/squirrel/squirrel/sqfuncproto.h +++ b/src/squirrel/squirrel/sqfuncproto.h @@ -12,7 +12,7 @@ enum SQOuterType { struct SQOuterVar { - + SQOuterVar(){} SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) { @@ -53,6 +53,23 @@ typedef sqvector SQOuterVarVec; typedef sqvector SQLocalVarInfoVec; typedef sqvector SQLineInfoVec; +#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf) (sizeof(SQFunctionProto) \ + +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ + +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ + +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ + +(localinf*sizeof(SQLocalVarInfo))) + +#define _CONSTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger n = 0; n < size; n++) { \ + new (&ptr[n]) type(); \ + } \ +} + +#define _DESTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger nl = 0; nl < size; nl++) { \ + ptr[nl].~type(); \ + } \ +} struct SQFunctionProto : public SQRefCounted { private: @@ -60,29 +77,79 @@ private: _stacksize=0; _bgenerator=false;} public: - static SQFunctionProto *Create() + static SQFunctionProto *Create(SQInteger ninstructions, + SQInteger nliterals,SQInteger nparameters, + SQInteger nfunctions,SQInteger noutervalues, + SQInteger nlineinfos,SQInteger nlocalvarinfos) { SQFunctionProto *f; - sq_new(f,SQFunctionProto); + //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)); + new (f) SQFunctionProto; + f->_ninstructions = ninstructions; + f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; + f->_nliterals = nliterals; + f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; + f->_nparameters = nparameters; + f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; + f->_nfunctions = nfunctions; + f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; + f->_noutervalues = noutervalues; + f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; + f->_nlineinfos = nlineinfos; + f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; + f->_nlocalvarinfos = nlocalvarinfos; + + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); + _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); + //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers + _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); return f; } - void Release(){ sq_delete(this,SQFunctionProto);} + void Release(){ + _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); + _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); + _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); + _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); + this->~SQFunctionProto(); + sq_vm_free(this,size); + } const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); SQInteger GetLine(SQInstruction *curr); bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); - bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read); - SQObjectPtrVec _literals; - SQObjectPtrVec _functions; - SQObjectPtrVec _parameters; - SQOuterVarVec _outervalues; - SQInstructionVec _instructions; + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); + SQObjectPtr _sourcename; SQObjectPtr _name; - SQLocalVarInfoVec _localvarinfos; - SQLineInfoVec _lineinfos; SQInteger _stacksize; bool _bgenerator; bool _varparams; + + SQInteger _nlocalvarinfos; + SQLocalVarInfo *_localvarinfos; + + SQInteger _nlineinfos; + SQLineInfo *_lineinfos; + + SQInteger _nliterals; + SQObjectPtr *_literals; + + SQInteger _nparameters; + SQObjectPtr *_parameters; + + SQInteger _nfunctions; + SQObjectPtr *_functions; + + SQInteger _noutervalues; + SQOuterVar *_outervalues; + + SQInteger _ninstructions; + SQInstruction _instructions[1]; }; #endif //_SQFUNCTION_H_ diff --git a/src/squirrel/squirrel/sqfuncstate.cpp b/src/squirrel/squirrel/sqfuncstate.cpp index 2ceb1b471..962a6cd7a 100644 --- a/src/squirrel/squirrel/sqfuncstate.cpp +++ b/src/squirrel/squirrel/sqfuncstate.cpp @@ -14,6 +14,7 @@ SQInstructionDesc g_InstrDesc[]={ {_SC("_OP_LINE")}, {_SC("_OP_LOAD")}, {_SC("_OP_LOADINT")}, + {_SC("_OP_LOADFLOAT")}, {_SC("_OP_DLOAD")}, {_SC("_OP_TAILCALL")}, {_SC("_OP_CALL")}, @@ -62,6 +63,7 @@ SQInstructionDesc g_InstrDesc[]={ {_SC("_OP_YIELD")}, {_SC("_OP_RESUME")}, {_SC("_OP_FOREACH")}, + {_SC("_OP_POSTFOREACH")}, {_SC("_OP_DELEGATE")}, {_SC("_OP_CLONE")}, {_SC("_OP_TYPEOF")}, @@ -110,6 +112,7 @@ void SQFuncState::Error(const SQChar *err) void SQFuncState::Dump(SQFunctionProto *func) { SQUnsignedInteger n=0,i; + SQInteger si; scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); scprintf(_SC("--------------------------------------------------------------------\n")); @@ -140,8 +143,8 @@ void SQFuncState::Dump(SQFunctionProto *func) n++; } scprintf(_SC("-----LOCALS\n")); - for(i=0;i_localvarinfos.size();i++){ - SQLocalVarInfo lvi=func->_localvarinfos[i]; + for(si=0;si_nlocalvarinfos;si++){ + SQLocalVarInfo lvi=func->_localvarinfos[si]; scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); n++; } @@ -156,7 +159,7 @@ void SQFuncState::Dump(SQFunctionProto *func) for(i=0;i<_instructions.size();i++){ SQInstruction &inst=_instructions[i]; if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ - + SQInteger lidx = inst._arg1; scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); if(lidx >= 0xFFFFFFFF) @@ -165,7 +168,7 @@ void SQFuncState::Dump(SQFunctionProto *func) SQInteger refidx; SQObjectPtr val,key,refo; while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { - refo = refidx; + refo = refidx; } DumpLiteral(key); } @@ -181,17 +184,20 @@ void SQFuncState::Dump(SQFunctionProto *func) SQInteger refidx; SQObjectPtr val,key,refo; while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { - refo = refidx; + refo = refidx; } DumpLiteral(key); scprintf(_SC("\n")); } } } + else if(inst.op==_OP_LOADFLOAT) { + scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); + } else if(inst.op==_OP_ARITH){ scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); } - else + else scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); n++; } @@ -320,7 +326,7 @@ SQInteger SQFuncState::PushLocalVariable(const SQObject &name) lvi._pos=_vlocals.size(); _vlocals.push_back(lvi); if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); - + return pos; } @@ -349,7 +355,7 @@ SQInteger SQFuncState::GetOuterVariable(const SQObject &name) void SQFuncState::AddOuterValue(const SQObject &name) { SQInteger pos=-1; - if(_parent) { + if(_parent) { pos = _parent->GetLocalVariable(name); if(pos == -1) { pos = _parent->GetOuterVariable(name); @@ -362,7 +368,7 @@ void SQFuncState::AddOuterValue(const SQObject &name) _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local return; } - } + } _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global } @@ -400,7 +406,7 @@ void SQFuncState::AddInstruction(SQInstruction &i) pi._arg2 = (unsigned char)i._arg1; pi.op = _OP_GETK; pi._arg0 = i._arg0; - + return; } break; @@ -424,7 +430,7 @@ void SQFuncState::AddInstruction(SQInstruction &i) return; } break; - case _OP_MOVE: + case _OP_MOVE: if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1)) { pi._arg0 = i._arg0; @@ -461,7 +467,7 @@ void SQFuncState::AddInstruction(SQInstruction &i) break; case _OP_LOADNULLS: if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { - + pi._arg1 = pi._arg1 + 1; pi.op = _OP_LOADNULLS; return; @@ -488,8 +494,10 @@ SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) SQFunctionProto *SQFuncState::BuildProto() { - SQFunctionProto *f=SQFunctionProto::Create(); - f->_literals.resize(_nliterals); + SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(), + _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), + _lineinfos.size(),_localvarinfos.size()); + SQObjectPtr refidx,key,val; SQInteger idx; @@ -503,18 +511,14 @@ SQFunctionProto *SQFuncState::BuildProto() refidx=idx; } - f->_functions.resize(_functions.size()); - f->_functions.copy(_functions); - f->_parameters.resize(_parameters.size()); - f->_parameters.copy(_parameters); - f->_outervalues.resize(_outervalues.size()); - f->_outervalues.copy(_outervalues); - f->_instructions.resize(_instructions.size()); - f->_instructions.copy(_instructions); - f->_localvarinfos.resize(_localvarinfos.size()); - f->_localvarinfos.copy(_localvarinfos); - f->_lineinfos.resize(_lineinfos.size()); - f->_lineinfos.copy(_lineinfos); + for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; + for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; + 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]; + + memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); + f->_varparams = _varparams; return f; diff --git a/src/squirrel/squirrel/sqfuncstate.h b/src/squirrel/squirrel/sqfuncstate.h index fd191f2b3..96eb5520b 100644 --- a/src/squirrel/squirrel/sqfuncstate.h +++ b/src/squirrel/squirrel/sqfuncstate.h @@ -77,3 +77,4 @@ private: #endif //_SQFUNCSTATE_H_ + diff --git a/src/squirrel/squirrel/sqlexer.cpp b/src/squirrel/squirrel/sqlexer.cpp index 2552f7d14..701dc79b3 100644 --- a/src/squirrel/squirrel/sqlexer.cpp +++ b/src/squirrel/squirrel/sqlexer.cpp @@ -135,7 +135,7 @@ SQInteger SQLexer::Lex() case _SC('*'): NEXT(); LexBlockComment(); - continue; + continue; case _SC('/'): do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); continue; @@ -165,8 +165,8 @@ SQInteger SQLexer::Lex() case _SC('>'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} - else if(CUR_CHAR == _SC('>')){ - NEXT(); + else if(CUR_CHAR == _SC('>')){ + NEXT(); if(CUR_CHAR == _SC('>')){ NEXT(); RETURN_TOKEN(TK_USHIFTR); @@ -180,7 +180,7 @@ SQInteger SQLexer::Lex() else { NEXT(); RETURN_TOKEN(TK_NE); } case _SC('@'): { SQInteger stype; - NEXT(); + NEXT(); if(CUR_CHAR != _SC('"')) Error(_SC("string expected")); if((stype=ReadString('"',true))!=-1) { @@ -252,15 +252,15 @@ SQInteger SQLexer::Lex() SQInteger c = CUR_CHAR; if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); NEXT(); - RETURN_TOKEN(c); + RETURN_TOKEN(c); } RETURN_TOKEN(0); } } } - return 0; + return 0; } - + SQInteger SQLexer::GetIDType(SQChar *s) { SQObjectPtr t; @@ -282,20 +282,20 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) case SQUIRREL_EOB: Error(_SC("unfinished string")); return -1; - case _SC('\n'): - if(!verbatim) Error(_SC("newline in a constant")); - APPEND_CHAR(CUR_CHAR); NEXT(); + case _SC('\n'): + if(!verbatim) Error(_SC("newline in a constant")); + APPEND_CHAR(CUR_CHAR); NEXT(); _currentline++; break; case _SC('\\'): if(verbatim) { - APPEND_CHAR('\\'); NEXT(); + APPEND_CHAR('\\'); NEXT(); } else { NEXT(); switch(CUR_CHAR) { case _SC('x'): NEXT(); { - if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); + if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); const SQInteger maxdigits = 4; SQChar temp[maxdigits+1]; SQInteger n = 0; @@ -408,7 +408,7 @@ SQInteger SQLexer::ReadNumber() } if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); } - + APPEND_CHAR(CUR_CHAR); NEXT(); } diff --git a/src/squirrel/squirrel/sqobject.cpp b/src/squirrel/squirrel/sqobject.cpp index e699e35e2..7bfc19de3 100644 --- a/src/squirrel/squirrel/sqobject.cpp +++ b/src/squirrel/squirrel/sqobject.cpp @@ -66,10 +66,10 @@ SQRefCounted::~SQRefCounted() } } -void SQWeakRef::Release() { - if(ISREFCOUNTED(_obj._type)) { +void SQWeakRef::Release() { + if(ISREFCOUNTED(_obj._type)) { _obj._unVal.pRefCounted->_weakref = NULL; - } + } sq_delete(this,SQWeakRef); } @@ -126,11 +126,11 @@ bool SQGenerator::Resume(SQVM *v,SQInteger target) SQInteger prevtop=v->_top-v->_stackbase; PUSH_CALLINFO(v,_ci); SQInteger oldstackbase=v->_stackbase; - v->_stackbase=v->_top; - v->ci->_target=target; - v->ci->_generator=SQObjectPtr(this); - v->ci->_vargs.size = _vargsstack.size(); - + v->_stackbase = v->_top; + v->ci->_target = (SQInt32)target; + v->ci->_generator = SQObjectPtr(this); + v->ci->_vargs.size = (unsigned short)_vargsstack.size(); + for(SQInteger i=0;i<_ci._etraps;i++) { v->_etraps.push_back(_etraps.top()); _etraps.pop_back(); @@ -143,10 +143,10 @@ bool SQGenerator::Resume(SQVM *v,SQInteger target) v->_vargsstack.push_back(_vargsstack.back()); _vargsstack.pop_back(); } - v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size; + v->ci->_vargs.base = (unsigned short)(v->_vargsstack.size() - v->ci->_vargs.size); v->_top=v->_stackbase+size; - v->ci->_prevtop=prevtop; - v->ci->_prevstkbase=v->_stackbase-oldstackbase; + v->ci->_prevtop = (SQInt32)prevtop; + v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase); _state=eRunning; return true; } @@ -160,8 +160,8 @@ void SQArray::Extend(const SQArray *a){ const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) { - SQUnsignedInteger nvars=_localvarinfos.size(); - const SQChar *res=NULL; + SQUnsignedInteger nvars=_nlocalvarinfos; + const SQChar *res=NULL; if(nvars>=nseq){ for(SQUnsignedInteger i=0;i=nop) @@ -180,9 +180,9 @@ const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQU SQInteger SQFunctionProto::GetLine(SQInstruction *curr) { - SQInteger op = (SQInteger)(curr-_instructions._vals); + SQInteger op = (SQInteger)(curr-_instructions); SQInteger line=_lineinfos[0]._line; - for(SQUnsignedInteger i=1;i<_lineinfos.size();i++){ + for(SQInteger i=1;i<_nlineinfos;i++){ if(_lineinfos[i]._op>=op) return line; line=_lineinfos[i]._line; @@ -190,7 +190,6 @@ SQInteger SQFunctionProto::GetLine(SQInstruction *curr) return line; } -//#define _ERROR_TRAP() error_trap: #define _CHECK_IO(exp) { if(!exp)return false; } bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) { @@ -286,62 +285,67 @@ bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) return true; } -bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read) +bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) { _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); - _CHECK_IO(_funcproto(_function)->Load(v,up,read)); + SQObjectPtr func; + _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); + ret = SQClosure::Create(_ss(v),_funcproto(func)); return true; } bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) { - SQInteger i,nsize=_literals.size(); + SQInteger i,nliterals = _nliterals,nparameters = _nparameters; + SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; + SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteObject(v,up,write,_sourcename)); _CHECK_IO(WriteObject(v,up,write,_name)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize))); - for(i=0;iSave(v,up,write)); } _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); @@ -350,63 +354,78 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) return true; } -bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read) +bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) { - SQInteger i, nsize = _literals.size(); + SQInteger i, nliterals,nparameters; + SQInteger noutervalues ,nlocalvarinfos ; + SQInteger nlineinfos,ninstructions ,nfunctions ; + SQObjectPtr sourcename, name; SQObjectPtr o; _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(ReadObject(v, up, read, _sourcename)); - _CHECK_IO(ReadObject(v, up, read, _name)); + _CHECK_IO(ReadObject(v, up, read, sourcename)); + _CHECK_IO(ReadObject(v, up, read, name)); + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize))); - for(i = 0;i < nsize; i++){ + _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); + _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); + _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, &ninstructions, sizeof(ninstructions))); + _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); + + SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos); + SQObjectPtr proto = f; //gets a ref in case of failure + f->_sourcename = sourcename; + f->_name = name; + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0;i < nliterals; i++){ _CHECK_IO(ReadObject(v, up, read, o)); - _literals.push_back(o); + f->_literals[i] = o; } _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize))); - for(i = 0; i < nsize; i++){ + + for(i = 0; i < nparameters; i++){ _CHECK_IO(ReadObject(v, up, read, o)); - _parameters.push_back(o); + f->_parameters[i] = o; } _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up,&nsize,sizeof(nsize))); - for(i = 0; i < nsize; i++){ + + for(i = 0; i < noutervalues; i++){ SQUnsignedInteger type; SQObjectPtr name; _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); _CHECK_IO(ReadObject(v, up, read, o)); _CHECK_IO(ReadObject(v, up, read, name)); - _outervalues.push_back(SQOuterVar(name,o, (SQOuterType)type)); + f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); } _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up,&nsize, sizeof(nsize))); - for(i = 0; i < nsize; i++){ + + for(i = 0; i < nlocalvarinfos; i++){ SQLocalVarInfo lvi; _CHECK_IO(ReadObject(v, up, read, lvi._name)); _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); - _localvarinfos.push_back(lvi); + f->_localvarinfos[i] = lvi; } _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, &nsize,sizeof(nsize))); - _lineinfos.resize(nsize); - _CHECK_IO(SafeRead(v,read,up, &_lineinfos[0], sizeof(SQLineInfo)*nsize)); + _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, &nsize, sizeof(nsize))); - _instructions.resize(nsize); - _CHECK_IO(SafeRead(v,read,up, &_instructions[0], sizeof(SQInstruction)*nsize)); + _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize))); - for(i = 0; i < nsize; i++){ - o = SQFunctionProto::Create(); - _CHECK_IO(_funcproto(o)->Load(v, up, read)); - _functions.push_back(o); + for(i = 0; i < nfunctions; i++){ + _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); + f->_functions[i] = o; } - _CHECK_IO(SafeRead(v,read,up, &_stacksize, sizeof(_stacksize))); - _CHECK_IO(SafeRead(v,read,up, &_bgenerator, sizeof(_bgenerator))); - _CHECK_IO(SafeRead(v,read,up, &_varparams, sizeof(_varparams))); + _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; } @@ -474,7 +493,8 @@ void SQInstance::Mark(SQCollectable **chain) { START_MARK() _class->Mark(chain); - for(SQUnsignedInteger i =0; i< _nvalues; i++) { + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger i =0; i< nvalues; i++) { SQSharedState::MarkObject(_values[i], chain); } END_MARK() @@ -512,3 +532,4 @@ void SQUserData::Mark(SQCollectable **chain){ void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } #endif + diff --git a/src/squirrel/squirrel/sqobject.h b/src/squirrel/squirrel/sqobject.h index ee655b08e..02d59678e 100644 --- a/src/squirrel/squirrel/sqobject.h +++ b/src/squirrel/squirrel/sqobject.h @@ -76,7 +76,7 @@ struct SQObjectPtr; #define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ { \ unval.pRefCounted->_uiRef++; \ - } + } #define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \ { \ @@ -258,12 +258,30 @@ struct SQObjectPtr : public SQObject } inline void Null() { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType = _type; + unOldVal = _unVal; + _type = OT_NULL; + _unVal.pUserPointer = NULL; + __Release(tOldType,unOldVal); + } + inline SQObjectPtr& operator=(SQInteger i) + { __Release(_type,_unVal); - _type=OT_NULL; - _unVal.pUserPointer=NULL; + _unVal.nInteger = i; + _type = OT_INTEGER; + return *this; + } + inline SQObjectPtr& operator=(SQFloat f) + { + __Release(_type,_unVal); + _unVal.fFloat = f; + _type = OT_FLOAT; + return *this; } inline SQObjectPtr& operator=(const SQObjectPtr& obj) - { + { SQObjectType tOldType; SQObjectValue unOldVal; tOldType=_type; @@ -275,7 +293,7 @@ struct SQObjectPtr : public SQObject return *this; } inline SQObjectPtr& operator=(const SQObject& obj) - { + { SQObjectType tOldType; SQObjectValue unOldVal; tOldType=_type; diff --git a/src/squirrel/squirrel/sqopcodes.h b/src/squirrel/squirrel/sqopcodes.h index be7fe29a2..a05788bf2 100644 --- a/src/squirrel/squirrel/sqopcodes.h +++ b/src/squirrel/squirrel/sqopcodes.h @@ -7,7 +7,7 @@ enum BitWiseOP { BW_AND = 0, - BW_OR = 2, //like ADD + BW_OR = 2, BW_XOR = 3, BW_SHIFTL = 4, BW_SHIFTR = 5, @@ -16,78 +16,80 @@ enum BitWiseOP { enum CmpOP { CMP_G = 0, - CMP_GE = 2, //like ADD + CMP_GE = 2, CMP_L = 3, CMP_LE = 4 }; enum SQOpcode { - _OP_LINE= 0x00, + _OP_LINE= 0x00, _OP_LOAD= 0x01, _OP_LOADINT= 0x02, - _OP_DLOAD= 0x03, - _OP_TAILCALL= 0x04, - _OP_CALL= 0x05, - _OP_PREPCALL= 0x06, - _OP_PREPCALLK= 0x07, - _OP_GETK= 0x08, - _OP_MOVE= 0x09, - _OP_NEWSLOT= 0x0A, - _OP_DELETE= 0x0B, - _OP_SET= 0x0C, - _OP_GET= 0x0D, - _OP_EQ= 0x0E, - _OP_NE= 0x0F, - _OP_ARITH= 0x10, - _OP_BITW= 0x11, - _OP_RETURN= 0x12, - _OP_LOADNULLS= 0x13, - _OP_LOADROOTTABLE= 0x14, - _OP_LOADBOOL= 0x15, - _OP_DMOVE= 0x16, - _OP_JMP= 0x17, - _OP_JNZ= 0x18, - _OP_JZ= 0x19, - _OP_LOADFREEVAR= 0x1A, - _OP_VARGC= 0x1B, - _OP_GETVARGV= 0x1C, - _OP_NEWTABLE= 0x1D, - _OP_NEWARRAY= 0x1E, - _OP_APPENDARRAY= 0x1F, - _OP_GETPARENT= 0x20, - _OP_COMPARITH= 0x21, - _OP_COMPARITHL= 0x22, - _OP_INC= 0x23, - _OP_INCL= 0x24, - _OP_PINC= 0x25, - _OP_PINCL= 0x26, - _OP_CMP= 0x27, - _OP_EXISTS= 0x28, - _OP_INSTANCEOF= 0x29, - _OP_AND= 0x2A, - _OP_OR= 0x2B, - _OP_NEG= 0x2C, - _OP_NOT= 0x2D, - _OP_BWNOT= 0x2E, - _OP_CLOSURE= 0x2F, - _OP_YIELD= 0x30, - _OP_RESUME= 0x31, - _OP_FOREACH= 0x32, - _OP_DELEGATE= 0x33, - _OP_CLONE= 0x34, - _OP_TYPEOF= 0x35, - _OP_PUSHTRAP= 0x36, - _OP_POPTRAP= 0x37, - _OP_THROW= 0x38, - _OP_CLASS= 0x39, - _OP_NEWSLOTA= 0x3A -}; + _OP_LOADFLOAT= 0x03, + _OP_DLOAD= 0x04, + _OP_TAILCALL= 0x05, + _OP_CALL= 0x06, + _OP_PREPCALL= 0x07, + _OP_PREPCALLK= 0x08, + _OP_GETK= 0x09, + _OP_MOVE= 0x0A, + _OP_NEWSLOT= 0x0B, + _OP_DELETE= 0x0C, + _OP_SET= 0x0D, + _OP_GET= 0x0E, + _OP_EQ= 0x0F, + _OP_NE= 0x10, + _OP_ARITH= 0x11, + _OP_BITW= 0x12, + _OP_RETURN= 0x13, + _OP_LOADNULLS= 0x14, + _OP_LOADROOTTABLE= 0x15, + _OP_LOADBOOL= 0x16, + _OP_DMOVE= 0x17, + _OP_JMP= 0x18, + _OP_JNZ= 0x19, + _OP_JZ= 0x1A, + _OP_LOADFREEVAR= 0x1B, + _OP_VARGC= 0x1C, + _OP_GETVARGV= 0x1D, + _OP_NEWTABLE= 0x1E, + _OP_NEWARRAY= 0x1F, + _OP_APPENDARRAY= 0x20, + _OP_GETPARENT= 0x21, + _OP_COMPARITH= 0x22, + _OP_COMPARITHL= 0x23, + _OP_INC= 0x24, + _OP_INCL= 0x25, + _OP_PINC= 0x26, + _OP_PINCL= 0x27, + _OP_CMP= 0x28, + _OP_EXISTS= 0x29, + _OP_INSTANCEOF= 0x2A, + _OP_AND= 0x2B, + _OP_OR= 0x2C, + _OP_NEG= 0x2D, + _OP_NOT= 0x2E, + _OP_BWNOT= 0x2F, + _OP_CLOSURE= 0x30, + _OP_YIELD= 0x31, + _OP_RESUME= 0x32, + _OP_FOREACH= 0x33, + _OP_POSTFOREACH= 0x34, + _OP_DELEGATE= 0x35, + _OP_CLONE= 0x36, + _OP_TYPEOF= 0x37, + _OP_PUSHTRAP= 0x38, + _OP_POPTRAP= 0x39, + _OP_THROW= 0x3A, + _OP_CLASS= 0x3B, + _OP_NEWSLOTA= 0x3C, +}; -struct SQInstructionDesc { - const SQChar *name; -}; +struct SQInstructionDesc { + const SQChar *name; +}; -struct SQInstruction +struct SQInstruction { SQInstruction(){}; SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) @@ -95,8 +97,8 @@ struct SQInstruction _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; } - - + + SQInt32 _arg1; unsigned char op; unsigned char _arg0; diff --git a/src/squirrel/squirrel/sqpcheader.h b/src/squirrel/squirrel/sqpcheader.h index db49f5e0d..a3fb037e4 100644 --- a/src/squirrel/squirrel/sqpcheader.h +++ b/src/squirrel/squirrel/sqpcheader.h @@ -4,7 +4,7 @@ #if defined(_MSC_VER) && defined(_DEBUG) #include -#endif +#endif #include #include diff --git a/src/squirrel/squirrel/sqstate.cpp b/src/squirrel/squirrel/sqstate.cpp index 85da8c8c3..150bb56e8 100644 --- a/src/squirrel/squirrel/sqstate.cpp +++ b/src/squirrel/squirrel/sqstate.cpp @@ -38,10 +38,10 @@ SQSharedState::SQSharedState() bool CompileTypemask(SQIntVec &res,const SQChar *typemask) { SQInteger i = 0; - + SQInteger mask = 0; while(typemask[i] != 0) { - + switch(typemask[i]){ case 'o': mask |= _RT_NULL; break; case 'i': mask |= _RT_INTEGER; break; @@ -65,15 +65,15 @@ bool CompileTypemask(SQIntVec &res,const SQChar *typemask) return false; } i++; - if(typemask[i] == '|') { - i++; + if(typemask[i] == '|') { + i++; if(typemask[i] == 0) return false; - continue; + continue; } res.push_back(mask); mask = 0; - + } return true; } @@ -95,7 +95,7 @@ SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz) } void SQSharedState::Init() -{ +{ _scratchpad=NULL; _scratchpadsize=0; #ifndef NO_GARBAGE_COLLECTOR @@ -164,10 +164,9 @@ SQSharedState::~SQSharedState() _refs_table.Finalize(); _table(_registry)->Finalize(); _table(_metamethodsmap)->Finalize(); -// _refs_table = _null_; _registry = _null_; _metamethodsmap = _null_; - while(!_systemstrings->empty()){ + while(!_systemstrings->empty()) { _systemstrings->back()=_null_; _systemstrings->pop_back(); } @@ -183,17 +182,15 @@ SQSharedState::~SQSharedState() _class_default_delegate=_null_; _instance_default_delegate=_null_; _weakref_default_delegate=_null_; - + #ifndef NO_GARBAGE_COLLECTOR - - SQCollectable *t=_gc_chain; SQCollectable *nx=NULL; - while(t){ + while(t) { t->_uiRef++; t->Finalize(); nx=t->_next; - if(--t->_uiRef==0) + if(--t->_uiRef == 0) t->Release(); t=nx; } @@ -203,6 +200,7 @@ SQSharedState::~SQSharedState() _gc_chain->Release(); } #endif + sq_delete(_types,SQObjectPtrVec); sq_delete(_systemstrings,SQObjectPtrVec); sq_delete(_metamethods,SQObjectPtrVec); @@ -245,8 +243,8 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm) { SQInteger n=0; SQCollectable *tchain=NULL; - SQVM *vms=_thread(_root_vm); - + SQVM *vms = _thread(_root_vm); + vms->Mark(&tchain); SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed(); _refs_table.Mark(&tchain); @@ -262,25 +260,25 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm) MarkObject(_class_default_delegate,&tchain); MarkObject(_instance_default_delegate,&tchain); MarkObject(_weakref_default_delegate,&tchain); - - SQCollectable *t=_gc_chain; - SQCollectable *nx=NULL; - while(t){ + + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + while(t) { t->_uiRef++; t->Finalize(); - nx=t->_next; - if(--t->_uiRef==0) + nx = t->_next; + if(--t->_uiRef == 0) t->Release(); - t=nx; + t = nx; n++; } - t=tchain; - while(t){ + t = tchain; + while(t) { t->UnMark(); - t=t->_next; + t = t->_next; } - _gc_chain=tchain; + _gc_chain = tchain; SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed(); assert(z == x); return n; @@ -290,36 +288,36 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm) #ifndef NO_GARBAGE_COLLECTOR void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) { - c->_prev=NULL; - c->_next=*chain; - if(*chain) (*chain)->_prev=c; - *chain=c; + c->_prev = NULL; + c->_next = *chain; + if(*chain) (*chain)->_prev = c; + *chain = c; } void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) { - if(c->_prev) c->_prev->_next=c->_next; - else *chain=c->_next; + if(c->_prev) c->_prev->_next = c->_next; + else *chain = c->_next; if(c->_next) - c->_next->_prev=c->_prev; - c->_next=NULL; - c->_prev=NULL; + c->_next->_prev = c->_prev; + c->_next = NULL; + c->_prev = NULL; } #endif SQChar* SQSharedState::GetScratchPad(SQInteger size) { SQInteger newsize; - if(size>0){ - if(_scratchpadsize>1); - _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize=newsize; - - }else if(_scratchpadsize>=(size<<5)){ - newsize=_scratchpadsize>>1; - _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize=newsize; + if(size>0) { + if(_scratchpadsize < size) { + newsize = size + (size>>1); + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + + }else if(_scratchpadsize >= (size<<5)) { + newsize = _scratchpadsize >> 1; + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; } } return _scratchpad; @@ -332,7 +330,7 @@ RefTable::RefTable() void RefTable::Finalize() { - RefNode *nodes = (RefNode *)&_buckets[_numofslots]; + RefNode *nodes = _nodes; for(SQUnsignedInteger n = 0; n < _numofslots; n++) { nodes->obj = _null_; nodes++; @@ -341,12 +339,13 @@ void RefTable::Finalize() RefTable::~RefTable() { - SQ_FREE(_buckets,_buffersize); + SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); } + #ifndef NO_GARBAGE_COLLECTOR void RefTable::Mark(SQCollectable **chain) { - RefNode *nodes = (RefNode *)&_buckets[_numofslots]; + RefNode *nodes = (RefNode *)_nodes; for(SQUnsignedInteger n = 0; n < _numofslots; n++) { if(type(nodes->obj) != OT_NULL) { SQSharedState::MarkObject(nodes->obj,chain); @@ -355,6 +354,7 @@ void RefTable::Mark(SQCollectable **chain) } } #endif + void RefTable::AddRef(SQObject &obj) { SQHash mainpos; @@ -370,7 +370,7 @@ SQBool RefTable::Release(SQObject &obj) RefNode *ref = Get(obj,mainpos,&prev,false); if(ref) { if(--ref->refs == 0) { - ref->obj = _null_; + SQObjectPtr o = ref->obj; if(prev) { prev->next = ref->next; } @@ -380,32 +380,38 @@ SQBool RefTable::Release(SQObject &obj) ref->next = _freelist; _freelist = ref; _slotused--; + ref->obj = _null_; //<>test for shrink? return SQTrue; } } + else { + assert(0); + } return SQFalse; } void RefTable::Resize(SQUnsignedInteger size) { - RefNode **oldbuffer = _buckets; - RefNode *oldnodes = (RefNode *)&_buckets[_numofslots]; + RefNode **oldbucks = _buckets; + RefNode *t = _nodes; SQUnsignedInteger oldnumofslots = _numofslots; - SQUnsignedInteger oldbuffersize = _buffersize; AllocNodes(size); //rehash + SQUnsignedInteger nfound = 0; for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { - if(type(oldnodes->obj) != OT_NULL) { + if(type(t->obj) != OT_NULL) { //add back; - assert(oldnodes->refs != 0); - RefNode *nn = Add(::HashObj(oldnodes->obj)&(_numofslots-1),oldnodes->obj); - nn->refs = oldnodes->refs; - oldnodes->obj = _null_; + assert(t->refs != 0); + RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); + nn->refs = t->refs; + t->obj = _null_; + nfound++; } - oldnodes++; + t++; } - SQ_FREE(oldbuffer,oldbuffersize); + assert(nfound == oldnumofslots); + SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); } RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) @@ -434,7 +440,9 @@ RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bo } if(ref == NULL && add) { if(_numofslots == _slotused) { + assert(_freelist == 0); Resize(_numofslots*2); + mainpos = ::HashObj(obj)&(_numofslots-1); } ref = Add(mainpos,obj); } @@ -444,11 +452,10 @@ RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bo void RefTable::AllocNodes(SQUnsignedInteger size) { RefNode **bucks; - RefNode *firstnode; - _buffersize = size * sizeof(RefNode *) + size * sizeof(RefNode); - bucks = (RefNode **)SQ_MALLOC(_buffersize); - firstnode = (RefNode *)&bucks[size]; - RefNode *temp = firstnode; + RefNode *nodes; + bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); + nodes = (RefNode *)&bucks[size]; + RefNode *temp = nodes; SQUnsignedInteger n; for(n = 0; n < size - 1; n++) { bucks[n] = NULL; @@ -461,7 +468,8 @@ void RefTable::AllocNodes(SQUnsignedInteger size) temp->refs = 0; new (&temp->obj) SQObjectPtr; temp->next = NULL; - _freelist = firstnode; + _freelist = nodes; + _nodes = nodes; _buckets = bucks; _slotused = 0; _numofslots = size; @@ -483,14 +491,13 @@ StringTable::StringTable() StringTable::~StringTable() { SQ_FREE(_strings,sizeof(SQString*)*_numofslots); - _strings=NULL; + _strings = NULL; } void StringTable::AllocNodes(SQInteger size) { - _numofslots=size; - //_slotused=0; - _strings=(SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); + _numofslots = size; + _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); memset(_strings,0,sizeof(SQString*)*_numofslots); } @@ -542,7 +549,7 @@ void StringTable::Remove(SQString *bs) SQString *s; SQString *prev=NULL; SQHash h = bs->_hash&(_numofslots - 1); - + for (s = _strings[h]; s; ){ if(s == bs){ if(prev) diff --git a/src/squirrel/squirrel/sqstate.h b/src/squirrel/squirrel/sqstate.h index fc2981617..fb6766510 100644 --- a/src/squirrel/squirrel/sqstate.h +++ b/src/squirrel/squirrel/sqstate.h @@ -44,7 +44,7 @@ private: void AllocNodes(SQUnsignedInteger size); SQUnsignedInteger _numofslots; SQUnsignedInteger _slotused; - SQUnsignedInteger _buffersize; + RefNode *_nodes; RefNode *_freelist; RefNode **_buckets; }; @@ -63,7 +63,7 @@ public: SQChar* GetScratchPad(SQInteger size); SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); #ifndef NO_GARBAGE_COLLECTOR - SQInteger CollectGarbage(SQVM *vm); + SQInteger CollectGarbage(SQVM *vm); static void MarkObject(SQObjectPtr &o,SQCollectable **chain); #endif SQObjectPtrVec *_metamethods; @@ -98,7 +98,7 @@ public: static SQRegFunction _instance_default_delegate_funcz[]; SQObjectPtr _weakref_default_delegate; static SQRegFunction _weakref_default_delegate_funcz[]; - + SQCOMPILERERROR _compilererrorhandler; SQPRINTFUNCTION _printfunc; bool _debuginfo; @@ -111,16 +111,16 @@ private: #define _sp(s) (_sharedstate->GetScratchPad(s)) #define _spval (_sharedstate->GetScratchPad(-1)) -#define _table_ddel _table(_sharedstate->_table_default_delegate) -#define _array_ddel _table(_sharedstate->_array_default_delegate) -#define _string_ddel _table(_sharedstate->_string_default_delegate) -#define _number_ddel _table(_sharedstate->_number_default_delegate) -#define _generator_ddel _table(_sharedstate->_generator_default_delegate) -#define _closure_ddel _table(_sharedstate->_closure_default_delegate) -#define _thread_ddel _table(_sharedstate->_thread_default_delegate) -#define _class_ddel _table(_sharedstate->_class_default_delegate) -#define _instance_ddel _table(_sharedstate->_instance_default_delegate) -#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) +#define _table_ddel _table(_sharedstate->_table_default_delegate) +#define _array_ddel _table(_sharedstate->_array_default_delegate) +#define _string_ddel _table(_sharedstate->_string_default_delegate) +#define _number_ddel _table(_sharedstate->_number_default_delegate) +#define _generator_ddel _table(_sharedstate->_generator_default_delegate) +#define _closure_ddel _table(_sharedstate->_closure_default_delegate) +#define _thread_ddel _table(_sharedstate->_thread_default_delegate) +#define _class_ddel _table(_sharedstate->_class_default_delegate) +#define _instance_ddel _table(_sharedstate->_instance_default_delegate) +#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) #ifdef SQUNICODE //rsl REAL STRING LEN #define rsl(l) ((l)<<1) diff --git a/src/squirrel/squirrel/sqtable.cpp b/src/squirrel/squirrel/sqtable.cpp index 71c2c0ed6..1b3acd0b7 100644 --- a/src/squirrel/squirrel/sqtable.cpp +++ b/src/squirrel/squirrel/sqtable.cpp @@ -20,7 +20,7 @@ SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) void SQTable::Remove(const SQObjectPtr &key) { - + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); if (n) { n->val = n->key = _null_; @@ -63,7 +63,7 @@ void SQTable::Rehash(bool force) if (type(old->key) != OT_NULL) NewSlot(old->key,old->val); } - for(SQInteger k=0;kkey) & (_numofnodes - 1); _HashNode *othern; /* main position of colliding node */ - + if (mp > n && (othern = &_nodes[mph]) != mp){ /* yes; move colliding node into free position */ while (othern->next != mp){ @@ -177,8 +177,20 @@ bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) return false; } -void SQTable::Finalize() +void SQTable::_ClearNodes() { for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; } - SetDelegate(NULL); +} + +void SQTable::Finalize() +{ + _ClearNodes(); + SetDelegate(NULL); +} + +void SQTable::Clear() +{ + _ClearNodes(); + _usednodes = 0; + Rehash(true); } diff --git a/src/squirrel/squirrel/sqtable.h b/src/squirrel/squirrel/sqtable.h index 742074f43..67a88de44 100644 --- a/src/squirrel/squirrel/sqtable.h +++ b/src/squirrel/squirrel/sqtable.h @@ -22,7 +22,7 @@ inline SQHash HashObj(const SQObjectPtr &key) } } -struct SQTable : public SQDelegable +struct SQTable : public SQDelegable { private: struct _HashNode @@ -36,11 +36,12 @@ private: _HashNode *_nodes; SQInteger _numofnodes; SQInteger _usednodes; - + /////////////////////////// void AllocNodes(SQInteger nSize); void Rehash(bool force); SQTable(SQSharedState *ss, SQInteger nInitialSize); + void _ClearNodes(); public: static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) { @@ -58,7 +59,7 @@ public: for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); } -#ifndef NO_GARBAGE_COLLECTOR +#ifndef NO_GARBAGE_COLLECTOR void Mark(SQCollectable **chain); #endif inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) @@ -77,13 +78,14 @@ public: //returns true if a new slot has been created false if it was already present bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); - + SQInteger CountUsed(){ return _usednodes;} + void Clear(); void Release() { sq_delete(this, SQTable); } - + }; #endif //_SQTABLE_H_ diff --git a/src/squirrel/squirrel/squserdata.h b/src/squirrel/squirrel/squserdata.h index 8b6b43148..d19255932 100644 --- a/src/squirrel/squirrel/squserdata.h +++ b/src/squirrel/squirrel/squserdata.h @@ -28,7 +28,7 @@ struct SQUserData : SQDelegable this->~SQUserData(); SQ_FREE(this, sizeof(SQUserData) + tsize); } - + SQInteger _size; SQRELEASEHOOK _hook; SQUserPointer _typetag; diff --git a/src/squirrel/squirrel/squtils.h b/src/squirrel/squirrel/squtils.h index 3f866210c..77ccdb2ff 100644 --- a/src/squirrel/squirrel/squtils.h +++ b/src/squirrel/squirrel/squtils.h @@ -4,9 +4,9 @@ #define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} #define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} -#define SQ_MALLOC(__size) sq_vm_malloc(__size); -#define SQ_FREE(__ptr,__size) sq_vm_free(__ptr,__size); -#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc(__ptr,__oldsize,__size); +#define SQ_MALLOC(__size) sq_vm_malloc((__size)); +#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); //sqvector mini vector class, supports objects by value template class sqvector diff --git a/src/squirrel/squirrel/sqvm.cpp b/src/squirrel/squirrel/sqvm.cpp index 888d34277..25ebcf984 100644 --- a/src/squirrel/squirrel/sqvm.cpp +++ b/src/squirrel/squirrel/sqvm.cpp @@ -14,7 +14,7 @@ #include "sqarray.h" #include "sqclass.h" -#define TOP() (_stack[_top-1]) +#define TOP() (_stack._vals[_top-1]) bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) { @@ -31,7 +31,7 @@ bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,con case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } } - } + } else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} trg = res; return true; @@ -41,30 +41,36 @@ bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1, { if(sq_isnumeric(o1) && sq_isnumeric(o2)) { if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) { + SQInteger res, i1 = _integer(o1), i2 = _integer(o2); switch(op) { - case '+': trg = _integer(o1) + _integer(o2); break; - case '-': trg = _integer(o1) - _integer(o2); break; - case '/': if(_integer(o2) == 0) { Raise_Error(_SC("division by zero")); return false; } - trg = _integer(o1) / _integer(o2); + case '+': res = i1 + i2; break; + case '-': res = i1 - i2; break; + case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; } + res = i1 / i2; break; - case '*': trg = _integer(o1) * _integer(o2); break; - case '%': trg = _integer(o1) % _integer(o2); break; + case '*': res = i1 * i2; break; + case '%': res = i1 % i2; break; + default: res = 0xDEADBEEF; } + trg = res; }else{ + SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); switch(op) { - case '+': trg = tofloat(o1) + tofloat(o2); break; - case '-': trg = tofloat(o1) - tofloat(o2); break; - case '/': trg = tofloat(o1) / tofloat(o2); break; - case '*': trg = tofloat(o1) * tofloat(o2); break; - case '%': trg = SQFloat(fmod((double)tofloat(o1),(double)tofloat(o2))); break; + case '+': res = f1 + f2; break; + case '-': res = f1 - f2; break; + case '/': res = f1 / f2; break; + case '*': res = f1 * f2; break; + case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; + default: res = 0x0f; } - } + trg = res; + } } else { if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){ if(!StringCat(o1, o2, trg)) return false; } - else if(!ArithMetaMethod(op,o1,o2,trg)) { - Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false; + else if(!ArithMetaMethod(op,o1,o2,trg)) { + Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false; } } return true; @@ -101,6 +107,7 @@ void SQVM::Finalize() SQVM::~SQVM() { Finalize(); + sq_free(_callsstack,_alloccallsstacksize*sizeof(CallInfo)); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } @@ -124,7 +131,7 @@ bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) { - + switch(type(o)) { case OT_INTEGER: trg = -_integer(o); @@ -148,7 +155,7 @@ bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) return false; } -#define _RET_SUCCEED(exp) { result = (exp); return true; } +#define _RET_SUCCEED(exp) { result = (exp); return true; } bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) { if(type(o1)==type(o2)){ @@ -164,18 +171,21 @@ bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) case OT_TABLE: case OT_USERDATA: case OT_INSTANCE: - Push(o1);Push(o2); - if(_delegable(o1)->_delegate)CallMetaMethod(_delegable(o1),MT_CMP,2,res); - break; - default: break; //shutup compiler + if(_delegable(o1)->_delegate) { + Push(o1);Push(o2); + if(CallMetaMethod(_delegable(o1),MT_CMP,2,res)) break; + } + //continues through (no break needed) + default: + _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); } if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } _RET_SUCCEED(_integer(res)); - + } else{ if(sq_isnumeric(o1) && sq_isnumeric(o2)){ - if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) { + if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) { if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } _RET_SUCCEED(1); @@ -189,7 +199,7 @@ bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);} else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);} else { Raise_CompareError(o1,o2); return false; } - + } assert(0); _RET_SUCCEED(0); //cannot happen @@ -204,7 +214,7 @@ bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObject case CMP_GE: res = (r >= 0)?_true_:_false_; return true; case CMP_L: res = (r < 0)?_true_:_false_; return true; case CMP_LE: res = (r <= 0)?_true_:_false_; return true; - + } assert(0); } @@ -251,7 +261,7 @@ bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr & ToString(obj, b); SQInteger l = _string(a)->_len , ol = _string(b)->_len; SQChar *s = _sp(rsl(l + ol + 1)); - memcpy(s, _stringval(a), rsl(l)); + memcpy(s, _stringval(a), rsl(l)); memcpy(s + l, _stringval(b), rsl(ol)); dest = SQString::Create(_ss(this), _spval, l + ol); return true; @@ -287,7 +297,7 @@ const SQChar *IdType2Name(SQObjectType type) const SQChar *GetTypeName(const SQObjectPtr &obj1) { - return IdType2Name(type(obj1)); + return IdType2Name(type(obj1)); } void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) @@ -303,17 +313,20 @@ void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) { _stack.resize(stacksize); - _callsstack.reserve(4); + //_callsstack.reserve(4); + _alloccallsstacksize = 4; + _callsstacksize = 0; + _callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo)); _stackbase = 0; _top = 0; - if(!friendvm) + if(!friendvm) _roottable = SQTable::Create(_ss(this), 0); else { _roottable = friendvm->_roottable; _errorhandler = friendvm->_errorhandler; _debughook = friendvm->_debughook; } - + sq_base_register(this); return true; } @@ -323,11 +336,11 @@ extern SQInstructionDesc g_InstrDesc[]; bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall) { SQFunctionProto *func = _funcproto(closure->_function); - - const SQInteger paramssize = func->_parameters.size(); + + const SQInteger paramssize = func->_nparameters; const SQInteger newtop = stackbase + func->_stacksize; - - + + if (paramssize != nargs) { if(func->_varparams) { @@ -336,8 +349,8 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteg return false; } for(SQInteger n = 0; n < nargs - paramssize; n++) { - _vargsstack.push_back(_stack[stackbase+paramssize+n]); - _stack[stackbase+paramssize+n] = _null_; + _vargsstack.push_back(_stack._vals[stackbase+paramssize+n]); + _stack._vals[stackbase+paramssize+n] = _null_; } } else { @@ -347,37 +360,35 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteg } if(type(closure->_env) == OT_WEAKREF) { - _stack[stackbase] = _weakref(closure->_env)->_obj; + _stack._vals[stackbase] = _weakref(closure->_env)->_obj; } if (!tailcall) { CallInfo lc; lc._etraps = 0; - lc._prevstkbase = stackbase - _stackbase; - lc._target = target; - lc._prevtop = _top - _stackbase; + lc._prevstkbase = (SQInt32) ( stackbase - _stackbase ); + lc._target = (SQInt32) target; + lc._prevtop = (SQInt32) (_top - _stackbase); lc._ncalls = 1; lc._root = SQFalse; PUSH_CALLINFO(this, lc); } else { ci->_ncalls++; - if(ci->_vargs.size) PopVarArgs(ci->_vargs); } - ci->_vargs.size = (nargs - paramssize); - ci->_vargs.base = _vargsstack.size()-(ci->_vargs.size); + ci->_vargs.size = (SQInt32)(nargs - paramssize); + ci->_vargs.base = (SQInt32) (_vargsstack.size()-(ci->_vargs.size)); ci->_closure._unVal.pClosure = closure; ci->_closure._type = OT_CLOSURE; - ci->_iv = &func->_instructions; - ci->_literals = &func->_literals; + ci->_literals = func->_literals; + ci->_ip = func->_instructions; //grows the stack if needed if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) { _stack.resize(_stack.size() + (func->_stacksize<<1)); } - + _top = newtop; _stackbase = stackbase; - ci->_ip = ci->_iv->_vals; return true; } @@ -386,7 +397,7 @@ bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) for(SQInteger i=0;i_ncalls;i++) CallDebugHook(_SC('r')); - + SQBool broot = ci->_root; SQInteger last_top = _top; SQInteger target = ci->_target; @@ -396,20 +407,20 @@ bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) if(ci->_vargs.size) PopVarArgs(ci->_vargs); POP_CALLINFO(this); if (broot) { - if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack[oldstackbase+_arg1]; + if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack._vals[oldstackbase+_arg1]; else retval = _null_; } else { if(target != -1) { //-1 is when a class contructor ret value has to be ignored if (_arg0 != MAX_FUNC_STACKSIZE) - STK(target) = _stack[oldstackbase+_arg1]; + STK(target) = _stack._vals[oldstackbase+_arg1]; else STK(target) = _null_; } } - while (last_top >= _top) _stack[last_top--].Null(); - assert(oldstackbase >= _stackbase); + while (last_top >= _top) _stack._vals[last_top--].Null(); + assert(oldstackbase >= _stackbase); return broot?true:false; } @@ -463,24 +474,24 @@ void SQVM::PopVarArgs(VarArgs &vargs) _vargsstack.pop_back(); } -#define _FINISH(stoploop) {finished = stoploop; return true; } -bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr -&o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished) +#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } +bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr +&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump) { SQInteger nrefidx; switch(type(o1)) { case OT_TABLE: - if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(true); - o4 = (SQInteger)nrefidx; _FINISH(false); + if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); case OT_ARRAY: - if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(true); - o4 = (SQInteger) nrefidx; _FINISH(false); + if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger) nrefidx; _FINISH(1); case OT_STRING: - if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(true); - o4 = (SQInteger)nrefidx; _FINISH(false); + if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); case OT_CLASS: - if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(true); - o4 = (SQInteger)nrefidx; _FINISH(false); + if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); case OT_USERDATA: case OT_INSTANCE: if(_delegable(o1)->_delegate) { @@ -489,19 +500,19 @@ bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr Push(o4); if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){ o4 = o2 = itr; - if(type(itr) == OT_NULL) _FINISH(true); + if(type(itr) == OT_NULL) _FINISH(exitpos); if(!Get(o1, itr, o3, false,false)) { Raise_Error(_SC("_nexti returned an invalid idx")); return false; } - _FINISH(false); + _FINISH(1); } Raise_Error(_SC("_nexti failed")); return false; } break; case OT_GENERATOR: - if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(true); + if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); if(_generator(o1)->_state == SQGenerator::eSuspended) { SQInteger idx = 0; if(type(o4) == OT_INTEGER) { @@ -510,9 +521,9 @@ bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr o2 = idx; o4 = idx; _generator(o1)->Resume(this, arg_2+1); - _FINISH(false); + _FINISH(0); } - default: + default: Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); } return false; //cannot be hit(just to avoid warnings) @@ -539,7 +550,7 @@ bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2) trg = o1; return true; } -#define COND_LITERAL (arg3!=0?(*ci->_literals)[arg1]:STK(arg1)) +#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) #define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} } @@ -549,7 +560,7 @@ bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) { SQInteger nouters; SQClosure *closure = SQClosure::Create(_ss(this), func); - if((nouters = func->_outervalues.size())) { + if((nouters = func->_noutervalues)) { closure->_outervalues.reserve(nouters); for(SQInteger i = 0; i_outervalues[i]; @@ -663,11 +674,12 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn SQInteger traps = 0; //temp_reg vars for OP_CALL SQInteger ct_target; - bool ct_tailcall; + SQInteger ct_stackbase; + bool ct_tailcall; switch(et) { - case ET_CALL: - if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) { + case ET_CALL: + if(!StartCall(_closure(closure), _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; @@ -678,10 +690,11 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn case ET_RESUME_VM: traps = _suspended_traps; ci->_root = _suspended_root; + ci->_vargs = _suspend_varargs; _suspended = SQFalse; break; } - + exception_restore: // { @@ -696,63 +709,72 @@ exception_restore: if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) CallDebugHook(_SC('l'),arg1); continue; - case _OP_LOAD: TARGET = (*ci->_literals)[arg1]; continue; + case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; case _OP_LOADINT: TARGET = (SQInteger)arg1; continue; - case _OP_DLOAD: TARGET = (*ci->_literals)[arg1]; STK(arg2) = (*ci->_literals)[arg3];continue; + case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue; + 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){ ct_tailcall = true; if(ci->_vargs.size) PopVarArgs(ci->_vargs); for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); ct_target = ci->_target; + ct_stackbase = _stackbase; goto common_call; } case _OP_CALL: { ct_tailcall = false; ct_target = arg0; temp_reg = STK(arg1); + ct_stackbase = _stackbase+arg2; + common_call: SQInteger last_top = _top; switch (type(temp_reg)) { case OT_CLOSURE:{ - _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_tailcall?_stackbase:_stackbase+arg2, ct_tailcall)); + _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(gen->Yield(this)); Return(1, ct_target, temp_reg); + + + + STK(ct_target) = gen; - while (last_top >= _top) _stack[last_top--].Null(); + while (last_top >= _top) _stack._vals[last_top--].Null(); continue; } if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) CallDebugHook(_SC('c')); } - break; + continue; case OT_NATIVECLOSURE: { bool suspend; - _GUARD(CallNative(_nativeclosure(temp_reg), arg3, _stackbase+arg2, ct_tailcall, temp_reg,suspend)); + _GUARD(CallNative(_nativeclosure(temp_reg), arg3, ct_stackbase, temp_reg,suspend)); if(suspend){ _suspended = SQTrue; _suspended_target = ct_target; _suspended_root = ci->_root; _suspended_traps = traps; + _suspend_varargs = ci->_vargs; outres = temp_reg; return true; } - if(ct_target != -1) { //skip return value for contructors + if(ct_target != -1) { //skip return value for constructors STK(ct_target) = temp_reg; } } - break; + continue; case OT_CLASS:{ SQObjectPtr inst; _GUARD(CreateClassInstance(_class(temp_reg),inst,temp_reg)); STK(ct_target) = inst; - ct_target = -1; //fakes return value target so that is not overwritten by the contructor + ct_target = -1; //fakes return value target so that is not overwritten by the constructor if(type(temp_reg) != OT_NULL) { - _stack[_stackbase+arg2] = inst; - goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the contructor) + _stack._vals[ct_stackbase] = inst; + goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the constructor) } } break; @@ -776,31 +798,27 @@ common_call: } continue; case _OP_PREPCALL: - if (!Get(STK(arg2), STK(arg1), temp_reg, false,true)) - { Raise_IdxError(STK(arg1)); SQ_THROW(); } - goto common_prepcall; case _OP_PREPCALLK: - if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg,false,true)) { - if(type(STK(arg2)) == OT_CLASS) { //hack? - if(_class_ddel->Get((*ci->_literals)[arg1],temp_reg)) { - STK(arg3) = STK(arg2); + { + SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); + SQObjectPtr &o = STK(arg2); + if (!Get(o, key, temp_reg,false,true)) { + if(type(o) == OT_CLASS) { //hack? + if(_class_ddel->Get(key,temp_reg)) { + STK(arg3) = o; TARGET = temp_reg; continue; } } - { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();} - } -common_prepcall: - if(type(STK(arg2)) == OT_CLASS) { - STK(arg3) = STK(0); // this - } - else { - STK(arg3) = STK(arg2); + { Raise_IdxError(key); SQ_THROW();} } + + STK(arg3) = type(o) == OT_CLASS?STK(0):o; TARGET = temp_reg; + } continue; case _OP_GETK: - if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg, false,true)) { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();} + if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,true)) { Raise_IdxError(ci->_literals[arg1]); SQ_THROW();} TARGET = temp_reg; continue; case _OP_MOVE: TARGET = STK(arg1); continue; @@ -822,7 +840,7 @@ common_prepcall: if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } TARGET = res?_true_:_false_; }continue; - case _OP_NE:{ + case _OP_NE:{ bool res; if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } TARGET = (!res)?_true_:_false_; @@ -848,8 +866,8 @@ common_prepcall: case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue; case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue; - case _OP_GETVARGV: - if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); } + case _OP_GETVARGV: + if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); } continue; case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; @@ -863,12 +881,12 @@ common_prepcall: case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue; case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue; - case _OP_INSTANCEOF: + case _OP_INSTANCEOF: if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE) {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_; continue; - case _OP_AND: + case _OP_AND: if(IsFalse(STK(arg2))) { TARGET = STK(arg2); ci->_ip += (sarg1); @@ -909,7 +927,7 @@ common_prepcall: outres = temp_reg; return true; } - + } continue; case _OP_RESUME: @@ -917,9 +935,14 @@ common_prepcall: _GUARD(_generator(STK(arg1))->Resume(this, arg0)); traps += ci->_etraps; continue; - case _OP_FOREACH:{ bool finished; - _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,finished)); - if(finished) ci->_ip += sarg1; } + case _OP_FOREACH:{ int tojump; + _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); + ci->_ip += tojump; } + continue; + case _OP_POSTFOREACH: + assert(type(STK(arg0)) == OT_GENERATOR); + if(_generator(STK(arg0))->_state == SQGenerator::eDead) + ci->_ip += (sarg1 - 1); continue; case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue; case _OP_CLONE: @@ -927,15 +950,18 @@ common_prepcall: { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();} continue; case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue; - case _OP_PUSHTRAP: - _etraps.push_back(SQExceptionTrap(_top,_stackbase, &ci->_iv->_vals[(ci->_ip-ci->_iv->_vals)+arg1], arg0)); traps++; + case _OP_PUSHTRAP:{ + SQInstruction *_iv = _funcproto(_closure(ci->_closure)->_function)->_instructions; + _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; ci->_etraps++; + } continue; - case _OP_POPTRAP: + case _OP_POPTRAP: { for(SQInteger i = 0; i < arg0; i++) { _etraps.pop_back(); traps--; ci->_etraps--; } + } continue; case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; @@ -958,7 +984,7 @@ common_prepcall: } continue; } - + } } exception_trap: @@ -977,9 +1003,9 @@ exception_trap: ci->_ip = et._ip; _top = et._stacksize; _stackbase = et._stackbase; - _stack[_stackbase+et._extarget] = currerror; + _stack._vals[_stackbase+et._extarget] = currerror; _etraps.pop_back(); traps--; ci->_etraps--; - while(last_top >= _top) _stack[last_top--].Null(); + while(last_top >= _top) _stack._vals[last_top--].Null(); goto exception_restore; } //if is a native closure @@ -989,7 +1015,7 @@ exception_trap: PopVarArgs(ci->_vargs); POP_CALLINFO(this); n++; - } while(_callsstack.size()); + } while(_callsstacksize); } else { //call the hook @@ -1005,9 +1031,9 @@ exception_trap: PopVarArgs(ci->_vargs); POP_CALLINFO(this); if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break; - } while(_callsstack.size()); + } while(_callsstacksize); - while(last_top >= _top) _stack[last_top--].Null(); + while(last_top >= _top) _stack._vals[last_top--].Null(); } _lasterror = currerror; return false; @@ -1046,7 +1072,7 @@ void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) Pop(nparams); } -bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,bool tailcall,SQObjectPtr &retval,bool &suspend) +bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,SQObjectPtr &retval,bool &suspend) { if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } SQInteger nparamscheck = nclosure->_nparamscheck; @@ -1059,8 +1085,8 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb SQInteger tcs; if((tcs = nclosure->_typecheck.size())) { for(SQInteger i = 0; i < nargs && i < tcs; i++) - if((nclosure->_typecheck[i] != -1) && !(type(_stack[stackbase+i]) & nclosure->_typecheck[i])) { - Raise_ParamTypeError(i,nclosure->_typecheck[i],type(_stack[stackbase+i])); + if((nclosure->_typecheck._vals[i] != -1) && !(type(_stack._vals[stackbase+i]) & nclosure->_typecheck[i])) { + Raise_ParamTypeError(i,nclosure->_typecheck._vals[i],type(_stack._vals[stackbase+i])); return false; } } @@ -1071,12 +1097,14 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb SQInteger oldtop = _top; SQInteger oldstackbase = _stackbase; _top = stackbase + nargs; - PUSH_CALLINFO(this, CallInfo()); - ci->_etraps = 0; - ci->_closure._unVal.pNativeClosure = nclosure; - ci->_closure._type = OT_NATIVECLOSURE; - ci->_prevstkbase = stackbase - _stackbase; - ci->_ncalls = 1; + CallInfo lci; + lci._etraps = 0; + lci._closure._unVal.pNativeClosure = nclosure; + lci._closure._type = OT_NATIVECLOSURE; + lci._prevstkbase = (SQInt32) (stackbase - _stackbase); + lci._ncalls = 1; + lci._prevtop = (SQInt32) (oldtop - oldstackbase); + PUSH_CALLINFO(this, lci); _stackbase = stackbase; //push free variables SQInteger outers = nclosure->_outervalues.size(); @@ -1088,19 +1116,19 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb _stack[stackbase] = _weakref(nclosure->_env)->_obj; } - ci->_prevtop = (oldtop - oldstackbase); + SQInteger ret = (nclosure->_function)(this); _nnativecalls--; suspend = false; if( ret == SQ_SUSPEND_FLAG) suspend = true; - else if (ret < 0) { + else if (ret < 0) { _stackbase = oldstackbase; _top = oldtop; POP_CALLINFO(this); Raise_Error(_lasterror); return false; } - + if (ret != 0){ retval = TOP(); } else { retval = _null_; } _stackbase = oldstackbase; @@ -1139,7 +1167,7 @@ bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest, bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw) { switch(type(self)){ - case OT_CLASS: + case OT_CLASS: return _class(self)->Get(key,dest); break; case OT_TABLE: @@ -1147,7 +1175,7 @@ bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPt //delegation if(_delegable(self)->_delegate) { if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false)) - return true; + return true; if(raw)return false; Push(self);Push(key); if(CallMetaMethod(_delegable(self),MT_GET,2,dest)) @@ -1184,13 +1212,13 @@ bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPt return _instance_ddel->Get(key,dest); } return true; - case OT_INTEGER:case OT_FLOAT:case OT_BOOL: + case OT_INTEGER:case OT_FLOAT:case OT_BOOL: if(raw)return false; return _number_ddel->Get(key,dest); - case OT_GENERATOR: + case OT_GENERATOR: if(raw)return false; return _generator_ddel->Get(key,dest); - case OT_CLOSURE: case OT_NATIVECLOSURE: + case OT_CLOSURE: case OT_NATIVECLOSURE: if(raw)return false; return _closure_ddel->Get(key,dest); case OT_THREAD: @@ -1265,7 +1293,7 @@ cloned_mt: } target = newobj; return true; - case OT_ARRAY: + case OT_ARRAY: target = _array(self)->Clone(); return true; default: return false; @@ -1286,9 +1314,9 @@ bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObject } } if(rawcall) _table(self)->NewSlot(key,val); //cannot fail - + break;} - case OT_CLASS: + case OT_CLASS: if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { if(_class(self)->_locked) { Raise_Error(_SC("trying to modify a class that has already been instantiated")); @@ -1358,8 +1386,8 @@ SQInteger prevstackbase = _stackbase; break; case OT_NATIVECLOSURE:{ bool suspend; - return CallNative(_nativeclosure(closure), nparams, stackbase, false, outres,suspend); - + return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend); + } break; case OT_CLASS: { @@ -1428,12 +1456,12 @@ void SQVM::dumpstack(SQInteger stackbase,bool dumpall) SQInteger size=dumpall?_stack.size():_top; SQInteger n=0; scprintf(_SC("\n>>>>stack dump<<<<\n")); - CallInfo &ci=_callsstack.back(); + CallInfo &ci=_callsstack[_callsstacksize-1]; scprintf(_SC("IP: %p\n"),ci._ip); scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); scprintf(_SC("prev top: %d\n"),ci._prevtop); for(SQInteger i=0;i"));else scprintf(_SC(" ")); scprintf(_SC("[%d]:"),n); switch(type(obj)){ diff --git a/src/squirrel/squirrel/sqvm.h b/src/squirrel/squirrel/sqvm.h index 20a9195b0..89710ffd5 100644 --- a/src/squirrel/squirrel/sqvm.h +++ b/src/squirrel/squirrel/sqvm.h @@ -21,7 +21,7 @@ struct SQExceptionTrap{ SQInteger _extarget; }; -#define _INLINE +#define _INLINE #define STK(a) _stack._vals[_stackbase+(a)] #define TARGET _stack._vals[_stackbase+arg0] @@ -32,27 +32,25 @@ struct SQVM : public CHAINABLE_OBJ { struct VarArgs { VarArgs() { size = 0; base = 0; } - SQInteger size; - SQInteger base; + unsigned short size; + unsigned short base; }; struct CallInfo{ CallInfo() { _generator._type = OT_NULL;} - //CallInfo(const CallInfo& ci) { } - SQInstructionVec *_iv; - SQObjectPtrVec *_literals; + SQInstruction *_ip; + SQObjectPtr *_literals; SQObject _closure; SQObject _generator; - SQInteger _etraps; - SQInteger _prevstkbase; - SQInteger _prevtop; - SQInteger _target; - SQInstruction *_ip; - SQInteger _ncalls; + SQInt32 _etraps; + SQInt32 _prevstkbase; + SQInt32 _prevtop; + SQInt32 _target; + SQInt32 _ncalls; SQBool _root; VarArgs _vargs; }; - + typedef sqvector CallInfoVec; public: enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM }; @@ -61,7 +59,7 @@ public: bool Init(SQVM *friendvm, SQInteger stacksize); bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); //starts a native call return when the NATIVE closure returns - bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend); + bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend); //starts a SQUIRREL call in the same "Execution loop" bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall); bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); @@ -83,7 +81,7 @@ public: void ToString(const SQObjectPtr &o,SQObjectPtr &res); SQString *PrintObjVal(const SQObject &o); - + void Raise_Error(const SQChar *s, ...); void Raise_Error(SQObjectPtr &desc); void Raise_IdxError(SQObject &o); @@ -104,7 +102,7 @@ public: bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs); bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target); //return true if the loop is finished - bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished); + bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump); bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2); _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); @@ -118,14 +116,18 @@ public: void Mark(SQCollectable **chain); #endif void Finalize(); - + void GrowCallStack() { + SQInteger newsize = _alloccallsstacksize*2; + _callsstack = (CallInfo*)sq_realloc(_callsstack,_alloccallsstacksize*sizeof(CallInfo),newsize*sizeof(CallInfo)); + _alloccallsstacksize = newsize; + } void Release(){ sq_delete(this,SQVM); } //does nothing //////////////////////////////////////////////////////////////////////////// //stack functions for the api void Remove(SQInteger n); bool IsFalse(SQObjectPtr &o); - + void Pop(); void Pop(SQInteger n); void Push(const SQObjectPtr &o); @@ -144,7 +146,12 @@ public: SQObjectPtr _debughook; SQObjectPtr temp_reg; - CallInfoVec _callsstack; + + + CallInfo* _callsstack; + SQInteger _callsstacksize; + SQInteger _alloccallsstacksize; + ExceptionsTraps _etraps; CallInfo *ci; void *_foreignptr; @@ -156,6 +163,7 @@ public: SQBool _suspended_root; SQInteger _suspended_target; SQInteger _suspended_traps; + VarArgs _suspend_varargs; }; struct AutoDec{ @@ -177,13 +185,18 @@ const SQChar *IdType2Name(SQObjectType type); #endif #define PUSH_CALLINFO(v,nci){ \ - v->ci = &v->_callsstack.push_back(nci); \ + if(v->_callsstacksize == v->_alloccallsstacksize) { \ + v->GrowCallStack(); \ + } \ + v->ci = &v->_callsstack[v->_callsstacksize]; \ + *(v->ci) = nci; \ + v->_callsstacksize++; \ } #define POP_CALLINFO(v){ \ - v->_callsstack.pop_back(); \ - if(v->_callsstack.size()) \ - v->ci = &v->_callsstack.back() ; \ + v->_callsstacksize--; \ + if(v->_callsstacksize) \ + v->ci = &v->_callsstack[v->_callsstacksize-1] ; \ else \ v->ci = NULL; \ } -- 2.11.0