[Supertux-Commit] r5175 - in trunk/supertux/src/squirrel: . include sqstdlib squirrel

sommer at millhouse.dreamhost.com sommer at millhouse.dreamhost.com
Sat Nov 3 09:15:22 PDT 2007


Author: sommer
Date: 2007-11-03 09:15:20 -0700 (Sat, 03 Nov 2007)
New Revision: 5175

Added:
   trunk/supertux/src/squirrel/COPYRIGHT
   trunk/supertux/src/squirrel/HISTORY
Modified:
   trunk/supertux/src/squirrel/README
   trunk/supertux/src/squirrel/include/sqstdblob.h
   trunk/supertux/src/squirrel/include/sqstdio.h
   trunk/supertux/src/squirrel/include/sqstdstring.h
   trunk/supertux/src/squirrel/include/squirrel.h
   trunk/supertux/src/squirrel/sqstdlib/sqstdaux.cpp
   trunk/supertux/src/squirrel/sqstdlib/sqstdblob.cpp
   trunk/supertux/src/squirrel/sqstdlib/sqstdio.cpp
   trunk/supertux/src/squirrel/sqstdlib/sqstdmath.cpp
   trunk/supertux/src/squirrel/sqstdlib/sqstdrex.cpp
   trunk/supertux/src/squirrel/sqstdlib/sqstdstream.cpp
   trunk/supertux/src/squirrel/sqstdlib/sqstdstring.cpp
   trunk/supertux/src/squirrel/squirrel/sqapi.cpp
   trunk/supertux/src/squirrel/squirrel/sqbaselib.cpp
   trunk/supertux/src/squirrel/squirrel/sqclass.cpp
   trunk/supertux/src/squirrel/squirrel/sqclass.h
   trunk/supertux/src/squirrel/squirrel/sqclosure.h
   trunk/supertux/src/squirrel/squirrel/sqcompiler.cpp
   trunk/supertux/src/squirrel/squirrel/sqdebug.cpp
   trunk/supertux/src/squirrel/squirrel/sqfuncproto.h
   trunk/supertux/src/squirrel/squirrel/sqfuncstate.cpp
   trunk/supertux/src/squirrel/squirrel/sqfuncstate.h
   trunk/supertux/src/squirrel/squirrel/sqlexer.cpp
   trunk/supertux/src/squirrel/squirrel/sqobject.cpp
   trunk/supertux/src/squirrel/squirrel/sqobject.h
   trunk/supertux/src/squirrel/squirrel/sqopcodes.h
   trunk/supertux/src/squirrel/squirrel/sqpcheader.h
   trunk/supertux/src/squirrel/squirrel/sqstate.cpp
   trunk/supertux/src/squirrel/squirrel/sqstate.h
   trunk/supertux/src/squirrel/squirrel/sqtable.cpp
   trunk/supertux/src/squirrel/squirrel/sqtable.h
   trunk/supertux/src/squirrel/squirrel/squserdata.h
   trunk/supertux/src/squirrel/squirrel/squtils.h
   trunk/supertux/src/squirrel/squirrel/sqvm.cpp
   trunk/supertux/src/squirrel/squirrel/sqvm.h
Log:
Upgrade to Squirrel 2.1.2 <http://squirrel-lang.org/>

 - Added upstream COPYRIGHT, HISTORY
 - Kept one custom patch.


Added: trunk/supertux/src/squirrel/COPYRIGHT
===================================================================
--- trunk/supertux/src/squirrel/COPYRIGHT	                        (rev 0)
+++ trunk/supertux/src/squirrel/COPYRIGHT	2007-11-03 16:15:20 UTC (rev 5175)
@@ -0,0 +1,29 @@
+Copyright (c) 2003-2007 Alberto Demichelis
+
+This software is provided 'as-is', without any 
+express or implied warranty. In no event will the 
+authors be held liable for any damages arising from 
+the use of this software.
+
+Permission is granted to anyone to use this software 
+for any purpose, including commercial applications, 
+and to alter it and redistribute it freely, subject 
+to the following restrictions:
+
+		1. The origin of this software must not be 
+		misrepresented; you must not claim that 
+		you wrote the original software. If you 
+		use this software in a product, an 
+		acknowledgment in the product 
+		documentation would be appreciated but is 
+		not required.
+
+		2. Altered source versions must be plainly 
+		marked as such, and must not be 
+		misrepresented as being the original 
+		software.
+
+		3. This notice may not be removed or 
+		altered from any source distribution.
+-----------------------------------------------------
+END OF COPYRIGHT
\ No newline at end of file

