Upgrade to Squirrel 2.1.2 <http://squirrel-lang.org/>
authorChristoph Sommer <mail@christoph-sommer.de>
Sat, 3 Nov 2007 16:15:20 +0000 (16:15 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Sat, 3 Nov 2007 16:15:20 +0000 (16:15 +0000)
 - Added upstream COPYRIGHT, HISTORY
 - Kept one custom patch.

SVN-Revision: 5175

37 files changed:
src/squirrel/COPYRIGHT [new file with mode: 0644]
src/squirrel/HISTORY [new file with mode: 0644]
src/squirrel/README
src/squirrel/include/sqstdblob.h
src/squirrel/include/sqstdio.h
src/squirrel/include/sqstdstring.h
src/squirrel/include/squirrel.h
src/squirrel/sqstdlib/sqstdaux.cpp
src/squirrel/sqstdlib/sqstdblob.cpp
src/squirrel/sqstdlib/sqstdio.cpp
src/squirrel/sqstdlib/sqstdmath.cpp
src/squirrel/sqstdlib/sqstdrex.cpp
src/squirrel/sqstdlib/sqstdstream.cpp
src/squirrel/sqstdlib/sqstdstring.cpp
src/squirrel/squirrel/sqapi.cpp
src/squirrel/squirrel/sqbaselib.cpp
src/squirrel/squirrel/sqclass.cpp
src/squirrel/squirrel/sqclass.h
src/squirrel/squirrel/sqclosure.h
src/squirrel/squirrel/sqcompiler.cpp
src/squirrel/squirrel/sqdebug.cpp
src/squirrel/squirrel/sqfuncproto.h
src/squirrel/squirrel/sqfuncstate.cpp
src/squirrel/squirrel/sqfuncstate.h
src/squirrel/squirrel/sqlexer.cpp
src/squirrel/squirrel/sqobject.cpp
src/squirrel/squirrel/sqobject.h
src/squirrel/squirrel/sqopcodes.h
src/squirrel/squirrel/sqpcheader.h
src/squirrel/squirrel/sqstate.cpp
src/squirrel/squirrel/sqstate.h
src/squirrel/squirrel/sqtable.cpp
src/squirrel/squirrel/sqtable.h
src/squirrel/squirrel/squserdata.h
src/squirrel/squirrel/squtils.h
src/squirrel/squirrel/sqvm.cpp
src/squirrel/squirrel/sqvm.h

diff --git a/src/squirrel/COPYRIGHT b/src/squirrel/COPYRIGHT
new file mode 100644 (file)
index 0000000..31e565a
--- /dev/null
@@ -0,0 +1,29 @@
+Copyright (c) 2003-2007 Alberto Demichelis\r
+\r
+This software is provided 'as-is', without any \r
+express or implied warranty. In no event will the \r
+authors be held liable for any damages arising from \r
+the use of this software.\r
+\r
+Permission is granted to anyone to use this software \r
+for any purpose, including commercial applications, \r
+and to alter it and redistribute it freely, subject \r
+to the following restrictions:\r
+\r
+               1. The origin of this software must not be \r
+               misrepresented; you must not claim that \r
+               you wrote the original software. If you \r
+               use this software in a product, an \r
+               acknowledgment in the product \r
+               documentation would be appreciated but is \r
+               not required.\r
+\r
+               2. Altered source versions must be plainly \r
+               marked as such, and must not be \r
+               misrepresented as being the original \r
+               software.\r
+\r
+               3. This notice may not be removed or \r
+               altered from any source distribution.\r
+-----------------------------------------------------\r
+END OF COPYRIGHT
\ No newline at end of file
diff --git a/src/squirrel/HISTORY b/src/squirrel/HISTORY
new file mode 100644 (file)
index 0000000..a76d0ff
--- /dev/null
@@ -0,0 +1,304 @@
+***version 2.1.2 stable***\r
+-new behaviour for generators iteration using foreach\r
+now when a generator is iterated by foreach the value returned by a 'return val' statement\r
+will terminate the iteration but will not be returned as foreach iteration\r
+-added sq_setclassudsize()\r
+-added sq_clear()\r
+-added table.clear(), array.clear()\r
+-fixed sq_cmp() (thx jyuill)\r
+-fixed minor bugs\r
+\r
+***2006-08-21       ***\r
+***version 2.1.1 stable***\r
+-vm refactoring\r
+-optimized internal function memory layout\r
+-new global symbol _version_ (is the version string)\r
+-code size optimization for float literals(on 32bits float builts)\r
+-now the raw ref API(sq_addref etc...) is fully reentrant.\r
+-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)\r
+-improved C reference performances in NO_GARBAGE_COLLECTOR builds\r
+-sq_getlocal() now enumerates also outer values.\r
+-fixed regexp library for GCC users.\r
+\r
+***2006-03-19       ***\r
+***version 2.1 stable***\r
+-added static class fields, new keyword static\r
+-added 64bits architecture support\r
+-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds\r
+-added functions with fixed environment, closure.bindenv() built-in function\r
+-all types except userdata and null implement the tostring() method\r
+-string concatenation now invokes metamethod _tostring\r
+-new metamethods for class objects _newmember and _inherited\r
+-sq_call() sq_resume() sq_wakeupvm() have a new signature\r
+-new C referencing implementation(scales more with the amount of references)\r
+-refactored hash table\r
+-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()\r
+-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot\r
+-sq_setreleasehook() now also works for classes\r
+-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)\r
+-fixed squirrel.h undeclared api calls\r
+-fixed few minor bugs\r
+-SQChar is now defined as wchar_t\r
+-removed warning when building with -Wall -pedantic for GCC users\r
+-added new std io function writeclosuretofile()\r
+-added new std string functions strip(),rstrip(),lstrip() and split()\r
+-regular expressions operators (+,*) now have more POSIX greedyness behaviour\r
+-class constructors are now invoked as normal functions\r
+\r
+***2005-10-02         ***\r
+***version 2.0.5 stable***\r
+-fixed some 64bits incompatibilities (thx sarge)\r
+-fixed minor bug in the stdlib format() function (thx Rick)\r
+-fixed a bug in dofile() that was preventing to compile empty files\r
+-added new API sq_poptop() & sq_getfreevariable()\r
+-some performance improvements\r
+\r
+***2005-08-14         ***\r
+***version 2.0.4 stable***\r
+-weak references and related API calls\r
+-added sq_objtobool()\r
+-class instances memory policies improved(1 mem allocation for the whole instance)\r
+-typetags are now declared as SQUserPointer instead of unsigned int\r
+-first pass for 64bits compatibility\r
+-fixed minor bug in the stdio stream\r
+-fixed a bug in format()\r
+-fixed bug in string.tointeger() and string.tofloat()\r
+\r
+***2005-06-24         ***\r
+***version 2.0.3 stable***\r
+-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian\r
+-sq_setparamscheck() : now typemesk can check for null\r
+-added string escape sequence \xhhhh\r
+-fixed some C++ standard incompatibilities\r
+\r
+***2005-05-15         ***\r
+***version 2.0.2 stable***\r
+-performances improvements (expecially for GCC users)\r
+-removed all dependencies from C++ exception handling\r
+-various bugfixes\r
+\r
+***2005-04-12           ***\r
+***version 2.0.1 stable***\r
+-various bugfixes\r
+-sq_setparamscheck() now allows spaces in the typemask\r
+\r
+***2005-04-03           ***\r
+***version 2.0 stable***\r
+-added API sq_gettypetag()\r
+-added built-in function to the bool type(tointeger, tostring etc...)\r
+\r
+***2005-02-27                                                  ***\r
+***version 2.0 release candidate 1(RC 1)***\r
+-added API sq_reseterror()\r
+-modified sq_release()\r
+-now class instances can be cloned\r
+-various bufixes\r
+\r
+***2005-01-26        ***\r
+***version 2.0 beta 1***\r
+-added bool type\r
+-class properties can be redefined in a derived class\r
+-added ops *= /= and %=\r
+-new syntax for class attributes declaration </ and /> instead of ( and )\r
+-increased the max number of literals per function from 65535 to 16777215\r
+-now free variables have proper lexical scoping\r
+-added API sq_createinstance(), sq_pushbool(), sq_getbool()\r
+-added built-in function type()\r
+-added built-in function obj.rawin(key) in table,class and instance\r
+-sq_rawget() and sq_rawset() now work also on classes and instances\r
+-the VM no longer uses C++ exception handling (more suitable for embedded devices)\r
+-various bufixes\r
+\r
+***2004-12-21         ***\r
+***version 2.0 alpha 2***\r
+-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table\r
+-various bufixes\r
+-added class level attributes\r
+\r
+***2004-12-12         ***\r
+***version 2.0 alpha 1***\r
+-codebase branch from version 1.x\r
+-added classes\r
+-added functions with variable number of parameters(vargc & vargv and the ...)\r
+-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)\r
+-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()\r
+-modified api sq_settypetag()\r
+\r
+***2004-11-01        ***\r
+***version 1.0 stable***\r
+-fixed some minor bug\r
+-improoved operator 'delete' performances\r
+-added scientific notation for float numbers( eg. 2.e16 or 2.e-2)\r
+\r
+***2004-08-30        ***\r
+***version 1.0 release candidate 2(RC 2)***\r
+-fixed bug in the vm(thx Pierre Renaux)\r
+-fixed bug in the optimizer(thx Pierre Renaux)\r
+-fixed some bug in the documentation(thx JD)\r
+-added new api functions for raw object handling\r
+-removed nested multiline comments\r
+-reduced memory footprint in C references\r
+\r
+***2004-08-23        ***\r
+***version 1.0 release candidate 1(RC 1)***\r
+-fixed division by zero\r
+-the 'in' operator and obj.rawget() do not query the default delegate anymore\r
+-added function sq_getprintfunc()\r
+-added new standard library 'auxlib'(implements default error handlers)\r
+\r
+***2004-07-12        ***\r
+***version 1.0 beta 4***\r
+-fixed a bug in the integer.tochar() built-in method\r
+-fixed unary minus operator\r
+-fixed bug in dofile()\r
+-fixed inconsistency between != and == operators(on float/integer comparison)\r
+-added javascript style unsigned right shift operator '>>>'\r
+-added array(size) constructor built-in function\r
+-array.resize(size,[fill]) built-in function accepts an optional 'fill' value\r
+-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()\r
+\r
+***2004-05-23        ***\r
+***version 1.0 beta 3***\r
+-minor vm bug fixes\r
+-string allocation is now faster\r
+-tables and array memory usage is now less conservative(they shrink)\r
+-added regular expression routines in the standard library\r
+-The 'c' expression now accepts only 1 character(thx irbrian)\r
+-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")\r
+-added new keyword 'parent' for accessing the delegate of tables and unserdata\r
+-The metamethod '_clone' has been renamed '_cloned'\r
+-the _delslot metamethod's behaviour and prototype have been changed\r
+-new default function in the integer and float object 'tochar()'\r
+-the built-in function chcode2string has been removed\r
+-the default method [table].getdelegate() has been removed\r
+-new api sq_rawdeleteslot()\r
+-new table built-in method rawdelete(key)\r
+-the dynamic mudule loading has been removed from the standard distribution\r
+-some optimizations in the VM\r
+\r
+***2004-04-21        ***\r
+***version 1.0 beta 2***\r
+-minor compiler/parser bug fixes\r
+-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()\r
+-sq_setparamscheck allows to add automatic parameters type checking in native closures\r
+-sq_compile() lost the lineinfo parameter\r
+-new api sq_enabledebuginfo() globally sets compiler's debug info generation\r
+-added consistency check on bytecode serialization\r
+-fixed += operator, now works on strings like +\r
+-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime\r
+-added registry table\r
+-new api call sq_pushregistrytable()\r
+-added type tag to the userdata type sq_settypetag()\r
+-sq_getuserdata now queries the userdata typetag\r
+-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons\r
+-new standard libraries(sqlibs are now obsolete)\r
+\r
+***2004-02-20       ***\r
+***version 1.0 beta 1***\r
+-fixed a bug in the compiler (thanks Martin Kofler)\r
+-fixed bug in the switch case statement\r
+-fixed the _unm metamethod\r
+-fixed minor bugs in the API\r
+-fixed automatic stack resizing\r
+-first beta version \r
+       first pass code clean up in the VM and base lib\r
+       first pass code coverege test has been done on VM and built-in lib\r
+-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)\r
+-new api allows to specifiy a "print" function to output text(sq_printfunc)\r
+-added some small optimizations\r
+-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")\r
+-new built in functions have been added for manipulating the new "thread" type\r
+-friend virtual machines share the same root table, error handler and debug hook by default\r
+-new compile time options\r
+\r
+***2004-01-19       ***\r
+***version 0.9 alpha***\r
+-fixed a garbage collection bug\r
+-fixed some API bugs(thanks to Joshua Jensen)\r
+-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)\r
+-new function parameters semantic, now passing a wrong number of parameters generates an exception\r
+-native closures have now a built in parameter number checking\r
+-sq_rawget and sq_rawset now work also on arrays\r
+-sq_getsize now woks also on userdata\r
+-the userdata release hook prototype is changed(now passes the size of the userdata)\r
+-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)\r
+-faster compiler\r
+-try/catch blocks do not cause any runtime memory allocation anymore\r
+\r
+***2003-12-06       ***\r
+***version 0.8 alpha***\r
+-fixed a bug that was preventing to have callable userdata throught the metamethod _call\r
+-fixed a garbage collection bug\r
+-fixed == operator now can compare correctly different types\r
+-new built in method getstackinfos(level)\r
+-improoved line informations precision for the debug hook\r
+-new api call sq_compilebuffer()\r
+-new built-in api function compilestring()\r
+-new syntactic sugar for function declarations inside tables\r
+-the debug API has been finalized\r
+\r
+***2003-11-17       ***\r
+***version 0.7 alpha***\r
+-fixed critical bug SQInteger the tail call system\r
+-fixed bug in the continue statement code generation\r
+-fixed func call param issue(thanks to Rewoonenco Andrew)\r
+-added _delslot metamethod(thanks to Rewoonenco Andrew)\r
+-new multiline string expression ( delimited by <[ and ]> )\r
+-normal strings ("") do not allow embedded new line anymore\r
+-reduced vm memory footprint(C refs are shared between friend VMs)\r
+-new api method sq_deleteslot()\r
+-new debug hook event 'r' is triggered when a function returns\r
+\r
+***2003-11-04       ***\r
+***version 0.6 alpha***\r
+-fixed switch statement(was executing the default case after a break)\r
+-sq_call() doesn't pop the closure (just the params)\r
+-the vm execution can be suspended from the C API anytime (micro-threads)\r
+-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()\r
+\r
+***2003-10-13       ***\r
+***version 0.5 alpha***\r
+-fixed some minor bug\r
+-tested with non ASCII identifiers in unicode mode(I've tried chinese chars)\r
+-added built-in function string.find()\r
+-the built-in function array.sort() optionally accepts a cmp(a,b) function\r
+-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)\r
+-fixed some debug info imprecision\r
+\r
+***2003-10-01       ***\r
+***version 0.4 alpha***\r
+-faster VM\r
+-sq_call will pop arguments and closure also in case of failure\r
+-fixed a bug in sq_remove\r
+-now the VM detects delegation cycles(and throws an exception)\r
+-new operators ++ and --\r
+-new operator ',' comma operator\r
+-fixed some expression precedence issue\r
+-fixed bug in sq_arraypop\r
+\r
+***2003-09-15       ***\r
+***version 0.3 alpha***\r
+-fixed a bug in array::insert()\r
+-optional Unicode core(define SQUNICODE or _UNICODE on Win32)\r
+-sq_compiler uses a new reader function SQLEXREADFUNC\r
+-the debug hook passes 'l' instead of 'line' for line callbacks\r
+       and 'c' instead of 'call' for call callbacks\r
+-new array.extend() bulit-in function\r
+-new API sq_clone()\r
+\r
+***2003-09-10           ***\r
+***version 0.2 pre-alpha***\r
+-new completely reentrant VM (sq_open and sq_close are now obsolete)\r
+-sq_newvm() has a new prototype\r
+-allocators are now global and linked in the VM\r
+-_newslot meta method added\r
+-rawset creates a slot if doesn't exists\r
+-the compiler error callback pass the vm handle(thanks Pierre Renaux)\r
+-sq_setforeignptr() sq_getforeingptr() are now public\r
+-sq_resume() now is possible to resume generators from C\r
+-sq_getlasterror() retrieve the last thrown error\r
+-improved docs\r
+\r
+***2003-09-06           ***\r
+***version 0.1 pre-alpha***\r
+first release\r
index d6c0471..3d984d9 100644 (file)
@@ -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\r
+\r
+--------------------------------------------------\r
+The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and\r
+Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64).\r
+\r
+Has been tested with the following compilers:\r
+       MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits)\r
+       MinGW gcc 3.2 (mingw special 20020817-1)\r
+       Cygnus gcc 3.2\r
+       Linux gcc 3.2.3\r
+       Linux gcc 4.0.0 (x86 64bits)\r
+       \r
+\r
+Feedback and suggestions are appreciated \r
+project page - http://www.squirrel-lang.org\r
+community forums - http://www.squirrel-lang.org/Forums\r
+wiki - http://wiki.squirrel-lang.org\r
+author - alberto@ademichelis.com\r
+\r
+END OF README\r
+\r
index e54d7be..1d9a4cd 100644 (file)
@@ -17,3 +17,4 @@ SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
 #endif
 
 #endif /*_SQSTDBLOB_H_*/