Added: trunk/supertux/src/squirrel/HISTORY
===================================================================
--- trunk/supertux/src/squirrel/HISTORY	                        (rev 0)
+++ trunk/supertux/src/squirrel/HISTORY	2007-11-03 16:15:20 UTC (rev 5175)
@@ -0,0 +1,304 @@
+***version 2.1.2 stable***
+-new behaviour for generators iteration using foreach
+now when a generator is iterated by foreach the value returned by a 'return val' statement
+will terminate the iteration but will not be returned as foreach iteration
+-added sq_setclassudsize()
+-added sq_clear()
+-added table.clear(), array.clear()
+-fixed sq_cmp() (thx jyuill)
+-fixed minor bugs
+
+***2006-08-21	     ***
+***version 2.1.1 stable***
+-vm refactoring
+-optimized internal function memory layout
+-new global symbol _version_ (is the version string)
+-code size optimization for float literals(on 32bits float builts)
+-now the raw ref API(sq_addref etc...) is fully reentrant.
+-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)
+-improved C reference performances in NO_GARBAGE_COLLECTOR builds
+-sq_getlocal() now enumerates also outer values.
+-fixed regexp library for GCC users.
+
+***2006-03-19	     ***
+***version 2.1 stable***
+-added static class fields, new keyword static
+-added 64bits architecture support
+-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds
+-added functions with fixed environment, closure.bindenv() built-in function
+-all types except userdata and null implement the tostring() method
+-string concatenation now invokes metamethod _tostring
+-new metamethods for class objects _newmember and _inherited
+-sq_call() sq_resume() sq_wakeupvm() have a new signature
+-new C referencing implementation(scales more with the amount of references)
+-refactored hash table
+-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()
+-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot
+-sq_setreleasehook() now also works for classes
+-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)
+-fixed squirrel.h undeclared api calls
+-fixed few minor bugs
+-SQChar is now defined as wchar_t
+-removed warning when building with -Wall -pedantic for GCC users
+-added new std io function writeclosuretofile()
+-added new std string functions strip(),rstrip(),lstrip() and split()
+-regular expressions operators (+,*) now have more POSIX greedyness behaviour
+-class constructors are now invoked as normal functions
+
+***2005-10-02	       ***
+***version 2.0.5 stable***
+-fixed some 64bits incompatibilities (thx sarge)
+-fixed minor bug in the stdlib format() function (thx Rick)
+-fixed a bug in dofile() that was preventing to compile empty files
+-added new API sq_poptop() & sq_getfreevariable()
+-some performance improvements
+
+***2005-08-14	       ***
+***version 2.0.4 stable***
+-weak references and related API calls
+-added sq_objtobool()
+-class instances memory policies improved(1 mem allocation for the whole instance)
+-typetags are now declared as SQUserPointer instead of unsigned int
+-first pass for 64bits compatibility
+-fixed minor bug in the stdio stream
+-fixed a bug in format()
+-fixed bug in string.tointeger() and string.tofloat()
+
+***2005-06-24	       ***
+***version 2.0.3 stable***
+-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian
+-sq_setparamscheck() : now typemesk can check for null
+-added string escape sequence \xhhhh
+-fixed some C++ standard incompatibilities
+
+***2005-05-15	       ***
+***version 2.0.2 stable***
+-performances improvements (expecially for GCC users)
+-removed all dependencies from C++ exception handling
+-various bugfixes
+
+***2005-04-12		 ***
+***version 2.0.1 stable***
+-various bugfixes
+-sq_setparamscheck() now allows spaces in the typemask
+
+***2005-04-03		 ***
+***version 2.0 stable***
+-added API sq_gettypetag()
+-added built-in function to the bool type(tointeger, tostring etc...)
+
+***2005-02-27							***
+***version 2.0 release candidate 1(RC 1)***
+-added API sq_reseterror()
+-modified sq_release()
+-now class instances can be cloned
+-various bufixes
+
+***2005-01-26        ***
+***version 2.0 beta 1***
+-added bool type
+-class properties can be redefined in a derived class
+-added ops *= /= and %=
+-new syntax for class attributes declaration </ and /> instead of ( and )
+-increased the max number of literals per function from 65535 to 16777215
+-now free variables have proper lexical scoping
+-added API sq_createinstance(), sq_pushbool(), sq_getbool()
+-added built-in function type()
+-added built-in function obj.rawin(key) in table,class and instance
+-sq_rawget() and sq_rawset() now work also on classes and instances
+-the VM no longer uses C++ exception handling (more suitable for embedded devices)
+-various bufixes
+
+***2004-12-21         ***
+***version 2.0 alpha 2***
+-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table
+-various bufixes
+-added class level attributes
+
+***2004-12-12         ***
+***version 2.0 alpha 1***
+-codebase branch from version 1.x
+-added classes
+-added functions with variable number of parameters(vargc & vargv and the ...)
+-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)
+-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()
+-modified api sq_settypetag()
+
+***2004-11-01        ***
+***version 1.0 stable***
+-fixed some minor bug
+-improoved operator 'delete' performances
+-added scientific notation for float numbers( eg. 2.e16 or 2.e-2)
+
+***2004-08-30        ***
+***version 1.0 release candidate 2(RC 2)***
+-fixed bug in the vm(thx Pierre Renaux)
+-fixed bug in the optimizer(thx Pierre Renaux)
+-fixed some bug in the documentation(thx JD)
+-added new api functions for raw object handling
+-removed nested multiline comments
+-reduced memory footprint in C references
+
+***2004-08-23        ***
+***version 1.0 release candidate 1(RC 1)***
+-fixed division by zero
+-the 'in' operator and obj.rawget() do not query the default delegate anymore
+-added function sq_getprintfunc()
+-added new standard library 'auxlib'(implements default error handlers)
+
+***2004-07-12        ***
+***version 1.0 beta 4***
+-fixed a bug in the integer.tochar() built-in method
+-fixed unary minus operator
+-fixed bug in dofile()
+-fixed inconsistency between != and == operators(on float/integer comparison)
+-added javascript style unsigned right shift operator '>>>'
+-added array(size) constructor built-in function
+-array.resize(size,[fill]) built-in function accepts an optional 'fill' value
+-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()
+
+***2004-05-23        ***
+***version 1.0 beta 3***
+-minor vm bug fixes
+-string allocation is now faster
+-tables and array memory usage is now less conservative(they shrink)
+-added regular expression routines in the standard library
+-The 'c' expression now accepts only 1 character(thx irbrian)
+-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")
+-added new keyword 'parent' for accessing the delegate of tables and unserdata
+-The metamethod '_clone' has been renamed '_cloned'
+-the _delslot metamethod's behaviour and prototype have been changed
+-new default function in the integer and float object 'tochar()'
+-the built-in function chcode2string has been removed
+-the default method [table].getdelegate() has been removed
+-new api sq_rawdeleteslot()
+-new table built-in method rawdelete(key)
+-the dynamic mudule loading has been removed from the standard distribution
+-some optimizations in the VM
+
+***2004-04-21        ***
+***version 1.0 beta 2***
+-minor compiler/parser bug fixes
+-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()
+-sq_setparamscheck allows to add automatic parameters type checking in native closures
+-sq_compile() lost the lineinfo parameter
+-new api sq_enabledebuginfo() globally sets compiler's debug info generation
+-added consistency check on bytecode serialization
+-fixed += operator, now works on strings like +
+-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime
+-added registry table
+-new api call sq_pushregistrytable()
+-added type tag to the userdata type sq_settypetag()
+-sq_getuserdata now queries the userdata typetag
+-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons
+-new standard libraries(sqlibs are now obsolete)
+
+***2004-02-20	     ***
+***version 1.0 beta 1***
+-fixed a bug in the compiler (thanks Martin Kofler)
+-fixed bug in the switch case statement
+-fixed the _unm metamethod
+-fixed minor bugs in the API
+-fixed automatic stack resizing
+-first beta version 
+	first pass code clean up in the VM and base lib
+	first pass code coverege test has been done on VM and built-in lib
+-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)
+-new api allows to specifiy a "print" function to output text(sq_printfunc)
+-added some small optimizations
+-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")
+-new built in functions have been added for manipulating the new "thread" type
+-friend virtual machines share the same root table, error handler and debug hook by default
+-new compile time options
+
+***2004-01-19       ***
+***version 0.9 alpha***
+-fixed a garbage collection bug
+-fixed some API bugs(thanks to Joshua Jensen)
+-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)
+-new function parameters semantic, now passing a wrong number of parameters generates an exception
+-native closures have now a built in parameter number checking
+-sq_rawget and sq_rawset now work also on arrays
+-sq_getsize now woks also on userdata
+-the userdata release hook prototype is changed(now passes the size of the userdata)
+-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)
+-faster compiler
+-try/catch blocks do not cause any runtime memory allocation anymore
+
+***2003-12-06       ***
+***version 0.8 alpha***
+-fixed a bug that was preventing to have callable userdata throught the metamethod _call
+-fixed a garbage collection bug
+-fixed == operator now can compare correctly different types
+-new built in method getstackinfos(level)
+-improoved line informations precision for the debug hook
+-new api call sq_compilebuffer()
+-new built-in api function compilestring()
+-new syntactic sugar for function declarations inside tables
+-the debug API has been finalized
+
+***2003-11-17       ***
+***version 0.7 alpha***
+-fixed critical bug SQInteger the tail call system
+-fixed bug in the continue statement code generation
+-fixed func call param issue(thanks to Rewoonenco Andrew)
+-added _delslot metamethod(thanks to Rewoonenco Andrew)
+-new multiline string expression ( delimited by <[ and ]> )
+-normal strings ("") do not allow embedded new line anymore
+-reduced vm memory footprint(C refs are shared between friend VMs)
+-new api method sq_deleteslot()
+-new debug hook event 'r' is triggered when a function returns
+
+***2003-11-04       ***
+***version 0.6 alpha***
+-fixed switch statement(was executing the default case after a break)
+-sq_call() doesn't pop the closure (just the params)
+-the vm execution can be suspended from the C API anytime (micro-threads)
+-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()
+
+***2003-10-13       ***
+***version 0.5 alpha***
+-fixed some minor bug
+-tested with non ASCII identifiers in unicode mode(I've tried chinese chars)
+-added built-in function string.find()
+-the built-in function array.sort() optionally accepts a cmp(a,b) function
+-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)
+-fixed some debug info imprecision
+
+***2003-10-01       ***
+***version 0.4 alpha***
+-faster VM
+-sq_call will pop arguments and closure also in case of failure
+-fixed a bug in sq_remove
+-now the VM detects delegation cycles(and throws an exception)
+-new operators ++ and --
+-new operator ',' comma operator
+-fixed some expression precedence issue
+-fixed bug in sq_arraypop
+
+***2003-09-15       ***
+***version 0.3 alpha***
+-fixed a bug in array::insert()
+-optional Unicode core(define SQUNICODE or _UNICODE on Win32)
+-sq_compiler uses a new reader function SQLEXREADFUNC
+-the debug hook passes 'l' instead of 'line' for line callbacks
+	and 'c' instead of 'call' for call callbacks
+-new array.extend() bulit-in function
+-new API sq_clone()
+
+***2003-09-10           ***
+***version 0.2 pre-alpha***
+-new completely reentrant VM (sq_open and sq_close are now obsolete)
+-sq_newvm() has a new prototype
+-allocators are now global and linked in the VM
+-_newslot meta method added
+-rawset creates a slot if doesn't exists
+-the compiler error callback pass the vm handle(thanks Pierre Renaux)
+-sq_setforeignptr() sq_getforeingptr() are now public
+-sq_resume() now is possible to resume generators from C
+-sq_getlasterror() retrieve the last thrown error
+-improved docs
+
+***2003-09-06           ***
+***version 0.1 pre-alpha***
+first release

Modified: trunk/supertux/src/squirrel/README
===================================================================
--- trunk/supertux/src/squirrel/README	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/README	2007-11-03 16:15:20 UTC (rev 5175)
@@ -1,66 +1,22 @@
-~~~~~~~~
-Squirrel
-~~~~~~~~
-
-This directory contains the SQUIRREL programming language as found on 
-http://www.squirrel-lang.org with some minor fixes to make it compile warning
-free on 64bit architectures.
-
-Squirrel Copyright:
-Copyright (c) 2003-2006 Alberto Demichelis
-
-This software is provided 'as-is', without any
-express or implied warranty. In no event will the
-authors be held liable for any damages arising from
-the use of this software.
-
-Permission is granted to anyone to use this software
-for any purpose, including commercial applications,
-and to alter it and redistribute it freely, subject
-to the following restrictions:
-
-                1. The origin of this software must not be
-                misrepresented; you must not claim that
-                you wrote the original software. If you
-                use this software in a product, an
-                acknowledgment in the product
-                documentation would be appreciated but is
-                not required.
-
-                2. Altered source versions must be plainly
-                marked as such, and must not be
-                misrepresented as being the original
-                software.
-
-                3. This notice may not be removed or
-                altered from any source distribution.
------------------------------------------------------
-END OF COPYRIGHT
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~
-Squirrel Remote Debugger
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The subdirectory sqdbg contains the sqdbg library by Alberto Demichelis.
-
-SQDBG License:
-
-This software is provided 'as-is', without any express or implied warranty. In
-no event will the authors be held liable for any damages arising from the use
-of this software.
-
-Permission is granted to anyone to use this software for any purpose, including
-commercial applications, and to alter it and redistribute it freely, subject to
-the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not claim
-that you wrote the original software. If you use this software in a product, an
-acknowledgment in the product documentation would be appreciated but is not
-required.
-
-2. Altered source versions must be plainly marked as such, and must not be
-misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source distribution.
-
+The programming language SQUIRREL 2.1.2 stable
+
+--------------------------------------------------
+The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and
+Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64).
+
+Has been tested with the following compilers:
+	MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits)
+	MinGW gcc 3.2 (mingw special 20020817-1)
+	Cygnus gcc 3.2
+	Linux gcc 3.2.3
+	Linux gcc 4.0.0 (x86 64bits)
+	
+
+Feedback and suggestions are appreciated 
+project page - http://www.squirrel-lang.org
+community forums - http://www.squirrel-lang.org/Forums
+wiki - http://wiki.squirrel-lang.org
+author - alberto at ademichelis.com
+
+END OF README
+