+
index c3137f1..6da1872 100644 (file)
@@ -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_*/
+
index ab68d16..72f30b4 100644 (file)
@@ -6,9 +6,6 @@
 extern "C" {
 #endif
 
-//#define SQRex_True 1
-//#define SQRex_False 0
-
 typedef unsigned int SQRexBool;
 typedef struct SQRex SQRex;
 
index 1a7efc5..5150312 100644 (file)
@@ -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);
index da014f5..6d3ea31 100644 (file)
@@ -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);
index ded3696..f1a9f00 100644 (file)
@@ -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);
 }
+
index ff99542..81ed732 100644 (file)
@@ -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 ;
index 01a808a..2ad9f02 100644 (file)
@@ -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)
index 59397a7..6f8d59c 100644 (file)
@@ -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;
 }
+
index b94ab5e..4cd63da 100644 (file)
@@ -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)
                {
index d500012..31735e1 100644 (file)
@@ -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)
 {
index 8857c9a..d6b08a7 100644 (file)
@@ -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<cstksize){
@@ -834,7 +856,12 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
                        return NULL;
                SQClosure *c=_closure(ci._closure);
                SQFunctionProto *func=_funcproto(c->_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);
index cc8b368..ee49b2d 100644 (file)
@@ -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<f->_parameters.size(); n++) {
+               for(SQInteger n = 0; n<f->_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}
 };