Modified: trunk/supertux/src/squirrel/include/sqstdblob.h
===================================================================
--- trunk/supertux/src/squirrel/include/sqstdblob.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/include/sqstdblob.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -17,3 +17,4 @@
 #endif
 
 #endif /*_SQSTDBLOB_H_*/
+

Modified: trunk/supertux/src/squirrel/include/sqstdio.h
===================================================================
--- trunk/supertux/src/squirrel/include/sqstdio.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/include/sqstdio.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -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 @@
 #endif
 
 #endif /*_SQSTDIO_H_*/
+

Modified: trunk/supertux/src/squirrel/include/sqstdstring.h
===================================================================
--- trunk/supertux/src/squirrel/include/sqstdstring.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/include/sqstdstring.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -6,9 +6,6 @@
 extern "C" {
 #endif
 
-//#define SQRex_True 1
-//#define SQRex_False 0
-
 typedef unsigned int SQRexBool;
 typedef struct SQRex SQRex;
 

Modified: trunk/supertux/src/squirrel/include/squirrel.h
===================================================================
--- trunk/supertux/src/squirrel/include/squirrel.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/include/squirrel.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -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 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 @@
 #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 @@
 #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 struct tagSQObject
 {
+	SQObjectType _type;
 	SQObjectValue _unVal;
-	SQObjectType _type;
 }SQObject;
 
 typedef struct tagSQStackInfos{
@@ -321,8 +328,7 @@
 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_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);

Modified: trunk/supertux/src/squirrel/sqstdlib/sqstdaux.cpp
===================================================================
--- trunk/supertux/src/squirrel/sqstdlib/sqstdaux.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/sqstdlib/sqstdaux.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -12,7 +12,7 @@
 		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 @@
 					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);

Modified: trunk/supertux/src/squirrel/sqstdlib/sqstdblob.cpp
===================================================================
--- trunk/supertux/src/squirrel/sqstdlib/sqstdblob.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/sqstdlib/sqstdblob.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -237,7 +237,6 @@
 		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 @@
 {
 	return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
 }
+

Modified: trunk/supertux/src/squirrel/sqstdlib/sqstdio.cpp
===================================================================
--- trunk/supertux/src/squirrel/sqstdlib/sqstdio.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/sqstdlib/sqstdio.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -72,7 +72,7 @@
 		return false;
 	}
 	void Close() {
-		if(_handle && _owns) {
+		if(_handle && _owns) { 
 			sqstd_fclose(_handle);
 			_handle = NULL;
 			_owns = false;
@@ -225,7 +225,7 @@
 	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 @@
 				//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 ;

Modified: trunk/supertux/src/squirrel/sqstdlib/sqstdmath.cpp
===================================================================
--- trunk/supertux/src/squirrel/sqstdlib/sqstdmath.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/sqstdlib/sqstdmath.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -37,8 +37,8 @@
 {
 	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)

Modified: trunk/supertux/src/squirrel/sqstdlib/sqstdrex.cpp
===================================================================
--- trunk/supertux/src/squirrel/sqstdlib/sqstdrex.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/sqstdlib/sqstdrex.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -24,28 +24,28 @@
 
 #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 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 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 @@
 		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_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_charnode(SQRex *exp,SQBool isclass)
 {
+	SQChar t;
 	if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
 		exp->_p++;
 		switch(*exp->_p) {
@@ -148,30 +138,32 @@
 			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 @@
 		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_element(SQRex *exp)
 {
-	SQInteger ret;
+	SQInteger ret = -1;
 	switch(*exp->_p)
 	{
 	case '(': {
@@ -251,11 +244,12 @@
 		}
 		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 @@
 		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 @@
 	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 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 @@
 					}
 				}
 			}
-
+			
 			if(s >= exp->_eol)
 				break;
 		}
@@ -458,7 +461,7 @@
 				exp->_matches[capture].begin = cur;
 				exp->_currsubexp++;
 			}
-
+			
 			do {
 				SQRexNode *subnext = NULL;
 				if(n->next != -1) {
@@ -475,10 +478,10 @@
 				}
 			} 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 @@
 	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 @@
 	*subexp = exp->_matches[n];
 	return SQTrue;
 }
+

Modified: trunk/supertux/src/squirrel/sqstdlib/sqstdstream.cpp
===================================================================
--- trunk/supertux/src/squirrel/sqstdlib/sqstdstream.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/sqstdlib/sqstdstream.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -163,7 +163,7 @@
 	case 'f': {
 		float f;
 		sq_getfloat(v, 2, &tf);
-		f = tf;
+		f = (float)tf;
 		self->Write(&f, sizeof(float));
 			  }
 		break;
@@ -302,7 +302,7 @@
 		}
 		sq_createslot(v,-3);
 		sq_pop(v,1);