+
+
index 405c737..309036a 100644 (file)
@@ -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)
index a451eed..4faff83 100644 (file)
@@ -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<SQClassMemeber> SQClassMemeberVec;
+typedef sqvector<SQClassMember> 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];
 };
index d8dc90a..1c9eaa9 100644 (file)
@@ -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;
 };
 
 
index a6bab09..7137c53 100644 (file)
@@ -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();
index 96da72d..40e0c9b 100644 (file)
@@ -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;
index 6444fbf..367b818 100644 (file)
@@ -12,7 +12,7 @@ enum SQOuterType {
 
 struct SQOuterVar
 {
-
+       
        SQOuterVar(){}
        SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
        {
@@ -53,6 +53,23 @@ typedef sqvector<SQOuterVar> SQOuterVarVec;
 typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
 typedef sqvector<SQLineInfo> 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_
index 2ceb1b4..962a6cd 100644 (file)
@@ -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<func->_localvarinfos.size();i++){
-               SQLocalVarInfo lvi=func->_localvarinfos[i];
+       for(si=0;si<func->_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;
index 2552f7d..701dc79 100644 (file)
@@ -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();
                }
index e699e35..7bfc19d 100644 (file)
@@ -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<nvars;i++){
                        if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=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;i<nsize;i++){
+       _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
+       _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
+       _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
+       _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
+       _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
+       _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
+       _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       for(i=0;i<nliterals;i++){
                _CHECK_IO(WriteObject(v,up,write,_literals[i]));
        }
+
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
-       nsize=_parameters.size();
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
-       for(i=0;i<nsize;i++){
+       for(i=0;i<nparameters;i++){
                _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
        }
+
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
-       nsize=_outervalues.size();
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
-       for(i=0;i<nsize;i++){
+       for(i=0;i<noutervalues;i++){
                _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
                _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
                _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
        }
+
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
-       nsize=_localvarinfos.size();
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
-       for(i=0;i<nsize;i++){
+       for(i=0;i<nlocalvarinfos;i++){
                SQLocalVarInfo &lvi=_localvarinfos[i];
                _CHECK_IO(WriteObject(v,up,write,lvi._name));
                _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
                _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
                _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
        }
+
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
-       nsize=_lineinfos.size();
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
-       _CHECK_IO(SafeWrite(v,write,up,&_lineinfos[0],sizeof(SQLineInfo)*nsize));
+       _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
+
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
-       nsize=_instructions.size();
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
-       _CHECK_IO(SafeWrite(v,write,up,&_instructions[0],sizeof(SQInstruction)*nsize));
+       _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
+
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
-       nsize=_functions.size();
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
-       for(i=0;i<nsize;i++){
+       for(i=0;i<nfunctions;i++){
                _CHECK_IO(_funcproto(_functions[i])->Save(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
+
index ee655b0..02d5967 100644 (file)
@@ -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;
index be7fe29..a05788b 100644 (file)
@@ -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;
index db49f5e..a3fb037 100644 (file)
@@ -4,7 +4,7 @@
 
 #if defined(_MSC_VER) && defined(_DEBUG)
 #include <crtdbg.h>
-#endif
+#endif 
 
 #include <stdio.h>
 #include <stdlib.h>
index 85da8c8..150bb56 100644 (file)
@@ -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<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;
+       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_;
                        //<<FIXME>>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)
index fc29816..fb67665 100644 (file)
@@ -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)
index 71c2c0e..1b3acd0 100644 (file)
@@ -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;k<oldsize;k++)
+       for(SQInteger k=0;k<oldsize;k++) 
                nold[k].~_HashNode();
        SQ_FREE(nold,oldsize*sizeof(_HashNode));
 }
@@ -111,7 +111,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
                n = _firstfree;  /* get a free place */
                SQHash mph = HashObj(mp->key) & (_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);
 }
index 742074f..67a88de 100644 (file)
@@ -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_
index 8b6b431..d192559 100644 (file)
@@ -28,7 +28,7 @@ struct SQUserData : SQDelegable
                this->~SQUserData();
                SQ_FREE(this, sizeof(SQUserData) + tsize);
        }
-
+               
        SQInteger _size;
        SQRELEASEHOOK _hook;
        SQUserPointer _typetag;
index 3f86621..77ccdb2 100644 (file)
@@ -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<typename T> class sqvector
index 888d342..25ebcf9 100644 (file)
@@ -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<ci->_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<nouters; i++) {
                        SQOuterVar &v = func->_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<size;i++){
-               SQObjectPtr &obj=_stack[i];
+               SQObjectPtr &obj=_stack[i];     
                if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
                scprintf(_SC("[%d]:"),n);
                switch(type(obj)){
index 20a9195..89710ff 100644 (file)
@@ -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<CallInfo> 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; \
 }