-
+		
 		i = 0;
 		while(globals[i].name!=0)
 		{

Modified: trunk/supertux/src/squirrel/sqstdlib/sqstdstring.cpp
===================================================================
--- trunk/supertux/src/squirrel/sqstdlib/sqstdstring.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/sqstdlib/sqstdstring.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -44,7 +44,7 @@
 		width = 0;
 	if (src[n] == '.') {
 	    n++;
-
+    	
 		wc = 0;
 		while (scisdigit(src[n])) {
 			swidth[wc] = src[n];
@@ -82,7 +82,7 @@
 		}
 		else if(format[n+1] == '%') { //handles %%
 				dest[i++] = '%';
-				n += 2;
+				n += 2; 
 		}
 		else {
 			n++;
@@ -97,19 +97,19 @@
 			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 @@
 
 #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)
 {

Modified: trunk/supertux/src/squirrel/squirrel/sqapi.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqapi.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqapi.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -29,7 +29,7 @@
 #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 @@
 	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 @@
 {
 	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_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 @@
 	return NULL;
 }
 
-SQInteger sq_objtointeger(HSQOBJECT *o)
+SQInteger sq_objtointeger(HSQOBJECT *o) 
 {
 	if(sq_isnumeric(*o)) {
 		return tointeger(*o);
@@ -162,7 +171,7 @@
 	return 0;
 }
 
-SQFloat sq_objtofloat(HSQOBJECT *o)
+SQFloat sq_objtofloat(HSQOBJECT *o) 
 {
 	if(sq_isnumeric(*o)) {
 		return tofloat(*o);
@@ -170,7 +179,7 @@
 	return 0;
 }
 
-SQBool sq_objtobool(HSQOBJECT *o)
+SQBool sq_objtobool(HSQOBJECT *o) 
 {
 	if(sq_isbool(*o)) {
 		return _integer(*o);
@@ -219,12 +228,12 @@
 
 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 @@
 	}
 	SQClass *newclass = SQClass::Create(_ss(v), baseclass);
 	if(baseclass) v->Pop();
-	v->Push(newclass);
+	v->Push(newclass);	
 	return SQ_OK;
 }
 
@@ -286,6 +295,7 @@
 	return SQ_OK;
 }
 
+
 SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
 {
 	sq_aux_paramscheck(v, 1);
@@ -314,7 +324,7 @@
 		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 @@
 	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 @@
 	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 @@
 	return type(stack_get(v, idx));
 }
 
+
 void sq_tostring(HSQUIRRELVM v,SQInteger idx)
 {
 	SQObjectPtr &o = stack_get(v, idx);
@@ -572,6 +597,16 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 
 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 @@
 			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_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 @@
 	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 @@
 	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 @@
 {
 	return SQ_REALLOC(p,oldsize,newsize);
 }
+
 void sq_free(void *p,SQUnsignedInteger size)
 {
 	SQ_FREE(p,size);

Modified: trunk/supertux/src/squirrel/squirrel/sqbaselib.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqbaselib.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqbaselib.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -30,6 +30,11 @@
 	}
 }
 
+static SQInteger base_dummy(HSQUIRRELVM v)
+{
+	return 0;
+}
+
 #ifndef NO_GARBAGE_COLLECTOR
 static SQInteger base_collectgarbage(HSQUIRRELVM v)
 {
@@ -217,6 +222,7 @@
 	{_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 @@
 		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 @@
 	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 @@
 	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 @@
 	{_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 @@
 		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 @@
 	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 @@
 	}
 	v->Push(arr);
 	return 1;
-
+	
 }
 
 SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
@@ -538,6 +555,7 @@
 	{_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 @@
 	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 @@
 		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 @@
 				break;
 			}
 		}
-
+			
 		SQInteger wakeupret = sq_gettop(v)>1?1:0;
 		if(wakeupret) {
 			sq_move(thread,v,2);
@@ -858,3 +876,5 @@
 	{_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 	{0,0}
 };
+
+

Modified: trunk/supertux/src/squirrel/squirrel/sqclass.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqclass.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqclass.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -12,6 +12,7 @@
 	_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 @@
 	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 @@
 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 @@
 	}
 	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 @@
 		}
 		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 @@
 {
 	_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 @@
 {
 	_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 @@
 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)

Modified: trunk/supertux/src/squirrel/squirrel/sqclass.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqclass.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqclass.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -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 @@
 	SQObjectPtr attrs;
 };
 
-typedef sqvector<SQClassMemeber> SQClassMemeberVec;
+typedef sqvector<SQClassMember> SQClassMemberVec;
 
 #define MEMBER_TYPE_METHOD 0x01000000
 #define MEMBER_TYPE_FIELD 0x02000000
@@ -53,9 +53,9 @@
 	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 @@
 	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 @@
 		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 @@
 		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 @@
 	SQClass *_class;
 	SQUserPointer _userpointer;
 	SQRELEASEHOOK _hook;
-	SQUnsignedInteger _nvalues;
 	SQInteger _memsize;
 	SQObjectPtr _values[1];
 };

Modified: trunk/supertux/src/squirrel/squirrel/sqclosure.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqclosure.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqclosure.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -29,7 +29,7 @@
 		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 @@
 	SQObjectPtrVec _outervalues;
 };
 //////////////////////////////////////////////
-struct SQGenerator : public CHAINABLE_OBJ
+struct SQGenerator : public CHAINABLE_OBJ 
 {
 	enum SQGeneratorState{eRunning,eSuspended,eDead};
 private:
@@ -92,7 +92,7 @@
 		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 @@
 	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;
 };
 
 

Modified: trunk/supertux/src/squirrel/squirrel/sqcompiler.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqcompiler.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqcompiler.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -87,7 +87,7 @@
 	}
 	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 @@
 			SQOpcode op;
 			if(_token == TK_RETURN) {
 				op = _OP_RETURN;
-
+				
 			}
 			else {
 				op = _OP_YIELD;
@@ -227,11 +227,11 @@
 				_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 @@
 		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 @@
 		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 @@
 		default: return;
 		}
 	}
-
+	
 	void MultExp()
 	{
 		PrefixedExpr();
@@ -512,7 +512,7 @@
 			switch(_token) {
 			case _SC('.'): {
 				pos = -1;
-				Lex();
+				Lex(); 
 				if(_token == TK_PARENT) {
 					Lex();
 					if(!NeedGet())
@@ -530,7 +530,7 @@
 				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 @@
 				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 @@
 					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 @@
 		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 @@
 					//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 @@
 			_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 @@
 						 }
 			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 @@
 				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 @@
 		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 @@
 		}
 		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 @@
 	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 @@
 			}
 			_fs->PopTarget();
 			_fs->PushLocalVariable(varname);
-
+		
 		} while(_token == _SC(','));
 	}
 	void IfStatement()
@@ -810,11 +815,11 @@
 		_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 @@
 		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 @@
 		_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 @@
 			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 @@
 		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 @@
 		__nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
 		if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
 		_fs->_breaktargets.pop_back();
-
+		
 	}
 	void FunctionStatement()
 	{
@@ -1002,7 +1009,7 @@
 		_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 @@
 	}
 	void CreateFunction(SQObject &name)
 	{
-
+		
 		SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
 		funcstate->_name = name;
 		SQObject paramname;
@@ -1151,7 +1158,7 @@
 			}
 			Lex();
 		}
-
+		
 		SQFuncState *currchunk = _fs;
 		_fs = funcstate;
 		Statement();

Modified: trunk/supertux/src/squirrel/squirrel/sqdebug.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqdebug.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqdebug.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -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_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;

Modified: trunk/supertux/src/squirrel/squirrel/sqfuncproto.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqfuncproto.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqfuncproto.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -12,7 +12,7 @@
 
 struct SQOuterVar
 {
-
+	
 	SQOuterVar(){}
 	SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
 	{
@@ -53,6 +53,23 @@
 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 @@
 	_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_

Modified: trunk/supertux/src/squirrel/squirrel/sqfuncstate.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqfuncstate.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqfuncstate.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -14,6 +14,7 @@
 	{_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 @@
 	{_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::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 @@
 		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 @@
 	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 @@
 				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 @@
 					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 @@
 	lvi._pos=_vlocals.size();
 	_vlocals.push_back(lvi);
 	if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
-
+	
 	return pos;
 }
 
@@ -349,7 +355,7 @@
 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 @@
 			_outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
 			return;
 		}
-	}
+	}	
 	_outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
 }
 
@@ -400,7 +406,7 @@
 				pi._arg2 = (unsigned char)i._arg1;
 				pi.op = _OP_GETK;
 				pi._arg0 = i._arg0;
-
+				
 				return;
 			}
 		break;
@@ -424,7 +430,7 @@
 				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 @@
 			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 @@
 
 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 @@
 		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;

Modified: trunk/supertux/src/squirrel/squirrel/sqfuncstate.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqfuncstate.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqfuncstate.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -77,3 +77,4 @@
 
 
 #endif //_SQFUNCSTATE_H_
+

Modified: trunk/supertux/src/squirrel/squirrel/sqlexer.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqlexer.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqlexer.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -135,7 +135,7 @@
 			case _SC('*'):
 				NEXT();
 				LexBlockComment();
-				continue;
+				continue;	
 			case _SC('/'):
 				do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
 				continue;
@@ -165,8 +165,8 @@
 		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 @@
 			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 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 @@
 			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 @@
 				}
 				if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
 			}
-
+			
 			APPEND_CHAR(CUR_CHAR);
 			NEXT();
 		}

Modified: trunk/supertux/src/squirrel/squirrel/sqobject.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqobject.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqobject.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -66,10 +66,10 @@
 	}
 }
 
-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 @@
 	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 @@
 		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 @@
 
 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 @@
 
 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 @@
 	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 @@
 	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 @@
 	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 @@
 {
 	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 SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
 
 #endif
+

Modified: trunk/supertux/src/squirrel/squirrel/sqobject.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqobject.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqobject.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -76,7 +76,7 @@
 #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 @@
 	}
 	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 @@
 		return *this;
 	}
 	inline SQObjectPtr& operator=(const SQObject& obj)
-	{
+	{ 
 		SQObjectType tOldType;
 		SQObjectValue unOldVal;
 		tOldType=_type;

Modified: trunk/supertux/src/squirrel/squirrel/sqopcodes.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqopcodes.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqopcodes.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -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 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 @@
 		_arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
 		_arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
 	}
-
-
+    
+	
 	SQInt32 _arg1;
 	unsigned char op;
 	unsigned char _arg0;

Modified: trunk/supertux/src/squirrel/squirrel/sqpcheader.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqpcheader.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqpcheader.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -4,7 +4,7 @@
 
 #if defined(_MSC_VER) && defined(_DEBUG)
 #include <crtdbg.h>
-#endif
+#endif 
 
 #include <stdio.h>
 #include <stdlib.h>

Modified: trunk/supertux/src/squirrel/squirrel/sqstate.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqstate.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqstate.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -38,10 +38,10 @@
 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 @@
 					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 @@
 }
 
 void SQSharedState::Init()
-{
+{	
 	_scratchpad=NULL;
 	_scratchpadsize=0;
 #ifndef NO_GARBAGE_COLLECTOR
@@ -164,10 +164,9 @@
 	_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 @@
 	_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 @@
 		_gc_chain->Release();
 	}
 #endif
+
 	sq_delete(_types,SQObjectPtrVec);
 	sq_delete(_systemstrings,SQObjectPtrVec);
 	sq_delete(_metamethods,SQObjectPtrVec);
@@ -245,8 +243,8 @@
 {
 	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 @@
 	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 @@
 #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;
+	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;
+		}else if(_scratchpadsize >= (size<<5)) {
+			newsize = _scratchpadsize >> 1;
+			_scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
+			_scratchpadsize = newsize;
 		}
 	}
 	return _scratchpad;
@@ -332,7 +330,7 @@
 
 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 @@
 
 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 @@
 	}
 }
 #endif
+
 void RefTable::AddRef(SQObject &obj)
 {
 	SQHash mainpos;
@@ -370,7 +370,7 @@
 	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 @@
 			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 @@
 	}
 	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 @@
 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 @@
 	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()
 {
 	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 @@
 	SQString *s;
 	SQString *prev=NULL;
 	SQHash h = bs->_hash&(_numofslots - 1);
-
+	
 	for (s = _strings[h]; s; ){
 		if(s == bs){
 			if(prev)

Modified: trunk/supertux/src/squirrel/squirrel/sqstate.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqstate.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqstate.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -44,7 +44,7 @@
 	void AllocNodes(SQUnsignedInteger size);
 	SQUnsignedInteger _numofslots;
 	SQUnsignedInteger _slotused;
-	SQUnsignedInteger _buffersize;
+	RefNode *_nodes;
 	RefNode *_freelist;
 	RefNode **_buckets;
 };
@@ -63,7 +63,7 @@
 	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 @@
 	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 @@
 #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)

Modified: trunk/supertux/src/squirrel/squirrel/sqtable.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqtable.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqtable.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -20,7 +20,7 @@
 
 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 @@
 		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 @@
 		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 @@
 	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);
+}

Modified: trunk/supertux/src/squirrel/squirrel/sqtable.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqtable.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqtable.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -22,7 +22,7 @@
 	}
 }
 
-struct SQTable : public SQDelegable
+struct SQTable : public SQDelegable 
 {
 private:
 	struct _HashNode
@@ -36,11 +36,12 @@
 	_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 @@
 		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 @@
 	//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_

Modified: trunk/supertux/src/squirrel/squirrel/squserdata.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/squserdata.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/squserdata.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -28,7 +28,7 @@
 		this->~SQUserData();
 		SQ_FREE(this, sizeof(SQUserData) + tsize);
 	}
-
+		
 	SQInteger _size;
 	SQRELEASEHOOK _hook;
 	SQUserPointer _typetag;

Modified: trunk/supertux/src/squirrel/squirrel/squtils.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/squtils.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/squtils.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -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

Modified: trunk/supertux/src/squirrel/squirrel/sqvm.cpp
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqvm.cpp	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqvm.cpp	2007-11-03 16:15:20 UTC (rev 5175)
@@ -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 @@
 			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 @@
 {
 	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 @@
 SQVM::~SQVM()
 {
 	Finalize();
+	sq_free(_callsstack,_alloccallsstacksize*sizeof(CallInfo));
 	REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
 }
 
@@ -124,7 +131,7 @@
 
 bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
 {
-
+	
 	switch(type(o)) {
 	case OT_INTEGER:
 		trg = -_integer(o);
@@ -148,7 +155,7 @@
 	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 @@
 		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 @@
 		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 @@
 			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 @@
 	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 *GetTypeName(const SQObjectPtr &obj1)
 {
-	return IdType2Name(type(obj1));
+	return IdType2Name(type(obj1));	
 }
 
 void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
@@ -303,17 +313,20 @@
 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 @@
 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 @@
 				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 @@
 	}
 
 	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 @@
 	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 @@
 	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 @@
 		_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 @@
 			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 @@
 			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 @@
 	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 @@
 {
 	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 @@
 	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 @@
 		case ET_RESUME_VM:
 			traps = _suspended_traps;
 			ci->_root = _suspended_root;
+			ci->_vargs = _suspend_varargs;
 			_suspended = SQFalse;
 			break;
 	}
-
+	
 exception_restore:
 	//
 	{
@@ -696,63 +709,72 @@
 				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 @@
 				}
 				  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();}
+						{ Raise_IdxError(key); SQ_THROW();}
 					}
-common_prepcall:
-					if(type(STK(arg2)) == OT_CLASS) {
-						STK(arg3) = STK(0); // this
-					}
-					else {
-						STK(arg3) = STK(arg2);
-					}
+
+					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 @@
 				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 @@
 			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 @@
 			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 @@
 					outres = temp_reg;
 					return true;
 				}
-
+					
 				}
 				continue;
 			case _OP_RESUME:
@@ -917,25 +935,33 @@
 				_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:
 				if(!Clone(STK(arg1), TARGET))
 				{ 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 @@
 				}
 				continue;
 			}
-
+			
 		}
 	}
 exception_trap:
@@ -977,9 +1003,9 @@
 						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 @@
 					PopVarArgs(ci->_vargs);
 					POP_CALLINFO(this);
 					n++;
-				} while(_callsstack.size());
+				} while(_callsstacksize);
 			}
 			else {
 				//call the hook
@@ -1005,9 +1031,9 @@
 				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 @@
 	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 @@
 	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 @@
 	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 @@
 		_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::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 @@
         //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 @@
 			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 @@
 		}
 		target = newobj;
 		return true;
-	case OT_ARRAY:
+	case OT_ARRAY: 
 		target = _array(self)->Clone();
 		return true;
 	default: return false;
@@ -1286,9 +1314,9 @@
 			}
 		}
 		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 @@
 		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 @@
 	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)){

Modified: trunk/supertux/src/squirrel/squirrel/sqvm.h
===================================================================
--- trunk/supertux/src/squirrel/squirrel/sqvm.h	2007-11-03 15:44:23 UTC (rev 5174)
+++ trunk/supertux/src/squirrel/squirrel/sqvm.h	2007-11-03 16:15:20 UTC (rev 5175)
@@ -21,7 +21,7 @@
 	SQInteger _extarget;
 };
 
-#define _INLINE
+#define _INLINE 
 
 #define STK(a) _stack._vals[_stackbase+(a)]
 #define TARGET _stack._vals[_stackbase+arg0]
@@ -32,27 +32,25 @@
 {
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	SQObjectPtr _debughook;
 
 	SQObjectPtr temp_reg;
-	CallInfoVec _callsstack;
+	
+
+	CallInfo* _callsstack;
+	SQInteger _callsstacksize;
+	SQInteger _alloccallsstacksize;
+
 	ExceptionsTraps _etraps;
 	CallInfo *ci;
 	void *_foreignptr;
@@ -156,6 +163,7 @@
 	SQBool _suspended_root;
 	SQInteger _suspended_target;
 	SQInteger _suspended_traps;
+	VarArgs _suspend_varargs;
 };
 
 struct AutoDec{
@@ -177,13 +185,18 @@
 #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; \
 }



More information about the Supertux-Commit mailing list