squirrel update
authorMatthias Braun <matze@braunis.de>
Thu, 9 Feb 2006 00:23:05 +0000 (00:23 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 9 Feb 2006 00:23:05 +0000 (00:23 +0000)
SVN-Revision: 3049

45 files changed:
src/squirrel/include/sqstdaux.h
src/squirrel/include/sqstdblob.h
src/squirrel/include/sqstdio.h
src/squirrel/include/sqstdmath.h
src/squirrel/include/sqstdstring.h
src/squirrel/include/sqstdsystem.h
src/squirrel/include/squirrel.h
src/squirrel/sqstdlib/sqstdaux.cpp
src/squirrel/sqstdlib/sqstdblob.cpp
src/squirrel/sqstdlib/sqstdblobimpl.h
src/squirrel/sqstdlib/sqstdio.cpp
src/squirrel/sqstdlib/sqstdmath.cpp
src/squirrel/sqstdlib/sqstdrex.c
src/squirrel/sqstdlib/sqstdstream.cpp
src/squirrel/sqstdlib/sqstdstream.h
src/squirrel/sqstdlib/sqstdstring.cpp
src/squirrel/sqstdlib/sqstdsystem.cpp
src/squirrel/squirrel/sqapi.cpp
src/squirrel/squirrel/sqarray.h
src/squirrel/squirrel/sqbaselib.cpp
src/squirrel/squirrel/sqclass.cpp
src/squirrel/squirrel/sqclass.h
src/squirrel/squirrel/sqclosure.h
src/squirrel/squirrel/sqcompiler.cpp
src/squirrel/squirrel/sqcompiler.h
src/squirrel/squirrel/sqdebug.cpp
src/squirrel/squirrel/sqfuncproto.h
src/squirrel/squirrel/sqfuncstate.cpp
src/squirrel/squirrel/sqfuncstate.h
src/squirrel/squirrel/sqlexer.cpp
src/squirrel/squirrel/sqlexer.h
src/squirrel/squirrel/sqmem.cpp
src/squirrel/squirrel/sqobject.cpp
src/squirrel/squirrel/sqobject.h
src/squirrel/squirrel/sqopcodes.h
src/squirrel/squirrel/sqpcheader.h
src/squirrel/squirrel/sqstate.cpp
src/squirrel/squirrel/sqstate.h
src/squirrel/squirrel/sqstring.h
src/squirrel/squirrel/sqtable.cpp
src/squirrel/squirrel/sqtable.h
src/squirrel/squirrel/squserdata.h
src/squirrel/squirrel/squtils.h
src/squirrel/squirrel/sqvm.cpp
src/squirrel/squirrel/sqvm.h

index c16b043..b900348 100644 (file)
@@ -1,16 +1,16 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTD_AUXLIB_H_
-#define _SQSTD_AUXLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
-SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_AUXLIB_H_ */
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTD_AUXLIB_H_\r
+#define _SQSTD_AUXLIB_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);\r
+SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);\r
+\r
+#ifdef __cplusplus\r
+} /*extern "C"*/\r
+#endif\r
+\r
+#endif /* _SQSTD_AUXLIB_H_ */\r
index 85c138f..eda4cc9 100644 (file)
@@ -1,20 +1,20 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTDBLOB_H_
-#define _SQSTDBLOB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, int size);
-SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,int idx,SQUserPointer *ptr);
-SQUIRREL_API int sqstd_getblobsize(HSQUIRRELVM v,int idx);
-
-SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDBLOB_H_*/
-
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTDBLOB_H_\r
+#define _SQSTDBLOB_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);\r
+SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);\r
+SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);\r
+\r
+SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);\r
+\r
+#ifdef __cplusplus\r
+} /*extern "C"*/\r
+#endif\r
+\r
+#endif /*_SQSTDBLOB_H_*/\r
+\r
index cbc8069..1174201 100644 (file)
@@ -1,55 +1,53 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTDIO_H_
-#define _SQSTDIO_H_
-
-#ifdef __cplusplus
-
-#define SQSTD_STREAM_TYPE_TAG 0x80000000
-
-struct SQStream {
-       virtual ~SQStream() {}
-
-       virtual SQInteger Read(void *buffer, SQInteger size) = 0;
-       virtual SQInteger Write(void *buffer, SQInteger size) = 0;
-       virtual int Flush() = 0;
-       virtual long Tell() = 0;
-       virtual SQInteger Len() = 0;
-       virtual SQInteger Seek(long offset, int origin) = 0;
-       virtual bool IsValid() = 0;
-       virtual bool EOS() = 0;
-};
-
-extern "C" {
-#endif
-
-#define SQ_SEEK_CUR 0
-#define SQ_SEEK_END 1
-#define SQ_SEEK_SET 2
-
-typedef void* SQFILE;
-
-SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
-SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fseek(SQFILE , long , int);
-SQUIRREL_API long sqstd_ftell(SQFILE);
-SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
-SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
-SQUIRREL_API SQInteger sqstd_feof(SQFILE);
-
-SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
-SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, int idx, SQFILE *file);
-
-//compiler helpers
-SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
-
-SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDIO_H_*/
-
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTDIO_H_\r
+#define _SQSTDIO_H_\r
+\r
+#ifdef __cplusplus\r
+\r
+#define SQSTD_STREAM_TYPE_TAG 0x80000000\r
+\r
+struct SQStream {\r
+       virtual SQInteger Read(void *buffer, SQInteger size) = 0;\r
+       virtual SQInteger Write(void *buffer, SQInteger size) = 0;\r
+       virtual SQInteger Flush() = 0;\r
+       virtual SQInteger Tell() = 0;\r
+       virtual SQInteger Len() = 0;\r
+       virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;\r
+       virtual bool IsValid() = 0;\r
+       virtual bool EOS() = 0;\r
+};\r
+\r
+extern "C" {\r
+#endif\r
+\r
+#define SQ_SEEK_CUR 0\r
+#define SQ_SEEK_END 1\r
+#define SQ_SEEK_SET 2\r
+\r
+typedef void* SQFILE;\r
+\r
+SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);\r
+SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);\r
+SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);\r
+SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);\r
+SQUIRREL_API SQInteger sqstd_ftell(SQFILE);\r
+SQUIRREL_API SQInteger sqstd_fflush(SQFILE);\r
+SQUIRREL_API SQInteger sqstd_fclose(SQFILE);\r
+SQUIRREL_API SQInteger sqstd_feof(SQFILE);\r
+\r
+SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);\r
+SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);\r
+\r
+//compiler helpers\r
+SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);\r
+SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);\r
+SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);\r
+\r
+SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);\r
+\r
+#ifdef __cplusplus\r
+} /*extern "C"*/\r
+#endif\r
+\r
+#endif /*_SQSTDIO_H_*/\r
+\r
index 65de6fd..420f2ce 100644 (file)
@@ -1,15 +1,15 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTD_MATH_H_
-#define _SQSTD_MATH_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_MATH_H_*/
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTD_MATH_H_\r
+#define _SQSTD_MATH_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);\r
+\r
+#ifdef __cplusplus\r
+} /*extern "C"*/\r
+#endif\r
+\r
+#endif /*_SQSTD_MATH_H_*/\r
index eb7790c..9db0ffc 100644 (file)
@@ -1,34 +1,34 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTD_STRING_H_
-#define _SQSTD_STRING_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//#define SQRex_True 1
-//#define SQRex_False 0
-
-typedef unsigned int SQRexBool;
-typedef struct SQRex SQRex;
-
-typedef struct {
-       const SQChar *begin;
-       int len;
-} SQRexMatch;
-
-SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
-SQUIRREL_API void sqstd_rex_free(SQRex *exp);
-SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
-SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API int sqstd_rex_getsubexpcount(SQRex* exp);
-SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, int n, SQRexMatch *subexp);
-
-SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_STRING_H_*/
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTD_STRING_H_\r
+#define _SQSTD_STRING_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+//#define SQRex_True 1\r
+//#define SQRex_False 0\r
+\r
+typedef unsigned int SQRexBool;\r
+typedef struct SQRex SQRex;\r
+\r
+typedef struct {\r
+       const SQChar *begin;\r
+       SQInteger len;\r
+} SQRexMatch;\r
+\r
+SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);\r
+SQUIRREL_API void sqstd_rex_free(SQRex *exp);\r
+SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);\r
+SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);\r
+SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);\r
+SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);\r
+SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);\r
+\r
+SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);\r
+\r
+#ifdef __cplusplus\r
+} /*extern "C"*/\r
+#endif\r
+\r
+#endif /*_SQSTD_STRING_H_*/\r
index a528f5d..daefa0f 100644 (file)
@@ -1,15 +1,15 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTD_SYSTEMLIB_H_
-#define _SQSTD_SYSTEMLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API int sqstd_register_systemlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_SYSTEMLIB_H_ */
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTD_SYSTEMLIB_H_\r
+#define _SQSTD_SYSTEMLIB_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);\r
+\r
+#ifdef __cplusplus\r
+} /*extern "C"*/\r
+#endif\r
+\r
+#endif /* _SQSTD_SYSTEMLIB_H_ */\r
index 8f23fb9..d301f83 100644 (file)
-/*
-Copyright (c) 2003-2005 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.
-
-*/
-#ifndef _SQUIRREL_H_
-#define _SQUIRREL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef SQUIRREL_API
-#define SQUIRREL_API extern
-#endif
-
-typedef float SQFloat;
-typedef int SQInteger;
-typedef void* SQUserPointer;
-typedef unsigned int SQBool;
-typedef int SQRESULT;
-
-#define SQTrue 1
-#define SQFalse        0
-
-
-struct SQVM;
-struct SQTable;
-struct SQArray;
-struct SQString;
-struct SQClosure;
-struct SQGenerator;
-struct SQNativeClosure;
-struct SQUserData;
-struct SQFunctionProto;
-struct SQRefCounted;
-struct SQClass;
-struct SQInstance;
-struct SQDelegable;
-
-#ifdef _UNICODE
-#define SQUNICODE
-#endif
-
-#ifdef SQUNICODE
-typedef unsigned short SQChar;
-#define _SC(a) L##a
-#define        scstrcmp        wcscmp
-#define scsprintf      swprintf
-#define scstrlen       wcslen
-#define scstrtod       wcstod
-#define scatoi         _wtoi
-#define scstrtoul      wcstoul
-#define scvsprintf     vswprintf
-#define scstrstr       wcsstr
-#define scisspace      iswspace
-#define scisdigit      iswdigit
-#define scisalpha      iswalpha
-#define sciscntrl      iswcntrl
-#define scisalnum      iswalnum
-#define scprintf       wprintf
-#define MAX_CHAR 0xFFFF
-#else
-typedef char SQChar;
-#define _SC(a) a
-#define        scstrcmp        strcmp
-#define scsprintf      sprintf
-#define scstrlen       strlen
-#define scstrtod       strtod
-#define scatoi         atoi
-#define scstrtoul      strtoul
-#define scvsprintf     vsprintf
-#define scstrstr       strstr
-#define scisspace      isspace
-#define scisdigit      isdigit
-#define sciscntrl      iscntrl
-#define scisalpha      isalpha
-#define scisalnum      isalnum
-#define scprintf       printf
-#define MAX_CHAR 0xFF
-#endif
-
-#define SQUIRREL_VERSION       _SC("Squirrel 2.0.3 stable")
-#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2005 Alberto Demichelis")
-#define SQUIRREL_AUTHOR                _SC("Alberto Demichelis")
-
-#define SQ_VMSTATE_IDLE                        0
-#define SQ_VMSTATE_RUNNING             1
-#define SQ_VMSTATE_SUSPENDED   2
-
-#define SQUIRREL_EOB 0
-#define SQ_BYTECODE_STREAM_TAG 0xFAFA
-
-#define SQOBJECT_REF_COUNTED   0x00800000
-#define SQOBJECT_NUMERIC               0x00400000
-#define SQOBJECT_DELEGABLE             0x00200000
-#define SQOBJECT_CANBEFALSE            0x00100000
-
-#define SQ_MATCHTYPEMASKSTRING (-99999)
-
-#define _RT_MASK 0x0000FFFF
-#define _RAW_TYPE(type) (type&_RT_MASK)
-
-#define _RT_NULL                       0x00000001
-#define _RT_INTEGER                    0x00000002
-#define _RT_FLOAT                      0x00000004
-#define _RT_BOOL                       0x00000008
-#define _RT_STRING                     0x00000010
-#define _RT_TABLE                      0x00000020
-#define _RT_ARRAY                      0x00000040
-#define _RT_USERDATA           0x00000080
-#define _RT_CLOSURE                    0x00000100
-#define _RT_NATIVECLOSURE      0x00000200
-#define _RT_GENERATOR          0x00000400
-#define _RT_USERPOINTER                0x00000800
-#define _RT_THREAD                     0x00001000
-#define _RT_FUNCPROTO          0x00002000
-#define _RT_CLASS                      0x00004000
-#define _RT_INSTANCE           0x00008000
-
-typedef enum {
-       OT_NULL =                       (_RT_NULL|SQOBJECT_CANBEFALSE),
-       OT_INTEGER =            (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
-       OT_FLOAT =                      (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
-       OT_BOOL =                       (_RT_BOOL|SQOBJECT_CANBEFALSE),
-       OT_STRING =                     (_RT_STRING|SQOBJECT_REF_COUNTED),
-       OT_TABLE =                      (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
-       OT_ARRAY =                      (_RT_ARRAY|SQOBJECT_REF_COUNTED),
-       OT_USERDATA =           (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
-       OT_CLOSURE =            (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
-       OT_NATIVECLOSURE =      (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
-       OT_GENERATOR =          (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
-       OT_USERPOINTER =        _RT_USERPOINTER,
-       OT_THREAD =                     (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
-       OT_FUNCPROTO =          (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
-       OT_CLASS =                      (_RT_CLASS|SQOBJECT_REF_COUNTED),
-       OT_INSTANCE =           (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE)
-}SQObjectType;
-
-#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
-
-
-typedef union tagSQObjectValue
-{
-       struct SQTable *pTable;
-       struct SQArray *pArray;
-       struct SQClosure *pClosure;
-       struct SQGenerator *pGenerator;
-       struct SQNativeClosure *pNativeClosure;
-       struct SQString *pString;
-       struct SQUserData *pUserData;
-       SQInteger nInteger;
-       SQFloat fFloat;
-       SQUserPointer pUserPointer;
-       struct SQFunctionProto *pFunctionProto;
-       struct SQRefCounted *pRefCounted;
-       struct SQDelegable *pDelegable;
-       struct SQVM *pThread;
-       struct SQClass *pClass;
-       struct SQInstance *pInstance;
-}SQObjectValue;
-
-
-typedef struct tagSQObject
-{
-       SQObjectValue _unVal;
-       SQObjectType _type;
-}SQObject;
-
-typedef struct tagSQStackInfos{
-       const SQChar* funcname;
-       const SQChar* source;
-       int line;
-}SQStackInfos;
-
-typedef struct SQVM* HSQUIRRELVM;
-typedef SQObject HSQOBJECT;
-typedef int (*SQFUNCTION)(HSQUIRRELVM);
-typedef int (*SQRELEASEHOOK)(SQUserPointer,int size);
-typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,int /*line*/,int /*column*/);
-typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
-
-typedef int (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,int);
-typedef int (*SQREADFUNC)(SQUserPointer,SQUserPointer,int);
-
-typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
-
-typedef struct tagSQRegFunction{
-       const SQChar *name;
-       SQFUNCTION f;
-       int nparamscheck;
-       const SQChar *typemask;
-}SQRegFunction;
-
-/*vm*/
-SQUIRREL_API HSQUIRRELVM sq_open(int initialstacksize);
-SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, int initialstacksize);
-SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
-SQUIRREL_API void sq_close(HSQUIRRELVM v);
-SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
-SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);
-SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval);
-SQUIRREL_API int sq_getvmstate(HSQUIRRELVM v);
-
-/*compiler*/
-SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,int size,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool debuginfo);
-SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
-
-/*stack operations*/
-SQUIRREL_API void sq_push(HSQUIRRELVM v,int idx);
-SQUIRREL_API void sq_pop(HSQUIRRELVM v,int nelemstopop);
-SQUIRREL_API void sq_remove(HSQUIRRELVM v,int idx);
-SQUIRREL_API int sq_gettop(HSQUIRRELVM v);
-SQUIRREL_API void sq_settop(HSQUIRRELVM v,int newtop);
-SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,int nsize);
-SQUIRREL_API int sq_cmp(HSQUIRRELVM v);
-SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,int idx);
-
-/*object creation handling*/
-SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,unsigned int size);
-SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
-SQUIRREL_API void sq_newarray(HSQUIRRELVM v,int size);
-SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,unsigned int nfreevars);
-SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,int nparamscheck,const SQChar *typemask);
-SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,int len);
-SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
-SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
-SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
-SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
-SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,int idx,const SQChar **c);
-SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,int idx,SQInteger *i);
-SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,int idx,SQFloat *f);
-SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,int idx,SQBool *b);
-SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,int idx,HSQUIRRELVM *thread);
-SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,int idx,SQUserPointer *p);
-SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,int idx,SQUserPointer *p,unsigned int *typetag);
-SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,int idx,unsigned int typetag);
-SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,int idx,unsigned int *typetag);
-SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,int idx,SQRELEASEHOOK hook);
-SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,int minsize);
-SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,int idx,unsigned int *nparams,unsigned int *nfreevars);
-SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,int idx,const SQChar *name);
-SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, int idx, SQUserPointer p);
-SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, int idx, SQUserPointer *p,unsigned int typetag);
-SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
-SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,int idx);
-
-/*object manipulation*/
-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,int idx);
-SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,int idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,int idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,int idx,SQBool pushval); 
-SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,int idx,int newsize); 
-SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,int idx); 
-SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,int idx);
-SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,int idx,unsigned int nval);
-SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,int idx);
-
-/*calls*/
-SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,int params,SQBool retval);
-SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval);
-SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,unsigned int level,unsigned int idx);
-SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
-SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
-SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
-
-/*raw object handling*/
-SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,int idx,HSQOBJECT *po);
-SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
-SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
-SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);
-SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);
-SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);
-
-/*GC*/
-SQUIRREL_API int sq_collectgarbage(HSQUIRRELVM v);
-
-/*serialization*/
-SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
-SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
-
-/*mem allocation*/
-SQUIRREL_API void *sq_malloc(unsigned int size);
-SQUIRREL_API void *sq_realloc(void* p,unsigned int oldsize,unsigned int newsize);
-SQUIRREL_API void sq_free(void *p,unsigned int size);
-
-/*debug*/
-SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,int level,SQStackInfos *si);
-SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
-
-/*UTILITY MACRO*/
-#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
-#define sq_istable(o) ((o)._type==OT_TABLE)
-#define sq_isarray(o) ((o)._type==OT_ARRAY)
-#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
-#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
-#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
-#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
-#define sq_isstring(o) ((o)._type==OT_STRING)
-#define sq_isinteger(o) ((o)._type==OT_INTEGER)
-#define sq_isfloat(o) ((o)._type==OT_FLOAT)
-#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
-#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
-#define sq_isthread(o) ((o)._type==OT_THREAD)
-#define sq_isnull(o) ((o)._type==OT_NULL)
-#define sq_isclass(o) ((o)._type==OT_CLASS)
-#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
-#define sq_isbool(o) ((o)._type==OT_BOOL)
-#define sq_type(o) ((o)._type)
-
-#define SQ_OK (0)
-#define SQ_ERROR (-1)
-
-#define SQ_FAILED(res) (res<0)
-#define SQ_SUCCEEDED(res) (res>=0)
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQUIRREL_H_*/
+/*\r
+Copyright (c) 2003-2005 Alberto Demichelis\r
+\r
+This software is provided 'as-is', without any \r
+express or implied warranty. In no event will the \r
+authors be held liable for any damages arising from \r
+the use of this software.\r
+\r
+Permission is granted to anyone to use this software \r
+for any purpose, including commercial applications, \r
+and to alter it and redistribute it freely, subject \r
+to the following restrictions:\r
+\r
+               1. The origin of this software must not be \r
+               misrepresented; you must not claim that \r
+               you wrote the original software. If you \r
+               use this software in a product, an \r
+               acknowledgment in the product \r
+               documentation would be appreciated but is \r
+               not required.\r
+\r
+               2. Altered source versions must be plainly \r
+               marked as such, and must not be \r
+               misrepresented as being the original \r
+               software.\r
+\r
+               3. This notice may not be removed or \r
+               altered from any source distribution.\r
+\r
+*/\r
+#ifndef _SQUIRREL_H_\r
+#define _SQUIRREL_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#ifndef SQUIRREL_API\r
+#define SQUIRREL_API extern\r
+#endif\r
+\r
+typedef float SQFloat;\r
+typedef int SQInteger;\r
+typedef int SQInt32; //must be 32 bits(also on 64bits processors)\r
+typedef void* SQUserPointer;\r
+typedef unsigned int SQUnsignedInteger;\r
+typedef unsigned int SQHash; //should be the same size of a pointer\r
+typedef SQUnsignedInteger SQBool;\r
+typedef SQInteger SQRESULT;\r
+\r
+#define SQTrue (1)\r
+#define SQFalse        (0)\r
+\r
+\r
+struct SQVM;\r
+struct SQTable;\r
+struct SQArray;\r
+struct SQString;\r
+struct SQClosure;\r
+struct SQGenerator;\r
+struct SQNativeClosure;\r
+struct SQUserData;\r
+struct SQFunctionProto;\r
+struct SQRefCounted;\r
+struct SQClass;\r
+struct SQInstance;\r
+struct SQDelegable;\r
+\r
+#ifdef _UNICODE\r
+#define SQUNICODE\r
+#endif\r
+\r
+#ifdef SQUNICODE\r
+typedef unsigned short SQChar;\r
+#define _SC(a) L##a\r
+#define        scstrcmp        wcscmp\r
+#define scsprintf      swprintf\r
+#define scstrlen       wcslen\r
+#define scstrtod       wcstod\r
+#define scstrtol       wcstol\r
+#define scatoi         _wtoi\r
+#define scstrtoul      wcstoul\r
+#define scvsprintf     vswprintf\r
+#define scstrstr       wcsstr\r
+#define scisspace      iswspace\r
+#define scisdigit      iswdigit\r
+#define scisalpha      iswalpha\r
+#define sciscntrl      iswcntrl\r
+#define scisalnum      iswalnum\r
+#define scprintf       wprintf\r
+#define MAX_CHAR 0xFFFF\r
+#else\r
+typedef char SQChar;\r
+#define _SC(a) a\r
+#define        scstrcmp        strcmp\r
+#define scsprintf      sprintf\r
+#define scstrlen       strlen\r
+#define scstrtod       strtod\r
+#define scstrtol       strtol\r
+#define scatoi         atoi\r
+#define scstrtoul      strtoul\r
+#define scvsprintf     vsprintf\r
+#define scstrstr       strstr\r
+#define scisspace      isspace\r
+#define scisdigit      isdigit\r
+#define sciscntrl      iscntrl\r
+#define scisalpha      isalpha\r
+#define scisalnum      isalnum\r
+#define scprintf       printf\r
+#define MAX_CHAR 0xFF\r
+#endif\r
+\r
+#define SQUIRREL_VERSION       _SC("Squirrel 2.0.5 stable")\r
+#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2005 Alberto Demichelis")\r
+#define SQUIRREL_AUTHOR                _SC("Alberto Demichelis")\r
+\r
+#define SQ_VMSTATE_IDLE                        0\r
+#define SQ_VMSTATE_RUNNING             1\r
+#define SQ_VMSTATE_SUSPENDED   2\r
+\r
+#define SQUIRREL_EOB 0\r
+#define SQ_BYTECODE_STREAM_TAG 0xFAFA\r
+\r
+#define SQOBJECT_REF_COUNTED   0x08000000\r
+#define SQOBJECT_NUMERIC               0x04000000\r
+#define SQOBJECT_DELEGABLE             0x02000000\r
+#define SQOBJECT_CANBEFALSE            0x01000000\r
+\r
+#define SQ_MATCHTYPEMASKSTRING (-99999)\r
+\r
+#define _RT_MASK 0x00FFFFFF\r
+#define _RAW_TYPE(type) (type&_RT_MASK)\r
+\r
+#define _RT_NULL                       0x00000001\r
+#define _RT_INTEGER                    0x00000002\r
+#define _RT_FLOAT                      0x00000004\r
+#define _RT_BOOL                       0x00000008\r
+#define _RT_STRING                     0x00000010\r
+#define _RT_TABLE                      0x00000020\r
+#define _RT_ARRAY                      0x00000040\r
+#define _RT_USERDATA           0x00000080\r
+#define _RT_CLOSURE                    0x00000100\r
+#define _RT_NATIVECLOSURE      0x00000200\r
+#define _RT_GENERATOR          0x00000400\r
+#define _RT_USERPOINTER                0x00000800\r
+#define _RT_THREAD                     0x00001000\r
+#define _RT_FUNCPROTO          0x00002000\r
+#define _RT_CLASS                      0x00004000\r
+#define _RT_INSTANCE           0x00008000\r
+#define _RT_WEAKREF                    0x00010000\r
+\r
+typedef enum {\r
+       OT_NULL =                       (_RT_NULL|SQOBJECT_CANBEFALSE),\r
+       OT_INTEGER =            (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),\r
+       OT_FLOAT =                      (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),\r
+       OT_BOOL =                       (_RT_BOOL|SQOBJECT_CANBEFALSE),\r
+       OT_STRING =                     (_RT_STRING|SQOBJECT_REF_COUNTED),\r
+       OT_TABLE =                      (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),\r
+       OT_ARRAY =                      (_RT_ARRAY|SQOBJECT_REF_COUNTED),\r
+       OT_USERDATA =           (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),\r
+       OT_CLOSURE =            (_RT_CLOSURE|SQOBJECT_REF_COUNTED),\r
+       OT_NATIVECLOSURE =      (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),\r
+       OT_GENERATOR =          (_RT_GENERATOR|SQOBJECT_REF_COUNTED),\r
+       OT_USERPOINTER =        _RT_USERPOINTER,\r
+       OT_THREAD =                     (_RT_THREAD|SQOBJECT_REF_COUNTED) ,\r
+       OT_FUNCPROTO =          (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only\r
+       OT_CLASS =                      (_RT_CLASS|SQOBJECT_REF_COUNTED),\r
+       OT_INSTANCE =           (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),\r
+       OT_WEAKREF =            (_RT_WEAKREF|SQOBJECT_REF_COUNTED)\r
+}SQObjectType;\r
+\r
+#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)\r
+\r
+\r
+typedef union tagSQObjectValue\r
+{\r
+       struct SQTable *pTable;\r
+       struct SQArray *pArray;\r
+       struct SQClosure *pClosure;\r
+       struct SQGenerator *pGenerator;\r
+       struct SQNativeClosure *pNativeClosure;\r
+       struct SQString *pString;\r
+       struct SQUserData *pUserData;\r
+       SQInteger nInteger;\r
+       SQFloat fFloat;\r
+       SQUserPointer pUserPointer;\r
+       struct SQFunctionProto *pFunctionProto;\r
+       struct SQRefCounted *pRefCounted;\r
+       struct SQDelegable *pDelegable;\r
+       struct SQVM *pThread;\r
+       struct SQClass *pClass;\r
+       struct SQInstance *pInstance;\r
+       struct SQWeakRef *pWeakRef;\r
+}SQObjectValue;\r
+\r
+\r
+typedef struct tagSQObject\r
+{\r
+       SQObjectValue _unVal;\r
+       SQObjectType _type;\r
+}SQObject;\r
+\r
+typedef struct tagSQStackInfos{\r
+       const SQChar* funcname;\r
+       const SQChar* source;\r
+       SQInteger line;\r
+}SQStackInfos;\r
+\r
+typedef struct SQVM* HSQUIRRELVM;\r
+typedef SQObject HSQOBJECT;\r
+typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);\r
+typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);\r
+typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);\r
+typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);\r
+\r
+typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);\r
+typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);\r
+\r
+typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);\r
+\r
+typedef struct tagSQRegFunction{\r
+       const SQChar *name;\r
+       SQFUNCTION f;\r
+       SQInteger nparamscheck;\r
+       const SQChar *typemask;\r
+}SQRegFunction;\r
+\r
+/*vm*/\r
+SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);\r
+SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);\r
+SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_close(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);\r
+SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);\r
+SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);\r
+SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);\r
+SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval);\r
+SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);\r
+\r
+/*compiler*/\r
+SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);\r
+SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);\r
+SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool debuginfo);\r
+SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);\r
+\r
+/*stack operations*/\r
+SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);\r
+SQUIRREL_API void sq_poptop(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);\r
+SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize);\r
+SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);\r
+\r
+/*object creation handling*/\r
+SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);\r
+SQUIRREL_API void sq_newtable(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);\r
+SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);\r
+SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);\r
+SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);\r
+SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);\r
+SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);\r
+SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);\r
+SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);\r
+SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);\r
+SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);\r
+SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);\r
+SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);\r
+SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);\r
+SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);\r
+SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);\r
+SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);\r
+SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);\r
+SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);\r
+SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);\r
+SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);\r
+SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);\r
+SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);\r
+SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);\r
+SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);\r
+SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);\r
+SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);\r
+\r
+/*object manipulation*/\r
+SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);\r
+SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);\r
+SQUIRREL_API SQRESULT sq_createslot(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);\r
+SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);\r
+SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); \r
+SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); \r
+SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); \r
+SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);\r
+SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);\r
+SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);\r
+\r
+/*calls*/\r
+SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval);\r
+SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval);\r
+SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);\r
+SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);\r
+SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);\r
+SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);\r
+SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);\r
+\r
+/*raw object handling*/\r
+SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);\r
+SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);\r
+SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);\r
+SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);\r
+SQUIRREL_API void sq_resetobject(HSQOBJECT *po);\r
+SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);\r
+SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o);\r
+SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);\r
+SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);\r
+\r
+/*GC*/\r
+SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);\r
+\r
+/*serialization*/\r
+SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);\r
+SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);\r
+\r
+/*mem allocation*/\r
+SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);\r
+SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);\r
+SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);\r
+\r
+/*debug*/\r
+SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);\r
+SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);\r
+\r
+/*UTILITY MACRO*/\r
+#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)\r
+#define sq_istable(o) ((o)._type==OT_TABLE)\r
+#define sq_isarray(o) ((o)._type==OT_ARRAY)\r
+#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)\r
+#define sq_isclosure(o) ((o)._type==OT_CLOSURE)\r
+#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)\r
+#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)\r
+#define sq_isstring(o) ((o)._type==OT_STRING)\r
+#define sq_isinteger(o) ((o)._type==OT_INTEGER)\r
+#define sq_isfloat(o) ((o)._type==OT_FLOAT)\r
+#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)\r
+#define sq_isuserdata(o) ((o)._type==OT_USERDATA)\r
+#define sq_isthread(o) ((o)._type==OT_THREAD)\r
+#define sq_isnull(o) ((o)._type==OT_NULL)\r
+#define sq_isclass(o) ((o)._type==OT_CLASS)\r
+#define sq_isinstance(o) ((o)._type==OT_INSTANCE)\r
+#define sq_isbool(o) ((o)._type==OT_BOOL)\r
+#define sq_isweakref(o) ((o)._type==OT_WEAKREF)\r
+#define sq_type(o) ((o)._type)\r
+\r
+#define SQ_OK (0)\r
+#define SQ_ERROR (-1)\r
+\r
+#define SQ_FAILED(res) (res<0)\r
+#define SQ_SUCCEEDED(res) (res>=0)\r
+\r
+#ifdef __cplusplus\r
+} /*extern "C"*/\r
+#endif\r
+\r
+#endif /*_SQUIRREL_H_*/\r
index 62a1598..30808ed 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdaux.h>
-
-void sqstd_printcallstack(HSQUIRRELVM v)
-{
-       SQPRINTFUNCTION pf = sq_getprintfunc(v);
-       if(pf) {
-               SQStackInfos si;
-               SQInteger i;
-               SQFloat f;
-               const SQChar *s;
-               int level=1; //1 is to skip this function that is level 0
-               const SQChar *name=0; 
-               int seq=0;
-               pf(v,_SC("\nCALLSTACK\n"));
-               while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
-               {
-                       const SQChar *fn=_SC("unknown");
-                       const SQChar *src=_SC("unknown");
-                       if(si.funcname)fn=si.funcname;
-                       if(si.source)src=si.source;
-                       pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
-                       level++;
-               }
-               level=0;
-               pf(v,_SC("\nLOCALS\n"));
-
-               for(level=0;level<10;level++){
-                       seq=0;
-                       while(name=sq_getlocal(v,level,seq))
-                       {
-                               seq++;
-                               switch(sq_gettype(v,-1))
-                               {
-                               case OT_NULL:
-                                       pf(v,_SC("[%s] NULL\n"),name);
-                                       break;
-                               case OT_INTEGER:
-                                       sq_getinteger(v,-1,&i);
-                                       pf(v,_SC("[%s] %d\n"),name,i);
-                                       break;
-                               case OT_FLOAT:
-                                       sq_getfloat(v,-1,&f);
-                                       pf(v,_SC("[%s] %.14g\n"),name,f);
-                                       break;
-                               case OT_USERPOINTER:
-                                       pf(v,_SC("[%s] USERPOINTER\n"),name);
-                                       break;
-                               case OT_STRING:
-                                       sq_getstring(v,-1,&s);
-                                       pf(v,_SC("[%s] \"%s\"\n"),name,s);
-                                       break;
-                               case OT_TABLE:
-                                       pf(v,_SC("[%s] TABLE\n"),name);
-                                       break;
-                               case OT_ARRAY:
-                                       pf(v,_SC("[%s] ARRAY\n"),name);
-                                       break;
-                               case OT_CLOSURE:
-                                       pf(v,_SC("[%s] CLOSURE\n"),name);
-                                       break;
-                               case OT_NATIVECLOSURE:
-                                       pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
-                                       break;
-                               case OT_USERDATA:
-                                       pf(v,_SC("[%s] USERDATA\n"),name);
-                                       break;
-                               case OT_THREAD:
-                                       pf(v,_SC("[%s] THREAD\n"),name);
-                                       break;
-                               case OT_CLASS:
-                                       pf(v,_SC("[%s] CLASS\n"),name);
-                                       break;
-                               case OT_INSTANCE:
-                                       pf(v,_SC("[%s] INSTANCE\n"),name);
-                                       break;
-                               }
-                               sq_pop(v,1);
-                       }
-               }
-       }
-}
-
-static int _sqstd_aux_printerror(HSQUIRRELVM v)
-{
-       SQPRINTFUNCTION pf = sq_getprintfunc(v);
-       if(pf) {
-               const SQChar *sErr = 0;
-               if(sq_gettop(v)>=1) {
-                       if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr)))       {
-                               pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
-                       }
-                       else{
-                               pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
-                       }
-                       sqstd_printcallstack(v);
-               }
-       }
-       return 0;
-}
-
-void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,int line,int column)
-{
-       SQPRINTFUNCTION pf = sq_getprintfunc(v);
-       if(pf) {
-               pf(v,_SC("ERROR %s line=(%d) column=(%d) [%s]\n"),sErr,line,column,sSource);
-       }
-}
-
-void sqstd_seterrorhandlers(HSQUIRRELVM v)
-{
-       sq_setcompilererrorhandler(v,_sqstd_compiler_error);
-       sq_newclosure(v,_sqstd_aux_printerror,0);
-       sq_seterrorhandler(v);
-}
+/* see copyright notice in squirrel.h */\r
+#include <squirrel.h>\r
+#include <sqstdaux.h>\r
+\r
+void sqstd_printcallstack(HSQUIRRELVM v)\r
+{\r
+       SQPRINTFUNCTION pf = sq_getprintfunc(v);\r
+       if(pf) {\r
+               SQStackInfos si;\r
+               SQInteger i;\r
+               SQFloat f;\r
+               const SQChar *s;\r
+               SQInteger level=1; //1 is to skip this function that is level 0\r
+               const SQChar *name=0; \r
+               SQInteger seq=0;\r
+               pf(v,_SC("\nCALLSTACK\n"));\r
+               while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))\r
+               {\r
+                       const SQChar *fn=_SC("unknown");\r
+                       const SQChar *src=_SC("unknown");\r
+                       if(si.funcname)fn=si.funcname;\r
+                       if(si.source)src=si.source;\r
+                       pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);\r
+                       level++;\r
+               }\r
+               level=0;\r
+               pf(v,_SC("\nLOCALS\n"));\r
+\r
+               for(level=0;level<10;level++){\r
+                       seq=0;\r
+                       while(name=sq_getlocal(v,level,seq))\r
+                       {\r
+                               seq++;\r
+                               switch(sq_gettype(v,-1))\r
+                               {\r
+                               case OT_NULL:\r
+                                       pf(v,_SC("[%s] NULL\n"),name);\r
+                                       break;\r
+                               case OT_INTEGER:\r
+                                       sq_getinteger(v,-1,&i);\r
+                                       pf(v,_SC("[%s] %d\n"),name,i);\r
+                                       break;\r
+                               case OT_FLOAT:\r
+                                       sq_getfloat(v,-1,&f);\r
+                                       pf(v,_SC("[%s] %.14g\n"),name,f);\r
+                                       break;\r
+                               case OT_USERPOINTER:\r
+                                       pf(v,_SC("[%s] USERPOINTER\n"),name);\r
+                                       break;\r
+                               case OT_STRING:\r
+                                       sq_getstring(v,-1,&s);\r
+                                       pf(v,_SC("[%s] \"%s\"\n"),name,s);\r
+                                       break;\r
+                               case OT_TABLE:\r
+                                       pf(v,_SC("[%s] TABLE\n"),name);\r
+                                       break;\r
+                               case OT_ARRAY:\r
+                                       pf(v,_SC("[%s] ARRAY\n"),name);\r
+                                       break;\r
+                               case OT_CLOSURE:\r
+                                       pf(v,_SC("[%s] CLOSURE\n"),name);\r
+                                       break;\r
+                               case OT_NATIVECLOSURE:\r
+                                       pf(v,_SC("[%s] NATIVECLOSURE\n"),name);\r
+                                       break;\r
+                               case OT_USERDATA:\r
+                                       pf(v,_SC("[%s] USERDATA\n"),name);\r
+                                       break;\r
+                               case OT_THREAD:\r
+                                       pf(v,_SC("[%s] THREAD\n"),name);\r
+                                       break;\r
+                               case OT_CLASS:\r
+                                       pf(v,_SC("[%s] CLASS\n"),name);\r
+                                       break;\r
+                               case OT_INSTANCE:\r
+                                       pf(v,_SC("[%s] INSTANCE\n"),name);\r
+                                       break;\r
+                               }\r
+                               sq_pop(v,1);\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)\r
+{\r
+       SQPRINTFUNCTION pf = sq_getprintfunc(v);\r
+       if(pf) {\r
+               const SQChar *sErr = 0;\r
+               if(sq_gettop(v)>=1) {\r
+                       if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr)))       {\r
+                               pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);\r
+                       }\r
+                       else{\r
+                               pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));\r
+                       }\r
+                       sqstd_printcallstack(v);\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)\r
+{\r
+       SQPRINTFUNCTION pf = sq_getprintfunc(v);\r
+       if(pf) {\r
+               pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);\r
+       }\r
+}\r
+\r
+void sqstd_seterrorhandlers(HSQUIRRELVM v)\r
+{\r
+       sq_setcompilererrorhandler(v,_sqstd_compiler_error);\r
+       sq_newclosure(v,_sqstd_aux_printerror,0);\r
+       sq_seterrorhandler(v);\r
+}\r
index 6dfb760..9b0fe59 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <string.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
-
-//Blob
-
-
-#define SETUP_BLOB(v) \
-       SQBlob *self = NULL; \
-       { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,SQSTD_BLOB_TYPE_TAG))) \
-               return SQ_ERROR; }
-
-
-static int _blob_resize(HSQUIRRELVM v)
-{
-       SETUP_BLOB(v);
-       SQInteger size;
-       sq_getinteger(v,2,&size);
-       if(!self->Resize(size))
-               return sq_throwerror(v,_SC("resize failed"));
-       return 0;
-}
-
-static void __swap_dword(unsigned int *n)
-{
-       *n=(unsigned int)(((*n&0xFF000000)>>24)  |
-                       ((*n&0x00FF0000)>>8)  |
-                       ((*n&0x0000FF00)<<8)  |
-                       ((*n&0x000000FF)<<24));
-}
-
-static void __swap_word(unsigned short *n)
-{
-       *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
-}
-
-static int _blob_swap4(HSQUIRRELVM v)
-{
-       SETUP_BLOB(v);
-       int num=(self->Len()-(self->Len()%4))>>2;
-       unsigned int *t=(unsigned int *)self->GetBuf();
-       for(int i = 0; i < num; i++) {
-               __swap_dword(&t[i]);
-       }
-       return 0;
-}
-
-static int _blob_swap2(HSQUIRRELVM v)
-{
-       SETUP_BLOB(v);
-       int num=(self->Len()-(self->Len()%2))>>1;
-       unsigned short *t = (unsigned short *)self->GetBuf();
-       for(int i = 0; i < num; i++) {
-               __swap_word(&t[i]);
-       }
-       return 0;
-}
-
-static int _blob__set(HSQUIRRELVM v)
-{
-       SETUP_BLOB(v);
-       SQInteger idx,val;
-       sq_getinteger(v,2,&idx);
-       sq_getinteger(v,3,&val);
-       if(idx < 0 || idx >= self->Len())
-               return sq_throwerror(v,_SC("index out of range"));
-       ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
-       sq_push(v,3);
-       return 1;
-}
-
-static int _blob__get(HSQUIRRELVM v)
-{
-       SETUP_BLOB(v);
-       SQInteger idx;
-       sq_getinteger(v,2,&idx);
-       if(idx < 0 || idx >= self->Len())
-               return sq_throwerror(v,_SC("index out of range"));
-       sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
-       return 1;
-}
-
-static int _blob__nexti(HSQUIRRELVM v)
-{
-       SETUP_BLOB(v);
-       if(sq_gettype(v,2) == OT_NULL) {
-               sq_pushinteger(v, 0);
-               return 1;
-       }
-       SQInteger idx;
-       if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
-               if(idx+1 < self->Len()) {
-                       sq_pushinteger(v, idx+1);
-                       return 1;
-               }
-               sq_pushnull(v);
-               return 1;
-       }
-       return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
-}
-
-static int _blob__typeof(HSQUIRRELVM v)
-{
-       sq_pushstring(v,_SC("blob"),-1);
-       return 1;
-}
-
-static int _blob_releasehook(SQUserPointer p, int size)
-{
-       SQBlob *self = (SQBlob*)p;
-       delete self;
-       return 1;
-}
-
-static int _blob_constructor(HSQUIRRELVM v)
-{
-       SQInteger nparam = sq_gettop(v);
-       SQInteger size = 0;
-       if(nparam == 2) {
-               sq_getinteger(v, 2, &size);
-       }
-       if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
-       SQBlob *b = new SQBlob(size);
-       if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
-               delete b;
-               return sq_throwerror(v, _SC("cannot create blob with negative size"));
-       }
-       sq_setreleasehook(v,1,_blob_releasehook);
-       return 0;
-}
-
-#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
-static SQRegFunction _blob_methods[] = {
-       _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
-       _DECL_BLOB_FUNC(resize,2,_SC("xn")),
-       _DECL_BLOB_FUNC(swap2,1,_SC("x")),
-       _DECL_BLOB_FUNC(swap4,1,_SC("x")),
-       _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
-       _DECL_BLOB_FUNC(_get,2,_SC("xn")),
-       _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
-       _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
-       {0,0,0,0}
-};
-
-
-
-//GLOBAL FUNCTIONS
-
-static int _g_blob_casti2f(HSQUIRRELVM v)
-{
-       SQInteger i;
-       sq_getinteger(v,2,&i);
-       sq_pushfloat(v,*((SQFloat *)&i));
-       return 1;
-}
-
-static int _g_blob_castf2i(HSQUIRRELVM v)
-{
-       SQFloat f;
-       sq_getfloat(v,2,&f);
-       sq_pushinteger(v,*((SQInteger *)&f));
-       return 1;
-}
-
-static int _g_blob_swap2(HSQUIRRELVM v)
-{
-       SQInteger i;
-       sq_getinteger(v,2,&i);
-       short s=(short)i;
-       sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
-       return 1;
-}
-
-static int _g_blob_swap4(HSQUIRRELVM v)
-{
-       SQInteger i;
-       sq_getinteger(v,2,&i);
-       __swap_dword((unsigned int *)&i);
-       sq_pushinteger(v,i);
-       return 1;
-}
-
-static int _g_blob_swapfloat(HSQUIRRELVM v)
-{
-       SQFloat f;
-       sq_getfloat(v,2,&f);
-       __swap_dword((unsigned int *)&f);
-       sq_pushfloat(v,f);
-       return 1;
-}
-
-#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
-static SQRegFunction bloblib_funcs[]={
-       _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
-       _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
-       _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
-       _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
-       _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
-       {0,0}
-};
-
-SQRESULT sqstd_getblob(HSQUIRRELVM v,int idx,SQUserPointer *ptr)
-{
-       SQBlob *blob;
-       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG)))
-               return -1;
-       *ptr = blob->GetBuf();
-       return SQ_OK;
-}
-
-int sqstd_getblobsize(HSQUIRRELVM v,int idx)
-{
-       SQBlob *blob;
-       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG)))
-               return -1;
-       return blob->Len();
-}
-
-SQUserPointer sqstd_createblob(HSQUIRRELVM v, int size)
-{
-       int top = sq_gettop(v);
-//     SQUserPointer p = sq_newuserdata(v, sizeof(SQBlob));
-//     sq_setreleasehook(v,-1,_blob_releasehook);
-//     sq_settypetag(v,-1,SQSTD_BLOB_TYPE_TAG);
-//     new (p) SQBlob(size);
-       sq_pushregistrytable(v);
-       sq_pushstring(v,_SC("std_blob"),-1);
-       if(SQ_SUCCEEDED(sq_get(v,-2))) {
-               sq_remove(v,-2); //removes the registry
-               sq_push(v,1); // push the this
-               sq_pushinteger(v,size); //size
-               SQBlob *blob = NULL;
-               if(SQ_SUCCEEDED(sq_call(v,2,SQTrue))
-                       && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG))) {
-                       sq_remove(v,-2);
-                       sq_remove(v,-2);
-                       return blob->GetBuf();
-               }
-       }
-       sq_settop(v,top);
-       return NULL;
-}
-
-SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
-{
-       return declare_stream(v,_SC("blob"),SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
-}
-
+/* see copyright notice in squirrel.h */\r
+#include <new>\r
+#include <squirrel.h>\r
+#include <sqstdio.h>\r
+#include <string.h>\r
+#include <sqstdblob.h>\r
+#include "sqstdstream.h"\r
+#include "sqstdblobimpl.h"\r
+\r
+#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)\r
+\r
+//Blob\r
+\r
+\r
+#define SETUP_BLOB(v) \\r
+       SQBlob *self = NULL; \\r
+       { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \\r
+               return SQ_ERROR; }\r
+\r
+\r
+static SQInteger _blob_resize(HSQUIRRELVM v)\r
+{\r
+       SETUP_BLOB(v);\r
+       SQInteger size;\r
+       sq_getinteger(v,2,&size);\r
+       if(!self->Resize(size))\r
+               return sq_throwerror(v,_SC("resize failed"));\r
+       return 0;\r
+}\r
+\r
+static void __swap_dword(unsigned int *n)\r
+{\r
+       *n=(SQUnsignedInteger)(((*n&0xFF000000)>>24)  |\r
+                       ((*n&0x00FF0000)>>8)  |\r
+                       ((*n&0x0000FF00)<<8)  |\r
+                       ((*n&0x000000FF)<<24));\r
+}\r
+\r
+static void __swap_word(unsigned short *n)\r
+{\r
+       *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);\r
+}\r
+\r
+static SQInteger _blob_swap4(HSQUIRRELVM v)\r
+{\r
+       SETUP_BLOB(v);\r
+       SQInteger num=(self->Len()-(self->Len()%4))>>2;\r
+       unsigned int *t=(unsigned int *)self->GetBuf();\r
+       for(SQInteger i = 0; i < num; i++) {\r
+               __swap_dword(&t[i]);\r
+       }\r
+       return 0;\r
+}\r
+\r
+static SQInteger _blob_swap2(HSQUIRRELVM v)\r
+{\r
+       SETUP_BLOB(v);\r
+       SQInteger num=(self->Len()-(self->Len()%2))>>1;\r
+       unsigned short *t = (unsigned short *)self->GetBuf();\r
+       for(SQInteger i = 0; i < num; i++) {\r
+               __swap_word(&t[i]);\r
+       }\r
+       return 0;\r
+}\r
+\r
+static SQInteger _blob__set(HSQUIRRELVM v)\r
+{\r
+       SETUP_BLOB(v);\r
+       SQInteger idx,val;\r
+       sq_getinteger(v,2,&idx);\r
+       sq_getinteger(v,3,&val);\r
+       if(idx < 0 || idx >= self->Len())\r
+               return sq_throwerror(v,_SC("index out of range"));\r
+       ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;\r
+       sq_push(v,3);\r
+       return 1;\r
+}\r
+\r
+static SQInteger _blob__get(HSQUIRRELVM v)\r
+{\r
+       SETUP_BLOB(v);\r
+       SQInteger idx;\r
+       sq_getinteger(v,2,&idx);\r
+       if(idx < 0 || idx >= self->Len())\r
+               return sq_throwerror(v,_SC("index out of range"));\r
+       sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);\r
+       return 1;\r
+}\r
+\r
+static SQInteger _blob__nexti(HSQUIRRELVM v)\r
+{\r
+       SETUP_BLOB(v);\r
+       if(sq_gettype(v,2) == OT_NULL) {\r
+               sq_pushinteger(v, 0);\r
+               return 1;\r
+       }\r
+       SQInteger idx;\r
+       if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {\r
+               if(idx+1 < self->Len()) {\r
+                       sq_pushinteger(v, idx+1);\r
+                       return 1;\r
+               }\r
+               sq_pushnull(v);\r
+               return 1;\r
+       }\r
+       return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));\r
+}\r
+\r
+static SQInteger _blob__typeof(HSQUIRRELVM v)\r
+{\r
+       sq_pushstring(v,_SC("blob"),-1);\r
+       return 1;\r
+}\r
+\r
+static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)\r
+{\r
+       SQBlob *self = (SQBlob*)p;\r
+       delete self;\r
+       return 1;\r
+}\r
+\r
+static SQInteger _blob_constructor(HSQUIRRELVM v)\r
+{\r
+       SQInteger nparam = sq_gettop(v);\r
+       SQInteger size = 0;\r
+       if(nparam == 2) {\r
+               sq_getinteger(v, 2, &size);\r
+       }\r
+       if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));\r
+       SQBlob *b = new SQBlob(size);\r
+       if(SQ_FAILED(sq_setinstanceup(v,1,b))) {\r
+               delete b;\r
+               return sq_throwerror(v, _SC("cannot create blob with negative size"));\r
+       }\r
+       sq_setreleasehook(v,1,_blob_releasehook);\r
+       return 0;\r
+}\r
+\r
+#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}\r
+static SQRegFunction _blob_methods[] = {\r
+       _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),\r
+       _DECL_BLOB_FUNC(resize,2,_SC("xn")),\r
+       _DECL_BLOB_FUNC(swap2,1,_SC("x")),\r
+       _DECL_BLOB_FUNC(swap4,1,_SC("x")),\r
+       _DECL_BLOB_FUNC(_set,3,_SC("xnn")),\r
+       _DECL_BLOB_FUNC(_get,2,_SC("xn")),\r
+       _DECL_BLOB_FUNC(_typeof,1,_SC("x")),\r
+       _DECL_BLOB_FUNC(_nexti,2,_SC("x")),\r
+       {0,0,0,0}\r
+};\r
+\r
+\r
+\r
+//GLOBAL FUNCTIONS\r
+\r
+static SQInteger _g_blob_casti2f(HSQUIRRELVM v)\r
+{\r
+       SQInteger i;\r
+       sq_getinteger(v,2,&i);\r
+       sq_pushfloat(v,*((SQFloat *)&i));\r
+       return 1;\r
+}\r
+\r
+static SQInteger _g_blob_castf2i(HSQUIRRELVM v)\r
+{\r
+       SQFloat f;\r
+       sq_getfloat(v,2,&f);\r
+       sq_pushinteger(v,*((SQInteger *)&f));\r
+       return 1;\r
+}\r
+\r
+static SQInteger _g_blob_swap2(HSQUIRRELVM v)\r
+{\r
+       SQInteger i;\r
+       sq_getinteger(v,2,&i);\r
+       short s=(short)i;\r
+       sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));\r
+       return 1;\r
+}\r
+\r
+static SQInteger _g_blob_swap4(HSQUIRRELVM v)\r
+{\r
+       SQInteger i;\r
+       sq_getinteger(v,2,&i);\r
+       __swap_dword((SQUnsignedInteger *)&i);\r
+       sq_pushinteger(v,i);\r
+       return 1;\r
+}\r
+\r
+static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)\r
+{\r
+       SQFloat f;\r
+       sq_getfloat(v,2,&f);\r
+       __swap_dword((SQUnsignedInteger *)&f);\r
+       sq_pushfloat(v,f);\r
+       return 1;\r
+}\r
+\r
+#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}\r
+static SQRegFunction bloblib_funcs[]={\r
+       _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),\r
+       _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),\r
+       _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),\r
+       _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),\r
+       _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),\r
+       {0,0}\r
+};\r
+\r
+SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)\r
+{\r
+       SQBlob *blob;\r
+       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))\r
+               return -1;\r
+       *ptr = blob->GetBuf();\r
+       return SQ_OK;\r
+}\r
+\r
+SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQBlob *blob;\r
+       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))\r
+               return -1;\r
+       return blob->Len();\r
+}\r
+\r
+SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)\r
+{\r
+       SQInteger top = sq_gettop(v);\r
+       sq_pushregistrytable(v);\r
+       sq_pushstring(v,_SC("std_blob"),-1);\r
+       if(SQ_SUCCEEDED(sq_get(v,-2))) {\r
+               sq_remove(v,-2); //removes the registry\r
+               sq_push(v,1); // push the this\r
+               sq_pushinteger(v,size); //size\r
+               SQBlob *blob = NULL;\r
+               if(SQ_SUCCEEDED(sq_call(v,2,SQTrue))\r
+                       && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {\r
+                       sq_remove(v,-2);\r
+                       sq_remove(v,-2);\r
+                       return blob->GetBuf();\r
+               }\r
+       }\r
+       sq_settop(v,top);\r
+       return NULL;\r
+}\r
+\r
+SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)\r
+{\r
+       return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);\r
+}\r
+\r
index 8e1fddb..b927e7c 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTD_BLOBIMPL_H_
-#define _SQSTD_BLOBIMPL_H_
-
-struct SQBlob : public SQStream
-{
-       SQBlob(int size) {
-               _size = size;
-               _allocated = size;
-               _buf = (unsigned char *)sq_malloc(size);
-               memset(_buf, 0, _size);
-               _ptr = 0;
-               _owns = true;
-       }
-       ~SQBlob() {
-               sq_free(_buf, _size);
-       }
-       SQInteger Write(void *buffer, SQInteger size) {
-               if(!CanAdvance(size)) {
-                       GrowBufOf(_ptr + size - _size);
-               }
-               memcpy(&_buf[_ptr], buffer, size);
-               _ptr += size;
-               return size;
-       }
-       SQInteger Read(void *buffer,SQInteger size) {
-               int n = size;
-               if(!CanAdvance(size)) {
-                       if((_size - _ptr) > 0)
-                               n = _size - _ptr;
-                       else return 0;
-               }
-               memcpy(buffer, &_buf[_ptr], n);
-               _ptr += n;
-               return n;
-       }
-       bool Resize(int n) {
-               if(!_owns) return false;
-               if(n != _allocated) {
-                       unsigned char *newbuf = (unsigned char *)sq_malloc(n);
-                       memset(newbuf,0,n);
-                       if(_size > n)
-                               memcpy(newbuf,_buf,n);
-                       else
-                               memcpy(newbuf,_buf,_size);
-                       sq_free(_buf,_allocated);
-                       _buf=newbuf;
-                       _allocated = n;
-                       if(_size > _allocated)
-                               _size = _allocated;
-                       if(_ptr > _allocated)
-                               _ptr = _allocated;
-               }
-               return true;
-       }
-       bool GrowBufOf(int n)
-       {
-               bool ret = true;
-               if(_size + n > _allocated) {
-                       if(_size + n > _size * 2)
-                               ret = Resize(_size + n);
-                       else
-                               ret = Resize(_size * 2);
-               }
-               _size = _size + n;
-               return ret;
-       }
-       bool CanAdvance(int n) {
-               if(_ptr+n>_size)return false;
-               return true;
-       }
-       SQInteger Seek(long offset, int origin) {
-               switch(origin) {
-                       case SQ_SEEK_SET:
-                               if(offset >= _size || offset < 0) return -1;
-                               _ptr = offset;
-                               break;
-                       case SQ_SEEK_CUR:
-                               if(_ptr + offset >= _size || _ptr + offset < 0) return -1;
-                               _ptr += offset;
-                               break;
-                       case SQ_SEEK_END:
-                               if(_size + offset >= _size || _size + offset < 0) return -1;
-                               _ptr = _size + offset;
-                               break;
-                       default: return -1;
-               }
-               return 0;
-       }
-       bool IsValid() {
-               return _buf?true:false;
-       }
-       bool EOS() {
-               return _ptr == _size;
-       }
-       int Flush() { return 0; }
-       long Tell() { return _ptr; }
-       SQInteger Len() { return _size; }
-       SQUserPointer GetBuf(){ return _buf; }
-private:
-       int _size;
-       int _allocated;
-       int _ptr;
-       unsigned char *_buf;
-       bool _owns;
-};
-
-#endif //_SQSTD_BLOBIMPL_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTD_BLOBIMPL_H_\r
+#define _SQSTD_BLOBIMPL_H_\r
+\r
+struct SQBlob : public SQStream\r
+{\r
+       SQBlob(SQInteger size) {\r
+               _size = size;\r
+               _allocated = size;\r
+               _buf = (unsigned char *)sq_malloc(size);\r
+               memset(_buf, 0, _size);\r
+               _ptr = 0;\r
+               _owns = true;\r
+       }\r
+       ~SQBlob() {\r
+               sq_free(_buf, _allocated);\r
+       }\r
+       SQInteger Write(void *buffer, SQInteger size) {\r
+               if(!CanAdvance(size)) {\r
+                       GrowBufOf(_ptr + size - _size);\r
+               }\r
+               memcpy(&_buf[_ptr], buffer, size);\r
+               _ptr += size;\r
+               return size;\r
+       }\r
+       SQInteger Read(void *buffer,SQInteger size) {\r
+               SQInteger n = size;\r
+               if(!CanAdvance(size)) {\r
+                       if((_size - _ptr) > 0)\r
+                               n = _size - _ptr;\r
+                       else return 0;\r
+               }\r
+               memcpy(buffer, &_buf[_ptr], n);\r
+               _ptr += n;\r
+               return n;\r
+       }\r
+       bool Resize(SQInteger n) {\r
+               if(!_owns) return false;\r
+               if(n != _allocated) {\r
+                       unsigned char *newbuf = (unsigned char *)sq_malloc(n);\r
+                       memset(newbuf,0,n);\r
+                       if(_size > n)\r
+                               memcpy(newbuf,_buf,n);\r
+                       else\r
+                               memcpy(newbuf,_buf,_size);\r
+                       sq_free(_buf,_allocated);\r
+                       _buf=newbuf;\r
+                       _allocated = n;\r
+                       if(_size > _allocated)\r
+                               _size = _allocated;\r
+                       if(_ptr > _allocated)\r
+                               _ptr = _allocated;\r
+               }\r
+               return true;\r
+       }\r
+       bool GrowBufOf(SQInteger n)\r
+       {\r
+               bool ret = true;\r
+               if(_size + n > _allocated) {\r
+                       if(_size + n > _size * 2)\r
+                               ret = Resize(_size + n);\r
+                       else\r
+                               ret = Resize(_size * 2);\r
+               }\r
+               _size = _size + n;\r
+               return ret;\r
+       }\r
+       bool CanAdvance(SQInteger n) {\r
+               if(_ptr+n>_size)return false;\r
+               return true;\r
+       }\r
+       SQInteger Seek(SQInteger offset, SQInteger origin) {\r
+               switch(origin) {\r
+                       case SQ_SEEK_SET:\r
+                               if(offset > _size || offset < 0) return -1;\r
+                               _ptr = offset;\r
+                               break;\r
+                       case SQ_SEEK_CUR:\r
+                               if(_ptr + offset > _size || _ptr + offset < 0) return -1;\r
+                               _ptr += offset;\r
+                               break;\r
+                       case SQ_SEEK_END:\r
+                               if(_size + offset > _size || _size + offset < 0) return -1;\r
+                               _ptr = _size + offset;\r
+                               break;\r
+                       default: return -1;\r
+               }\r
+               return 0;\r
+       }\r
+       bool IsValid() {\r
+               return _buf?true:false;\r
+       }\r
+       bool EOS() {\r
+               return _ptr == _size;\r
+       }\r
+       SQInteger Flush() { return 0; }\r
+       SQInteger Tell() { return _ptr; }\r
+       SQInteger Len() { return _size; }\r
+       SQUserPointer GetBuf(){ return _buf; }\r
+private:\r
+       SQInteger _size;\r
+       SQInteger _allocated;\r
+       SQInteger _ptr;\r
+       unsigned char *_buf;\r
+       bool _owns;\r
+};\r
+\r
+#endif //_SQSTD_BLOBIMPL_H_\r
index 7534697..396d222 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "sqstdstream.h"
-
-#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
-//basic API
-SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
-{
-#ifndef _UNICODE
-       return (SQFILE)fopen(filename,mode);
-#else
-       return (SQFILE)_wfopen(filename,mode);
-#endif
-}
-
-SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
-{
-       return (SQInteger)fread(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
-{
-       return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fseek(SQFILE file, long offset, int origin)
-{
-       int realorigin;
-       switch(origin) {
-               case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
-               case SQ_SEEK_END: realorigin = SEEK_END; break;
-               case SQ_SEEK_SET: realorigin = SEEK_SET; break;
-               default: return -1; //failed
-       }
-       return fseek((FILE *)file,offset,realorigin);
-}
-
-long sqstd_ftell(SQFILE file)
-{
-       return ftell((FILE *)file);
-}
-
-SQInteger sqstd_fflush(SQFILE file)
-{
-       return fflush((FILE *)file);
-}
-
-SQInteger sqstd_fclose(SQFILE file)
-{
-       return fclose((FILE *)file);
-}
-
-SQInteger sqstd_feof(SQFILE file)
-{
-       return feof((FILE *)file);
-}
-
-//File
-struct SQFile : public SQStream {
-       SQFile() { _handle = NULL; _owns = false;}
-       SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
-       ~SQFile() { Close(); }
-       bool Open(const SQChar *filename ,const SQChar *mode) {
-               Close();
-               if(_handle = sqstd_fopen(filename,mode)) {
-                       _owns = true;
-                       return true;
-               }
-               return false;
-       }
-       void Close() {
-               if(_handle && _owns) { 
-                       sqstd_fclose(_handle);
-                       _handle = NULL;
-                       _owns = false;
-               }
-       }
-       SQInteger Read(void *buffer,SQInteger size) {
-               return sqstd_fread(buffer,1,size,_handle);
-       }
-       SQInteger Write(void *buffer,SQInteger size) {
-               return sqstd_fwrite(buffer,1,size,_handle);
-       }
-       int Flush() {
-               return sqstd_fflush(_handle);
-       }
-       long Tell() {
-               return sqstd_ftell(_handle);
-       }
-       SQInteger Len() {
-               int prevpos=Tell();
-               Seek(0,SQ_SEEK_END);
-               int size=Tell();
-               Seek(prevpos,SQ_SEEK_SET);
-               return size;
-       }
-       SQInteger Seek(long offset, int origin) {
-               return sqstd_fseek(_handle,offset,origin);
-       }
-       bool IsValid() { return _handle?true:false; }
-       bool EOS() { return Tell()==Len()?true:false;}
-       SQFILE GetHandle() {return _handle;}
-private:
-       SQFILE _handle;
-       bool _owns;
-};
-
-static int _file__typeof(HSQUIRRELVM v)
-{
-       sq_pushstring(v,_SC("file"),-1);
-       return 1;
-}
-
-static int _file_releasehook(SQUserPointer p, int size)
-{
-       SQFile *self = (SQFile*)p;
-       delete self;
-       return 1;
-}
-
-static int _file_constructor(HSQUIRRELVM v)
-{
-       const SQChar *filename,*mode;
-       bool owns = true;
-       SQFile *f;
-       SQFILE newf;
-       if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
-               sq_getstring(v, 2, &filename);
-               sq_getstring(v, 3, &mode);
-               newf = sqstd_fopen(filename, mode);
-               if(!newf) return sq_throwerror(v, _SC("cannot open file"));
-       } else if(sq_gettype(v,2) == OT_USERPOINTER) {
-               owns = !(sq_gettype(v,3) == OT_NULL);
-               sq_getuserpointer(v,2,&newf);
-       } else {
-               return sq_throwerror(v,_SC("wrong parameter"));
-       }
-       f = new SQFile(newf,owns);
-       if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
-               delete f;
-               return sq_throwerror(v, _SC("cannot create blob with negative size"));
-       }
-       sq_setreleasehook(v,1,_file_releasehook);
-       return 0;
-}
-
-//bindings
-#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
-static SQRegFunction _file_methods[] = {
-       _DECL_FILE_FUNC(constructor,3,_SC("x")),
-       _DECL_FILE_FUNC(_typeof,1,_SC("x")),
-       {0,0,0,0},
-};
-
-
-
-SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
-{
-       int top = sq_gettop(v);
-       sq_pushregistrytable(v);
-       sq_pushstring(v,_SC("std_file"),-1);
-       if(SQ_SUCCEEDED(sq_get(v,-2))) {
-               sq_remove(v,-2); //removes the registry
-               sq_pushroottable(v); // push the this
-               sq_pushuserpointer(v,file); //file
-               if(own){
-                       sq_pushinteger(v,1); //true
-               }
-               else{
-                       sq_pushnull(v); //false
-               }
-               if(SQ_SUCCEEDED( sq_call(v,3,SQTrue) )) {
-                       sq_remove(v,-2);
-                       return SQ_OK;
-               }
-       }
-       sq_settop(v,top);
-       return SQ_OK;
-}
-
-SQRESULT sqstd_getfile(HSQUIRRELVM v, int idx, SQFILE *file)
-{
-       SQFile *fileobj = NULL;
-       if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,SQSTD_FILE_TYPE_TAG))) {
-               *file = fileobj->GetHandle();
-               return SQ_OK;
-       }
-       return sq_throwerror(v,_SC("not a file"));
-}
-
-
-
-static SQInteger _io_file_lexfeedASCII(SQUserPointer file)
-{
-       int ret;
-       char c;
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
-               return c;
-       return 0;
-}
-
-static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
-{
-#define READ() \
-       if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
-               return 0;
-
-       static const int utf8_lengths[16] =
-       {
-               1,1,1,1,1,1,1,1,        /* 0000 to 0111 : 1 byte (plain ASCII) */
-               0,0,0,0,                /* 1000 to 1011 : not valid */
-               2,2,                    /* 1100, 1101 : 2 bytes */
-               3,                      /* 1110 : 3 bytes */
-               4                       /* 1111 :4 bytes */
-       };
-       static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
-       unsigned char inchar;
-       int c = 0;
-       READ();
-       c = inchar;
-       //
-       if(c >= 0x80) {
-               int tmp;
-               int codelen = utf8_lengths[c>>4];
-               if(codelen == 0) 
-                       return 0;
-                       //"invalid UTF-8 stream";
-               tmp = c&byte_masks[codelen];
-               for(int n = 0; n < codelen-1; n++) {
-                       tmp<<=6;
-                       READ();
-                       tmp |= inchar & 0x3F;
-               }
-               c = tmp;
-       }
-       return c;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
-{
-       int ret;
-       wchar_t c;
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
-               return (SQChar)c;
-       return 0;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
-{
-       int ret;
-       unsigned short c;
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
-               c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
-               return (SQChar)c;
-       }
-       return 0;
-}
-
-int file_read(SQUserPointer file,SQUserPointer buf,int size)
-{
-       int ret;
-       if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
-       return -1;
-}
-
-int file_write(SQUserPointer file,SQUserPointer p,int size)
-{
-       return sqstd_fwrite(p,1,size,(SQFILE)file);
-}
-
-SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
-{
-       SQFILE file = sqstd_fopen(filename,_SC("rb"));
-       int ret;
-       unsigned short us;
-       unsigned char uc;
-       SQLEXREADFUNC func = _io_file_lexfeed_UTF8;
-       if(file && (ret = sqstd_fread(&us,1,2,file))){
-               if(ret != 2) {
-                       sqstd_fclose(file);
-                       return sq_throwerror(v,_SC("io error"));
-               }
-               if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
-                       sqstd_fseek(file,0,SQ_SEEK_SET);
-                       if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
-                               sqstd_fclose(file);
-                               return SQ_OK;
-                       }
-               }
-               else { //SCRIPT
-                       switch(us)
-                       {
-                               //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")); 
-                                       }
-                                       if(uc != 0xBF) { 
-                                               sqstd_fclose(file); 
-                                               return sq_throwerror(v,_SC("Unrecognozed ecoding")); 
-                                       }
-                                       func = _io_file_lexfeed_UTF8;
-                                       break;//UTF-8 ;
-                               default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
-                       }
-
-                       if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
-                               sqstd_fclose(file);
-                               return SQ_OK;
-                       }
-               }
-               sqstd_fclose(file);
-               return SQ_ERROR;
-       }
-       return sq_throwerror(v,_SC("cannot open the file"));
-}
-
-SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
-{
-       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
-               sq_push(v,-2);
-               int ntop = sq_gettop(v);
-               if(SQ_SUCCEEDED(sq_call(v,1,retval))) {
-                       sq_remove(v,retval?-2:-1); //removes the closure
-                       return 1;
-               }
-               sq_pop(v,1); //removes the closure
-       }
-       return SQ_ERROR;
-}
-
-SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
-{
-       SQFILE file = sqstd_fopen(filename,_SC("wb+"));
-       if(!file) return sq_throwerror(v,_SC("cannot open the file"));
-       if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
-               sqstd_fclose(file);
-               return SQ_OK;
-       }
-       sqstd_fclose(file);
-       return SQ_ERROR; //forward the error
-}
-
-int _g_io_loadfile(HSQUIRRELVM v)
-{
-       const SQChar *filename;
-       SQBool printerror = SQFalse;
-       sq_getstring(v,2,&filename);
-       if(sq_gettop(v) >= 3) {
-               sq_getbool(v,3,&printerror);
-       }
-       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
-               return 1;
-       return SQ_ERROR; //propagates the error
-}
-
-int _g_io_dofile(HSQUIRRELVM v)
-{
-       const SQChar *filename;
-       SQBool printerror = SQFalse;
-       sq_getstring(v,2,&filename);
-       if(sq_gettop(v) >= 3) {
-               sq_getbool(v,3,&printerror);
-       }
-       sq_push(v,1); //repush the this
-       if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
-               return 1;
-       return SQ_ERROR; //propagates the error
-}
-
-#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
-static SQRegFunction iolib_funcs[]={
-       _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
-       _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
-       {0,0}
-};
-
-SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
-{
-       int top = sq_gettop(v);
-       //create delegate
-       declare_stream(v,_SC("file"),SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
-       sq_pushstring(v,_SC("stdout"),-1);
-       sqstd_createfile(v,stdout,SQFalse);
-       sq_createslot(v,-3);
-       sq_pushstring(v,_SC("stdin"),-1);
-       sqstd_createfile(v,stdin,SQFalse);
-       sq_createslot(v,-3);
-       sq_pushstring(v,_SC("stderr"),-1);
-       sqstd_createfile(v,stderr,SQFalse);
-       sq_createslot(v,-3);
-       sq_settop(v,top);
-       return SQ_OK;
-}
+/* see copyright notice in squirrel.h */\r
+#include <new>\r
+#include <stdio.h>\r
+#include <squirrel.h>\r
+#include <sqstdio.h>\r
+#include "sqstdstream.h"\r
+\r
+#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)\r
+//basic API\r
+SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)\r
+{\r
+#ifndef _UNICODE\r
+       return (SQFILE)fopen(filename,mode);\r
+#else\r
+       return (SQFILE)_wfopen(filename,mode);\r
+#endif\r
+}\r
+\r
+SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)\r
+{\r
+       return (SQInteger)fread(buffer,size,count,(FILE *)file);\r
+}\r
+\r
+SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)\r
+{\r
+       return (SQInteger)fwrite(buffer,size,count,(FILE *)file);\r
+}\r
+\r
+SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)\r
+{\r
+       SQInteger realorigin;\r
+       switch(origin) {\r
+               case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;\r
+               case SQ_SEEK_END: realorigin = SEEK_END; break;\r
+               case SQ_SEEK_SET: realorigin = SEEK_SET; break;\r
+               default: return -1; //failed\r
+       }\r
+       return fseek((FILE *)file,offset,realorigin);\r
+}\r
+\r
+SQInteger sqstd_ftell(SQFILE file)\r
+{\r
+       return ftell((FILE *)file);\r
+}\r
+\r
+SQInteger sqstd_fflush(SQFILE file)\r
+{\r
+       return fflush((FILE *)file);\r
+}\r
+\r
+SQInteger sqstd_fclose(SQFILE file)\r
+{\r
+       return fclose((FILE *)file);\r
+}\r
+\r
+SQInteger sqstd_feof(SQFILE file)\r
+{\r
+       return feof((FILE *)file);\r
+}\r
+\r
+//File\r
+struct SQFile : public SQStream {\r
+       SQFile() { _handle = NULL; _owns = false;}\r
+       SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}\r
+       ~SQFile() { Close(); }\r
+       bool Open(const SQChar *filename ,const SQChar *mode) {\r
+               Close();\r
+               if(_handle = sqstd_fopen(filename,mode)) {\r
+                       _owns = true;\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       void Close() {\r
+               if(_handle && _owns) { \r
+                       sqstd_fclose(_handle);\r
+                       _handle = NULL;\r
+                       _owns = false;\r
+               }\r
+       }\r
+       SQInteger Read(void *buffer,SQInteger size) {\r
+               return sqstd_fread(buffer,1,size,_handle);\r
+       }\r
+       SQInteger Write(void *buffer,SQInteger size) {\r
+               return sqstd_fwrite(buffer,1,size,_handle);\r
+       }\r
+       SQInteger Flush() {\r
+               return sqstd_fflush(_handle);\r
+       }\r
+       SQInteger Tell() {\r
+               return sqstd_ftell(_handle);\r
+       }\r
+       SQInteger Len() {\r
+               SQInteger prevpos=Tell();\r
+               Seek(0,SQ_SEEK_END);\r
+               SQInteger size=Tell();\r
+               Seek(prevpos,SQ_SEEK_SET);\r
+               return size;\r
+       }\r
+       SQInteger Seek(SQInteger offset, SQInteger origin)      {\r
+               return sqstd_fseek(_handle,offset,origin);\r
+       }\r
+       bool IsValid() { return _handle?true:false; }\r
+       bool EOS() { return Tell()==Len()?true:false;}\r
+       SQFILE GetHandle() {return _handle;}\r
+private:\r
+       SQFILE _handle;\r
+       bool _owns;\r
+};\r
+\r
+static SQInteger _file__typeof(HSQUIRRELVM v)\r
+{\r
+       sq_pushstring(v,_SC("file"),-1);\r
+       return 1;\r
+}\r
+\r
+static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)\r
+{\r
+       SQFile *self = (SQFile*)p;\r
+       delete self;\r
+       return 1;\r
+}\r
+\r
+static SQInteger _file_constructor(HSQUIRRELVM v)\r
+{\r
+       const SQChar *filename,*mode;\r
+       bool owns = true;\r
+       SQFile *f;\r
+       SQFILE newf;\r
+       if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {\r
+               sq_getstring(v, 2, &filename);\r
+               sq_getstring(v, 3, &mode);\r
+               newf = sqstd_fopen(filename, mode);\r
+               if(!newf) return sq_throwerror(v, _SC("cannot open file"));\r
+       } else if(sq_gettype(v,2) == OT_USERPOINTER) {\r
+               owns = !(sq_gettype(v,3) == OT_NULL);\r
+               sq_getuserpointer(v,2,&newf);\r
+       } else {\r
+               return sq_throwerror(v,_SC("wrong parameter"));\r
+       }\r
+       f = new SQFile(newf,owns);\r
+       if(SQ_FAILED(sq_setinstanceup(v,1,f))) {\r
+               delete f;\r
+               return sq_throwerror(v, _SC("cannot create blob with negative size"));\r
+       }\r
+       sq_setreleasehook(v,1,_file_releasehook);\r
+       return 0;\r
+}\r
+\r
+//bindings\r
+#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}\r
+static SQRegFunction _file_methods[] = {\r
+       _DECL_FILE_FUNC(constructor,3,_SC("x")),\r
+       _DECL_FILE_FUNC(_typeof,1,_SC("x")),\r
+       {0,0,0,0},\r
+};\r
+\r
+\r
+\r
+SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)\r
+{\r
+       SQInteger top = sq_gettop(v);\r
+       sq_pushregistrytable(v);\r
+       sq_pushstring(v,_SC("std_file"),-1);\r
+       if(SQ_SUCCEEDED(sq_get(v,-2))) {\r
+               sq_remove(v,-2); //removes the registry\r
+               sq_pushroottable(v); // push the this\r
+               sq_pushuserpointer(v,file); //file\r
+               if(own){\r
+                       sq_pushinteger(v,1); //true\r
+               }\r
+               else{\r
+                       sq_pushnull(v); //false\r
+               }\r
+               if(SQ_SUCCEEDED( sq_call(v,3,SQTrue) )) {\r
+                       sq_remove(v,-2);\r
+                       return SQ_OK;\r
+               }\r
+       }\r
+       sq_settop(v,top);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)\r
+{\r
+       SQFile *fileobj = NULL;\r
+       if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {\r
+               *file = fileobj->GetHandle();\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("not a file"));\r
+}\r
+\r
+\r
+\r
+static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)\r
+{\r
+       SQInteger ret;\r
+       char c;\r
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )\r
+               return c;\r
+       return 0;\r
+}\r
+\r
+static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)\r
+{\r
+#define READ() \\r
+       if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \\r
+               return 0;\r
+\r
+       static const SQInteger utf8_lengths[16] =\r
+       {\r
+               1,1,1,1,1,1,1,1,        /* 0000 to 0111 : 1 byte (plain ASCII) */\r
+               0,0,0,0,                /* 1000 to 1011 : not valid */\r
+               2,2,                    /* 1100, 1101 : 2 bytes */\r
+               3,                      /* 1110 : 3 bytes */\r
+               4                       /* 1111 :4 bytes */\r
+       };\r
+       static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};\r
+       unsigned char inchar;\r
+       SQInteger c = 0;\r
+       READ();\r
+       c = inchar;\r
+       //\r
+       if(c >= 0x80) {\r
+               SQInteger tmp;\r
+               SQInteger codelen = utf8_lengths[c>>4];\r
+               if(codelen == 0) \r
+                       return 0;\r
+                       //"invalid UTF-8 stream";\r
+               tmp = c&byte_masks[codelen];\r
+               for(SQInteger n = 0; n < codelen-1; n++) {\r
+                       tmp<<=6;\r
+                       READ();\r
+                       tmp |= inchar & 0x3F;\r
+               }\r
+               c = tmp;\r
+       }\r
+       return c;\r
+}\r
+\r
+static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)\r
+{\r
+       SQInteger ret;\r
+       wchar_t c;\r
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )\r
+               return (SQChar)c;\r
+       return 0;\r
+}\r
+\r
+static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)\r
+{\r
+       SQInteger ret;\r
+       unsigned short c;\r
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {\r
+               c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);\r
+               return (SQChar)c;\r
+       }\r
+       return 0;\r
+}\r
+\r
+SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)\r
+{\r
+       SQInteger ret;\r
+       if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;\r
+       return -1;\r
+}\r
+\r
+SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)\r
+{\r
+       return sqstd_fwrite(p,1,size,(SQFILE)file);\r
+}\r
+\r
+SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)\r
+{\r
+       SQFILE file = sqstd_fopen(filename,_SC("rb"));\r
+       SQInteger ret;\r
+       unsigned short us;\r
+       unsigned char uc;\r
+       SQLEXREADFUNC func = _io_file_lexfeed_ASCII;\r
+       if(file){\r
+               ret = sqstd_fread(&us,1,2,file);\r
+               if(ret != 2) {\r
+                       //probably an empty file\r
+                       us = 0;\r
+               }\r
+               if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE\r
+                       sqstd_fseek(file,0,SQ_SEEK_SET);\r
+                       if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {\r
+                               sqstd_fclose(file);\r
+                               return SQ_OK;\r
+                       }\r
+               }\r
+               else { //SCRIPT\r
+                       switch(us)\r
+                       {\r
+                               //gotta swap the next 2 lines on BIG endian machines\r
+                               case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;\r
+                               case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;\r
+                               case 0xBBEF: \r
+                                       if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { \r
+                                               sqstd_fclose(file); \r
+                                               return sq_throwerror(v,_SC("io error")); \r
+                                       }\r
+                                       if(uc != 0xBF) { \r
+                                               sqstd_fclose(file); \r
+                                               return sq_throwerror(v,_SC("Unrecognozed ecoding")); \r
+                                       }\r
+                                       func = _io_file_lexfeed_UTF8;\r
+                                       break;//UTF-8 ;\r
+                               default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii\r
+                       }\r
+\r
+                       if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){\r
+                               sqstd_fclose(file);\r
+                               return SQ_OK;\r
+                       }\r
+               }\r
+               sqstd_fclose(file);\r
+               return SQ_ERROR;\r
+       }\r
+       return sq_throwerror(v,_SC("cannot open the file"));\r
+}\r
+\r
+SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)\r
+{\r
+       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {\r
+               sq_push(v,-2);\r
+               SQInteger ntop = sq_gettop(v);\r
+               if(SQ_SUCCEEDED(sq_call(v,1,retval))) {\r
+                       sq_remove(v,retval?-2:-1); //removes the closure\r
+                       return 1;\r
+               }\r
+               sq_pop(v,1); //removes the closure\r
+       }\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)\r
+{\r
+       SQFILE file = sqstd_fopen(filename,_SC("wb+"));\r
+       if(!file) return sq_throwerror(v,_SC("cannot open the file"));\r
+       if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {\r
+               sqstd_fclose(file);\r
+               return SQ_OK;\r
+       }\r
+       sqstd_fclose(file);\r
+       return SQ_ERROR; //forward the error\r
+}\r
+\r
+SQInteger _g_io_loadfile(HSQUIRRELVM v)\r
+{\r
+       const SQChar *filename;\r
+       SQBool printerror = SQFalse;\r
+       sq_getstring(v,2,&filename);\r
+       if(sq_gettop(v) >= 3) {\r
+               sq_getbool(v,3,&printerror);\r
+       }\r
+       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))\r
+               return 1;\r
+       return SQ_ERROR; //propagates the error\r
+}\r
+\r
+SQInteger _g_io_dofile(HSQUIRRELVM v)\r
+{\r
+       const SQChar *filename;\r
+       SQBool printerror = SQFalse;\r
+       sq_getstring(v,2,&filename);\r
+       if(sq_gettop(v) >= 3) {\r
+               sq_getbool(v,3,&printerror);\r
+       }\r
+       sq_push(v,1); //repush the this\r
+       if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))\r
+               return 1;\r
+       return SQ_ERROR; //propagates the error\r
+}\r
+\r
+#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}\r
+static SQRegFunction iolib_funcs[]={\r
+       _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),\r
+       _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),\r
+       {0,0}\r
+};\r
+\r
+SQRESULT sqstd_register_iolib(HSQUIRRELVM v)\r
+{\r
+       SQInteger top = sq_gettop(v);\r
+       //create delegate\r
+       declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);\r
+       sq_pushstring(v,_SC("stdout"),-1);\r
+       sqstd_createfile(v,stdout,SQFalse);\r
+       sq_createslot(v,-3);\r
+       sq_pushstring(v,_SC("stdin"),-1);\r
+       sqstd_createfile(v,stdin,SQFalse);\r
+       sq_createslot(v,-3);\r
+       sq_pushstring(v,_SC("stderr"),-1);\r
+       sqstd_createfile(v,stderr,SQFalse);\r
+       sq_createslot(v,-3);\r
+       sq_settop(v,top);\r
+       return SQ_OK;\r
+}\r
index f6d4d71..3d90ee9 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <math.h>
-#include <stdlib.h>
-#include <sqstdmath.h>
-
-#define SINGLE_ARG_FUNC(_funcname) static int math_##_funcname(HSQUIRRELVM v){ \
-       SQFloat f; \
-       sq_getfloat(v,2,&f); \
-       sq_pushfloat(v,(SQFloat)_funcname(f)); \
-       return 1; \
-}
-
-#define TWO_ARGS_FUNC(_funcname) static int math_##_funcname(HSQUIRRELVM v){ \
-       SQFloat p1,p2; \
-       sq_getfloat(v,2,&p1); \
-       sq_getfloat(v,3,&p2); \
-       sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
-       return 1; \
-}
-
-static int math_srand(HSQUIRRELVM v)
-{
-       SQInteger i;
-       if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param"));
-       srand(i);
-       return 0;
-}
-
-static int math_rand(HSQUIRRELVM v)
-{
-       sq_pushinteger(v,rand());
-       return 1;
-}
-
-static int math_abs(HSQUIRRELVM v)
-{
-       SQInteger n;
-       sq_getinteger(v,2,&n);
-       sq_pushinteger(v,(SQInteger)abs(n)); 
-       return 1; 
-}
-
-SINGLE_ARG_FUNC(sqrt)
-SINGLE_ARG_FUNC(fabs)
-SINGLE_ARG_FUNC(sin)
-SINGLE_ARG_FUNC(cos)
-SINGLE_ARG_FUNC(asin)
-SINGLE_ARG_FUNC(acos)
-SINGLE_ARG_FUNC(log)
-SINGLE_ARG_FUNC(log10)
-SINGLE_ARG_FUNC(tan)
-SINGLE_ARG_FUNC(atan)
-TWO_ARGS_FUNC(atan2)
-TWO_ARGS_FUNC(pow)
-SINGLE_ARG_FUNC(floor)
-SINGLE_ARG_FUNC(ceil)
-SINGLE_ARG_FUNC(exp)
-
-#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
-static SQRegFunction mathlib_funcs[] = {
-       _DECL_FUNC(sqrt,2,_SC(".n")),
-       _DECL_FUNC(sin,2,_SC(".n")),
-       _DECL_FUNC(cos,2,_SC(".n")),
-       _DECL_FUNC(asin,2,_SC(".n")),
-       _DECL_FUNC(acos,2,_SC(".n")),
-       _DECL_FUNC(log,2,_SC(".n")),
-       _DECL_FUNC(log10,2,_SC(".n")),
-       _DECL_FUNC(tan,2,_SC(".n")),
-       _DECL_FUNC(atan,2,_SC(".n")),
-       _DECL_FUNC(atan2,3,_SC(".nn")),
-       _DECL_FUNC(pow,3,_SC(".nn")),
-       _DECL_FUNC(floor,2,_SC(".n")),
-       _DECL_FUNC(ceil,2,_SC(".n")),
-       _DECL_FUNC(exp,2,_SC(".n")),
-       _DECL_FUNC(srand,2,_SC(".n")),
-       _DECL_FUNC(rand,1,NULL),
-       _DECL_FUNC(fabs,2,_SC(".n")),
-       _DECL_FUNC(abs,2,_SC(".n")),
-       {0,0},
-};
-
-#ifndef M_PI
-#define M_PI (3.14159265358979323846)
-#endif
-
-SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
-{
-       int i=0;
-       while(mathlib_funcs[i].name!=0) {
-               sq_pushstring(v,mathlib_funcs[i].name,-1);
-               sq_newclosure(v,mathlib_funcs[i].f,0);
-               sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
-               sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
-               sq_createslot(v,-3);
-               i++;
-       }
-       sq_pushstring(v,_SC("RAND_MAX"),-1);
-       sq_pushinteger(v,RAND_MAX);
-       sq_createslot(v,-3);
-       sq_pushstring(v,_SC("PI"),-1);
-       sq_pushfloat(v,(SQFloat)M_PI);
-       sq_createslot(v,-3);
-       return SQ_OK;
-}
+/* see copyright notice in squirrel.h */\r
+#include <squirrel.h>\r
+#include <math.h>\r
+#include <stdlib.h>\r
+#include <sqstdmath.h>\r
+\r
+#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \\r
+       SQFloat f; \\r
+       sq_getfloat(v,2,&f); \\r
+       sq_pushfloat(v,(SQFloat)_funcname(f)); \\r
+       return 1; \\r
+}\r
+\r
+#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \\r
+       SQFloat p1,p2; \\r
+       sq_getfloat(v,2,&p1); \\r
+       sq_getfloat(v,3,&p2); \\r
+       sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \\r
+       return 1; \\r
+}\r
+\r
+static SQInteger math_srand(HSQUIRRELVM v)\r
+{\r
+       SQInteger i;\r
+       if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param"));\r
+       srand(i);\r
+       return 0;\r
+}\r
+\r
+static SQInteger math_rand(HSQUIRRELVM v)\r
+{\r
+       sq_pushinteger(v,rand());\r
+       return 1;\r
+}\r
+\r
+static SQInteger math_abs(HSQUIRRELVM v)\r
+{\r
+       SQInteger n;\r
+       sq_getinteger(v,2,&n);\r
+       sq_pushinteger(v,(SQInteger)abs(n)); \r
+       return 1; \r
+}\r
+\r
+SINGLE_ARG_FUNC(sqrt)\r
+SINGLE_ARG_FUNC(fabs)\r
+SINGLE_ARG_FUNC(sin)\r
+SINGLE_ARG_FUNC(cos)\r
+SINGLE_ARG_FUNC(asin)\r
+SINGLE_ARG_FUNC(acos)\r
+SINGLE_ARG_FUNC(log)\r
+SINGLE_ARG_FUNC(log10)\r
+SINGLE_ARG_FUNC(tan)\r
+SINGLE_ARG_FUNC(atan)\r
+TWO_ARGS_FUNC(atan2)\r
+TWO_ARGS_FUNC(pow)\r
+SINGLE_ARG_FUNC(floor)\r
+SINGLE_ARG_FUNC(ceil)\r
+SINGLE_ARG_FUNC(exp)\r
+\r
+#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}\r
+static SQRegFunction mathlib_funcs[] = {\r
+       _DECL_FUNC(sqrt,2,_SC(".n")),\r
+       _DECL_FUNC(sin,2,_SC(".n")),\r
+       _DECL_FUNC(cos,2,_SC(".n")),\r
+       _DECL_FUNC(asin,2,_SC(".n")),\r
+       _DECL_FUNC(acos,2,_SC(".n")),\r
+       _DECL_FUNC(log,2,_SC(".n")),\r
+       _DECL_FUNC(log10,2,_SC(".n")),\r
+       _DECL_FUNC(tan,2,_SC(".n")),\r
+       _DECL_FUNC(atan,2,_SC(".n")),\r
+       _DECL_FUNC(atan2,3,_SC(".nn")),\r
+       _DECL_FUNC(pow,3,_SC(".nn")),\r
+       _DECL_FUNC(floor,2,_SC(".n")),\r
+       _DECL_FUNC(ceil,2,_SC(".n")),\r
+       _DECL_FUNC(exp,2,_SC(".n")),\r
+       _DECL_FUNC(srand,2,_SC(".n")),\r
+       _DECL_FUNC(rand,1,NULL),\r
+       _DECL_FUNC(fabs,2,_SC(".n")),\r
+       _DECL_FUNC(abs,2,_SC(".n")),\r
+       {0,0},\r
+};\r
+\r
+#ifndef M_PI\r
+#define M_PI (3.14159265358979323846)\r
+#endif\r
+\r
+SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)\r
+{\r
+       SQInteger i=0;\r
+       while(mathlib_funcs[i].name!=0) {\r
+               sq_pushstring(v,mathlib_funcs[i].name,-1);\r
+               sq_newclosure(v,mathlib_funcs[i].f,0);\r
+               sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);\r
+               sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);\r
+               sq_createslot(v,-3);\r
+               i++;\r
+       }\r
+       sq_pushstring(v,_SC("RAND_MAX"),-1);\r
+       sq_pushinteger(v,RAND_MAX);\r
+       sq_createslot(v,-3);\r
+       sq_pushstring(v,_SC("PI"),-1);\r
+       sq_pushfloat(v,(SQFloat)M_PI);\r
+       sq_createslot(v,-3);\r
+       return SQ_OK;\r
+}\r
index 534f17d..e37a58c 100644 (file)
@@ -46,30 +46,30 @@ typedef int SQRexNodeType;
 \r
 typedef struct tagSQRexNode{\r
        SQRexNodeType type;\r
-       long left;\r
-       long right;\r
-       int next;\r
+       SQInteger left;\r
+       SQInteger right;\r
+       SQInteger next;\r
 }SQRexNode;\r
 \r
 struct SQRex{\r
        const SQChar *_eol;\r
        const SQChar *_bol;\r
        const SQChar *_p;\r
-       int _first;\r
-       int _op;\r
+       SQInteger _first;\r
+       SQInteger _op;\r
        SQRexNode *_nodes;\r
-       int _nallocated;\r
-       int _nsize;\r
-       int _nsubexpr;\r
+       SQInteger _nallocated;\r
+       SQInteger _nsize;\r
+       SQInteger _nsubexpr;\r
        SQRexMatch *_matches;\r
-       int _currsubexp;\r
+       SQInteger _currsubexp;\r
        void *_jmpbuf;\r
        const SQChar **_error;\r
 };\r
 \r
-static int sqstd_rex_list(SQRex *exp);\r
+static SQInteger sqstd_rex_list(SQRex *exp);\r
 \r
-static int sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)\r
+static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)\r
 {\r
        SQRexNode n;\r
        n.type = type;\r
@@ -77,12 +77,12 @@ static int sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
        if(type == OP_EXPR)\r
                n.right = exp->_nsubexpr++;\r
        if(exp->_nallocated < (exp->_nsize + 1)) {\r
-               int oldsize = exp->_nallocated;\r
+               SQInteger oldsize = exp->_nallocated;\r
                exp->_nallocated *= 2;\r
                exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));\r
        }\r
        exp->_nodes[exp->_nsize++] = n;\r
-       return (int)exp->_nsize - 1;\r
+       return (SQInteger)exp->_nsize - 1;\r
 }\r
 \r
 static void sqstd_rex_error(SQRex *exp,const SQChar *error)\r
@@ -91,7 +91,7 @@ static void sqstd_rex_error(SQRex *exp,const SQChar *error)
        longjmp(*((jmp_buf*)exp->_jmpbuf),-1);\r
 }\r
 \r
-static void sqstd_rex_expect(SQRex *exp, int n){\r
+static void sqstd_rex_expect(SQRex *exp, SQInteger n){\r
        if((*exp->_p) != n) \r
                sqstd_rex_error(exp, _SC("expected paren"));\r
        exp->_p++;\r
@@ -125,14 +125,14 @@ static SQChar sqstd_rex_escapechar(SQRex *exp)
        return (*exp->_p++);\r
 }\r
 \r
-static int sqstd_rex_charclass(SQRex *exp,int classid)\r
+static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)\r
 {\r
-       int n = sqstd_rex_newnode(exp,OP_CCLASS);\r
+       SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);\r
        exp->_nodes[n].left = classid;\r
        return n;\r
 }\r
 \r
-static int sqstd_rex_charnode(SQRex *exp,SQBool isclass)\r
+static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass)\r
 {\r
        if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {\r
                exp->_p++;\r
@@ -153,7 +153,7 @@ static int sqstd_rex_charnode(SQRex *exp,SQBool isclass)
                        case 'b': \r
                        case 'B':\r
                                if(!isclass) {\r
-                                       int node = sqstd_rex_newnode(exp,OP_WB);\r
+                                       SQInteger node = sqstd_rex_newnode(exp,OP_WB);\r
                                        exp->_nodes[node].left = *exp->_p;\r
                                        exp->_p++; \r
                                        return node;\r
@@ -167,10 +167,10 @@ static int sqstd_rex_charnode(SQRex *exp,SQBool isclass)
        }\r
        return sqstd_rex_newnode(exp,*exp->_p++);\r
 }\r
-static int sqstd_rex_class(SQRex *exp)\r
+static SQInteger sqstd_rex_class(SQRex *exp)\r
 {\r
-       int ret = -1;\r
-       int first = -1,chain;\r
+       SQInteger ret = -1;\r
+       SQInteger first = -1,chain;\r
        if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){\r
                ret = sqstd_rex_newnode(exp,OP_NCLASS);\r
                exp->_p++;\r
@@ -183,7 +183,7 @@ static int sqstd_rex_class(SQRex *exp)
        chain = ret;\r
        while(*exp->_p != ']' && exp->_p != exp->_eol) {\r
                if(*exp->_p == '-' && first != -1){ \r
-                       int r;\r
+                       SQInteger r;\r
                        if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));\r
                        r = sqstd_rex_newnode(exp,OP_RANGE);\r
                        if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));\r
@@ -196,7 +196,7 @@ static int sqstd_rex_class(SQRex *exp)
                }\r
                else{\r
                        if(first!=-1){\r
-                               int c = first;\r
+                               SQInteger c = first;\r
                                exp->_nodes[chain].next = c;\r
                                chain = c;\r
                                first = sqstd_rex_charnode(exp,SQTrue);\r
@@ -207,7 +207,7 @@ static int sqstd_rex_class(SQRex *exp)
                }\r
        }\r
        if(first!=-1){\r
-               int c = first;\r
+               SQInteger c = first;\r
                exp->_nodes[chain].next = c;\r
                chain = c;\r
                first = -1;\r
@@ -218,10 +218,10 @@ static int sqstd_rex_class(SQRex *exp)
        return ret;\r
 }\r
 \r
-static int sqstd_rex_parsenumber(SQRex *exp)\r
+static SQInteger sqstd_rex_parsenumber(SQRex *exp)\r
 {\r
-       int ret = *exp->_p-'0';\r
-       int positions = 10;\r
+       SQInteger ret = *exp->_p-'0';\r
+       SQInteger positions = 10;\r
        exp->_p++;\r
        while(isdigit(*exp->_p)) {\r
                ret = ret*10+(*exp->_p++-'0');\r
@@ -231,13 +231,13 @@ static int sqstd_rex_parsenumber(SQRex *exp)
        return ret;\r
 }\r
 \r
-static int sqstd_rex_element(SQRex *exp)\r
+static SQInteger sqstd_rex_element(SQRex *exp)\r
 {\r
-       int ret;\r
+       SQInteger ret;\r
        switch(*exp->_p)\r
        {\r
        case '(': {\r
-               int expr;\r
+               SQInteger expr;\r
                exp->_p++;\r
                \r
                \r
@@ -266,7 +266,7 @@ static int sqstd_rex_element(SQRex *exp)
        }\r
        /* scope block */\r
        {\r
-               int op;\r
+               SQInteger op;\r
                unsigned short p0 = 0, p1 = 0;\r
                switch(*exp->_p){\r
                case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; goto __end;\r
@@ -293,7 +293,7 @@ static int sqstd_rex_element(SQRex *exp)
                        }\r
                }\r
                __end: {\r
-                               int nnode = sqstd_rex_newnode(exp,OP_GREEDY);\r
+                               SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY);\r
                                op = OP_GREEDY;\r
                                exp->_nodes[nnode].left = ret;\r
                                exp->_nodes[nnode].right = ((p0)<<16)|p1;\r
@@ -306,9 +306,9 @@ static int sqstd_rex_element(SQRex *exp)
        return ret;\r
 }\r
 \r
-static int sqstd_rex_list(SQRex *exp)\r
+static SQInteger sqstd_rex_list(SQRex *exp)\r
 {\r
-       int ret=-1,e;\r
+       SQInteger ret=-1,e;\r
        if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {\r
                exp->_p++;\r
                ret = sqstd_rex_newnode(exp,OP_BOL);\r
@@ -320,7 +320,7 @@ static int sqstd_rex_list(SQRex *exp)
        else ret = e;\r
 \r
        if(*exp->_p == SQREX_SYMBOL_BRANCH) {\r
-               int temp;\r
+               SQInteger temp;\r
                exp->_p++;\r
                temp = sqstd_rex_newnode(exp,OP_OR);\r
                exp->_nodes[temp].left = ret;\r
@@ -330,7 +330,7 @@ static int sqstd_rex_list(SQRex *exp)
        return ret;\r
 }\r
 \r
-static SQBool sqstd_rex_matchcclass(int cclass,SQChar c)\r
+static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c)\r
 {\r
        switch(cclass) {\r
        case 'a': return isalpha(c)?SQTrue:SQFalse;\r
@@ -375,7 +375,7 @@ static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar
        SQRexNodeType type = node->type;\r
        switch(type) {\r
        case OP_GREEDY: {\r
-               int p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;\r
+               SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;\r
                const SQChar *s=str, *good = str;\r
                while((nmaches == 0xFFFF || nmaches < p1) \r
                        && (s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s))) {\r
@@ -413,7 +413,7 @@ static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar
        case OP_NOCAPEXPR:{\r
                        SQRexNode *n = &exp->_nodes[node->left];\r
                        const SQChar *cur = str;\r
-                       int capture = -1;\r
+                       SQInteger capture = -1;\r
                        if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {\r
                                capture = exp->_currsubexp;\r
                                exp->_matches[capture].begin = cur;\r
@@ -477,7 +477,7 @@ SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
 {\r
        SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));\r
        exp->_p = pattern;\r
-       exp->_nallocated = (int)scstrlen(pattern) * sizeof(SQChar);\r
+       exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar);\r
        exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));\r
        exp->_nsize = 0;\r
        exp->_matches = 0;\r
@@ -491,7 +491,7 @@ SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
                        sqstd_rex_error(exp,_SC("unexpected character"));\r
 #ifdef _DEBUG\r
                {\r
-                       int nsize,i;\r
+                       SQInteger nsize,i;\r
                        SQRexNode *t;\r
                        nsize = exp->_nsize;\r
                        t = &exp->_nodes[0];\r
@@ -541,7 +541,7 @@ SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
 SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)\r
 {\r
        const SQChar *cur = NULL;\r
-       int node = exp->_first;\r
+       SQInteger node = exp->_first;\r
        if(text_begin >= text_end) return SQFalse;\r
        exp->_bol = text_begin;\r
        exp->_eol = text_end;\r
@@ -572,12 +572,12 @@ SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin,
        return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);\r
 }\r
 \r
-int sqstd_rex_getsubexpcount(SQRex* exp)\r
+SQInteger sqstd_rex_getsubexpcount(SQRex* exp)\r
 {\r
        return exp->_nsubexpr;\r
 }\r
 \r
-SQBool sqstd_rex_getsubexp(SQRex* exp, int n, SQRexMatch *subexp)\r
+SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)\r
 {\r
        if( n<0 || n >= exp->_nsubexpr) return SQFalse;\r
        *subexp = exp->_matches[n];\r
index fea88f8..a02c022 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SETUP_STREAM(v) \
-       SQStream *self = NULL; \
-       if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,SQSTD_STREAM_TYPE_TAG))) \
-               return sq_throwerror(v,_SC("invalid type tag")); \
-       if(!self->IsValid())  \
-               return sq_throwerror(v,_SC("the stream is invalid"));
-
-int _stream_readstr(HSQUIRRELVM v)
-{
-    SETUP_STREAM(v);
-       SQInteger type = _SC('a'), size = 0;
-       sq_getinteger(v, 2, &size);
-       if(size <= 0) return sq_throwerror(v,_SC("invalid size"));
-       if(sq_gettop(v) > 2)
-               sq_getinteger(v, 3, &type);
-       SQChar *dest = NULL;
-       switch(type) {
-       case _SC('a'): {
-               char *temp;
-               if(self->Read(sq_getscratchpad(v, size+1), size) != size)
-                       return sq_throwerror(v, _SC("io failure"));
-#ifdef _UNICODE
-               temp = (char*) sq_getscratchpad(v, size + (size * sizeof(SQChar)));
-               dest = (SQChar*) &temp[size];
-               size = (SQInteger)mbstowcs(dest, (const char*)temp, size);
-#else
-               temp = (char *) sq_getscratchpad(v, -1);
-               dest = temp;
-#endif
-                                  }
-               break;
-       case _SC('u'): {
-               wchar_t *temp;
-               if(self->Read(sq_getscratchpad(v, (size + 1) * sizeof(wchar_t)),size * sizeof(wchar_t)) != (size * sizeof(wchar_t)))
-                       return sq_throwerror(v, _SC("io failure"));
-               
-#ifdef _UNICODE
-               temp = (wchar_t*) sq_getscratchpad(v, -1);
-               dest = (SQChar*) temp;
-#else
-               temp = (wchar_t*) sq_getscratchpad(v,(size * 3) + (size * sizeof(wchar_t)));
-               dest = (char*) &temp[size];
-               size = (SQInteger)wcstombs(dest, (const wchar_t*)temp, size);
-#endif
-                                  }
-               break;
-       default:
-               return sq_throwerror(v, _SC("invalid coding"));
-       }
-
-       sq_pushstring(v, dest, size);
-       return 1;
-}
-
-int _stream_readblob(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       SQUserPointer data,blobp;
-       SQInteger size,res;
-       sq_getinteger(v,2,&size);
-       if(size > self->Len()) {
-               size = self->Len();
-       }
-       data = sq_getscratchpad(v,size);
-       res = self->Read(data,size);
-       if(res <= 0)
-               return sq_throwerror(v,_SC("no data left to read"));
-       blobp = sqstd_createblob(v,res);
-       memcpy(blobp,data,res);
-       return 1;
-}
-
-#define SAFE_READN(ptr,len) { \
-       if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
-       }
-int _stream_readn(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       SQInteger format;
-       sq_getinteger(v, 2, &format);
-       switch(format) {
-       case 'i': {
-               int i;
-               SAFE_READN(&i, sizeof(i));
-               sq_pushinteger(v, i);
-                         }
-               break;
-       case 's': {
-               short s;
-               SAFE_READN(&s, sizeof(short));
-               sq_pushinteger(v, s);
-                         }
-               break;
-       case 'w': {
-               unsigned short w;
-               SAFE_READN(&w, sizeof(unsigned short));
-               sq_pushinteger(v, w);
-                         }
-               break;
-       case 'c': {
-               char c;
-               SAFE_READN(&c, sizeof(char));
-               sq_pushinteger(v, c);
-                         }
-               break;
-       case 'b': {
-               unsigned char c;
-               SAFE_READN(&c, sizeof(unsigned char));
-               sq_pushinteger(v, c);
-                         }
-               break;
-       case 'f': {
-               float f;
-               SAFE_READN(&f, sizeof(float));
-               sq_pushfloat(v, f);
-                         }
-               break;
-       case 'd': {
-               double d;
-               SAFE_READN(&d, sizeof(double));
-               sq_pushfloat(v, (SQFloat)d);
-                         }
-               break;
-       default:
-               return sq_throwerror(v, _SC("invalid format"));
-       }
-       return 1;
-}
-
-int _stream_writestr(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       const SQChar *str,*res;
-       SQInteger trgformat = 'a',len = 0;
-       sq_getstring(v,2,&str);
-       len = sq_getsize(v,2);
-       if(sq_gettop(v)>2)
-               sq_getinteger(v,3,&trgformat);
-       switch(trgformat)
-       {
-       case 'a':
-#ifdef _UNICODE
-               res = sq_getscratchpad(v,len*3);
-               len = (SQInteger) wcstombs((char *)res, (const wchar_t*)str, len);
-#else
-               res = str;
-#endif
-               self->Write((void *)res,len);
-               break;
-       case 'u':
-#ifdef _UNICODE
-               res = str;
-#else
-               res = sq_getscratchpad(v,len*sizeof(wchar_t));
-               len = (SQInteger) mbstowcs((wchar_t*)res, str, len);
-#endif
-               self->Write((void *)res,len*sizeof(wchar_t));
-               break;
-       default:
-               return sq_throwerror(v,_SC("wrong encoding"));
-       }
-       
-       return 0;
-}
-
-int _stream_writeblob(HSQUIRRELVM v)
-{
-       SQUserPointer data;
-       int size;
-       SETUP_STREAM(v);
-       if(SQ_FAILED(sqstd_getblob(v,2,&data)))
-               return sq_throwerror(v,_SC("invalid parameter"));
-       size = sqstd_getblobsize(v,2);
-       if(self->Write(data,size) != size)
-               return sq_throwerror(v,_SC("io error"));
-       sq_pushinteger(v,size);
-       return 1;
-}
-
-int _stream_writen(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       SQInteger format, ti;
-       SQFloat tf;
-       sq_getinteger(v, 3, &format);
-       switch(format) {
-       case 'i': {
-               int i;
-               sq_getinteger(v, 2, &ti);
-               i = ti;
-               self->Write(&i, sizeof(int));
-                         }
-               break;
-       case 's': {
-               short s;
-               sq_getinteger(v, 2, &ti);
-               s = ti;
-               self->Write(&s, sizeof(short));
-                         }
-               break;
-       case 'w': {
-               unsigned short w;
-               sq_getinteger(v, 2, &ti);
-               w = ti;
-               self->Write(&w, sizeof(unsigned short));
-                         }
-               break;
-       case 'c': {
-               char c;
-               sq_getinteger(v, 2, &ti);
-               c = ti;
-               self->Write(&c, sizeof(char));
-                                 }
-               break;
-       case 'b': {
-               unsigned char b;
-               sq_getinteger(v, 2, &ti);
-               b = ti;
-               self->Write(&b, sizeof(unsigned char));
-                         }
-               break;
-       case 'f': {
-               float f;
-               sq_getfloat(v, 2, &tf);
-               f = tf;
-               self->Write(&f, sizeof(float));
-                         }
-               break;
-       case 'd': {
-               double d;
-               sq_getfloat(v, 2, &tf);
-               d = tf;
-               self->Write(&d, sizeof(double));
-                         }
-               break;
-       default:
-               return sq_throwerror(v, _SC("invalid format"));
-       }
-       return 0;
-}
-
-int _stream_seek(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       SQInteger offset, origin = SQ_SEEK_SET;
-       sq_getinteger(v, 2, &offset);
-       if(sq_gettop(v) > 2) {
-               SQInteger t;
-               sq_getinteger(v, 3, &t);
-               switch(t) {
-                       case 'b': origin = SQ_SEEK_SET; break;
-                       case 'c': origin = SQ_SEEK_CUR; break;
-                       case 'e': origin = SQ_SEEK_END; break;
-                       default: return sq_throwerror(v,_SC("invalid origin"));
-               }
-       }
-       sq_pushinteger(v, self->Seek(offset, origin));
-       return 1;
-}
-
-int _stream_tell(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       sq_pushinteger(v, self->Tell());
-       return 1;
-}
-
-int _stream_len(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       sq_pushinteger(v, self->Len());
-       return 1;
-}
-
-int _stream_flush(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       if(!self->Flush())
-               sq_pushinteger(v, 1);
-       else
-               sq_pushnull(v);
-       return 1;
-}
-
-int _stream_eos(HSQUIRRELVM v)
-{
-       SETUP_STREAM(v);
-       if(self->EOS())
-               sq_pushinteger(v, 1);
-       else
-               sq_pushnull(v);
-       return 1;
-}
-
-static SQRegFunction _stream_methods[] = {
-       _DECL_STREAM_FUNC(readstr,-2,_SC("xnn")),
-       _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
-       _DECL_STREAM_FUNC(readn,2,_SC("xn")),
-       _DECL_STREAM_FUNC(writestr,-2,_SC("xsn")),
-       _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
-       _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
-       _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
-       _DECL_STREAM_FUNC(tell,1,_SC("x")),
-       _DECL_STREAM_FUNC(len,1,_SC("x")),
-       _DECL_STREAM_FUNC(eos,1,_SC("x")),
-       _DECL_STREAM_FUNC(flush,1,_SC("x")),
-       {0,0}
-};
-
-void init_streamclass(HSQUIRRELVM v)
-{
-       sq_pushregistrytable(v);
-       sq_pushstring(v,_SC("std_stream"),-1);
-       if(SQ_FAILED(sq_get(v,-2))) {
-               sq_pushstring(v,_SC("std_stream"),-1);
-               sq_newclass(v,SQFalse);
-               sq_settypetag(v,-1,SQSTD_STREAM_TYPE_TAG);
-               int i = 0;
-               while(_stream_methods[i].name != 0) {
-                       SQRegFunction &f = _stream_methods[i];
-                       sq_pushstring(v,f.name,-1);
-                       sq_newclosure(v,f.f,0);
-                       sq_setparamscheck(v,f.nparamscheck,f.typemask);
-                       sq_createslot(v,-3);
-                       i++;
-               }
-               sq_createslot(v,-3);
-       }
-       else {
-               sq_pop(v,1); //result
-       }
-       sq_pop(v,1);
-}
-
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,int typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
-{
-       if(sq_gettype(v,-1) != OT_TABLE)
-               return sq_throwerror(v,_SC("table expected"));
-       int top = sq_gettop(v);
-       //create delegate
-    init_streamclass(v);
-       sq_pushregistrytable(v);
-       sq_pushstring(v,reg_name,-1);
-       sq_pushstring(v,_SC("std_stream"),-1);
-       if(SQ_SUCCEEDED(sq_get(v,-3))) {
-               sq_newclass(v,SQTrue);
-               sq_settypetag(v,-1,typetag);
-               int i = 0;
-               while(methods[i].name != 0) {
-                       SQRegFunction &f = methods[i];
-                       sq_pushstring(v,f.name,-1);
-                       sq_newclosure(v,f.f,0);
-                       sq_setparamscheck(v,f.nparamscheck,f.typemask);
-                       sq_setnativeclosurename(v,-1,f.name);
-                       sq_createslot(v,-3);
-                       i++;
-               }
-               sq_createslot(v,-3);
-               sq_pop(v,1);
-               
-               i = 0;
-               while(globals[i].name!=0)
-               {
-                       SQRegFunction &f = globals[i];
-                       sq_pushstring(v,f.name,-1);
-                       sq_newclosure(v,f.f,0);
-                       sq_setparamscheck(v,f.nparamscheck,f.typemask);
-                       sq_setnativeclosurename(v,-1,f.name);
-                       sq_createslot(v,-3);
-                       i++;
-               }
-               //register the class in the target table
-               sq_pushstring(v,name,-1);
-               sq_pushregistrytable(v);
-               sq_pushstring(v,reg_name,-1);
-               sq_get(v,-2);
-               sq_remove(v,-2);
-               sq_createslot(v,-3);
-
-               sq_settop(v,top);
-               return SQ_OK;
-       }
-       sq_settop(v,top);
-       return SQ_ERROR;
-}
+/* see copyright notice in squirrel.h */\r
+#include <new>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <squirrel.h>\r
+#include <sqstdio.h>\r
+#include <sqstdblob.h>\r
+#include "sqstdstream.h"\r
+#include "sqstdblobimpl.h"\r
+\r
+#define SETUP_STREAM(v) \\r
+       SQStream *self = NULL; \\r
+       if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \\r
+               return sq_throwerror(v,_SC("invalid type tag")); \\r
+       if(!self->IsValid())  \\r
+               return sq_throwerror(v,_SC("the stream is invalid"));\r
+\r
+SQInteger _stream_readstr(HSQUIRRELVM v)\r
+{\r
+    SETUP_STREAM(v);\r
+       SQInteger type = _SC('a'), size = 0;\r
+       sq_getinteger(v, 2, &size);\r
+       if(size <= 0) return sq_throwerror(v,_SC("invalid size"));\r
+       if(sq_gettop(v) > 2)\r
+               sq_getinteger(v, 3, &type);\r
+       SQChar *dest = NULL;\r
+       switch(type) {\r
+       case _SC('a'): {\r
+               char *temp;\r
+               if(self->Read(sq_getscratchpad(v, size+1), size) != size)\r
+                       return sq_throwerror(v, _SC("io failure"));\r
+#ifdef _UNICODE\r
+               temp = (char*) sq_getscratchpad(v, size + (size * sizeof(SQChar)));\r
+               dest = (SQChar*) &temp[size];\r
+               size = (SQInteger)mbstowcs(dest, (const char*)temp, size);\r
+#else\r
+               temp = (char *) sq_getscratchpad(v, -1);\r
+               dest = temp;\r
+#endif\r
+                                  }\r
+               break;\r
+       case _SC('u'): {\r
+               wchar_t *temp;\r
+               if(self->Read(sq_getscratchpad(v, (size + 1) * sizeof(wchar_t)),size * sizeof(wchar_t)) != (size * sizeof(wchar_t)))\r
+                       return sq_throwerror(v, _SC("io failure"));\r
+               \r
+#ifdef _UNICODE\r
+               temp = (wchar_t*) sq_getscratchpad(v, -1);\r
+               dest = (SQChar*) temp;\r
+#else\r
+               temp = (wchar_t*) sq_getscratchpad(v,(size * 3) + (size * sizeof(wchar_t)));\r
+               dest = (char*) &temp[size];\r
+               size = (SQInteger)wcstombs(dest, (const wchar_t*)temp, size);\r
+#endif\r
+                                  }\r
+               break;\r
+       default:\r
+               return sq_throwerror(v, _SC("invalid coding"));\r
+       }\r
+\r
+       sq_pushstring(v, dest, size);\r
+       return 1;\r
+}\r
+\r
+SQInteger _stream_readblob(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       SQUserPointer data,blobp;\r
+       SQInteger size,res;\r
+       sq_getinteger(v,2,&size);\r
+       if(size > self->Len()) {\r
+               size = self->Len();\r
+       }\r
+       data = sq_getscratchpad(v,size);\r
+       res = self->Read(data,size);\r
+       if(res <= 0)\r
+               return sq_throwerror(v,_SC("no data left to read"));\r
+       blobp = sqstd_createblob(v,res);\r
+       memcpy(blobp,data,res);\r
+       return 1;\r
+}\r
+\r
+#define SAFE_READN(ptr,len) { \\r
+       if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \\r
+       }\r
+SQInteger _stream_readn(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       SQInteger format;\r
+       sq_getinteger(v, 2, &format);\r
+       switch(format) {\r
+       case 'i': {\r
+               SQInteger i;\r
+               SAFE_READN(&i, sizeof(i));\r
+               sq_pushinteger(v, i);\r
+                         }\r
+               break;\r
+       case 's': {\r
+               short s;\r
+               SAFE_READN(&s, sizeof(short));\r
+               sq_pushinteger(v, s);\r
+                         }\r
+               break;\r
+       case 'w': {\r
+               unsigned short w;\r
+               SAFE_READN(&w, sizeof(unsigned short));\r
+               sq_pushinteger(v, w);\r
+                         }\r
+               break;\r
+       case 'c': {\r
+               char c;\r
+               SAFE_READN(&c, sizeof(char));\r
+               sq_pushinteger(v, c);\r
+                         }\r
+               break;\r
+       case 'b': {\r
+               unsigned char c;\r
+               SAFE_READN(&c, sizeof(unsigned char));\r
+               sq_pushinteger(v, c);\r
+                         }\r
+               break;\r
+       case 'f': {\r
+               float f;\r
+               SAFE_READN(&f, sizeof(float));\r
+               sq_pushfloat(v, f);\r
+                         }\r
+               break;\r
+       case 'd': {\r
+               double d;\r
+               SAFE_READN(&d, sizeof(double));\r
+               sq_pushfloat(v, (SQFloat)d);\r
+                         }\r
+               break;\r
+       default:\r
+               return sq_throwerror(v, _SC("invalid format"));\r
+       }\r
+       return 1;\r
+}\r
+\r
+SQInteger _stream_writestr(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       const SQChar *str,*res;\r
+       SQInteger trgformat = 'a',len = 0;\r
+       sq_getstring(v,2,&str);\r
+       len = sq_getsize(v,2);\r
+       if(sq_gettop(v)>2)\r
+               sq_getinteger(v,3,&trgformat);\r
+       switch(trgformat)\r
+       {\r
+       case 'a':\r
+#ifdef _UNICODE\r
+               res = sq_getscratchpad(v,len*3);\r
+               len = (SQInteger) wcstombs((char *)res, (const wchar_t*)str, len);\r
+#else\r
+               res = str;\r
+#endif\r
+               self->Write((void *)res,len);\r
+               break;\r
+       case 'u':\r
+#ifdef _UNICODE\r
+               res = str;\r
+#else\r
+               res = sq_getscratchpad(v,len*sizeof(wchar_t));\r
+               len = (SQInteger) mbstowcs((wchar_t*)res, str, len);\r
+#endif\r
+               self->Write((void *)res,len*sizeof(wchar_t));\r
+               break;\r
+       default:\r
+               return sq_throwerror(v,_SC("wrong encoding"));\r
+       }\r
+       \r
+       return 0;\r
+}\r
+\r
+SQInteger _stream_writeblob(HSQUIRRELVM v)\r
+{\r
+       SQUserPointer data;\r
+       SQInteger size;\r
+       SETUP_STREAM(v);\r
+       if(SQ_FAILED(sqstd_getblob(v,2,&data)))\r
+               return sq_throwerror(v,_SC("invalid parameter"));\r
+       size = sqstd_getblobsize(v,2);\r
+       if(self->Write(data,size) != size)\r
+               return sq_throwerror(v,_SC("io error"));\r
+       sq_pushinteger(v,size);\r
+       return 1;\r
+}\r
+\r
+SQInteger _stream_writen(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       SQInteger format, ti;\r
+       SQFloat tf;\r
+       sq_getinteger(v, 3, &format);\r
+       switch(format) {\r
+       case 'i': {\r
+               SQInteger i;\r
+               sq_getinteger(v, 2, &ti);\r
+               i = ti;\r
+               self->Write(&i, sizeof(SQInteger));\r
+                         }\r
+               break;\r
+       case 's': {\r
+               short s;\r
+               sq_getinteger(v, 2, &ti);\r
+               s = ti;\r
+               self->Write(&s, sizeof(short));\r
+                         }\r
+               break;\r
+       case 'w': {\r
+               unsigned short w;\r
+               sq_getinteger(v, 2, &ti);\r
+               w = ti;\r
+               self->Write(&w, sizeof(unsigned short));\r
+                         }\r
+               break;\r
+       case 'c': {\r
+               char c;\r
+               sq_getinteger(v, 2, &ti);\r
+               c = ti;\r
+               self->Write(&c, sizeof(char));\r
+                                 }\r
+               break;\r
+       case 'b': {\r
+               unsigned char b;\r
+               sq_getinteger(v, 2, &ti);\r
+               b = ti;\r
+               self->Write(&b, sizeof(unsigned char));\r
+                         }\r
+               break;\r
+       case 'f': {\r
+               float f;\r
+               sq_getfloat(v, 2, &tf);\r
+               f = tf;\r
+               self->Write(&f, sizeof(float));\r
+                         }\r
+               break;\r
+       case 'd': {\r
+               double d;\r
+               sq_getfloat(v, 2, &tf);\r
+               d = tf;\r
+               self->Write(&d, sizeof(double));\r
+                         }\r
+               break;\r
+       default:\r
+               return sq_throwerror(v, _SC("invalid format"));\r
+       }\r
+       return 0;\r
+}\r
+\r
+SQInteger _stream_seek(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       SQInteger offset, origin = SQ_SEEK_SET;\r
+       sq_getinteger(v, 2, &offset);\r
+       if(sq_gettop(v) > 2) {\r
+               SQInteger t;\r
+               sq_getinteger(v, 3, &t);\r
+               switch(t) {\r
+                       case 'b': origin = SQ_SEEK_SET; break;\r
+                       case 'c': origin = SQ_SEEK_CUR; break;\r
+                       case 'e': origin = SQ_SEEK_END; break;\r
+                       default: return sq_throwerror(v,_SC("invalid origin"));\r
+               }\r
+       }\r
+       sq_pushinteger(v, self->Seek(offset, origin));\r
+       return 1;\r
+}\r
+\r
+SQInteger _stream_tell(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       sq_pushinteger(v, self->Tell());\r
+       return 1;\r
+}\r
+\r
+SQInteger _stream_len(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       sq_pushinteger(v, self->Len());\r
+       return 1;\r
+}\r
+\r
+SQInteger _stream_flush(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       if(!self->Flush())\r
+               sq_pushinteger(v, 1);\r
+       else\r
+               sq_pushnull(v);\r
+       return 1;\r
+}\r
+\r
+SQInteger _stream_eos(HSQUIRRELVM v)\r
+{\r
+       SETUP_STREAM(v);\r
+       if(self->EOS())\r
+               sq_pushinteger(v, 1);\r
+       else\r
+               sq_pushnull(v);\r
+       return 1;\r
+}\r
+\r
+static SQRegFunction _stream_methods[] = {\r
+       _DECL_STREAM_FUNC(readstr,-2,_SC("xnn")),\r
+       _DECL_STREAM_FUNC(readblob,2,_SC("xn")),\r
+       _DECL_STREAM_FUNC(readn,2,_SC("xn")),\r
+       _DECL_STREAM_FUNC(writestr,-2,_SC("xsn")),\r
+       _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),\r
+       _DECL_STREAM_FUNC(writen,3,_SC("xnn")),\r
+       _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),\r
+       _DECL_STREAM_FUNC(tell,1,_SC("x")),\r
+       _DECL_STREAM_FUNC(len,1,_SC("x")),\r
+       _DECL_STREAM_FUNC(eos,1,_SC("x")),\r
+       _DECL_STREAM_FUNC(flush,1,_SC("x")),\r
+       {0,0}\r
+};\r
+\r
+void init_streamclass(HSQUIRRELVM v)\r
+{\r
+       sq_pushregistrytable(v);\r
+       sq_pushstring(v,_SC("std_stream"),-1);\r
+       if(SQ_FAILED(sq_get(v,-2))) {\r
+               sq_pushstring(v,_SC("std_stream"),-1);\r
+               sq_newclass(v,SQFalse);\r
+               sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);\r
+               SQInteger i = 0;\r
+               while(_stream_methods[i].name != 0) {\r
+                       SQRegFunction &f = _stream_methods[i];\r
+                       sq_pushstring(v,f.name,-1);\r
+                       sq_newclosure(v,f.f,0);\r
+                       sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
+                       sq_createslot(v,-3);\r
+                       i++;\r
+               }\r
+               sq_createslot(v,-3);\r
+       }\r
+       else {\r
+               sq_pop(v,1); //result\r
+       }\r
+       sq_pop(v,1);\r
+}\r
+\r
+SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)\r
+{\r
+       if(sq_gettype(v,-1) != OT_TABLE)\r
+               return sq_throwerror(v,_SC("table expected"));\r
+       SQInteger top = sq_gettop(v);\r
+       //create delegate\r
+    init_streamclass(v);\r
+       sq_pushregistrytable(v);\r
+       sq_pushstring(v,reg_name,-1);\r
+       sq_pushstring(v,_SC("std_stream"),-1);\r
+       if(SQ_SUCCEEDED(sq_get(v,-3))) {\r
+               sq_newclass(v,SQTrue);\r
+               sq_settypetag(v,-1,typetag);\r
+               SQInteger i = 0;\r
+               while(methods[i].name != 0) {\r
+                       SQRegFunction &f = methods[i];\r
+                       sq_pushstring(v,f.name,-1);\r
+                       sq_newclosure(v,f.f,0);\r
+                       sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
+                       sq_setnativeclosurename(v,-1,f.name);\r
+                       sq_createslot(v,-3);\r
+                       i++;\r
+               }\r
+               sq_createslot(v,-3);\r
+               sq_pop(v,1);\r
+               \r
+               i = 0;\r
+               while(globals[i].name!=0)\r
+               {\r
+                       SQRegFunction &f = globals[i];\r
+                       sq_pushstring(v,f.name,-1);\r
+                       sq_newclosure(v,f.f,0);\r
+                       sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
+                       sq_setnativeclosurename(v,-1,f.name);\r
+                       sq_createslot(v,-3);\r
+                       i++;\r
+               }\r
+               //register the class in the target table\r
+               sq_pushstring(v,name,-1);\r
+               sq_pushregistrytable(v);\r
+               sq_pushstring(v,reg_name,-1);\r
+               sq_get(v,-2);\r
+               sq_remove(v,-2);\r
+               sq_createslot(v,-3);\r
+\r
+               sq_settop(v,top);\r
+               return SQ_OK;\r
+       }\r
+       sq_settop(v,top);\r
+       return SQ_ERROR;\r
+}\r
index fdb6858..d08fc4c 100644 (file)
@@ -1,20 +1,20 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTD_STREAM_H_
-#define _SQSTD_STREAM_H_
-
-int _stream_readstr(HSQUIRRELVM v);
-int _stream_readblob(HSQUIRRELVM v);
-int _stream_readline(HSQUIRRELVM v);
-int _stream_readn(HSQUIRRELVM v);
-int _stream_writestr(HSQUIRRELVM v);
-int _stream_writeblob(HSQUIRRELVM v);
-int _stream_writen(HSQUIRRELVM v);
-int _stream_seek(HSQUIRRELVM v);
-int _stream_tell(HSQUIRRELVM v);
-int _stream_len(HSQUIRRELVM v);
-int _stream_eos(HSQUIRRELVM v);
-int _stream_flush(HSQUIRRELVM v);
-
-#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,int typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
-#endif /*_SQSTD_STREAM_H_*/
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTD_STREAM_H_\r
+#define _SQSTD_STREAM_H_\r
+\r
+SQInteger _stream_readstr(HSQUIRRELVM v);\r
+SQInteger _stream_readblob(HSQUIRRELVM v);\r
+SQInteger _stream_readline(HSQUIRRELVM v);\r
+SQInteger _stream_readn(HSQUIRRELVM v);\r
+SQInteger _stream_writestr(HSQUIRRELVM v);\r
+SQInteger _stream_writeblob(HSQUIRRELVM v);\r
+SQInteger _stream_writen(HSQUIRRELVM v);\r
+SQInteger _stream_seek(HSQUIRRELVM v);\r
+SQInteger _stream_tell(HSQUIRRELVM v);\r
+SQInteger _stream_len(HSQUIRRELVM v);\r
+SQInteger _stream_eos(HSQUIRRELVM v);\r
+SQInteger _stream_flush(HSQUIRRELVM v);\r
+\r
+#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}\r
+SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);\r
+#endif /*_SQSTD_STREAM_H_*/\r
index 9caef54..81fc7c2 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdstring.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#ifdef _UNICODE
-#define scstrchr wcschr
-#define scsnprintf wsnprintf
-#define scatoi _wtoi
-#else
-#define scstrchr strchr
-#define scsnprintf snprintf
-#define scatoi atoi
-#endif
-#define MAX_FORMAT_LEN 20
-#define MAX_WFORMAT_LEN        3
-#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
-
-static int validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, int n,int &width)
-{
-       SQChar swidth[MAX_WFORMAT_LEN];
-       int wc = 0;
-       int start = n;
-       fmt[0] = '%';
-       while (scstrchr(_SC("-+ #0"), src[n])) n++;
-       while (scisdigit(src[n])) {
-               swidth[wc] = src[n];
-               n++;
-               wc++;
-               if(wc>=MAX_WFORMAT_LEN)
-                       return sq_throwerror(v,_SC("width format too long"));
-       }
-       swidth[wc] = '\0';
-       if(wc > 0) {
-               width = scatoi(swidth);
-       }
-       else
-               width = 0;
-       if (src[n] == '.') {
-           n++;
-       
-               wc = 0;
-               while (scisdigit(src[n])) {
-                       swidth[wc] = src[n];
-                       n++;
-                       wc++;
-                       if(wc>=MAX_WFORMAT_LEN)
-                               return sq_throwerror(v,_SC("precision format too long"));
-               }
-               swidth[wc] = '\0';
-               if(wc > 0) {
-                       width += scatoi(swidth);
-               }
-       }
-       if (n-start > MAX_FORMAT_LEN )
-               return sq_throwerror(v,_SC("format too long"));
-       memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
-       fmt[(n-start)+2] = '\0';
-       return n;
-}
-
-static int _string_format(HSQUIRRELVM v)
-{
-       const SQChar *format;
-       SQChar *dest;
-       SQChar fmt[MAX_FORMAT_LEN];
-       sq_getstring(v,2,&format);
-       int allocated = (sq_getsize(v,2)+1)*sizeof(SQChar);
-       dest = sq_getscratchpad(v,allocated);
-       int n = 0,i = 0, nparam = 3, w;
-       while(format[n] != '\0') {
-               if(format[n] != '%') {
-                       dest[i++] = format[n];
-                       n++;
-               }
-               else if(format[++n] == '%') {
-                       dest[i++] = '%';
-               }
-               else {
-                       if( nparam > sq_gettop(v) )
-                               return sq_throwerror(v,_SC("not enough paramters for the given format string"));
-                       n = validate_format(v,fmt,format,n,w);
-                       if(n < 0) return -1;
-                       int addlen = 0;
-                       int valtype = 0;
-                       const SQChar *ts;
-                       SQInteger ti;
-                       SQFloat tf;
-                       switch(format[n]) {
-                       case 's':
-                               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))) 
-                                       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))) 
-                                       return sq_throwerror(v,_SC("float expected for the specified format"));
-                               addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
-                               valtype = 'f';
-                               break;
-                       default:
-                               return sq_throwerror(v,_SC("invalid format"));
-                       }
-                       n++;
-                       if((allocated-i) < addlen)
-                               allocated += addlen - (allocated-i);
-                       dest = sq_getscratchpad(v,allocated);
-                       switch(valtype) {
-                       case 's': i += scsprintf(&dest[i],fmt,ts); break;
-                       case 'i': i += scsprintf(&dest[i],fmt,ti); break;
-                       case 'f': i += scsprintf(&dest[i],fmt,tf); break;
-                       };
-                       nparam ++;
-               }
-       }
-       sq_pushstring(v,dest,i);
-       return 1;
-}
-
-#define SETUP_REX(v) \
-       SQRex *self = NULL; \
-       sq_getinstanceup(v,1,(SQUserPointer *)&self,0); 
-
-static int _rexobj_releasehook(SQUserPointer p, int size)
-{
-       SQRex *self = ((SQRex *)p);
-       sqstd_rex_free(self);
-       return 1;
-}
-
-static int _regexp_match(HSQUIRRELVM v)
-{
-       SETUP_REX(v);
-       const SQChar *str;
-       sq_getstring(v,2,&str);
-       if(sqstd_rex_match(self,str) == SQTrue)
-       {
-               sq_pushinteger(v,1);
-               return 1;
-       }
-       return 0;
-}
-
-static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
-{
-       sq_newtable(v);
-       sq_pushstring(v,_SC("begin"),-1);
-       sq_pushinteger(v,begin - str);
-       sq_rawset(v,-3);
-       sq_pushstring(v,_SC("end"),-1);
-       sq_pushinteger(v,end - str);
-       sq_rawset(v,-3);
-}
-
-static int _regexp_search(HSQUIRRELVM v)
-{
-       SETUP_REX(v);
-       const SQChar *str,*begin,*end;
-       SQInteger start = 0;
-       sq_getstring(v,2,&str);
-       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
-       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
-               _addrexmatch(v,str,begin,end);
-               return 1;
-       }
-       return 0;
-}
-
-static int _regexp_capture(HSQUIRRELVM v)
-{
-       SETUP_REX(v);
-       const SQChar *str,*begin,*end;
-       SQInteger start = 0;
-       sq_getstring(v,2,&str);
-       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
-       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
-               SQInteger n = sqstd_rex_getsubexpcount(self);
-               SQRexMatch match;
-               sq_newarray(v,0);
-               for(SQInteger i = 0;i < n; i++) {
-                       sqstd_rex_getsubexp(self,i,&match);
-                       if(match.len > 0)
-                               _addrexmatch(v,str,match.begin,match.begin+match.len);
-                       else
-                               _addrexmatch(v,str,str,str); //empty match
-                       sq_arrayappend(v,-2);
-               }
-               return 1;
-       }
-       return 0;
-}
-
-static int _regexp_subexpcount(HSQUIRRELVM v)
-{
-       SETUP_REX(v);
-       sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
-       return 1;
-}
-
-static int _regexp_constructor(HSQUIRRELVM v)
-{
-       const SQChar *error,*pattern;
-       sq_getstring(v,2,&pattern);
-       SQRex *rex = sqstd_rex_compile(pattern,&error);
-       if(!rex) return sq_throwerror(v,error);
-       sq_setinstanceup(v,1,rex);
-       sq_setreleasehook(v,1,_rexobj_releasehook);
-       return 0;
-}
-
-static int _regexp__typeof(HSQUIRRELVM v)
-{
-       sq_pushstring(v,_SC("regexp"),-1);
-       return 1;
-}
-
-#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
-static SQRegFunction rexobj_funcs[]={
-       _DECL_REX_FUNC(constructor,2,_SC(".s")),
-       _DECL_REX_FUNC(search,-2,_SC("xsn")),
-       _DECL_REX_FUNC(match,2,_SC("xs")),
-       _DECL_REX_FUNC(capture,-2,_SC("xsn")),
-       _DECL_REX_FUNC(subexpcount,1,_SC("x")),
-       _DECL_REX_FUNC(_typeof,1,_SC("x")),
-       {0,0}
-};
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
-static SQRegFunction stringlib_funcs[]={
-       _DECL_FUNC(format,-2,_SC(".s")),
-       {0,0}
-};
-
-
-int sqstd_register_stringlib(HSQUIRRELVM v)
-{
-       sq_pushstring(v,_SC("regexp"),-1);
-       sq_newclass(v,SQFalse);
-       int i = 0;
-       while(rexobj_funcs[i].name != 0) {
-               SQRegFunction &f = rexobj_funcs[i];
-               sq_pushstring(v,f.name,-1);
-               sq_newclosure(v,f.f,0);
-               sq_setparamscheck(v,f.nparamscheck,f.typemask);
-               sq_setnativeclosurename(v,-1,f.name);
-               sq_createslot(v,-3);
-               i++;
-       }
-       sq_createslot(v,-3);
-
-       i = 0;
-       while(stringlib_funcs[i].name!=0)
-       {
-               sq_pushstring(v,stringlib_funcs[i].name,-1);
-               sq_newclosure(v,stringlib_funcs[i].f,0);
-               sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
-               sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
-               sq_createslot(v,-3);
-               i++;
-       }
-       return 1;
-}
+/* see copyright notice in squirrel.h */\r
+#include <squirrel.h>\r
+#include <sqstdstring.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <assert.h>\r
+\r
+#ifdef _UNICODE\r
+#define scstrchr wcschr\r
+#define scsnprintf wsnprintf\r
+#define scatoi _wtoi\r
+#else\r
+#define scstrchr strchr\r
+#define scsnprintf snprintf\r
+#define scatoi atoi\r
+#endif\r
+#define MAX_FORMAT_LEN 20\r
+#define MAX_WFORMAT_LEN        3\r
+#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))\r
+\r
+static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)\r
+{\r
+       SQChar swidth[MAX_WFORMAT_LEN];\r
+       SQInteger wc = 0;\r
+       SQInteger start = n;\r
+       fmt[0] = '%';\r
+       while (scstrchr(_SC("-+ #0"), src[n])) n++;\r
+       while (scisdigit(src[n])) {\r
+               swidth[wc] = src[n];\r
+               n++;\r
+               wc++;\r
+               if(wc>=MAX_WFORMAT_LEN)\r
+                       return sq_throwerror(v,_SC("width format too long"));\r
+       }\r
+       swidth[wc] = '\0';\r
+       if(wc > 0) {\r
+               width = scatoi(swidth);\r
+       }\r
+       else\r
+               width = 0;\r
+       if (src[n] == '.') {\r
+           n++;\r
+       \r
+               wc = 0;\r
+               while (scisdigit(src[n])) {\r
+                       swidth[wc] = src[n];\r
+                       n++;\r
+                       wc++;\r
+                       if(wc>=MAX_WFORMAT_LEN)\r
+                               return sq_throwerror(v,_SC("precision format too long"));\r
+               }\r
+               swidth[wc] = '\0';\r
+               if(wc > 0) {\r
+                       width += scatoi(swidth);\r
+               }\r
+       }\r
+       if (n-start > MAX_FORMAT_LEN )\r
+               return sq_throwerror(v,_SC("format too long"));\r
+       memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));\r
+       fmt[(n-start)+2] = '\0';\r
+       return n;\r
+}\r
+\r
+static SQInteger _string_format(HSQUIRRELVM v)\r
+{\r
+       const SQChar *format;\r
+       SQChar *dest;\r
+       SQChar fmt[MAX_FORMAT_LEN];\r
+       sq_getstring(v,2,&format);\r
+       SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar);\r
+       dest = sq_getscratchpad(v,allocated);\r
+       SQInteger n = 0,i = 0, nparam = 3, w;\r
+       while(format[n] != '\0') {\r
+               if(format[n] != '%') {\r
+                       assert(i < allocated);\r
+                       dest[i++] = format[n];\r
+                       n++;\r
+               }\r
+               else if(format[n+1] == '%') { //handles %%\r
+                               dest[i++] = '%';\r
+                               n += 2; \r
+               }\r
+               else {\r
+                       n++;\r
+                       if( nparam > sq_gettop(v) )\r
+                               return sq_throwerror(v,_SC("not enough paramters for the given format string"));\r
+                       n = validate_format(v,fmt,format,n,w);\r
+                       if(n < 0) return -1;\r
+                       SQInteger addlen = 0;\r
+                       SQInteger valtype = 0;\r
+                       const SQChar *ts;\r
+                       SQInteger ti;\r
+                       SQFloat tf;\r
+                       switch(format[n]) {\r
+                       case 's':\r
+                               if(SQ_FAILED(sq_getstring(v,nparam,&ts))) \r
+                                       return sq_throwerror(v,_SC("string expected for the specified format"));\r
+                               addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));\r
+                               valtype = 's';\r
+                               break;\r
+                       case 'i': case 'd': case 'c':case 'o':  case 'u':  case 'x':  case 'X':\r
+                               if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) \r
+                                       return sq_throwerror(v,_SC("integer expected for the specified format"));\r
+                               addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));\r
+                               valtype = 'i';\r
+                               break;\r
+                       case 'f': case 'g': case 'G': case 'e':  case 'E':\r
+                               if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) \r
+                                       return sq_throwerror(v,_SC("float expected for the specified format"));\r
+                               addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));\r
+                               valtype = 'f';\r
+                               break;\r
+                       default:\r
+                               return sq_throwerror(v,_SC("invalid format"));\r
+                       }\r
+                       n++;\r
+                       if((allocated-i) < addlen)\r
+                               allocated += addlen;\r
+                       dest = sq_getscratchpad(v,allocated);\r
+                       switch(valtype) {\r
+                       case 's': i += scsprintf(&dest[i],fmt,ts); break;\r
+                       case 'i': i += scsprintf(&dest[i],fmt,ti); break;\r
+                       case 'f': i += scsprintf(&dest[i],fmt,tf); break;\r
+                       };\r
+                       nparam ++;\r
+               }\r
+       }\r
+       sq_pushstring(v,dest,i);\r
+       return 1;\r
+}\r
+\r
+#define SETUP_REX(v) \\r
+       SQRex *self = NULL; \\r
+       sq_getinstanceup(v,1,(SQUserPointer *)&self,0); \r
+\r
+static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)\r
+{\r
+       SQRex *self = ((SQRex *)p);\r
+       sqstd_rex_free(self);\r
+       return 1;\r
+}\r
+\r
+static SQInteger _regexp_match(HSQUIRRELVM v)\r
+{\r
+       SETUP_REX(v);\r
+       const SQChar *str;\r
+       sq_getstring(v,2,&str);\r
+       if(sqstd_rex_match(self,str) == SQTrue)\r
+       {\r
+               sq_pushinteger(v,1);\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)\r
+{\r
+       sq_newtable(v);\r
+       sq_pushstring(v,_SC("begin"),-1);\r
+       sq_pushinteger(v,begin - str);\r
+       sq_rawset(v,-3);\r
+       sq_pushstring(v,_SC("end"),-1);\r
+       sq_pushinteger(v,end - str);\r
+       sq_rawset(v,-3);\r
+}\r
+\r
+static SQInteger _regexp_search(HSQUIRRELVM v)\r
+{\r
+       SETUP_REX(v);\r
+       const SQChar *str,*begin,*end;\r
+       SQInteger start = 0;\r
+       sq_getstring(v,2,&str);\r
+       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);\r
+       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {\r
+               _addrexmatch(v,str,begin,end);\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static SQInteger _regexp_capture(HSQUIRRELVM v)\r
+{\r
+       SETUP_REX(v);\r
+       const SQChar *str,*begin,*end;\r
+       SQInteger start = 0;\r
+       sq_getstring(v,2,&str);\r
+       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);\r
+       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {\r
+               SQInteger n = sqstd_rex_getsubexpcount(self);\r
+               SQRexMatch match;\r
+               sq_newarray(v,0);\r
+               for(SQInteger i = 0;i < n; i++) {\r
+                       sqstd_rex_getsubexp(self,i,&match);\r
+                       if(match.len > 0)\r
+                               _addrexmatch(v,str,match.begin,match.begin+match.len);\r
+                       else\r
+                               _addrexmatch(v,str,str,str); //empty match\r
+                       sq_arrayappend(v,-2);\r
+               }\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static SQInteger _regexp_subexpcount(HSQUIRRELVM v)\r
+{\r
+       SETUP_REX(v);\r
+       sq_pushinteger(v,sqstd_rex_getsubexpcount(self));\r
+       return 1;\r
+}\r
+\r
+static SQInteger _regexp_constructor(HSQUIRRELVM v)\r
+{\r
+       const SQChar *error,*pattern;\r
+       sq_getstring(v,2,&pattern);\r
+       SQRex *rex = sqstd_rex_compile(pattern,&error);\r
+       if(!rex) return sq_throwerror(v,error);\r
+       sq_setinstanceup(v,1,rex);\r
+       sq_setreleasehook(v,1,_rexobj_releasehook);\r
+       return 0;\r
+}\r
+\r
+static SQInteger _regexp__typeof(HSQUIRRELVM v)\r
+{\r
+       sq_pushstring(v,_SC("regexp"),-1);\r
+       return 1;\r
+}\r
+\r
+#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}\r
+static SQRegFunction rexobj_funcs[]={\r
+       _DECL_REX_FUNC(constructor,2,_SC(".s")),\r
+       _DECL_REX_FUNC(search,-2,_SC("xsn")),\r
+       _DECL_REX_FUNC(match,2,_SC("xs")),\r
+       _DECL_REX_FUNC(capture,-2,_SC("xsn")),\r
+       _DECL_REX_FUNC(subexpcount,1,_SC("x")),\r
+       _DECL_REX_FUNC(_typeof,1,_SC("x")),\r
+       {0,0}\r
+};\r
+\r
+#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}\r
+static SQRegFunction stringlib_funcs[]={\r
+       _DECL_FUNC(format,-2,_SC(".s")),\r
+       {0,0}\r
+};\r
+\r
+\r
+SQInteger sqstd_register_stringlib(HSQUIRRELVM v)\r
+{\r
+       sq_pushstring(v,_SC("regexp"),-1);\r
+       sq_newclass(v,SQFalse);\r
+       SQInteger i = 0;\r
+       while(rexobj_funcs[i].name != 0) {\r
+               SQRegFunction &f = rexobj_funcs[i];\r
+               sq_pushstring(v,f.name,-1);\r
+               sq_newclosure(v,f.f,0);\r
+               sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
+               sq_setnativeclosurename(v,-1,f.name);\r
+               sq_createslot(v,-3);\r
+               i++;\r
+       }\r
+       sq_createslot(v,-3);\r
+\r
+       i = 0;\r
+       while(stringlib_funcs[i].name!=0)\r
+       {\r
+               sq_pushstring(v,stringlib_funcs[i].name,-1);\r
+               sq_newclosure(v,stringlib_funcs[i].f,0);\r
+               sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);\r
+               sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);\r
+               sq_createslot(v,-3);\r
+               i++;\r
+       }\r
+       return 1;\r
+}\r
index 075a880..b52f057 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sqstdsystem.h>
-
-#ifdef SQUNICODE
-#include <wchar.h>
-#define scgetenv _wgetenv
-#define scsystem _wsystem
-#define scasctime _wasctime
-#define scremove _wremove
-#define screname _wrename
-#else
-#define scgetenv getenv
-#define scsystem system
-#define scasctime asctime
-#define scremove remove
-#define screname rename
-#endif
-
-static int _system_getenv(HSQUIRRELVM v)
-{
-       const SQChar *s;
-       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
-        sq_pushstring(v,scgetenv(s),-1);
-               return 1;
-       }
-       return 0;
-}
-
-
-static int _system_system(HSQUIRRELVM v)
-{
-       const SQChar *s;
-       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
-               sq_pushinteger(v,scsystem(s));
-               return 1;
-       }
-       return sq_throwerror(v,_SC("wrong param"));
-}
-
-
-static int _system_clock(HSQUIRRELVM v)
-{
-       sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
-       return 1;
-}
-
-static int _system_time(HSQUIRRELVM v)
-{
-       time_t t;
-       time(&t);
-       sq_pushinteger(v,*((SQInteger *)&t));
-       return 1;
-}
-
-static int _system_remove(HSQUIRRELVM v)
-{
-       const SQChar *s;
-       sq_getstring(v,2,&s);
-       if(scremove(s)==-1)
-               return sq_throwerror(v,_SC("remove() failed"));
-       return 0;
-}
-
-static int _system_rename(HSQUIRRELVM v)
-{
-       const SQChar *oldn,*newn;
-       sq_getstring(v,2,&oldn);
-       sq_getstring(v,3,&newn);
-       if(screname(oldn,newn)==-1)
-               return sq_throwerror(v,_SC("rename() failed"));
-       return 0;
-}
-
-static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
-{
-       sq_pushstring(v,name,-1);
-       sq_pushinteger(v,val);
-       sq_rawset(v,-3);
-}
-
-static int _system_date(HSQUIRRELVM v)
-{
-       time_t t;
-       SQInteger format = 'l';
-       if(sq_gettop(v) > 1) {
-               sq_getinteger(v,2,(SQInteger*)&t);
-               if(sq_gettop(v) > 2) {
-                       sq_getinteger(v,3,(SQInteger*)&format);
-               }
-       }
-       else {
-               time(&t);
-       }
-       tm *date;
-    if(format == 'u')
-               date = gmtime(&t);
-       else
-               date = localtime(&t);
-       if(!date)
-               return sq_throwerror(v,_SC("crt api failure"));
-       sq_newtable(v);
-       _set_integer_slot(v, _SC("sec"), date->tm_sec);
-    _set_integer_slot(v, _SC("min"), date->tm_min);
-    _set_integer_slot(v, _SC("hour"), date->tm_hour);
-    _set_integer_slot(v, _SC("day"), date->tm_mday);
-    _set_integer_slot(v, _SC("month"), date->tm_mon);
-    _set_integer_slot(v, _SC("year"), date->tm_year+1900);
-    _set_integer_slot(v, _SC("wday"), date->tm_wday);
-    _set_integer_slot(v, _SC("yday"), date->tm_yday);
-       return 1;
-}
-
-
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
-static SQRegFunction systemlib_funcs[]={
-       _DECL_FUNC(getenv,2,_SC(".s")),
-       _DECL_FUNC(system,2,_SC(".s")),
-       _DECL_FUNC(clock,1,NULL),
-       _DECL_FUNC(time,1,NULL),
-       _DECL_FUNC(date,-1,_SC(".nn")),
-       _DECL_FUNC(remove,2,_SC(".s")),
-       _DECL_FUNC(rename,3,_SC(".ss")),
-       {0,0}
-};
-
-
-int sqstd_register_systemlib(HSQUIRRELVM v)
-{
-       int i=0;
-       while(systemlib_funcs[i].name!=0)
-       {
-               sq_pushstring(v,systemlib_funcs[i].name,-1);
-               sq_newclosure(v,systemlib_funcs[i].f,0);
-               sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
-               sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
-               sq_createslot(v,-3);
-               i++;
-       }
-       return 1;
-}
+/* see copyright notice in squirrel.h */\r
+#include <squirrel.h>\r
+#include <time.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <sqstdsystem.h>\r
+\r
+#ifdef SQUNICODE\r
+#include <wchar.h>\r
+#define scgetenv _wgetenv\r
+#define scsystem _wsystem\r
+#define scasctime _wasctime\r
+#define scremove _wremove\r
+#define screname _wrename\r
+#else\r
+#define scgetenv getenv\r
+#define scsystem system\r
+#define scasctime asctime\r
+#define scremove remove\r
+#define screname rename\r
+#endif\r
+\r
+static SQInteger _system_getenv(HSQUIRRELVM v)\r
+{\r
+       const SQChar *s;\r
+       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){\r
+        sq_pushstring(v,scgetenv(s),-1);\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+\r
+static SQInteger _system_system(HSQUIRRELVM v)\r
+{\r
+       const SQChar *s;\r
+       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){\r
+               sq_pushinteger(v,scsystem(s));\r
+               return 1;\r
+       }\r
+       return sq_throwerror(v,_SC("wrong param"));\r
+}\r
+\r
+\r
+static SQInteger _system_clock(HSQUIRRELVM v)\r
+{\r
+       sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);\r
+       return 1;\r
+}\r
+\r
+static SQInteger _system_time(HSQUIRRELVM v)\r
+{\r
+       time_t t;\r
+       time(&t);\r
+       sq_pushinteger(v,*((SQInteger *)&t));\r
+       return 1;\r
+}\r
+\r
+static SQInteger _system_remove(HSQUIRRELVM v)\r
+{\r
+       const SQChar *s;\r
+       sq_getstring(v,2,&s);\r
+       if(scremove(s)==-1)\r
+               return sq_throwerror(v,_SC("remove() failed"));\r
+       return 0;\r
+}\r
+\r
+static SQInteger _system_rename(HSQUIRRELVM v)\r
+{\r
+       const SQChar *oldn,*newn;\r
+       sq_getstring(v,2,&oldn);\r
+       sq_getstring(v,3,&newn);\r
+       if(screname(oldn,newn)==-1)\r
+               return sq_throwerror(v,_SC("rename() failed"));\r
+       return 0;\r
+}\r
+\r
+static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)\r
+{\r
+       sq_pushstring(v,name,-1);\r
+       sq_pushinteger(v,val);\r
+       sq_rawset(v,-3);\r
+}\r
+\r
+static SQInteger _system_date(HSQUIRRELVM v)\r
+{\r
+       time_t t;\r
+       SQInteger format = 'l';\r
+       if(sq_gettop(v) > 1) {\r
+               sq_getinteger(v,2,(SQInteger*)&t);\r
+               if(sq_gettop(v) > 2) {\r
+                       sq_getinteger(v,3,(SQInteger*)&format);\r
+               }\r
+       }\r
+       else {\r
+               time(&t);\r
+       }\r
+       tm *date;\r
+    if(format == 'u')\r
+               date = gmtime(&t);\r
+       else\r
+               date = localtime(&t);\r
+       if(!date)\r
+               return sq_throwerror(v,_SC("crt api failure"));\r
+       sq_newtable(v);\r
+       _set_integer_slot(v, _SC("sec"), date->tm_sec);\r
+    _set_integer_slot(v, _SC("min"), date->tm_min);\r
+    _set_integer_slot(v, _SC("hour"), date->tm_hour);\r
+    _set_integer_slot(v, _SC("day"), date->tm_mday);\r
+    _set_integer_slot(v, _SC("month"), date->tm_mon);\r
+    _set_integer_slot(v, _SC("year"), date->tm_year+1900);\r
+    _set_integer_slot(v, _SC("wday"), date->tm_wday);\r
+    _set_integer_slot(v, _SC("yday"), date->tm_yday);\r
+       return 1;\r
+}\r
+\r
+\r
+\r
+#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}\r
+static SQRegFunction systemlib_funcs[]={\r
+       _DECL_FUNC(getenv,2,_SC(".s")),\r
+       _DECL_FUNC(system,2,_SC(".s")),\r
+       _DECL_FUNC(clock,1,NULL),\r
+       _DECL_FUNC(time,1,NULL),\r
+       _DECL_FUNC(date,-1,_SC(".nn")),\r
+       _DECL_FUNC(remove,2,_SC(".s")),\r
+       _DECL_FUNC(rename,3,_SC(".ss")),\r
+       {0,0}\r
+};\r
+\r
+\r
+SQInteger sqstd_register_systemlib(HSQUIRRELVM v)\r
+{\r
+       SQInteger i=0;\r
+       while(systemlib_funcs[i].name!=0)\r
+       {\r
+               sq_pushstring(v,systemlib_funcs[i].name,-1);\r
+               sq_newclosure(v,systemlib_funcs[i].f,0);\r
+               sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);\r
+               sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);\r
+               sq_createslot(v,-3);\r
+               i++;\r
+       }\r
+       return 1;\r
+}\r
index 1234d99..638280f 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "squserdata.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqclass.h"
-
-bool sq_aux_gettypedarg(HSQUIRRELVM v,int idx,SQObjectType type,SQObjectPtr **o)
-{
-       *o = &stack_get(v,idx);
-       if(type(**o) != type){
-               SQObjectPtr oval = v->PrintObjVal(**o);
-               v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
-               return false;
-       }
-       return true;
-}
-
-#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
-
-#define sq_aux_paramscheck(v,count) \
-{ \
-       if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
-}              
-
-int sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)
-{
-       v->_lasterror = e;
-       return SQ_ERROR;
-}
-
-int sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
-{
-       scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
-       return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
-}
-
-HSQUIRRELVM sq_open(int initialstacksize)
-{
-       SQSharedState *ss;
-       SQVM *v;
-       sq_new(ss, SQSharedState);
-       ss->Init();
-       v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
-       new (v) SQVM(ss);
-       ss->_root_vm = v;
-       if(v->Init(NULL, initialstacksize)) {
-               return v;
-       } else {
-               sq_delete(v, SQVM);
-               return NULL;
-       }
-       return v;
-}
-
-HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, int initialstacksize)
-{
-       SQSharedState *ss;
-       SQVM *v;
-       ss=_ss(friendvm);
-       
-       v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
-       new (v) SQVM(ss);
-       
-       if(v->Init(friendvm, initialstacksize)) {
-               friendvm->Push(v);
-               return v;
-       } else {
-               sq_delete(v, SQVM);
-               return NULL;
-       }
-}
-
-int sq_getvmstate(HSQUIRRELVM v)
-{
-       if(v->_suspended)
-               return SQ_VMSTATE_SUSPENDED;
-       else { 
-               if(v->_callsstack.size() != 0) return SQ_VMSTATE_RUNNING;
-               else return SQ_VMSTATE_IDLE;
-       }
-}
-
-void sq_seterrorhandler(HSQUIRRELVM v)
-{
-       SQObject o = stack_get(v, -1);
-       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
-               v->_errorhandler = o;
-               v->Pop();
-       }
-}
-
-void sq_setdebughook(HSQUIRRELVM v)
-{
-       SQObject o = stack_get(v,-1);
-       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
-               v->_debughook = o;
-               v->Pop();
-       }
-}
-
-void sq_close(HSQUIRRELVM v)
-{
-       SQSharedState *ss = _ss(v);
-       _thread(ss->_root_vm)->Finalize();
-       sq_delete(ss, SQSharedState);
-}
-
-SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
-{
-       SQObjectPtr o;
-       if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
-               v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
-               return SQ_OK;
-       }
-       return SQ_ERROR;
-}
-
-void sq_enabledebuginfo(HSQUIRRELVM v, SQBool debuginfo)
-{
-       _ss(v)->_debuginfo = debuginfo?true:false;
-}
-
-void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
-{
-       SQObjectPtr refs;
-       if(!ISREFCOUNTED(type(*po))) return;
-       if(_table(_ss(v)->_refs_table)->Get(*po, refs)) {
-               refs = _integer(refs) + 1;
-       }
-       else{
-               refs = 1;
-       }
-       _table(_ss(v)->_refs_table)->NewSlot(*po, refs);
-}
-
-SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
-{
-       SQObjectPtr refs;
-       if(!ISREFCOUNTED(type(*po))) return SQTrue;
-       if(_table(_ss(v)->_refs_table)->Get(*po, refs)) {
-               int n = _integer(refs) - 1;
-               if(n <= 0) {
-                       _table(_ss(v)->_refs_table)->Remove(*po);
-                       sq_resetobject(po);
-               }
-               else {
-                       refs = n;_table(_ss(v)->_refs_table)->Set(*po, refs);
-                       return SQFalse;
-               }
-       }
-       return SQTrue;
-}
-
-const SQChar *sq_objtostring(HSQOBJECT *o) 
-{
-       if(sq_type(*o) == OT_STRING) {
-               return o->_unVal.pString->_val;
-       }
-       return NULL;
-}
-
-SQInteger sq_objtointeger(HSQOBJECT *o) 
-{
-       if(sq_isnumeric(*o)) {
-               return tointeger(*o);
-       }
-       return 0;
-}
-
-SQFloat sq_objtofloat(HSQOBJECT *o) 
-{
-       if(sq_isnumeric(*o)) {
-               return tofloat(*o);
-       }
-       return 0;
-}
-
-void sq_pushnull(HSQUIRRELVM v)
-{
-       v->Push(_null_);
-}
-
-void sq_pushstring(HSQUIRRELVM v,const SQChar *s,int len)
-{
-       if(s)
-               v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
-       else v->Push(_null_);
-}
-
-void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
-{
-       v->Push(n);
-}
-
-void sq_pushbool(HSQUIRRELVM v,SQBool b)
-{
-       v->Push(b?true:false);
-}
-
-void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
-{
-       v->Push(n);
-}
-
-void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
-{
-       v->Push(p);
-}
-
-SQUserPointer sq_newuserdata(HSQUIRRELVM v,unsigned int size)
-{
-       SQUserData *ud = SQUserData::Create(_ss(v), size);
-       v->Push(ud);
-       return ud->_val;
-}
-
-void sq_newtable(HSQUIRRELVM v)
-{
-       v->Push(SQTable::Create(_ss(v), 0));    
-}
-
-void sq_newarray(HSQUIRRELVM v,int size)
-{
-       v->Push(SQArray::Create(_ss(v), size)); 
-}
-
-SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
-{
-       SQClass *baseclass = NULL;
-       if(hasbase) {
-               SQObjectPtr &base = stack_get(v,-1);
-               if(type(base) != OT_CLASS)
-                       return sq_throwerror(v,_SC("invalid base type"));
-               baseclass = _class(base);
-       }
-       SQClass *newclass = SQClass::Create(_ss(v), baseclass);
-       if(baseclass) v->Pop();
-       v->Push(newclass);      
-       return SQ_OK;
-}
-
-int sq_instanceof(HSQUIRRELVM v)
-{
-       SQObjectPtr &inst = stack_get(v,-1);
-       SQObjectPtr &cl = stack_get(v,-2);
-       if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
-               return sq_throwerror(v,_SC("invalid param type"));
-       return _instance(inst)->InstanceOf(_class(cl))?1:0;
-}
-
-SQRESULT sq_arrayappend(HSQUIRRELVM v,int idx)
-{
-       sq_aux_paramscheck(v,2);
-       SQObjectPtr *arr;
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
-       _array(*arr)->Append(v->GetUp(-1));
-       v->Pop(1);
-       return SQ_OK;
-}
-
-SQRESULT sq_arraypop(HSQUIRRELVM v,int idx,SQBool pushval)
-{
-       sq_aux_paramscheck(v, 1);
-       SQObjectPtr *arr;
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
-       if(_array(*arr)->Size() > 0) {
-        if(pushval != 0){ v->Push(_array(*arr)->Top()); }
-               _array(*arr)->Pop();
-               return SQ_OK;
-       }
-       return sq_throwerror(v, _SC("empty array"));
-}
-
-SQRESULT sq_arrayresize(HSQUIRRELVM v,int idx,int newsize)
-{
-       sq_aux_paramscheck(v,1);
-       SQObjectPtr *arr;
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
-       if(_array(*arr)->Size() > 0) {
-               _array(*arr)->Resize(newsize);
-               return SQ_OK;
-       }
-       return sq_throwerror(v, _SC("empty array"));
-}
-
-SQRESULT sq_arrayreverse(HSQUIRRELVM v,int idx)
-{
-       sq_aux_paramscheck(v, 1);
-       SQObjectPtr *o;
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
-       SQArray *arr = _array(*o);
-       if(arr->Size() > 0) {
-               SQObjectPtr t;
-               int size = arr->Size();
-               int n = size >> 1; size -= 1;
-               for(int i = 0; i < n; i++) {
-                       t = arr->_values[i];
-                       arr->_values[i] = arr->_values[size-i];
-                       arr->_values[size-i] = t;
-               }
-               return SQ_OK;
-       }
-       return sq_throwerror(v, _SC("empty array"));
-}
-
-void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,unsigned int nfreevars)
-{
-       SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);
-       nc->_nparamscheck = 0;
-       for(unsigned int i = 0; i < nfreevars; i++) {
-               nc->_outervalues.push_back(v->Top());
-               v->Pop();
-       }
-       v->Push(SQObjectPtr(nc));       
-}
-
-SQRESULT sq_getclosureinfo(HSQUIRRELVM v,int idx,unsigned int *nparams,unsigned int *nfreevars)
-{
-       SQObject o = stack_get(v, idx);
-       if(sq_isclosure(o)) {
-               SQClosure *c = _closure(o);
-               SQFunctionProto *proto = _funcproto(c->_function);
-               *nparams = (unsigned int)proto->_parameters.size();
-        *nfreevars = (unsigned int)c->_outervalues.size();
-               return SQ_OK;
-       }
-       return sq_throwerror(v,_SC("the object is not a closure"));
-}
-
-SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,int idx,const SQChar *name)
-{
-       SQObject o = stack_get(v, idx);
-       if(sq_isnativeclosure(o)) {
-               SQNativeClosure *nc = _nativeclosure(o);
-               nc->_name = SQString::Create(_ss(v),name);
-               return SQ_OK;
-       }
-       return sq_throwerror(v,_SC("the object is not a nativeclosure"));
-}
-
-SQRESULT sq_setparamscheck(HSQUIRRELVM v,int nparamscheck,const SQChar *typemask)
-{
-       SQObject o = stack_get(v, -1);
-       if(!sq_isnativeclosure(o))
-               return sq_throwerror(v, _SC("native closure expected"));
-       SQNativeClosure *nc = _nativeclosure(o);
-       nc->_nparamscheck = nparamscheck;
-       if(typemask) {
-               SQIntVec res;
-               if(!CompileTypemask(res, typemask))
-                       return sq_throwerror(v, _SC("invalid typemask"));
-               nc->_typecheck.copy(res);
-       }
-       else {
-               nc->_typecheck.resize(0);
-       }
-       if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
-               nc->_nparamscheck = nc->_typecheck.size();
-       }
-       return SQ_OK;
-}
-
-void sq_pushroottable(HSQUIRRELVM v)
-{
-       v->Push(v->_roottable);
-}
-
-void sq_pushregistrytable(HSQUIRRELVM v)
-{
-       v->Push(_ss(v)->_registry);
-}
-
-SQRESULT sq_setroottable(HSQUIRRELVM v)
-{
-       SQObject o = stack_get(v, -1);
-       if(sq_istable(o) || sq_isnull(o)) {
-               v->_roottable = o;
-               v->Pop();
-               return SQ_OK;
-       }
-       return sq_throwerror(v, _SC("ivalid type"));
-}
-
-void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
-{
-       v->_foreignptr = p;
-}
-
-SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
-{
-       return v->_foreignptr;
-}
-
-void sq_push(HSQUIRRELVM v,int idx)
-{
-       v->Push(stack_get(v, idx));
-}
-
-SQObjectType sq_gettype(HSQUIRRELVM v,int idx)
-{
-       return type(stack_get(v, idx));
-}
-
-SQRESULT sq_getinteger(HSQUIRRELVM v,int idx,SQInteger *i)
-{
-       SQObjectPtr &o = stack_get(v, idx);
-       if(sq_isnumeric(o)) {
-               *i = tointeger(o);
-               return SQ_OK;
-       }
-       return SQ_ERROR;
-}
-
-SQRESULT sq_getfloat(HSQUIRRELVM v,int idx,SQFloat *f)
-{
-       SQObjectPtr &o = stack_get(v, idx);
-       if(sq_isnumeric(o)) {
-               *f = tofloat(o);
-               return SQ_OK;
-       }
-       return SQ_ERROR;
-}
-
-SQRESULT sq_getbool(HSQUIRRELVM v,int idx,SQBool *b)
-{
-       SQObjectPtr &o = stack_get(v, idx);
-       if(sq_isbool(o)) {
-               *b = _integer(o);
-               return SQ_OK;
-       }
-       return SQ_ERROR;
-}
-
-SQRESULT sq_getstring(HSQUIRRELVM v,int idx,const SQChar **c)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_STRING,o);
-       *c = _stringval(*o);
-       return SQ_OK;
-}
-
-SQRESULT sq_getthread(HSQUIRRELVM v,int idx,HSQUIRRELVM *thread)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_THREAD,o);
-       *thread = _thread(*o);
-       return SQ_OK;
-}
-
-SQRESULT sq_clone(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr &o = stack_get(v,idx);
-       v->Push(_null_);
-       if(!v->Clone(o, stack_get(v, -1))){
-               v->Pop();
-               return sq_aux_invalidtype(v, type(o));
-       }
-       return SQ_OK;
-}
-
-SQInteger sq_getsize(HSQUIRRELVM v, int idx)
-{
-       SQObjectPtr &o = stack_get(v, idx);
-       SQObjectType type = type(o);
-       switch(type) {
-       case OT_STRING:         return _string(o)->_len;
-       case OT_TABLE:          return _table(o)->CountUsed();
-       case OT_ARRAY:          return _array(o)->Size();
-       case OT_USERDATA:       return _userdata(o)->_size;
-       default:
-               return sq_aux_invalidtype(v, type);
-       }
-}
-
-SQRESULT sq_getuserdata(HSQUIRRELVM v,int idx,SQUserPointer *p,unsigned int *typetag)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
-       (*p) = _userdataval(*o);
-       if(typetag) *typetag = _userdata(*o)->_typetag;
-       return SQ_OK;
-}
-
-SQRESULT sq_settypetag(HSQUIRRELVM v,int idx,unsigned int typetag)
-{
-       SQObjectPtr &o = stack_get(v,idx);
-       switch(type(o)) {
-               case OT_USERDATA:       _userdata(o)->_typetag = typetag;       break;
-               case OT_CLASS:          _class(o)->_typetag = typetag;          break;
-               default:                        return sq_throwerror(v,_SC("invalid object type"));
-       }
-       return SQ_OK;
-}
-
-SQRESULT sq_gettypetag(HSQUIRRELVM v,int idx,unsigned int *typetag)
-{
-       SQObjectPtr &o = stack_get(v,idx);
-       switch(type(o)) {
-               case OT_USERDATA:       *typetag = _userdata(o)->_typetag;      break;
-               case OT_CLASS:          *typetag = _class(o)->_typetag;         break;
-               default:                        return sq_throwerror(v,_SC("invalid object type"));
-       }
-       return SQ_OK;
-}
-
-SQRESULT sq_getuserpointer(HSQUIRRELVM v, int idx, SQUserPointer *p)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
-       (*p) = _userpointer(*o);
-       return SQ_OK;
-}
-
-SQRESULT sq_setinstanceup(HSQUIRRELVM v, int idx, SQUserPointer p)
-{
-       SQObjectPtr &o = stack_get(v,idx);
-       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
-       _instance(o)->_userpointer = p;
-       return SQ_OK;
-}
-
-SQRESULT sq_getinstanceup(HSQUIRRELVM v, int idx, SQUserPointer *p,unsigned int typetag)
-{
-       SQObjectPtr &o = stack_get(v,idx);
-       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
-       (*p) = _instance(o)->_userpointer;
-       if(typetag != 0) {
-               SQClass *cl = _instance(o)->_class;
-               do{
-                       if(cl->_typetag == typetag)
-                               return SQ_OK;
-                       cl = cl->_base;
-               }while(cl != NULL);
-               return sq_throwerror(v,_SC("invalid type tag"));
-       }
-       return SQ_OK;
-}
-
-int sq_gettop(HSQUIRRELVM v)
-{
-       return (v->_top) - v->_stackbase;
-}
-
-void sq_settop(HSQUIRRELVM v, int newtop)
-{
-       int top = sq_gettop(v);
-       if(top > newtop)
-               sq_pop(v, top - newtop);
-       else
-               while(top < newtop) sq_pushnull(v);
-}
-
-void sq_pop(HSQUIRRELVM v, int nelemstopop)
-{
-       assert(v->_top >= nelemstopop);
-       v->Pop(nelemstopop);
-}
-
-void sq_remove(HSQUIRRELVM v, int idx)
-{
-       v->Remove(idx);
-}
-
-int sq_cmp(HSQUIRRELVM v)
-{
-       int res;
-       v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
-       return res;
-}
-
-SQRESULT sq_createslot(HSQUIRRELVM v, int 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,int idx,SQBool pushval)
-{
-       sq_aux_paramscheck(v, 2);
-       SQObjectPtr *self;
-       _GETSAFE_OBJ(v, idx, OT_TABLE,self);
-       SQObjectPtr &key = v->GetUp(-1);
-       if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
-       SQObjectPtr res;
-       if(!v->DeleteSlot(*self, key, res)){
-               return SQ_ERROR;
-       }
-       if(pushval)     v->GetUp(-1) = res;
-       else v->Pop(1);
-       return SQ_OK;
-}
-
-SQRESULT sq_set(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr &self = stack_get(v, idx);
-       if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
-               v->Pop(2);
-               return SQ_OK;
-       }
-       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_rawset(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr &self = stack_get(v, idx);
-       if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
-       switch(type(self)) {
-       case OT_TABLE:
-               _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
-               v->Pop(2);
-               return SQ_OK;
-       break;
-       case OT_CLASS:
-               _class(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
-               v->Pop(2);
-               return SQ_OK;
-       break;
-       case OT_INSTANCE:
-               if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
-                       v->Pop(2);
-                       return SQ_OK;
-               }
-       break;
-       case OT_ARRAY:
-               if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
-                       v->Pop(2);
-                       return SQ_OK;
-               }
-       break;
-       default:
-               v->Pop(2);
-               return sq_throwerror(v, _SC("rawset works only on arrays,tables,calsses and instances"));
-       }
-       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_setdelegate(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr &self = stack_get(v, idx);
-       SQObjectPtr &mt = v->GetUp(-1);
-       SQObjectType type = type(self);
-       switch(type) {
-       case OT_TABLE:
-               if(type(mt) == OT_TABLE) {
-                       if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
-               else if(type(mt)==OT_NULL) {
-                       _table(self)->SetDelegate(NULL); v->Pop(); }
-               else return sq_aux_invalidtype(v,type);
-               break;
-       case OT_USERDATA:
-               if(type(mt)==OT_TABLE) {
-                       _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
-               else if(type(mt)==OT_NULL) {
-                       _userdata(self)->SetDelegate(NULL); v->Pop(); }
-               else return sq_aux_invalidtype(v, type);
-               break;
-       default:
-                       return sq_aux_invalidtype(v, type);
-               break;
-       }
-       return SQ_OK;
-}
-
-SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,int idx,SQBool pushval)
-{
-       sq_aux_paramscheck(v, 2);
-       SQObjectPtr *self;
-       _GETSAFE_OBJ(v, idx, OT_TABLE,self);
-       SQObjectPtr &key = v->GetUp(-1);
-       SQObjectPtr t;
-       if(_table(*self)->Get(key,t)) {
-               _table(*self)->Remove(key);
-       }
-       if(pushval != 0)
-               if(pushval)     v->GetUp(-1) = t;
-       else
-               v->Pop(1);
-       return SQ_OK;
-}
-
-SQRESULT sq_getdelegate(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr &self=stack_get(v,idx);
-       switch(type(self)){
-       case OT_TABLE:
-               if(!_table(self)->_delegate)break;
-               v->Push(SQObjectPtr(_table(self)->_delegate));
-               return SQ_OK;
-               break;
-       case OT_USERDATA:
-               if(!_userdata(self)->_delegate)break;
-               v->Push(SQObjectPtr(_userdata(self)->_delegate));
-               return SQ_OK;
-               break;
-       }
-       return sq_throwerror(v,_SC("wrong type"));
-}
-
-SQRESULT sq_get(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr &self=stack_get(v,idx);
-       if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
-               return SQ_OK;
-       v->Pop(1);
-       return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_rawget(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr &self=stack_get(v,idx);
-       switch(type(self)) {
-       case OT_TABLE:
-               if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
-                       return SQ_OK;
-               break;
-       case OT_CLASS:
-               if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
-                       return SQ_OK;
-               break;
-       case OT_INSTANCE:
-               if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
-                       return SQ_OK;
-               break;
-       case OT_ARRAY:
-               if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
-                       return SQ_OK;
-               break;
-       default:
-               v->Pop(1);
-               return sq_throwerror(v,_SC("rawget works only on arrays and tables"));
-       }       
-       v->Pop(1);
-       return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_getstackobj(HSQUIRRELVM v,int idx,HSQOBJECT *po)
-{
-       *po=stack_get(v,idx);
-       return SQ_OK;
-}
-
-const SQChar *sq_getlocal(HSQUIRRELVM v,unsigned int level,unsigned int idx)
-{
-       unsigned int cstksize=v->_callsstack.size();
-       unsigned int lvl=(cstksize-level)-1;
-       int stackbase=v->_stackbase;
-       if(lvl<cstksize){
-               for(unsigned int i=0;i<level;i++){
-                       SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
-                       stackbase-=ci._prevstkbase;
-               }
-               SQVM::CallInfo &ci=v->_callsstack[lvl];
-               if(type(ci._closure)!=OT_CLOSURE)
-                       return NULL;
-               SQClosure *c=_closure(ci._closure);
-               SQFunctionProto *func=_funcproto(c->_function);
-               return func->GetLocal(v,stackbase,idx,(ci._ip-func->_instructions._vals)-1);
-       }
-       return NULL;
-}
-
-void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
-{
-       v->Push(SQObjectPtr(obj));
-}
-
-void sq_resetobject(HSQOBJECT *po)
-{
-       po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
-}
-
-SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
-{
-       v->_lasterror=SQString::Create(_ss(v),err);
-       return -1;
-}
-
-void sq_reseterror(HSQUIRRELVM v)
-{
-       v->_lasterror = _null_;
-}
-
-void sq_getlasterror(HSQUIRRELVM v)
-{
-       v->Push(v->_lasterror);
-}
-
-void sq_reservestack(HSQUIRRELVM v,int nsize)
-{
-       if (((unsigned int)v->_top + nsize) > v->_stack.size()) {
-               v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
-       }
-}
-
-SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval)
-{
-       if(type(v->GetUp(-1))==OT_GENERATOR){
-               v->Push(_null_); //retval
-               if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),SQVM::ET_RESUME_GENERATOR))
-               {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
-               if(!retval)
-                       v->Pop();
-               return SQ_OK;
-       }
-       return sq_throwerror(v,_SC("only generators can be resumed"));
-}
-
-SQRESULT sq_call(HSQUIRRELVM v,int params,SQBool retval)
-{
-       SQObjectPtr res;
-       if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res)){
-               v->Pop(params);//pop closure and args
-               if(retval){
-                       v->Push(res); return SQ_OK;
-               }
-               return SQ_OK;
-       }
-       else {
-               v->Pop(params);
-               return SQ_ERROR;
-       }
-       if(!v->_suspended)
-               v->Pop(params);
-       return sq_throwerror(v,_SC("call failed"));
-}
-
-SQRESULT sq_suspendvm(HSQUIRRELVM v)
-{
-       return v->Suspend();
-}
-
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval)
-{
-       SQObjectPtr ret;
-       if(!v->_suspended)
-               return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
-       if(wakeupret) {
-               v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
-               v->Pop();
-       } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
-       if(!v->Execute(_null_,v->_top,-1,-1,ret,SQVM::ET_RESUME_VM))
-               return SQ_ERROR;
-       if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {
-               while (v->_top > 1) v->_stack[--v->_top] = _null_;
-       }
-       if(retval)
-               v->Push(ret);
-       return SQ_OK;
-}
-
-void sq_setreleasehook(HSQUIRRELVM v,int idx,SQRELEASEHOOK hook)
-{
-       if(sq_gettop(v) >= 1){
-               SQObjectPtr &ud=stack_get(v,idx);
-               switch( type(ud) ) {
-               case OT_USERDATA:
-                       _userdata(ud)->_hook = hook;
-                       break;
-               case OT_INSTANCE:
-                       _instance(ud)->_hook = hook;
-                       break;
-               }
-       }
-}
-
-void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
-{
-       _ss(v)->_compilererrorhandler = f;
-}
-
-SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
-       SQClosure *c=_closure(*o);
-       unsigned short tag = SQ_BYTECODE_STREAM_TAG;
-       if(w(up,&tag,2) != 2)
-               return sq_throwerror(v,_SC("io error"));
-       if(!_closure(*o)->Save(v,up,w))
-               return SQ_ERROR;
-       return SQ_OK;
-}
-
-SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
-{
-       SQObjectPtr func=SQFunctionProto::Create();
-       SQObjectPtr closure=SQClosure::Create(_ss(v),_funcproto(func));
-       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))
-               return SQ_ERROR;
-       v->Push(closure);
-       return SQ_OK;
-}
-
-SQChar *sq_getscratchpad(HSQUIRRELVM v,int minsize)
-{
-       return _ss(v)->GetScratchPad(minsize);
-}
-
-int sq_collectgarbage(HSQUIRRELVM v)
-{
-#ifndef NO_GARBAGE_COLLECTOR
-       return _ss(v)->CollectGarbage(v);
-#else
-       return -1;
-#endif
-}
-
-SQRESULT sq_setfreevariable(HSQUIRRELVM v,int idx,unsigned int nval)
-{
-       SQObjectPtr &self=stack_get(v,idx);
-       switch(type(self))
-       {
-       case OT_CLOSURE:
-               if(_closure(self)->_outervalues.size()>nval){
-                       _closure(self)->_outervalues[nval]=stack_get(v,-1);
-               }
-               else return sq_throwerror(v,_SC("invalid free var index"));
-               break;
-       case OT_NATIVECLOSURE:
-               if(_nativeclosure(self)->_outervalues.size()>nval){
-                       _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
-               }
-               else return sq_throwerror(v,_SC("invalid free var index"));
-               break;
-       default:
-               return sq_aux_invalidtype(v,type(self));
-       }
-       v->Pop(1);
-       return SQ_OK;
-}
-
-SQRESULT sq_setattributes(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_CLASS,o);
-       SQObjectPtr &key = stack_get(v,-2);
-       SQObjectPtr &val = stack_get(v,-1);
-       SQObjectPtr attrs;
-       if(type(key) == OT_NULL) {
-               attrs = _class(*o)->_attributes;
-               _class(*o)->_attributes = val;
-               v->Pop(2);
-               v->Push(attrs);
-               return SQ_OK;
-       }else if(_class(*o)->GetAttributes(key,attrs)) {
-               _class(*o)->SetAttributes(key,val);
-               v->Pop(2);
-               v->Push(attrs);
-               return SQ_OK;
-       }
-       return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getattributes(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_CLASS,o);
-       SQObjectPtr &key = stack_get(v,-1);
-       SQObjectPtr attrs;
-       if(type(key) == OT_NULL) {
-               attrs = _class(*o)->_attributes;
-               v->Pop();
-               v->Push(attrs);
-               return SQ_OK;
-       }
-       else if(_class(*o)->GetAttributes(key,attrs)) {
-               v->Pop();
-               v->Push(attrs);
-               return SQ_OK;
-       }
-       return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getclass(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
-       v->Push(SQObjectPtr(_instance(*o)->_class));
-       return SQ_OK;
-}
-
-SQRESULT sq_createinstance(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr *o = NULL;
-       _GETSAFE_OBJ(v, idx, OT_CLASS,o);
-       v->Push(_class(*o)->CreateInstance());
-       return SQ_OK;
-}
-
-SQRESULT sq_next(HSQUIRRELVM v,int idx)
-{
-       SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
-       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))
-               return SQ_ERROR;
-       if(!finished) {
-               v->Push(realkey);
-               v->Push(val);
-               return SQ_OK;
-       }
-       return SQ_ERROR;
-}
-
-struct BufState{
-       const SQChar *buf;
-       int ptr;
-       int size;
-};
-
-SQInteger buf_lexfeed(SQUserPointer file)
-{
-       BufState *buf=(BufState*)file;
-       if(buf->size<(buf->ptr+1))
-               return 0;
-       return buf->buf[buf->ptr++];
-}
-
-SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,int size,const SQChar *sourcename,SQBool raiseerror) {
-       BufState buf;
-       buf.buf = s;
-       buf.size = size;
-       buf.ptr = 0;
-       return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
-}
-
-void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,int idx)
-{
-       dest->Push(stack_get(src,idx));
-}
-
-void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)
-{
-       _ss(v)->_printfunc = printfunc;
-}
-
-SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
-{
-       return _ss(v)->_printfunc;
-}
-
-void *sq_malloc(unsigned int size)
-{
-       return SQ_MALLOC(size);
-}
-
-void *sq_realloc(void* p,unsigned int oldsize,unsigned int newsize)
-{
-       return SQ_REALLOC(p,oldsize,newsize);
-}
-void sq_free(void *p,unsigned int size)
-{
-       SQ_FREE(p,size);
-}
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include "sqvm.h"\r
+#include "sqstring.h"\r
+#include "sqtable.h"\r
+#include "sqarray.h"\r
+#include "sqfuncproto.h"\r
+#include "sqclosure.h"\r
+#include "squserdata.h"\r
+#include "sqcompiler.h"\r
+#include "sqfuncstate.h"\r
+#include "sqclass.h"\r
+\r
+bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)\r
+{\r
+       *o = &stack_get(v,idx);\r
+       if(type(**o) != type){\r
+               SQObjectPtr oval = v->PrintObjVal(**o);\r
+               v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }\r
+\r
+#define sq_aux_paramscheck(v,count) \\r
+{ \\r
+       if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\\r
+}              \r
+\r
+SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)\r
+{\r
+       v->_lasterror = e;\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)\r
+{\r
+       scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));\r
+       return sq_throwerror(v, _ss(v)->GetScratchPad(-1));\r
+}\r
+\r
+HSQUIRRELVM sq_open(SQInteger initialstacksize)\r
+{\r
+       SQSharedState *ss;\r
+       SQVM *v;\r
+       sq_new(ss, SQSharedState);\r
+       ss->Init();\r
+       v = (SQVM *)SQ_MALLOC(sizeof(SQVM));\r
+       new (v) SQVM(ss);\r
+       ss->_root_vm = v;\r
+       if(v->Init(NULL, initialstacksize)) {\r
+               return v;\r
+       } else {\r
+               sq_delete(v, SQVM);\r
+               return NULL;\r
+       }\r
+       return v;\r
+}\r
+\r
+HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)\r
+{\r
+       SQSharedState *ss;\r
+       SQVM *v;\r
+       ss=_ss(friendvm);\r
+       \r
+       v= (SQVM *)SQ_MALLOC(sizeof(SQVM));\r
+       new (v) SQVM(ss);\r
+       \r
+       if(v->Init(friendvm, initialstacksize)) {\r
+               friendvm->Push(v);\r
+               return v;\r
+       } else {\r
+               sq_delete(v, SQVM);\r
+               return NULL;\r
+       }\r
+}\r
+\r
+SQInteger sq_getvmstate(HSQUIRRELVM v)\r
+{\r
+       if(v->_suspended)\r
+               return SQ_VMSTATE_SUSPENDED;\r
+       else { \r
+               if(v->_callsstack.size() != 0) return SQ_VMSTATE_RUNNING;\r
+               else return SQ_VMSTATE_IDLE;\r
+       }\r
+}\r
+\r
+void sq_seterrorhandler(HSQUIRRELVM v)\r
+{\r
+       SQObject o = stack_get(v, -1);\r
+       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {\r
+               v->_errorhandler = o;\r
+               v->Pop();\r
+       }\r
+}\r
+\r
+void sq_setdebughook(HSQUIRRELVM v)\r
+{\r
+       SQObject o = stack_get(v,-1);\r
+       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {\r
+               v->_debughook = o;\r
+               v->Pop();\r
+       }\r
+}\r
+\r
+void sq_close(HSQUIRRELVM v)\r
+{\r
+       SQSharedState *ss = _ss(v);\r
+       _thread(ss->_root_vm)->Finalize();\r
+       sq_delete(ss, SQSharedState);\r
+}\r
+\r
+SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)\r
+{\r
+       SQObjectPtr o;\r
+       if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {\r
+               v->Push(SQClosure::Create(_ss(v), _funcproto(o)));\r
+               return SQ_OK;\r
+       }\r
+       return SQ_ERROR;\r
+}\r
+\r
+void sq_enabledebuginfo(HSQUIRRELVM v, SQBool debuginfo)\r
+{\r
+       _ss(v)->_debuginfo = debuginfo?true:false;\r
+}\r
+\r
+void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)\r
+{\r
+       SQObjectPtr refs;\r
+       if(!ISREFCOUNTED(type(*po))) return;\r
+       if(_table(_ss(v)->_refs_table)->Get(*po, refs)) {\r
+               refs = _integer(refs) + 1;\r
+       }\r
+       else{\r
+               refs = 1;\r
+       }\r
+       _table(_ss(v)->_refs_table)->NewSlot(*po, refs);\r
+}\r
+\r
+SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)\r
+{\r
+       SQObjectPtr refs;\r
+       if(!ISREFCOUNTED(type(*po))) return SQTrue;\r
+       if(_table(_ss(v)->_refs_table)->Get(*po, refs)) {\r
+               SQInteger n = _integer(refs) - 1;\r
+               if(n <= 0) {\r
+                       _table(_ss(v)->_refs_table)->Remove(*po);\r
+                       sq_resetobject(po);\r
+               }\r
+               else {\r
+                       refs = n;_table(_ss(v)->_refs_table)->Set(*po, refs);\r
+                       return SQFalse;\r
+               }\r
+       }\r
+       return SQTrue;\r
+}\r
+\r
+const SQChar *sq_objtostring(HSQOBJECT *o) \r
+{\r
+       if(sq_type(*o) == OT_STRING) {\r
+               return _stringval(*o);\r
+       }\r
+       return NULL;\r
+}\r
+\r
+SQInteger sq_objtointeger(HSQOBJECT *o) \r
+{\r
+       if(sq_isnumeric(*o)) {\r
+               return tointeger(*o);\r
+       }\r
+       return 0;\r
+}\r
+\r
+SQFloat sq_objtofloat(HSQOBJECT *o) \r
+{\r
+       if(sq_isnumeric(*o)) {\r
+               return tofloat(*o);\r
+       }\r
+       return 0;\r
+}\r
+\r
+SQBool sq_objtobool(HSQOBJECT *o) \r
+{\r
+       if(sq_isbool(*o)) {\r
+               return _integer(*o);\r
+       }\r
+       return SQFalse;\r
+}\r
+\r
+void sq_pushnull(HSQUIRRELVM v)\r
+{\r
+       v->Push(_null_);\r
+}\r
+\r
+void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)\r
+{\r
+       if(s)\r
+               v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));\r
+       else v->Push(_null_);\r
+}\r
+\r
+void sq_pushinteger(HSQUIRRELVM v,SQInteger n)\r
+{\r
+       v->Push(n);\r
+}\r
+\r
+void sq_pushbool(HSQUIRRELVM v,SQBool b)\r
+{\r
+       v->Push(b?true:false);\r
+}\r
+\r
+void sq_pushfloat(HSQUIRRELVM v,SQFloat n)\r
+{\r
+       v->Push(n);\r
+}\r
+\r
+void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)\r
+{\r
+       v->Push(p);\r
+}\r
+\r
+SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)\r
+{\r
+       SQUserData *ud = SQUserData::Create(_ss(v), size);\r
+       v->Push(ud);\r
+       return ud->_val;\r
+}\r
+\r
+void sq_newtable(HSQUIRRELVM v)\r
+{\r
+       v->Push(SQTable::Create(_ss(v), 0));    \r
+}\r
+\r
+void sq_newarray(HSQUIRRELVM v,SQInteger size)\r
+{\r
+       v->Push(SQArray::Create(_ss(v), size)); \r
+}\r
+\r
+SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)\r
+{\r
+       SQClass *baseclass = NULL;\r
+       if(hasbase) {\r
+               SQObjectPtr &base = stack_get(v,-1);\r
+               if(type(base) != OT_CLASS)\r
+                       return sq_throwerror(v,_SC("invalid base type"));\r
+               baseclass = _class(base);\r
+       }\r
+       SQClass *newclass = SQClass::Create(_ss(v), baseclass);\r
+       if(baseclass) v->Pop();\r
+       v->Push(newclass);      \r
+       return SQ_OK;\r
+}\r
+\r
+SQInteger sq_instanceof(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &inst = stack_get(v,-1);\r
+       SQObjectPtr &cl = stack_get(v,-2);\r
+       if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)\r
+               return sq_throwerror(v,_SC("invalid param type"));\r
+       return _instance(inst)->InstanceOf(_class(cl))?1:0;\r
+}\r
+\r
+SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       sq_aux_paramscheck(v,2);\r
+       SQObjectPtr *arr;\r
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);\r
+       _array(*arr)->Append(v->GetUp(-1));\r
+       v->Pop(1);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)\r
+{\r
+       sq_aux_paramscheck(v, 1);\r
+       SQObjectPtr *arr;\r
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);\r
+       if(_array(*arr)->Size() > 0) {\r
+        if(pushval != 0){ v->Push(_array(*arr)->Top()); }\r
+               _array(*arr)->Pop();\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v, _SC("empty array"));\r
+}\r
+\r
+SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)\r
+{\r
+       sq_aux_paramscheck(v,1);\r
+       SQObjectPtr *arr;\r
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);\r
+       if(_array(*arr)->Size() > 0) {\r
+               _array(*arr)->Resize(newsize);\r
+               return SQ_OK;\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       sq_aux_paramscheck(v, 1);\r
+       SQObjectPtr *o;\r
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,o);\r
+       SQArray *arr = _array(*o);\r
+       if(arr->Size() > 0) {\r
+               SQObjectPtr t;\r
+               SQInteger size = arr->Size();\r
+               SQInteger n = size >> 1; size -= 1;\r
+               for(SQInteger i = 0; i < n; i++) {\r
+                       t = arr->_values[i];\r
+                       arr->_values[i] = arr->_values[size-i];\r
+                       arr->_values[size-i] = t;\r
+               }\r
+               return SQ_OK;\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)\r
+{\r
+       SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);\r
+       nc->_nparamscheck = 0;\r
+       for(SQUnsignedInteger i = 0; i < nfreevars; i++) {\r
+               nc->_outervalues.push_back(v->Top());\r
+               v->Pop();\r
+       }\r
+       v->Push(SQObjectPtr(nc));       \r
+}\r
+\r
+SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)\r
+{\r
+       SQObject o = stack_get(v, idx);\r
+       if(sq_isclosure(o)) {\r
+               SQClosure *c = _closure(o);\r
+               SQFunctionProto *proto = _funcproto(c->_function);\r
+               *nparams = (SQUnsignedInteger)proto->_parameters.size();\r
+        *nfreevars = (SQUnsignedInteger)c->_outervalues.size();\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("the object is not a closure"));\r
+}\r
+\r
+SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)\r
+{\r
+       SQObject o = stack_get(v, idx);\r
+       if(sq_isnativeclosure(o)) {\r
+               SQNativeClosure *nc = _nativeclosure(o);\r
+               nc->_name = SQString::Create(_ss(v),name);\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("the object is not a nativeclosure"));\r
+}\r
+\r
+SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)\r
+{\r
+       SQObject o = stack_get(v, -1);\r
+       if(!sq_isnativeclosure(o))\r
+               return sq_throwerror(v, _SC("native closure expected"));\r
+       SQNativeClosure *nc = _nativeclosure(o);\r
+       nc->_nparamscheck = nparamscheck;\r
+       if(typemask) {\r
+               SQIntVec res;\r
+               if(!CompileTypemask(res, typemask))\r
+                       return sq_throwerror(v, _SC("invalid typemask"));\r
+               nc->_typecheck.copy(res);\r
+       }\r
+       else {\r
+               nc->_typecheck.resize(0);\r
+       }\r
+       if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {\r
+               nc->_nparamscheck = nc->_typecheck.size();\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+void sq_pushroottable(HSQUIRRELVM v)\r
+{\r
+       v->Push(v->_roottable);\r
+}\r
+\r
+void sq_pushregistrytable(HSQUIRRELVM v)\r
+{\r
+       v->Push(_ss(v)->_registry);\r
+}\r
+\r
+SQRESULT sq_setroottable(HSQUIRRELVM v)\r
+{\r
+       SQObject o = stack_get(v, -1);\r
+       if(sq_istable(o) || sq_isnull(o)) {\r
+               v->_roottable = o;\r
+               v->Pop();\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v, _SC("ivalid type"));\r
+}\r
+\r
+void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)\r
+{\r
+       v->_foreignptr = p;\r
+}\r
+\r
+SQUserPointer sq_getforeignptr(HSQUIRRELVM v)\r
+{\r
+       return v->_foreignptr;\r
+}\r
+\r
+void sq_push(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       v->Push(stack_get(v, idx));\r
+}\r
+\r
+SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       return type(stack_get(v, idx));\r
+}\r
+\r
+void sq_tostring(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &o = stack_get(v, idx);\r
+       SQObjectPtr res;\r
+       v->ToString(o,res);\r
+       v->Push(res);\r
+}\r
+\r
+SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)\r
+{\r
+       SQObjectPtr &o = stack_get(v, idx);\r
+       if(sq_isnumeric(o)) {\r
+               *i = tointeger(o);\r
+               return SQ_OK;\r
+       }\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)\r
+{\r
+       SQObjectPtr &o = stack_get(v, idx);\r
+       if(sq_isnumeric(o)) {\r
+               *f = tofloat(o);\r
+               return SQ_OK;\r
+       }\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)\r
+{\r
+       SQObjectPtr &o = stack_get(v, idx);\r
+       if(sq_isbool(o)) {\r
+               *b = _integer(o);\r
+               return SQ_OK;\r
+       }\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_STRING,o);\r
+       *c = _stringval(*o);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_THREAD,o);\r
+       *thread = _thread(*o);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &o = stack_get(v,idx);\r
+       v->Push(_null_);\r
+       if(!v->Clone(o, stack_get(v, -1))){\r
+               v->Pop();\r
+               return sq_aux_invalidtype(v, type(o));\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)\r
+{\r
+       SQObjectPtr &o = stack_get(v, idx);\r
+       SQObjectType type = type(o);\r
+       switch(type) {\r
+       case OT_STRING:         return _string(o)->_len;\r
+       case OT_TABLE:          return _table(o)->CountUsed();\r
+       case OT_ARRAY:          return _array(o)->Size();\r
+       case OT_USERDATA:       return _userdata(o)->_size;\r
+       default:\r
+               return sq_aux_invalidtype(v, type);\r
+       }\r
+}\r
+\r
+SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_USERDATA,o);\r
+       (*p) = _userdataval(*o);\r
+       if(typetag) *typetag = _userdata(*o)->_typetag;\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)\r
+{\r
+       SQObjectPtr &o = stack_get(v,idx);\r
+       switch(type(o)) {\r
+               case OT_USERDATA:       _userdata(o)->_typetag = typetag;       break;\r
+               case OT_CLASS:          _class(o)->_typetag = typetag;          break;\r
+               default:                        return sq_throwerror(v,_SC("invalid object type"));\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)\r
+{\r
+  switch(type(*o)) {\r
+    case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;\r
+    case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;\r
+    case OT_CLASS:    *typetag = _class(*o)->_typetag; break;\r
+    default: return SQ_ERROR;\r
+  }\r
+  return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)\r
+{\r
+       SQObjectPtr &o = stack_get(v,idx);\r
+       if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))\r
+               return sq_throwerror(v,_SC("invalid object type"));\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);\r
+       (*p) = _userpointer(*o);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)\r
+{\r
+       SQObjectPtr &o = stack_get(v,idx);\r
+       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));\r
+       _instance(o)->_userpointer = p;\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)\r
+{\r
+       SQObjectPtr &o = stack_get(v,idx);\r
+       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));\r
+       (*p) = _instance(o)->_userpointer;\r
+       if(typetag != 0) {\r
+               SQClass *cl = _instance(o)->_class;\r
+               do{\r
+                       if(cl->_typetag == typetag)\r
+                               return SQ_OK;\r
+                       cl = cl->_base;\r
+               }while(cl != NULL);\r
+               return sq_throwerror(v,_SC("invalid type tag"));\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+SQInteger sq_gettop(HSQUIRRELVM v)\r
+{\r
+       return (v->_top) - v->_stackbase;\r
+}\r
+\r
+void sq_settop(HSQUIRRELVM v, SQInteger newtop)\r
+{\r
+       SQInteger top = sq_gettop(v);\r
+       if(top > newtop)\r
+               sq_pop(v, top - newtop);\r
+       else\r
+               while(top < newtop) sq_pushnull(v);\r
+}\r
+\r
+void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)\r
+{\r
+       assert(v->_top >= nelemstopop);\r
+       v->Pop(nelemstopop);\r
+}\r
+\r
+void sq_poptop(HSQUIRRELVM v)\r
+{\r
+       assert(v->_top >= 1);\r
+    v->Pop();\r
+}\r
+\r
+\r
+void sq_remove(HSQUIRRELVM v, SQInteger idx)\r
+{\r
+       v->Remove(idx);\r
+}\r
+\r
+SQInteger sq_cmp(HSQUIRRELVM v)\r
+{\r
+       SQInteger res;\r
+       v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);\r
+       return res;\r
+}\r
+\r
+SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx)\r
+{\r
+       sq_aux_paramscheck(v, 3);\r
+       SQObjectPtr &self = stack_get(v, idx);\r
+       if(type(self) == OT_TABLE || type(self) == OT_CLASS) {\r
+               SQObjectPtr &key = v->GetUp(-2);\r
+               if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
+               v->NewSlot(self, key, v->GetUp(-1));\r
+               v->Pop(2);\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)\r
+{\r
+       sq_aux_paramscheck(v, 2);\r
+       SQObjectPtr *self;\r
+       _GETSAFE_OBJ(v, idx, OT_TABLE,self);\r
+       SQObjectPtr &key = v->GetUp(-1);\r
+       if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
+       SQObjectPtr res;\r
+       if(!v->DeleteSlot(*self, key, res)){\r
+               return SQ_ERROR;\r
+       }\r
+       if(pushval)     v->GetUp(-1) = res;\r
+       else v->Pop(1);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &self = stack_get(v, idx);\r
+       if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {\r
+               v->Pop(2);\r
+               return SQ_OK;\r
+       }\r
+       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;\r
+}\r
+\r
+SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &self = stack_get(v, idx);\r
+       if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));\r
+       switch(type(self)) {\r
+       case OT_TABLE:\r
+               _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));\r
+               v->Pop(2);\r
+               return SQ_OK;\r
+       break;\r
+       case OT_CLASS:\r
+               _class(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));\r
+               v->Pop(2);\r
+               return SQ_OK;\r
+       break;\r
+       case OT_INSTANCE:\r
+               if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {\r
+                       v->Pop(2);\r
+                       return SQ_OK;\r
+               }\r
+       break;\r
+       case OT_ARRAY:\r
+               if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {\r
+                       v->Pop(2);\r
+                       return SQ_OK;\r
+               }\r
+       break;\r
+       default:\r
+               v->Pop(2);\r
+               return sq_throwerror(v, _SC("rawset works only on array/table/calsse and instance"));\r
+       }\r
+       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;\r
+}\r
+\r
+SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &self = stack_get(v, idx);\r
+       SQObjectPtr &mt = v->GetUp(-1);\r
+       SQObjectType type = type(self);\r
+       switch(type) {\r
+       case OT_TABLE:\r
+               if(type(mt) == OT_TABLE) {\r
+                       if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}\r
+               else if(type(mt)==OT_NULL) {\r
+                       _table(self)->SetDelegate(NULL); v->Pop(); }\r
+               else return sq_aux_invalidtype(v,type);\r
+               break;\r
+       case OT_USERDATA:\r
+               if(type(mt)==OT_TABLE) {\r
+                       _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }\r
+               else if(type(mt)==OT_NULL) {\r
+                       _userdata(self)->SetDelegate(NULL); v->Pop(); }\r
+               else return sq_aux_invalidtype(v, type);\r
+               break;\r
+       default:\r
+                       return sq_aux_invalidtype(v, type);\r
+               break;\r
+       }\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)\r
+{\r
+       sq_aux_paramscheck(v, 2);\r
+       SQObjectPtr *self;\r
+       _GETSAFE_OBJ(v, idx, OT_TABLE,self);\r
+       SQObjectPtr &key = v->GetUp(-1);\r
+       SQObjectPtr t;\r
+       if(_table(*self)->Get(key,t)) {\r
+               _table(*self)->Remove(key);\r
+       }\r
+       if(pushval != 0)\r
+               if(pushval)     v->GetUp(-1) = t;\r
+       else\r
+               v->Pop(1);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &self=stack_get(v,idx);\r
+       switch(type(self)){\r
+       case OT_TABLE:\r
+               if(!_table(self)->_delegate)break;\r
+               v->Push(SQObjectPtr(_table(self)->_delegate));\r
+               return SQ_OK;\r
+               break;\r
+       case OT_USERDATA:\r
+               if(!_userdata(self)->_delegate)break;\r
+               v->Push(SQObjectPtr(_userdata(self)->_delegate));\r
+               return SQ_OK;\r
+               break;\r
+       }\r
+       return sq_throwerror(v,_SC("wrong type"));\r
+}\r
+\r
+SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &self=stack_get(v,idx);\r
+       if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))\r
+               return SQ_OK;\r
+       v->Pop(1);\r
+       return sq_throwerror(v,_SC("the index doesn't exist"));\r
+}\r
+\r
+SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &self=stack_get(v,idx);\r
+       switch(type(self)) {\r
+       case OT_TABLE:\r
+               if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))\r
+                       return SQ_OK;\r
+               break;\r
+       case OT_CLASS:\r
+               if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))\r
+                       return SQ_OK;\r
+               break;\r
+       case OT_INSTANCE:\r
+               if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))\r
+                       return SQ_OK;\r
+               break;\r
+       case OT_ARRAY:\r
+               if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))\r
+                       return SQ_OK;\r
+               break;\r
+       default:\r
+               v->Pop(1);\r
+               return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));\r
+       }       \r
+       v->Pop(1);\r
+       return sq_throwerror(v,_SC("the index doesn't exist"));\r
+}\r
+\r
+SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)\r
+{\r
+       *po=stack_get(v,idx);\r
+       return SQ_OK;\r
+}\r
+\r
+const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)\r
+{\r
+       SQUnsignedInteger cstksize=v->_callsstack.size();\r
+       SQUnsignedInteger lvl=(cstksize-level)-1;\r
+       SQInteger stackbase=v->_stackbase;\r
+       if(lvl<cstksize){\r
+               for(SQUnsignedInteger i=0;i<level;i++){\r
+                       SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];\r
+                       stackbase-=ci._prevstkbase;\r
+               }\r
+               SQVM::CallInfo &ci=v->_callsstack[lvl];\r
+               if(type(ci._closure)!=OT_CLOSURE)\r
+                       return NULL;\r
+               SQClosure *c=_closure(ci._closure);\r
+               SQFunctionProto *func=_funcproto(c->_function);\r
+               return func->GetLocal(v,stackbase,idx,(ci._ip-func->_instructions._vals)-1);\r
+       }\r
+       return NULL;\r
+}\r
+\r
+void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)\r
+{\r
+       v->Push(SQObjectPtr(obj));\r
+}\r
+\r
+void sq_resetobject(HSQOBJECT *po)\r
+{\r
+       po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;\r
+}\r
+\r
+SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)\r
+{\r
+       v->_lasterror=SQString::Create(_ss(v),err);\r
+       return -1;\r
+}\r
+\r
+void sq_reseterror(HSQUIRRELVM v)\r
+{\r
+       v->_lasterror = _null_;\r
+}\r
+\r
+void sq_getlasterror(HSQUIRRELVM v)\r
+{\r
+       v->Push(v->_lasterror);\r
+}\r
+\r
+void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)\r
+{\r
+       if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {\r
+               v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));\r
+       }\r
+}\r
+\r
+SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval)\r
+{\r
+       if(type(v->GetUp(-1))==OT_GENERATOR){\r
+               v->Push(_null_); //retval\r
+               if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),SQVM::ET_RESUME_GENERATOR))\r
+               {v->Raise_Error(v->_lasterror); return SQ_ERROR;}\r
+               if(!retval)\r
+                       v->Pop();\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("only generators can be resumed"));\r
+}\r
+\r
+SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval)\r
+{\r
+       SQObjectPtr res;\r
+       if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res)){\r
+               v->Pop(params);//pop closure and args\r
+               if(retval){\r
+                       v->Push(res); return SQ_OK;\r
+               }\r
+               return SQ_OK;\r
+       }\r
+       else {\r
+               v->Pop(params);\r
+               return SQ_ERROR;\r
+       }\r
+       if(!v->_suspended)\r
+               v->Pop(params);\r
+       return sq_throwerror(v,_SC("call failed"));\r
+}\r
+\r
+SQRESULT sq_suspendvm(HSQUIRRELVM v)\r
+{\r
+       return v->Suspend();\r
+}\r
+\r
+SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval)\r
+{\r
+       SQObjectPtr ret;\r
+       if(!v->_suspended)\r
+               return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));\r
+       if(wakeupret) {\r
+               v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval\r
+               v->Pop();\r
+       } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;\r
+       if(!v->Execute(_null_,v->_top,-1,-1,ret,SQVM::ET_RESUME_VM))\r
+               return SQ_ERROR;\r
+       if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {\r
+               while (v->_top > 1) v->_stack[--v->_top] = _null_;\r
+       }\r
+       if(retval)\r
+               v->Push(ret);\r
+       return SQ_OK;\r
+}\r
+\r
+void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)\r
+{\r
+       if(sq_gettop(v) >= 1){\r
+               SQObjectPtr &ud=stack_get(v,idx);\r
+               switch( type(ud) ) {\r
+               case OT_USERDATA:\r
+                       _userdata(ud)->_hook = hook;\r
+                       break;\r
+               case OT_INSTANCE:\r
+                       _instance(ud)->_hook = hook;\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)\r
+{\r
+       _ss(v)->_compilererrorhandler = f;\r
+}\r
+\r
+SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);\r
+       SQClosure *c=_closure(*o);\r
+       unsigned short tag = SQ_BYTECODE_STREAM_TAG;\r
+       if(w(up,&tag,2) != 2)\r
+               return sq_throwerror(v,_SC("io error"));\r
+       if(!_closure(*o)->Save(v,up,w))\r
+               return SQ_ERROR;\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)\r
+{\r
+       SQObjectPtr func=SQFunctionProto::Create();\r
+       SQObjectPtr closure=SQClosure::Create(_ss(v),_funcproto(func));\r
+       unsigned short tag;\r
+       if(r(up,&tag,2) != 2)\r
+               return sq_throwerror(v,_SC("io error"));\r
+       if(tag != SQ_BYTECODE_STREAM_TAG)\r
+               return sq_throwerror(v,_SC("invalid stream"));\r
+       if(!_closure(closure)->Load(v,up,r))\r
+               return SQ_ERROR;\r
+       v->Push(closure);\r
+       return SQ_OK;\r
+}\r
+\r
+SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)\r
+{\r
+       return _ss(v)->GetScratchPad(minsize);\r
+}\r
+\r
+SQInteger sq_collectgarbage(HSQUIRRELVM v)\r
+{\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       return _ss(v)->CollectGarbage(v);\r
+#else\r
+       return -1;\r
+#endif\r
+}\r
+\r
+const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)\r
+{\r
+       SQObjectPtr &self = stack_get(v,idx);\r
+       const SQChar *name = NULL;\r
+       if(type(self) == OT_CLOSURE) {\r
+               if(_closure(self)->_outervalues.size()>nval) {\r
+                       v->Push(_closure(self)->_outervalues[nval]);\r
+                       SQFunctionProto *fp = _funcproto(_closure(self)->_function);\r
+                       SQOuterVar &ov = fp->_outervalues[nval];\r
+                       name = _stringval(ov._name);\r
+               }\r
+       }\r
+       return name;\r
+}\r
+\r
+SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)\r
+{\r
+       SQObjectPtr &self=stack_get(v,idx);\r
+       switch(type(self))\r
+       {\r
+       case OT_CLOSURE:\r
+               if(_closure(self)->_outervalues.size()>nval){\r
+                       _closure(self)->_outervalues[nval]=stack_get(v,-1);\r
+               }\r
+               else return sq_throwerror(v,_SC("invalid free var index"));\r
+               break;\r
+       case OT_NATIVECLOSURE:\r
+               if(_nativeclosure(self)->_outervalues.size()>nval){\r
+                       _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);\r
+               }\r
+               else return sq_throwerror(v,_SC("invalid free var index"));\r
+               break;\r
+       default:\r
+               return sq_aux_invalidtype(v,type(self));\r
+       }\r
+       v->Pop(1);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
+       SQObjectPtr &key = stack_get(v,-2);\r
+       SQObjectPtr &val = stack_get(v,-1);\r
+       SQObjectPtr attrs;\r
+       if(type(key) == OT_NULL) {\r
+               attrs = _class(*o)->_attributes;\r
+               _class(*o)->_attributes = val;\r
+               v->Pop(2);\r
+               v->Push(attrs);\r
+               return SQ_OK;\r
+       }else if(_class(*o)->GetAttributes(key,attrs)) {\r
+               _class(*o)->SetAttributes(key,val);\r
+               v->Pop(2);\r
+               v->Push(attrs);\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("wrong index"));\r
+}\r
+\r
+SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
+       SQObjectPtr &key = stack_get(v,-1);\r
+       SQObjectPtr attrs;\r
+       if(type(key) == OT_NULL) {\r
+               attrs = _class(*o)->_attributes;\r
+               v->Pop();\r
+               v->Push(attrs);\r
+               return SQ_OK;\r
+       }\r
+       else if(_class(*o)->GetAttributes(key,attrs)) {\r
+               v->Pop();\r
+               v->Push(attrs);\r
+               return SQ_OK;\r
+       }\r
+       return sq_throwerror(v,_SC("wrong index"));\r
+}\r
+\r
+SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);\r
+       v->Push(SQObjectPtr(_instance(*o)->_class));\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr *o = NULL;\r
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
+       v->Push(_class(*o)->CreateInstance());\r
+       return SQ_OK;\r
+}\r
+\r
+void sq_weakref(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObject &o=stack_get(v,idx);\r
+       if(ISREFCOUNTED(type(o))) {\r
+               v->Push(_refcounted(o)->GetWeakRef(type(o)));\r
+               return;\r
+       }\r
+       v->Push(o);\r
+}\r
+\r
+SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr &o = stack_get(v,idx);\r
+       if(type(o) != OT_WEAKREF) {\r
+               return sq_throwerror(v,_SC("the object must be a weakref"));\r
+       }\r
+       v->Push(_weakref(o)->_obj);\r
+       return SQ_OK;\r
+}\r
+\r
+SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)\r
+{\r
+       SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;\r
+       if(type(o) == OT_GENERATOR) {\r
+               return sq_throwerror(v,_SC("cannot iterate a generator"));\r
+       }\r
+       bool finished;\r
+       if(!v->FOREACH_OP(o,realkey,val,refpos,0,finished))\r
+               return SQ_ERROR;\r
+       if(!finished) {\r
+               v->Push(realkey);\r
+               v->Push(val);\r
+               return SQ_OK;\r
+       }\r
+       return SQ_ERROR;\r
+}\r
+\r
+struct BufState{\r
+       const SQChar *buf;\r
+       SQInteger ptr;\r
+       SQInteger size;\r
+};\r
+\r
+SQInteger buf_lexfeed(SQUserPointer file)\r
+{\r
+       BufState *buf=(BufState*)file;\r
+       if(buf->size<(buf->ptr+1))\r
+               return 0;\r
+       return buf->buf[buf->ptr++];\r
+}\r
+\r
+SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {\r
+       BufState buf;\r
+       buf.buf = s;\r
+       buf.size = size;\r
+       buf.ptr = 0;\r
+       return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);\r
+}\r
+\r
+void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)\r
+{\r
+       dest->Push(stack_get(src,idx));\r
+}\r
+\r
+void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)\r
+{\r
+       _ss(v)->_printfunc = printfunc;\r
+}\r
+\r
+SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)\r
+{\r
+       return _ss(v)->_printfunc;\r
+}\r
+\r
+void *sq_malloc(SQUnsignedInteger size)\r
+{\r
+       return SQ_MALLOC(size);\r
+}\r
+\r
+void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)\r
+{\r
+       return SQ_REALLOC(p,oldsize,newsize);\r
+}\r
+void sq_free(void *p,SQUnsignedInteger size)\r
+{\r
+       SQ_FREE(p,size);\r
+}\r
index 7aadbd7..b463e81 100644 (file)
@@ -1,77 +1,79 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQARRAY_H_
-#define _SQARRAY_H_
-
-struct SQArray : public CHAINABLE_OBJ
-{
-private:
-       SQArray(SQSharedState *ss,int nsize){_values.resize(nsize);_uiRef=0;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-       ~SQArray()
-       {
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-       }
-public:
-       static SQArray* Create(SQSharedState *ss,int nInitialSize){
-               SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
-               new (newarray) SQArray(ss,nInitialSize);
-               return newarray;
-       }
-#ifndef NO_GARBAGE_COLLECTOR
-       void Mark(SQCollectable **chain);
-#endif
-       void Finalize(){
-               _values.resize(0);
-       }
-       bool Get(const int nidx,SQObjectPtr &val)
-       {
-               if(nidx>=0 && nidx<(int)_values.size()){
-                       val=_values[nidx];
-                       return true;
-               }
-               else return false;
-       }
-       bool Set(const int nidx,const SQObjectPtr &val)
-       {
-               if(nidx>=0 && nidx<(int)_values.size()){
-                       _values[nidx]=val;
-                       return true;
-               }
-               else return false;
-       }
-       int Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
-       {
-               unsigned int idx=TranslateIndex(refpos);
-               while(idx<_values.size()){
-                       //first found
-                       outkey=(SQInteger)idx;
-                       outval=_values[idx];
-                       //return idx for the next iteration
-                       return ++idx;
-               }
-               //nothing to iterate anymore
-               return -1;
-       }
-       SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }
-       int Size() const {return _values.size();}
-       void Resize(int size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }
-       void Reserve(int size) { _values.reserve(size); }
-       void Append(const SQObject &o){_values.push_back(o);}
-       void Extend(const SQArray *a);
-       SQObjectPtr &Top(){return _values.top();}
-       void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
-       void Insert(const SQObject& idx,const SQObject &val){_values.insert((unsigned int)tointeger(idx),val);}
-       void ShrinkIfNeeded() {
-               if(_values.size() <= _values.capacity()>>2) //shrink the array
-                       _values.shrinktofit();
-       }
-       void Remove(unsigned int idx){
-               _values.remove(idx);
-               ShrinkIfNeeded();
-       }
-       void Release()
-       {
-               sq_delete(this,SQArray);
-       }
-       SQObjectPtrVec _values;
-};
-#endif //_SQARRAY_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQARRAY_H_\r
+#define _SQARRAY_H_\r
+\r
+struct SQArray : public CHAINABLE_OBJ\r
+{\r
+private:\r
+       SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}\r
+       ~SQArray()\r
+       {\r
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
+       }\r
+public:\r
+       static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){\r
+               SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));\r
+               new (newarray) SQArray(ss,nInitialSize);\r
+               return newarray;\r
+       }\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       void Mark(SQCollectable **chain);\r
+#endif\r
+       void Finalize(){\r
+               _values.resize(0);\r
+       }\r
+       bool Get(const SQInteger nidx,SQObjectPtr &val)\r
+       {\r
+               if(nidx>=0 && nidx<(SQInteger)_values.size()){\r
+                       SQObjectPtr &o = _values[nidx];\r
+                       val = _realval(o);\r
+                       return true;\r
+               }\r
+               else return false;\r
+       }\r
+       bool Set(const SQInteger nidx,const SQObjectPtr &val)\r
+       {\r
+               if(nidx>=0 && nidx<(SQInteger)_values.size()){\r
+                       _values[nidx]=val;\r
+                       return true;\r
+               }\r
+               else return false;\r
+       }\r
+       SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)\r
+       {\r
+               SQUnsignedInteger idx=TranslateIndex(refpos);\r
+               while(idx<_values.size()){\r
+                       //first found\r
+                       outkey=(SQInteger)idx;\r
+                       SQObjectPtr &o = _values[idx];\r
+                       outval = _realval(o);\r
+                       //return idx for the next iteration\r
+                       return ++idx;\r
+               }\r
+               //nothing to iterate anymore\r
+               return -1;\r
+       }\r
+       SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }\r
+       SQInteger Size() const {return _values.size();}\r
+       void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }\r
+       void Reserve(SQInteger size) { _values.reserve(size); }\r
+       void Append(const SQObject &o){_values.push_back(o);}\r
+       void Extend(const SQArray *a);\r
+       SQObjectPtr &Top(){return _values.top();}\r
+       void Pop(){_values.pop_back(); ShrinkIfNeeded(); }\r
+       void Insert(const SQObject& idx,const SQObject &val){_values.insert((SQUnsignedInteger)tointeger(idx),val);}\r
+       void ShrinkIfNeeded() {\r
+               if(_values.size() <= _values.capacity()>>2) //shrink the array\r
+                       _values.shrinktofit();\r
+       }\r
+       void Remove(SQUnsignedInteger idx){\r
+               _values.remove(idx);\r
+               ShrinkIfNeeded();\r
+       }\r
+       void Release()\r
+       {\r
+               sq_delete(this,SQArray);\r
+       }\r
+       SQObjectPtrVec _values;\r
+};\r
+#endif //_SQARRAY_H_\r
index 01bce2c..674608f 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqclass.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-bool str2num(const SQChar *s,SQObjectPtr &res)
-{
-       SQChar *end;
-       if(scstrstr(s,_SC("."))){
-               SQFloat r = SQFloat(scstrtod(s,&end));
-               if(s == end) return false;
-               while (scisspace((*end)) ) end++;
-               if (*end != _SC('\0')) return false;
-               res = r;
-               return true;
-       }
-       else{
-               const SQChar *t = s;
-               while(*t != _SC('\0')) if(!scisdigit(*t++)) return false;
-               res = SQInteger(scatoi(s));
-               return true;
-       }
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-static int base_collectgarbage(HSQUIRRELVM v)
-{
-       sq_pushinteger(v, sq_collectgarbage(v));
-       return 1;
-}
-#endif
-
-static int base_getroottable(HSQUIRRELVM v)
-{
-       v->Push(v->_roottable);
-       return 1;
-}
-
-static int base_setroottable(HSQUIRRELVM v)
-{
-       SQObjectPtr &o=stack_get(v,2);
-       if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
-       v->Push(o);
-       return 1;
-}
-
-static int base_seterrorhandler(HSQUIRRELVM v)
-{
-       sq_seterrorhandler(v);
-       return 0;
-}
-
-static int base_setdebughook(HSQUIRRELVM v)
-{
-       sq_setdebughook(v);
-       return 0;
-}
-
-static int base_enabledebuginfo(HSQUIRRELVM v)
-{
-       SQObjectPtr &o=stack_get(v,2);
-       sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
-       return 0;
-}
-
-static int base_getstackinfos(HSQUIRRELVM v)
-{
-       SQInteger level;
-       SQStackInfos si;
-       int seq = 0;
-       const SQChar *name = NULL;
-       sq_getinteger(v, -1, &level);
-       if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
-       {
-               const SQChar *fn = _SC("unknown");
-               const SQChar *src = _SC("unknown");
-               if(si.funcname)fn = si.funcname;
-               if(si.source)src = si.source;
-               sq_newtable(v);
-               sq_pushstring(v, _SC("func"), -1);
-               sq_pushstring(v, fn, -1);
-               sq_createslot(v, -3);
-               sq_pushstring(v, _SC("src"), -1);
-               sq_pushstring(v, src, -1);
-               sq_createslot(v, -3);
-               sq_pushstring(v, _SC("line"), -1);
-               sq_pushinteger(v, si.line);
-               sq_createslot(v, -3);
-               sq_pushstring(v, _SC("locals"), -1);
-               sq_newtable(v);
-               seq=0;
-               while (name = sq_getlocal(v, level, seq)) {
-                       sq_pushstring(v, name, -1);
-                       sq_push(v, -2);
-                       sq_createslot(v, -4);
-                       sq_pop(v, 1);
-                       seq++;
-               }
-               sq_createslot(v, -3);
-               return 1;
-       }
-
-       return 0;
-}
-
-static int base_assert(HSQUIRRELVM v)
-{
-       if(v->IsFalse(stack_get(v,2))){
-               return sq_throwerror(v,_SC("assertion failed"));
-       }
-       return 0;
-}
-
-static int get_slice_params(HSQUIRRELVM v,int &sidx,int &eidx,SQObjectPtr &o)
-{
-       int top = sq_gettop(v);
-       sidx=0;
-       eidx=0;
-       o=stack_get(v,1);
-       SQObjectPtr &start=stack_get(v,2);
-       if(type(start)!=OT_NULL && sq_isnumeric(start)){
-               sidx=tointeger(start);
-       }
-       if(top>2){
-               SQObjectPtr &end=stack_get(v,3);
-               if(sq_isnumeric(end)){
-                       eidx=tointeger(end);
-               }
-       }
-       else {
-               eidx = sq_getsize(v,1);
-       }
-       return 1;
-}
-
-static int base_print(HSQUIRRELVM v)
-{
-       SQObjectPtr &o=stack_get(v,2);
-       switch(type(o)){
-       case OT_STRING:
-               if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),_stringval(o));
-               break;
-       case OT_INTEGER:
-               if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%d"),_integer(o));
-               break;
-       case OT_FLOAT:
-               if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%.14g"),_float(o));
-               break;
-       default:{
-               SQObjectPtr tname;
-               v->TypeOf(o,tname);
-               if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("(%s)"),_stringval(tname));
-               }
-               break;
-       }
-       return 0;
-}
-
-static int base_compilestring(HSQUIRRELVM v)
-{
-       int nargs=sq_gettop(v);
-       const SQChar *src=NULL,*name=_SC("unnamedbuffer");
-       SQInteger size;
-       sq_getstring(v,2,&src);
-       size=sq_getsize(v,2);
-       if(nargs>2){
-               sq_getstring(v,3,&name);
-       }
-       if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
-               return 1;
-       else
-               return SQ_ERROR;
-}
-
-static int base_newthread(HSQUIRRELVM v)
-{
-       SQObjectPtr &func = stack_get(v,2);
-       int stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
-       HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
-       sq_move(newv,v,-2);
-       return 1;
-}
-
-static int base_suspend(HSQUIRRELVM v)
-{
-       return sq_suspendvm(v);
-}
-
-static int base_array(HSQUIRRELVM v)
-{
-       SQArray *a;
-       SQObject &size = stack_get(v,2);
-       if(sq_gettop(v) > 2) {
-               a = SQArray::Create(_ss(v),0);
-               a->Resize(tointeger(size),stack_get(v,3));
-       }
-       else {
-               a = SQArray::Create(_ss(v),tointeger(size));
-       }
-       v->Push(a);
-       return 1;
-}
-
-static int base_type(HSQUIRRELVM v)
-{
-       SQObjectPtr &o = stack_get(v,2);
-       v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
-       return 1;
-}
-
-static SQRegFunction base_funcs[]={
-       //generic
-       {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
-       {_SC("setdebughook"),base_setdebughook,2, NULL},
-       {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
-       {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
-       {_SC("getroottable"),base_getroottable,1, NULL},
-       {_SC("setroottable"),base_setroottable,2, NULL},
-       {_SC("assert"),base_assert,2, NULL},
-       {_SC("print"),base_print,2, NULL},
-       {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
-       {_SC("newthread"),base_newthread,2, _SC(".c")},
-       {_SC("suspend"),base_suspend,-1, NULL},
-       {_SC("array"),base_array,-2, _SC(".n")},
-       {_SC("type"),base_type,2, NULL},
-#ifndef NO_GARBAGE_COLLECTOR
-       {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
-#endif
-       {0,0}
-};
-
-void sq_base_register(HSQUIRRELVM v)
-{
-       int i=0;
-       sq_pushroottable(v);
-       while(base_funcs[i].name!=0) {
-               sq_pushstring(v,base_funcs[i].name,-1);
-               sq_newclosure(v,base_funcs[i].f,0);
-               sq_setnativeclosurename(v,-1,base_funcs[i].name);
-               sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
-               sq_createslot(v,-3);
-               i++;
-       }
-       sq_pushstring(v,_SC("_charsize_"),-1);
-       sq_pushinteger(v,sizeof(SQChar));
-       sq_createslot(v,-3);
-       sq_pop(v,1);
-}
-
-static int default_delegate_len(HSQUIRRELVM v)
-{
-       v->Push(SQInteger(sq_getsize(v,1)));
-       return 1;
-}
-
-static int default_delegate_tofloat(HSQUIRRELVM v)
-{
-       SQObjectPtr &o=stack_get(v,1);
-       switch(type(o)){
-       case OT_STRING:{
-               SQObjectPtr res;
-               if(str2num(_stringval(o),res)){
-                       v->Push(SQObjectPtr(tofloat(res)));
-                       break;
-               }}
-       case OT_INTEGER:case OT_FLOAT:
-               v->Push(SQObjectPtr(tofloat(o)));
-               break;
-       case OT_BOOL:
-               v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
-               break;
-       default:
-               v->Push(_null_);
-               break;
-       }
-       return 1;
-}
-
-static int default_delegate_tointeger(HSQUIRRELVM v)
-{
-       SQObjectPtr &o=stack_get(v,1);
-       switch(type(o)){
-       case OT_STRING:{
-               SQObjectPtr res;
-               if(str2num(_stringval(o),res)){
-                       v->Push(SQObjectPtr(tointeger(res)));
-                       break;
-               }}
-       case OT_INTEGER:case OT_FLOAT:
-               v->Push(SQObjectPtr(tointeger(o)));
-               break;
-       case OT_BOOL:
-               v->Push(SQObjectPtr(_integer(o)?1:0));
-               break;
-       default:
-               v->Push(_null_);
-               break;
-       }
-       return 1;
-}
-
-static int default_delegate_tostring(HSQUIRRELVM v)
-{
-       SQObjectPtr &o=stack_get(v,1);
-       switch(type(o)){
-       case OT_STRING:
-               v->Push(o);
-               break;
-       case OT_INTEGER:
-               scsprintf(_ss(v)->GetScratchPad(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));
-               v->Push(SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1)));
-               break;
-       case OT_FLOAT:
-               scsprintf(_ss(v)->GetScratchPad(rsl(NUMBER_MAX_CHAR+1)),_SC("%.14g"),_float(o));
-               v->Push(SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1)));
-               break;
-       case OT_BOOL:
-               v->Push(SQObjectPtr(SQString::Create(_ss(v),_integer(o)?_SC("true"):_SC("false"))));
-               break;
-       default:
-               v->Push(_null_);
-               break;
-       }
-       return 1;
-}
-
-static int number_delegate_tochar(HSQUIRRELVM v)
-{
-       SQObject &o=stack_get(v,1);
-       SQChar c=tointeger(o);
-       v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
-       return 1;
-}
-
-
-/////////////////////////////////////////////////////////////////
-//TABLE DEFAULT DELEGATE
-
-static int table_rawdelete(HSQUIRRELVM v)
-{
-       if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
-               return SQ_ERROR;
-       return 1;
-}
-
-
-static int container_rawexists(HSQUIRRELVM v)
-{
-       if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
-               sq_pushbool(v,SQTrue);
-               return 1;
-       }
-       sq_pushbool(v,SQFalse);
-       return 1;
-}
-
-static int table_rawset(HSQUIRRELVM v)
-{
-       return sq_rawset(v,-3);
-}
-
-
-static int table_rawget(HSQUIRRELVM v)
-{
-       return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
-       {_SC("len"),default_delegate_len,1, _SC("t")},
-       {_SC("rawget"),table_rawget,2, _SC("t")},
-       {_SC("rawset"),table_rawset,3, _SC("t")},
-       {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
-       {_SC("rawin"),container_rawexists,2, _SC("t")},
-       {0,0}
-};
-
-//ARRAY DEFAULT DELEGATE///////////////////////////////////////
-
-static int array_append(HSQUIRRELVM v)
-{
-       return sq_arrayappend(v,-2);
-}
-
-static int array_extend(HSQUIRRELVM v)
-{
-       _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
-       return 0;
-}
-
-static int array_reverse(HSQUIRRELVM v)
-{
-       return sq_arrayreverse(v,-1);
-}
-
-static int array_pop(HSQUIRRELVM v)
-{
-       return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
-}
-
-static int array_top(HSQUIRRELVM v)
-{
-       SQObject &o=stack_get(v,1);
-       if(_array(o)->Size()>0){
-               v->Push(_array(o)->Top());
-               return 1;
-       }
-       else return sq_throwerror(v,_SC("top() on a empty array"));
-}
-
-static int array_insert(HSQUIRRELVM v)
-{
-       SQObject &o=stack_get(v,1);
-       SQObject &idx=stack_get(v,2);
-       SQObject &val=stack_get(v,3);
-       _array(o)->Insert(idx,val);
-       return 0;
-}
-
-static int array_remove(HSQUIRRELVM v)
-{
-       SQObject &o = stack_get(v, 1);
-       SQObject &idx = stack_get(v, 2);
-       if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
-       SQObjectPtr val;
-       if(_array(o)->Get(tointeger(idx), val)) {
-               _array(o)->Remove(tointeger(idx));
-               v->Push(val);
-               return 1;
-       }
-       return sq_throwerror(v, _SC("idx out of range"));
-}
-
-static int array_resize(HSQUIRRELVM v)
-{
-       SQObject &o = stack_get(v, 1);
-       SQObject &nsize = stack_get(v, 2);
-       SQObjectPtr fill;
-       if(sq_isnumeric(nsize)) {
-               if(sq_gettop(v) > 2)
-                       fill = stack_get(v, 3);
-               _array(o)->Resize(tointeger(nsize),fill);
-               return 0;
-       }
-       return sq_throwerror(v, _SC("size must be a number"));
-}
-
-
-//QSORT ala Sedgewick
-bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,int func,int &ret)
-{
-       if(func < 0) {
-               if(!v->ObjCmp(a,b,ret)) return false;
-       }
-       else {
-               int top = sq_gettop(v);
-               sq_push(v, func);
-               sq_pushroottable(v);
-               v->Push(a);
-               v->Push(b);
-               if(SQ_FAILED(sq_call(v, 3, SQTrue))) {
-                       v->Raise_Error(_SC("compare func failed"));
-                       return false;
-               }
-               sq_getinteger(v, -1, &ret);
-               sq_settop(v, top);
-               return true;
-       }
-       return true;
-}
-//QSORT ala Sedgewick
-bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, int l, int r,int func)
-{
-       int i, j;
-       SQArray *a=_array(arr);
-       SQObjectPtr pivot,t;
-       if( l < r ){
-               pivot = a->_values[l];
-               i = l; j = r+1;
-               while(1){
-                       int ret;
-                       do { 
-                               ++i; 
-                               if(i > r) break;
-                               if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
-                                       return false;
-                       } while( ret <= 0);
-                       do {
-                               --j; 
-                               if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
-                                       return false;
-                       }
-                       while( ret > 0 );
-                       if( i >= j ) break;
-                       t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
-               }
-               t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
-               if(!_qsort( v, arr, l, j-1,func)) return false;
-               if(!_qsort( v, arr, j+1, r,func)) return false;
-       }
-       return true;
-}
-
-static int array_sort(HSQUIRRELVM v)
-{
-       //SQ_TRY {
-       int func = -1;
-       SQObjectPtr &o = stack_get(v,1);
-       SQObject &funcobj = stack_get(v,2);
-       if(_array(o)->Size() > 1) {
-               if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
-               if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
-                       return SQ_ERROR;
-
-       }
-       return 0;
-}
-static int array_slice(HSQUIRRELVM v)
-{
-       int sidx,eidx;
-       SQObjectPtr o;
-       if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
-       if(sidx<0)sidx=_array(o)->Size()+sidx;
-       if(eidx<0)eidx=_array(o)->Size()+eidx;
-       if(eidx <= sidx)return sq_throwerror(v,_SC("wrong indexes"));
-       SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
-       SQObjectPtr t;
-       int count=0;
-       for(int i=sidx;i<eidx;i++){
-               _array(o)->Get(i,t);
-               arr->Set(count++,t);
-       }
-       v->Push(arr);
-       return 1;
-       
-}
-
-SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
-       {_SC("len"),default_delegate_len,1, _SC("a")},
-       {_SC("append"),array_append,2, _SC("a")},
-       {_SC("extend"),array_extend,2, _SC("aa")},
-       {_SC("push"),array_append,2, _SC("a")},
-       {_SC("pop"),array_pop,1, _SC("a")},
-       {_SC("top"),array_top,1, _SC("a")},
-       {_SC("insert"),array_insert,3, _SC("an")},
-       {_SC("remove"),array_remove,2, _SC("an")},
-       {_SC("resize"),array_resize,-2, _SC("an")},
-       {_SC("reverse"),array_reverse,1, _SC("a")},
-       {_SC("sort"),array_sort,-1, _SC("ac")},
-       {_SC("slice"),array_slice,-1, _SC("ann")},
-       {0,0}
-};
-
-//STRING DEFAULT DELEGATE//////////////////////////
-static int string_slice(HSQUIRRELVM v)
-{
-       int sidx,eidx;
-       SQObjectPtr o;
-       if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
-       if(sidx<0)sidx=_string(o)->_len+sidx;
-       if(eidx<0)eidx=_string(o)->_len+eidx;
-       if(eidx<sidx)
-               return sq_throwerror(v,_SC("wrong indexes"));
-       v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
-       return 1;
-}
-
-static int string_find(HSQUIRRELVM v)
-{
-       int top,start_idx=0;
-       const SQChar *str,*substr,*ret;
-       if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
-               if(top>2)sq_getinteger(v,3,&start_idx);
-               if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
-                       ret=scstrstr(&str[start_idx],substr);
-                       if(ret){
-                               sq_pushinteger(v,(int)(ret-str));
-                               return 1;
-                       }
-               }
-               return 0;
-       }
-       return sq_throwerror(v,_SC("invalid param"));
-}
-
-#define STRING_TOFUNCZ(func) static int string_##func(HSQUIRRELVM v) \
-{ \
-       SQObject str=stack_get(v,1); \
-       int len=_string(str)->_len; \
-       const SQChar *sThis=_stringval(str); \
-       SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
-       for(int i=0;i<len;i++) sNew[i]=func(sThis[i]); \
-       v->Push(SQString::Create(_ss(v),sNew,len)); \
-       return 1; \
-}
-
-
-STRING_TOFUNCZ(tolower)
-STRING_TOFUNCZ(toupper)
-
-SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
-       {_SC("len"),default_delegate_len,1, _SC("s")},
-       {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
-       {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
-       {_SC("tostring"),default_delegate_tostring,1, _SC("s")},
-       {_SC("slice"),string_slice,-1, _SC(" s n  n")},
-       {_SC("find"),string_find,-2, _SC("s s n ")},
-       {_SC("tolower"),string_tolower,1, _SC("s")},
-       {_SC("toupper"),string_toupper,1, _SC("s")},
-       {0,0}
-};
-
-//INTEGER DEFAULT DELEGATE//////////////////////////
-SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
-       {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
-       {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
-       {_SC("tostring"),default_delegate_tostring,1, _SC("n|b")},
-       {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
-       {0,0}
-};
-
-//CLOSURE DEFAULT DELEGATE//////////////////////////
-static int closure_call(HSQUIRRELVM v)
-{
-       return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue))?1:SQ_ERROR;
-}
-
-static int closure_acall(HSQUIRRELVM v)
-{
-       SQArray *aparams=_array(stack_get(v,2));
-       int nparams=aparams->Size();
-       v->Push(stack_get(v,1));
-       for(int i=0;i<nparams;i++)v->Push(aparams->_values[i]);
-       return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue))?1:SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
-       {_SC("call"),closure_call,-1, _SC("c")},
-       {_SC("acall"),closure_acall,2, _SC("ca")},
-       {0,0}
-};
-
-//GENERATOR DEFAULT DELEGATE
-static int generator_getstatus(HSQUIRRELVM v)
-{
-       SQObject &o=stack_get(v,1);
-       switch(_generator(o)->_state){
-               case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
-               case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
-               case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
-       }
-       return 1;
-}
-
-SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
-       {_SC("getstatus"),generator_getstatus,1, _SC("g")},
-       {0,0}
-};
-
-//THREAD DEFAULT DELEGATE
-
-static int thread_call(HSQUIRRELVM v)
-{
-       SQObjectPtr o = stack_get(v,1);
-       if(type(o) == OT_THREAD) {
-               int nparams = sq_gettop(v);
-               _thread(o)->Push(_thread(o)->_roottable);
-               for(int i = 2; i<(nparams+1); i++)
-                       sq_move(_thread(o),v,i);
-               if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue))) {
-                       sq_move(v,_thread(o),-1);
-                       return 1;
-               }
-               return SQ_ERROR;
-       }
-       return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static int thread_wakeup(HSQUIRRELVM v)
-{
-       SQObjectPtr o = stack_get(v,1);
-       if(type(o) == OT_THREAD) {
-               SQVM *thread = _thread(o);
-               int state = sq_getvmstate(thread);
-               if(state != SQ_VMSTATE_SUSPENDED) {
-                       switch(state) {
-                               case SQ_VMSTATE_IDLE:
-                                       return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
-                               break;
-                               case SQ_VMSTATE_RUNNING:
-                                       return sq_throwerror(v,_SC("cannot wakeup a running thread"));
-                               break;
-                       }
-               }
-                       
-               int wakeupret = sq_gettop(v)>1?1:0;
-               if(wakeupret) {
-                       sq_move(thread,v,2);
-               }
-               if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1))) {
-                       sq_move(v,thread,-1);
-                       sq_pop(thread,1);
-                       if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
-                               sq_pop(thread,1);
-                       }
-                       return 1;
-               }
-               return SQ_ERROR;
-       }
-       return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static int thread_getstatus(HSQUIRRELVM v)
-{
-       SQObjectPtr &o = stack_get(v,1);
-       switch(sq_getvmstate(_thread(o))) {
-               case SQ_VMSTATE_IDLE:
-                       sq_pushstring(v,_SC("idle"),-1);
-               break;
-               case SQ_VMSTATE_RUNNING:
-                       sq_pushstring(v,_SC("running"),-1);
-               break;
-               case SQ_VMSTATE_SUSPENDED:
-                       sq_pushstring(v,_SC("suspended"),-1);
-               break;
-               default:
-                       return sq_throwerror(v,_SC("internal VM error"));
-       }
-       return 1;
-}
-
-SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
-       {_SC("call"), thread_call, -1, _SC("v")},
-       {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
-       {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
-       {0,0},
-};
-
-static int class_getattributes(HSQUIRRELVM v)
-{
-       if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
-               return 1;
-       return SQ_ERROR;
-}
-
-static int class_setattributes(HSQUIRRELVM v)
-{
-       if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
-               return 1;
-       return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
-       {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
-       {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
-       {_SC("rawin"),container_rawexists,2, _SC("y")},
-       {0,0}
-};
-
-static int instance_getclass(HSQUIRRELVM v)
-{
-       if(SQ_SUCCEEDED(sq_getclass(v,1)))
-               return 1;
-       return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
-       {_SC("getclass"), instance_getclass, 1, _SC("x")},
-       {_SC("rawin"),container_rawexists,2, _SC("x")},
-       {0,0}
-};
-
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include "sqvm.h"\r
+#include "sqstring.h"\r
+#include "sqtable.h"\r
+#include "sqarray.h"\r
+#include "sqfuncproto.h"\r
+#include "sqclosure.h"\r
+#include "sqclass.h"\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <ctype.h>\r
+\r
+bool str2num(const SQChar *s,SQObjectPtr &res)\r
+{\r
+       SQChar *end;\r
+       if(scstrstr(s,_SC("."))){\r
+               SQFloat r = SQFloat(scstrtod(s,&end));\r
+               if(s == end) return false;\r
+               res = r;\r
+               return true;\r
+       }\r
+       else{\r
+               SQInteger r = SQInteger(scstrtol(s,&end,10));\r
+               if(s == end) return false;\r
+               res = r;\r
+               return true;\r
+       }\r
+}\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+static SQInteger base_collectgarbage(HSQUIRRELVM v)\r
+{\r
+       sq_pushinteger(v, sq_collectgarbage(v));\r
+       return 1;\r
+}\r
+#endif\r
+\r
+static SQInteger base_getroottable(HSQUIRRELVM v)\r
+{\r
+       v->Push(v->_roottable);\r
+       return 1;\r
+}\r
+\r
+static SQInteger base_setroottable(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &o=stack_get(v,2);\r
+       if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;\r
+       v->Push(o);\r
+       return 1;\r
+}\r
+\r
+static SQInteger base_seterrorhandler(HSQUIRRELVM v)\r
+{\r
+       sq_seterrorhandler(v);\r
+       return 0;\r
+}\r
+\r
+static SQInteger base_setdebughook(HSQUIRRELVM v)\r
+{\r
+       sq_setdebughook(v);\r
+       return 0;\r
+}\r
+\r
+static SQInteger base_enabledebuginfo(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &o=stack_get(v,2);\r
+       sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);\r
+       return 0;\r
+}\r
+\r
+static SQInteger base_getstackinfos(HSQUIRRELVM v)\r
+{\r
+       SQInteger level;\r
+       SQStackInfos si;\r
+       SQInteger seq = 0;\r
+       const SQChar *name = NULL;\r
+       sq_getinteger(v, -1, &level);\r
+       if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))\r
+       {\r
+               const SQChar *fn = _SC("unknown");\r
+               const SQChar *src = _SC("unknown");\r
+               if(si.funcname)fn = si.funcname;\r
+               if(si.source)src = si.source;\r
+               sq_newtable(v);\r
+               sq_pushstring(v, _SC("func"), -1);\r
+               sq_pushstring(v, fn, -1);\r
+               sq_createslot(v, -3);\r
+               sq_pushstring(v, _SC("src"), -1);\r
+               sq_pushstring(v, src, -1);\r
+               sq_createslot(v, -3);\r
+               sq_pushstring(v, _SC("line"), -1);\r
+               sq_pushinteger(v, si.line);\r
+               sq_createslot(v, -3);\r
+               sq_pushstring(v, _SC("locals"), -1);\r
+               sq_newtable(v);\r
+               seq=0;\r
+               while (name = sq_getlocal(v, level, seq)) {\r
+                       sq_pushstring(v, name, -1);\r
+                       sq_push(v, -2);\r
+                       sq_createslot(v, -4);\r
+                       sq_pop(v, 1);\r
+                       seq++;\r
+               }\r
+               sq_createslot(v, -3);\r
+               return 1;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+static SQInteger base_assert(HSQUIRRELVM v)\r
+{\r
+       if(v->IsFalse(stack_get(v,2))){\r
+               return sq_throwerror(v,_SC("assertion failed"));\r
+       }\r
+       return 0;\r
+}\r
+\r
+static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)\r
+{\r
+       SQInteger top = sq_gettop(v);\r
+       sidx=0;\r
+       eidx=0;\r
+       o=stack_get(v,1);\r
+       SQObjectPtr &start=stack_get(v,2);\r
+       if(type(start)!=OT_NULL && sq_isnumeric(start)){\r
+               sidx=tointeger(start);\r
+       }\r
+       if(top>2){\r
+               SQObjectPtr &end=stack_get(v,3);\r
+               if(sq_isnumeric(end)){\r
+                       eidx=tointeger(end);\r
+               }\r
+       }\r
+       else {\r
+               eidx = sq_getsize(v,1);\r
+       }\r
+       return 1;\r
+}\r
+\r
+static SQInteger base_print(HSQUIRRELVM v)\r
+{\r
+       const SQChar *str;\r
+       sq_tostring(v,2);\r
+       sq_getstring(v,-1,&str);\r
+       if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);\r
+       return 0;\r
+}\r
+\r
+static SQInteger base_compilestring(HSQUIRRELVM v)\r
+{\r
+       SQInteger nargs=sq_gettop(v);\r
+       const SQChar *src=NULL,*name=_SC("unnamedbuffer");\r
+       SQInteger size;\r
+       sq_getstring(v,2,&src);\r
+       size=sq_getsize(v,2);\r
+       if(nargs>2){\r
+               sq_getstring(v,3,&name);\r
+       }\r
+       if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))\r
+               return 1;\r
+       else\r
+               return SQ_ERROR;\r
+}\r
+\r
+static SQInteger base_newthread(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &func = stack_get(v,2);\r
+       SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;\r
+       HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);\r
+       sq_move(newv,v,-2);\r
+       return 1;\r
+}\r
+\r
+static SQInteger base_suspend(HSQUIRRELVM v)\r
+{\r
+       return sq_suspendvm(v);\r
+}\r
+\r
+static SQInteger base_array(HSQUIRRELVM v)\r
+{\r
+       SQArray *a;\r
+       SQObject &size = stack_get(v,2);\r
+       if(sq_gettop(v) > 2) {\r
+               a = SQArray::Create(_ss(v),0);\r
+               a->Resize(tointeger(size),stack_get(v,3));\r
+       }\r
+       else {\r
+               a = SQArray::Create(_ss(v),tointeger(size));\r
+       }\r
+       v->Push(a);\r
+       return 1;\r
+}\r
+\r
+static SQInteger base_type(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &o = stack_get(v,2);\r
+       v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));\r
+       return 1;\r
+}\r
+\r
+static SQRegFunction base_funcs[]={\r
+       //generic\r
+       {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},\r
+       {_SC("setdebughook"),base_setdebughook,2, NULL},\r
+       {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},\r
+       {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},\r
+       {_SC("getroottable"),base_getroottable,1, NULL},\r
+       {_SC("setroottable"),base_setroottable,2, NULL},\r
+       {_SC("assert"),base_assert,2, NULL},\r
+       {_SC("print"),base_print,2, NULL},\r
+       {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},\r
+       {_SC("newthread"),base_newthread,2, _SC(".c")},\r
+       {_SC("suspend"),base_suspend,-1, NULL},\r
+       {_SC("array"),base_array,-2, _SC(".n")},\r
+       {_SC("type"),base_type,2, NULL},\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},\r
+#endif\r
+       {0,0}\r
+};\r
+\r
+void sq_base_register(HSQUIRRELVM v)\r
+{\r
+       SQInteger i=0;\r
+       sq_pushroottable(v);\r
+       while(base_funcs[i].name!=0) {\r
+               sq_pushstring(v,base_funcs[i].name,-1);\r
+               sq_newclosure(v,base_funcs[i].f,0);\r
+               sq_setnativeclosurename(v,-1,base_funcs[i].name);\r
+               sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);\r
+               sq_createslot(v,-3);\r
+               i++;\r
+       }\r
+       sq_pushstring(v,_SC("_charsize_"),-1);\r
+       sq_pushinteger(v,sizeof(SQChar));\r
+       sq_createslot(v,-3);\r
+       sq_pop(v,1);\r
+}\r
+\r
+static SQInteger default_delegate_len(HSQUIRRELVM v)\r
+{\r
+       v->Push(SQInteger(sq_getsize(v,1)));\r
+       return 1;\r
+}\r
+\r
+static SQInteger default_delegate_tofloat(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &o=stack_get(v,1);\r
+       switch(type(o)){\r
+       case OT_STRING:{\r
+               SQObjectPtr res;\r
+               if(str2num(_stringval(o),res)){\r
+                       v->Push(SQObjectPtr(tofloat(res)));\r
+                       break;\r
+               }}\r
+               return sq_throwerror(v, _SC("cannot convert the string"));\r
+               break;\r
+       case OT_INTEGER:case OT_FLOAT:\r
+               v->Push(SQObjectPtr(tofloat(o)));\r
+               break;\r
+       case OT_BOOL:\r
+               v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));\r
+               break;\r
+       default:\r
+               v->Push(_null_);\r
+               break;\r
+       }\r
+       return 1;\r
+}\r
+\r
+static SQInteger default_delegate_tointeger(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &o=stack_get(v,1);\r
+       switch(type(o)){\r
+       case OT_STRING:{\r
+               SQObjectPtr res;\r
+               if(str2num(_stringval(o),res)){\r
+                       v->Push(SQObjectPtr(tointeger(res)));\r
+                       break;\r
+               }}\r
+               return sq_throwerror(v, _SC("cannot convert the string"));\r
+               break;\r
+       case OT_INTEGER:case OT_FLOAT:\r
+               v->Push(SQObjectPtr(tointeger(o)));\r
+               break;\r
+       case OT_BOOL:\r
+               v->Push(SQObjectPtr(_integer(o)?1:0));\r
+               break;\r
+       default:\r
+               v->Push(_null_);\r
+               break;\r
+       }\r
+       return 1;\r
+}\r
+\r
+static SQInteger default_delegate_tostring(HSQUIRRELVM v)\r
+{\r
+       sq_tostring(v,1);\r
+       return 1;\r
+}\r
+\r
+static SQInteger obj_delegate_weakref(HSQUIRRELVM v)\r
+{\r
+       sq_weakref(v,1);\r
+       return 1;\r
+}\r
+\r
+static SQInteger number_delegate_tochar(HSQUIRRELVM v)\r
+{\r
+       SQObject &o=stack_get(v,1);\r
+       SQChar c=tointeger(o);\r
+       v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));\r
+       return 1;\r
+}\r
+\r
+\r
+/////////////////////////////////////////////////////////////////\r
+//TABLE DEFAULT DELEGATE\r
+\r
+static SQInteger table_rawdelete(HSQUIRRELVM v)\r
+{\r
+       if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))\r
+               return SQ_ERROR;\r
+       return 1;\r
+}\r
+\r
+\r
+static SQInteger container_rawexists(HSQUIRRELVM v)\r
+{\r
+       if(SQ_SUCCEEDED(sq_rawget(v,-2))) {\r
+               sq_pushbool(v,SQTrue);\r
+               return 1;\r
+       }\r
+       sq_pushbool(v,SQFalse);\r
+       return 1;\r
+}\r
+\r
+static SQInteger table_rawset(HSQUIRRELVM v)\r
+{\r
+       return sq_rawset(v,-3);\r
+}\r
+\r
+\r
+static SQInteger table_rawget(HSQUIRRELVM v)\r
+{\r
+       return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;\r
+}\r
+\r
+SQRegFunction SQSharedState::_table_default_delegate_funcz[]={\r
+       {_SC("len"),default_delegate_len,1, _SC("t")},\r
+       {_SC("rawget"),table_rawget,2, _SC("t")},\r
+       {_SC("rawset"),table_rawset,3, _SC("t")},\r
+       {_SC("rawdelete"),table_rawdelete,2, _SC("t")},\r
+       {_SC("rawin"),container_rawexists,2, _SC("t")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+//ARRAY DEFAULT DELEGATE///////////////////////////////////////\r
+\r
+static SQInteger array_append(HSQUIRRELVM v)\r
+{\r
+       return sq_arrayappend(v,-2);\r
+}\r
+\r
+static SQInteger array_extend(HSQUIRRELVM v)\r
+{\r
+       _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));\r
+       return 0;\r
+}\r
+\r
+static SQInteger array_reverse(HSQUIRRELVM v)\r
+{\r
+       return sq_arrayreverse(v,-1);\r
+}\r
+\r
+static SQInteger array_pop(HSQUIRRELVM v)\r
+{\r
+       return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;\r
+}\r
+\r
+static SQInteger array_top(HSQUIRRELVM v)\r
+{\r
+       SQObject &o=stack_get(v,1);\r
+       if(_array(o)->Size()>0){\r
+               v->Push(_array(o)->Top());\r
+               return 1;\r
+       }\r
+       else return sq_throwerror(v,_SC("top() on a empty array"));\r
+}\r
+\r
+static SQInteger array_insert(HSQUIRRELVM v)\r
+{\r
+       SQObject &o=stack_get(v,1);\r
+       SQObject &idx=stack_get(v,2);\r
+       SQObject &val=stack_get(v,3);\r
+       _array(o)->Insert(idx,val);\r
+       return 0;\r
+}\r
+\r
+static SQInteger array_remove(HSQUIRRELVM v)\r
+{\r
+       SQObject &o = stack_get(v, 1);\r
+       SQObject &idx = stack_get(v, 2);\r
+       if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));\r
+       SQObjectPtr val;\r
+       if(_array(o)->Get(tointeger(idx), val)) {\r
+               _array(o)->Remove(tointeger(idx));\r
+               v->Push(val);\r
+               return 1;\r
+       }\r
+       return sq_throwerror(v, _SC("idx out of range"));\r
+}\r
+\r
+static SQInteger array_resize(HSQUIRRELVM v)\r
+{\r
+       SQObject &o = stack_get(v, 1);\r
+       SQObject &nsize = stack_get(v, 2);\r
+       SQObjectPtr fill;\r
+       if(sq_isnumeric(nsize)) {\r
+               if(sq_gettop(v) > 2)\r
+                       fill = stack_get(v, 3);\r
+               _array(o)->Resize(tointeger(nsize),fill);\r
+               return 0;\r
+       }\r
+       return sq_throwerror(v, _SC("size must be a number"));\r
+}\r
+\r
+\r
+//QSORT ala Sedgewick\r
+bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)\r
+{\r
+       if(func < 0) {\r
+               if(!v->ObjCmp(a,b,ret)) return false;\r
+       }\r
+       else {\r
+               SQInteger top = sq_gettop(v);\r
+               sq_push(v, func);\r
+               sq_pushroottable(v);\r
+               v->Push(a);\r
+               v->Push(b);\r
+               if(SQ_FAILED(sq_call(v, 3, SQTrue))) {\r
+                       v->Raise_Error(_SC("compare func failed"));\r
+                       return false;\r
+               }\r
+               sq_getinteger(v, -1, &ret);\r
+               sq_settop(v, top);\r
+               return true;\r
+       }\r
+       return true;\r
+}\r
+//QSORT ala Sedgewick\r
+bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)\r
+{\r
+       SQInteger i, j;\r
+       SQArray *a=_array(arr);\r
+       SQObjectPtr pivot,t;\r
+       if( l < r ){\r
+               pivot = a->_values[l];\r
+               i = l; j = r+1;\r
+               while(1){\r
+                       SQInteger ret;\r
+                       do { \r
+                               ++i; \r
+                               if(i > r) break;\r
+                               if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))\r
+                                       return false;\r
+                       } while( ret <= 0);\r
+                       do {\r
+                               --j; \r
+                               if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))\r
+                                       return false;\r
+                       }\r
+                       while( ret > 0 );\r
+                       if( i >= j ) break;\r
+                       t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;\r
+               }\r
+               t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;\r
+               if(!_qsort( v, arr, l, j-1,func)) return false;\r
+               if(!_qsort( v, arr, j+1, r,func)) return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+static SQInteger array_sort(HSQUIRRELVM v)\r
+{\r
+       //SQ_TRY {\r
+       SQInteger func = -1;\r
+       SQObjectPtr &o = stack_get(v,1);\r
+       SQObject &funcobj = stack_get(v,2);\r
+       if(_array(o)->Size() > 1) {\r
+               if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;\r
+               if(!_qsort(v, o, 0, _array(o)->Size()-1, func))\r
+                       return SQ_ERROR;\r
+\r
+       }\r
+       return 0;\r
+}\r
+static SQInteger array_slice(HSQUIRRELVM v)\r
+{\r
+       SQInteger sidx,eidx;\r
+       SQObjectPtr o;\r
+       if(get_slice_params(v,sidx,eidx,o)==-1)return -1;\r
+       if(sidx<0)sidx=_array(o)->Size()+sidx;\r
+       if(eidx<0)eidx=_array(o)->Size()+eidx;\r
+       if(eidx <= sidx)return sq_throwerror(v,_SC("wrong indexes"));\r
+       SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);\r
+       SQObjectPtr t;\r
+       SQInteger count=0;\r
+       for(SQInteger i=sidx;i<eidx;i++){\r
+               _array(o)->Get(i,t);\r
+               arr->Set(count++,t);\r
+       }\r
+       v->Push(arr);\r
+       return 1;\r
+       \r
+}\r
+\r
+SQRegFunction SQSharedState::_array_default_delegate_funcz[]={\r
+       {_SC("len"),default_delegate_len,1, _SC("a")},\r
+       {_SC("append"),array_append,2, _SC("a")},\r
+       {_SC("extend"),array_extend,2, _SC("aa")},\r
+       {_SC("push"),array_append,2, _SC("a")},\r
+       {_SC("pop"),array_pop,1, _SC("a")},\r
+       {_SC("top"),array_top,1, _SC("a")},\r
+       {_SC("insert"),array_insert,3, _SC("an")},\r
+       {_SC("remove"),array_remove,2, _SC("an")},\r
+       {_SC("resize"),array_resize,-2, _SC("an")},\r
+       {_SC("reverse"),array_reverse,1, _SC("a")},\r
+       {_SC("sort"),array_sort,-1, _SC("ac")},\r
+       {_SC("slice"),array_slice,-1, _SC("ann")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+//STRING DEFAULT DELEGATE//////////////////////////\r
+static SQInteger string_slice(HSQUIRRELVM v)\r
+{\r
+       SQInteger sidx,eidx;\r
+       SQObjectPtr o;\r
+       if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;\r
+       if(sidx<0)sidx=_string(o)->_len+sidx;\r
+       if(eidx<0)eidx=_string(o)->_len+eidx;\r
+       if(eidx<sidx)\r
+               return sq_throwerror(v,_SC("wrong indexes"));\r
+       v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));\r
+       return 1;\r
+}\r
+\r
+static SQInteger string_find(HSQUIRRELVM v)\r
+{\r
+       SQInteger top,start_idx=0;\r
+       const SQChar *str,*substr,*ret;\r
+       if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){\r
+               if(top>2)sq_getinteger(v,3,&start_idx);\r
+               if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){\r
+                       ret=scstrstr(&str[start_idx],substr);\r
+                       if(ret){\r
+                               sq_pushinteger(v,(SQInteger)(ret-str));\r
+                               return 1;\r
+                       }\r
+               }\r
+               return 0;\r
+       }\r
+       return sq_throwerror(v,_SC("invalid param"));\r
+}\r
+\r
+#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \\r
+{ \\r
+       SQObject str=stack_get(v,1); \\r
+       SQInteger len=_string(str)->_len; \\r
+       const SQChar *sThis=_stringval(str); \\r
+       SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \\r
+       for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \\r
+       v->Push(SQString::Create(_ss(v),sNew,len)); \\r
+       return 1; \\r
+}\r
+\r
+\r
+STRING_TOFUNCZ(tolower)\r
+STRING_TOFUNCZ(toupper)\r
+\r
+SQRegFunction SQSharedState::_string_default_delegate_funcz[]={\r
+       {_SC("len"),default_delegate_len,1, _SC("s")},\r
+       {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},\r
+       {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},\r
+       {_SC("tostring"),default_delegate_tostring,1, _SC("s")},\r
+       {_SC("slice"),string_slice,-1, _SC(" s n  n")},\r
+       {_SC("find"),string_find,-2, _SC("s s n ")},\r
+       {_SC("tolower"),string_tolower,1, _SC("s")},\r
+       {_SC("toupper"),string_toupper,1, _SC("s")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+//INTEGER DEFAULT DELEGATE//////////////////////////\r
+SQRegFunction SQSharedState::_number_default_delegate_funcz[]={\r
+       {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},\r
+       {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},\r
+       {_SC("tostring"),default_delegate_tostring,1, _SC("n|b")},\r
+       {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+//CLOSURE DEFAULT DELEGATE//////////////////////////\r
+static SQInteger closure_call(HSQUIRRELVM v)\r
+{\r
+       return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue))?1:SQ_ERROR;\r
+}\r
+\r
+static SQInteger closure_acall(HSQUIRRELVM v)\r
+{\r
+       SQArray *aparams=_array(stack_get(v,2));\r
+       SQInteger nparams=aparams->Size();\r
+       v->Push(stack_get(v,1));\r
+       for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);\r
+       return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue))?1:SQ_ERROR;\r
+}\r
+\r
+SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={\r
+       {_SC("call"),closure_call,-1, _SC("c")},\r
+       {_SC("acall"),closure_acall,2, _SC("ca")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+//GENERATOR DEFAULT DELEGATE\r
+static SQInteger generator_getstatus(HSQUIRRELVM v)\r
+{\r
+       SQObject &o=stack_get(v,1);\r
+       switch(_generator(o)->_state){\r
+               case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;\r
+               case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;\r
+               case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;\r
+       }\r
+       return 1;\r
+}\r
+\r
+SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={\r
+       {_SC("getstatus"),generator_getstatus,1, _SC("g")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+//THREAD DEFAULT DELEGATE\r
+\r
+static SQInteger thread_call(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr o = stack_get(v,1);\r
+       if(type(o) == OT_THREAD) {\r
+               SQInteger nparams = sq_gettop(v);\r
+               _thread(o)->Push(_thread(o)->_roottable);\r
+               for(SQInteger i = 2; i<(nparams+1); i++)\r
+                       sq_move(_thread(o),v,i);\r
+               if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue))) {\r
+                       sq_move(v,_thread(o),-1);\r
+                       return 1;\r
+               }\r
+               return SQ_ERROR;\r
+       }\r
+       return sq_throwerror(v,_SC("wrong parameter"));\r
+}\r
+\r
+static SQInteger thread_wakeup(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr o = stack_get(v,1);\r
+       if(type(o) == OT_THREAD) {\r
+               SQVM *thread = _thread(o);\r
+               SQInteger state = sq_getvmstate(thread);\r
+               if(state != SQ_VMSTATE_SUSPENDED) {\r
+                       switch(state) {\r
+                               case SQ_VMSTATE_IDLE:\r
+                                       return sq_throwerror(v,_SC("cannot wakeup a idle thread"));\r
+                               break;\r
+                               case SQ_VMSTATE_RUNNING:\r
+                                       return sq_throwerror(v,_SC("cannot wakeup a running thread"));\r
+                               break;\r
+                       }\r
+               }\r
+                       \r
+               SQInteger wakeupret = sq_gettop(v)>1?1:0;\r
+               if(wakeupret) {\r
+                       sq_move(thread,v,2);\r
+               }\r
+               if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1))) {\r
+                       sq_move(v,thread,-1);\r
+                       sq_pop(thread,1);\r
+                       if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {\r
+                               sq_pop(thread,1);\r
+                       }\r
+                       return 1;\r
+               }\r
+               return SQ_ERROR;\r
+       }\r
+       return sq_throwerror(v,_SC("wrong parameter"));\r
+}\r
+\r
+static SQInteger thread_getstatus(HSQUIRRELVM v)\r
+{\r
+       SQObjectPtr &o = stack_get(v,1);\r
+       switch(sq_getvmstate(_thread(o))) {\r
+               case SQ_VMSTATE_IDLE:\r
+                       sq_pushstring(v,_SC("idle"),-1);\r
+               break;\r
+               case SQ_VMSTATE_RUNNING:\r
+                       sq_pushstring(v,_SC("running"),-1);\r
+               break;\r
+               case SQ_VMSTATE_SUSPENDED:\r
+                       sq_pushstring(v,_SC("suspended"),-1);\r
+               break;\r
+               default:\r
+                       return sq_throwerror(v,_SC("internal VM error"));\r
+       }\r
+       return 1;\r
+}\r
+\r
+SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {\r
+       {_SC("call"), thread_call, -1, _SC("v")},\r
+       {_SC("wakeup"), thread_wakeup, -1, _SC("v")},\r
+       {_SC("getstatus"), thread_getstatus, 1, _SC("v")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0},\r
+};\r
+\r
+static SQInteger class_getattributes(HSQUIRRELVM v)\r
+{\r
+       if(SQ_SUCCEEDED(sq_getattributes(v,-2)))\r
+               return 1;\r
+       return SQ_ERROR;\r
+}\r
+\r
+static SQInteger class_setattributes(HSQUIRRELVM v)\r
+{\r
+       if(SQ_SUCCEEDED(sq_setattributes(v,-3)))\r
+               return 1;\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {\r
+       {_SC("getattributes"), class_getattributes, 2, _SC("y.")},\r
+       {_SC("setattributes"), class_setattributes, 3, _SC("y..")},\r
+       {_SC("rawin"),container_rawexists,2, _SC("y")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+static SQInteger instance_getclass(HSQUIRRELVM v)\r
+{\r
+       if(SQ_SUCCEEDED(sq_getclass(v,1)))\r
+               return 1;\r
+       return SQ_ERROR;\r
+}\r
+\r
+SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {\r
+       {_SC("getclass"), instance_getclass, 1, _SC("x")},\r
+       {_SC("rawin"),container_rawexists,2, _SC("x")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+static SQInteger weakref_ref(HSQUIRRELVM v)\r
+{\r
+       if(SQ_FAILED(sq_getweakrefval(v,1)))\r
+               return SQ_ERROR;\r
+       return 1;\r
+}\r
+\r
+SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {\r
+       {_SC("ref"),weakref_ref,1, _SC("r")},\r
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
+       {0,0}\r
+};\r
+\r
+\r
index 11d4095..21d6006 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-SQClass::SQClass(SQSharedState *ss,SQClass *base)
-{
-       _uiRef=0;
-       _base = base;
-       _typetag = 0;
-       _metamethods.resize(MT_LAST); //size it to max size
-       if(_base) {
-               _defaultvalues.copy(base->_defaultvalues);
-               _methods.copy(base->_methods);
-               _metamethods.copy(base->_metamethods);
-               __ObjAddRef(_base);
-       }
-       _members = base?base->_members->Clone() : SQTable::Create(ss,0);
-       __ObjAddRef(_members);
-       _locked = false;
-       INIT_CHAIN();
-       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-void SQClass::Finalize() { 
-       _attributes = _null_;
-       _defaultvalues.resize(0);
-       _methods.resize(0);
-       _metamethods.resize(0);
-       __ObjRelease(_members);
-       if(_base) {
-               __ObjRelease(_base);
-       }
-}
-
-SQClass::~SQClass()
-{
-       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
-       Finalize();
-}
-
-bool SQClass::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
-{
-       SQObjectPtr temp;
-       if(_locked) 
-               return false; //the slot already exists
-       if(_members->Get(key,temp) && type(temp) == OT_INTEGER) //overrides the default value
-       {
-               _defaultvalues[_integer(temp)].val = val;
-               return true;
-       }
-       if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) {
-               SQInteger mmidx;
-               if((mmidx = _sharedstate->GetMetaMethodIdxByName(key)) != -1) {
-                       _metamethods[mmidx] = val;
-               } 
-               else {
-                       if(type(temp) == OT_NULL) {
-                               SQClassMemeber m;
-                               m.val = val;
-                               _members->NewSlot(key,SQObjectPtr((SQUserPointer)_methods.size()));
-                               _methods.push_back(m);
-                       }
-                       else {
-                               _methods[(int)_userpointer(temp)].val = val;
-                       }
-               }
-               return true;
-       }
-       SQClassMemeber m;
-       m.val = val;
-       _members->NewSlot(key,SQObjectPtr((SQInteger)_defaultvalues.size()));
-       _defaultvalues.push_back(m);
-       return true;
-}
-
-SQInstance *SQClass::CreateInstance()
-{
-       if(!_locked) Lock();
-       return SQInstance::Create(_opt_ss(this),this);
-}
-
-int SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
-       SQObjectPtr oval;
-       int idx = _members->Next(refpos,outkey,oval);
-       if(idx != -1) {
-               if(type(oval) != OT_INTEGER) {
-                       outval = _methods[(int)_userpointer(oval)].val;
-               }
-               else {
-                       outval = _defaultvalues[_integer(oval)].val;
-               }
-       }
-       return idx;
-}
-
-bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
-{
-       SQObjectPtr idx;
-       if(_members->Get(key,idx)) {
-               if(type(idx) == OT_INTEGER)
-                       _defaultvalues[_integer(idx)].attrs = val;
-               else
-                       _methods[(int)_userpointer(idx)].attrs = val;
-               return true;
-       }
-       return false;
-}
-
-bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
-{
-       SQObjectPtr idx;
-       if(_members->Get(key,idx)) {
-               outval = (type(idx) == OT_INTEGER?_defaultvalues[_integer(idx)].attrs:_methods[(int)_userpointer(idx)].attrs);
-               return true;
-       }
-       return false;
-}
-
-///////////////////////////////////////////////////////////////////////
-void SQInstance::Init(SQSharedState *ss)
-{
-       _uiRef = 0;
-       _userpointer = NULL;
-       _hook = NULL;
-       __ObjAddRef(_class);
-       _delegate = _class->_members;
-       INIT_CHAIN();
-       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQClass *c)
-{
-       _class = c;
-       _values.resize(_class->_defaultvalues.size());
-       for(unsigned int i = 0; i < _class->_defaultvalues.size(); i++) {
-               _values[i] = _class->_defaultvalues[i].val;
-       }
-       Init(ss);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQInstance *i)
-{
-       _class = i->_class;
-       _values.copy(i->_values);
-       Init(ss);
-}
-
-void SQInstance::Finalize() 
-{
-       __ObjRelease(_class);
-       _values.resize(0);
-}
-
-SQInstance::~SQInstance()
-{
-       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
-       Finalize();
-}
-
-bool SQInstance::GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res)
-{
-       if(type(_class->_metamethods[mm]) != OT_NULL) {
-               res = _class->_metamethods[mm];
-               return true;
-       }
-       return false;
-}
-
-bool SQInstance::InstanceOf(SQClass *trg)
-{
-       SQClass *parent = _class;
-       while(parent != NULL) {
-               if(parent == trg)
-                       return true;
-               parent = parent->_base;
-       }
-       return false;
-}
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include "sqvm.h"\r
+#include "sqtable.h"\r
+#include "sqclass.h"\r
+#include "sqclosure.h"\r
+\r
+SQClass::SQClass(SQSharedState *ss,SQClass *base)\r
+{\r
+       _base = base;\r
+       _typetag = 0;\r
+       _metamethods.resize(MT_LAST); //size it to max size\r
+       if(_base) {\r
+               _defaultvalues.copy(base->_defaultvalues);\r
+               _methods.copy(base->_methods);\r
+               _metamethods.copy(base->_metamethods);\r
+               __ObjAddRef(_base);\r
+       }\r
+       _members = base?base->_members->Clone() : SQTable::Create(ss,0);\r
+       __ObjAddRef(_members);\r
+       _locked = false;\r
+       INIT_CHAIN();\r
+       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);\r
+}\r
+\r
+void SQClass::Finalize() { \r
+       _attributes = _null_;\r
+       _defaultvalues.resize(0);\r
+       _methods.resize(0);\r
+       _metamethods.resize(0);\r
+       __ObjRelease(_members);\r
+       if(_base) {\r
+               __ObjRelease(_base);\r
+       }\r
+}\r
+\r
+SQClass::~SQClass()\r
+{\r
+       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
+       Finalize();\r
+}\r
+\r
+bool SQClass::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)\r
+{\r
+       SQObjectPtr temp;\r
+       if(_locked) \r
+               return false; //the class already has an instance so cannot be modified\r
+       if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value\r
+       {\r
+               _defaultvalues[_member_idx(temp)].val = val;\r
+               return true;\r
+       }\r
+       if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) {\r
+               SQInteger mmidx;\r
+               if((mmidx = _sharedstate->GetMetaMethodIdxByName(key)) != -1) {\r
+                       _metamethods[mmidx] = val;\r
+               } \r
+               else {\r
+                       if(type(temp) == OT_NULL) {\r
+                               SQClassMemeber m;\r
+                               m.val = val;\r
+                               _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));\r
+                               _methods.push_back(m);\r
+                       }\r
+                       else {\r
+                               _methods[_member_idx(temp)].val = val;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       SQClassMemeber m;\r
+       m.val = val;\r
+       _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));\r
+       _defaultvalues.push_back(m);\r
+       return true;\r
+}\r
+\r
+SQInstance *SQClass::CreateInstance()\r
+{\r
+       if(!_locked) Lock();\r
+       return SQInstance::Create(_opt_ss(this),this);\r
+}\r
+\r
+SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
+{\r
+       SQObjectPtr oval;\r
+       SQInteger idx = _members->Next(false,refpos,outkey,oval);\r
+       if(idx != -1) {\r
+               if(_ismethod(oval)) {\r
+                       outval = _methods[_member_idx(oval)].val;\r
+               }\r
+               else {\r
+                       SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;\r
+                       outval = _realval(o);\r
+               }\r
+       }\r
+       return idx;\r
+}\r
+\r
+bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)\r
+{\r
+       SQObjectPtr idx;\r
+       if(_members->Get(key,idx)) {\r
+               if(_isfield(idx))\r
+                       _defaultvalues[_member_idx(idx)].attrs = val;\r
+               else\r
+                       _methods[_member_idx(idx)].attrs = val;\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)\r
+{\r
+       SQObjectPtr idx;\r
+       if(_members->Get(key,idx)) {\r
+               outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////\r
+void SQInstance::Init(SQSharedState *ss)\r
+{\r
+       _userpointer = NULL;\r
+       _hook = NULL;\r
+       __ObjAddRef(_class);\r
+       _delegate = _class->_members;\r
+       INIT_CHAIN();\r
+       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);\r
+}\r
+\r
+SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)\r
+{\r
+       _memsize = memsize;\r
+       _class = c;\r
+       _nvalues = _class->_defaultvalues.size();\r
+       for(SQUnsignedInteger n = 0; n < _nvalues; n++) {\r
+               new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);\r
+       }\r
+       Init(ss);\r
+}\r
+\r
+SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)\r
+{\r
+       _memsize = memsize;\r
+       _class = i->_class;\r
+       _nvalues = _class->_defaultvalues.size();\r
+       for(SQUnsignedInteger n = 0; n < _nvalues; n++) {\r
+               new (&_values[n]) SQObjectPtr(i->_values[n]);\r
+       }\r
+       Init(ss);\r
+}\r
+\r
+void SQInstance::Finalize() \r
+{\r
+       __ObjRelease(_class);\r
+       for(SQUnsignedInteger i = 0; i < _nvalues; i++) {\r
+               _values[i] = _null_;\r
+       }\r
+}\r
+\r
+SQInstance::~SQInstance()\r
+{\r
+       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
+       Finalize();\r
+}\r
+\r
+bool SQInstance::GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res)\r
+{\r
+       if(type(_class->_metamethods[mm]) != OT_NULL) {\r
+               res = _class->_metamethods[mm];\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+bool SQInstance::InstanceOf(SQClass *trg)\r
+{\r
+       SQClass *parent = _class;\r
+       while(parent != NULL) {\r
+               if(parent == trg)\r
+                       return true;\r
+               parent = parent->_base;\r
+       }\r
+       return false;\r
+}\r
index 5c12d7e..3ef4f19 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQCLASS_H_
-#define _SQCLASS_H_
-
-struct SQInstance;
-
-struct SQClassMemeber {
-       SQClassMemeber(){}
-       SQClassMemeber(const SQClassMemeber &o) {
-               val = o.val;
-               attrs = o.attrs;
-       }
-       SQObjectPtr val;
-       SQObjectPtr attrs;
-};
-
-typedef sqvector<SQClassMemeber> SQClassMemeberVec;
-
-struct SQClass : public CHAINABLE_OBJ
-{
-       SQClass(SQSharedState *ss,SQClass *base);
-public:
-       static SQClass* Create(SQSharedState *ss,SQClass *base) {
-               SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
-               new (newclass) SQClass(ss, base);
-               return newclass;
-       }
-       ~SQClass();
-       bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
-       bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
-               if(_members->Get(key,val)) {
-                       val = (type(val) == OT_INTEGER?_defaultvalues[_integer(val)].val:_methods[(int)_userpointer(val)].val);
-                       return true;
-               }
-               return false;
-       }
-       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() { sq_delete(this, SQClass);      }
-       void Finalize();
-       void Mark(SQCollectable ** );
-       int Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-       SQInstance *CreateInstance();
-       SQTable *_members;
-       //SQTable *_properties;
-       SQClass *_base;
-       SQClassMemeberVec _defaultvalues;
-       SQClassMemeberVec _methods;
-       SQObjectPtrVec _metamethods;
-       SQObjectPtr _attributes;
-       unsigned int _typetag;
-       bool _locked;
-};
-
-struct SQInstance : public SQDelegable 
-{
-       void Init(SQSharedState *ss);
-       SQInstance(SQSharedState *ss, SQClass *c);
-       SQInstance(SQSharedState *ss, SQInstance *c);
-public:
-       static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
-               SQInstance *newinst = (SQInstance *)SQ_MALLOC(sizeof(SQInstance));
-               new (newinst) SQInstance(ss, theclass);
-               return newinst;
-       }
-       SQInstance *Clone(SQSharedState *ss)
-       {
-               SQInstance *newinst = (SQInstance *)SQ_MALLOC(sizeof(SQInstance));
-               new (newinst) SQInstance(ss, this);
-               return newinst;
-       }
-       ~SQInstance();
-       bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {
-               if(_class->_members->Get(key,val)) {
-                       val = (type(val) == OT_INTEGER?_values[_integer(val)]:_class->_methods[(int)_userpointer(val)].val);
-                       return true;
-               }
-               return false;
-       }
-       bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
-               SQObjectPtr idx;
-               if(_class->_members->Get(key,idx) && type(idx) == OT_INTEGER) {
-            _values[_integer(idx)] = val;
-                       return true;
-               }
-               return false;
-       }
-       void Release() { 
-               if (_hook) { _hook(_userpointer,0);}
-               sq_delete(this, SQInstance);
-       }
-       void Finalize();
-       void Mark(SQCollectable ** );
-       bool InstanceOf(SQClass *trg);
-       bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res);
-
-       SQClass *_class;
-       SQUserPointer _userpointer;
-       SQRELEASEHOOK _hook;
-       SQObjectPtrVec _values;
-};
-
-#endif //_SQCLASS_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQCLASS_H_\r
+#define _SQCLASS_H_\r
+\r
+struct SQInstance;\r
+\r
+struct SQClassMemeber {\r
+       SQClassMemeber(){}\r
+       SQClassMemeber(const SQClassMemeber &o) {\r
+               val = o.val;\r
+               attrs = o.attrs;\r
+       }\r
+       SQObjectPtr val;\r
+       SQObjectPtr attrs;\r
+};\r
+\r
+typedef sqvector<SQClassMemeber> SQClassMemeberVec;\r
+\r
+#define MEMBER_TYPE_METHOD 0x01000000\r
+#define MEMBER_TYPE_FIELD 0x02000000\r
+\r
+#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)\r
+#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)\r
+#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))\r
+#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))\r
+#define _member_type(o) (_integer(o)&0xFF000000)\r
+#define _member_idx(o) (_integer(o)&0x00FFFFFF)\r
+\r
+struct SQClass : public CHAINABLE_OBJ\r
+{\r
+       SQClass(SQSharedState *ss,SQClass *base);\r
+public:\r
+       static SQClass* Create(SQSharedState *ss,SQClass *base) {\r
+               SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));\r
+               new (newclass) SQClass(ss, base);\r
+               return newclass;\r
+       }\r
+       ~SQClass();\r
+       bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);\r
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val) {\r
+               if(_members->Get(key,val)) {\r
+                       if(_isfield(val)) {\r
+                               SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;\r
+                               val = _realval(o);\r
+                       }\r
+                       else {\r
+                               val = _methods[_member_idx(val)].val;\r
+                       }\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);\r
+       bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);\r
+       void Lock() { _locked = true; if(_base) _base->Lock(); }\r
+       void Release() { sq_delete(this, SQClass);      }\r
+       void Finalize();\r
+       void Mark(SQCollectable ** );\r
+       SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
+       SQInstance *CreateInstance();\r
+       SQTable *_members;\r
+       //SQTable *_properties;\r
+       SQClass *_base;\r
+       SQClassMemeberVec _defaultvalues;\r
+       SQClassMemeberVec _methods;\r
+       SQObjectPtrVec _metamethods;\r
+       SQObjectPtr _attributes;\r
+       SQUserPointer _typetag;\r
+       bool _locked;\r
+};\r
+\r
+#define calcinstancesize(_theclass_) \\r
+       (sizeof(SQInstance)+(sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))\r
+struct SQInstance : public SQDelegable \r
+{\r
+       void Init(SQSharedState *ss);\r
+       SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);\r
+       SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);\r
+public:\r
+       static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {\r
+               \r
+               SQInteger size = calcinstancesize(theclass);\r
+               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
+               new (newinst) SQInstance(ss, theclass,size);\r
+               return newinst;\r
+       }\r
+       SQInstance *Clone(SQSharedState *ss)\r
+       {\r
+               SQInteger size = calcinstancesize(_class);\r
+               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
+               new (newinst) SQInstance(ss, this,size);\r
+               return newinst;\r
+       }\r
+       ~SQInstance();\r
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {\r
+               if(_class->_members->Get(key,val)) {\r
+                       if(_isfield(val)) {\r
+                               SQObjectPtr &o = _values[_member_idx(val)];\r
+                               val = _realval(o);\r
+                       }\r
+                       else {\r
+                               val = _class->_methods[_member_idx(val)].val;\r
+                       }\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {\r
+               SQObjectPtr idx;\r
+               if(_class->_members->Get(key,idx) && _isfield(idx)) {\r
+            _values[_member_idx(idx)] = val;\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       void Release() { \r
+               if (_hook) { _hook(_userpointer,0);}\r
+               SQInteger size = _memsize;\r
+               this->~SQInstance();\r
+               SQ_FREE(this, size);\r
+       }\r
+       void Finalize();\r
+       void Mark(SQCollectable ** );\r
+       bool InstanceOf(SQClass *trg);\r
+       bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res);\r
+\r
+       SQClass *_class;\r
+       SQUserPointer _userpointer;\r
+       SQRELEASEHOOK _hook;\r
+       SQUnsignedInteger _nvalues;\r
+       SQInteger _memsize;\r
+       SQObjectPtr _values[1];\r
+};\r
+\r
+#endif //_SQCLASS_H_\r
index 1ce8d10..8565621 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQCLOSURE_H_
-#define _SQCLOSURE_H_
-
-struct SQFunctionProto;
-
-struct SQClosure : public CHAINABLE_OBJ
-{
-private:
-       SQClosure(SQSharedState *ss,SQFunctionProto *func){_uiRef=0;_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
-       static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
-               SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));
-               new (nc) SQClosure(ss,func);
-               return nc;
-       }
-       void Release(){
-               sq_delete(this,SQClosure);
-       }
-       ~SQClosure()
-       {
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-       }
-       bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
-       bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read);
-#ifndef NO_GARBAGE_COLLECTOR
-       void Mark(SQCollectable **chain);
-       void Finalize(){_outervalues.resize(0); }
-#endif
-       SQObjectPtr _function;
-       SQObjectPtrVec _outervalues;
-};
-//////////////////////////////////////////////
-struct SQGenerator : public CHAINABLE_OBJ 
-{
-       enum SQGeneratorState{eRunning,eSuspended,eDead};
-private:
-       SQGenerator(SQSharedState *ss,SQClosure *closure){_uiRef=0;_closure=closure;_state=eRunning;_ci._generator=_null_;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
-       static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
-               SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
-               new (nc) SQGenerator(ss,closure);
-               return nc;
-       }
-       ~SQGenerator()
-       {
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-       }
-    void Kill(){
-               _state=eDead;
-               _stack.resize(0);
-               _closure=_null_;}
-       void Release(){
-               sq_delete(this,SQGenerator);
-       }
-       bool Yield(SQVM *v);
-       bool Resume(SQVM *v,int target);
-#ifndef NO_GARBAGE_COLLECTOR
-       void Mark(SQCollectable **chain);
-       void Finalize(){_stack.resize(0);_closure=_null_;}
-#endif
-       SQObjectPtr _closure;
-       SQObjectPtrVec _stack;
-       SQObjectPtrVec _vargsstack;
-       SQVM::CallInfo _ci;
-       ExceptionsTraps _etraps;
-       SQGeneratorState _state;
-};
-
-struct SQNativeClosure : public CHAINABLE_OBJ
-{
-private:
-       SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_uiRef=0;_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);       }
-public:
-       static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)
-       {
-               SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));
-               new (nc) SQNativeClosure(ss,func);
-               return nc;
-       }
-       ~SQNativeClosure()
-       {
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-       }
-       void Release(){
-               sq_delete(this,SQNativeClosure);
-       }
-#ifndef NO_GARBAGE_COLLECTOR
-       void Mark(SQCollectable **chain);
-       void Finalize(){_outervalues.resize(0);}
-#endif
-       SQFUNCTION _function;
-       SQObjectPtr _name;
-       SQObjectPtrVec _outervalues;
-       SQIntVec _typecheck;
-       int _nparamscheck;
-};
-
-
-
-#endif //_SQCLOSURE_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQCLOSURE_H_\r
+#define _SQCLOSURE_H_\r
+\r
+struct SQFunctionProto;\r
+\r
+struct SQClosure : public CHAINABLE_OBJ\r
+{\r
+private:\r
+       SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}\r
+public:\r
+       static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){\r
+               SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));\r
+               new (nc) SQClosure(ss,func);\r
+               return nc;\r
+       }\r
+       void Release(){\r
+               sq_delete(this,SQClosure);\r
+       }\r
+       ~SQClosure()\r
+       {\r
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
+       }\r
+       bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);\r
+       bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read);\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       void Mark(SQCollectable **chain);\r
+       void Finalize(){_outervalues.resize(0); }\r
+#endif\r
+       SQObjectPtr _function;\r
+       SQObjectPtrVec _outervalues;\r
+};\r
+//////////////////////////////////////////////\r
+struct SQGenerator : public CHAINABLE_OBJ \r
+{\r
+       enum SQGeneratorState{eRunning,eSuspended,eDead};\r
+private:\r
+       SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=_null_;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}\r
+public:\r
+       static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){\r
+               SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));\r
+               new (nc) SQGenerator(ss,closure);\r
+               return nc;\r
+       }\r
+       ~SQGenerator()\r
+       {\r
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
+       }\r
+    void Kill(){\r
+               _state=eDead;\r
+               _stack.resize(0);\r
+               _closure=_null_;}\r
+       void Release(){\r
+               sq_delete(this,SQGenerator);\r
+       }\r
+       bool Yield(SQVM *v);\r
+       bool Resume(SQVM *v,SQInteger target);\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       void Mark(SQCollectable **chain);\r
+       void Finalize(){_stack.resize(0);_closure=_null_;}\r
+#endif\r
+       SQObjectPtr _closure;\r
+       SQObjectPtrVec _stack;\r
+       SQObjectPtrVec _vargsstack;\r
+       SQVM::CallInfo _ci;\r
+       ExceptionsTraps _etraps;\r
+       SQGeneratorState _state;\r
+};\r
+\r
+struct SQNativeClosure : public CHAINABLE_OBJ\r
+{\r
+private:\r
+       SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);        }\r
+public:\r
+       static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)\r
+       {\r
+               SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));\r
+               new (nc) SQNativeClosure(ss,func);\r
+               return nc;\r
+       }\r
+       ~SQNativeClosure()\r
+       {\r
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
+       }\r
+       void Release(){\r
+               sq_delete(this,SQNativeClosure);\r
+       }\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       void Mark(SQCollectable **chain);\r
+       void Finalize(){_outervalues.resize(0);}\r
+#endif\r
+       SQFUNCTION _function;\r
+       SQObjectPtr _name;\r
+       SQObjectPtrVec _outervalues;\r
+       SQIntVec _typecheck;\r
+       SQInteger _nparamscheck;\r
+};\r
+\r
+\r
+\r
+#endif //_SQCLOSURE_H_\r
index 1f20728..ed99a73 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include <setjmp.h>
-#include "sqopcodes.h"
-#include "sqstring.h"
-#include "sqfuncproto.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqlexer.h"
-#include "sqvm.h"
-
-#define DEREF_NO_DEREF -1
-#define DEREF_FIELD            -2
-
-struct ExpState
-{
-       ExpState()
-       {
-               _deref = DEREF_NO_DEREF;
-               _freevar = false;
-               _class_or_delete = false;
-               _funcarg = false;
-       }
-       bool _class_or_delete;
-       bool _funcarg;
-       bool _freevar;
-       int _deref;
-};
-
-typedef sqvector<ExpState> ExpStateVec;
-
-#define _exst (_expstates.top())
-
-#define BEGIN_BREAKBLE_BLOCK() int __nbreaks__=_fs->_unresolvedbreaks.size(); \
-                                                       int __ncontinues__=_fs->_unresolvedcontinues.size(); \
-                                                       _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
-
-#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
-                                       __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \
-                                       if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \
-                                       if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
-                                       _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}
-
-class SQCompiler
-{
-public:
-       SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
-       {
-               _vm=v;
-               _lex.Init(_ss(v), rg, up,ThrowError,this);
-               _sourcename = SQString::Create(_ss(v), sourcename);
-               _lineinfo = lineinfo;_raiseerror = raiseerror;
-               compilererror = NULL;
-       }
-       static void ThrowError(void *ud, const SQChar *s) {
-               SQCompiler *c = (SQCompiler *)ud;
-               c->Error(s);
-       }
-       void Error(const SQChar *s, ...)
-       {
-               static SQChar temp[256];
-               va_list vl;
-               va_start(vl, s);
-               scvsprintf(temp, s, vl);
-               va_end(vl);
-               compilererror = temp;
-               longjmp(_errorjmp,1);
-       }
-       void Lex(){     _token = _lex.Lex();}
-       void PushExpState(){ _expstates.push_back(ExpState()); }
-       bool IsDerefToken(int tok)
-       {
-               switch(tok){
-               case _SC('='): case _SC('('): case TK_NEWSLOT:
-               case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;
-               }
-               return false;
-       }
-       ExpState PopExpState()
-       {
-               ExpState ret = _expstates.top();
-               _expstates.pop_back();
-               return ret;
-       }
-       SQObject Expect(int tok)
-       {
-               
-               if(_token != tok) {
-                       if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
-                               //ret = SQString::Create(_ss(_vm),_SC("constructor"));
-                               //do nothing
-                       }
-                       else {
-                               const SQChar *etypename;
-                               if(tok > 255) {
-                                       switch(tok)
-                                       {
-                                       case TK_IDENTIFIER:
-                                               etypename = _SC("IDENTIFIER");
-                                               break;
-                                       case TK_STRING_LITERAL:
-                                               etypename = _SC("STRING_LITERAL");
-                                               break;
-                                       case TK_INTEGER:
-                                               etypename = _SC("INTEGER");
-                                               break;
-                                       case TK_FLOAT:
-                                               etypename = _SC("FLOAT");
-                                               break;
-                                       default:
-                                               etypename = _lex.Tok2Str(tok);
-                                       }
-                                       Error(_SC("expected '%s'"), etypename);
-                               }
-                               Error(_SC("expected '%c'"), tok);
-                       }
-               }
-               SQObjectPtr ret;
-               switch(tok)
-               {
-               case TK_IDENTIFIER:
-                       ret = _fs->CreateString(_lex._svalue);
-                       break;
-               case TK_STRING_LITERAL:
-                       ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
-                       break;
-               case TK_INTEGER:
-                       ret = SQObjectPtr(_lex._nvalue);
-                       break;
-               case TK_FLOAT:
-                       ret = SQObjectPtr(_lex._fvalue);
-                       break;
-               }
-               Lex();
-               return ret;
-       }
-       bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }
-       void OptionalSemicolon()
-       {
-               if(_token == _SC(';')) { Lex(); return; }
-               if(!IsEndOfStatement()) {
-                       Error(_SC("end of statement expected (; or lf)"));
-               }
-       }
-       void MoveIfCurrentTargetIsLocal() {
-               int trg = _fs->TopTarget();
-               if(_fs->IsLocal(trg)) {
-                       trg = _fs->PopTarget(); //no pops the target and move it
-                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
-               }
-       }
-       bool Compile(SQObjectPtr &o)
-       {
-               _debugline = 1;
-               _debugop = 0;
-
-               SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), NULL,ThrowError,this);
-               _funcproto(funcstate._func)->_name = SQString::Create(_ss(_vm), _SC("main"));
-               _fs = &funcstate;
-               _fs->AddParameter(_fs->CreateString(_SC("this")));
-               _funcproto(_fs->_func)->_sourcename = _sourcename;
-               int stacksize = _fs->GetStackSize();
-               if(setjmp(_errorjmp) == 0) {
-                       Lex();
-                       while(_token > 0){
-                               Statement();
-                               if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
-                       }
-                       CleanStack(stacksize);
-                       _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
-                       _fs->AddInstruction(_OP_RETURN, 0xFF);
-                       _funcproto(_fs->_func)->_stacksize = _fs->_stacksize;
-                       _fs->SetStackSize(0);
-                       _fs->Finalize();
-                       o = _fs->_func;
-#ifdef _DEBUG_DUMP
-                       _fs->Dump();
-#endif
-               }
-               else {
-                       if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
-                               _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
-                                       _lex._currentline, _lex._currentcolumn);
-                       }
-                       _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
-                       return false;
-               }
-               return true;
-       }
-       void Statements()
-       {
-               while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
-                       Statement();
-                       if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
-               }
-       }
-       void Statement()
-       {
-               _fs->AddLineInfos(_lex._currentline, _lineinfo);
-               switch(_token){
-               case _SC(';'):  Lex();                                  break;
-               case TK_IF:             IfStatement();                  break;
-               case TK_WHILE:          WhileStatement();               break;
-               case TK_DO:             DoWhileStatement();             break;
-               case TK_FOR:            ForStatement();                 break;
-               case TK_FOREACH:        ForEachStatement();             break;
-               case TK_SWITCH: SwitchStatement();              break;
-               case TK_LOCAL:          LocalDeclStatement();   break;
-               case TK_RETURN:
-               case TK_YIELD: {
-                       SQOpcode op;
-                       if(_token == TK_RETURN) {
-                               op = _OP_RETURN;
-                               
-                       }
-                       else {
-                               op = _OP_YIELD;
-                               _funcproto(_fs->_func)->_bgenerator = true;
-                       }
-                       Lex();
-                       if(!IsEndOfStatement()) {
-                               int retexp = _fs->GetCurrentPos()+1;
-                               CommaExpr();
-                               if(op == _OP_RETURN && _fs->_traps > 0)
-                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
-                               _fs->_returnexp = retexp;
-                               _fs->AddInstruction(op, 1, _fs->PopTarget());
-                       }
-                       else{ 
-                               if(op == _OP_RETURN && _fs->_traps > 0)
-                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
-                               _fs->_returnexp = -1;
-                               _fs->AddInstruction(op, 0xFF); 
-                       }
-                       break;}
-               case TK_BREAK:
-                       if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));
-                       if(_fs->_breaktargets.top() > 0){
-                               _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);
-                       }
-                       _fs->AddInstruction(_OP_JMP, 0, -1234);
-                       _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());
-                       Lex();
-                       break;
-               case TK_CONTINUE:
-                       if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));
-                       if(_fs->_continuetargets.top() > 0) {
-                               _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);
-                       }
-                       _fs->AddInstruction(_OP_JMP, 0, -1234);
-                       _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());
-                       Lex();
-                       break;
-               case TK_FUNCTION:
-                       FunctionStatement();
-                       break;
-               case TK_CLASS:
-                       ClassStatement();
-                       break;
-               case _SC('{'):{
-                               int stacksize = _fs->GetStackSize();
-                               Lex();
-                               Statements();
-                               Expect(_SC('}'));
-                               _fs->SetStackSize(stacksize);
-                       }
-                       break;
-               case TK_TRY:
-                       TryCatchStatement();
-                       break;
-               case TK_THROW:
-                       Lex();
-                       CommaExpr();
-                       _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
-                       break;
-               default:
-                       CommaExpr();
-                       _fs->PopTarget();
-                       break;
-               }
-               _fs->SnoozeOpt();
-       }
-       void EmitDerefOp(SQOpcode op)
-       {
-               int val = _fs->PopTarget();
-               int key = _fs->PopTarget();
-               int src = _fs->PopTarget();
-        _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
-       }
-       void Emit2ArgsOP(SQOpcode op, int p3 = 0)
-       {
-               int p2 = _fs->PopTarget(); //src in OP_GET
-               int p1 = _fs->PopTarget(); //key in OP_GET
-               _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
-       }
-       void EmitCompoundArith(int tok,bool deref)
-       {
-               int oper;
-               switch(tok){
-               case TK_MINUSEQ: oper = '-'; break;
-               case TK_PLUSEQ: oper = '+'; break;
-               case TK_MULEQ: oper = '*'; break;
-               case TK_DIVEQ: oper = '/'; break;
-               case TK_MODEQ: oper = '%'; break;
-               default: assert(0); break;
-               };
-               if(deref) {
-                       int val = _fs->PopTarget();
-                       int key = _fs->PopTarget();
-                       int src = _fs->PopTarget();
-                       //mixes dest obj and source val in the arg1(hack?)
-                       _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);
-               }
-               else {
-                       Emit2ArgsOP(_OP_COMPARITHL, oper);
-               }
-       }
-       void CommaExpr()
-       {
-               for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());
-       }
-       ExpState Expression(bool funcarg = false)
-       {
-               PushExpState();
-               _exst._class_or_delete = false;
-               _exst._funcarg = funcarg;
-               LogicalOrExp();
-               switch(_token)  {
-               case _SC('='):
-               case TK_NEWSLOT:
-               case TK_MINUSEQ:
-               case TK_PLUSEQ:
-               case TK_MULEQ:
-               case TK_DIVEQ:
-               case TK_MODEQ:
-               {
-                               int op = _token;
-                               int ds = _exst._deref;
-                               bool freevar = _exst._freevar;
-                               if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));
-                               Lex(); Expression();
-
-                               switch(op){
-                               case TK_NEWSLOT:
-                                       if(freevar) Error(_SC("free variables cannot be modified"));
-                                       if(ds == DEREF_FIELD)
-                                               EmitDerefOp(_OP_NEWSLOT);
-                                       else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
-                                               Error(_SC("can't 'create' a local slot"));
-                                       break;
-                               case _SC('='): //ASSIGN
-                                       if(freevar) Error(_SC("free variables cannot be modified"));
-                                       if(ds == DEREF_FIELD)
-                                               EmitDerefOp(_OP_SET);
-                                       else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
-                                               int p2 = _fs->PopTarget(); //src in OP_GET
-                                               int p1 = _fs->TopTarget(); //key in OP_GET
-                                               _fs->AddInstruction(_OP_MOVE, p1, p2);
-                                       }
-                                       break;
-                               case TK_MINUSEQ:
-                               case TK_PLUSEQ:
-                               case TK_MULEQ:
-                               case TK_DIVEQ:
-                               case TK_MODEQ:
-                                       EmitCompoundArith(op,ds == DEREF_FIELD);
-                                       break;
-                               }
-                       }
-                       break;
-               case _SC('?'): {
-                       Lex();
-                       _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
-                       int jzpos = _fs->GetCurrentPos();
-                       int trg = _fs->PushTarget();
-                       Expression();
-                       int first_exp = _fs->PopTarget();
-                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
-                       int endfirstexp = _fs->GetCurrentPos();
-                       _fs->AddInstruction(_OP_JMP, 0, 0);
-                       Expect(_SC(':'));
-                       int jmppos = _fs->GetCurrentPos();
-                       Expression();
-                       int second_exp = _fs->PopTarget();
-                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
-                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
-                       _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
-                       _fs->SnoozeOpt();
-                       }
-                       break;
-               }
-               return PopExpState();
-       }
-       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),int op3 = 0)
-       {
-               Lex(); (this->*f)();
-               int op1 = _fs->PopTarget();int op2 = _fs->PopTarget();
-               _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
-       }
-       void LogicalOrExp()
-       {
-               LogicalAndExp();
-               for(;;) if(_token == TK_OR) {
-                       int first_exp = _fs->PopTarget();
-                       int trg = _fs->PushTarget();
-                       _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
-                       int jpos = _fs->GetCurrentPos();
-                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
-                       Lex(); LogicalOrExp();
-                       _fs->SnoozeOpt();
-                       int second_exp = _fs->PopTarget();
-                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
-                       _fs->SnoozeOpt();
-                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
-                       break;
-               }else return;
-       }
-       void LogicalAndExp()
-       {
-               BitwiseOrExp();
-               for(;;) switch(_token) {
-               case TK_AND: {
-                       int first_exp = _fs->PopTarget();
-                       int trg = _fs->PushTarget();
-                       _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
-                       int jpos = _fs->GetCurrentPos();
-                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
-                       Lex(); LogicalAndExp();
-                       _fs->SnoozeOpt();
-                       int second_exp = _fs->PopTarget();
-                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
-                       _fs->SnoozeOpt();
-                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
-                       break;
-                       }
-               case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;
-               case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;
-               default:
-                       return;
-               }
-       }
-       void BitwiseOrExp()
-       {
-               BitwiseXorExp();
-               for(;;) if(_token == _SC('|'))
-               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);
-               }else return;
-       }
-       void BitwiseXorExp()
-       {
-               BitwiseAndExp();
-               for(;;) if(_token == _SC('^'))
-               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);
-               }else return;
-       }
-       void BitwiseAndExp()
-       {
-               CompExp();
-               for(;;) if(_token == _SC('&'))
-               {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);
-               }else return;
-       }
-       void CompExp()
-       {
-               ShiftExp();
-               for(;;) switch(_token) {
-               case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;
-               case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;
-               case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;
-               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;        
-               }
-       }
-       void ShiftExp()
-       {
-               PlusExp();
-               for(;;) switch(_token) {
-               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;        
-               }
-       }
-       void PlusExp()
-       {
-               MultExp();
-               for(;;) switch(_token) {
-               case _SC('+'): case _SC('-'):
-                       BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;
-               default: return;
-               }
-       }
-       
-       void MultExp()
-       {
-               PrefixedExpr();
-               for(;;) switch(_token) {
-               case _SC('*'): case _SC('/'): case _SC('%'):
-                       BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;
-               default: return;
-               }
-       }
-       //if 'pos' != -1 the previous variable is a local variable
-       void PrefixedExpr()
-       {
-               int pos = Factor();
-               for(;;) {
-                       switch(_token) {
-                       case _SC('.'): {
-                               pos = -1;
-                               Lex(); 
-                               if(_token == TK_PARENT) {
-                                       Lex();
-                                       if(!NeedGet())
-                                               Error(_SC("parent cannot be set"));
-                                       int src = _fs->PopTarget();
-                                       _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
-                               }
-                               else {
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
-                                       if(NeedGet()) Emit2ArgsOP(_OP_GET);
-                               }
-                               _exst._deref = DEREF_FIELD;
-                               _exst._freevar = false;
-                               }
-                               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(']')); 
-                               pos = -1;
-                               if(NeedGet()) Emit2ArgsOP(_OP_GET);
-                               _exst._deref = DEREF_FIELD;
-                               _exst._freevar = false;
-                               break;
-                       case TK_MINUSMINUS:
-                       case TK_PLUSPLUS:
-                       if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { 
-                               int tok = _token; Lex();
-                               if(pos < 0)
-                                       Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
-                               else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
-                                       int src = _fs->PopTarget();
-                                       _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
-                               }
-                               
-                       }
-                       return;
-                       break;  
-                       case _SC('('): 
-                               {
-                               if(_exst._deref != DEREF_NO_DEREF) {
-                                       if(pos<0) {
-                                               int key = _fs->PopTarget(); //key
-                                               int table = _fs->PopTarget(); //table etc...
-                                               int closure = _fs->PushTarget();
-                                               int ttarget = _fs->PushTarget();
-                                               _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
-                                       }
-                                       else{
-                                               _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
-                                       }
-                               }
-                               else
-                                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
-                               _exst._deref = DEREF_NO_DEREF;
-                               Lex();
-                               FunctionCallArgs();
-                                }
-                               break;
-                       default: return;
-                       }
-               }
-       }
-       int Factor()
-       {
-               switch(_token)
-               {
-               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(); 
-                       }
-                       break;
-               case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
-               case TK_VARGV: { Lex();
-                       Expect(_SC('['));
-                       Expression();
-                       Expect(_SC(']'));
-                       int src = _fs->PopTarget();
-                       _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);
-                                          }
-                       break;
-               case TK_IDENTIFIER:
-               case TK_CONSTRUCTOR:
-               case TK_THIS:{
-                       _exst._freevar = false;
-                       SQObject id;
-                               switch(_token) {
-                                       case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
-                                       case TK_THIS: id = _fs->CreateString(_SC("this")); break;
-                                       case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
-                               }
-                               int pos = -1;
-                               Lex();
-                               if((pos = _fs->GetLocalVariable(id)) == -1) {
-                                       //checks if is a free variable
-                                       if((pos = _fs->GetOuterVariable(id)) != -1) {
-                                               _exst._deref = _fs->PushTarget();
-                                               _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);        
-                                               _exst._freevar = true;
-                                       } else {
-                                               _fs->PushTarget(0);
-                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
-                                               if(NeedGet()) Emit2ArgsOP(_OP_GET);
-                                               _exst._deref = DEREF_FIELD;
-                                       }
-                               }
-                               else{
-                                       _fs->PushTarget(pos);
-                                       _exst._deref = pos;
-                               }
-                               return _exst._deref;
-                       }
-                       break;
-               case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;
-               case TK_DOUBLE_COLON:  // "::"
-                       _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());
-                       _exst._deref = DEREF_FIELD;
-                       _token = _SC('.'); //hack
-                       return -1;
-                       break;
-               case TK_NULL: 
-                       _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
-                       Lex();
-                       break;
-               case TK_INTEGER: 
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
-                       Lex();
-                       break;
-               case TK_FLOAT: 
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
-                       Lex();
-                       break;
-               case TK_TRUE: case TK_FALSE:
-                       _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);
-                       Lex();
-                       break;
-               case _SC('['): {
-                               _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());
-                               int apos = _fs->GetCurrentPos(),key = 0;
-                               Lex();
-                               while(_token != _SC(']')) {
-                    Expression(); 
-                                       if(_token == _SC(',')) Lex();
-                                       int val = _fs->PopTarget();
-                                       int array = _fs->TopTarget();
-                                       _fs->AddInstruction(_OP_APPENDARRAY, array, val);
-                                       key++;
-                               }
-                               _fs->SetIntructionParam(apos, 1, key);
-                               Lex();
-                       }
-                       break;
-               case _SC('{'):{
-                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
-                       Lex();ParseTableOrClass(_SC(','));
-                                }
-                       break;
-               case TK_FUNCTION: FunctionExp(_token);break;
-               case TK_CLASS: Lex(); ClassExp();break;
-               case _SC('-'): UnaryOP(_OP_NEG); break;
-               case _SC('!'): UnaryOP(_OP_NOT); break;
-               case _SC('~'): UnaryOP(_OP_BWNOT); break;
-               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_PLUSPLUS :PrefixIncDec(_token); break;
-               case TK_DELETE : DeleteExpr(); break;
-               case TK_DELEGATE : DelegateExpr(); break;
-               case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));
-                       break;
-               default: Error(_SC("expression expected"));
-               }
-               return -1;
-       }
-       void UnaryOP(SQOpcode op)
-       {
-               Lex(); PrefixedExpr();
-               int src = _fs->PopTarget();
-               _fs->AddInstruction(op, _fs->PushTarget(), src);
-       }
-       bool NeedGet()
-       {
-               switch(_token) {
-               case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:
-               case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:
-                       return false;
-               }
-               return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
-       }
-       
-       void FunctionCallArgs()
-       {
-               int nargs = 1;//this
-                while(_token != _SC(')')) {
-                        Expression(true);
-                        MoveIfCurrentTargetIsLocal();
-                        nargs++; 
-                        if(_token == _SC(',')){ 
-                                Lex(); 
-                                if(_token == ')') Error(_SC("expression expected, found ')'"));
-                        }
-                }
-                Lex();
-                for(int i = 0; i < (nargs - 1); i++) _fs->PopTarget();
-                int stackbase = _fs->PopTarget();
-                int closure = _fs->PopTarget();
-         _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
-       }
-       void ParseTableOrClass(int separator,int terminator = '}')
-       {
-               int tpos = _fs->GetCurrentPos(),nkeys = 0;
-               
-               while(_token != terminator) {
-                       bool hasattrs = false;
-                       //check if is an attribute
-                       if(separator == ';' && _token == TK_ATTR_OPEN) {
-                               _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
-                               ParseTableOrClass(',',TK_ATTR_CLOSE);
-                               hasattrs = true;
-                       }
-                       switch(_token) {
-                               case TK_FUNCTION:
-                               case TK_CONSTRUCTOR:{
-                                       int tk = _token;
-                                       Lex();
-                                       SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
-                                       Expect(_SC('('));
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
-                                       CreateFunction(id);
-                                       _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
-                                                                 }
-                                                                 break;
-                               case _SC('['):
-                                       Lex(); CommaExpr(); Expect(_SC(']'));
-                                       Expect(_SC('=')); Expression();
-                                       break;
-                               default :
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
-                                       Expect(_SC('=')); Expression();
-                       }
-
-                       if(_token == separator) Lex();//optional comma/semicolon
-                       nkeys++;
-                       int val = _fs->PopTarget();
-                       int key = _fs->PopTarget();
-                       int attrs = hasattrs ? _fs->PopTarget():-1;
-                       assert(hasattrs && attrs == key-1 || !hasattrs);
-                       int table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
-                       _fs->AddInstruction(hasattrs?_OP_NEWSLOTA:_OP_NEWSLOT, _fs->PushTarget(), table, key, val);
-                       _fs->PopTarget();
-               }
-               if(separator == _SC(',')) //hack recognizes a table from the separator
-                       _fs->SetIntructionParam(tpos, 1, nkeys);
-               Lex();
-       }
-       void LocalDeclStatement()
-       {
-               SQObject varname;
-               do {
-                       Lex(); varname = Expect(TK_IDENTIFIER);
-                       if(_token == _SC('=')) {
-                               Lex(); Expression();
-                               int src = _fs->PopTarget();
-                               int dest = _fs->PushTarget();
-                               if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
-                       }
-                       else{
-                               _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
-                       }
-                       _fs->PopTarget();
-                       _fs->PushLocalVariable(varname);
-               
-               } while(_token == _SC(','));
-       }
-       void IfStatement()
-       {
-               int jmppos;
-               bool haselse = false;
-               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-               _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
-               int jnepos = _fs->GetCurrentPos();
-               int stacksize = _fs->GetStackSize();
-               
-               Statement();
-               //
-               if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
-               
-               CleanStack(stacksize);
-               int endifblock = _fs->GetCurrentPos();
-               if(_token == TK_ELSE){
-                       haselse = true;
-                       stacksize = _fs->GetStackSize();
-                       _fs->AddInstruction(_OP_JMP);
-                       jmppos = _fs->GetCurrentPos();
-                       Lex();
-                       Statement(); OptionalSemicolon();
-                       CleanStack(stacksize);
-                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
-               }
-               _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));
-       }
-       void WhileStatement()
-       {
-               int jzpos, jmppos;
-               int 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()
-       {
-               Lex();
-               int jzpos = _fs->GetCurrentPos();
-               int stacksize = _fs->GetStackSize();
-               BEGIN_BREAKBLE_BLOCK()
-               Statement();
-               CleanStack(stacksize);
-               Expect(TK_WHILE);
-               int continuetrg = _fs->GetCurrentPos();
-               Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-               _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);
-               END_BREAKBLE_BLOCK(continuetrg);
-       }
-       void ForStatement()
-       {
-               Lex();
-               int stacksize = _fs->GetStackSize();
-               Expect(_SC('('));
-               if(_token == TK_LOCAL) LocalDeclStatement();
-               else if(_token != _SC(';')){
-                       CommaExpr();
-                       _fs->PopTarget();
-               }
-               Expect(_SC(';'));
-               _fs->SnoozeOpt();
-               int jmppos = _fs->GetCurrentPos();
-               int jzpos = -1;
-               if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
-               Expect(_SC(';'));
-               _fs->SnoozeOpt();
-               int expstart = _fs->GetCurrentPos() + 1;
-               if(_token != _SC(')')) {
-                       CommaExpr();
-                       _fs->PopTarget();
-               }
-               Expect(_SC(')'));
-               _fs->SnoozeOpt();
-               int expend = _fs->GetCurrentPos();
-               int expsize = (expend - expstart) + 1;
-               SQInstructionVec exp;
-               if(expsize > 0) {
-                       for(int i = 0; i < expsize; i++)
-                               exp.push_back(_fs->GetInstruction(expstart + i));
-                       _fs->PopInstructions(expsize);
-               }
-               BEGIN_BREAKBLE_BLOCK()
-               Statement();
-               int continuetrg = _fs->GetCurrentPos();
-               if(expsize > 0) {
-                       for(int i = 0; i < expsize; i++)
-                               _fs->AddInstruction(exp[i]);
-               }
-               _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()
-       {
-               SQObject idxname, valname;
-               Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
-               if(_token == _SC(',')) {
-                       idxname = valname;
-                       Lex(); valname = Expect(TK_IDENTIFIER);
-               }
-               else{
-                       idxname = _fs->CreateString(_SC("@INDEX@"));
-               }
-               Expect(TK_IN);
-               
-               //save the stack size
-               int stacksize = _fs->GetStackSize();
-               //put the table in the stack(evaluate the table expression)
-               Expression(); Expect(_SC(')'));
-               int container = _fs->TopTarget();
-               //push the index local var
-               int indexpos = _fs->PushLocalVariable(idxname);
-               _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
-               //push the value local var
-               int valuepos = _fs->PushLocalVariable(valname);
-               _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
-               //push reference index
-               int itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
-               _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
-               int jmppos = _fs->GetCurrentPos();
-               _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
-               int foreachpos = _fs->GetCurrentPos();
-               //generate the statement code
-               BEGIN_BREAKBLE_BLOCK()
-               Statement();
-               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
-               _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
-               //restore the local variable stack(remove index,val and ref idx)
-               CleanStack(stacksize);
-               END_BREAKBLE_BLOCK(foreachpos - 1);
-       }
-       void SwitchStatement()
-       {
-               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-               Expect(_SC('{'));
-               int expr = _fs->TopTarget();
-               bool bfirst = true;
-               int tonextcondjmp = -1;
-               int skipcondjmp = -1;
-               int __nbreaks__ = _fs->_unresolvedbreaks.size();
-               _fs->_breaktargets.push_back(0);
-               while(_token == TK_CASE) {
-                       if(!bfirst) {
-                               _fs->AddInstruction(_OP_JMP, 0, 0);
-                               skipcondjmp = _fs->GetCurrentPos();
-                               _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
-                       }
-                       //condition
-                       Lex(); Expression(); Expect(_SC(':'));
-                       int trg = _fs->PopTarget();
-                       _fs->AddInstruction(_OP_EQ, trg, trg, expr);
-                       _fs->AddInstruction(_OP_JZ, trg, 0);
-                       //end condition
-                       if(skipcondjmp != -1) {
-                               _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
-                       }
-                       tonextcondjmp = _fs->GetCurrentPos();
-                       int stacksize = _fs->GetStackSize();
-                       Statements();
-                       _fs->SetStackSize(stacksize);
-                       bfirst = false;
-               }
-               if(tonextcondjmp != -1)
-                       _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
-               if(_token == TK_DEFAULT) {
-                       Lex(); Expect(_SC(':'));
-                       int stacksize = _fs->GetStackSize();
-                       Statements();
-                       _fs->SetStackSize(stacksize);
-               }
-               Expect(_SC('}'));
-               _fs->PopTarget();
-               __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
-               if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
-               _fs->_breaktargets.pop_back();
-               
-       }
-       void FunctionStatement()
-       {
-               SQObject id;
-               Lex(); id = Expect(TK_IDENTIFIER);
-               _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);
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
-                       if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
-               }
-               Expect(_SC('('));
-               CreateFunction(id);
-               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
-               EmitDerefOp(_OP_NEWSLOT);
-               _fs->PopTarget();
-       }
-       void ClassStatement()
-       {
-               ExpState es;
-               Lex(); PushExpState();
-               _exst._class_or_delete = true;
-               _exst._funcarg = false;
-               PrefixedExpr();
-               es = PopExpState();
-               if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));
-               if(es._deref == DEREF_FIELD) {
-                       ClassExp();
-                       EmitDerefOp(_OP_NEWSLOT);
-                       _fs->PopTarget();
-               }
-               else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
-       }
-       void TryCatchStatement()
-       {
-               SQObject exid;
-               Lex();
-               _fs->AddInstruction(_OP_PUSHTRAP,0,0);
-               _fs->_traps++;
-               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
-               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
-               int trappos = _fs->GetCurrentPos();
-               Statement();
-               _fs->_traps--;
-               _fs->AddInstruction(_OP_POPTRAP, 1, 0);
-               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
-               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
-               _fs->AddInstruction(_OP_JMP, 0, 0);
-               int jmppos = _fs->GetCurrentPos();
-               _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
-               Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
-               int stacksize = _fs->GetStackSize();
-               int ex_target = _fs->PushLocalVariable(exid);
-               _fs->SetIntructionParam(trappos, 0, ex_target);
-               Statement();
-               _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
-               CleanStack(stacksize);
-       }
-       void FunctionExp(int ftype)
-       {
-               Lex(); Expect(_SC('('));
-               CreateFunction(_null_);
-               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
-       }
-       void ClassExp()
-       {
-               int base = -1;
-               int attrs = -1;
-               if(_token == TK_EXTENDS) {
-                       Lex(); Expression();
-                       base = _fs->TopTarget();
-               }
-               if(_token == TK_ATTR_OPEN) {
-                       Lex();
-                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
-                       ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);
-                       attrs = _fs->TopTarget();
-               }
-               Expect(_SC('{'));
-               if(attrs != -1) _fs->PopTarget();
-               if(base != -1) _fs->PopTarget();
-               _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);
-               ParseTableOrClass(_SC(';'));
-       }
-       void DelegateExpr()
-       {
-               Lex(); CommaExpr();
-               Expect(_SC(':'));
-               CommaExpr();
-               int table = _fs->PopTarget(), delegate = _fs->PopTarget();
-               _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);
-       }
-       void DeleteExpr()
-       {
-               ExpState es;
-               Lex(); PushExpState();
-               _exst._class_or_delete = true;
-               _exst._funcarg = false;
-               PrefixedExpr();
-               es = PopExpState();
-               if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));
-               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);
-               else Error(_SC("cannot delete a local"));
-       }
-       void PrefixIncDec(int token)
-       {
-               ExpState es;
-               Lex(); PushExpState();
-               _exst._class_or_delete = true;
-               _exst._funcarg = false;
-               PrefixedExpr();
-               es = PopExpState();
-               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);
-               else {
-                       int src = _fs->PopTarget();
-                       _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
-               }
-       }
-       void CreateFunction(SQObject &name)
-       {
-               
-               SQFuncState *funcstate = _fs->PushChildState(_ss(_vm), SQFunctionProto::Create());
-               _funcproto(funcstate->_func)->_name = name;
-               SQObject paramname;
-               funcstate->AddParameter(_fs->CreateString(_SC("this")));
-               _funcproto(funcstate->_func)->_sourcename = _sourcename;
-               while(_token!=_SC(')')) {
-                       if(_token == TK_VARPARAMS) {
-                               funcstate->_varparams = true;
-                               Lex();
-                               if(_token != _SC(')')) Error(_SC("expected ')'"));
-                               break;
-                       }
-                       else {
-                               paramname = Expect(TK_IDENTIFIER);
-                               funcstate->AddParameter(paramname);
-                               if(_token == _SC(',')) Lex();
-                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
-                       }
-               }
-               Expect(_SC(')'));
-               //outer values
-               if(_token == _SC(':')) {
-                       Lex(); Expect(_SC('('));
-                       while(_token != _SC(')')) {
-                               paramname = Expect(TK_IDENTIFIER);
-                               //outers are treated as implicit local variables
-                               funcstate->AddOuterValue(paramname);
-                               if(_token == _SC(',')) Lex();
-                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
-                       }
-                       Lex();
-               }
-               
-               SQFuncState *currchunk = _fs;
-               _fs = funcstate;
-               Statement();
-               funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
-        funcstate->AddInstruction(_OP_RETURN, -1);
-               funcstate->SetStackSize(0);
-               _funcproto(_fs->_func)->_stacksize = _fs->_stacksize;
-               funcstate->Finalize();
-#ifdef _DEBUG_DUMP
-               funcstate->Dump();
-#endif
-               _fs = currchunk;
-               _fs->_functions.push_back(funcstate->_func);
-               _fs->PopChildState();
-       }
-       void CleanStack(int stacksize)
-       {
-               if(_fs->GetStackSize() != stacksize)
-                       _fs->SetStackSize(stacksize);
-       }
-       void ResolveBreaks(SQFuncState *funcstate, int ntoresolve)
-       {
-               while(ntoresolve > 0) {
-                       int pos = funcstate->_unresolvedbreaks.back();
-                       funcstate->_unresolvedbreaks.pop_back();
-                       //set the jmp instruction
-                       funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
-                       ntoresolve--;
-               }
-       }
-       void ResolveContinues(SQFuncState *funcstate, int ntoresolve, int targetpos)
-       {
-               while(ntoresolve > 0) {
-                       int pos = funcstate->_unresolvedcontinues.back();
-                       funcstate->_unresolvedcontinues.pop_back();
-                       //set the jmp instruction
-                       funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
-                       ntoresolve--;
-               }
-       }
-private:
-       int _token;
-       SQFuncState *_fs;
-       SQObjectPtr _sourcename;
-       SQLexer _lex;
-       bool _lineinfo;
-       bool _raiseerror;
-       int _debugline;
-       int _debugop;
-       ExpStateVec _expstates;
-       SQChar *compilererror;
-       jmp_buf _errorjmp;
-       SQVM *_vm;
-};
-
-bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
-{
-       SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
-       return p.Compile(out);
-}
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include <stdarg.h>\r
+#include <setjmp.h>\r
+#include "sqopcodes.h"\r
+#include "sqstring.h"\r
+#include "sqfuncproto.h"\r
+#include "sqcompiler.h"\r
+#include "sqfuncstate.h"\r
+#include "sqlexer.h"\r
+#include "sqvm.h"\r
+\r
+#define DEREF_NO_DEREF -1\r
+#define DEREF_FIELD            -2\r
+\r
+struct ExpState\r
+{\r
+       ExpState()\r
+       {\r
+               _deref = DEREF_NO_DEREF;\r
+               _freevar = false;\r
+               _class_or_delete = false;\r
+               _funcarg = false;\r
+       }\r
+       bool _class_or_delete;\r
+       bool _funcarg;\r
+       bool _freevar;\r
+       SQInteger _deref;\r
+};\r
+\r
+typedef sqvector<ExpState> ExpStateVec;\r
+\r
+#define _exst (_expstates.top())\r
+\r
+#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \\r
+                                                       SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \\r
+                                                       _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);\r
+\r
+#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \\r
+                                       __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \\r
+                                       if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \\r
+                                       if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \\r
+                                       _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}\r
+\r
+class SQCompiler\r
+{\r
+public:\r
+       SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)\r
+       {\r
+               _vm=v;\r
+               _lex.Init(_ss(v), rg, up,ThrowError,this);\r
+               _sourcename = SQString::Create(_ss(v), sourcename);\r
+               _lineinfo = lineinfo;_raiseerror = raiseerror;\r
+               compilererror = NULL;\r
+       }\r
+       static void ThrowError(void *ud, const SQChar *s) {\r
+               SQCompiler *c = (SQCompiler *)ud;\r
+               c->Error(s);\r
+       }\r
+       void Error(const SQChar *s, ...)\r
+       {\r
+               static SQChar temp[256];\r
+               va_list vl;\r
+               va_start(vl, s);\r
+               scvsprintf(temp, s, vl);\r
+               va_end(vl);\r
+               compilererror = temp;\r
+               longjmp(_errorjmp,1);\r
+       }\r
+       void Lex(){     _token = _lex.Lex();}\r
+       void PushExpState(){ _expstates.push_back(ExpState()); }\r
+       bool IsDerefToken(SQInteger tok)\r
+       {\r
+               switch(tok){\r
+               case _SC('='): case _SC('('): case TK_NEWSLOT:\r
+               case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;\r
+               }\r
+               return false;\r
+       }\r
+       ExpState PopExpState()\r
+       {\r
+               ExpState ret = _expstates.top();\r
+               _expstates.pop_back();\r
+               return ret;\r
+       }\r
+       SQObject Expect(SQInteger tok)\r
+       {\r
+               \r
+               if(_token != tok) {\r
+                       if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {\r
+                               //ret = SQString::Create(_ss(_vm),_SC("constructor"));\r
+                               //do nothing\r
+                       }\r
+                       else {\r
+                               const SQChar *etypename;\r
+                               if(tok > 255) {\r
+                                       switch(tok)\r
+                                       {\r
+                                       case TK_IDENTIFIER:\r
+                                               etypename = _SC("IDENTIFIER");\r
+                                               break;\r
+                                       case TK_STRING_LITERAL:\r
+                                               etypename = _SC("STRING_LITERAL");\r
+                                               break;\r
+                                       case TK_INTEGER:\r
+                                               etypename = _SC("INTEGER");\r
+                                               break;\r
+                                       case TK_FLOAT:\r
+                                               etypename = _SC("FLOAT");\r
+                                               break;\r
+                                       default:\r
+                                               etypename = _lex.Tok2Str(tok);\r
+                                       }\r
+                                       Error(_SC("expected '%s'"), etypename);\r
+                               }\r
+                               Error(_SC("expected '%c'"), tok);\r
+                       }\r
+               }\r
+               SQObjectPtr ret;\r
+               switch(tok)\r
+               {\r
+               case TK_IDENTIFIER:\r
+                       ret = _fs->CreateString(_lex._svalue);\r
+                       break;\r
+               case TK_STRING_LITERAL:\r
+                       ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);\r
+                       break;\r
+               case TK_INTEGER:\r
+                       ret = SQObjectPtr(_lex._nvalue);\r
+                       break;\r
+               case TK_FLOAT:\r
+                       ret = SQObjectPtr(_lex._fvalue);\r
+                       break;\r
+               }\r
+               Lex();\r
+               return ret;\r
+       }\r
+       bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }\r
+       void OptionalSemicolon()\r
+       {\r
+               if(_token == _SC(';')) { Lex(); return; }\r
+               if(!IsEndOfStatement()) {\r
+                       Error(_SC("end of statement expected (; or lf)"));\r
+               }\r
+       }\r
+       void MoveIfCurrentTargetIsLocal() {\r
+               SQInteger trg = _fs->TopTarget();\r
+               if(_fs->IsLocal(trg)) {\r
+                       trg = _fs->PopTarget(); //no pops the target and move it\r
+                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);\r
+               }\r
+       }\r
+       bool Compile(SQObjectPtr &o)\r
+       {\r
+               _debugline = 1;\r
+               _debugop = 0;\r
+\r
+               SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);\r
+               funcstate._name = SQString::Create(_ss(_vm), _SC("main"));\r
+               _fs = &funcstate;\r
+               _fs->AddParameter(_fs->CreateString(_SC("this")));\r
+               _fs->_sourcename = _sourcename;\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               if(setjmp(_errorjmp) == 0) {\r
+                       Lex();\r
+                       while(_token > 0){\r
+                               Statement();\r
+                               if(_lex._prevtoken != _SC('}')) OptionalSemicolon();\r
+                       }\r
+                       CleanStack(stacksize);\r
+                       _fs->AddLineInfos(_lex._currentline, _lineinfo, true);\r
+                       _fs->AddInstruction(_OP_RETURN, 0xFF);\r
+                       _fs->SetStackSize(0);\r
+                       o =_fs->BuildProto();\r
+#ifdef _DEBUG_DUMP\r
+                       _fs->Dump(_funcproto(o));\r
+#endif\r
+               }\r
+               else {\r
+                       if(_raiseerror && _ss(_vm)->_compilererrorhandler) {\r
+                               _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),\r
+                                       _lex._currentline, _lex._currentcolumn);\r
+                       }\r
+                       _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+       void Statements()\r
+       {\r
+               while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {\r
+                       Statement();\r
+                       if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();\r
+               }\r
+       }\r
+       void Statement()\r
+       {\r
+               _fs->AddLineInfos(_lex._currentline, _lineinfo);\r
+               switch(_token){\r
+               case _SC(';'):  Lex();                                  break;\r
+               case TK_IF:             IfStatement();                  break;\r
+               case TK_WHILE:          WhileStatement();               break;\r
+               case TK_DO:             DoWhileStatement();             break;\r
+               case TK_FOR:            ForStatement();                 break;\r
+               case TK_FOREACH:        ForEachStatement();             break;\r
+               case TK_SWITCH: SwitchStatement();              break;\r
+               case TK_LOCAL:          LocalDeclStatement();   break;\r
+               case TK_RETURN:\r
+               case TK_YIELD: {\r
+                       SQOpcode op;\r
+                       if(_token == TK_RETURN) {\r
+                               op = _OP_RETURN;\r
+                               \r
+                       }\r
+                       else {\r
+                               op = _OP_YIELD;\r
+                               _fs->_bgenerator = true;\r
+                       }\r
+                       Lex();\r
+                       if(!IsEndOfStatement()) {\r
+                               SQInteger retexp = _fs->GetCurrentPos()+1;\r
+                               CommaExpr();\r
+                               if(op == _OP_RETURN && _fs->_traps > 0)\r
+                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);\r
+                               _fs->_returnexp = retexp;\r
+                               _fs->AddInstruction(op, 1, _fs->PopTarget());\r
+                       }\r
+                       else{ \r
+                               if(op == _OP_RETURN && _fs->_traps > 0)\r
+                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);\r
+                               _fs->_returnexp = -1;\r
+                               _fs->AddInstruction(op, 0xFF); \r
+                       }\r
+                       break;}\r
+               case TK_BREAK:\r
+                       if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));\r
+                       if(_fs->_breaktargets.top() > 0){\r
+                               _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);\r
+                       }\r
+                       _fs->AddInstruction(_OP_JMP, 0, -1234);\r
+                       _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());\r
+                       Lex();\r
+                       break;\r
+               case TK_CONTINUE:\r
+                       if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));\r
+                       if(_fs->_continuetargets.top() > 0) {\r
+                               _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);\r
+                       }\r
+                       _fs->AddInstruction(_OP_JMP, 0, -1234);\r
+                       _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());\r
+                       Lex();\r
+                       break;\r
+               case TK_FUNCTION:\r
+                       FunctionStatement();\r
+                       break;\r
+               case TK_CLASS:\r
+                       ClassStatement();\r
+                       break;\r
+               case _SC('{'):{\r
+                               SQInteger stacksize = _fs->GetStackSize();\r
+                               Lex();\r
+                               Statements();\r
+                               Expect(_SC('}'));\r
+                               _fs->SetStackSize(stacksize);\r
+                       }\r
+                       break;\r
+               case TK_TRY:\r
+                       TryCatchStatement();\r
+                       break;\r
+               case TK_THROW:\r
+                       Lex();\r
+                       CommaExpr();\r
+                       _fs->AddInstruction(_OP_THROW, _fs->PopTarget());\r
+                       break;\r
+               default:\r
+                       CommaExpr();\r
+                       _fs->PopTarget();\r
+                       break;\r
+               }\r
+               _fs->SnoozeOpt();\r
+       }\r
+       void EmitDerefOp(SQOpcode op)\r
+       {\r
+               SQInteger val = _fs->PopTarget();\r
+               SQInteger key = _fs->PopTarget();\r
+               SQInteger src = _fs->PopTarget();\r
+        _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);\r
+       }\r
+       void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)\r
+       {\r
+               SQInteger p2 = _fs->PopTarget(); //src in OP_GET\r
+               SQInteger p1 = _fs->PopTarget(); //key in OP_GET\r
+               _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);\r
+       }\r
+       void EmitCompoundArith(SQInteger tok,bool deref)\r
+       {\r
+               SQInteger oper;\r
+               switch(tok){\r
+               case TK_MINUSEQ: oper = '-'; break;\r
+               case TK_PLUSEQ: oper = '+'; break;\r
+               case TK_MULEQ: oper = '*'; break;\r
+               case TK_DIVEQ: oper = '/'; break;\r
+               case TK_MODEQ: oper = '%'; break;\r
+               default: assert(0); break;\r
+               };\r
+               if(deref) {\r
+                       SQInteger val = _fs->PopTarget();\r
+                       SQInteger key = _fs->PopTarget();\r
+                       SQInteger src = _fs->PopTarget();\r
+                       //mixes dest obj and source val in the arg1(hack?)\r
+                       _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);\r
+               }\r
+               else {\r
+                       Emit2ArgsOP(_OP_COMPARITHL, oper);\r
+               }\r
+       }\r
+       void CommaExpr()\r
+       {\r
+               for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());\r
+       }\r
+       ExpState Expression(bool funcarg = false)\r
+       {\r
+               PushExpState();\r
+               _exst._class_or_delete = false;\r
+               _exst._funcarg = funcarg;\r
+               LogicalOrExp();\r
+               switch(_token)  {\r
+               case _SC('='):\r
+               case TK_NEWSLOT:\r
+               case TK_MINUSEQ:\r
+               case TK_PLUSEQ:\r
+               case TK_MULEQ:\r
+               case TK_DIVEQ:\r
+               case TK_MODEQ:\r
+               {\r
+                               SQInteger op = _token;\r
+                               SQInteger ds = _exst._deref;\r
+                               bool freevar = _exst._freevar;\r
+                               if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));\r
+                               Lex(); Expression();\r
+\r
+                               switch(op){\r
+                               case TK_NEWSLOT:\r
+                                       if(freevar) Error(_SC("free variables cannot be modified"));\r
+                                       if(ds == DEREF_FIELD)\r
+                                               EmitDerefOp(_OP_NEWSLOT);\r
+                                       else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
+                                               Error(_SC("can't 'create' a local slot"));\r
+                                       break;\r
+                               case _SC('='): //ASSIGN\r
+                                       if(freevar) Error(_SC("free variables cannot be modified"));\r
+                                       if(ds == DEREF_FIELD)\r
+                                               EmitDerefOp(_OP_SET);\r
+                                       else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
+                                               SQInteger p2 = _fs->PopTarget(); //src in OP_GET\r
+                                               SQInteger p1 = _fs->TopTarget(); //key in OP_GET\r
+                                               _fs->AddInstruction(_OP_MOVE, p1, p2);\r
+                                       }\r
+                                       break;\r
+                               case TK_MINUSEQ:\r
+                               case TK_PLUSEQ:\r
+                               case TK_MULEQ:\r
+                               case TK_DIVEQ:\r
+                               case TK_MODEQ:\r
+                                       EmitCompoundArith(op,ds == DEREF_FIELD);\r
+                                       break;\r
+                               }\r
+                       }\r
+                       break;\r
+               case _SC('?'): {\r
+                       Lex();\r
+                       _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
+                       SQInteger jzpos = _fs->GetCurrentPos();\r
+                       SQInteger trg = _fs->PushTarget();\r
+                       Expression();\r
+                       SQInteger first_exp = _fs->PopTarget();\r
+                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
+                       SQInteger endfirstexp = _fs->GetCurrentPos();\r
+                       _fs->AddInstruction(_OP_JMP, 0, 0);\r
+                       Expect(_SC(':'));\r
+                       SQInteger jmppos = _fs->GetCurrentPos();\r
+                       Expression();\r
+                       SQInteger second_exp = _fs->PopTarget();\r
+                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
+                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);\r
+                       _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);\r
+                       _fs->SnoozeOpt();\r
+                       }\r
+                       break;\r
+               }\r
+               return PopExpState();\r
+       }\r
+       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)\r
+       {\r
+               Lex(); (this->*f)();\r
+               SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();\r
+               _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);\r
+       }\r
+       void LogicalOrExp()\r
+       {\r
+               LogicalAndExp();\r
+               for(;;) if(_token == TK_OR) {\r
+                       SQInteger first_exp = _fs->PopTarget();\r
+                       SQInteger trg = _fs->PushTarget();\r
+                       _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);\r
+                       SQInteger jpos = _fs->GetCurrentPos();\r
+                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
+                       Lex(); LogicalOrExp();\r
+                       _fs->SnoozeOpt();\r
+                       SQInteger second_exp = _fs->PopTarget();\r
+                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
+                       _fs->SnoozeOpt();\r
+                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));\r
+                       break;\r
+               }else return;\r
+       }\r
+       void LogicalAndExp()\r
+       {\r
+               BitwiseOrExp();\r
+               for(;;) switch(_token) {\r
+               case TK_AND: {\r
+                       SQInteger first_exp = _fs->PopTarget();\r
+                       SQInteger trg = _fs->PushTarget();\r
+                       _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);\r
+                       SQInteger jpos = _fs->GetCurrentPos();\r
+                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
+                       Lex(); LogicalAndExp();\r
+                       _fs->SnoozeOpt();\r
+                       SQInteger second_exp = _fs->PopTarget();\r
+                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
+                       _fs->SnoozeOpt();\r
+                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));\r
+                       break;\r
+                       }\r
+               case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;\r
+               case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;\r
+               default:\r
+                       return;\r
+               }\r
+       }\r
+       void BitwiseOrExp()\r
+       {\r
+               BitwiseXorExp();\r
+               for(;;) if(_token == _SC('|'))\r
+               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);\r
+               }else return;\r
+       }\r
+       void BitwiseXorExp()\r
+       {\r
+               BitwiseAndExp();\r
+               for(;;) if(_token == _SC('^'))\r
+               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);\r
+               }else return;\r
+       }\r
+       void BitwiseAndExp()\r
+       {\r
+               CompExp();\r
+               for(;;) if(_token == _SC('&'))\r
+               {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);\r
+               }else return;\r
+       }\r
+       void CompExp()\r
+       {\r
+               ShiftExp();\r
+               for(;;) switch(_token) {\r
+               case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;\r
+               case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;\r
+               case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;\r
+               case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;\r
+               case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;\r
+               case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;\r
+               default: return;        \r
+               }\r
+       }\r
+       void ShiftExp()\r
+       {\r
+               PlusExp();\r
+               for(;;) switch(_token) {\r
+               case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;\r
+               case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;\r
+               case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;\r
+               default: return;        \r
+               }\r
+       }\r
+       void PlusExp()\r
+       {\r
+               MultExp();\r
+               for(;;) switch(_token) {\r
+               case _SC('+'): case _SC('-'):\r
+                       BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;\r
+               default: return;\r
+               }\r
+       }\r
+       \r
+       void MultExp()\r
+       {\r
+               PrefixedExpr();\r
+               for(;;) switch(_token) {\r
+               case _SC('*'): case _SC('/'): case _SC('%'):\r
+                       BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;\r
+               default: return;\r
+               }\r
+       }\r
+       //if 'pos' != -1 the previous variable is a local variable\r
+       void PrefixedExpr()\r
+       {\r
+               SQInteger pos = Factor();\r
+               for(;;) {\r
+                       switch(_token) {\r
+                       case _SC('.'): {\r
+                               pos = -1;\r
+                               Lex(); \r
+                               if(_token == TK_PARENT) {\r
+                                       Lex();\r
+                                       if(!NeedGet())\r
+                                               Error(_SC("parent cannot be set"));\r
+                                       SQInteger src = _fs->PopTarget();\r
+                                       _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);\r
+                               }\r
+                               else {\r
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));\r
+                                       if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
+                               }\r
+                               _exst._deref = DEREF_FIELD;\r
+                               _exst._freevar = false;\r
+                               }\r
+                               break;\r
+                       case _SC('['):\r
+                               if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));\r
+                               Lex(); Expression(); Expect(_SC(']')); \r
+                               pos = -1;\r
+                               if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
+                               _exst._deref = DEREF_FIELD;\r
+                               _exst._freevar = false;\r
+                               break;\r
+                       case TK_MINUSMINUS:\r
+                       case TK_PLUSPLUS:\r
+                       if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { \r
+                               SQInteger tok = _token; Lex();\r
+                               if(pos < 0)\r
+                                       Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);\r
+                               else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
+                                       SQInteger src = _fs->PopTarget();\r
+                                       _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);\r
+                               }\r
+                               \r
+                       }\r
+                       return;\r
+                       break;  \r
+                       case _SC('('): \r
+                               {\r
+                               if(_exst._deref != DEREF_NO_DEREF) {\r
+                                       if(pos<0) {\r
+                                               SQInteger key = _fs->PopTarget(); //key\r
+                                               SQInteger table = _fs->PopTarget(); //table etc...\r
+                                               SQInteger closure = _fs->PushTarget();\r
+                                               SQInteger ttarget = _fs->PushTarget();\r
+                                               _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);\r
+                                       }\r
+                                       else{\r
+                                               _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);\r
+                                       }\r
+                               }\r
+                               else\r
+                                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);\r
+                               _exst._deref = DEREF_NO_DEREF;\r
+                               Lex();\r
+                               FunctionCallArgs();\r
+                                }\r
+                               break;\r
+                       default: return;\r
+                       }\r
+               }\r
+       }\r
+       SQInteger Factor()\r
+       {\r
+               switch(_token)\r
+               {\r
+               case TK_STRING_LITERAL: {\r
+                               //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));\r
+                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));\r
+                               Lex(); \r
+                       }\r
+                       break;\r
+               case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;\r
+               case TK_VARGV: { Lex();\r
+                       Expect(_SC('['));\r
+                       Expression();\r
+                       Expect(_SC(']'));\r
+                       SQInteger src = _fs->PopTarget();\r
+                       _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);\r
+                                          }\r
+                       break;\r
+               case TK_IDENTIFIER:\r
+               case TK_CONSTRUCTOR:\r
+               case TK_THIS:{\r
+                       _exst._freevar = false;\r
+                       SQObject id;\r
+                               switch(_token) {\r
+                                       case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;\r
+                                       case TK_THIS: id = _fs->CreateString(_SC("this")); break;\r
+                                       case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;\r
+                               }\r
+                               SQInteger pos = -1;\r
+                               Lex();\r
+                               if((pos = _fs->GetLocalVariable(id)) == -1) {\r
+                                       //checks if is a free variable\r
+                                       if((pos = _fs->GetOuterVariable(id)) != -1) {\r
+                                               _exst._deref = _fs->PushTarget();\r
+                                               _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);        \r
+                                               _exst._freevar = true;\r
+                                       } else {\r
+                                               _fs->PushTarget(0);\r
+                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
+                                               if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
+                                               _exst._deref = DEREF_FIELD;\r
+                                       }\r
+                               }\r
+                               else{\r
+                                       _fs->PushTarget(pos);\r
+                                       _exst._deref = pos;\r
+                               }\r
+                               return _exst._deref;\r
+                       }\r
+                       break;\r
+               case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;\r
+               case TK_DOUBLE_COLON:  // "::"\r
+                       _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());\r
+                       _exst._deref = DEREF_FIELD;\r
+                       _token = _SC('.'); //hack\r
+                       return -1;\r
+                       break;\r
+               case TK_NULL: \r
+                       _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);\r
+                       Lex();\r
+                       break;\r
+               case TK_INTEGER: \r
+                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));\r
+                       Lex();\r
+                       break;\r
+               case TK_FLOAT: \r
+                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));\r
+                       Lex();\r
+                       break;\r
+               case TK_TRUE: case TK_FALSE:\r
+                       _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);\r
+                       Lex();\r
+                       break;\r
+               case _SC('['): {\r
+                               _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());\r
+                               SQInteger apos = _fs->GetCurrentPos(),key = 0;\r
+                               Lex();\r
+                               while(_token != _SC(']')) {\r
+                    Expression(); \r
+                                       if(_token == _SC(',')) Lex();\r
+                                       SQInteger val = _fs->PopTarget();\r
+                                       SQInteger array = _fs->TopTarget();\r
+                                       _fs->AddInstruction(_OP_APPENDARRAY, array, val);\r
+                                       key++;\r
+                               }\r
+                               _fs->SetIntructionParam(apos, 1, key);\r
+                               Lex();\r
+                       }\r
+                       break;\r
+               case _SC('{'):{\r
+                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());\r
+                       Lex();ParseTableOrClass(_SC(','));\r
+                                }\r
+                       break;\r
+               case TK_FUNCTION: FunctionExp(_token);break;\r
+               case TK_CLASS: Lex(); ClassExp();break;\r
+               case _SC('-'): UnaryOP(_OP_NEG); break;\r
+               case _SC('!'): UnaryOP(_OP_NOT); break;\r
+               case _SC('~'): UnaryOP(_OP_BWNOT); break;\r
+               case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;\r
+               case TK_RESUME : UnaryOP(_OP_RESUME); break;\r
+               case TK_CLONE : UnaryOP(_OP_CLONE); break;\r
+               case TK_MINUSMINUS : \r
+               case TK_PLUSPLUS :PrefixIncDec(_token); break;\r
+               case TK_DELETE : DeleteExpr(); break;\r
+               case TK_DELEGATE : DelegateExpr(); break;\r
+               case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));\r
+                       break;\r
+               default: Error(_SC("expression expected"));\r
+               }\r
+               return -1;\r
+       }\r
+       void UnaryOP(SQOpcode op)\r
+       {\r
+               Lex(); PrefixedExpr();\r
+               SQInteger src = _fs->PopTarget();\r
+               _fs->AddInstruction(op, _fs->PushTarget(), src);\r
+       }\r
+       bool NeedGet()\r
+       {\r
+               switch(_token) {\r
+               case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:\r
+               case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:\r
+                       return false;\r
+               }\r
+               return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));\r
+       }\r
+       \r
+       void FunctionCallArgs()\r
+       {\r
+               SQInteger nargs = 1;//this\r
+                while(_token != _SC(')')) {\r
+                        Expression(true);\r
+                        MoveIfCurrentTargetIsLocal();\r
+                        nargs++; \r
+                        if(_token == _SC(',')){ \r
+                                Lex(); \r
+                                if(_token == ')') Error(_SC("expression expected, found ')'"));\r
+                        }\r
+                }\r
+                Lex();\r
+                for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();\r
+                SQInteger stackbase = _fs->PopTarget();\r
+                SQInteger closure = _fs->PopTarget();\r
+         _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);\r
+       }\r
+       void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')\r
+       {\r
+               SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;\r
+               \r
+               while(_token != terminator) {\r
+                       bool hasattrs = false;\r
+                       //check if is an attribute\r
+                       if(separator == ';' && _token == TK_ATTR_OPEN) {\r
+                               _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();\r
+                               ParseTableOrClass(',',TK_ATTR_CLOSE);\r
+                               hasattrs = true;\r
+                       }\r
+                       switch(_token) {\r
+                               case TK_FUNCTION:\r
+                               case TK_CONSTRUCTOR:{\r
+                                       SQInteger tk = _token;\r
+                                       Lex();\r
+                                       SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));\r
+                                       Expect(_SC('('));\r
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
+                                       CreateFunction(id);\r
+                                       _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);\r
+                                                                 }\r
+                                                                 break;\r
+                               case _SC('['):\r
+                                       Lex(); CommaExpr(); Expect(_SC(']'));\r
+                                       Expect(_SC('=')); Expression();\r
+                                       break;\r
+                               default :\r
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));\r
+                                       Expect(_SC('=')); Expression();\r
+                       }\r
+\r
+                       if(_token == separator) Lex();//optional comma/semicolon\r
+                       nkeys++;\r
+                       SQInteger val = _fs->PopTarget();\r
+                       SQInteger key = _fs->PopTarget();\r
+                       SQInteger attrs = hasattrs ? _fs->PopTarget():-1;\r
+                       assert(hasattrs && attrs == key-1 || !hasattrs);\r
+                       SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE\r
+                       _fs->AddInstruction(hasattrs?_OP_NEWSLOTA:_OP_NEWSLOT, _fs->PushTarget(), table, key, val);\r
+                       _fs->PopTarget();\r
+               }\r
+               if(separator == _SC(',')) //hack recognizes a table from the separator\r
+                       _fs->SetIntructionParam(tpos, 1, nkeys);\r
+               Lex();\r
+       }\r
+       void LocalDeclStatement()\r
+       {\r
+               SQObject varname;\r
+               do {\r
+                       Lex(); varname = Expect(TK_IDENTIFIER);\r
+                       if(_token == _SC('=')) {\r
+                               Lex(); Expression();\r
+                               SQInteger src = _fs->PopTarget();\r
+                               SQInteger dest = _fs->PushTarget();\r
+                               if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);\r
+                       }\r
+                       else{\r
+                               _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);\r
+                       }\r
+                       _fs->PopTarget();\r
+                       _fs->PushLocalVariable(varname);\r
+               \r
+               } while(_token == _SC(','));\r
+       }\r
+       void IfStatement()\r
+       {\r
+               SQInteger jmppos;\r
+               bool haselse = false;\r
+               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
+               _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
+               SQInteger jnepos = _fs->GetCurrentPos();\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               \r
+               Statement();\r
+               //\r
+               if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();\r
+               \r
+               CleanStack(stacksize);\r
+               SQInteger endifblock = _fs->GetCurrentPos();\r
+               if(_token == TK_ELSE){\r
+                       haselse = true;\r
+                       stacksize = _fs->GetStackSize();\r
+                       _fs->AddInstruction(_OP_JMP);\r
+                       jmppos = _fs->GetCurrentPos();\r
+                       Lex();\r
+                       Statement(); OptionalSemicolon();\r
+                       CleanStack(stacksize);\r
+                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);\r
+               }\r
+               _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));\r
+       }\r
+       void WhileStatement()\r
+       {\r
+               SQInteger jzpos, jmppos;\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               jmppos = _fs->GetCurrentPos();\r
+               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
+               \r
+               BEGIN_BREAKBLE_BLOCK();\r
+               _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
+               jzpos = _fs->GetCurrentPos();\r
+               stacksize = _fs->GetStackSize();\r
+               \r
+               Statement();\r
+               \r
+               CleanStack(stacksize);\r
+               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);\r
+               _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);\r
+               \r
+               END_BREAKBLE_BLOCK(jmppos);\r
+       }\r
+       void DoWhileStatement()\r
+       {\r
+               Lex();\r
+               SQInteger jzpos = _fs->GetCurrentPos();\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               BEGIN_BREAKBLE_BLOCK()\r
+               Statement();\r
+               CleanStack(stacksize);\r
+               Expect(TK_WHILE);\r
+               SQInteger continuetrg = _fs->GetCurrentPos();\r
+               Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
+               _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);\r
+               END_BREAKBLE_BLOCK(continuetrg);\r
+       }\r
+       void ForStatement()\r
+       {\r
+               Lex();\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               Expect(_SC('('));\r
+               if(_token == TK_LOCAL) LocalDeclStatement();\r
+               else if(_token != _SC(';')){\r
+                       CommaExpr();\r
+                       _fs->PopTarget();\r
+               }\r
+               Expect(_SC(';'));\r
+               _fs->SnoozeOpt();\r
+               SQInteger jmppos = _fs->GetCurrentPos();\r
+               SQInteger jzpos = -1;\r
+               if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }\r
+               Expect(_SC(';'));\r
+               _fs->SnoozeOpt();\r
+               SQInteger expstart = _fs->GetCurrentPos() + 1;\r
+               if(_token != _SC(')')) {\r
+                       CommaExpr();\r
+                       _fs->PopTarget();\r
+               }\r
+               Expect(_SC(')'));\r
+               _fs->SnoozeOpt();\r
+               SQInteger expend = _fs->GetCurrentPos();\r
+               SQInteger expsize = (expend - expstart) + 1;\r
+               SQInstructionVec exp;\r
+               if(expsize > 0) {\r
+                       for(SQInteger i = 0; i < expsize; i++)\r
+                               exp.push_back(_fs->GetInstruction(expstart + i));\r
+                       _fs->PopInstructions(expsize);\r
+               }\r
+               BEGIN_BREAKBLE_BLOCK()\r
+               Statement();\r
+               SQInteger continuetrg = _fs->GetCurrentPos();\r
+               if(expsize > 0) {\r
+                       for(SQInteger i = 0; i < expsize; i++)\r
+                               _fs->AddInstruction(exp[i]);\r
+               }\r
+               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);\r
+               if(jzpos>  0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);\r
+               CleanStack(stacksize);\r
+               \r
+               END_BREAKBLE_BLOCK(continuetrg);\r
+       }\r
+       void ForEachStatement()\r
+       {\r
+               SQObject idxname, valname;\r
+               Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);\r
+               if(_token == _SC(',')) {\r
+                       idxname = valname;\r
+                       Lex(); valname = Expect(TK_IDENTIFIER);\r
+               }\r
+               else{\r
+                       idxname = _fs->CreateString(_SC("@INDEX@"));\r
+               }\r
+               Expect(TK_IN);\r
+               \r
+               //save the stack size\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               //put the table in the stack(evaluate the table expression)\r
+               Expression(); Expect(_SC(')'));\r
+               SQInteger container = _fs->TopTarget();\r
+               //push the index local var\r
+               SQInteger indexpos = _fs->PushLocalVariable(idxname);\r
+               _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);\r
+               //push the value local var\r
+               SQInteger valuepos = _fs->PushLocalVariable(valname);\r
+               _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);\r
+               //push reference index\r
+               SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible\r
+               _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);\r
+               SQInteger jmppos = _fs->GetCurrentPos();\r
+               _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);\r
+               SQInteger foreachpos = _fs->GetCurrentPos();\r
+               //generate the statement code\r
+               BEGIN_BREAKBLE_BLOCK()\r
+               Statement();\r
+               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);\r
+               _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);\r
+               //restore the local variable stack(remove index,val and ref idx)\r
+               CleanStack(stacksize);\r
+               END_BREAKBLE_BLOCK(foreachpos - 1);\r
+       }\r
+       void SwitchStatement()\r
+       {\r
+               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
+               Expect(_SC('{'));\r
+               SQInteger expr = _fs->TopTarget();\r
+               bool bfirst = true;\r
+               SQInteger tonextcondjmp = -1;\r
+               SQInteger skipcondjmp = -1;\r
+               SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();\r
+               _fs->_breaktargets.push_back(0);\r
+               while(_token == TK_CASE) {\r
+                       if(!bfirst) {\r
+                               _fs->AddInstruction(_OP_JMP, 0, 0);\r
+                               skipcondjmp = _fs->GetCurrentPos();\r
+                               _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);\r
+                       }\r
+                       //condition\r
+                       Lex(); Expression(); Expect(_SC(':'));\r
+                       SQInteger trg = _fs->PopTarget();\r
+                       _fs->AddInstruction(_OP_EQ, trg, trg, expr);\r
+                       _fs->AddInstruction(_OP_JZ, trg, 0);\r
+                       //end condition\r
+                       if(skipcondjmp != -1) {\r
+                               _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));\r
+                       }\r
+                       tonextcondjmp = _fs->GetCurrentPos();\r
+                       SQInteger stacksize = _fs->GetStackSize();\r
+                       Statements();\r
+                       _fs->SetStackSize(stacksize);\r
+                       bfirst = false;\r
+               }\r
+               if(tonextcondjmp != -1)\r
+                       _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);\r
+               if(_token == TK_DEFAULT) {\r
+                       Lex(); Expect(_SC(':'));\r
+                       SQInteger stacksize = _fs->GetStackSize();\r
+                       Statements();\r
+                       _fs->SetStackSize(stacksize);\r
+               }\r
+               Expect(_SC('}'));\r
+               _fs->PopTarget();\r
+               __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;\r
+               if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);\r
+               _fs->_breaktargets.pop_back();\r
+               \r
+       }\r
+       void FunctionStatement()\r
+       {\r
+               SQObject id;\r
+               Lex(); id = Expect(TK_IDENTIFIER);\r
+               _fs->PushTarget(0);\r
+               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
+               if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);\r
+               \r
+               while(_token == TK_DOUBLE_COLON) {\r
+                       Lex();\r
+                       id = Expect(TK_IDENTIFIER);\r
+                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
+                       if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);\r
+               }\r
+               Expect(_SC('('));\r
+               CreateFunction(id);\r
+               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);\r
+               EmitDerefOp(_OP_NEWSLOT);\r
+               _fs->PopTarget();\r
+       }\r
+       void ClassStatement()\r
+       {\r
+               ExpState es;\r
+               Lex(); PushExpState();\r
+               _exst._class_or_delete = true;\r
+               _exst._funcarg = false;\r
+               PrefixedExpr();\r
+               es = PopExpState();\r
+               if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));\r
+               if(es._deref == DEREF_FIELD) {\r
+                       ClassExp();\r
+                       EmitDerefOp(_OP_NEWSLOT);\r
+                       _fs->PopTarget();\r
+               }\r
+               else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));\r
+       }\r
+       void TryCatchStatement()\r
+       {\r
+               SQObject exid;\r
+               Lex();\r
+               _fs->AddInstruction(_OP_PUSHTRAP,0,0);\r
+               _fs->_traps++;\r
+               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;\r
+               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;\r
+               SQInteger trappos = _fs->GetCurrentPos();\r
+               Statement();\r
+               _fs->_traps--;\r
+               _fs->AddInstruction(_OP_POPTRAP, 1, 0);\r
+               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;\r
+               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;\r
+               _fs->AddInstruction(_OP_JMP, 0, 0);\r
+               SQInteger jmppos = _fs->GetCurrentPos();\r
+               _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));\r
+               Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               SQInteger ex_target = _fs->PushLocalVariable(exid);\r
+               _fs->SetIntructionParam(trappos, 0, ex_target);\r
+               Statement();\r
+               _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);\r
+               CleanStack(stacksize);\r
+       }\r
+       void FunctionExp(SQInteger ftype)\r
+       {\r
+               Lex(); Expect(_SC('('));\r
+               CreateFunction(_null_);\r
+               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);\r
+       }\r
+       void ClassExp()\r
+       {\r
+               SQInteger base = -1;\r
+               SQInteger attrs = -1;\r
+               if(_token == TK_EXTENDS) {\r
+                       Lex(); Expression();\r
+                       base = _fs->TopTarget();\r
+               }\r
+               if(_token == TK_ATTR_OPEN) {\r
+                       Lex();\r
+                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());\r
+                       ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);\r
+                       attrs = _fs->TopTarget();\r
+               }\r
+               Expect(_SC('{'));\r
+               if(attrs != -1) _fs->PopTarget();\r
+               if(base != -1) _fs->PopTarget();\r
+               _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);\r
+               ParseTableOrClass(_SC(';'));\r
+       }\r
+       void DelegateExpr()\r
+       {\r
+               Lex(); CommaExpr();\r
+               Expect(_SC(':'));\r
+               CommaExpr();\r
+               SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();\r
+               _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);\r
+       }\r
+       void DeleteExpr()\r
+       {\r
+               ExpState es;\r
+               Lex(); PushExpState();\r
+               _exst._class_or_delete = true;\r
+               _exst._funcarg = false;\r
+               PrefixedExpr();\r
+               es = PopExpState();\r
+               if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));\r
+               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);\r
+               else Error(_SC("cannot delete a local"));\r
+       }\r
+       void PrefixIncDec(SQInteger token)\r
+       {\r
+               ExpState es;\r
+               Lex(); PushExpState();\r
+               _exst._class_or_delete = true;\r
+               _exst._funcarg = false;\r
+               PrefixedExpr();\r
+               es = PopExpState();\r
+               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);\r
+               else {\r
+                       SQInteger src = _fs->PopTarget();\r
+                       _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);\r
+               }\r
+       }\r
+       void CreateFunction(SQObject &name)\r
+       {\r
+               \r
+               SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));\r
+               funcstate->_name = name;\r
+               SQObject paramname;\r
+               funcstate->AddParameter(_fs->CreateString(_SC("this")));\r
+               funcstate->_sourcename = _sourcename;\r
+               while(_token!=_SC(')')) {\r
+                       if(_token == TK_VARPARAMS) {\r
+                               funcstate->_varparams = true;\r
+                               Lex();\r
+                               if(_token != _SC(')')) Error(_SC("expected ')'"));\r
+                               break;\r
+                       }\r
+                       else {\r
+                               paramname = Expect(TK_IDENTIFIER);\r
+                               funcstate->AddParameter(paramname);\r
+                               if(_token == _SC(',')) Lex();\r
+                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));\r
+                       }\r
+               }\r
+               Expect(_SC(')'));\r
+               //outer values\r
+               if(_token == _SC(':')) {\r
+                       Lex(); Expect(_SC('('));\r
+                       while(_token != _SC(')')) {\r
+                               paramname = Expect(TK_IDENTIFIER);\r
+                               //outers are treated as implicit local variables\r
+                               funcstate->AddOuterValue(paramname);\r
+                               if(_token == _SC(',')) Lex();\r
+                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));\r
+                       }\r
+                       Lex();\r
+               }\r
+               \r
+               SQFuncState *currchunk = _fs;\r
+               _fs = funcstate;\r
+               Statement();\r
+               funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);\r
+        funcstate->AddInstruction(_OP_RETURN, -1);\r
+               funcstate->SetStackSize(0);\r
+               //_fs->->_stacksize = _fs->_stacksize;\r
+               SQFunctionProto *func = funcstate->BuildProto();\r
+#ifdef _DEBUG_DUMP\r
+               funcstate->Dump(func);\r
+#endif\r
+               _fs = currchunk;\r
+               _fs->_functions.push_back(func);\r
+               _fs->PopChildState();\r
+       }\r
+       void CleanStack(SQInteger stacksize)\r
+       {\r
+               if(_fs->GetStackSize() != stacksize)\r
+                       _fs->SetStackSize(stacksize);\r
+       }\r
+       void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)\r
+       {\r
+               while(ntoresolve > 0) {\r
+                       SQInteger pos = funcstate->_unresolvedbreaks.back();\r
+                       funcstate->_unresolvedbreaks.pop_back();\r
+                       //set the jmp instruction\r
+                       funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);\r
+                       ntoresolve--;\r
+               }\r
+       }\r
+       void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)\r
+       {\r
+               while(ntoresolve > 0) {\r
+                       SQInteger pos = funcstate->_unresolvedcontinues.back();\r
+                       funcstate->_unresolvedcontinues.pop_back();\r
+                       //set the jmp instruction\r
+                       funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);\r
+                       ntoresolve--;\r
+               }\r
+       }\r
+private:\r
+       SQInteger _token;\r
+       SQFuncState *_fs;\r
+       SQObjectPtr _sourcename;\r
+       SQLexer _lex;\r
+       bool _lineinfo;\r
+       bool _raiseerror;\r
+       SQInteger _debugline;\r
+       SQInteger _debugop;\r
+       ExpStateVec _expstates;\r
+       SQChar *compilererror;\r
+       jmp_buf _errorjmp;\r
+       SQVM *_vm;\r
+};\r
+\r
+bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)\r
+{\r
+       SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);\r
+       return p.Compile(out);\r
+}\r
index 595d9c4..71dbfa2 100644 (file)
@@ -1,74 +1,74 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQCOMPILER_H_
-#define _SQCOMPILER_H_
-
-struct SQVM;
-
-#define        TK_IDENTIFIER   258
-#define        TK_STRING_LITERAL       259
-#define        TK_INTEGER      260
-#define        TK_FLOAT        261
-#define        TK_DELEGATE     262
-#define        TK_DELETE       263
-#define        TK_EQ   264
-#define        TK_NE   265
-#define        TK_LE   266
-#define        TK_GE   267
-#define        TK_SWITCH       268
-#define        TK_ARROW        269
-#define        TK_AND  270
-#define        TK_OR   271
-#define        TK_IF   272
-#define        TK_ELSE 273
-#define        TK_WHILE        274
-#define        TK_BREAK        275
-#define        TK_FOR  276
-#define        TK_DO   277
-#define        TK_NULL 278
-#define        TK_FOREACH      279
-#define        TK_IN   280
-#define        TK_NEWSLOT      281
-#define        TK_MODULO       282
-#define        TK_LOCAL        283
-#define        TK_CLONE        284
-#define        TK_FUNCTION     285
-#define        TK_RETURN       286
-#define        TK_TYPEOF       287
-#define        TK_UMINUS       288
-#define        TK_PLUSEQ       289
-#define        TK_MINUSEQ      290
-#define        TK_CONTINUE     291
-#define TK_YIELD 292
-#define TK_TRY 293
-#define TK_CATCH 294
-#define TK_THROW 295
-#define TK_SHIFTL 296
-#define TK_SHIFTR 297
-#define TK_RESUME 298
-#define TK_DOUBLE_COLON 299
-#define TK_CASE 300
-#define TK_DEFAULT 301
-#define TK_THIS 302
-#define TK_PLUSPLUS 303
-#define TK_MINUSMINUS 304
-#define TK_PARENT 305
-#define TK_USHIFTR 306
-#define TK_CLASS 307
-#define TK_EXTENDS 308
-#define TK_CONSTRUCTOR 310
-#define TK_INSTANCEOF 311
-#define TK_VARPARAMS 312
-#define TK_VARGC 313
-#define TK_VARGV 314
-#define TK_TRUE 315
-#define TK_FALSE 316
-#define TK_MULEQ 317
-#define TK_DIVEQ 318
-#define TK_MODEQ 319
-#define TK_ATTR_OPEN 320
-#define TK_ATTR_CLOSE 321
-
-
-typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
-bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
-#endif //_SQCOMPILER_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQCOMPILER_H_\r
+#define _SQCOMPILER_H_\r
+\r
+struct SQVM;\r
+\r
+#define        TK_IDENTIFIER   258\r
+#define        TK_STRING_LITERAL       259\r
+#define        TK_INTEGER      260\r
+#define        TK_FLOAT        261\r
+#define        TK_DELEGATE     262\r
+#define        TK_DELETE       263\r
+#define        TK_EQ   264\r
+#define        TK_NE   265\r
+#define        TK_LE   266\r
+#define        TK_GE   267\r
+#define        TK_SWITCH       268\r
+#define        TK_ARROW        269\r
+#define        TK_AND  270\r
+#define        TK_OR   271\r
+#define        TK_IF   272\r
+#define        TK_ELSE 273\r
+#define        TK_WHILE        274\r
+#define        TK_BREAK        275\r
+#define        TK_FOR  276\r
+#define        TK_DO   277\r
+#define        TK_NULL 278\r
+#define        TK_FOREACH      279\r
+#define        TK_IN   280\r
+#define        TK_NEWSLOT      281\r
+#define        TK_MODULO       282\r
+#define        TK_LOCAL        283\r
+#define        TK_CLONE        284\r
+#define        TK_FUNCTION     285\r
+#define        TK_RETURN       286\r
+#define        TK_TYPEOF       287\r
+#define        TK_UMINUS       288\r
+#define        TK_PLUSEQ       289\r
+#define        TK_MINUSEQ      290\r
+#define        TK_CONTINUE     291\r
+#define TK_YIELD 292\r
+#define TK_TRY 293\r
+#define TK_CATCH 294\r
+#define TK_THROW 295\r
+#define TK_SHIFTL 296\r
+#define TK_SHIFTR 297\r
+#define TK_RESUME 298\r
+#define TK_DOUBLE_COLON 299\r
+#define TK_CASE 300\r
+#define TK_DEFAULT 301\r
+#define TK_THIS 302\r
+#define TK_PLUSPLUS 303\r
+#define TK_MINUSMINUS 304\r
+#define TK_PARENT 305\r
+#define TK_USHIFTR 306\r
+#define TK_CLASS 307\r
+#define TK_EXTENDS 308\r
+#define TK_CONSTRUCTOR 310\r
+#define TK_INSTANCEOF 311\r
+#define TK_VARPARAMS 312\r
+#define TK_VARGC 313\r
+#define TK_VARGV 314\r
+#define TK_TRUE 315\r
+#define TK_FALSE 316\r
+#define TK_MULEQ 317\r
+#define TK_DIVEQ 318\r
+#define TK_MODEQ 319\r
+#define TK_ATTR_OPEN 320\r
+#define TK_ATTR_CLOSE 321\r
+\r
+\r
+typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);\r
+bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);\r
+#endif //_SQCOMPILER_H_\r
index 88daf9e..9612d06 100644 (file)
@@ -1,98 +1,98 @@
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-
-SQRESULT sq_stackinfos(HSQUIRRELVM v, int level, SQStackInfos *si)
-{
-       int cssize = v->_callsstack.size();
-       if (cssize > level) {
-               memset(si, 0, sizeof(SQStackInfos));
-               SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
-               switch (type(ci._closure)) {
-               case OT_CLOSURE:{
-                       SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);
-                       if (type(func->_name) == OT_STRING)
-                               si->funcname = _stringval(func->_name);
-                       if (type(func->_sourcename) == OT_STRING)
-                               si->source = _stringval(func->_sourcename);
-                       si->line = func->GetLine(ci._ip);
-                                               }
-                       break;
-               case OT_NATIVECLOSURE:
-                       si->source = _SC("NATIVE");
-                       si->funcname = _SC("unknown");
-                       if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
-                               si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
-                       si->line = -1;
-                       break;
-               }
-               return SQ_OK;
-       }
-       return SQ_ERROR;
-}
-
-void SQVM::Raise_Error(const SQChar *s, ...)
-{
-       va_list vl;
-       va_start(vl, s);
-       scvsprintf(_sp(rsl(scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
-       va_end(vl);
-       _lasterror = SQString::Create(_ss(this),_spval,-1);
-}
-
-void SQVM::Raise_Error(SQObjectPtr &desc)
-{
-       _lasterror = desc;
-}
-
-SQString *SQVM::PrintObjVal(const SQObject &o)
-{
-       switch(type(o)) {
-       case OT_STRING: return _string(o);
-       case OT_INTEGER:
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));
-               return SQString::Create(_ss(this), _spval);
-               break;
-       case OT_FLOAT:
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
-               return SQString::Create(_ss(this), _spval);
-               break;
-       default:
-               return SQString::Create(_ss(this), GetTypeName(o));
-       }
-}
-
-void SQVM::Raise_IdxError(SQObject &o)
-{
-       SQObjectPtr oval = PrintObjVal(o);
-       Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
-}
-
-void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
-{
-       SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
-       Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
-}
-
-
-void SQVM::Raise_ParamTypeError(int nparam,int typemask,int type)
-{
-       SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
-       int found = 0;  
-       for(int i=0; i<16; i++)
-       {
-               int mask = 0x00000001 << i;
-               if(typemask & (mask)) {
-                       if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
-                       found ++;
-                       StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
-               }
-       }
-       Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
-}
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include <stdarg.h>\r
+#include "sqvm.h"\r
+#include "sqfuncproto.h"\r
+#include "sqclosure.h"\r
+#include "sqstring.h"\r
+\r
+SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)\r
+{\r
+       SQInteger cssize = v->_callsstack.size();\r
+       if (cssize > level) {\r
+               memset(si, 0, sizeof(SQStackInfos));\r
+               SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];\r
+               switch (type(ci._closure)) {\r
+               case OT_CLOSURE:{\r
+                       SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);\r
+                       if (type(func->_name) == OT_STRING)\r
+                               si->funcname = _stringval(func->_name);\r
+                       if (type(func->_sourcename) == OT_STRING)\r
+                               si->source = _stringval(func->_sourcename);\r
+                       si->line = func->GetLine(ci._ip);\r
+                                               }\r
+                       break;\r
+               case OT_NATIVECLOSURE:\r
+                       si->source = _SC("NATIVE");\r
+                       si->funcname = _SC("unknown");\r
+                       if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)\r
+                               si->funcname = _stringval(_nativeclosure(ci._closure)->_name);\r
+                       si->line = -1;\r
+                       break;\r
+               }\r
+               return SQ_OK;\r
+       }\r
+       return SQ_ERROR;\r
+}\r
+\r
+void SQVM::Raise_Error(const SQChar *s, ...)\r
+{\r
+       va_list vl;\r
+       va_start(vl, s);\r
+       scvsprintf(_sp(rsl(scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);\r
+       va_end(vl);\r
+       _lasterror = SQString::Create(_ss(this),_spval,-1);\r
+}\r
+\r
+void SQVM::Raise_Error(SQObjectPtr &desc)\r
+{\r
+       _lasterror = desc;\r
+}\r
+\r
+SQString *SQVM::PrintObjVal(const SQObject &o)\r
+{\r
+       switch(type(o)) {\r
+       case OT_STRING: return _string(o);\r
+       case OT_INTEGER:\r
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));\r
+               return SQString::Create(_ss(this), _spval);\r
+               break;\r
+       case OT_FLOAT:\r
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));\r
+               return SQString::Create(_ss(this), _spval);\r
+               break;\r
+       default:\r
+               return SQString::Create(_ss(this), GetTypeName(o));\r
+       }\r
+}\r
+\r
+void SQVM::Raise_IdxError(SQObject &o)\r
+{\r
+       SQObjectPtr oval = PrintObjVal(o);\r
+       Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));\r
+}\r
+\r
+void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)\r
+{\r
+       SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);\r
+       Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));\r
+}\r
+\r
+\r
+void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)\r
+{\r
+       SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);\r
+       SQInteger found = 0;    \r
+       for(SQInteger i=0; i<16; i++)\r
+       {\r
+               SQInteger mask = 0x00000001 << i;\r
+               if(typemask & (mask)) {\r
+                       if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);\r
+                       found ++;\r
+                       StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);\r
+               }\r
+       }\r
+       Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));\r
+}\r
index 6d9ccc0..b4079b0 100644 (file)
@@ -1,89 +1,88 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQFUNCTION_H_
-#define _SQFUNCTION_H_
-
-#include "sqopcodes.h"
-
-enum SQOuterType {
-       otLOCAL = 0,
-       otSYMBOL = 1,
-       otOUTER = 2
-};
-
-struct SQOuterVar
-{
-       
-       SQOuterVar(){}
-       SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
-       {
-               _name = name;
-               _src=src;
-               _type=t;
-       }
-       SQOuterVar(const SQOuterVar &ov)
-       {
-               _type=ov._type;
-               _src=ov._src;
-               _name=ov._name;
-       }
-       SQOuterType _type;
-       SQObjectPtr _name;
-       SQObjectPtr _src;
-};
-
-struct SQLocalVarInfo
-{
-       SQLocalVarInfo():_start_op(0),_end_op(0){}
-       SQLocalVarInfo(const SQLocalVarInfo &lvi)
-       {
-               _name=lvi._name;
-               _start_op=lvi._start_op;
-               _end_op=lvi._end_op;
-               _pos=lvi._pos;
-       }
-       SQObjectPtr _name;
-       unsigned int _start_op;
-       unsigned int _end_op;
-       unsigned int _pos;
-};
-
-struct SQLineInfo { int _line;int _op; };
-
-typedef sqvector<SQOuterVar> SQOuterVarVec;
-typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
-typedef sqvector<SQLineInfo> SQLineInfoVec;
-
-struct SQFunctionProto : public SQRefCounted
-{
-private:
-       SQFunctionProto(){
-               _uiRef=0;
-       _stacksize=0;
-       _bgenerator=false;}
-public:
-       static SQFunctionProto *Create()
-       {
-               SQFunctionProto *f;
-               sq_new(f,SQFunctionProto);
-               return f;
-       }
-       void Release(){ sq_delete(this,SQFunctionProto);}
-       const SQChar* GetLocal(SQVM *v,unsigned int stackbase,unsigned int nseq,unsigned int nop);
-       int 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;
-       SQObjectPtr _sourcename;
-       SQObjectPtr _name;
-       SQLocalVarInfoVec _localvarinfos;
-       SQLineInfoVec _lineinfos;
-    int _stacksize;
-       bool _bgenerator;
-       bool _varparams;
-};
-
-#endif //_SQFUNCTION_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQFUNCTION_H_\r
+#define _SQFUNCTION_H_\r
+\r
+#include "sqopcodes.h"\r
+\r
+enum SQOuterType {\r
+       otLOCAL = 0,\r
+       otSYMBOL = 1,\r
+       otOUTER = 2\r
+};\r
+\r
+struct SQOuterVar\r
+{\r
+       \r
+       SQOuterVar(){}\r
+       SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)\r
+       {\r
+               _name = name;\r
+               _src=src;\r
+               _type=t;\r
+       }\r
+       SQOuterVar(const SQOuterVar &ov)\r
+       {\r
+               _type=ov._type;\r
+               _src=ov._src;\r
+               _name=ov._name;\r
+       }\r
+       SQOuterType _type;\r
+       SQObjectPtr _name;\r
+       SQObjectPtr _src;\r
+};\r
+\r
+struct SQLocalVarInfo\r
+{\r
+       SQLocalVarInfo():_start_op(0),_end_op(0){}\r
+       SQLocalVarInfo(const SQLocalVarInfo &lvi)\r
+       {\r
+               _name=lvi._name;\r
+               _start_op=lvi._start_op;\r
+               _end_op=lvi._end_op;\r
+               _pos=lvi._pos;\r
+       }\r
+       SQObjectPtr _name;\r
+       SQUnsignedInteger _start_op;\r
+       SQUnsignedInteger _end_op;\r
+       SQUnsignedInteger _pos;\r
+};\r
+\r
+struct SQLineInfo { SQInteger _line;SQInteger _op; };\r
+\r
+typedef sqvector<SQOuterVar> SQOuterVarVec;\r
+typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;\r
+typedef sqvector<SQLineInfo> SQLineInfoVec;\r
+\r
+struct SQFunctionProto : public SQRefCounted\r
+{\r
+private:\r
+       SQFunctionProto(){\r
+       _stacksize=0;\r
+       _bgenerator=false;}\r
+public:\r
+       static SQFunctionProto *Create()\r
+       {\r
+               SQFunctionProto *f;\r
+               sq_new(f,SQFunctionProto);\r
+               return f;\r
+       }\r
+       void Release(){ sq_delete(this,SQFunctionProto);}\r
+       const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);\r
+       SQInteger GetLine(SQInstruction *curr);\r
+       bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);\r
+       bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read);\r
+       SQObjectPtrVec _literals;\r
+       SQObjectPtrVec _functions;\r
+       SQObjectPtrVec _parameters;\r
+       SQOuterVarVec _outervalues;\r
+       SQInstructionVec _instructions;\r
+       SQObjectPtr _sourcename;\r
+       SQObjectPtr _name;\r
+       SQLocalVarInfoVec _localvarinfos;\r
+       SQLineInfoVec _lineinfos;\r
+    SQInteger _stacksize;\r
+       bool _bgenerator;\r
+       bool _varparams;\r
+};\r
+\r
+#endif //_SQFUNCTION_H_\r
index 9823fd3..9e16026 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqcompiler.h"
-#include "sqfuncproto.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqopcodes.h"
-#include "sqfuncstate.h"
-
-#ifdef _DEBUG_DUMP
-SQInstructionDesc g_InstrDesc[]={
-       {_SC("_OP_LINE")},
-       {_SC("_OP_LOAD")},
-       {_SC("_OP_TAILCALL")},
-       {_SC("_OP_CALL")},
-       {_SC("_OP_PREPCALL")},
-       {_SC("_OP_PREPCALLK")},
-       {_SC("_OP_GETK")},
-       {_SC("_OP_MOVE")},
-       {_SC("_OP_NEWSLOT")},
-       {_SC("_OP_DELETE")},
-       {_SC("_OP_SET")},
-       {_SC("_OP_GET")},
-       {_SC("_OP_EQ")},
-       {_SC("_OP_NE")},
-       {_SC("_OP_ARITH")},
-       {_SC("_OP_BITW")},
-       {_SC("_OP_RETURN")},
-       {_SC("_OP_LOADNULLS")},
-       {_SC("_OP_LOADROOTTABLE")},
-       {_SC("_OP_DMOVE")},
-       {_SC("_OP_JMP")},
-       {_SC("_OP_JNZ")},
-       {_SC("_OP_JZ")},
-       {_SC("_OP_LOADFREEVAR")},
-       {_SC("_OP_VARGC")},
-       {_SC("_OP_GETVARGV")},
-       {_SC("_OP_NEWTABLE")},
-       {_SC("_OP_NEWARRAY")},
-       {_SC("_OP_APPENDARRAY")},
-       {_SC("_OP_GETPARENT")},
-       {_SC("_OP_COMPARITH")},
-       {_SC("_OP_COMPARITHL")},
-       {_SC("_OP_INC")},
-       {_SC("_OP_INCL")},
-       {_SC("_OP_PINC")},
-       {_SC("_OP_PINCL")},
-       {_SC("_OP_CMP")},
-       {_SC("_OP_EXISTS")},
-       {_SC("_OP_INSTANCEOF")},
-       {_SC("_OP_AND")},
-       {_SC("_OP_OR")},
-       {_SC("_OP_NEG")},
-       {_SC("_OP_NOT")},
-       {_SC("_OP_BWNOT")},
-       {_SC("_OP_CLOSURE")},
-       {_SC("_OP_YIELD")},
-       {_SC("_OP_RESUME")},
-       {_SC("_OP_FOREACH")},
-       {_SC("_OP_DELEGATE")},
-       {_SC("_OP_CLONE")},
-       {_SC("_OP_TYPEOF")},
-       {_SC("_OP_PUSHTRAP")},
-       {_SC("_OP_POPTRAP")},
-       {_SC("_OP_THROW")},
-       {_SC("_OP_CLASS")},
-       {_SC("_OP_NEWSLOTA")},
-       {_SC("_OP_LOADBOOL")}
-};
-#endif
-void DumpLiteral(SQObjectPtr &o)
-{
-       switch(type(o)){
-               case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
-               case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
-               case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
-       }
-}
-
-SQFuncState::SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
-{
-               _nliterals = 0;
-               _literals = SQTable::Create(ss,0);
-               _strings =  SQTable::Create(ss,0);
-               _sharedstate = ss;
-               _lastline = 0;
-               _optimization = true;
-               _func = func;
-               _parent = parent;
-               _stacksize = 0;
-               _traps = 0;
-               _returnexp = 0;
-               _varparams = false;
-               _errfunc = efunc;
-               _errtarget = ed;
-
-}
-
-void SQFuncState::Error(const SQChar *err)
-{
-       _errfunc(_errtarget,err);
-}
-
-#ifdef _DEBUG_DUMP
-void SQFuncState::Dump()
-{
-       unsigned int n=0,i;
-       SQFunctionProto *func=_funcproto(_func);
-       scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
-       scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
-       scprintf(_SC("--------------------------------------------------------------------\n"));
-       scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
-       scprintf(_SC("-----LITERALS\n"));
-       SQObjectPtr refidx,key,val;
-       SQInteger idx;
-       SQObjectPtrVec templiterals;
-       templiterals.resize(_nliterals);
-       while((idx=_table(_literals)->Next(refidx,key,val))!=-1) {
-               refidx=idx;
-               templiterals[_integer(val)]=key;
-       }
-       for(i=0;i<templiterals.size();i++){
-               scprintf(_SC("[%d] "),n);
-               DumpLiteral(templiterals[i]);
-               scprintf(_SC("\n"));
-               n++;
-       }
-       scprintf(_SC("-----PARAMS\n"));
-       if(_varparams)
-               scprintf(_SC("<<VARPARAMS>>\n"));
-       n=0;
-       for(i=0;i<_parameters.size();i++){
-               scprintf(_SC("[%d] "),n);
-               DumpLiteral(_parameters[i]);
-               scprintf(_SC("\n"));
-               n++;
-       }
-       scprintf(_SC("-----LOCALS\n"));
-       for(i=0;i<func->_localvarinfos.size();i++){
-               SQLocalVarInfo lvi=func->_localvarinfos[i];
-               scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
-               n++;
-       }
-       scprintf(_SC("-----LINE INFO\n"));
-       for(i=0;i<_lineinfos.size();i++){
-               SQLineInfo li=_lineinfos[i];
-               scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
-               n++;
-       }
-       scprintf(_SC("-----dump\n"));
-       n=0;
-       for(i=0;i<_instructions.size();i++){
-               SQInstruction &inst=_instructions[i];
-               if(inst.op==_OP_LOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
-                       
-                       int lidx = inst._arg1;
-                       scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
-                       if(lidx >= 0xFFFFFFFF)
-                               scprintf(_SC("null"));
-                       else {
-                               int refidx;
-                               SQObjectPtr val,key,refo;
-                               while(((refidx=_table(_literals)->Next(refo,key,val))!= -1) && (_integer(val) != lidx)) {
-                                       refo = refidx;  
-                               }
-                               DumpLiteral(key);
-                       }
-                       scprintf(_SC(" %d %d \n"),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 
-                       scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
-               n++;
-       }
-       scprintf(_SC("-----\n"));
-       scprintf(_SC("stack size[%d]\n"),func->_stacksize);
-       scprintf(_SC("--------------------------------------------------------------------\n\n"));
-}
-#endif
-/*int SQFuncState::GetStringConstant(SQObjectPtr &cons)
-{
-       return GetConstant(cons);
-}*/
-
-int SQFuncState::GetNumericConstant(const SQInteger cons)
-{
-       return GetConstant(SQObjectPtr(cons));
-}
-
-int SQFuncState::GetNumericConstant(const SQFloat cons)
-{
-       return GetConstant(SQObjectPtr(cons));
-}
-
-int SQFuncState::GetConstant(const SQObject &cons)
-{
-       int n=0;
-       SQObjectPtr val;
-       if(!_table(_literals)->Get(cons,val))
-       {
-               val = _nliterals;
-               _table(_literals)->NewSlot(cons,val);
-               _nliterals++;
-               if(_nliterals > MAX_LITERALS) {
-                       val.Null();
-                       Error(_SC("internal compiler error: too many literals"));
-               }
-       }
-       return _integer(val);
-}
-
-void SQFuncState::SetIntructionParams(int pos,int arg0,int arg1,int arg2,int arg3)
-{
-       _instructions[pos]._arg0=*((unsigned int *)&arg0);
-       _instructions[pos]._arg1=*((unsigned int *)&arg1);
-       _instructions[pos]._arg2=*((unsigned int *)&arg2);
-       _instructions[pos]._arg3=*((unsigned int *)&arg3);
-}
-
-void SQFuncState::SetIntructionParam(int pos,int arg,int val)
-{
-       switch(arg){
-               case 0:_instructions[pos]._arg0=*((unsigned int *)&val);break;
-               case 1:_instructions[pos]._arg1=*((unsigned int *)&val);break;
-               case 2:_instructions[pos]._arg2=*((unsigned int *)&val);break;
-               case 3:_instructions[pos]._arg3=*((unsigned int *)&val);break;
-               case 4:_instructions[pos]._arg1=*((unsigned int *)&val);break;
-       };
-}
-
-int SQFuncState::AllocStackPos()
-{
-       int npos=_vlocals.size();
-       _vlocals.push_back(SQLocalVarInfo());
-       if(_vlocals.size()>((unsigned int)_stacksize)) {
-               if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
-               _stacksize=_vlocals.size();
-       }
-       return npos;
-}
-
-int SQFuncState::PushTarget(int n)
-{
-       if(n!=-1){
-               _targetstack.push_back(n);
-               return n;
-       }
-       n=AllocStackPos();
-       _targetstack.push_back(n);
-       return n;
-}
-
-int SQFuncState::GetUpTarget(int n){
-       return _targetstack[((_targetstack.size()-1)-n)];
-}
-
-int SQFuncState::TopTarget(){
-       return _targetstack.back();
-}
-int SQFuncState::PopTarget()
-{
-       int npos=_targetstack.back();
-       SQLocalVarInfo t=_vlocals[_targetstack.back()];
-       if(type(t._name)==OT_NULL){
-               _vlocals.pop_back();
-       }
-       _targetstack.pop_back();
-       return npos;
-}
-
-int SQFuncState::GetStackSize()
-{
-       return _vlocals.size();
-}
-
-void SQFuncState::SetStackSize(int n)
-{
-       int size=_vlocals.size();
-       while(size>n){
-               size--;
-               SQLocalVarInfo lvi=_vlocals.back();
-               if(type(lvi._name)!=OT_NULL){
-                       lvi._end_op=GetCurrentPos();
-                       _localvarinfos.push_back(lvi);
-               }
-               _vlocals.pop_back();
-       }
-}
-
-bool SQFuncState::IsLocal(unsigned int stkpos)
-{
-       if(stkpos>=_vlocals.size())return false;
-       else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
-       return false;
-}
-
-int SQFuncState::PushLocalVariable(const SQObject &name)
-{
-       int pos=_vlocals.size();
-       SQLocalVarInfo lvi;
-       lvi._name=name;
-       lvi._start_op=GetCurrentPos()+1;
-       lvi._pos=_vlocals.size();
-       _vlocals.push_back(lvi);
-       if(_vlocals.size()>((unsigned int)_stacksize))_stacksize=_vlocals.size();
-       
-       return pos;
-}
-
-int SQFuncState::GetLocalVariable(const SQObject &name)
-{
-       int locals=_vlocals.size();
-       while(locals>=1){
-               if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){
-                       return locals-1;
-               }
-               locals--;
-       }
-       return -1;
-}
-
-int SQFuncState::GetOuterVariable(const SQObject &name)
-{
-       int outers = _outervalues.size();
-       for(int i = 0; i<outers; i++) {
-               if(_string(_outervalues[i]._name) == _string(name))
-                       return i;
-       }
-       return -1;
-}
-
-void SQFuncState::AddOuterValue(const SQObject &name)
-{
-       //AddParameter(name);
-       int pos=-1;
-       if(_parent) { 
-               pos = _parent->GetLocalVariable(name);
-               if(pos == -1) {
-                       pos = _parent->GetOuterVariable(name);
-                       if(pos != -1) {
-                               _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
-                               return;
-                       }
-               }
-               else {
-                       _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
-                       return;
-               }
-       }       
-       _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
-}
-
-void SQFuncState::AddParameter(const SQObject &name)
-{
-       PushLocalVariable(name);
-       _parameters.push_back(name);
-}
-
-void SQFuncState::AddLineInfos(int line,bool lineop,bool force)
-{
-       if(_lastline!=line || force){
-               SQLineInfo li;
-               li._line=line;li._op=(GetCurrentPos()+1);
-               if(lineop)AddInstruction(_OP_LINE,0,line);
-               _lineinfos.push_back(li);
-               _lastline=line;
-       }
-}
-
-void SQFuncState::AddInstruction(SQInstruction &i)
-{
-       int size = _instructions.size();
-       if(size > 0 && _optimization){ //simple optimizer
-               SQInstruction &pi = _instructions[size-1];//previous instruction
-               switch(i.op) {
-               case _OP_RETURN:
-                       if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
-                               pi.op = _OP_TAILCALL;
-                       }
-               break;
-               case _OP_GET:
-                       if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
-                               pi._arg1 = pi._arg1;
-                               pi._arg2 = (unsigned char)i._arg1;
-                               pi.op = _OP_GETK;
-                               pi._arg0 = i._arg0;
-                               
-                               return;
-                       }
-               break;
-               case _OP_PREPCALL:
-                       if( pi.op == _OP_LOAD  && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
-                               pi.op = _OP_PREPCALLK;
-                               pi._arg0 = i._arg0;
-                               pi._arg1 = pi._arg1;
-                               pi._arg2 = i._arg2;
-                               pi._arg3 = i._arg3;
-                               return;
-                       }
-                       break;
-               case _OP_APPENDARRAY:
-                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
-                               pi.op = _OP_APPENDARRAY;
-                               pi._arg0 = i._arg0;
-                               pi._arg1 = pi._arg1;
-                               pi._arg2 = MAX_FUNC_STACKSIZE;
-                               pi._arg3 = MAX_FUNC_STACKSIZE;
-                               return;
-                       }
-                       break;
-               case _OP_MOVE: 
-                       if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))
-                       {
-                               pi._arg0 = i._arg0;
-                               _optimization = false;
-                               return;
-                       }
-
-                       if(pi.op == _OP_MOVE)
-                       {
-                               pi.op = _OP_DMOVE;
-                               pi._arg2 = i._arg0;
-                               pi._arg3 = (unsigned char)i._arg1;
-                               return;
-                       }
-                       break;
-
-               case _OP_EQ:case _OP_NE:
-                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
-                       {
-                               pi.op = i.op;
-                               pi._arg0 = i._arg0;
-                               pi._arg1 = pi._arg1;
-                               pi._arg2 = i._arg2;
-                               pi._arg3 = MAX_FUNC_STACKSIZE;
-                               return;
-                       }
-                       break;
-               case _OP_LOADNULLS:
-               //case _OP_LOADNULL:
-                       if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
-                               
-                               pi._arg1 = pi._arg1 + 1;
-                               pi.op = _OP_LOADNULLS;
-                               return;
-                       }
-            break;
-               case _OP_LINE:
-                       if(pi.op == _OP_LINE) {
-                               _instructions.pop_back();
-                               _lineinfos.pop_back();
-                       }
-                       break;
-               }
-       }
-       _optimization = true;
-       _instructions.push_back(i);
-}
-
-SQObject SQFuncState::CreateString(const SQChar *s,int len)
-{
-       SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
-       _table(_strings)->NewSlot(ns,1);
-       return ns;
-}
-
-void SQFuncState::Finalize()
-{
-       SQFunctionProto *f=_funcproto(_func);
-       f->_literals.resize(_nliterals);
-       SQObjectPtr refidx,key,val;
-       SQInteger idx;
-       while((idx=_table(_literals)->Next(refidx,key,val))!=-1) {
-               f->_literals[_integer(val)]=key;
-               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);
-       f->_varparams = _varparams;
-}
-
-SQFuncState *SQFuncState::PushChildState(SQSharedState *ss,SQFunctionProto *func)
-{
-       SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
-       new (child) SQFuncState(ss,func,this,_errfunc,_errtarget);
-       _childstates.push_back(child);
-       return child;
-}
-
-void SQFuncState::PopChildState()
-{
-       SQFuncState *child = _childstates.back();
-       sq_delete(child,SQFuncState);
-       _childstates.pop_back();
-}
-
-SQFuncState::~SQFuncState()
-{
-       while(_childstates.size() > 0)
-       {
-               PopChildState();
-       }
-}
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include "sqcompiler.h"\r
+#include "sqfuncproto.h"\r
+#include "sqstring.h"\r
+#include "sqtable.h"\r
+#include "sqopcodes.h"\r
+#include "sqfuncstate.h"\r
+\r
+#ifdef _DEBUG_DUMP\r
+SQInstructionDesc g_InstrDesc[]={\r
+       {_SC("_OP_LINE")},\r
+       {_SC("_OP_LOAD")},\r
+       {_SC("_OP_DLOAD")},\r
+       {_SC("_OP_TAILCALL")},\r
+       {_SC("_OP_CALL")},\r
+       {_SC("_OP_PREPCALL")},\r
+       {_SC("_OP_PREPCALLK")},\r
+       {_SC("_OP_GETK")},\r
+       {_SC("_OP_MOVE")},\r
+       {_SC("_OP_NEWSLOT")},\r
+       {_SC("_OP_DELETE")},\r
+       {_SC("_OP_SET")},\r
+       {_SC("_OP_GET")},\r
+       {_SC("_OP_EQ")},\r
+       {_SC("_OP_NE")},\r
+       {_SC("_OP_ARITH")},\r
+       {_SC("_OP_BITW")},\r
+       {_SC("_OP_RETURN")},\r
+       {_SC("_OP_LOADNULLS")},\r
+       {_SC("_OP_LOADROOTTABLE")},\r
+       {_SC("_OP_LOADBOOL")},\r
+       {_SC("_OP_DMOVE")},\r
+       {_SC("_OP_JMP")},\r
+       {_SC("_OP_JNZ")},\r
+       {_SC("_OP_JZ")},\r
+       {_SC("_OP_LOADFREEVAR")},\r
+       {_SC("_OP_VARGC")},\r
+       {_SC("_OP_GETVARGV")},\r
+       {_SC("_OP_NEWTABLE")},\r
+       {_SC("_OP_NEWARRAY")},\r
+       {_SC("_OP_APPENDARRAY")},\r
+       {_SC("_OP_GETPARENT")},\r
+       {_SC("_OP_COMPARITH")},\r
+       {_SC("_OP_COMPARITHL")},\r
+       {_SC("_OP_INC")},\r
+       {_SC("_OP_INCL")},\r
+       {_SC("_OP_PINC")},\r
+       {_SC("_OP_PINCL")},\r
+       {_SC("_OP_CMP")},\r
+       {_SC("_OP_EXISTS")},\r
+       {_SC("_OP_INSTANCEOF")},\r
+       {_SC("_OP_AND")},\r
+       {_SC("_OP_OR")},\r
+       {_SC("_OP_NEG")},\r
+       {_SC("_OP_NOT")},\r
+       {_SC("_OP_BWNOT")},\r
+       {_SC("_OP_CLOSURE")},\r
+       {_SC("_OP_YIELD")},\r
+       {_SC("_OP_RESUME")},\r
+       {_SC("_OP_FOREACH")},\r
+       {_SC("_OP_DELEGATE")},\r
+       {_SC("_OP_CLONE")},\r
+       {_SC("_OP_TYPEOF")},\r
+       {_SC("_OP_PUSHTRAP")},\r
+       {_SC("_OP_POPTRAP")},\r
+       {_SC("_OP_THROW")},\r
+       {_SC("_OP_CLASS")},\r
+       {_SC("_OP_NEWSLOTA")}\r
+};\r
+#endif\r
+void DumpLiteral(SQObjectPtr &o)\r
+{\r
+       switch(type(o)){\r
+               case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;\r
+               case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;\r
+               case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;\r
+       }\r
+}\r
+\r
+SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)\r
+{\r
+               _nliterals = 0;\r
+               _literals = SQTable::Create(ss,0);\r
+               _strings =  SQTable::Create(ss,0);\r
+               _sharedstate = ss;\r
+               _lastline = 0;\r
+               _optimization = true;\r
+               _parent = parent;\r
+               _stacksize = 0;\r
+               _traps = 0;\r
+               _returnexp = 0;\r
+               _varparams = false;\r
+               _errfunc = efunc;\r
+               _errtarget = ed;\r
+               _bgenerator = false;\r
+\r
+}\r
+\r
+void SQFuncState::Error(const SQChar *err)\r
+{\r
+       _errfunc(_errtarget,err);\r
+}\r
+\r
+#ifdef _DEBUG_DUMP\r
+void SQFuncState::Dump(SQFunctionProto *func)\r
+{\r
+       SQUnsignedInteger n=0,i;\r
+       scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));\r
+       scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));\r
+       scprintf(_SC("--------------------------------------------------------------------\n"));\r
+       scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));\r
+       scprintf(_SC("-----LITERALS\n"));\r
+       SQObjectPtr refidx,key,val;\r
+       SQInteger idx;\r
+       SQObjectPtrVec templiterals;\r
+       templiterals.resize(_nliterals);\r
+       while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {\r
+               refidx=idx;\r
+               templiterals[_integer(val)]=key;\r
+       }\r
+       for(i=0;i<templiterals.size();i++){\r
+               scprintf(_SC("[%d] "),n);\r
+               DumpLiteral(templiterals[i]);\r
+               scprintf(_SC("\n"));\r
+               n++;\r
+       }\r
+       scprintf(_SC("-----PARAMS\n"));\r
+       if(_varparams)\r
+               scprintf(_SC("<<VARPARAMS>>\n"));\r
+       n=0;\r
+       for(i=0;i<_parameters.size();i++){\r
+               scprintf(_SC("[%d] "),n);\r
+               DumpLiteral(_parameters[i]);\r
+               scprintf(_SC("\n"));\r
+               n++;\r
+       }\r
+       scprintf(_SC("-----LOCALS\n"));\r
+       for(i=0;i<func->_localvarinfos.size();i++){\r
+               SQLocalVarInfo lvi=func->_localvarinfos[i];\r
+               scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);\r
+               n++;\r
+       }\r
+       scprintf(_SC("-----LINE INFO\n"));\r
+       for(i=0;i<_lineinfos.size();i++){\r
+               SQLineInfo li=_lineinfos[i];\r
+               scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);\r
+               n++;\r
+       }\r
+       scprintf(_SC("-----dump\n"));\r
+       n=0;\r
+       for(i=0;i<_instructions.size();i++){\r
+               SQInstruction &inst=_instructions[i];\r
+               if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){\r
+                       \r
+                       SQInteger lidx = inst._arg1;\r
+                       scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);\r
+                       if(lidx >= 0xFFFFFFFF)\r
+                               scprintf(_SC("null"));\r
+                       else {\r
+                               SQInteger refidx;\r
+                               SQObjectPtr val,key,refo;\r
+                               while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {\r
+                                       refo = refidx;  \r
+                               }\r
+                               DumpLiteral(key);\r
+                       }\r
+                       if(inst.op != _OP_DLOAD) {\r
+                               scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);\r
+                       }\r
+                       else {\r
+                               scprintf(_SC(" %d "),inst._arg2);\r
+                               lidx = inst._arg3;\r
+                               if(lidx >= 0xFFFFFFFF)\r
+                                       scprintf(_SC("null"));\r
+                               else {\r
+                                       SQInteger refidx;\r
+                                       SQObjectPtr val,key,refo;\r
+                                       while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {\r
+                                               refo = refidx;  \r
+                               }\r
+                               DumpLiteral(key);\r
+                               scprintf(_SC("\n"));\r
+                       }\r
+                       }\r
+               }\r
+               else if(inst.op==_OP_ARITH){\r
+                       scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);\r
+               }\r
+               else \r
+                       scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);\r
+               n++;\r
+       }\r
+       scprintf(_SC("-----\n"));\r
+       scprintf(_SC("stack size[%d]\n"),func->_stacksize);\r
+       scprintf(_SC("--------------------------------------------------------------------\n\n"));\r
+}\r
+#endif\r
+\r
+SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)\r
+{\r
+       return GetConstant(SQObjectPtr(cons));\r
+}\r
+\r
+SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)\r
+{\r
+       return GetConstant(SQObjectPtr(cons));\r
+}\r
+\r
+SQInteger SQFuncState::GetConstant(const SQObject &cons)\r
+{\r
+       SQInteger n=0;\r
+       SQObjectPtr val;\r
+       if(!_table(_literals)->Get(cons,val))\r
+       {\r
+               val = _nliterals;\r
+               _table(_literals)->NewSlot(cons,val);\r
+               _nliterals++;\r
+               if(_nliterals > MAX_LITERALS) {\r
+                       val.Null();\r
+                       Error(_SC("internal compiler error: too many literals"));\r
+               }\r
+       }\r
+       return _integer(val);\r
+}\r
+\r
+void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)\r
+{\r
+       _instructions[pos]._arg0=*((SQUnsignedInteger *)&arg0);\r
+       _instructions[pos]._arg1=*((SQUnsignedInteger *)&arg1);\r
+       _instructions[pos]._arg2=*((SQUnsignedInteger *)&arg2);\r
+       _instructions[pos]._arg3=*((SQUnsignedInteger *)&arg3);\r
+}\r
+\r
+void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)\r
+{\r
+       switch(arg){\r
+               case 0:_instructions[pos]._arg0=*((SQUnsignedInteger *)&val);break;\r
+               case 1:_instructions[pos]._arg1=*((SQUnsignedInteger *)&val);break;\r
+               case 2:_instructions[pos]._arg2=*((SQUnsignedInteger *)&val);break;\r
+               case 3:_instructions[pos]._arg3=*((SQUnsignedInteger *)&val);break;\r
+               case 4:_instructions[pos]._arg1=*((SQUnsignedInteger *)&val);break;\r
+       };\r
+}\r
+\r
+SQInteger SQFuncState::AllocStackPos()\r
+{\r
+       SQInteger npos=_vlocals.size();\r
+       _vlocals.push_back(SQLocalVarInfo());\r
+       if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {\r
+               if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));\r
+               _stacksize=_vlocals.size();\r
+       }\r
+       return npos;\r
+}\r
+\r
+SQInteger SQFuncState::PushTarget(SQInteger n)\r
+{\r
+       if(n!=-1){\r
+               _targetstack.push_back(n);\r
+               return n;\r
+       }\r
+       n=AllocStackPos();\r
+       _targetstack.push_back(n);\r
+       return n;\r
+}\r
+\r
+SQInteger SQFuncState::GetUpTarget(SQInteger n){\r
+       return _targetstack[((_targetstack.size()-1)-n)];\r
+}\r
+\r
+SQInteger SQFuncState::TopTarget(){\r
+       return _targetstack.back();\r
+}\r
+SQInteger SQFuncState::PopTarget()\r
+{\r
+       SQInteger npos=_targetstack.back();\r
+       SQLocalVarInfo t=_vlocals[_targetstack.back()];\r
+       if(type(t._name)==OT_NULL){\r
+               _vlocals.pop_back();\r
+       }\r
+       _targetstack.pop_back();\r
+       return npos;\r
+}\r
+\r
+SQInteger SQFuncState::GetStackSize()\r
+{\r
+       return _vlocals.size();\r
+}\r
+\r
+void SQFuncState::SetStackSize(SQInteger n)\r
+{\r
+       SQInteger size=_vlocals.size();\r
+       while(size>n){\r
+               size--;\r
+               SQLocalVarInfo lvi=_vlocals.back();\r
+               if(type(lvi._name)!=OT_NULL){\r
+                       lvi._end_op=GetCurrentPos();\r
+                       _localvarinfos.push_back(lvi);\r
+               }\r
+               _vlocals.pop_back();\r
+       }\r
+}\r
+\r
+bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)\r
+{\r
+       if(stkpos>=_vlocals.size())return false;\r
+       else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;\r
+       return false;\r
+}\r
+\r
+SQInteger SQFuncState::PushLocalVariable(const SQObject &name)\r
+{\r
+       SQInteger pos=_vlocals.size();\r
+       SQLocalVarInfo lvi;\r
+       lvi._name=name;\r
+       lvi._start_op=GetCurrentPos()+1;\r
+       lvi._pos=_vlocals.size();\r
+       _vlocals.push_back(lvi);\r
+       if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();\r
+       \r
+       return pos;\r
+}\r
+\r
+SQInteger SQFuncState::GetLocalVariable(const SQObject &name)\r
+{\r
+       SQInteger locals=_vlocals.size();\r
+       while(locals>=1){\r
+               if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){\r
+                       return locals-1;\r
+               }\r
+               locals--;\r
+       }\r
+       return -1;\r
+}\r
+\r
+SQInteger SQFuncState::GetOuterVariable(const SQObject &name)\r
+{\r
+       SQInteger outers = _outervalues.size();\r
+       for(SQInteger i = 0; i<outers; i++) {\r
+               if(_string(_outervalues[i]._name) == _string(name))\r
+                       return i;\r
+       }\r
+       return -1;\r
+}\r
+\r
+void SQFuncState::AddOuterValue(const SQObject &name)\r
+{\r
+       SQInteger pos=-1;\r
+       if(_parent) { \r
+               pos = _parent->GetLocalVariable(name);\r
+               if(pos == -1) {\r
+                       pos = _parent->GetOuterVariable(name);\r
+                       if(pos != -1) {\r
+                               _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local\r
+                               return;\r
+                       }\r
+               }\r
+               else {\r
+                       _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local\r
+                       return;\r
+               }\r
+       }       \r
+       _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global\r
+}\r
+\r
+void SQFuncState::AddParameter(const SQObject &name)\r
+{\r
+       PushLocalVariable(name);\r
+       _parameters.push_back(name);\r
+}\r
+\r
+void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)\r
+{\r
+       if(_lastline!=line || force){\r
+               SQLineInfo li;\r
+               li._line=line;li._op=(GetCurrentPos()+1);\r
+               if(lineop)AddInstruction(_OP_LINE,0,line);\r
+               _lineinfos.push_back(li);\r
+               _lastline=line;\r
+       }\r
+}\r
+\r
+void SQFuncState::AddInstruction(SQInstruction &i)\r
+{\r
+       SQInteger size = _instructions.size();\r
+       if(size > 0 && _optimization){ //simple optimizer\r
+               SQInstruction &pi = _instructions[size-1];//previous instruction\r
+               switch(i.op) {\r
+               case _OP_RETURN:\r
+                       if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {\r
+                               pi.op = _OP_TAILCALL;\r
+                       }\r
+               break;\r
+               case _OP_GET:\r
+                       if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){\r
+                               pi._arg1 = pi._arg1;\r
+                               pi._arg2 = (unsigned char)i._arg1;\r
+                               pi.op = _OP_GETK;\r
+                               pi._arg0 = i._arg0;\r
+                               \r
+                               return;\r
+                       }\r
+               break;\r
+               case _OP_PREPCALL:\r
+                       if( pi.op == _OP_LOAD  && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){\r
+                               pi.op = _OP_PREPCALLK;\r
+                               pi._arg0 = i._arg0;\r
+                               pi._arg1 = pi._arg1;\r
+                               pi._arg2 = i._arg2;\r
+                               pi._arg3 = i._arg3;\r
+                               return;\r
+                       }\r
+                       break;\r
+               case _OP_APPENDARRAY:\r
+                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){\r
+                               pi.op = _OP_APPENDARRAY;\r
+                               pi._arg0 = i._arg0;\r
+                               pi._arg1 = pi._arg1;\r
+                               pi._arg2 = MAX_FUNC_STACKSIZE;\r
+                               pi._arg3 = MAX_FUNC_STACKSIZE;\r
+                               return;\r
+                       }\r
+                       break;\r
+               case _OP_MOVE: \r
+                       if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))\r
+                       {\r
+                               pi._arg0 = i._arg0;\r
+                               _optimization = false;\r
+                               return;\r
+                       }\r
+\r
+                       if(pi.op == _OP_MOVE)\r
+                       {\r
+                               pi.op = _OP_DMOVE;\r
+                               pi._arg2 = i._arg0;\r
+                               pi._arg3 = (unsigned char)i._arg1;\r
+                               return;\r
+                       }\r
+                       break;\r
+               case _OP_LOAD:\r
+                       if(pi.op == _OP_LOAD && i._arg1 < 256) {\r
+                               pi.op = _OP_DLOAD;\r
+                               pi._arg2 = i._arg0;\r
+                               pi._arg3 = (unsigned char)i._arg1;\r
+                               return;\r
+                       }\r
+                       break;\r
+               case _OP_EQ:case _OP_NE:\r
+                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))\r
+                       {\r
+                               pi.op = i.op;\r
+                               pi._arg0 = i._arg0;\r
+                               pi._arg1 = pi._arg1;\r
+                               pi._arg2 = i._arg2;\r
+                               pi._arg3 = MAX_FUNC_STACKSIZE;\r
+                               return;\r
+                       }\r
+                       break;\r
+               case _OP_LOADNULLS:\r
+                       if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {\r
+                               \r
+                               pi._arg1 = pi._arg1 + 1;\r
+                               pi.op = _OP_LOADNULLS;\r
+                               return;\r
+                       }\r
+            break;\r
+               case _OP_LINE:\r
+                       if(pi.op == _OP_LINE) {\r
+                               _instructions.pop_back();\r
+                               _lineinfos.pop_back();\r
+                       }\r
+                       break;\r
+               }\r
+       }\r
+       _optimization = true;\r
+       _instructions.push_back(i);\r
+}\r
+\r
+SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)\r
+{\r
+       SQObjectPtr ns(SQString::Create(_sharedstate,s,len));\r
+       _table(_strings)->NewSlot(ns,1);\r
+       return ns;\r
+}\r
+\r
+SQFunctionProto *SQFuncState::BuildProto()\r
+{\r
+       SQFunctionProto *f=SQFunctionProto::Create();\r
+       f->_literals.resize(_nliterals);\r
+       SQObjectPtr refidx,key,val;\r
+       SQInteger idx;\r
+\r
+       f->_stacksize = _stacksize;\r
+       f->_sourcename = _sourcename;\r
+       f->_bgenerator = _bgenerator;\r
+       f->_name = _name;\r
+\r
+       while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {\r
+               f->_literals[_integer(val)]=key;\r
+               refidx=idx;\r
+       }\r
+\r
+       f->_functions.resize(_functions.size());\r
+       f->_functions.copy(_functions);\r
+       f->_parameters.resize(_parameters.size());\r
+       f->_parameters.copy(_parameters);\r
+       f->_outervalues.resize(_outervalues.size());\r
+       f->_outervalues.copy(_outervalues);\r
+       f->_instructions.resize(_instructions.size());\r
+       f->_instructions.copy(_instructions);\r
+       f->_localvarinfos.resize(_localvarinfos.size());\r
+       f->_localvarinfos.copy(_localvarinfos);\r
+       f->_lineinfos.resize(_lineinfos.size());\r
+       f->_lineinfos.copy(_lineinfos);\r
+       f->_varparams = _varparams;\r
+\r
+       return f;\r
+}\r
+\r
+SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)\r
+{\r
+       SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));\r
+       new (child) SQFuncState(ss,this,_errfunc,_errtarget);\r
+       _childstates.push_back(child);\r
+       return child;\r
+}\r
+\r
+void SQFuncState::PopChildState()\r
+{\r
+       SQFuncState *child = _childstates.back();\r
+       sq_delete(child,SQFuncState);\r
+       _childstates.pop_back();\r
+}\r
+\r
+SQFuncState::~SQFuncState()\r
+{\r
+       while(_childstates.size() > 0)\r
+       {\r
+               PopChildState();\r
+       }\r
+}\r
index 4324eaa..c69a2f4 100644 (file)
@@ -1,79 +1,81 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQFUNCSTATE_H_
-#define _SQFUNCSTATE_H_
-///////////////////////////////////
-#include "squtils.h"
-
-struct SQFuncState
-{
-       SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
-       ~SQFuncState();
-#ifdef _DEBUG_DUMP
-       void Dump();
-#endif
-       void Error(const SQChar *err);
-       SQFuncState *PushChildState(SQSharedState *ss,SQFunctionProto *func);
-       void PopChildState();
-       void AddInstruction(SQOpcode _op,int arg0=0,int arg1=0,int arg2=0,int arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
-       void AddInstruction(SQInstruction &i);
-       void SetIntructionParams(int pos,int arg0,int arg1,int arg2=0,int arg3=0);
-       void SetIntructionParam(int pos,int arg,int val);
-       SQInstruction &GetInstruction(int pos){return _instructions[pos];}
-       void PopInstructions(int size){for(int i=0;i<size;i++)_instructions.pop_back();}
-       void SetStackSize(int n);
-       void SnoozeOpt(){_optimization=false;}
-       int GetCurrentPos(){return _instructions.size()-1;}
-       //int GetStringConstant(const SQChar *cons);
-       int GetNumericConstant(const SQInteger cons);
-       int GetNumericConstant(const SQFloat cons);
-       int PushLocalVariable(const SQObject &name);
-       void AddParameter(const SQObject &name);
-       void AddOuterValue(const SQObject &name);
-       int GetLocalVariable(const SQObject &name);
-       int GetOuterVariable(const SQObject &name);
-       int GenerateCode();
-       int GetStackSize();
-       int CalcStackFrameSize();
-       void AddLineInfos(int line,bool lineop,bool force=false);
-       void Finalize();
-       int AllocStackPos();
-       int PushTarget(int n=-1);
-       int PopTarget();
-       int TopTarget();
-       int GetUpTarget(int n);
-       bool IsLocal(unsigned int stkpos);
-       SQObject CreateString(const SQChar *s,int len = -1);
-       int _returnexp;
-       SQLocalVarInfoVec _vlocals;
-       SQIntVec _targetstack;
-       int _stacksize;
-       bool _varparams;
-       SQIntVec _unresolvedbreaks;
-       SQIntVec _unresolvedcontinues;
-       SQObjectPtrVec _functions;
-       SQObjectPtrVec _parameters;
-       SQOuterVarVec _outervalues;
-       SQInstructionVec _instructions;
-       SQLocalVarInfoVec _localvarinfos;
-       SQObjectPtr _literals;
-       SQObjectPtr _strings;
-       SQInteger _nliterals;
-       SQLineInfoVec _lineinfos;
-       SQObjectPtr _func;
-       SQFuncState *_parent;
-       SQIntVec _breaktargets; //contains number of nested exception traps
-       SQIntVec _continuetargets;
-       int _lastline;
-       int _traps;
-       bool _optimization;
-       SQSharedState *_sharedstate;
-       sqvector<SQFuncState*> _childstates;
-       int GetConstant(const SQObject &cons);
-private:
-       CompilerErrorFunc _errfunc;
-       void *_errtarget;
-};
-
-
-#endif //_SQFUNCSTATE_H_
-
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQFUNCSTATE_H_\r
+#define _SQFUNCSTATE_H_\r
+///////////////////////////////////\r
+#include "squtils.h"\r
+\r
+struct SQFuncState\r
+{\r
+       SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);\r
+       ~SQFuncState();\r
+#ifdef _DEBUG_DUMP\r
+       void Dump(SQFunctionProto *func);\r
+#endif\r
+       void Error(const SQChar *err);\r
+       SQFuncState *PushChildState(SQSharedState *ss);\r
+       void PopChildState();\r
+       void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}\r
+       void AddInstruction(SQInstruction &i);\r
+       void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);\r
+       void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);\r
+       SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}\r
+       void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}\r
+       void SetStackSize(SQInteger n);\r
+       void SnoozeOpt(){_optimization=false;}\r
+       SQInteger GetCurrentPos(){return _instructions.size()-1;}\r
+       //SQInteger GetStringConstant(const SQChar *cons);\r
+       SQInteger GetNumericConstant(const SQInteger cons);\r
+       SQInteger GetNumericConstant(const SQFloat cons);\r
+       SQInteger PushLocalVariable(const SQObject &name);\r
+       void AddParameter(const SQObject &name);\r
+       void AddOuterValue(const SQObject &name);\r
+       SQInteger GetLocalVariable(const SQObject &name);\r
+       SQInteger GetOuterVariable(const SQObject &name);\r
+       SQInteger GenerateCode();\r
+       SQInteger GetStackSize();\r
+       SQInteger CalcStackFrameSize();\r
+       void AddLineInfos(SQInteger line,bool lineop,bool force=false);\r
+       SQFunctionProto *BuildProto();\r
+       SQInteger AllocStackPos();\r
+       SQInteger PushTarget(SQInteger n=-1);\r
+       SQInteger PopTarget();\r
+       SQInteger TopTarget();\r
+       SQInteger GetUpTarget(SQInteger n);\r
+       bool IsLocal(SQUnsignedInteger stkpos);\r
+       SQObject CreateString(const SQChar *s,SQInteger len = -1);\r
+       SQInteger _returnexp;\r
+       SQLocalVarInfoVec _vlocals;\r
+       SQIntVec _targetstack;\r
+       SQInteger _stacksize;\r
+       bool _varparams;\r
+       bool _bgenerator;\r
+       SQIntVec _unresolvedbreaks;\r
+       SQIntVec _unresolvedcontinues;\r
+       SQObjectPtrVec _functions;\r
+       SQObjectPtrVec _parameters;\r
+       SQOuterVarVec _outervalues;\r
+       SQInstructionVec _instructions;\r
+       SQLocalVarInfoVec _localvarinfos;\r
+       SQObjectPtr _literals;\r
+       SQObjectPtr _strings;\r
+       SQObjectPtr _name;\r
+       SQObjectPtr _sourcename;\r
+       SQInteger _nliterals;\r
+       SQLineInfoVec _lineinfos;\r
+       SQFuncState *_parent;\r
+       SQIntVec _breaktargets; //contains number of nested exception traps\r
+       SQIntVec _continuetargets;\r
+       SQInteger _lastline;\r
+       SQInteger _traps;\r
+       bool _optimization;\r
+       SQSharedState *_sharedstate;\r
+       sqvector<SQFuncState*> _childstates;\r
+       SQInteger GetConstant(const SQObject &cons);\r
+private:\r
+       CompilerErrorFunc _errfunc;\r
+       void *_errtarget;\r
+};\r
+\r
+\r
+#endif //_SQFUNCSTATE_H_\r
+\r
index a0a53f1..93bd577 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include "sqtable.h"
-#include "sqstring.h"
-#include "sqcompiler.h"
-#include "sqlexer.h"
-
-#define CUR_CHAR (_currdata)
-#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
-#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
-#define NEXT() {Next();_currentcolumn++;}
-#define INIT_TEMP_STRING() { _longstr.resize(0);}
-#define APPEND_CHAR(c) { _longstr.push_back(c);}
-#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
-#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
-
-SQLexer::SQLexer(){}
-SQLexer::~SQLexer()
-{
-       _keywords->Release();
-}
-
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
-{
-       _errfunc = efunc;
-       _errtarget = ed;
-       _sharedstate = ss;
-       _keywords = SQTable::Create(ss, 26);
-       ADD_KEYWORD(while, TK_WHILE);
-       ADD_KEYWORD(do, TK_DO);
-       ADD_KEYWORD(if, TK_IF);
-       ADD_KEYWORD(else, TK_ELSE);
-       ADD_KEYWORD(break, TK_BREAK);
-       ADD_KEYWORD(continue, TK_CONTINUE);
-       ADD_KEYWORD(return, TK_RETURN);
-       ADD_KEYWORD(null, TK_NULL);
-       ADD_KEYWORD(function, TK_FUNCTION);
-       ADD_KEYWORD(local, TK_LOCAL);
-       ADD_KEYWORD(for, TK_FOR);
-       ADD_KEYWORD(foreach, TK_FOREACH);
-       ADD_KEYWORD(in, TK_IN);
-       ADD_KEYWORD(typeof, TK_TYPEOF);
-       ADD_KEYWORD(delegate, TK_DELEGATE);
-       ADD_KEYWORD(delete, TK_DELETE);
-       ADD_KEYWORD(try, TK_TRY);
-       ADD_KEYWORD(catch, TK_CATCH);
-       ADD_KEYWORD(throw, TK_THROW);
-       ADD_KEYWORD(clone, TK_CLONE);
-       ADD_KEYWORD(yield, TK_YIELD);
-       ADD_KEYWORD(resume, TK_RESUME);
-       ADD_KEYWORD(switch, TK_SWITCH);
-       ADD_KEYWORD(case, TK_CASE);
-       ADD_KEYWORD(default, TK_DEFAULT);
-       ADD_KEYWORD(this, TK_THIS);
-       ADD_KEYWORD(parent,TK_PARENT);
-       ADD_KEYWORD(class,TK_CLASS);
-       ADD_KEYWORD(extends,TK_EXTENDS);
-       ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
-       ADD_KEYWORD(instanceof,TK_INSTANCEOF);
-       ADD_KEYWORD(vargc,TK_VARGC);
-       ADD_KEYWORD(vargv,TK_VARGV);
-       ADD_KEYWORD(true,TK_TRUE);
-       ADD_KEYWORD(false,TK_FALSE);
-
-       _readf = rg;
-       _up = up;
-       _lasttokenline = _currentline = 1;
-       _currentcolumn = 0;
-       _prevtoken = -1;
-       Next();
-}
-
-void SQLexer::Error(const SQChar *err)
-{
-       _errfunc(_errtarget,err);
-}
-
-void SQLexer::Next()
-{
-       SQInteger t = _readf(_up);
-       if(t > MAX_CHAR) Error(_SC("Invalid character"));
-       if(t != 0) {
-               _currdata = t;
-               return;
-       }
-       _currdata = SQUIRREL_EOB;
-}
-
-const SQChar *SQLexer::Tok2Str(int tok)
-{
-       SQObjectPtr itr, key, val;
-       int nitr;
-       while((nitr = _keywords->Next(itr, key, val)) != -1) {
-               itr = (SQInteger)nitr;
-               if(((int)_integer(val)) == tok)
-                       return _stringval(key);
-       }
-       return NULL;
-}
-
-void SQLexer::LexBlockComment()
-{
-       bool done = false;
-       while(!done) {
-               switch(CUR_CHAR) {
-                       case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
-                       //case _SC('/'): { NEXT(); if(CUR_CHAR == _SC('*')) { nest++; NEXT(); }}; continue;
-                       case _SC('\n'): _currentline++; NEXT(); continue;
-                       case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
-                       default: NEXT();
-               }
-       }
-}
-
-int SQLexer::Lex()
-{
-       _lasttokenline = _currentline;
-       while(CUR_CHAR != SQUIRREL_EOB) {
-               switch(CUR_CHAR){
-               case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
-               case _SC('\n'):
-                       _currentline++;
-                       _prevtoken=_curtoken;
-                       _curtoken=_SC('\n');
-                       NEXT();
-                       _currentcolumn=1;
-                       continue;
-               case _SC('/'):
-                       NEXT();
-                       switch(CUR_CHAR){
-                       case _SC('*'):
-                               NEXT();
-                               LexBlockComment();
-                               continue;       
-                       case _SC('/'):
-                               do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
-                               continue;
-                       case _SC('='):
-                               NEXT();
-                               RETURN_TOKEN(TK_DIVEQ);
-                               continue;
-                       case _SC('>'):
-                               NEXT();
-                               RETURN_TOKEN(TK_ATTR_CLOSE);
-                               continue;
-                       default:
-                               RETURN_TOKEN('/');
-                       }
-               case _SC('='):
-                       NEXT();
-                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
-                       else { NEXT(); RETURN_TOKEN(TK_EQ); }
-               case _SC('<'):
-                       NEXT();
-                       if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }
-                       else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }
-                       else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }
-                       else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }
-                       //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }
-                       else { RETURN_TOKEN('<') }
-               case _SC('>'):
-                       NEXT();
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
-                       else if(CUR_CHAR == _SC('>')){ 
-                               NEXT(); 
-                               if(CUR_CHAR == _SC('>')){
-                                       NEXT();
-                                       RETURN_TOKEN(TK_USHIFTR);
-                               }
-                               RETURN_TOKEN(TK_SHIFTR);
-                       }
-                       else { RETURN_TOKEN('>') }
-               case _SC('!'):
-                       NEXT();
-                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
-                       else { NEXT(); RETURN_TOKEN(TK_NE); }
-               case _SC('@'): {
-                       int stype;
-                       NEXT(); 
-                       if(CUR_CHAR != _SC('"'))
-                               Error(_SC("string expected"));
-                       if((stype=ReadString('"',true))!=-1) {
-                               RETURN_TOKEN(stype);
-                       }
-                       Error(_SC("error parsing the string"));
-                                          }
-               case _SC('"'):
-               case _SC('\''): {
-                       int stype;
-                       if((stype=ReadString(CUR_CHAR,false))!=-1){
-                               RETURN_TOKEN(stype);
-                       }
-                       Error(_SC("error parsing the string"));
-                       }
-               case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
-               case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
-                       {int ret = CUR_CHAR;
-                       NEXT(); RETURN_TOKEN(ret); }
-               case _SC('.'):
-                       NEXT();
-                       if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
-                       NEXT();
-                       if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
-                       NEXT();
-                       RETURN_TOKEN(TK_VARPARAMS);
-               case _SC('&'):
-                       NEXT();
-                       if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
-                       else { NEXT(); RETURN_TOKEN(TK_AND); }
-               case _SC('|'):
-                       NEXT();
-                       if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
-                       else { NEXT(); RETURN_TOKEN(TK_OR); }
-               case _SC(':'):
-                       NEXT();
-                       if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
-                       else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
-               case _SC('*'):
-                       NEXT();
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
-                       else RETURN_TOKEN('*');
-               case _SC('%'):
-                       NEXT();
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
-                       else RETURN_TOKEN('%');
-               case _SC('-'):
-                       NEXT();
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
-                       else if  (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
-                       else RETURN_TOKEN('-');
-               case _SC('+'):
-                       NEXT();
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
-                       else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
-                       else RETURN_TOKEN('+');
-               case SQUIRREL_EOB:
-                       return 0;
-               default:{
-                               if (scisdigit(CUR_CHAR)) {
-                                       int ret = ReadNumber();
-                                       RETURN_TOKEN(ret);
-                               }
-                               else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
-                                       int t = ReadID();
-                                       RETURN_TOKEN(t);
-                               }
-                               else {
-                                       int c = CUR_CHAR;
-                                       if (sciscntrl(c)) Error(_SC("unexpected character(control)"));
-                                       NEXT();
-                                       RETURN_TOKEN(c);  
-                               }
-                               RETURN_TOKEN(0);
-                       }
-               }
-       }
-       return 0;    
-}
-       
-int SQLexer::GetIDType(SQChar *s)
-{
-       SQObjectPtr t;
-       if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
-               return int(_integer(t));
-       }
-       return TK_IDENTIFIER;
-}
-
-
-int SQLexer::ReadString(int ndelim,bool verbatim)
-{
-       INIT_TEMP_STRING();
-       NEXT();
-       if(IS_EOB()) return -1;
-       for(;;) {
-               while(CUR_CHAR != ndelim) {
-                       switch(CUR_CHAR) {
-                       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(); 
-                               break;
-                       case _SC('\\'):
-                               if(verbatim) {
-                                       APPEND_CHAR('\\'); NEXT(); 
-                               }
-                               else {
-                                       NEXT();
-                                       switch(CUR_CHAR) {
-                                       case _SC('x'): NEXT(); {
-                                               if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); 
-                                               const int maxdigits = 4;
-                                               SQChar temp[maxdigits+1];
-                                               int n = 0;
-                                               while(isxdigit(CUR_CHAR) && n < maxdigits) {
-                                                       temp[n] = CUR_CHAR;
-                                                       n++;
-                                                       NEXT();
-                                               }
-                                               temp[n] = 0;
-                                               SQChar *sTemp;
-                                               APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
-                                       }
-                                   break;
-                                       case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
-                                       case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
-                                       case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
-                                       case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
-                                       case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
-                                       case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
-                                       case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
-                                       case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
-                                       case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
-                                       case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
-                                       case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
-                                       default:
-                                               Error(_SC("unrecognised escaper char"));
-                                       break;
-                                       }
-                               }
-                               break;
-                       default:
-                               APPEND_CHAR(CUR_CHAR);
-                               NEXT();
-                       }
-               }
-               NEXT();
-               if(verbatim && CUR_CHAR == '"') { //double quotation
-                       APPEND_CHAR(CUR_CHAR);
-                       NEXT();
-               }
-               else {
-                       break;
-               }
-       }
-       TERMINATE_BUFFER();
-       int len = _longstr.size()-1;
-       if(ndelim == _SC('\'')) {
-               if(len == 0) Error(_SC("empty constant"));
-               if(len > 1) Error(_SC("constant too long"));
-               _nvalue = _longstr[0];
-               return TK_INTEGER;
-       }
-       _svalue = &_longstr[0];
-       return TK_STRING_LITERAL;
-}
-
-int isexponent(int c) { return c == 'e' || c=='E'; }
-
-int SQLexer::ReadNumber()
-{
-#define TINT 1
-#define TFLOAT 2
-#define THEX 3
-#define TSCIENTIFIC 4
-       int type = TINT, firstchar = CUR_CHAR;
-       bool isfloat = false;
-       SQChar *sTemp;
-       INIT_TEMP_STRING();
-       NEXT();
-       if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) {
-               NEXT();
-               type = THEX;
-               while(isxdigit(CUR_CHAR)) {
-                       APPEND_CHAR(CUR_CHAR);
-                       NEXT();
-               }
-               if(_longstr.size() > 8) Error(_SC("Hex number over 8 digits"));
-       }
-       else {
-               APPEND_CHAR(firstchar);
-               while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
-            if(CUR_CHAR == _SC('.')) type = TFLOAT;
-                       if(isexponent(CUR_CHAR)) {
-                               if(type != TFLOAT) Error(_SC("invalid numeric format"));
-                               type = TSCIENTIFIC;
-                               APPEND_CHAR(CUR_CHAR);
-                               NEXT();
-                               if(CUR_CHAR == '+' || CUR_CHAR == '-'){
-                                       APPEND_CHAR(CUR_CHAR);
-                                       NEXT();
-                               }
-                               if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
-                       }
-                       
-                       APPEND_CHAR(CUR_CHAR);
-                       NEXT();
-               }
-       }
-       TERMINATE_BUFFER();
-       switch(type) {
-       case TSCIENTIFIC:
-       case TFLOAT:
-               _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
-               return TK_FLOAT;
-       case TINT:
-               _nvalue = (SQInteger)scatoi(&_longstr[0]);
-               return TK_INTEGER;
-       case THEX:
-               *((unsigned long *)&_nvalue) = scstrtoul(&_longstr[0],&sTemp,16);
-               return TK_INTEGER;
-       }
-       return 0;
-}
-
-int SQLexer::ReadID()
-{
-       int res, size = 0;
-       INIT_TEMP_STRING();
-       do {
-               APPEND_CHAR(CUR_CHAR);
-               NEXT();
-       } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
-       TERMINATE_BUFFER();
-       res = GetIDType(&_longstr[0]);
-       if(res == TK_IDENTIFIER) {
-               _svalue = &_longstr[0];
-       }
-       return res;
-}
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include <ctype.h>\r
+#include <stdlib.h>\r
+#include "sqtable.h"\r
+#include "sqstring.h"\r
+#include "sqcompiler.h"\r
+#include "sqlexer.h"\r
+\r
+#define CUR_CHAR (_currdata)\r
+#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}\r
+#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)\r
+#define NEXT() {Next();_currentcolumn++;}\r
+#define INIT_TEMP_STRING() { _longstr.resize(0);}\r
+#define APPEND_CHAR(c) { _longstr.push_back(c);}\r
+#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}\r
+#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))\r
+\r
+SQLexer::SQLexer(){}\r
+SQLexer::~SQLexer()\r
+{\r
+       _keywords->Release();\r
+}\r
+\r
+void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)\r
+{\r
+       _errfunc = efunc;\r
+       _errtarget = ed;\r
+       _sharedstate = ss;\r
+       _keywords = SQTable::Create(ss, 26);\r
+       ADD_KEYWORD(while, TK_WHILE);\r
+       ADD_KEYWORD(do, TK_DO);\r
+       ADD_KEYWORD(if, TK_IF);\r
+       ADD_KEYWORD(else, TK_ELSE);\r
+       ADD_KEYWORD(break, TK_BREAK);\r
+       ADD_KEYWORD(continue, TK_CONTINUE);\r
+       ADD_KEYWORD(return, TK_RETURN);\r
+       ADD_KEYWORD(null, TK_NULL);\r
+       ADD_KEYWORD(function, TK_FUNCTION);\r
+       ADD_KEYWORD(local, TK_LOCAL);\r
+       ADD_KEYWORD(for, TK_FOR);\r
+       ADD_KEYWORD(foreach, TK_FOREACH);\r
+       ADD_KEYWORD(in, TK_IN);\r
+       ADD_KEYWORD(typeof, TK_TYPEOF);\r
+       ADD_KEYWORD(delegate, TK_DELEGATE);\r
+       ADD_KEYWORD(delete, TK_DELETE);\r
+       ADD_KEYWORD(try, TK_TRY);\r
+       ADD_KEYWORD(catch, TK_CATCH);\r
+       ADD_KEYWORD(throw, TK_THROW);\r
+       ADD_KEYWORD(clone, TK_CLONE);\r
+       ADD_KEYWORD(yield, TK_YIELD);\r
+       ADD_KEYWORD(resume, TK_RESUME);\r
+       ADD_KEYWORD(switch, TK_SWITCH);\r
+       ADD_KEYWORD(case, TK_CASE);\r
+       ADD_KEYWORD(default, TK_DEFAULT);\r
+       ADD_KEYWORD(this, TK_THIS);\r
+       ADD_KEYWORD(parent,TK_PARENT);\r
+       ADD_KEYWORD(class,TK_CLASS);\r
+       ADD_KEYWORD(extends,TK_EXTENDS);\r
+       ADD_KEYWORD(constructor,TK_CONSTRUCTOR);\r
+       ADD_KEYWORD(instanceof,TK_INSTANCEOF);\r
+       ADD_KEYWORD(vargc,TK_VARGC);\r
+       ADD_KEYWORD(vargv,TK_VARGV);\r
+       ADD_KEYWORD(true,TK_TRUE);\r
+       ADD_KEYWORD(false,TK_FALSE);\r
+\r
+       _readf = rg;\r
+       _up = up;\r
+       _lasttokenline = _currentline = 1;\r
+       _currentcolumn = 0;\r
+       _prevtoken = -1;\r
+       Next();\r
+}\r
+\r
+void SQLexer::Error(const SQChar *err)\r
+{\r
+       _errfunc(_errtarget,err);\r
+}\r
+\r
+void SQLexer::Next()\r
+{\r
+       SQInteger t = _readf(_up);\r
+       if(t > MAX_CHAR) Error(_SC("Invalid character"));\r
+       if(t != 0) {\r
+               _currdata = t;\r
+               return;\r
+       }\r
+       _currdata = SQUIRREL_EOB;\r
+}\r
+\r
+const SQChar *SQLexer::Tok2Str(SQInteger tok)\r
+{\r
+       SQObjectPtr itr, key, val;\r
+       SQInteger nitr;\r
+       while((nitr = _keywords->Next(false,itr, key, val)) != -1) {\r
+               itr = (SQInteger)nitr;\r
+               if(((SQInteger)_integer(val)) == tok)\r
+                       return _stringval(key);\r
+       }\r
+       return NULL;\r
+}\r
+\r
+void SQLexer::LexBlockComment()\r
+{\r
+       bool done = false;\r
+       while(!done) {\r
+               switch(CUR_CHAR) {\r
+                       case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;\r
+                       case _SC('\n'): _currentline++; NEXT(); continue;\r
+                       case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));\r
+                       default: NEXT();\r
+               }\r
+       }\r
+}\r
+\r
+SQInteger SQLexer::Lex()\r
+{\r
+       _lasttokenline = _currentline;\r
+       while(CUR_CHAR != SQUIRREL_EOB) {\r
+               switch(CUR_CHAR){\r
+               case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;\r
+               case _SC('\n'):\r
+                       _currentline++;\r
+                       _prevtoken=_curtoken;\r
+                       _curtoken=_SC('\n');\r
+                       NEXT();\r
+                       _currentcolumn=1;\r
+                       continue;\r
+               case _SC('/'):\r
+                       NEXT();\r
+                       switch(CUR_CHAR){\r
+                       case _SC('*'):\r
+                               NEXT();\r
+                               LexBlockComment();\r
+                               continue;       \r
+                       case _SC('/'):\r
+                               do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));\r
+                               continue;\r
+                       case _SC('='):\r
+                               NEXT();\r
+                               RETURN_TOKEN(TK_DIVEQ);\r
+                               continue;\r
+                       case _SC('>'):\r
+                               NEXT();\r
+                               RETURN_TOKEN(TK_ATTR_CLOSE);\r
+                               continue;\r
+                       default:\r
+                               RETURN_TOKEN('/');\r
+                       }\r
+               case _SC('='):\r
+                       NEXT();\r
+                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }\r
+                       else { NEXT(); RETURN_TOKEN(TK_EQ); }\r
+               case _SC('<'):\r
+                       NEXT();\r
+                       if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }\r
+                       else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }\r
+                       else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }\r
+                       else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }\r
+                       //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }\r
+                       else { RETURN_TOKEN('<') }\r
+               case _SC('>'):\r
+                       NEXT();\r
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}\r
+                       else if(CUR_CHAR == _SC('>')){ \r
+                               NEXT(); \r
+                               if(CUR_CHAR == _SC('>')){\r
+                                       NEXT();\r
+                                       RETURN_TOKEN(TK_USHIFTR);\r
+                               }\r
+                               RETURN_TOKEN(TK_SHIFTR);\r
+                       }\r
+                       else { RETURN_TOKEN('>') }\r
+               case _SC('!'):\r
+                       NEXT();\r
+                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}\r
+                       else { NEXT(); RETURN_TOKEN(TK_NE); }\r
+               case _SC('@'): {\r
+                       SQInteger stype;\r
+                       NEXT(); \r
+                       if(CUR_CHAR != _SC('"'))\r
+                               Error(_SC("string expected"));\r
+                       if((stype=ReadString('"',true))!=-1) {\r
+                               RETURN_TOKEN(stype);\r
+                       }\r
+                       Error(_SC("error parsing the string"));\r
+                                          }\r
+               case _SC('"'):\r
+               case _SC('\''): {\r
+                       SQInteger stype;\r
+                       if((stype=ReadString(CUR_CHAR,false))!=-1){\r
+                               RETURN_TOKEN(stype);\r
+                       }\r
+                       Error(_SC("error parsing the string"));\r
+                       }\r
+               case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):\r
+               case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):\r
+                       {SQInteger ret = CUR_CHAR;\r
+                       NEXT(); RETURN_TOKEN(ret); }\r
+               case _SC('.'):\r
+                       NEXT();\r
+                       if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }\r
+                       NEXT();\r
+                       if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }\r
+                       NEXT();\r
+                       RETURN_TOKEN(TK_VARPARAMS);\r
+               case _SC('&'):\r
+                       NEXT();\r
+                       if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }\r
+                       else { NEXT(); RETURN_TOKEN(TK_AND); }\r
+               case _SC('|'):\r
+                       NEXT();\r
+                       if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }\r
+                       else { NEXT(); RETURN_TOKEN(TK_OR); }\r
+               case _SC(':'):\r
+                       NEXT();\r
+                       if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }\r
+                       else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }\r
+               case _SC('*'):\r
+                       NEXT();\r
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}\r
+                       else RETURN_TOKEN('*');\r
+               case _SC('%'):\r
+                       NEXT();\r
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}\r
+                       else RETURN_TOKEN('%');\r
+               case _SC('-'):\r
+                       NEXT();\r
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}\r
+                       else if  (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}\r
+                       else RETURN_TOKEN('-');\r
+               case _SC('+'):\r
+                       NEXT();\r
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}\r
+                       else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}\r
+                       else RETURN_TOKEN('+');\r
+               case SQUIRREL_EOB:\r
+                       return 0;\r
+               default:{\r
+                               if (scisdigit(CUR_CHAR)) {\r
+                                       SQInteger ret = ReadNumber();\r
+                                       RETURN_TOKEN(ret);\r
+                               }\r
+                               else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {\r
+                                       SQInteger t = ReadID();\r
+                                       RETURN_TOKEN(t);\r
+                               }\r
+                               else {\r
+                                       SQInteger c = CUR_CHAR;\r
+                                       if (sciscntrl(c)) Error(_SC("unexpected character(control)"));\r
+                                       NEXT();\r
+                                       RETURN_TOKEN(c);  \r
+                               }\r
+                               RETURN_TOKEN(0);\r
+                       }\r
+               }\r
+       }\r
+       return 0;    \r
+}\r
+       \r
+SQInteger SQLexer::GetIDType(SQChar *s)\r
+{\r
+       SQObjectPtr t;\r
+       if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {\r
+               return SQInteger(_integer(t));\r
+       }\r
+       return TK_IDENTIFIER;\r
+}\r
+\r
+\r
+SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)\r
+{\r
+       INIT_TEMP_STRING();\r
+       NEXT();\r
+       if(IS_EOB()) return -1;\r
+       for(;;) {\r
+               while(CUR_CHAR != ndelim) {\r
+                       switch(CUR_CHAR) {\r
+                       case SQUIRREL_EOB:\r
+                               Error(_SC("unfinished string"));\r
+                               return -1;\r
+                       case _SC('\n'): \r
+                               if(!verbatim) Error(_SC("newline in a constant")); \r
+                               APPEND_CHAR(CUR_CHAR); NEXT(); \r
+                               _currentline++;\r
+                               break;\r
+                       case _SC('\\'):\r
+                               if(verbatim) {\r
+                                       APPEND_CHAR('\\'); NEXT(); \r
+                               }\r
+                               else {\r
+                                       NEXT();\r
+                                       switch(CUR_CHAR) {\r
+                                       case _SC('x'): NEXT(); {\r
+                                               if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); \r
+                                               const SQInteger maxdigits = 4;\r
+                                               SQChar temp[maxdigits+1];\r
+                                               SQInteger n = 0;\r
+                                               while(isxdigit(CUR_CHAR) && n < maxdigits) {\r
+                                                       temp[n] = CUR_CHAR;\r
+                                                       n++;\r
+                                                       NEXT();\r
+                                               }\r
+                                               temp[n] = 0;\r
+                                               SQChar *sTemp;\r
+                                               APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));\r
+                                       }\r
+                                   break;\r
+                                       case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;\r
+                                       case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;\r
+                                       case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;\r
+                                       case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;\r
+                                       case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;\r
+                                       case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;\r
+                                       case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;\r
+                                       case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;\r
+                                       case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;\r
+                                       case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;\r
+                                       case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;\r
+                                       default:\r
+                                               Error(_SC("unrecognised escaper char"));\r
+                                       break;\r
+                                       }\r
+                               }\r
+                               break;\r
+                       default:\r
+                               APPEND_CHAR(CUR_CHAR);\r
+                               NEXT();\r
+                       }\r
+               }\r
+               NEXT();\r
+               if(verbatim && CUR_CHAR == '"') { //double quotation\r
+                       APPEND_CHAR(CUR_CHAR);\r
+                       NEXT();\r
+               }\r
+               else {\r
+                       break;\r
+               }\r
+       }\r
+       TERMINATE_BUFFER();\r
+       SQInteger len = _longstr.size()-1;\r
+       if(ndelim == _SC('\'')) {\r
+               if(len == 0) Error(_SC("empty constant"));\r
+               if(len > 1) Error(_SC("constant too long"));\r
+               _nvalue = _longstr[0];\r
+               return TK_INTEGER;\r
+       }\r
+       _svalue = &_longstr[0];\r
+       return TK_STRING_LITERAL;\r
+}\r
+\r
+SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }\r
+\r
+SQInteger SQLexer::ReadNumber()\r
+{\r
+#define TINT 1\r
+#define TFLOAT 2\r
+#define THEX 3\r
+#define TSCIENTIFIC 4\r
+       SQInteger type = TINT, firstchar = CUR_CHAR;\r
+       bool isfloat = false;\r
+       SQChar *sTemp;\r
+       INIT_TEMP_STRING();\r
+       NEXT();\r
+       if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) {\r
+               NEXT();\r
+               type = THEX;\r
+               while(isxdigit(CUR_CHAR)) {\r
+                       APPEND_CHAR(CUR_CHAR);\r
+                       NEXT();\r
+               }\r
+               if(_longstr.size() > 8) Error(_SC("Hex number over 8 digits"));\r
+       }\r
+       else {\r
+               APPEND_CHAR(firstchar);\r
+               while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {\r
+            if(CUR_CHAR == _SC('.')) type = TFLOAT;\r
+                       if(isexponent(CUR_CHAR)) {\r
+                               if(type != TFLOAT) Error(_SC("invalid numeric format"));\r
+                               type = TSCIENTIFIC;\r
+                               APPEND_CHAR(CUR_CHAR);\r
+                               NEXT();\r
+                               if(CUR_CHAR == '+' || CUR_CHAR == '-'){\r
+                                       APPEND_CHAR(CUR_CHAR);\r
+                                       NEXT();\r
+                               }\r
+                               if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));\r
+                       }\r
+                       \r
+                       APPEND_CHAR(CUR_CHAR);\r
+                       NEXT();\r
+               }\r
+       }\r
+       TERMINATE_BUFFER();\r
+       switch(type) {\r
+       case TSCIENTIFIC:\r
+       case TFLOAT:\r
+               _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);\r
+               return TK_FLOAT;\r
+       case TINT:\r
+               _nvalue = (SQInteger)scstrtol(&_longstr[0],&sTemp,10);\r
+               return TK_INTEGER;\r
+       case THEX:\r
+               *((SQUnsignedInteger *)&_nvalue) = scstrtoul(&_longstr[0],&sTemp,16);\r
+               return TK_INTEGER;\r
+       }\r
+       return 0;\r
+}\r
+\r
+SQInteger SQLexer::ReadID()\r
+{\r
+       SQInteger res, size = 0;\r
+       INIT_TEMP_STRING();\r
+       do {\r
+               APPEND_CHAR(CUR_CHAR);\r
+               NEXT();\r
+       } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));\r
+       TERMINATE_BUFFER();\r
+       res = GetIDType(&_longstr[0]);\r
+       if(res == TK_IDENTIFIER) {\r
+               _svalue = &_longstr[0];\r
+       }\r
+       return res;\r
+}\r
index 9182420..750bbd0 100644 (file)
@@ -1,47 +1,47 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQLEXER_H_
-#define _SQLEXER_H_
-
-#define MAX_STRING 2024
-
-
-
-struct SQLexer
-{
-       SQLexer();
-       ~SQLexer();
-       void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
-       void Error(const SQChar *err);
-       int Lex();
-       const SQChar *Tok2Str(int tok);
-private:
-       int GetIDType(SQChar *s);
-       int ReadString(int ndelim,bool verbatim);
-       int ReadNumber();
-       void LexBlockComment();
-       int ReadID();
-       void Next();
-       int _curtoken;
-       SQTable *_keywords;
-public:
-       int _prevtoken;
-       int _currentline;
-       int _lasttokenline;
-       int _currentcolumn;
-       const SQChar *_svalue;
-       SQInteger _nvalue;
-       SQFloat _fvalue;
-       SQLEXREADFUNC _readf;
-       SQUserPointer _up;
-#ifdef _UNICODE
-       SQChar _currdata;
-#else
-       unsigned char _currdata;
-#endif
-       SQSharedState *_sharedstate;
-       sqvector<SQChar> _longstr;
-       CompilerErrorFunc _errfunc;
-       void *_errtarget;
-};
-
-#endif
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQLEXER_H_\r
+#define _SQLEXER_H_\r
+\r
+#define MAX_STRING 2024\r
+\r
+\r
+\r
+struct SQLexer\r
+{\r
+       SQLexer();\r
+       ~SQLexer();\r
+       void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);\r
+       void Error(const SQChar *err);\r
+       SQInteger Lex();\r
+       const SQChar *Tok2Str(SQInteger tok);\r
+private:\r
+       SQInteger GetIDType(SQChar *s);\r
+       SQInteger ReadString(SQInteger ndelim,bool verbatim);\r
+       SQInteger ReadNumber();\r
+       void LexBlockComment();\r
+       SQInteger ReadID();\r
+       void Next();\r
+       SQInteger _curtoken;\r
+       SQTable *_keywords;\r
+public:\r
+       SQInteger _prevtoken;\r
+       SQInteger _currentline;\r
+       SQInteger _lasttokenline;\r
+       SQInteger _currentcolumn;\r
+       const SQChar *_svalue;\r
+       SQInteger _nvalue;\r
+       SQFloat _fvalue;\r
+       SQLEXREADFUNC _readf;\r
+       SQUserPointer _up;\r
+#ifdef _UNICODE\r
+       SQChar _currdata;\r
+#else\r
+       unsigned char _currdata;\r
+#endif\r
+       SQSharedState *_sharedstate;\r
+       sqvector<SQChar> _longstr;\r
+       CompilerErrorFunc _errfunc;\r
+       void *_errtarget;\r
+};\r
+\r
+#endif\r
index b955a29..520f7eb 100644 (file)
@@ -1,9 +1,9 @@
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-void *sq_vm_malloc(unsigned int size){ return malloc(size); }
-
-void *sq_vm_realloc(void *p, unsigned int oldsize, unsigned int size){ return realloc(p, size); }
-
-void sq_vm_free(void *p, unsigned int size){   free(p); }
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+void *sq_vm_malloc(SQUnsignedInteger size){    return malloc(size); }\r
+\r
+void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }\r
+\r
+void sq_vm_free(void *p, SQUnsignedInteger size){      free(p); }\r
index 209c1e5..92499c2 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqarray.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqfuncproto.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-SQString *SQString::Create(SQSharedState *ss,const SQChar *s,int len)
-{
-       SQString *str=ADD_STRING(ss,s,len);
-       str->_sharedstate=ss;
-       return str;
-}
-
-void SQString::Release()
-{
-       REMOVE_STRING(_sharedstate,this);
-}
-
-unsigned int TranslateIndex(const SQObjectPtr &idx)
-{
-       switch(type(idx)){
-               case OT_NULL:
-                       return 0;
-               case OT_INTEGER:
-                       return (unsigned int)_integer(idx);
-       }
-       assert(0);
-       return 0;
-}
-
-bool SQDelegable::GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res) {
-       if(_delegate) {
-               return _delegate->Get((*_ss(this)->_metamethods)[mm],res);
-       }
-       return false;
-}
-
-bool SQGenerator::Yield(SQVM *v)
-{
-       if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator"));  return false;}
-       if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
-       int size = v->_top-v->_stackbase;
-       _ci=*v->ci;
-       _stack.resize(size);
-       for(int n =0; n<size; n++) {
-               _stack._vals[n] = v->_stack[v->_stackbase+n];
-               v->_stack[v->_stackbase+n] = _null_;
-       }
-       int nvargs = v->ci->_vargs.size;
-       int vargsbase = v->ci->_vargs.base;
-       for(int j = nvargs - 1; j >= 0; j--) {
-               _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
-       }
-       _ci._generator=_null_;
-       for(int i=0;i<_ci._etraps;i++) {
-               _etraps.push_back(v->_etraps.top());
-               v->_etraps.pop_back();
-       }
-       _state=eSuspended;
-       return true;
-}
-
-bool SQGenerator::Resume(SQVM *v,int target)
-{
-       int size=_stack.size();
-       if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
-       if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
-       int prevtop=v->_top-v->_stackbase;
-       PUSH_CALLINFO(v,_ci);
-       int oldstackbase=v->_stackbase;
-       v->_stackbase=v->_top;
-       v->ci->_target=target;
-       v->ci->_generator=SQObjectPtr(this);
-       v->ci->_vargs.size = _vargsstack.size();
-       
-       for(int i=0;i<_ci._etraps;i++) {
-               v->_etraps.push_back(_etraps.top());
-               _etraps.pop_back();
-       }
-       for(int n =0; n<size; n++) {
-               v->_stack[v->_stackbase+n] = _stack._vals[n];
-               _stack._vals[0] = _null_;
-       }
-       while(_vargsstack.size()) {
-               v->_vargsstack.push_back(_vargsstack.back());
-               _vargsstack.pop_back();
-       }
-       v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size;
-       v->_top=v->_stackbase+size;
-       v->ci->_prevtop=prevtop;
-       v->ci->_prevstkbase=v->_stackbase-oldstackbase;
-       _state=eRunning;
-       return true;
-}
-
-void SQArray::Extend(const SQArray *a){
-       int xlen;
-       if((xlen=a->Size()))
-               for(int i=0;i<xlen;i++)
-                       Append(a->_values[i]);
-}
-
-const SQChar* SQFunctionProto::GetLocal(SQVM *vm,unsigned int stackbase,unsigned int nseq,unsigned int nop)
-{
-       unsigned int nvars=_localvarinfos.size();
-       const SQChar *res=NULL; 
-       if(nvars>=nseq){
-               for(unsigned int i=0;i<nvars;i++){
-                       if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
-                       {
-                               if(nseq==0){
-                                       vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
-                                       res=_stringval(_localvarinfos[i]._name);
-                                       break;
-                               }
-                               nseq--;
-                       }
-               }
-       }
-       return res;
-}
-
-int SQFunctionProto::GetLine(SQInstruction *curr)
-{
-       int op=(curr-_instructions._vals);
-       int line=_lineinfos[0]._line;
-       for(unsigned int i=1;i<_lineinfos.size();i++){
-               if(_lineinfos[i]._op>=op)
-                       return line;
-               line=_lineinfos[i]._line;
-       }
-       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,int size)
-{
-       if(write(up,dest,size) != size) {
-               v->Raise_Error(_SC("io error (write function failure)"));
-               return false;
-       }
-       return true;
-}
-
-bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,int size)
-{
-       if(size && read(up,dest,size) != size) {
-               v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
-               return false;
-       }
-       return true;
-}
-
-bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,int tag)
-{
-       return SafeWrite(v,write,up,&tag,sizeof(tag));
-}
-
-bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,int tag)
-{
-       int t;
-       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
-       if(t != tag){
-               v->Raise_Error(_SC("invalid or corrupted closure stream"));
-               return false;
-       }
-       return true;
-}
-
-bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
-{
-       _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
-       switch(type(o)){
-       case OT_STRING:
-               _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
-               _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
-               break;
-       case OT_INTEGER:
-               _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
-       case OT_FLOAT:
-               _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
-       case OT_NULL:
-               break;
-       default:
-               v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
-               return false;
-       }
-       return true;
-}
-
-bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
-{
-       SQObjectType t;
-       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
-       switch(t){
-       case OT_STRING:{
-               int len;
-               _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
-               _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
-               o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
-                                  }
-               break;
-       case OT_INTEGER:{
-               SQInteger i;
-               _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
-                                       }
-       case OT_FLOAT:{
-               SQFloat f;
-               _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
-                                 }
-       case OT_NULL:
-               o=_null_;
-               break;
-       default:
-               v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
-               return false;
-       }
-       return true;
-}
-
-bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
-       _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
-       _CHECK_IO(_funcproto(_function)->Save(v,up,write));
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
-       return true;
-}
-
-bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
-{
-       _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));
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
-       return true;
-}
-
-bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
-       int i,nsize=_literals.size();
-       _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(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++){
-               _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++){
-               _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(unsigned int)));
-               _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++){
-               SQLocalVarInfo &lvi=_localvarinfos[i];
-               _CHECK_IO(WriteObject(v,up,write,lvi._name));
-               _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(unsigned int)));
-               _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(unsigned int)));
-               _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(unsigned int)));
-       }
-       _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(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(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++){
-               _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
-       }
-       _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
-       _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
-       _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
-       return true;
-}
-
-bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
-{
-       int i, nsize = _literals.size();
-       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(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
-       for(i = 0;i < nsize; i++){
-               _CHECK_IO(ReadObject(v, up, read, o));
-               _literals.push_back(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++){
-               _CHECK_IO(ReadObject(v, up, read, o));
-               _parameters.push_back(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++){
-               unsigned int type;
-               SQObjectPtr name;
-               _CHECK_IO(SafeRead(v,read,up, &type, sizeof(unsigned int)));
-               _CHECK_IO(ReadObject(v, up, read, o));
-               _CHECK_IO(ReadObject(v, up, read, name));
-               _outervalues.push_back(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++){
-               SQLocalVarInfo lvi;
-               _CHECK_IO(ReadObject(v, up, read, lvi._name));
-               _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(unsigned int)));
-               _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(unsigned int)));
-               _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(unsigned int)));
-               _localvarinfos.push_back(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(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(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);
-       }
-       _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)));
-       return true;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-#define START_MARK()   if(!(_uiRef&MARK_FLAG)){ \
-               _uiRef|=MARK_FLAG;
-
-#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
-               AddToChain(chain, this); }
-
-void SQVM::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               SQSharedState::MarkObject(_lasterror,chain);
-               SQSharedState::MarkObject(_errorhandler,chain);
-               SQSharedState::MarkObject(_debughook,chain);
-               SQSharedState::MarkObject(_roottable, chain);
-               SQSharedState::MarkObject(temp_reg, chain);
-               for(unsigned int i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
-               for(unsigned int j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
-       END_MARK()
-}
-
-void SQArray::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               int len = _values.size();
-               for(int i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
-       END_MARK()
-}
-void SQTable::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               if(_delegate) _delegate->Mark(chain);
-               int len = _numofnodes;
-               for(int i = 0; i < len; i++){
-                       SQSharedState::MarkObject(_nodes[i].key, chain);
-                       SQSharedState::MarkObject(_nodes[i].val, chain);
-               }
-       END_MARK()
-}
-
-void SQClass::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               _members->Mark(chain);
-               if(_base) _base->Mark(chain);
-               SQSharedState::MarkObject(_attributes, chain);
-               for(unsigned int i =0; i< _defaultvalues.size(); i++) {
-                       SQSharedState::MarkObject(_defaultvalues[i].val, chain);
-                       SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
-               }
-               for(unsigned int j =0; j< _methods.size(); j++) {
-                       SQSharedState::MarkObject(_methods[j].val, chain);
-                       SQSharedState::MarkObject(_methods[j].attrs, chain);
-               }
-               for(unsigned int k =0; k< _metamethods.size(); k++) {
-                       SQSharedState::MarkObject(_metamethods[k], chain);
-               }
-       END_MARK()
-}
-
-void SQInstance::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               _class->Mark(chain);
-               for(unsigned int i =0; i< _values.size(); i++) {
-                       SQSharedState::MarkObject(_values[i], chain);
-               }
-       END_MARK()
-}
-
-void SQGenerator::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               for(unsigned int i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
-               for(unsigned int j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
-               SQSharedState::MarkObject(_closure, chain);
-       END_MARK()
-}
-
-void SQClosure::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               for(unsigned int i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
-       END_MARK()
-}
-
-void SQNativeClosure::Mark(SQCollectable **chain)
-{
-       START_MARK()
-               for(unsigned int i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
-       END_MARK()
-}
-
-void SQUserData::Mark(SQCollectable **chain){
-       START_MARK()
-               if(_delegate) _delegate->Mark(chain);
-       END_MARK()
-}
-
-void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
-
-#endif
-
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include "sqvm.h"\r
+#include "sqstring.h"\r
+#include "sqarray.h"\r
+#include "sqtable.h"\r
+#include "squserdata.h"\r
+#include "sqfuncproto.h"\r
+#include "sqclass.h"\r
+#include "sqclosure.h"\r
+\r
+SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)\r
+{\r
+       SQString *str=ADD_STRING(ss,s,len);\r
+       str->_sharedstate=ss;\r
+       return str;\r
+}\r
+\r
+void SQString::Release()\r
+{\r
+       REMOVE_STRING(_sharedstate,this);\r
+}\r
+\r
+SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)\r
+{\r
+       switch(type(idx)){\r
+               case OT_NULL:\r
+                       return 0;\r
+               case OT_INTEGER:\r
+                       return (SQUnsignedInteger)_integer(idx);\r
+       }\r
+       assert(0);\r
+       return 0;\r
+}\r
+\r
+SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)\r
+{\r
+       if(!_weakref) {\r
+               sq_new(_weakref,SQWeakRef);\r
+               _weakref->_obj._type = type;\r
+               _weakref->_obj._unVal.pRefCounted = this;\r
+       }\r
+       return _weakref;\r
+}\r
+\r
+SQRefCounted::~SQRefCounted()\r
+{\r
+       if(_weakref) {\r
+               _weakref->_obj._type = OT_NULL;\r
+               _weakref->_obj._unVal.pRefCounted = NULL;\r
+       }\r
+}\r
+\r
+void SQWeakRef::Release() { \r
+       if(ISREFCOUNTED(_obj._type)) { \r
+               _obj._unVal.pRefCounted->_weakref = NULL;\r
+       } \r
+       sq_delete(this,SQWeakRef);\r
+}\r
+\r
+bool SQDelegable::GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res) {\r
+       if(_delegate) {\r
+               return _delegate->Get((*_ss(this)->_metamethods)[mm],res);\r
+       }\r
+       return false;\r
+}\r
+\r
+bool SQDelegable::SetDelegate(SQTable *mt)\r
+{\r
+       SQTable *temp = mt;\r
+       while (temp) {\r
+               if (temp->_delegate == this) return false; //cycle detected\r
+               temp = temp->_delegate;\r
+       }\r
+       if (mt) __ObjAddRef(mt);\r
+       __ObjRelease(_delegate);\r
+       _delegate = mt;\r
+       return true;\r
+}\r
+\r
+bool SQGenerator::Yield(SQVM *v)\r
+{\r
+       if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator"));  return false;}\r
+       if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }\r
+       SQInteger size = v->_top-v->_stackbase;\r
+       _ci=*v->ci;\r
+       _stack.resize(size);\r
+       for(SQInteger n =0; n<size; n++) {\r
+               _stack._vals[n] = v->_stack[v->_stackbase+n];\r
+               v->_stack[v->_stackbase+n] = _null_;\r
+       }\r
+       SQInteger nvargs = v->ci->_vargs.size;\r
+       SQInteger vargsbase = v->ci->_vargs.base;\r
+       for(SQInteger j = nvargs - 1; j >= 0; j--) {\r
+               _vargsstack.push_back(v->_vargsstack[vargsbase+j]);\r
+       }\r
+       _ci._generator=_null_;\r
+       for(SQInteger i=0;i<_ci._etraps;i++) {\r
+               _etraps.push_back(v->_etraps.top());\r
+               v->_etraps.pop_back();\r
+       }\r
+       _state=eSuspended;\r
+       return true;\r
+}\r
+\r
+bool SQGenerator::Resume(SQVM *v,SQInteger target)\r
+{\r
+       SQInteger size=_stack.size();\r
+       if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }\r
+       if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }\r
+       SQInteger prevtop=v->_top-v->_stackbase;\r
+       PUSH_CALLINFO(v,_ci);\r
+       SQInteger oldstackbase=v->_stackbase;\r
+       v->_stackbase=v->_top;\r
+       v->ci->_target=target;\r
+       v->ci->_generator=SQObjectPtr(this);\r
+       v->ci->_vargs.size = _vargsstack.size();\r
+       \r
+       for(SQInteger i=0;i<_ci._etraps;i++) {\r
+               v->_etraps.push_back(_etraps.top());\r
+               _etraps.pop_back();\r
+       }\r
+       for(SQInteger n =0; n<size; n++) {\r
+               v->_stack[v->_stackbase+n] = _stack._vals[n];\r
+               _stack._vals[0] = _null_;\r
+       }\r
+       while(_vargsstack.size()) {\r
+               v->_vargsstack.push_back(_vargsstack.back());\r
+               _vargsstack.pop_back();\r
+       }\r
+       v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size;\r
+       v->_top=v->_stackbase+size;\r
+       v->ci->_prevtop=prevtop;\r
+       v->ci->_prevstkbase=v->_stackbase-oldstackbase;\r
+       _state=eRunning;\r
+       return true;\r
+}\r
+\r
+void SQArray::Extend(const SQArray *a){\r
+       SQInteger xlen;\r
+       if((xlen=a->Size()))\r
+               for(SQInteger i=0;i<xlen;i++)\r
+                       Append(a->_values[i]);\r
+}\r
+\r
+const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)\r
+{\r
+       SQUnsignedInteger nvars=_localvarinfos.size();\r
+       const SQChar *res=NULL; \r
+       if(nvars>=nseq){\r
+               for(SQUnsignedInteger i=0;i<nvars;i++){\r
+                       if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)\r
+                       {\r
+                               if(nseq==0){\r
+                                       vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);\r
+                                       res=_stringval(_localvarinfos[i]._name);\r
+                                       break;\r
+                               }\r
+                               nseq--;\r
+                       }\r
+               }\r
+       }\r
+       return res;\r
+}\r
+\r
+SQInteger SQFunctionProto::GetLine(SQInstruction *curr)\r
+{\r
+       SQInteger op=(curr-_instructions._vals);\r
+       SQInteger line=_lineinfos[0]._line;\r
+       for(SQUnsignedInteger i=1;i<_lineinfos.size();i++){\r
+               if(_lineinfos[i]._op>=op)\r
+                       return line;\r
+               line=_lineinfos[i]._line;\r
+       }\r
+       return line;\r
+}\r
+\r
+//#define _ERROR_TRAP() error_trap:\r
+#define _CHECK_IO(exp)  { if(!exp)return false; }\r
+bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)\r
+{\r
+       if(write(up,dest,size) != size) {\r
+               v->Raise_Error(_SC("io error (write function failure)"));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)\r
+{\r
+       if(size && read(up,dest,size) != size) {\r
+               v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)\r
+{\r
+       return SafeWrite(v,write,up,&tag,sizeof(tag));\r
+}\r
+\r
+bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)\r
+{\r
+       SQInteger t;\r
+       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));\r
+       if(t != tag){\r
+               v->Raise_Error(_SC("invalid or corrupted closure stream"));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)\r
+{\r
+       _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));\r
+       switch(type(o)){\r
+       case OT_STRING:\r
+               _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));\r
+               _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));\r
+               break;\r
+       case OT_INTEGER:\r
+               _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;\r
+       case OT_FLOAT:\r
+               _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;\r
+       case OT_NULL:\r
+               break;\r
+       default:\r
+               v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)\r
+{\r
+       SQObjectType t;\r
+       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));\r
+       switch(t){\r
+       case OT_STRING:{\r
+               SQInteger len;\r
+               _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));\r
+               _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));\r
+               o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);\r
+                                  }\r
+               break;\r
+       case OT_INTEGER:{\r
+               SQInteger i;\r
+               _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;\r
+                                       }\r
+       case OT_FLOAT:{\r
+               SQFloat f;\r
+               _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;\r
+                                 }\r
+       case OT_NULL:\r
+               o=_null_;\r
+               break;\r
+       default:\r
+               v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)\r
+{\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));\r
+       _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));\r
+       _CHECK_IO(_funcproto(_function)->Save(v,up,write));\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));\r
+       return true;\r
+}\r
+\r
+bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)\r
+{\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));\r
+       _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));\r
+       _CHECK_IO(_funcproto(_function)->Load(v,up,read));\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));\r
+       return true;\r
+}\r
+\r
+bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)\r
+{\r
+       SQInteger i,nsize=_literals.size();\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(WriteObject(v,up,write,_sourcename));\r
+       _CHECK_IO(WriteObject(v,up,write,_name));\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
+       for(i=0;i<nsize;i++){\r
+               _CHECK_IO(WriteObject(v,up,write,_literals[i]));\r
+       }\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       nsize=_parameters.size();\r
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
+       for(i=0;i<nsize;i++){\r
+               _CHECK_IO(WriteObject(v,up,write,_parameters[i]));\r
+       }\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       nsize=_outervalues.size();\r
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
+       for(i=0;i<nsize;i++){\r
+               _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));\r
+               _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));\r
+               _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));\r
+       }\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       nsize=_localvarinfos.size();\r
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
+       for(i=0;i<nsize;i++){\r
+               SQLocalVarInfo &lvi=_localvarinfos[i];\r
+               _CHECK_IO(WriteObject(v,up,write,lvi._name));\r
+               _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));\r
+               _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));\r
+               _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));\r
+       }\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       nsize=_lineinfos.size();\r
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
+       _CHECK_IO(SafeWrite(v,write,up,&_lineinfos[0],sizeof(SQLineInfo)*nsize));\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       nsize=_instructions.size();\r
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
+       _CHECK_IO(SafeWrite(v,write,up,&_instructions[0],sizeof(SQInstruction)*nsize));\r
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
+       nsize=_functions.size();\r
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
+       for(i=0;i<nsize;i++){\r
+               _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));\r
+       }\r
+       _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));\r
+       _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));\r
+       _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));\r
+       return true;\r
+}\r
+\r
+bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)\r
+{\r
+       SQInteger i, nsize = _literals.size();\r
+       SQObjectPtr o;\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(ReadObject(v, up, read, _sourcename));\r
+       _CHECK_IO(ReadObject(v, up, read, _name));\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
+       for(i = 0;i < nsize; i++){\r
+               _CHECK_IO(ReadObject(v, up, read, o));\r
+               _literals.push_back(o);\r
+       }\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
+       for(i = 0; i < nsize; i++){\r
+               _CHECK_IO(ReadObject(v, up, read, o));\r
+               _parameters.push_back(o);\r
+       }\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeRead(v,read,up,&nsize,sizeof(nsize)));\r
+       for(i = 0; i < nsize; i++){\r
+               SQUnsignedInteger type;\r
+               SQObjectPtr name;\r
+               _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));\r
+               _CHECK_IO(ReadObject(v, up, read, o));\r
+               _CHECK_IO(ReadObject(v, up, read, name));\r
+               _outervalues.push_back(SQOuterVar(name,o, (SQOuterType)type));\r
+       }\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeRead(v,read,up,&nsize, sizeof(nsize)));\r
+       for(i = 0; i < nsize; i++){\r
+               SQLocalVarInfo lvi;\r
+               _CHECK_IO(ReadObject(v, up, read, lvi._name));\r
+               _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));\r
+               _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));\r
+               _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));\r
+               _localvarinfos.push_back(lvi);\r
+       }\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeRead(v,read,up, &nsize,sizeof(nsize)));\r
+       _lineinfos.resize(nsize);\r
+       _CHECK_IO(SafeRead(v,read,up, &_lineinfos[0], sizeof(SQLineInfo)*nsize));\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
+       _instructions.resize(nsize);\r
+       _CHECK_IO(SafeRead(v,read,up, &_instructions[0], sizeof(SQInstruction)*nsize));\r
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
+       for(i = 0; i < nsize; i++){\r
+               o = SQFunctionProto::Create();\r
+               _CHECK_IO(_funcproto(o)->Load(v, up, read));\r
+               _functions.push_back(o);\r
+       }\r
+       _CHECK_IO(SafeRead(v,read,up, &_stacksize, sizeof(_stacksize)));\r
+       _CHECK_IO(SafeRead(v,read,up, &_bgenerator, sizeof(_bgenerator)));\r
+       _CHECK_IO(SafeRead(v,read,up, &_varparams, sizeof(_varparams)));\r
+       return true;\r
+}\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+\r
+#define START_MARK()   if(!(_uiRef&MARK_FLAG)){ \\r
+               _uiRef|=MARK_FLAG;\r
+\r
+#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \\r
+               AddToChain(chain, this); }\r
+\r
+void SQVM::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               SQSharedState::MarkObject(_lasterror,chain);\r
+               SQSharedState::MarkObject(_errorhandler,chain);\r
+               SQSharedState::MarkObject(_debughook,chain);\r
+               SQSharedState::MarkObject(_roottable, chain);\r
+               SQSharedState::MarkObject(temp_reg, chain);\r
+               for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);\r
+               for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);\r
+       END_MARK()\r
+}\r
+\r
+void SQArray::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               SQInteger len = _values.size();\r
+               for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);\r
+       END_MARK()\r
+}\r
+void SQTable::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               if(_delegate) _delegate->Mark(chain);\r
+               SQInteger len = _numofnodes;\r
+               for(SQInteger i = 0; i < len; i++){\r
+                       SQSharedState::MarkObject(_nodes[i].key, chain);\r
+                       SQSharedState::MarkObject(_nodes[i].val, chain);\r
+               }\r
+       END_MARK()\r
+}\r
+\r
+void SQClass::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               _members->Mark(chain);\r
+               if(_base) _base->Mark(chain);\r
+               SQSharedState::MarkObject(_attributes, chain);\r
+               for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {\r
+                       SQSharedState::MarkObject(_defaultvalues[i].val, chain);\r
+                       SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);\r
+               }\r
+               for(SQUnsignedInteger j =0; j< _methods.size(); j++) {\r
+                       SQSharedState::MarkObject(_methods[j].val, chain);\r
+                       SQSharedState::MarkObject(_methods[j].attrs, chain);\r
+               }\r
+               for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) {\r
+                       SQSharedState::MarkObject(_metamethods[k], chain);\r
+               }\r
+       END_MARK()\r
+}\r
+\r
+void SQInstance::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               _class->Mark(chain);\r
+               for(SQUnsignedInteger i =0; i< _nvalues; i++) {\r
+                       SQSharedState::MarkObject(_values[i], chain);\r
+               }\r
+       END_MARK()\r
+}\r
+\r
+void SQGenerator::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);\r
+               for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);\r
+               SQSharedState::MarkObject(_closure, chain);\r
+       END_MARK()\r
+}\r
+\r
+void SQClosure::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);\r
+       END_MARK()\r
+}\r
+\r
+void SQNativeClosure::Mark(SQCollectable **chain)\r
+{\r
+       START_MARK()\r
+               for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);\r
+       END_MARK()\r
+}\r
+\r
+void SQUserData::Mark(SQCollectable **chain){\r
+       START_MARK()\r
+               if(_delegate) _delegate->Mark(chain);\r
+       END_MARK()\r
+}\r
+\r
+void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }\r
+\r
+#endif\r
+\r
index 9f5823d..230ed4c 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQOBJECT_H_
-#define _SQOBJECT_H_
-
-#include "squtils.h"
-
-#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
-#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
-#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
-
-struct SQSharedState;
-
-enum SQMetaMethod{
-       MT_ADD=0,
-       MT_SUB=1,
-       MT_MUL=2,
-       MT_DIV=3,
-       MT_UNM=4,
-       MT_MODULO=5,
-       MT_SET=6,
-       MT_GET=7,
-       MT_TYPEOF=8,
-       MT_NEXTI=9,
-       MT_CMP=10,
-       MT_CALL=11,
-       MT_CLONED=12,
-       MT_NEWSLOT=13,
-       MT_DELSLOT=14,
-       MT_LAST = 15,
-};
-
-#define MM_ADD         _SC("_add")
-#define MM_SUB         _SC("_sub")
-#define MM_MUL         _SC("_mul")
-#define MM_DIV         _SC("_div")
-#define MM_UNM         _SC("_unm")
-#define MM_MODULO      _SC("_modulo")
-#define MM_SET         _SC("_set")
-#define MM_GET         _SC("_get")
-#define MM_TYPEOF      _SC("_typeof")
-#define MM_NEXTI       _SC("_nexti")
-#define MM_CMP         _SC("_cmp")
-#define MM_CALL                _SC("_call")
-#define MM_CLONED      _SC("_cloned")
-#define MM_NEWSLOT     _SC("_newslot")
-#define MM_DELSLOT     _SC("_delslot")
-
-#define MINPOWER2 4
-
-struct SQRefCounted
-{
-       unsigned int _uiRef;
-       virtual void Release()=0;
-};
-
-struct SQObjectPtr;
-
-#define __AddRef(type,unval) if(ISREFCOUNTED(type))    \
-               { \
-                       unval.pRefCounted->_uiRef++; \
-               }  
-
-#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0))     \
-               {       \
-                       unval.pRefCounted->Release();   \
-               }
-
-#define __ObjRelease(obj) { \
-       if((obj)) {     \
-               (obj)->_uiRef--; \
-               if((obj)->_uiRef == 0) \
-                       (obj)->Release(); \
-               (obj) = NULL;   \
-       } \
-}
-
-#define __ObjAddRef(obj) { \
-       (obj)->_uiRef++; \
-}
-
-#define type(obj) ((obj)._type)
-#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
-#define raw_type(obj) _RAW_TYPE((obj)._type)
-
-#define _integer(obj) ((obj)._unVal.nInteger)
-#define _float(obj) ((obj)._unVal.fFloat)
-#define _string(obj) ((obj)._unVal.pString)
-#define _table(obj) ((obj)._unVal.pTable)
-#define _array(obj) ((obj)._unVal.pArray)
-#define _closure(obj) ((obj)._unVal.pClosure)
-#define _generator(obj) ((obj)._unVal.pGenerator)
-#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
-#define _userdata(obj) ((obj)._unVal.pUserData)
-#define _userpointer(obj) ((obj)._unVal.pUserPointer)
-#define _thread(obj) ((obj)._unVal.pThread)
-#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
-#define _class(obj) ((obj)._unVal.pClass)
-#define _instance(obj) ((obj)._unVal.pInstance)
-#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
-#define _rawval(obj) ((obj)._unVal.pRefCounted)
-
-#define _stringval(obj) (obj)._unVal.pString->_val
-#define _userdataval(obj) (obj)._unVal.pUserData->_val
-
-#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
-#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
-/////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////
-struct SQObjectPtr : public SQObject
-{
-       SQObjectPtr()
-       {
-               _type=OT_NULL;
-               _unVal.pUserPointer=NULL;
-       }
-       SQObjectPtr(const SQObjectPtr &o)
-       {
-               _type=o._type;
-               _unVal=o._unVal;
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(const SQObject &o)
-       {
-               _type=o._type;
-               _unVal=o._unVal;
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQTable *pTable)
-       {
-               _type=OT_TABLE;
-               _unVal.pTable=pTable;
-               assert(_unVal.pTable);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQClass *pClass)
-       {
-               _type=OT_CLASS;
-               _unVal.pClass=pClass;
-               assert(_unVal.pClass);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQInstance *pInstance)
-       {
-               _type=OT_INSTANCE;
-               _unVal.pInstance=pInstance;
-               assert(_unVal.pInstance);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQArray *pArray)
-       {
-               _type=OT_ARRAY;
-               _unVal.pArray=pArray;
-               assert(_unVal.pArray);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQClosure *pClosure)
-       {
-               _type=OT_CLOSURE;
-               _unVal.pClosure=pClosure;
-               assert(_unVal.pClosure);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQGenerator *pGenerator)
-       {
-               _type=OT_GENERATOR;
-               _unVal.pGenerator=pGenerator;
-               assert(_unVal.pGenerator);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQNativeClosure *pNativeClosure)
-       {
-               _type=OT_NATIVECLOSURE;
-               _unVal.pNativeClosure=pNativeClosure;
-               assert(_unVal.pNativeClosure);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQString *pString)
-       {
-               _type=OT_STRING;
-               _unVal.pString=pString;
-               assert(_unVal.pString);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQUserData *pUserData)
-       {
-               _type=OT_USERDATA;
-               _unVal.pUserData=pUserData;
-               assert(_unVal.pUserData);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQVM *pThread)
-       {
-               _type=OT_THREAD;
-               _unVal.pThread=pThread;
-               assert(_unVal.pThread);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQFunctionProto *pFunctionProto)
-       {
-               _type=OT_FUNCPROTO;
-               _unVal.pFunctionProto=pFunctionProto;
-               assert(_unVal.pFunctionProto);
-               __AddRef(_type,_unVal);
-       }
-       SQObjectPtr(SQInteger nInteger)
-       {
-               _type=OT_INTEGER;
-               _unVal.nInteger=nInteger;
-       }
-       SQObjectPtr(SQFloat fFloat)
-       {
-               _type=OT_FLOAT;
-               _unVal.fFloat=fFloat;
-       }
-       SQObjectPtr(bool bBool)
-       {
-               _type = OT_BOOL;
-               _unVal.nInteger = bBool?1:0;
-       }
-       SQObjectPtr(SQUserPointer pUserPointer)
-       {
-               _type=OT_USERPOINTER;
-               _unVal.pUserPointer=pUserPointer;
-       }
-       ~SQObjectPtr()
-       {
-               __Release(_type,_unVal);
-       }
-       inline void Null()
-       {
-               __Release(_type,_unVal);
-               _type=OT_NULL;
-               _unVal.pUserPointer=NULL;
-       }
-       inline SQObjectPtr& operator=(const SQObjectPtr& obj)
-       { 
-               SQObjectType tOldType;
-               SQObjectValue unOldVal;
-               tOldType=_type;
-               unOldVal=_unVal;
-               _unVal = obj._unVal;
-               _type = obj._type;
-               __AddRef(_type,_unVal);
-               __Release(tOldType,unOldVal);
-               return *this;
-       }
-       inline SQObjectPtr& operator=(const SQObject& obj)
-       { 
-               SQObjectType tOldType;
-               SQObjectValue unOldVal;
-               tOldType=_type;
-               unOldVal=_unVal;
-               _unVal = obj._unVal;
-               _type = obj._type;
-               __AddRef(_type,_unVal);
-               __Release(tOldType,unOldVal);
-               return *this;
-       }
-       private:
-               SQObjectPtr(const SQChar *){} //safety
-};
-/////////////////////////////////////////////////////////////////////////////////////
-#ifndef NO_GARBAGE_COLLECTOR
-#define MARK_FLAG 0x80000000
-struct SQCollectable : public SQRefCounted {
-       SQCollectable *_next;
-       SQCollectable *_prev;
-       SQSharedState *_sharedstate;
-       virtual void Release()=0;
-       virtual void Mark(SQCollectable **chain)=0;
-       void UnMark();
-       virtual void Finalize()=0;
-       static void AddToChain(SQCollectable **chain,SQCollectable *c);
-       static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
-};
-
-
-#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
-#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
-#define CHAINABLE_OBJ SQCollectable
-#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
-#else
-
-#define ADD_TO_CHAIN(chain,obj) ((void)0)
-#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
-#define CHAINABLE_OBJ SQRefCounted
-#define INIT_CHAIN() ((void)0)
-#endif
-
-struct SQDelegable : public CHAINABLE_OBJ {
-       virtual bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res);
-       SQTable *_delegate;
-};
-
-unsigned int TranslateIndex(const SQObjectPtr &idx);
-typedef sqvector<SQObjectPtr> SQObjectPtrVec;
-typedef sqvector<int> SQIntVec;
-
-#endif //_SQOBJECT_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQOBJECT_H_\r
+#define _SQOBJECT_H_\r
+\r
+#include "squtils.h"\r
+\r
+#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))\r
+#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))\r
+#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))\r
+\r
+struct SQSharedState;\r
+\r
+enum SQMetaMethod{\r
+       MT_ADD=0,\r
+       MT_SUB=1,\r
+       MT_MUL=2,\r
+       MT_DIV=3,\r
+       MT_UNM=4,\r
+       MT_MODULO=5,\r
+       MT_SET=6,\r
+       MT_GET=7,\r
+       MT_TYPEOF=8,\r
+       MT_NEXTI=9,\r
+       MT_CMP=10,\r
+       MT_CALL=11,\r
+       MT_CLONED=12,\r
+       MT_NEWSLOT=13,\r
+       MT_DELSLOT=14,\r
+       MT_TOSTRING=15,\r
+       MT_LAST = 16,\r
+};\r
+\r
+#define MM_ADD         _SC("_add")\r
+#define MM_SUB         _SC("_sub")\r
+#define MM_MUL         _SC("_mul")\r
+#define MM_DIV         _SC("_div")\r
+#define MM_UNM         _SC("_unm")\r
+#define MM_MODULO      _SC("_modulo")\r
+#define MM_SET         _SC("_set")\r
+#define MM_GET         _SC("_get")\r
+#define MM_TYPEOF      _SC("_typeof")\r
+#define MM_NEXTI       _SC("_nexti")\r
+#define MM_CMP         _SC("_cmp")\r
+#define MM_CALL                _SC("_call")\r
+#define MM_CLONED      _SC("_cloned")\r
+#define MM_NEWSLOT     _SC("_newslot")\r
+#define MM_DELSLOT     _SC("_delslot")\r
+#define MM_TOSTRING    _SC("_tostring")\r
+\r
+#define MINPOWER2 4\r
+\r
+struct SQRefCounted\r
+{\r
+       SQRefCounted() { _uiRef = 0; _weakref = NULL; }\r
+       ~SQRefCounted();\r
+       SQWeakRef *GetWeakRef(SQObjectType type);\r
+       SQUnsignedInteger _uiRef;\r
+       struct SQWeakRef *_weakref;\r
+       virtual void Release()=0;\r
+};\r
+\r
+struct SQWeakRef : SQRefCounted\r
+{\r
+       void Release();\r
+       SQObject _obj;\r
+};\r
+\r
+#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)\r
+\r
+struct SQObjectPtr;\r
+\r
+#define __AddRef(type,unval) if(ISREFCOUNTED(type))    \\r
+               { \\r
+                       unval.pRefCounted->_uiRef++; \\r
+               }  \r
+\r
+#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0))     \\r
+               {       \\r
+                       unval.pRefCounted->Release();   \\r
+               }\r
+\r
+#define __ObjRelease(obj) { \\r
+       if((obj)) {     \\r
+               (obj)->_uiRef--; \\r
+               if((obj)->_uiRef == 0) \\r
+                       (obj)->Release(); \\r
+               (obj) = NULL;   \\r
+       } \\r
+}\r
+\r
+#define __ObjAddRef(obj) { \\r
+       (obj)->_uiRef++; \\r
+}\r
+\r
+#define type(obj) ((obj)._type)\r
+#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)\r
+#define raw_type(obj) _RAW_TYPE((obj)._type)\r
+\r
+#define _integer(obj) ((obj)._unVal.nInteger)\r
+#define _float(obj) ((obj)._unVal.fFloat)\r
+#define _string(obj) ((obj)._unVal.pString)\r
+#define _table(obj) ((obj)._unVal.pTable)\r
+#define _array(obj) ((obj)._unVal.pArray)\r
+#define _closure(obj) ((obj)._unVal.pClosure)\r
+#define _generator(obj) ((obj)._unVal.pGenerator)\r
+#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)\r
+#define _userdata(obj) ((obj)._unVal.pUserData)\r
+#define _userpointer(obj) ((obj)._unVal.pUserPointer)\r
+#define _thread(obj) ((obj)._unVal.pThread)\r
+#define _funcproto(obj) ((obj)._unVal.pFunctionProto)\r
+#define _class(obj) ((obj)._unVal.pClass)\r
+#define _instance(obj) ((obj)._unVal.pInstance)\r
+#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)\r
+#define _weakref(obj) ((obj)._unVal.pWeakRef)\r
+#define _refcounted(obj) ((obj)._unVal.pRefCounted)\r
+#define _rawval(obj) ((obj)._unVal.pRefCounted)\r
+\r
+#define _stringval(obj) (obj)._unVal.pString->_val\r
+#define _userdataval(obj) (obj)._unVal.pUserData->_val\r
+\r
+#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))\r
+#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))\r
+/////////////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////////////\r
+struct SQObjectPtr : public SQObject\r
+{\r
+       SQObjectPtr()\r
+       {\r
+               _type=OT_NULL;\r
+               _unVal.pUserPointer=NULL;\r
+       }\r
+       SQObjectPtr(const SQObjectPtr &o)\r
+       {\r
+               _type=o._type;\r
+               _unVal=o._unVal;\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(const SQObject &o)\r
+       {\r
+               _type=o._type;\r
+               _unVal=o._unVal;\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQTable *pTable)\r
+       {\r
+               _type=OT_TABLE;\r
+               _unVal.pTable=pTable;\r
+               assert(_unVal.pTable);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQClass *pClass)\r
+       {\r
+               _type=OT_CLASS;\r
+               _unVal.pClass=pClass;\r
+               assert(_unVal.pClass);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQInstance *pInstance)\r
+       {\r
+               _type=OT_INSTANCE;\r
+               _unVal.pInstance=pInstance;\r
+               assert(_unVal.pInstance);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQArray *pArray)\r
+       {\r
+               _type=OT_ARRAY;\r
+               _unVal.pArray=pArray;\r
+               assert(_unVal.pArray);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQClosure *pClosure)\r
+       {\r
+               _type=OT_CLOSURE;\r
+               _unVal.pClosure=pClosure;\r
+               assert(_unVal.pClosure);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQGenerator *pGenerator)\r
+       {\r
+               _type=OT_GENERATOR;\r
+               _unVal.pGenerator=pGenerator;\r
+               assert(_unVal.pGenerator);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQNativeClosure *pNativeClosure)\r
+       {\r
+               _type=OT_NATIVECLOSURE;\r
+               _unVal.pNativeClosure=pNativeClosure;\r
+               assert(_unVal.pNativeClosure);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQString *pString)\r
+       {\r
+               _type=OT_STRING;\r
+               _unVal.pString=pString;\r
+               assert(_unVal.pString);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQUserData *pUserData)\r
+       {\r
+               _type=OT_USERDATA;\r
+               _unVal.pUserData=pUserData;\r
+               assert(_unVal.pUserData);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQVM *pThread)\r
+       {\r
+               _type=OT_THREAD;\r
+               _unVal.pThread=pThread;\r
+               assert(_unVal.pThread);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQWeakRef *pWeakRef)\r
+       {\r
+               _type=OT_WEAKREF;\r
+               _unVal.pWeakRef=pWeakRef;\r
+               assert(_unVal.pWeakRef);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQFunctionProto *pFunctionProto)\r
+       {\r
+               _type=OT_FUNCPROTO;\r
+               _unVal.pFunctionProto=pFunctionProto;\r
+               assert(_unVal.pFunctionProto);\r
+               __AddRef(_type,_unVal);\r
+       }\r
+       SQObjectPtr(SQInteger nInteger)\r
+       {\r
+               _unVal.pUserPointer=NULL;\r
+               _type=OT_INTEGER;\r
+               _unVal.nInteger=nInteger;\r
+       }\r
+       SQObjectPtr(SQFloat fFloat)\r
+       {\r
+               _unVal.pUserPointer=NULL;\r
+               _type=OT_FLOAT;\r
+               _unVal.fFloat=fFloat;\r
+       }\r
+       SQObjectPtr(bool bBool)\r
+       {\r
+               _unVal.pUserPointer=NULL;\r
+               _type = OT_BOOL;\r
+               _unVal.nInteger = bBool?1:0;\r
+       }\r
+       SQObjectPtr(SQUserPointer pUserPointer)\r
+       {\r
+               _type=OT_USERPOINTER;\r
+               _unVal.pUserPointer=pUserPointer;\r
+       }\r
+       ~SQObjectPtr()\r
+       {\r
+               __Release(_type,_unVal);\r
+       }\r
+       inline void Null()\r
+       {\r
+               __Release(_type,_unVal);\r
+               _type=OT_NULL;\r
+               _unVal.pUserPointer=NULL;\r
+       }\r
+       inline SQObjectPtr& operator=(const SQObjectPtr& obj)\r
+       { \r
+               SQObjectType tOldType;\r
+               SQObjectValue unOldVal;\r
+               tOldType=_type;\r
+               unOldVal=_unVal;\r
+               _unVal = obj._unVal;\r
+               _type = obj._type;\r
+               __AddRef(_type,_unVal);\r
+               __Release(tOldType,unOldVal);\r
+               return *this;\r
+       }\r
+       inline SQObjectPtr& operator=(const SQObject& obj)\r
+       { \r
+               SQObjectType tOldType;\r
+               SQObjectValue unOldVal;\r
+               tOldType=_type;\r
+               unOldVal=_unVal;\r
+               _unVal = obj._unVal;\r
+               _type = obj._type;\r
+               __AddRef(_type,_unVal);\r
+               __Release(tOldType,unOldVal);\r
+               return *this;\r
+       }\r
+       private:\r
+               SQObjectPtr(const SQChar *){} //safety\r
+};\r
+/////////////////////////////////////////////////////////////////////////////////////\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+#define MARK_FLAG 0x80000000\r
+struct SQCollectable : public SQRefCounted {\r
+       SQCollectable *_next;\r
+       SQCollectable *_prev;\r
+       SQSharedState *_sharedstate;\r
+       virtual void Release()=0;\r
+       virtual void Mark(SQCollectable **chain)=0;\r
+       void UnMark();\r
+       virtual void Finalize()=0;\r
+       static void AddToChain(SQCollectable **chain,SQCollectable *c);\r
+       static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);\r
+};\r
+\r
+\r
+#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)\r
+#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}\r
+#define CHAINABLE_OBJ SQCollectable\r
+#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}\r
+#else\r
+\r
+#define ADD_TO_CHAIN(chain,obj) ((void)0)\r
+#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)\r
+#define CHAINABLE_OBJ SQRefCounted\r
+#define INIT_CHAIN() ((void)0)\r
+#endif\r
+\r
+struct SQDelegable : public CHAINABLE_OBJ {\r
+       bool SetDelegate(SQTable *m);\r
+       virtual bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res);\r
+       SQTable *_delegate;\r
+};\r
+\r
+SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);\r
+typedef sqvector<SQObjectPtr> SQObjectPtrVec;\r
+typedef sqvector<SQInteger> SQIntVec;\r
+\r
+#endif //_SQOBJECT_H_\r
index dbb7d0c..f34ca37 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQOPCODES_H_
-#define _SQOPCODES_H_
-
-#define MAX_FUNC_STACKSIZE 0xFF
-#define MAX_LITERALS 0xFFFFFFFF
-
-enum BitWiseOP {
-       BW_AND = 0,
-       BW_OR = 2,      //like ADD
-       BW_XOR = 3,
-       BW_SHIFTL = 4,
-       BW_SHIFTR = 5,
-       BW_USHIFTR = 6
-};
-
-enum CmpOP {
-       CMP_G = 0,
-       CMP_GE = 2,     //like ADD
-       CMP_L = 3,
-       CMP_LE = 4
-};
-enum SQOpcode
-{
-       _OP_LINE=                               0x00,   
-       _OP_LOAD=                               0x01,   
-       _OP_TAILCALL=                   0x02,   
-       _OP_CALL=                               0x03,   
-       _OP_PREPCALL=                   0x04,   
-       _OP_PREPCALLK=                  0x05,   
-       _OP_GETK=                               0x06,   
-       _OP_MOVE=                               0x07,   
-       _OP_NEWSLOT=                    0x08,   
-       _OP_DELETE=                             0x09,   
-       _OP_SET=                                0x0A,   
-       _OP_GET=                                0x0B,
-       _OP_EQ=                                 0x0C,
-       _OP_NE=                                 0x0D,
-       _OP_ARITH=                              0x0E,
-       _OP_BITW=                               0x0F,
-       _OP_RETURN=                             0x10,   
-       _OP_LOADNULLS=                  0x11,   
-       _OP_LOADROOTTABLE=              0x12,   
-       _OP_DMOVE=                              0x13,   
-       _OP_JMP=                                0x14,   
-       _OP_JNZ=                                0x15,   
-       _OP_JZ=                                 0x16,   
-       _OP_LOADFREEVAR=                0x17,   
-       _OP_VARGC=                              0x18,   
-       _OP_GETVARGV=                   0x19,   
-       _OP_NEWTABLE=                   0x1A,   
-       _OP_NEWARRAY=                   0x1B,   
-       _OP_APPENDARRAY=                0x1C,   
-       _OP_GETPARENT=                  0x1D,   
-       _OP_COMPARITH=                  0x1E,   
-       _OP_COMPARITHL=                 0x1F,   
-       _OP_INC=                                0x20,   
-       _OP_INCL=                               0x21,   
-       _OP_PINC=                               0x22,   
-       _OP_PINCL=                              0x23,   
-       _OP_CMP=                                0x24,
-       _OP_EXISTS=                             0x25,   
-       _OP_INSTANCEOF=                 0x26,
-       _OP_AND=                                0x27,
-       _OP_OR=                                 0x28,
-       _OP_NEG=                                0x29,
-       _OP_NOT=                                0x2A,
-       _OP_BWNOT=                              0x2B,   
-       _OP_CLOSURE=                    0x2C,   
-       _OP_YIELD=                              0x2D,   
-       _OP_RESUME=                             0x2E,
-       _OP_FOREACH=                    0x2F,
-       _OP_DELEGATE=                   0x30,
-       _OP_CLONE=                              0x31,
-       _OP_TYPEOF=                             0x32,
-       _OP_PUSHTRAP=                   0x33,
-       _OP_POPTRAP=                    0x34,
-       _OP_THROW=                              0x35,
-       _OP_CLASS=                              0x36,
-       _OP_NEWSLOTA=                   0x37,
-       _OP_LOADBOOL=                   0x38
-};                                                       
-struct SQInstructionDesc {       
-       const SQChar *name;               
-};                                                       
-
-struct SQInstruction 
-{
-       SQInstruction(){};
-       SQInstruction(SQOpcode _op,int a0=0,int a1=0,int a2=0,int a3=0)
-       {       op = _op;
-               _arg0 = a0;_arg1 = a1;
-               _arg2 = a2;_arg3 = a3;
-       }
-    
-       
-       unsigned int _arg1;
-       unsigned char op;
-       unsigned char _arg0;
-       unsigned char _arg2;
-       unsigned char _arg3;
-};
-
-#include "squtils.h"
-typedef sqvector<SQInstruction> SQInstructionVec;
-
-#endif // _SQOPCODES_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQOPCODES_H_\r
+#define _SQOPCODES_H_\r
+\r
+#define MAX_FUNC_STACKSIZE 0xFF\r
+#define MAX_LITERALS 0xFFFFFFFF\r
+\r
+enum BitWiseOP {\r
+       BW_AND = 0,\r
+       BW_OR = 2,      //like ADD\r
+       BW_XOR = 3,\r
+       BW_SHIFTL = 4,\r
+       BW_SHIFTR = 5,\r
+       BW_USHIFTR = 6\r
+};\r
+\r
+enum CmpOP {\r
+       CMP_G = 0,\r
+       CMP_GE = 2,     //like ADD\r
+       CMP_L = 3,\r
+       CMP_LE = 4\r
+};\r
+enum SQOpcode\r
+{\r
+       _OP_LINE=                               0x00,   \r
+       _OP_LOAD=                               0x01,\r
+       _OP_DLOAD=                              0x02,\r
+       _OP_TAILCALL=                   0x03,   \r
+       _OP_CALL=                               0x04,   \r
+       _OP_PREPCALL=                   0x05,   \r
+       _OP_PREPCALLK=                  0x06,   \r
+       _OP_GETK=                               0x07,   \r
+       _OP_MOVE=                               0x08,   \r
+       _OP_NEWSLOT=                    0x09,   \r
+       _OP_DELETE=                             0x0A,   \r
+       _OP_SET=                                0x0B,   \r
+       _OP_GET=                                0x0C,\r
+       _OP_EQ=                                 0x0D,\r
+       _OP_NE=                                 0x0E,\r
+       _OP_ARITH=                              0x0F,\r
+       _OP_BITW=                               0x10,\r
+       _OP_RETURN=                             0x11,   \r
+       _OP_LOADNULLS=                  0x12,   \r
+       _OP_LOADROOTTABLE=              0x13,\r
+       _OP_LOADBOOL=                   0x14,\r
+       _OP_DMOVE=                              0x15,   \r
+       _OP_JMP=                                0x16,   \r
+       _OP_JNZ=                                0x17,   \r
+       _OP_JZ=                                 0x18,   \r
+       _OP_LOADFREEVAR=                0x19,   \r
+       _OP_VARGC=                              0x1A,   \r
+       _OP_GETVARGV=                   0x1B,   \r
+       _OP_NEWTABLE=                   0x1C,   \r
+       _OP_NEWARRAY=                   0x1D,   \r
+       _OP_APPENDARRAY=                0x1E,   \r
+       _OP_GETPARENT=                  0x1F,   \r
+       _OP_COMPARITH=                  0x20,   \r
+       _OP_COMPARITHL=                 0x21,   \r
+       _OP_INC=                                0x22,   \r
+       _OP_INCL=                               0x23,   \r
+       _OP_PINC=                               0x24,   \r
+       _OP_PINCL=                              0x25,   \r
+       _OP_CMP=                                0x26,\r
+       _OP_EXISTS=                             0x27,   \r
+       _OP_INSTANCEOF=                 0x28,\r
+       _OP_AND=                                0x29,\r
+       _OP_OR=                                 0x2A,\r
+       _OP_NEG=                                0x2B,\r
+       _OP_NOT=                                0x2C,\r
+       _OP_BWNOT=                              0x2D,   \r
+       _OP_CLOSURE=                    0x2E,   \r
+       _OP_YIELD=                              0x2F,   \r
+       _OP_RESUME=                             0x30,\r
+       _OP_FOREACH=                    0x31,\r
+       _OP_DELEGATE=                   0x32,\r
+       _OP_CLONE=                              0x33,\r
+       _OP_TYPEOF=                             0x34,\r
+       _OP_PUSHTRAP=                   0x35,\r
+       _OP_POPTRAP=                    0x36,\r
+       _OP_THROW=                              0x37,\r
+       _OP_CLASS=                              0x38,\r
+       _OP_NEWSLOTA=                   0x39,\r
+                                                       \r
+       \r
+};                                                       \r
+struct SQInstructionDesc {       \r
+       const SQChar *name;               \r
+};                                                       \r
+\r
+struct SQInstruction \r
+{\r
+       SQInstruction(){};\r
+       SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)\r
+       {       op = _op;\r
+               _arg0 = a0;_arg1 = a1;\r
+               _arg2 = a2;_arg3 = a3;\r
+       }\r
+    \r
+       \r
+       SQInt32 _arg1;\r
+       unsigned char op;\r
+       unsigned char _arg0;\r
+       unsigned char _arg2;\r
+       unsigned char _arg3;\r
+};\r
+\r
+#include "squtils.h"\r
+typedef sqvector<SQInstruction> SQInstructionVec;\r
+\r
+#endif // _SQOPCODES_H_\r
index a3fb037..f0e5cf2 100644 (file)
@@ -1,19 +1,19 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQPCHEADER_H_
-#define _SQPCHEADER_H_
-
-#if defined(_MSC_VER) && defined(_DEBUG)
-#include <crtdbg.h>
-#endif 
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <new>
-//squirrel stuff
-#include <squirrel.h>
-#include "sqobject.h"
-#include "sqstate.h"
-
-#endif //_SQPCHEADER_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQPCHEADER_H_\r
+#define _SQPCHEADER_H_\r
+\r
+#if defined(_MSC_VER) && defined(_DEBUG)\r
+#include <crtdbg.h>\r
+#endif \r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <assert.h>\r
+#include <new>\r
+//squirrel stuff\r
+#include <squirrel.h>\r
+#include "sqobject.h"\r
+#include "sqstate.h"\r
+\r
+#endif //_SQPCHEADER_H_\r
index db8e5b2..e209095 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqopcodes.h"
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "squserdata.h"
-#include "sqclass.h"
-
-SQObjectPtr _null_;
-SQObjectPtr _true_(true);
-SQObjectPtr _false_(false);
-SQObjectPtr _one_(1);
-SQObjectPtr _minusone_(-1);
-
-SQSharedState::SQSharedState()
-{
-       _compilererrorhandler = NULL;
-       _printfunc = NULL;
-       _debuginfo = false;
-}
-
-#define newsysstring(s) {      \
-       _systemstrings->push_back(SQString::Create(this,s));    \
-       }
-
-#define newmetamethod(s) {     \
-       _metamethods->push_back(SQString::Create(this,s));      \
-       _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
-       }
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
-{
-       int i = 0;
-       
-       int mask = 0;
-       while(typemask[i] != 0) {
-               
-               switch(typemask[i]){
-                               case 'o': mask |= _RT_NULL; break;
-                               case 'i': mask |= _RT_INTEGER; break;
-                               case 'f': mask |= _RT_FLOAT; break;
-                               case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
-                               case 's': mask |= _RT_STRING; break;
-                               case 't': mask |= _RT_TABLE; break;
-                               case 'a': mask |= _RT_ARRAY; break;
-                               case 'u': mask |= _RT_USERDATA; break;
-                               case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
-                               case 'b': mask |= _RT_BOOL; break;
-                               case 'g': mask |= _RT_GENERATOR; break;
-                               case 'p': mask |= _RT_USERPOINTER; break;
-                               case 'v': mask |= _RT_THREAD; break;
-                               case 'x': mask |= _RT_INSTANCE; break;
-                               case 'y': mask |= _RT_CLASS; break;
-                               case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
-                               case ' ': i++; continue; //ignores spaces
-                               default:
-                                       return false;
-               }
-               i++;
-               if(typemask[i] == '|') { 
-                       i++; 
-                       if(typemask[i] == 0)
-                               return false;
-                       continue; 
-               }
-               res.push_back(mask);
-               mask = 0;
-               
-       }
-       return true;
-}
-
-SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
-{
-       int i=0;
-       SQTable *t=SQTable::Create(ss,0);
-       while(funcz[i].name!=0){
-               SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
-               nc->_nparamscheck = funcz[i].nparamscheck;
-               nc->_name = SQString::Create(ss,funcz[i].name);
-               if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
-                       return NULL;
-               t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
-               i++;
-       }
-       return t;
-}
-
-void SQSharedState::Init()
-{      
-       _scratchpad=NULL;
-       _scratchpadsize=0;
-#ifndef NO_GARBAGE_COLLECTOR
-       _gc_chain=NULL;
-#endif
-       sq_new(_stringtable,StringTable);
-       sq_new(_metamethods,SQObjectPtrVec);
-       sq_new(_systemstrings,SQObjectPtrVec);
-       sq_new(_types,SQObjectPtrVec);
-       _metamethodsmap = SQTable::Create(this,MT_LAST-1);
-       //adding type strings to avoid memory trashing
-       //types names
-       newsysstring(_SC("null"));
-       newsysstring(_SC("table"));
-       newsysstring(_SC("array"));
-       newsysstring(_SC("closure"));
-       newsysstring(_SC("string"));
-       newsysstring(_SC("userdata"));
-       newsysstring(_SC("integer"));
-       newsysstring(_SC("float"));
-       newsysstring(_SC("userpointer"));
-       newsysstring(_SC("function"));
-       newsysstring(_SC("generator"));
-       newsysstring(_SC("thread"));
-       newsysstring(_SC("class"));
-       newsysstring(_SC("instance"));
-       newsysstring(_SC("bool"));
-       //meta methods
-       newmetamethod(MM_ADD);
-       newmetamethod(MM_SUB);
-       newmetamethod(MM_MUL);
-       newmetamethod(MM_DIV);
-       newmetamethod(MM_UNM);
-       newmetamethod(MM_MODULO);
-       newmetamethod(MM_SET);
-       newmetamethod(MM_GET);
-       newmetamethod(MM_TYPEOF);
-       newmetamethod(MM_NEXTI);
-       newmetamethod(MM_CMP);
-       newmetamethod(MM_CALL);
-       newmetamethod(MM_CLONED);
-       newmetamethod(MM_NEWSLOT);
-       newmetamethod(MM_DELSLOT);
-
-       _constructoridx = SQString::Create(this,_SC("constructor"));
-       _refs_table = SQTable::Create(this,0);
-       _registry = SQTable::Create(this,0);
-       _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);
-       _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);
-       _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);
-       _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);
-       _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);
-       _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);
-       _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);
-       _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);
-       _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);
-
-}
-
-SQSharedState::~SQSharedState()
-{
-       _constructoridx = _null_;
-       _table(_refs_table)->Finalize();
-       _table(_registry)->Finalize();
-       _table(_metamethodsmap)->Finalize();
-       _refs_table = _null_;
-       _registry = _null_;
-       _metamethodsmap = _null_;
-       while(!_systemstrings->empty()){
-               _systemstrings->back()=_null_;
-               _systemstrings->pop_back();
-       }
-       _thread(_root_vm)->Finalize();
-       _root_vm = _null_;
-       _table_default_delegate=_null_;
-       _array_default_delegate=_null_;
-       _string_default_delegate=_null_;
-       _number_default_delegate=_null_;
-       _closure_default_delegate=_null_;
-       _generator_default_delegate=_null_;
-       _thread_default_delegate=_null_;
-       _class_default_delegate=_null_;
-       _instance_default_delegate=_null_;
-       
-#ifndef NO_GARBAGE_COLLECTOR
-       
-       
-       SQCollectable *t=_gc_chain;
-       SQCollectable *nx=NULL;
-       while(t){
-               t->_uiRef++;
-               t->Finalize();
-               nx=t->_next;
-               if(--t->_uiRef==0)
-                       t->Release();
-               t=nx;
-       }
-       assert(_gc_chain==NULL); //just to proove a theory
-       while(_gc_chain){
-               _gc_chain->_uiRef++;
-               _gc_chain->Release();
-       }
-#endif
-       sq_delete(_types,SQObjectPtrVec);
-       sq_delete(_systemstrings,SQObjectPtrVec);
-       sq_delete(_metamethods,SQObjectPtrVec);
-       sq_delete(_stringtable,StringTable);
-       if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
-}
-
-
-SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
-{
-       if(type(name) != OT_STRING)
-               return -1;
-       SQObjectPtr ret;
-       if(_table(_metamethodsmap)->Get(name,ret)) {
-               return _integer(ret);
-       }
-       return -1;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
-{
-       switch(type(o)){
-       case OT_TABLE:_table(o)->Mark(chain);break;
-       case OT_ARRAY:_array(o)->Mark(chain);break;
-       case OT_USERDATA:_userdata(o)->Mark(chain);break;
-       case OT_CLOSURE:_closure(o)->Mark(chain);break;
-       case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
-       case OT_GENERATOR:_generator(o)->Mark(chain);break;
-       case OT_THREAD:_thread(o)->Mark(chain);break;
-       case OT_CLASS:_class(o)->Mark(chain);break;
-       case OT_INSTANCE:_instance(o)->Mark(chain);break;
-       }
-}
-
-
-int SQSharedState::CollectGarbage(SQVM *vm)
-{
-       int n=0;
-       SQCollectable *tchain=NULL;
-       SQVM *vms=_thread(_root_vm);
-       
-       vms->Mark(&tchain);
-       int x = _table(_thread(_root_vm)->_roottable)->CountUsed();
-       MarkObject(_refs_table,&tchain);
-       MarkObject(_registry,&tchain);
-       MarkObject(_metamethodsmap,&tchain);
-       MarkObject(_table_default_delegate,&tchain);
-       MarkObject(_array_default_delegate,&tchain);
-       MarkObject(_string_default_delegate,&tchain);
-       MarkObject(_number_default_delegate,&tchain);
-       MarkObject(_generator_default_delegate,&tchain);
-       MarkObject(_thread_default_delegate,&tchain);
-       MarkObject(_closure_default_delegate,&tchain);
-       MarkObject(_class_default_delegate,&tchain);
-       MarkObject(_instance_default_delegate,&tchain);
-       
-       SQCollectable *t=_gc_chain;
-       SQCollectable *nx=NULL;
-       while(t){
-               t->_uiRef++;
-               t->Finalize();
-               nx=t->_next;
-               if(--t->_uiRef==0)
-                       t->Release();
-               t=nx;
-               n++;
-       }
-
-       t=tchain;
-       while(t){
-               t->UnMark();
-               t=t->_next;
-       }
-       _gc_chain=tchain;
-       int z = _table(_thread(_root_vm)->_roottable)->CountUsed();
-       assert(z == x);
-       return n;
-}
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
-void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *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->_next)
-               c->_next->_prev=c->_prev;
-       c->_next=NULL;
-       c->_prev=NULL;
-}
-#endif
-
-SQChar* SQSharedState::GetScratchPad(int size)
-{
-       int newsize;
-       if(size>0){
-               if(_scratchpadsize<size){
-                       newsize=size+(size>>1);
-                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
-                       _scratchpadsize=newsize;
-
-               }else if(_scratchpadsize>=(size<<5)){
-                       newsize=_scratchpadsize>>1;
-                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
-                       _scratchpadsize=newsize;
-               }
-       }
-       return _scratchpad;
-}
-
-//////////////////////////////////////////////////////////////////////////
-//StringTable
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_lstring.c.html
-*/
-
-int SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
-       int idx = (int)TranslateIndex(refpos);
-       while(idx < _len){
-               outkey = (SQInteger)idx;
-               outval = SQInteger(_val[idx]);
-               //return idx for the next iteration
-               return ++idx;
-       }
-       //nothing to iterate anymore
-       return -1;
-}
-
-StringTable::StringTable()
-{
-       AllocNodes(4);
-       _slotused = 0;
-}
-
-StringTable::~StringTable()
-{
-       SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
-       _strings=NULL;
-}
-
-void StringTable::AllocNodes(int size)
-{
-       _numofslots=size;
-       //_slotused=0;
-       _strings=(SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
-       memset(_strings,0,sizeof(SQString*)*_numofslots);
-}
-
-SQString *StringTable::Add(const SQChar *news,int len)
-{
-       if(len<0)
-               len=scstrlen(news);
-       unsigned int h=::_hashstr(news,len)&(_numofslots-1);
-       SQString *s;
-       for (s = _strings[h]; s; s = s->_next){
-               if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
-                       return s; //found
-       }
-
-       SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
-       new (t) SQString;
-       memcpy(t->_val,news,rsl(len));
-       t->_val[len]=_SC('\0');
-       t->_len=len;
-       t->_hash=::_hashstr(news,len);
-       t->_next=_strings[h];
-       t->_uiRef=0;
-       _strings[h]=t;
-       _slotused++;
-       if (_slotused > _numofslots)  /* too crowded? */
-               Resize(_numofslots*2);
-       return t;
-}
-
-void StringTable::Resize(int size)
-{
-       int oldsize=_numofslots;
-       SQString **oldtable=_strings;
-       AllocNodes(size);
-       for (int i=0; i<oldsize; i++){
-               SQString *p = oldtable[i];
-               while(p){
-                       SQString *next = p->_next;
-                       unsigned int h=p->_hash&(_numofslots-1);
-                       p->_next=_strings[h];
-                       _strings[h] = p;
-                       p=next;
-               }
-       }
-       SQ_FREE(oldtable,oldsize*sizeof(SQString*));
-}
-
-void StringTable::Remove(SQString *bs)
-{
-       SQString *s;
-       SQString *prev=NULL;
-       unsigned int h=bs->_hash&(_numofslots-1);
-       
-       for (s = _strings[h]; s; ){
-               if(s == bs){
-                       if(prev)
-                               prev->_next = s->_next;
-                       else
-                               _strings[h] = s->_next;
-                       _slotused--;
-                       int slen=s->_len;
-                       s->~SQString();
-                       SQ_FREE(s,sizeof(SQString)+rsl(slen));
-                       return;
-               }
-               prev = s;
-               s = s->_next;
-       }
-       assert(0);//if this fail something is wrong
-}
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include "sqopcodes.h"\r
+#include "sqvm.h"\r
+#include "sqfuncproto.h"\r
+#include "sqclosure.h"\r
+#include "sqstring.h"\r
+#include "sqtable.h"\r
+#include "sqarray.h"\r
+#include "squserdata.h"\r
+#include "sqclass.h"\r
+\r
+SQObjectPtr _null_;\r
+SQObjectPtr _true_(true);\r
+SQObjectPtr _false_(false);\r
+SQObjectPtr _one_(1);\r
+SQObjectPtr _minusone_(-1);\r
+\r
+SQSharedState::SQSharedState()\r
+{\r
+       _compilererrorhandler = NULL;\r
+       _printfunc = NULL;\r
+       _debuginfo = false;\r
+}\r
+\r
+#define newsysstring(s) {      \\r
+       _systemstrings->push_back(SQString::Create(this,s));    \\r
+       }\r
+\r
+#define newmetamethod(s) {     \\r
+       _metamethods->push_back(SQString::Create(this,s));      \\r
+       _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \\r
+       }\r
+\r
+bool CompileTypemask(SQIntVec &res,const SQChar *typemask)\r
+{\r
+       SQInteger i = 0;\r
+       \r
+       SQInteger mask = 0;\r
+       while(typemask[i] != 0) {\r
+               \r
+               switch(typemask[i]){\r
+                               case 'o': mask |= _RT_NULL; break;\r
+                               case 'i': mask |= _RT_INTEGER; break;\r
+                               case 'f': mask |= _RT_FLOAT; break;\r
+                               case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;\r
+                               case 's': mask |= _RT_STRING; break;\r
+                               case 't': mask |= _RT_TABLE; break;\r
+                               case 'a': mask |= _RT_ARRAY; break;\r
+                               case 'u': mask |= _RT_USERDATA; break;\r
+                               case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;\r
+                               case 'b': mask |= _RT_BOOL; break;\r
+                               case 'g': mask |= _RT_GENERATOR; break;\r
+                               case 'p': mask |= _RT_USERPOINTER; break;\r
+                               case 'v': mask |= _RT_THREAD; break;\r
+                               case 'x': mask |= _RT_INSTANCE; break;\r
+                               case 'y': mask |= _RT_CLASS; break;\r
+                               case 'r': mask |= _RT_WEAKREF; break;\r
+                               case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;\r
+                               case ' ': i++; continue; //ignores spaces\r
+                               default:\r
+                                       return false;\r
+               }\r
+               i++;\r
+               if(typemask[i] == '|') { \r
+                       i++; \r
+                       if(typemask[i] == 0)\r
+                               return false;\r
+                       continue; \r
+               }\r
+               res.push_back(mask);\r
+               mask = 0;\r
+               \r
+       }\r
+       return true;\r
+}\r
+\r
+SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)\r
+{\r
+       SQInteger i=0;\r
+       SQTable *t=SQTable::Create(ss,0);\r
+       while(funcz[i].name!=0){\r
+               SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);\r
+               nc->_nparamscheck = funcz[i].nparamscheck;\r
+               nc->_name = SQString::Create(ss,funcz[i].name);\r
+               if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))\r
+                       return NULL;\r
+               t->NewSlot(SQString::Create(ss,funcz[i].name),nc);\r
+               i++;\r
+       }\r
+       return t;\r
+}\r
+\r
+void SQSharedState::Init()\r
+{      \r
+       _scratchpad=NULL;\r
+       _scratchpadsize=0;\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       _gc_chain=NULL;\r
+#endif\r
+       sq_new(_stringtable,StringTable);\r
+       sq_new(_metamethods,SQObjectPtrVec);\r
+       sq_new(_systemstrings,SQObjectPtrVec);\r
+       sq_new(_types,SQObjectPtrVec);\r
+       _metamethodsmap = SQTable::Create(this,MT_LAST-1);\r
+       //adding type strings to avoid memory trashing\r
+       //types names\r
+       newsysstring(_SC("null"));\r
+       newsysstring(_SC("table"));\r
+       newsysstring(_SC("array"));\r
+       newsysstring(_SC("closure"));\r
+       newsysstring(_SC("string"));\r
+       newsysstring(_SC("userdata"));\r
+       newsysstring(_SC("integer"));\r
+       newsysstring(_SC("float"));\r
+       newsysstring(_SC("userpointer"));\r
+       newsysstring(_SC("function"));\r
+       newsysstring(_SC("generator"));\r
+       newsysstring(_SC("thread"));\r
+       newsysstring(_SC("class"));\r
+       newsysstring(_SC("instance"));\r
+       newsysstring(_SC("bool"));\r
+       //meta methods\r
+       newmetamethod(MM_ADD);\r
+       newmetamethod(MM_SUB);\r
+       newmetamethod(MM_MUL);\r
+       newmetamethod(MM_DIV);\r
+       newmetamethod(MM_UNM);\r
+       newmetamethod(MM_MODULO);\r
+       newmetamethod(MM_SET);\r
+       newmetamethod(MM_GET);\r
+       newmetamethod(MM_TYPEOF);\r
+       newmetamethod(MM_NEXTI);\r
+       newmetamethod(MM_CMP);\r
+       newmetamethod(MM_CALL);\r
+       newmetamethod(MM_CLONED);\r
+       newmetamethod(MM_NEWSLOT);\r
+       newmetamethod(MM_DELSLOT);\r
+       newmetamethod(MM_TOSTRING);\r
+\r
+       _constructoridx = SQString::Create(this,_SC("constructor"));\r
+       _refs_table = SQTable::Create(this,0);\r
+       _registry = SQTable::Create(this,0);\r
+       _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);\r
+       _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);\r
+       _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);\r
+       _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);\r
+       _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);\r
+       _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);\r
+       _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);\r
+       _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);\r
+       _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);\r
+       _weakref_default_delegate=CreateDefaultDelegate(this,_weakref_default_delegate_funcz);\r
+\r
+}\r
+\r
+SQSharedState::~SQSharedState()\r
+{\r
+       _constructoridx = _null_;\r
+       _table(_refs_table)->Finalize();\r
+       _table(_registry)->Finalize();\r
+       _table(_metamethodsmap)->Finalize();\r
+       _refs_table = _null_;\r
+       _registry = _null_;\r
+       _metamethodsmap = _null_;\r
+       while(!_systemstrings->empty()){\r
+               _systemstrings->back()=_null_;\r
+               _systemstrings->pop_back();\r
+       }\r
+       _thread(_root_vm)->Finalize();\r
+       _root_vm = _null_;\r
+       _table_default_delegate=_null_;\r
+       _array_default_delegate=_null_;\r
+       _string_default_delegate=_null_;\r
+       _number_default_delegate=_null_;\r
+       _closure_default_delegate=_null_;\r
+       _generator_default_delegate=_null_;\r
+       _thread_default_delegate=_null_;\r
+       _class_default_delegate=_null_;\r
+       _instance_default_delegate=_null_;\r
+       _weakref_default_delegate=_null_;\r
+       \r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       \r
+       \r
+       SQCollectable *t=_gc_chain;\r
+       SQCollectable *nx=NULL;\r
+       while(t){\r
+               t->_uiRef++;\r
+               t->Finalize();\r
+               nx=t->_next;\r
+               if(--t->_uiRef==0)\r
+                       t->Release();\r
+               t=nx;\r
+       }\r
+       assert(_gc_chain==NULL); //just to proove a theory\r
+       while(_gc_chain){\r
+               _gc_chain->_uiRef++;\r
+               _gc_chain->Release();\r
+       }\r
+#endif\r
+       sq_delete(_types,SQObjectPtrVec);\r
+       sq_delete(_systemstrings,SQObjectPtrVec);\r
+       sq_delete(_metamethods,SQObjectPtrVec);\r
+       sq_delete(_stringtable,StringTable);\r
+       if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);\r
+}\r
+\r
+\r
+SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)\r
+{\r
+       if(type(name) != OT_STRING)\r
+               return -1;\r
+       SQObjectPtr ret;\r
+       if(_table(_metamethodsmap)->Get(name,ret)) {\r
+               return _integer(ret);\r
+       }\r
+       return -1;\r
+}\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+\r
+void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)\r
+{\r
+       switch(type(o)){\r
+       case OT_TABLE:_table(o)->Mark(chain);break;\r
+       case OT_ARRAY:_array(o)->Mark(chain);break;\r
+       case OT_USERDATA:_userdata(o)->Mark(chain);break;\r
+       case OT_CLOSURE:_closure(o)->Mark(chain);break;\r
+       case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;\r
+       case OT_GENERATOR:_generator(o)->Mark(chain);break;\r
+       case OT_THREAD:_thread(o)->Mark(chain);break;\r
+       case OT_CLASS:_class(o)->Mark(chain);break;\r
+       case OT_INSTANCE:_instance(o)->Mark(chain);break;\r
+       }\r
+}\r
+\r
+\r
+SQInteger SQSharedState::CollectGarbage(SQVM *vm)\r
+{\r
+       SQInteger n=0;\r
+       SQCollectable *tchain=NULL;\r
+       SQVM *vms=_thread(_root_vm);\r
+       \r
+       vms->Mark(&tchain);\r
+       SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();\r
+       MarkObject(_refs_table,&tchain);\r
+       MarkObject(_registry,&tchain);\r
+       MarkObject(_metamethodsmap,&tchain);\r
+       MarkObject(_table_default_delegate,&tchain);\r
+       MarkObject(_array_default_delegate,&tchain);\r
+       MarkObject(_string_default_delegate,&tchain);\r
+       MarkObject(_number_default_delegate,&tchain);\r
+       MarkObject(_generator_default_delegate,&tchain);\r
+       MarkObject(_thread_default_delegate,&tchain);\r
+       MarkObject(_closure_default_delegate,&tchain);\r
+       MarkObject(_class_default_delegate,&tchain);\r
+       MarkObject(_instance_default_delegate,&tchain);\r
+       MarkObject(_weakref_default_delegate,&tchain);\r
+       \r
+       SQCollectable *t=_gc_chain;\r
+       SQCollectable *nx=NULL;\r
+       while(t){\r
+               t->_uiRef++;\r
+               t->Finalize();\r
+               nx=t->_next;\r
+               if(--t->_uiRef==0)\r
+                       t->Release();\r
+               t=nx;\r
+               n++;\r
+       }\r
+\r
+       t=tchain;\r
+       while(t){\r
+               t->UnMark();\r
+               t=t->_next;\r
+       }\r
+       _gc_chain=tchain;\r
+       SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();\r
+       assert(z == x);\r
+       return n;\r
+}\r
+#endif\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)\r
+{\r
+    c->_prev=NULL;\r
+       c->_next=*chain;\r
+       if(*chain) (*chain)->_prev=c;\r
+       *chain=c;\r
+}\r
+\r
+void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)\r
+{\r
+       if(c->_prev) c->_prev->_next=c->_next;\r
+       else *chain=c->_next;\r
+       if(c->_next)\r
+               c->_next->_prev=c->_prev;\r
+       c->_next=NULL;\r
+       c->_prev=NULL;\r
+}\r
+#endif\r
+\r
+SQChar* SQSharedState::GetScratchPad(SQInteger size)\r
+{\r
+       SQInteger newsize;\r
+       if(size>0){\r
+               if(_scratchpadsize<size){\r
+                       newsize=size+(size>>1);\r
+                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);\r
+                       _scratchpadsize=newsize;\r
+\r
+               }else if(_scratchpadsize>=(size<<5)){\r
+                       newsize=_scratchpadsize>>1;\r
+                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);\r
+                       _scratchpadsize=newsize;\r
+               }\r
+       }\r
+       return _scratchpad;\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+//StringTable\r
+/*\r
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)\r
+* http://www.lua.org/copyright.html#4\r
+* http://www.lua.org/source/4.0.1/src_lstring.c.html\r
+*/\r
+\r
+SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
+{\r
+       SQInteger idx = (SQInteger)TranslateIndex(refpos);\r
+       while(idx < _len){\r
+               outkey = (SQInteger)idx;\r
+               outval = SQInteger(_val[idx]);\r
+               //return idx for the next iteration\r
+               return ++idx;\r
+       }\r
+       //nothing to iterate anymore\r
+       return -1;\r
+}\r
+\r
+StringTable::StringTable()\r
+{\r
+       AllocNodes(4);\r
+       _slotused = 0;\r
+}\r
+\r
+StringTable::~StringTable()\r
+{\r
+       SQ_FREE(_strings,sizeof(SQString*)*_numofslots);\r
+       _strings=NULL;\r
+}\r
+\r
+void StringTable::AllocNodes(SQInteger size)\r
+{\r
+       _numofslots=size;\r
+       //_slotused=0;\r
+       _strings=(SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);\r
+       memset(_strings,0,sizeof(SQString*)*_numofslots);\r
+}\r
+\r
+SQString *StringTable::Add(const SQChar *news,SQInteger len)\r
+{\r
+       if(len<0)\r
+               len=scstrlen(news);\r
+       SQHash h = ::_hashstr(news,len)&(_numofslots-1);\r
+       SQString *s;\r
+       for (s = _strings[h]; s; s = s->_next){\r
+               if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))\r
+                       return s; //found\r
+       }\r
+\r
+       SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));\r
+       new (t) SQString;\r
+       memcpy(t->_val,news,rsl(len));\r
+       t->_val[len] = _SC('\0');\r
+       t->_len = len;\r
+       t->_hash = ::_hashstr(news,len);\r
+       t->_next = _strings[h];\r
+       _strings[h] = t;\r
+       _slotused++;\r
+       if (_slotused > _numofslots)  /* too crowded? */\r
+               Resize(_numofslots*2);\r
+       return t;\r
+}\r
+\r
+void StringTable::Resize(SQInteger size)\r
+{\r
+       SQInteger oldsize=_numofslots;\r
+       SQString **oldtable=_strings;\r
+       AllocNodes(size);\r
+       for (SQInteger i=0; i<oldsize; i++){\r
+               SQString *p = oldtable[i];\r
+               while(p){\r
+                       SQString *next = p->_next;\r
+                       SQHash h = p->_hash&(_numofslots-1);\r
+                       p->_next = _strings[h];\r
+                       _strings[h] = p;\r
+                       p = next;\r
+               }\r
+       }\r
+       SQ_FREE(oldtable,oldsize*sizeof(SQString*));\r
+}\r
+\r
+void StringTable::Remove(SQString *bs)\r
+{\r
+       SQString *s;\r
+       SQString *prev=NULL;\r
+       SQHash h = bs->_hash&(_numofslots - 1);\r
+       \r
+       for (s = _strings[h]; s; ){\r
+               if(s == bs){\r
+                       if(prev)\r
+                               prev->_next = s->_next;\r
+                       else\r
+                               _strings[h] = s->_next;\r
+                       _slotused--;\r
+                       SQInteger slen = s->_len;\r
+                       s->~SQString();\r
+                       SQ_FREE(s,sizeof(SQString) + rsl(slen));\r
+                       return;\r
+               }\r
+               prev = s;\r
+               s = s->_next;\r
+       }\r
+       assert(0);//if this fail something is wrong\r
+}\r
index f85e864..13aa719 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTATE_H_
-#define _SQSTATE_H_
-
-#include "squtils.h"
-#include "sqobject.h"
-struct SQString;
-struct SQTable;
-//max number of character for a printed number
-#define NUMBER_MAX_CHAR 50
-
-struct StringTable
-{
-       StringTable();
-       ~StringTable();
-       //return a string obj if exists
-       //so when there is a table query, if the string doesn't exists in the global state
-       //it cannot be in a table so the result will be always null
-       //SQString *get(const SQChar *news);
-       SQString *Add(const SQChar *,int len);
-       void Remove(SQString *);
-private:
-       void Resize(int size);
-       void AllocNodes(int size);
-       SQString **_strings;
-       unsigned int _numofslots;
-       unsigned int _slotused;
-};
-
-#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
-#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
-
-struct SQObjectPtr;
-
-struct SQSharedState
-{
-       SQSharedState();
-       ~SQSharedState();
-       void Init();
-public:
-       SQChar* GetScratchPad(int size);
-       SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
-#ifndef NO_GARBAGE_COLLECTOR
-       int CollectGarbage(SQVM *vm); 
-       static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
-#endif
-       SQObjectPtrVec *_metamethods;
-       SQObjectPtr _metamethodsmap;
-       SQObjectPtrVec *_systemstrings;
-       SQObjectPtrVec *_types;
-       StringTable *_stringtable;
-       SQObjectPtr _refs_table;
-       SQObjectPtr _registry;
-       SQObjectPtr _constructoridx;
-#ifndef NO_GARBAGE_COLLECTOR
-       SQCollectable *_gc_chain;
-#endif
-       SQObjectPtr _root_vm;
-       SQObjectPtr _table_default_delegate;
-       static SQRegFunction _table_default_delegate_funcz[];
-       SQObjectPtr _array_default_delegate;
-       static SQRegFunction _array_default_delegate_funcz[];
-       SQObjectPtr _string_default_delegate;
-       static SQRegFunction _string_default_delegate_funcz[];
-       SQObjectPtr _number_default_delegate;
-       static SQRegFunction _number_default_delegate_funcz[];
-       SQObjectPtr _generator_default_delegate;
-       static SQRegFunction _generator_default_delegate_funcz[];
-       SQObjectPtr _closure_default_delegate;
-       static SQRegFunction _closure_default_delegate_funcz[];
-       SQObjectPtr _thread_default_delegate;
-       static SQRegFunction _thread_default_delegate_funcz[];
-       SQObjectPtr _class_default_delegate;
-       static SQRegFunction _class_default_delegate_funcz[];
-       SQObjectPtr _instance_default_delegate;
-       static SQRegFunction _instance_default_delegate_funcz[];
-       
-       SQCOMPILERERROR _compilererrorhandler;
-       SQPRINTFUNCTION _printfunc;
-       bool _debuginfo;
-private:
-       SQChar *_scratchpad;
-       int _scratchpadsize;
-};
-
-#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) 
-
-#ifdef SQUNICODE //rsl REAL STRING LEN
-#define rsl(l) ((l)<<1)
-#else
-#define rsl(l) (l)
-#endif
-
-extern SQObjectPtr _null_;
-extern SQObjectPtr _true_;
-extern SQObjectPtr _false_;
-extern SQObjectPtr _one_;
-extern SQObjectPtr _minusone_;
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
-
-void *sq_vm_malloc(unsigned int size);
-void *sq_vm_realloc(void *p,unsigned int oldsize,unsigned int size);
-void sq_vm_free(void *p,unsigned int size);
-#endif //_SQSTATE_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTATE_H_\r
+#define _SQSTATE_H_\r
+\r
+#include "squtils.h"\r
+#include "sqobject.h"\r
+struct SQString;\r
+struct SQTable;\r
+//max number of character for a printed number\r
+#define NUMBER_MAX_CHAR 50\r
+\r
+struct StringTable\r
+{\r
+       StringTable();\r
+       ~StringTable();\r
+       //return a string obj if exists\r
+       //so when there is a table query, if the string doesn't exists in the global state\r
+       //it cannot be in a table so the result will be always null\r
+       //SQString *get(const SQChar *news);\r
+       SQString *Add(const SQChar *,SQInteger len);\r
+       void Remove(SQString *);\r
+private:\r
+       void Resize(SQInteger size);\r
+       void AllocNodes(SQInteger size);\r
+       SQString **_strings;\r
+       SQUnsignedInteger _numofslots;\r
+       SQUnsignedInteger _slotused;\r
+};\r
+\r
+#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)\r
+#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)\r
+\r
+struct SQObjectPtr;\r
+\r
+struct SQSharedState\r
+{\r
+       SQSharedState();\r
+       ~SQSharedState();\r
+       void Init();\r
+public:\r
+       SQChar* GetScratchPad(SQInteger size);\r
+       SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       SQInteger CollectGarbage(SQVM *vm); \r
+       static void MarkObject(SQObjectPtr &o,SQCollectable **chain);\r
+#endif\r
+       SQObjectPtrVec *_metamethods;\r
+       SQObjectPtr _metamethodsmap;\r
+       SQObjectPtrVec *_systemstrings;\r
+       SQObjectPtrVec *_types;\r
+       StringTable *_stringtable;\r
+       SQObjectPtr _refs_table;\r
+       SQObjectPtr _registry;\r
+       SQObjectPtr _constructoridx;\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       SQCollectable *_gc_chain;\r
+#endif\r
+       SQObjectPtr _root_vm;\r
+       SQObjectPtr _table_default_delegate;\r
+       static SQRegFunction _table_default_delegate_funcz[];\r
+       SQObjectPtr _array_default_delegate;\r
+       static SQRegFunction _array_default_delegate_funcz[];\r
+       SQObjectPtr _string_default_delegate;\r
+       static SQRegFunction _string_default_delegate_funcz[];\r
+       SQObjectPtr _number_default_delegate;\r
+       static SQRegFunction _number_default_delegate_funcz[];\r
+       SQObjectPtr _generator_default_delegate;\r
+       static SQRegFunction _generator_default_delegate_funcz[];\r
+       SQObjectPtr _closure_default_delegate;\r
+       static SQRegFunction _closure_default_delegate_funcz[];\r
+       SQObjectPtr _thread_default_delegate;\r
+       static SQRegFunction _thread_default_delegate_funcz[];\r
+       SQObjectPtr _class_default_delegate;\r
+       static SQRegFunction _class_default_delegate_funcz[];\r
+       SQObjectPtr _instance_default_delegate;\r
+       static SQRegFunction _instance_default_delegate_funcz[];\r
+       SQObjectPtr _weakref_default_delegate;\r
+       static SQRegFunction _weakref_default_delegate_funcz[];\r
+       \r
+       SQCOMPILERERROR _compilererrorhandler;\r
+       SQPRINTFUNCTION _printfunc;\r
+       bool _debuginfo;\r
+private:\r
+       SQChar *_scratchpad;\r
+       SQInteger _scratchpadsize;\r
+};\r
+\r
+#define _sp(s) (_sharedstate->GetScratchPad(s))\r
+#define _spval (_sharedstate->GetScratchPad(-1))\r
+\r
+#define _table_ddel            _table(_sharedstate->_table_default_delegate) \r
+#define _array_ddel            _table(_sharedstate->_array_default_delegate) \r
+#define _string_ddel   _table(_sharedstate->_string_default_delegate) \r
+#define _number_ddel   _table(_sharedstate->_number_default_delegate) \r
+#define _generator_ddel        _table(_sharedstate->_generator_default_delegate) \r
+#define _closure_ddel  _table(_sharedstate->_closure_default_delegate) \r
+#define _thread_ddel   _table(_sharedstate->_thread_default_delegate) \r
+#define _class_ddel            _table(_sharedstate->_class_default_delegate) \r
+#define _instance_ddel _table(_sharedstate->_instance_default_delegate) \r
+#define _weakref_ddel  _table(_sharedstate->_weakref_default_delegate) \r
+\r
+#ifdef SQUNICODE //rsl REAL STRING LEN\r
+#define rsl(l) ((l)<<1)\r
+#else\r
+#define rsl(l) (l)\r
+#endif\r
+\r
+extern SQObjectPtr _null_;\r
+extern SQObjectPtr _true_;\r
+extern SQObjectPtr _false_;\r
+extern SQObjectPtr _one_;\r
+extern SQObjectPtr _minusone_;\r
+\r
+bool CompileTypemask(SQIntVec &res,const SQChar *typemask);\r
+\r
+void *sq_vm_malloc(SQUnsignedInteger size);\r
+void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);\r
+void sq_vm_free(void *p,SQUnsignedInteger size);\r
+#endif //_SQSTATE_H_\r
index 5061c13..29ca9c2 100644 (file)
@@ -1,31 +1,31 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQSTRING_H_
-#define _SQSTRING_H_
-
-inline unsigned int _hashstr (const SQChar *s, size_t l)
-{
-               unsigned int h = l;  /* seed */
-               size_t step = (l>>5)|1;  /* if string is too long, don't hash all its chars */
-               for (; l>=step; l-=step)
-                       h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
-               return h;
-}
-
-struct SQString : public SQRefCounted
-{
-       SQString(){}
-       ~SQString(){}
-public:
-       static SQString *Create(SQSharedState *ss, const SQChar *, int len = -1 );
-       int Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-       void Release();
-       SQSharedState *_sharedstate;
-       SQString *_next; //chain for the string table
-       int _len;
-       int _hash;
-       SQChar _val[1];
-};
-
-
-
-#endif //_SQSTRING_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQSTRING_H_\r
+#define _SQSTRING_H_\r
+\r
+inline SQHash _hashstr (const SQChar *s, size_t l)\r
+{\r
+               SQHash h = l;  /* seed */\r
+               size_t step = (l>>5)|1;  /* if string is too long, don't hash all its chars */\r
+               for (; l>=step; l-=step)\r
+                       h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));\r
+               return h;\r
+}\r
+\r
+struct SQString : public SQRefCounted\r
+{\r
+       SQString(){}\r
+       ~SQString(){}\r
+public:\r
+       static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );\r
+       SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
+       void Release();\r
+       SQSharedState *_sharedstate;\r
+       SQString *_next; //chain for the string table\r
+       SQInteger _len;\r
+       SQHash _hash;\r
+       SQChar _val[1];\r
+};\r
+\r
+\r
+\r
+#endif //_SQSTRING_H_\r
index 1b4f244..8eef4b8 100644 (file)
-/*
-see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-
-SQTable::SQTable(SQSharedState *ss,int nInitialSize)
-{
-       int pow2size=MINPOWER2;
-       while(nInitialSize>pow2size)pow2size=pow2size<<1;
-       AllocNodes(pow2size);
-       _uiRef = 0;
-       _usednodes = 0;
-       _delegate = NULL;
-       INIT_CHAIN();
-       ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
-}
-
-void SQTable::Remove(const SQObjectPtr &key)
-{
-       _HashNode *n = _Get(key, HashKey(key) & (_numofnodes - 1));
-       if (n) {
-               n->val = n->key = _null_;
-               _usednodes--;
-               Rehash(false);
-       }
-}
-
-void SQTable::AllocNodes(int nSize)
-{
-       _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
-       for(int i=0;i<nSize;i++){
-               new (&nodes[i]) _HashNode;
-               nodes[i].next=NULL;
-       }
-       _numofnodes=nSize;
-       _nodes=nodes;
-       _firstfree=&_nodes[_numofnodes-1];
-}
-
-int SQTable::CountUsed()
-{
-       /*int n=0;
-       for(int i=0;i<_numofnodes;i++){
-               if(type(_nodes[i].key)!=OT_NULL) n++;
-       }*/
-       return _usednodes;
-}
-
-void SQTable::Rehash(bool force)
-{
-       int oldsize=_numofnodes;
-       //prevent problems with the integer division
-       if(oldsize<4)oldsize=4;
-       _HashNode *nold=_nodes;
-       int nelems=CountUsed();
-       if (nelems >= oldsize-oldsize/4)  /* using more than 3/4? */
-               AllocNodes(oldsize*2);
-       else if (nelems <= oldsize/4 &&  /* less than 1/4? */
-               oldsize > MINPOWER2)
-               AllocNodes(oldsize/2);
-       else if(force)
-               AllocNodes(oldsize);
-       else
-               return;
-       _usednodes = 0;
-       for (int i=0; i<oldsize; i++) {
-               _HashNode *old = nold+i;
-               if (type(old->key) != OT_NULL)
-                       NewSlot(old->key,old->val);
-       }
-       for(int k=0;k<oldsize;k++) 
-               nold[k].~_HashNode();
-       SQ_FREE(nold,oldsize*sizeof(_HashNode));
-}
-
-SQTable *SQTable::Clone()
-{
-       SQTable *nt=Create(_opt_ss(this),_numofnodes);
-       SQInteger ridx=0;
-       SQObjectPtr key,val;
-       while((ridx=Next(ridx,key,val))!=-1){
-               nt->NewSlot(key,val);
-       }
-       nt->SetDelegate(_delegate);
-       return nt;
-}
-
-bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
-{
-       _HashNode *n = _Get(key, HashKey(key) & (_numofnodes - 1));
-       if (n) {
-               val = n->val;
-               return true;
-       }
-       return false;
-}
-bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
-{
-       unsigned long h = HashKey(key) & (_numofnodes - 1);
-       _HashNode *n = _Get(key, h);
-       if (n) {
-               n->val = val;
-               return false;
-       }
-       _HashNode *mp = &_nodes[h];
-       n = mp;
-
-       //key not found I'll insert it
-       //main pos is not free
-
-       if(type(mp->key)!=OT_NULL) {
-
-               _HashNode *othern;  /* main position of colliding node */
-               n = _firstfree;  /* get a free place */
-               if (mp > n && (othern = &_nodes[h]) != mp){
-                       /* yes; move colliding node into free position */
-                       while (othern->next != mp)
-                               othern = othern->next;  /* find previous */
-                       othern->next = n;  /* redo the chain with `n' in place of `mp' */
-                       *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
-                       mp->next = NULL;  /* now `mp' is free */
-               }
-               else{
-                       /* new node will go into free position */
-                       n->next = mp->next;  /* chain new position */
-                       mp->next = n;
-                       mp = n;
-               }
-       }
-       mp->key = key;
-
-       for (;;) {  /* correct `firstfree' */
-               if (type(_firstfree->key) == OT_NULL) {
-                       mp->val = val;
-                       _usednodes++;
-                       return true;  /* OK; table still has a free place */
-               }
-               else if (_firstfree == _nodes) break;  /* cannot decrement from here */
-               else (_firstfree)--;
-       }
-       Rehash(true);
-       return NewSlot(key, val);
-}
-
-int SQTable::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
-       int idx = (int)TranslateIndex(refpos);
-       while (idx < _numofnodes) {
-               if(type(_nodes[idx].key) != OT_NULL) {
-                       //first found
-                       outkey = _nodes[idx].key;
-                       outval = _nodes[idx].val;
-                       //return idx for the next iteration
-                       return ++idx;
-               }
-               ++idx;
-       }
-       //nothing to iterate anymore
-       return -1;
-}
-
-bool SQTable::SetDelegate(SQTable *mt)
-{
-       SQTable *temp = mt;
-       while (temp) {
-               if (temp->_delegate == this) return false; //cycle detected
-               temp = temp->_delegate;
-       }
-       if (mt) __ObjAddRef(mt);
-       __ObjRelease(_delegate);
-       _delegate = mt;
-       return true;
-}
-
-bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
-{
-       _HashNode *n = _Get(key, HashKey(key) & (_numofnodes - 1));
-       if (n) {
-               n->val = val;
-               return true;
-       }
-       return false;
-}
-
-void SQTable::Finalize()
-{
-       for(int i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }
-               SetDelegate(NULL);
-}
+/*\r
+see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include "sqvm.h"\r
+#include "sqtable.h"\r
+#include "sqfuncproto.h"\r
+#include "sqclosure.h"\r
+\r
+SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)\r
+{\r
+       SQInteger pow2size=MINPOWER2;\r
+       while(nInitialSize>pow2size)pow2size=pow2size<<1;\r
+       AllocNodes(pow2size);\r
+       _usednodes = 0;\r
+       _delegate = NULL;\r
+       INIT_CHAIN();\r
+       ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);\r
+}\r
+\r
+void SQTable::Remove(const SQObjectPtr &key)\r
+{\r
+       _HashNode *n = _Get(key, HashKey(key) & (_numofnodes - 1));\r
+       if (n) {\r
+               n->val = n->key = _null_;\r
+               _usednodes--;\r
+               Rehash(false);\r
+       }\r
+}\r
+\r
+void SQTable::AllocNodes(SQInteger nSize)\r
+{\r
+       _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);\r
+       for(SQInteger i=0;i<nSize;i++){\r
+               new (&nodes[i]) _HashNode;\r
+               nodes[i].next=NULL;\r
+       }\r
+       _numofnodes=nSize;\r
+       _nodes=nodes;\r
+       _firstfree=&_nodes[_numofnodes-1];\r
+}\r
+\r
+void SQTable::Rehash(bool force)\r
+{\r
+       SQInteger oldsize=_numofnodes;\r
+       //prevent problems with the integer division\r
+       if(oldsize<4)oldsize=4;\r
+       _HashNode *nold=_nodes;\r
+       SQInteger nelems=CountUsed();\r
+       if (nelems >= oldsize-oldsize/4)  /* using more than 3/4? */\r
+               AllocNodes(oldsize*2);\r
+       else if (nelems <= oldsize/4 &&  /* less than 1/4? */\r
+               oldsize > MINPOWER2)\r
+               AllocNodes(oldsize/2);\r
+       else if(force)\r
+               AllocNodes(oldsize);\r
+       else\r
+               return;\r
+       _usednodes = 0;\r
+       for (SQInteger i=0; i<oldsize; i++) {\r
+               _HashNode *old = nold+i;\r
+               if (type(old->key) != OT_NULL)\r
+                       NewSlot(old->key,old->val);\r
+       }\r
+       for(SQInteger k=0;k<oldsize;k++) \r
+               nold[k].~_HashNode();\r
+       SQ_FREE(nold,oldsize*sizeof(_HashNode));\r
+}\r
+\r
+SQTable *SQTable::Clone()\r
+{\r
+       SQTable *nt=Create(_opt_ss(this),_numofnodes);\r
+       SQInteger ridx=0;\r
+       SQObjectPtr key,val;\r
+       while((ridx=Next(true,ridx,key,val))!=-1){\r
+               nt->NewSlot(key,val);\r
+       }\r
+       nt->SetDelegate(_delegate);\r
+       return nt;\r
+}\r
+\r
+bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)\r
+{\r
+       _HashNode *n = _Get(key, HashKey(key) & (_numofnodes - 1));\r
+       if (n) {\r
+               val = _realval(n->val);\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)\r
+{\r
+       SQHash h = HashKey(key) & (_numofnodes - 1);\r
+       _HashNode *n = _Get(key, h);\r
+       if (n) {\r
+               n->val = val;\r
+               return false;\r
+       }\r
+       _HashNode *mp = &_nodes[h];\r
+       n = mp;\r
+\r
+       //key not found I'll insert it\r
+       //main pos is not free\r
+\r
+       if(type(mp->key)!=OT_NULL) {\r
+\r
+               _HashNode *othern;  /* main position of colliding node */\r
+               n = _firstfree;  /* get a free place */\r
+               if (mp > n && (othern = &_nodes[h]) != mp){\r
+                       /* yes; move colliding node into free position */\r
+                       while (othern->next != mp)\r
+                               othern = othern->next;  /* find previous */\r
+                       othern->next = n;  /* redo the chain with `n' in place of `mp' */\r
+                       *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */\r
+                       mp->next = NULL;  /* now `mp' is free */\r
+               }\r
+               else{\r
+                       /* new node will go into free position */\r
+                       n->next = mp->next;  /* chain new position */\r
+                       mp->next = n;\r
+                       mp = n;\r
+               }\r
+       }\r
+       mp->key = key;\r
+\r
+       for (;;) {  /* correct `firstfree' */\r
+               if (type(_firstfree->key) == OT_NULL) {\r
+                       mp->val = val;\r
+                       _usednodes++;\r
+                       return true;  /* OK; table still has a free place */\r
+               }\r
+               else if (_firstfree == _nodes) break;  /* cannot decrement from here */\r
+               else (_firstfree)--;\r
+       }\r
+       Rehash(true);\r
+       return NewSlot(key, val);\r
+}\r
+\r
+SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
+{\r
+       SQInteger idx = (SQInteger)TranslateIndex(refpos);\r
+       while (idx < _numofnodes) {\r
+               if(type(_nodes[idx].key) != OT_NULL) {\r
+                       //first found\r
+                       _HashNode &n = _nodes[idx];\r
+                       outkey = n.key;\r
+                       outval = getweakrefs?(SQObject)n.val:_realval(n.val);\r
+                       //return idx for the next iteration\r
+                       return ++idx;\r
+               }\r
+               ++idx;\r
+       }\r
+       //nothing to iterate anymore\r
+       return -1;\r
+}\r
+\r
+\r
+bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)\r
+{\r
+       _HashNode *n = _Get(key, HashKey(key) & (_numofnodes - 1));\r
+       if (n) {\r
+               n->val = val;\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+void SQTable::Finalize()\r
+{\r
+       for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }\r
+               SetDelegate(NULL);\r
+}\r
index 820639c..141261f 100644 (file)
@@ -1,88 +1,86 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQTABLE_H_
-#define _SQTABLE_H_
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_ltable.c.html
-*/
-
-#include "sqstring.h"
-
-#define hashptr(p)  (((unsigned long)(p)) >> 3)
-
-struct SQTable : public SQDelegable 
-{
-private:
-       struct _HashNode
-       {
-               SQObjectPtr val;
-               SQObjectPtr key;
-               _HashNode *next;
-       };
-       _HashNode *_firstfree;
-       _HashNode *_nodes;
-       int _numofnodes;
-       int _usednodes;
-       
-///////////////////////////
-       void AllocNodes(int nSize);
-       void Rehash(bool force);
-       SQTable(SQSharedState *ss, int nInitialSize);
-public:
-       static SQTable* Create(SQSharedState *ss,int nInitialSize)
-       {
-               SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
-               new (newtable) SQTable(ss, nInitialSize);
-               newtable->_delegate = NULL;
-               return newtable;
-       }
-       void Finalize();
-       SQTable *Clone();
-       ~SQTable()
-       {
-               SetDelegate(NULL);
-               REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
-               for (int i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
-               SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
-       }
-#ifndef NO_GARBAGE_COLLECTOR 
-       void Mark(SQCollectable **chain);
-#endif
-       inline unsigned long HashKey(const SQObjectPtr &key)
-       {
-               switch(type(key)){
-                       case OT_STRING:         return _string(key)->_hash;
-                       case OT_FLOAT:          return (unsigned long)((long)_float(key));
-                       case OT_INTEGER:        return (unsigned long)((long)_integer(key));
-                       default:                        return hashptr(key._unVal.pRefCounted);
-               }
-       }
-       inline _HashNode *_Get(const SQObjectPtr &key,unsigned long hash)
-       {
-               _HashNode *n = &_nodes[hash];
-               do{
-                       if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
-                               return n;
-                       }
-               }while(n = n->next);
-               return NULL;
-       }
-       bool Get(const SQObjectPtr &key,SQObjectPtr &val);
-       void Remove(const SQObjectPtr &key);
-       bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
-       //returns true if a new slot has been created false if it was already present
-       bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
-       int Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-       
-       int CountUsed();
-       void Release()
-       {
-               sq_delete(this, SQTable);
-       }
-       bool SetDelegate(SQTable *mt);
-       
-
-};
-
-#endif //_SQTABLE_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQTABLE_H_\r
+#define _SQTABLE_H_\r
+/*\r
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)\r
+* http://www.lua.org/copyright.html#4\r
+* http://www.lua.org/source/4.0.1/src_ltable.c.html\r
+*/\r
+\r
+#include "sqstring.h"\r
+\r
+#define hashptr(p)  (((SQHash)(p)) >> 3)\r
+\r
+struct SQTable : public SQDelegable \r
+{\r
+private:\r
+       struct _HashNode\r
+       {\r
+               SQObjectPtr val;\r
+               SQObjectPtr key;\r
+               _HashNode *next;\r
+       };\r
+       _HashNode *_firstfree;\r
+       _HashNode *_nodes;\r
+       SQInteger _numofnodes;\r
+       SQInteger _usednodes;\r
+       \r
+///////////////////////////\r
+       void AllocNodes(SQInteger nSize);\r
+       void Rehash(bool force);\r
+       SQTable(SQSharedState *ss, SQInteger nInitialSize);\r
+public:\r
+       static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)\r
+       {\r
+               SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));\r
+               new (newtable) SQTable(ss, nInitialSize);\r
+               newtable->_delegate = NULL;\r
+               return newtable;\r
+       }\r
+       void Finalize();\r
+       SQTable *Clone();\r
+       ~SQTable()\r
+       {\r
+               SetDelegate(NULL);\r
+               REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
+               for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();\r
+               SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));\r
+       }\r
+#ifndef NO_GARBAGE_COLLECTOR \r
+       void Mark(SQCollectable **chain);\r
+#endif\r
+       inline SQHash HashKey(const SQObjectPtr &key)\r
+       {\r
+               switch(type(key)){\r
+                       case OT_STRING:         return _string(key)->_hash;\r
+                       case OT_FLOAT:          return (SQHash)((SQInteger)_float(key));\r
+                       case OT_INTEGER:        return (SQHash)((SQInteger)_integer(key));\r
+                       default:                        return hashptr(key._unVal.pRefCounted);\r
+               }\r
+       }\r
+       inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)\r
+       {\r
+               _HashNode *n = &_nodes[hash];\r
+               do{\r
+                       if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){\r
+                               return n;\r
+                       }\r
+               }while(n = n->next);\r
+               return NULL;\r
+       }\r
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val);\r
+       void Remove(const SQObjectPtr &key);\r
+       bool Set(const SQObjectPtr &key, const SQObjectPtr &val);\r
+       //returns true if a new slot has been created false if it was already present\r
+       bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);\r
+       SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
+       \r
+       SQInteger CountUsed(){ return _usednodes;}\r
+       void Release()\r
+       {\r
+               sq_delete(this, SQTable);\r
+       }\r
+       \r
+};\r
+\r
+#endif //_SQTABLE_H_\r
index d9c6d51..8fe0411 100644 (file)
@@ -1,45 +1,38 @@
-/*     see copyright notice in squirrel.h */
-#ifndef _SQUSERDATA_H_
-#define _SQUSERDATA_H_
-
-struct SQUserData : SQDelegable
-{
-       SQUserData(SQSharedState *ss){ _uiRef = 0; _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
-       ~SQUserData()
-       {
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
-               SetDelegate(NULL);
-       }
-       static SQUserData* Create(SQSharedState *ss, int size)
-       {
-               SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));
-               new (ud) SQUserData(ss);
-               ud->_size = size;
-               ud->_typetag = 0;
-               return ud;
-       }
-#ifndef NO_GARBAGE_COLLECTOR
-       void Mark(SQCollectable **chain);
-       void Finalize(){SetDelegate(NULL);}
-#endif
-       void Release() {
-               if (_hook) _hook(_val,_size);
-               int tsize = _size - 1;
-               this->~SQUserData();
-               SQ_FREE(this, sizeof(SQUserData) + tsize);
-       }
-       void SetDelegate(SQTable *mt)
-       {
-               if (mt) __ObjAddRef(mt);
-               __ObjRelease(_delegate);
-               _delegate = mt;
-       }
-
-       
-       int _size;
-       SQRELEASEHOOK _hook;
-       unsigned int _typetag;
-       SQChar _val[1];
-};
-
-#endif //_SQUSERDATA_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQUSERDATA_H_\r
+#define _SQUSERDATA_H_\r
+\r
+struct SQUserData : SQDelegable\r
+{\r
+       SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }\r
+       ~SQUserData()\r
+       {\r
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);\r
+               SetDelegate(NULL);\r
+       }\r
+       static SQUserData* Create(SQSharedState *ss, SQInteger size)\r
+       {\r
+               SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));\r
+               new (ud) SQUserData(ss);\r
+               ud->_size = size;\r
+               ud->_typetag = 0;\r
+               return ud;\r
+       }\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       void Mark(SQCollectable **chain);\r
+       void Finalize(){SetDelegate(NULL);}\r
+#endif\r
+       void Release() {\r
+               if (_hook) _hook(_val,_size);\r
+               SQInteger tsize = _size - 1;\r
+               this->~SQUserData();\r
+               SQ_FREE(this, sizeof(SQUserData) + tsize);\r
+       }\r
+               \r
+       SQInteger _size;\r
+       SQRELEASEHOOK _hook;\r
+       SQUserPointer _typetag;\r
+       SQChar _val[1];\r
+};\r
+\r
+#endif //_SQUSERDATA_H_\r
index 71938fa..86456ba 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQUTILS_H_
-#define _SQUTILS_H_
-
-#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);
-
-//sqvector mini vector class, supports objects by value
-template<typename T> class sqvector
-{
-public:
-       sqvector()
-       {
-               _vals = NULL;
-               _size = 0;
-               _allocated = 0;
-       }
-       sqvector(const sqvector<T>& v)
-       {
-               copy(v);
-       }
-       void copy(const sqvector<T>& v)
-       {
-               resize(v._size);
-               for(unsigned int i = 0; i < v._size; i++) {
-                       new ((void *)&_vals[i]) T(v._vals[i]);
-               }
-               _size = v._size;
-       }
-       ~sqvector()
-       {
-               if(_allocated) {
-                       for(unsigned int i = 0; i < _size; i++)
-                               _vals[i].~T();
-                       SQ_FREE(_vals, (_allocated * sizeof(T)));
-               }
-       }
-       void reserve(unsigned int newsize) { _realloc(newsize); }
-       void resize(unsigned int newsize, const T& fill = T())
-       {
-               if(newsize > _allocated)
-                       _realloc(newsize);
-               if(newsize > _size) {
-                       while(_size < newsize) {
-                               new ((void *)&_vals[_size]) T(fill);
-                               _size++;
-                       }
-               }
-               else{
-                       for(unsigned int i = newsize; i < _size; i++) {
-                               _vals[i].~T();
-                       }
-                       _size = newsize;
-               }
-       }
-       void shrinktofit() { if(_size > 4) { _realloc(_size); } }
-       T& top() const { return _vals[_size - 1]; }
-       inline unsigned int size() const { return _size; }
-       bool empty() const { return (_size <= 0); }
-       inline T &push_back(const T& val = T())
-       {
-               if(_allocated <= _size)
-                       _realloc(_size * 2);
-               return *(new ((void *)&_vals[_size++]) T(val));
-       }
-       inline void pop_back()
-       {
-               _size--; _vals[_size].~T();
-       }
-       void insert(unsigned int idx, const T& val)
-       {
-               resize(_size + 1);
-               for(unsigned int i = _size - 1; i > idx; i--) {
-                       _vals[i] = _vals[i - 1];
-               }
-       _vals[idx] = val;
-       }
-       void remove(unsigned int idx)
-       {
-               _vals[idx].~T();
-               if(idx < (_size - 1)) {
-                       memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
-               }
-               _size--;
-       }
-       unsigned int capacity() { return _allocated; }
-       inline T &back() const { return _vals[_size - 1]; }
-       inline T& operator[](unsigned int pos) const{ return _vals[pos]; }
-       T* _vals;
-private:
-       void _realloc(unsigned int newsize)
-       {
-               newsize = (newsize > 0)?newsize:4;
-               _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
-               _allocated = newsize;
-       }
-       unsigned int _size;
-       unsigned int _allocated;
-};
-
-#endif //_SQUTILS_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQUTILS_H_\r
+#define _SQUTILS_H_\r
+\r
+#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}\r
+#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}\r
+#define SQ_MALLOC(__size) sq_vm_malloc(__size);\r
+#define SQ_FREE(__ptr,__size) sq_vm_free(__ptr,__size);\r
+#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc(__ptr,__oldsize,__size);\r
+\r
+//sqvector mini vector class, supports objects by value\r
+template<typename T> class sqvector\r
+{\r
+public:\r
+       sqvector()\r
+       {\r
+               _vals = NULL;\r
+               _size = 0;\r
+               _allocated = 0;\r
+       }\r
+       sqvector(const sqvector<T>& v)\r
+       {\r
+               copy(v);\r
+       }\r
+       void copy(const sqvector<T>& v)\r
+       {\r
+               resize(v._size);\r
+               for(SQUnsignedInteger i = 0; i < v._size; i++) {\r
+                       new ((void *)&_vals[i]) T(v._vals[i]);\r
+               }\r
+               _size = v._size;\r
+       }\r
+       ~sqvector()\r
+       {\r
+               if(_allocated) {\r
+                       for(SQUnsignedInteger i = 0; i < _size; i++)\r
+                               _vals[i].~T();\r
+                       SQ_FREE(_vals, (_allocated * sizeof(T)));\r
+               }\r
+       }\r
+       void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }\r
+       void resize(SQUnsignedInteger newsize, const T& fill = T())\r
+       {\r
+               if(newsize > _allocated)\r
+                       _realloc(newsize);\r
+               if(newsize > _size) {\r
+                       while(_size < newsize) {\r
+                               new ((void *)&_vals[_size]) T(fill);\r
+                               _size++;\r
+                       }\r
+               }\r
+               else{\r
+                       for(SQUnsignedInteger i = newsize; i < _size; i++) {\r
+                               _vals[i].~T();\r
+                       }\r
+                       _size = newsize;\r
+               }\r
+       }\r
+       void shrinktofit() { if(_size > 4) { _realloc(_size); } }\r
+       T& top() const { return _vals[_size - 1]; }\r
+       inline SQUnsignedInteger size() const { return _size; }\r
+       bool empty() const { return (_size <= 0); }\r
+       inline T &push_back(const T& val = T())\r
+       {\r
+               if(_allocated <= _size)\r
+                       _realloc(_size * 2);\r
+               return *(new ((void *)&_vals[_size++]) T(val));\r
+       }\r
+       inline void pop_back()\r
+       {\r
+               _size--; _vals[_size].~T();\r
+       }\r
+       void insert(SQUnsignedInteger idx, const T& val)\r
+       {\r
+               resize(_size + 1);\r
+               for(SQUnsignedInteger i = _size - 1; i > idx; i--) {\r
+                       _vals[i] = _vals[i - 1];\r
+               }\r
+       _vals[idx] = val;\r
+       }\r
+       void remove(SQUnsignedInteger idx)\r
+       {\r
+               _vals[idx].~T();\r
+               if(idx < (_size - 1)) {\r
+                       memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));\r
+               }\r
+               _size--;\r
+       }\r
+       SQUnsignedInteger capacity() { return _allocated; }\r
+       inline T &back() const { return _vals[_size - 1]; }\r
+       inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }\r
+       T* _vals;\r
+private:\r
+       void _realloc(SQUnsignedInteger newsize)\r
+       {\r
+               newsize = (newsize > 0)?newsize:4;\r
+               _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));\r
+               _allocated = newsize;\r
+       }\r
+       SQUnsignedInteger _size;\r
+       SQUnsignedInteger _allocated;\r
+};\r
+\r
+#endif //_SQUTILS_H_\r
index 725cad0..3137b0a 100644 (file)
-/*
-       see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <math.h>
-#include <stdlib.h>
-#include "sqopcodes.h"
-#include "sqfuncproto.h"
-#include "sqvm.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqarray.h"
-#include "sqclass.h"
-
-#define TOP() (_stack[_top-1])
-
-bool SQVM::BW_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
-       SQInteger res;
-       SQInteger i1 = _integer(o1), i2 = _integer(o2);
-       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))
-       {
-               switch(op) {
-                       case BW_AND:    res = i1 & i2; break;
-                       case BW_OR:             res = i1 | i2; break;
-                       case BW_XOR:    res = i1 ^ i2; break;
-                       case BW_SHIFTL: res = i1 << i2; break;
-                       case BW_SHIFTR: res = i1 >> i2; break;
-                       case BW_USHIFTR:res = (SQInteger)(*((unsigned int*)&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;
-}
-
-bool SQVM::ARITH_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
-       if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
-                       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {
-                               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); 
-                                       break;
-                               case '*': trg = _integer(o1) * _integer(o2); break;
-                               case '%': trg = _integer(o1) % _integer(o2); break;
-                               }
-                       }else{
-                               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;
-                               }
-                       }       
-               } 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; 
-                       }
-               }
-               return true;
-}
-
-SQObjectPtr &stack_get(HSQUIRRELVM v,int idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
-
-SQVM::SQVM(SQSharedState *ss)
-{
-       _sharedstate=ss;
-       _suspended = SQFalse;
-       _suspended_target=-1;
-       _suspended_root = SQFalse;
-       _suspended_traps=-1;
-       _foreignptr=NULL;
-       _nnativecalls=0;
-       _uiRef=0;
-       _lasterror = _null_;
-       _errorhandler = _null_;
-       _debughook = _null_;
-       INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-void SQVM::Finalize()
-{
-       _roottable = _null_;
-       _lasterror = _null_;
-       _errorhandler = _null_;
-       _debughook = _null_;
-       temp_reg = _null_;
-       int size=_stack.size();
-       for(int i=0;i<size;i++)
-               _stack[i]=_null_;
-}
-
-SQVM::~SQVM()
-{
-       Finalize();
-       REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-bool SQVM::ArithMetaMethod(int op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)
-{
-       SQMetaMethod mm;
-       switch(op){
-               case _SC('+'): mm=MT_ADD; break;
-               case _SC('-'): mm=MT_SUB; break;
-               case _SC('/'): mm=MT_DIV; break;
-               case _SC('*'): mm=MT_MUL; break;
-               case _SC('%'): mm=MT_MODULO; break;
-       }
-       if(is_delegable(o1) && _delegable(o1)->_delegate) {
-               Push(o1);Push(o2);
-               return CallMetaMethod(_delegable(o1),mm,2,dest);
-       }
-       return false;
-}
-
-bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
-{
-       
-       switch(type(o)) {
-       case OT_INTEGER:
-               trg = -_integer(o);
-               return true;
-       case OT_FLOAT:
-               trg = -_float(o);
-               return true;
-       case OT_TABLE:
-       case OT_USERDATA:
-       case OT_INSTANCE:
-               if(_delegable(o)->_delegate) {
-                       Push(o);
-                       if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {
-                               trg = temp_reg;
-                               return true;
-                       }
-               }
-               return true;
-
-       }
-       Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
-       return false;
-}
-
-#define _RET_SUCCEED(exp) { result = (exp); return true; } 
-bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,int &result)
-{
-       if(type(o1)==type(o2)){
-               if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);
-               SQObjectPtr res;
-               switch(type(o1)){
-               case OT_STRING:
-                       _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
-               case OT_INTEGER:
-                       _RET_SUCCEED(_integer(o1)-_integer(o2));
-               case OT_FLOAT:
-                       _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
-               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;
-               }
-               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( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }
-                               else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }
-                               _RET_SUCCEED(1);
-                       }
-                       else{
-                               if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }
-                               else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }
-                               _RET_SUCCEED(1);
-                       }
-               }
-               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
-}
-
-bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)
-{
-       int r;
-       if(ObjCmp(o1,o2,r)) {
-               switch(op) {
-                       case CMP_G: res = (r > 0)?_true_:_false_; return true;
-                       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);
-       }
-       return false;
-}
-
-bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
-{
-       switch(type(obj))
-       {
-       case OT_STRING:
-               switch(type(str)){
-               case OT_STRING: {
-                       int l=_string(str)->_len,ol=_string(obj)->_len;
-                       SQChar *s=_sp(rsl(l+ol+1));
-                       memcpy(s,_stringval(str),rsl(l));memcpy(s+l,_stringval(obj),rsl(ol));s[l+ol]=_SC('\0');
-                       break;
-               }
-               case OT_FLOAT:
-                       scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(obj)->_len+1)),_SC("%g%s"),_float(str),_stringval(obj));
-                       break;
-               case OT_INTEGER:
-                       scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(obj)->_len+1)),_SC("%d%s"),_integer(str),_stringval(obj));
-                       break;
-               default:
-                       Raise_Error(_SC("string concatenation between '%s' and '%s'"),GetTypeName(str),GetTypeName(obj));
-                       return false;
-               }
-               dest=SQString::Create(_ss(this),_spval);
-               break;
-       case OT_FLOAT:
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(str)->_len+1)),_SC("%s%g"),_stringval(str),_float(obj));
-               dest=SQString::Create(_ss(this),_spval);
-               break;
-       case OT_INTEGER:
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(str)->_len+1)),_SC("%s%d"),_stringval(str),_integer(obj));
-               dest=SQString::Create(_ss(this),_spval);
-               break;
-       default:
-               Raise_Error(_SC("string concatenation between '%s' and '%s'"),GetTypeName(str),GetTypeName(obj));
-               return false;
-       }
-       return true;
-}
-
-const SQChar *IdType2Name(SQObjectType type)
-{
-       switch(_RAW_TYPE(type))
-       {
-       case _RT_NULL:return _SC("null");
-       case _RT_INTEGER:return _SC("integer");
-       case _RT_FLOAT:return _SC("float");
-       case _RT_BOOL:return _SC("bool");
-       case _RT_STRING:return _SC("string");
-       case _RT_TABLE:return _SC("table");
-       case _RT_ARRAY:return _SC("array");
-       case _RT_GENERATOR:return _SC("generator");
-       case _RT_CLOSURE:
-       case _RT_NATIVECLOSURE:
-               return _SC("function");
-       case _RT_USERDATA:
-       case _RT_USERPOINTER:
-               return _SC("userdata");
-       case _RT_THREAD: return _SC("thread");
-       case _RT_FUNCPROTO: return _SC("function");
-       case _RT_CLASS: return _SC("class");
-       case _RT_INSTANCE: return _SC("instance");
-       default:
-               return NULL;
-       }
-}
-
-const SQChar *GetTypeName(const SQObjectPtr &obj1)
-{
-       return IdType2Name(type(obj1)); 
-}
-
-void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
-{
-       if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
-               Push(obj1);
-               if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))
-                       return;
-       }
-       dest = SQString::Create(_ss(this),GetTypeName(obj1));
-}
-
-bool SQVM::Init(SQVM *friendvm, int stacksize)
-{
-       _stack.resize(stacksize);
-       _callsstack.reserve(4);
-       _stackbase = 0;
-       _top = 0;
-       if(!friendvm) 
-               _roottable = SQTable::Create(_ss(this), 0);
-       else {
-               _roottable = friendvm->_roottable;
-               _errorhandler = friendvm->_errorhandler;
-               _debughook = friendvm->_debughook;
-       }
-       
-       sq_base_register(this);
-       return true;
-}
-
-extern SQInstructionDesc g_InstrDesc[];
-
-bool SQVM::StartCall(SQClosure *closure,int target,int nargs,int stackbase,bool tailcall)
-{
-       SQFunctionProto *func = _funcproto(closure->_function);
-       //const int outerssize = func->_outervalues.size();
-
-       const int paramssize = func->_parameters.size();
-       const int oldtop = _top;
-       const int newtop = stackbase + func->_stacksize;
-       
-       
-       if(func->_varparams)
-       {
-               if (nargs < paramssize) {
-                       Raise_Error(_SC("wrong number of parameters"));
-                       return false;
-               }
-               for(int n = 0; n < nargs - paramssize; n++) {
-                       _vargsstack.push_back(_stack[stackbase+paramssize+n]);
-                       _stack[stackbase+paramssize+n] = _null_;
-               }
-       }
-       else {
-               if (paramssize != nargs) {
-                       Raise_Error(_SC("wrong number of parameters"));
-                       return false;
-               }
-               
-       }
-       
-       if (!tailcall) {
-               PUSH_CALLINFO(this, CallInfo());
-               ci->_etraps = 0;
-               ci->_prevstkbase = stackbase - _stackbase;
-               ci->_target = target;
-               ci->_prevtop = _top - _stackbase;
-               ci->_ncalls = 1;
-               ci->_root = SQFalse;
-       }
-       else {
-               ci->_ncalls++;
-       }
-       ci->_vargs.size = (nargs - paramssize);
-       ci->_vargs.base = _vargsstack.size()-(nargs - paramssize);
-       ci->_closure._unVal.pClosure = closure;
-       ci->_closure._type = OT_CLOSURE;
-       ci->_iv = &func->_instructions;
-       ci->_literals = &func->_literals;
-       //grows the stack if needed
-       if (((unsigned int)newtop + (func->_stacksize<<1)) > _stack.size()) {
-               _stack.resize(_stack.size() + (func->_stacksize<<1));
-       }
-               
-       _top = newtop;
-       _stackbase = stackbase;
-       ci->_ip = ci->_iv->_vals;
-       return true;
-}
-
-bool SQVM::Return(int _arg0, int _arg1, SQObjectPtr &retval)
-{
-       if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
-               for(int i=0;i<ci->_ncalls;i++)
-                       CallDebugHook(_SC('r'));
-                                               
-       SQBool broot = ci->_root;
-       int last_top = _top;
-       int target = ci->_target;
-       int oldstackbase = _stackbase;
-       _stackbase -= ci->_prevstkbase;
-       _top = _stackbase + ci->_prevtop;
-       if(ci->_vargs.size) PopVarArgs(ci->_vargs);
-       POP_CALLINFO(this);
-       if (broot) {
-               if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack[oldstackbase+_arg1];
-               else retval = _null_;
-       }
-       else {
-               if (_arg0 != MAX_FUNC_STACKSIZE)
-                       STK(target) = _stack[oldstackbase+_arg1];
-               else
-                       STK(target) = _null_;
-       }
-
-       while (last_top >= _top) _stack[last_top--].Null();
-       assert(oldstackbase >= _stackbase); 
-       return broot?true:false;
-}
-
-#define _RET_ON_FAIL(exp) { if(!exp) return false; }
-
-bool SQVM::LOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
-       _RET_ON_FAIL(ARITH_OP( op , target, a, incr));
-       a = target;
-       return true;
-}
-
-bool SQVM::PLOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
-       SQObjectPtr trg;
-       _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));
-       target = a;
-       a = trg;
-       return true;
-}
-
-bool SQVM::DerefInc(int op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)
-{
-       SQObjectPtr tmp, tself = self, tkey = key;
-       if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }
-       _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
-       Set(tself, tkey, target,true);
-       if (postfix) target = tmp;
-       return true;
-}
-
-#define arg0 (_i_._arg0)
-#define arg1 (_i_._arg1)
-#define sarg1 (*((int *)&_i_._arg1))
-#define arg2 (_i_._arg2)
-#define arg3 (_i_._arg3)
-#define sarg3 (*((char *)&_i_._arg3))
-
-SQRESULT SQVM::Suspend()
-{
-       if (_suspended)
-               return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));
-       if (_nnativecalls!=2)
-               return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));
-       return SQ_SUSPEND_FLAG;
-}
-
-void SQVM::PopVarArgs(VarArgs &vargs)
-{
-       for(int n = 0; n< vargs.size; n++)
-               _vargsstack.pop_back();
-}
-
-#define _FINISH(stoploop) {finished = stoploop; return true; }
-bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr 
-&o3,SQObjectPtr &o4,int arg_2,bool &finished)
-{
-       int nrefidx;
-       switch(type(o1)) {
-       case OT_TABLE:
-               if((nrefidx = _table(o1)->Next(o4, o2, o3)) == -1) _FINISH(true);
-               o4 = (SQInteger)nrefidx; _FINISH(false);
-       case OT_ARRAY:
-               if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(true);
-               o4 = (SQInteger) nrefidx; _FINISH(false);
-       case OT_STRING:
-               if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);
-               o4 = (SQInteger)nrefidx; _FINISH(false);
-       case OT_CLASS:
-               if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);
-               o4 = (SQInteger)nrefidx; _FINISH(false);
-       case OT_USERDATA:
-       case OT_INSTANCE:
-               if(_delegable(o1)->_delegate) {
-                       SQObjectPtr itr;
-                       Push(o1);
-                       Push(o4);
-                       if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){
-                               o4 = o2 = itr;
-                               if(type(itr) == OT_NULL) _FINISH(true);
-                               if(!Get(o1, itr, o3, false,false)) {
-                                       Raise_Error(_SC("_nexti returned an invalid idx"));
-                                       return false;
-                               }
-                               _FINISH(false);
-                       }
-                       Raise_Error(_SC("_nexti failed"));
-                       return false;
-               }
-               break;
-       case OT_GENERATOR:
-               if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(true);
-               if(_generator(o1)->_state == SQGenerator::eSuspended) {
-                       SQInteger idx = 0;
-                       if(type(o4) == OT_INTEGER) {
-                               idx = _integer(o4) + 1;
-                       }
-                       o2 = idx;
-                       o4 = idx;
-                       _generator(o1)->Resume(this, arg_2+1);
-                       _FINISH(false);
-               }
-       }
-       Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
-       return false; //cannot be hit(just to avoid warnings)
-}
-
-bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
-{
-       if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }
-       switch(type(o2)) {
-       case OT_TABLE:
-               if(!_table(o1)->SetDelegate(_table(o2))){
-                       Raise_Error(_SC("delegate cycle detected"));
-                       return false;
-               }
-               break;
-       case OT_NULL:
-               _table(o1)->SetDelegate(NULL);
-               break;
-       default:
-               Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));
-               return false;
-               break;
-       }
-       trg = o1;
-       return true;
-}
-#define COND_LITERAL (arg3!=0?(*ci->_literals)[arg1]:STK(arg1))
-
-#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }
-
-#define SQ_THROW() { goto exception_trap; }
-
-bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
-{
-       int nouters;
-       SQClosure *closure = SQClosure::Create(_ss(this), func);
-       if(nouters = func->_outervalues.size()) {
-               closure->_outervalues.reserve(nouters);
-               for(int i = 0; i<nouters; i++) {
-                       SQOuterVar &v = func->_outervalues[i];
-                       switch(v._type){
-                       case otSYMBOL:
-                               closure->_outervalues.push_back(_null_);
-                               if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))
-                               {Raise_IdxError(v._src); return false; }
-                               break;
-                       case otLOCAL:
-                               closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);
-                               break;
-                       case otOUTER:
-                               closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);
-                               break;
-                       }
-               }
-       }
-       target = closure;
-       return true;
-
-}
-
-bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
-{
-       if(ci->_vargs.size == 0) {
-               Raise_Error(_SC("the function doesn't have var args"));
-               return false;
-       }
-       if(!sq_isnumeric(index)){
-               Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));
-               return false;
-       }
-       int idx = tointeger(index);
-       if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }
-       target = _vargsstack[ci->_vargs.base+idx];
-       return true;
-}
-
-bool SQVM::CLASS_OP(SQObjectPtr &target,int baseclass,int attributes)
-{
-       SQClass *base = NULL;
-       SQObjectPtr attrs;
-       if(baseclass != MAX_LITERALS) {
-               if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
-               base = _class(_stack._vals[_stackbase + baseclass]);
-       }
-       if(attributes != MAX_FUNC_STACKSIZE) {
-               attrs = _stack._vals[_stackbase+attributes];
-       }
-       target = SQClass::Create(_ss(this),base);
-       _class(target)->_attributes = attrs;
-       return true;
-}
-
-bool SQVM::IsFalse(SQObjectPtr &o)
-{
-       SQObjectType t = type(o);
-       if((t & SQOBJECT_CANBEFALSE)
-               && ((t == OT_NULL) || ((t == OT_INTEGER || t == OT_BOOL) && _integer(o) == 0)
-               || (t == OT_FLOAT && _float(o) == SQFloat(0.0)))) {
-                       return true;
-               }
-       return false;
-}
-
-bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
-{
-       if(type(o1) == type(o2)) {
-               res = ((_userpointer(o1) == _userpointer(o2)?true:false));
-       }
-       else {
-               if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
-                       int cmpres;
-                       if(!ObjCmp(o1, o2,cmpres)) return false;
-                       res = (cmpres == 0);
-               }
-               else {
-                       res = false;
-               }
-       }
-       return true;
-}
-
-bool SQVM::Execute(SQObjectPtr &closure, int target, int nargs, int stackbase,SQObjectPtr &outres, ExecutionType et)
-{
-       if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
-       _nnativecalls++;
-       AutoDec ad(&_nnativecalls);
-       int traps = 0;
-       //temp_reg vars for OP_CALL
-       int ct_target;
-       bool ct_tailcall; 
-
-       switch(et) {
-               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;
-                       }
-                       ci->_root = SQTrue;
-                       break;
-               case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
-               case ET_RESUME_VM:
-                       traps = _suspended_traps;
-                       ci->_root = _suspended_root;
-                       _suspended = SQFalse;
-                       break;
-       }
-       
-exception_restore:
-       //
-       {
-               for(;;)
-               {
-                       const SQInstruction &_i_ = *ci->_ip++;
-                       //dumpstack(_stackbase);
-                       //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
-                       switch(_i_.op)
-                       {
-                       case _OP_LINE:
-                               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_TAILCALL:
-                               temp_reg = STK(arg1);
-                               if (type(temp_reg) == OT_CLOSURE){ 
-                                       ct_tailcall = true;
-                                       if(ci->_vargs.size) PopVarArgs(ci->_vargs);
-                                       for (int i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
-                                       ct_target = ci->_target;
-                                       goto common_call;
-                               }
-                       case _OP_CALL: {
-                                       ct_tailcall = false;
-                                       ct_target = arg0;
-                                       temp_reg = STK(arg1);
-common_call:
-                                       int 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));
-                                               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();
-                                                       continue;
-                                               }
-                                               if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
-                                                       CallDebugHook(_SC('c'));
-                                               }
-                                               break;
-                                       case OT_NATIVECLOSURE: {
-                                               bool suspend;
-                                               _GUARD(CallNative(_nativeclosure(temp_reg), arg3, _stackbase+arg2, ct_tailcall, temp_reg,suspend));
-                                               if(suspend){
-                                                       _suspended = SQTrue;
-                                                       _suspended_target = ct_target;
-                                                       _suspended_root = ci->_root;
-                                                       _suspended_traps = traps;
-                                                       outres = temp_reg;
-                                                       return true;
-                                               }
-                                               STK(ct_target) = temp_reg;
-                                                                                  }
-                                               break;
-                                       case OT_CLASS:{
-                                               _GUARD(CreateClassInstance(_class(temp_reg),arg3,_stackbase+arg2,STK(ct_target)));
-                                               }
-                                               break;
-                                       case OT_TABLE:
-                                       case OT_USERDATA:
-                                       case OT_INSTANCE:
-                                               {
-                                               Push(temp_reg);
-                                               for (int i = 0; i < arg3; i++) Push(STK(arg2 + i));
-                                               if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){
-                                                       STK(ct_target) = temp_reg;
-                                                       break;
-                                               }
-                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
-                                               SQ_THROW();
-                                         }
-                                       default:
-                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
-                                               SQ_THROW();
-                                       }
-                               }
-                                 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);
-                                                               TARGET = temp_reg;
-                                                               continue;
-                                                       }
-                                               }
-                                               { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();}
-                                       }
-common_prepcall:
-                                       if(type(STK(arg2)) == OT_CLASS) {
-                                               STK(arg3) = STK(0); // this
-                                       }
-                                       else {
-                                               STK(arg3) = STK(arg2);
-                                       }
-                                       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();}
-                               TARGET = temp_reg;
-                               continue;
-                       case _OP_MOVE: TARGET = STK(arg1); continue;
-                       case _OP_NEWSLOT:
-                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3)));
-                               if(arg0 != arg3) TARGET = STK(arg3);
-                               continue;
-                       case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;
-                       case _OP_SET:
-                               if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
-                               if (arg0 != arg3) TARGET = STK(arg3);
-                               continue;
-                       case _OP_GET:
-                               if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
-                               TARGET = temp_reg;
-                               continue;
-                       case _OP_EQ:{
-                               bool res;
-                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
-                               TARGET = res?_true_:_false_;
-                               }continue;
-                       case _OP_NE:{ 
-                               bool res;
-                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
-                               TARGET = (!res)?_true_:_false_;
-                               } continue;
-                       case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;
-                       case _OP_BITW:  _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;
-                       case _OP_RETURN:
-                               if(type((ci)->_generator) == OT_GENERATOR) {
-                                       _generator((ci)->_generator)->Kill();
-                               }
-                               if(Return(arg0, arg1, temp_reg)){
-                                       assert(traps==0);
-                                       outres = temp_reg;
-                                       return true;
-                               }
-                               continue;
-                       case _OP_LOADNULLS:{ for(unsigned int n=0;n<arg1;n++) STK(arg0+n) = _null_; }continue;
-                       case _OP_LOADROOTTABLE: TARGET = _roottable; continue;
-                       case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;
-                       case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;
-                       case _OP_JMP: ci->_ip += (sarg1); continue;
-                       case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
-                       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(); } 
-                               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;
-                       case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL);  continue;
-                       case _OP_GETPARENT:
-                               switch(type(STK(arg1))) {
-                               case OT_TABLE: 
-                       TARGET = _table(STK(arg1))->_delegate?SQObjectPtr(_table(STK(arg1))->_delegate):_null_;
-                                       continue;
-                               case OT_CLASS: TARGET = _class(STK(arg1))->_base?_class(STK(arg1))->_base:_null_;
-                                       continue;
-                               }
-                               Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(STK(arg1)));
-                               SQ_THROW();
-                               continue;
-                       case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((unsigned int)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;
-                       case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;
-                       case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;
-                       case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;
-                       case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;
-                       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: 
-                               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: 
-                               if(IsFalse(STK(arg2))) {
-                                       TARGET = STK(arg2);
-                                       ci->_ip += (sarg1);
-                               }
-                               continue;
-                       case _OP_OR:
-                               if(!IsFalse(STK(arg2))) {
-                                       TARGET = STK(arg2);
-                                       ci->_ip += (sarg1);
-                               }
-                               continue;
-                       case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
-                       case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;
-                       case _OP_BWNOT:
-                               if(type(STK(arg1)) == OT_INTEGER) {
-                                       TARGET = SQInteger(~_integer(STK(arg1)));
-                                       continue;
-                               }
-                               Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));
-                               SQ_THROW();
-                       case _OP_CLOSURE: {
-                               SQClosure *c = ci->_closure._unVal.pClosure;
-                               SQFunctionProto *fp = c->_function._unVal.pFunctionProto;
-                               if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
-                               continue;
-                       }
-                       case _OP_YIELD:{
-                               if(type(ci->_generator) == OT_GENERATOR) {
-                                       if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);
-                                       _GUARD(_generator(ci->_generator)->Yield(this));
-                                       traps -= ci->_etraps;
-                                       if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;
-                               }
-                               else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}
-                               if(Return(arg0, arg1, temp_reg)){
-                                       assert(traps==0);
-                                       outres = temp_reg;
-                                       return true;
-                               }
-                                       
-                               }
-                               continue;
-                       case _OP_RESUME:
-                               if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}
-                               _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; }
-                               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++;
-                               ci->_etraps++;
-                               continue;
-                       case _OP_POPTRAP:{
-                               for(int 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;
-                       case _OP_NEWSLOTA:
-                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3)));
-                               _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));
-                               if(arg0 != arg3) TARGET = STK(arg3);
-                               continue;
-                       }
-                       
-               }
-       }
-exception_trap:
-       {
-               SQObjectPtr currerror = _lasterror;
-//             dumpstack(_stackbase);
-               int n = 0;
-               int last_top = _top;
-               if(ci) {
-                       if(traps) {
-                               do {
-                                       if(ci->_etraps > 0) {
-                                               SQExceptionTrap &et = _etraps.top();
-                                               ci->_ip = et._ip;
-                                               _top = et._stacksize;
-                                               _stackbase = et._stackbase;
-                                               _stack[_stackbase+et._extarget] = currerror;
-                                               _etraps.pop_back(); traps--; ci->_etraps--;
-                                               while(last_top >= _top) _stack[last_top--].Null();
-                                               goto exception_restore;
-                                       }
-                                       //if is a native closure
-                                       if(type(ci->_closure) != OT_CLOSURE && n)
-                                               break;
-                                       if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
-                                       PopVarArgs(ci->_vargs);
-                                       POP_CALLINFO(this);
-                                       n++;
-                               }while(_callsstack.size());
-                       }
-                       //call the hook
-                       CallErrorHandler(currerror);
-                       //remove call stack until a C function is found or the cstack is empty
-                       if(ci) do{
-                               SQBool exitafterthisone = ci->_root;
-                               if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
-                               _stackbase -= ci->_prevstkbase;
-                               _top = _stackbase + ci->_prevtop;
-                               PopVarArgs(ci->_vargs);
-                               POP_CALLINFO(this);
-                               if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
-                       }while(_callsstack.size());
-
-                       while(last_top >= _top) _stack[last_top--].Null();
-               }
-               _lasterror = currerror;
-               return false;
-       }
-       assert(0);
-}
-
-bool SQVM::CreateClassInstance(SQClass *theclass, int nargs, int stackbase, SQObjectPtr &retval)
-{
-       SQObjectPtr constr;
-       SQObjectPtr inst = theclass->CreateInstance();
-       _stack[stackbase] = inst;
-       if(theclass->Get(_ss(this)->_constructoridx,constr)) {
-               if(!Call(constr,nargs,stackbase,constr))
-                       return false;
-       }
-       retval = inst;
-       return true;
-}
-
-void SQVM::CallErrorHandler(SQObjectPtr &error)
-{
-       if(type(_errorhandler) != OT_NULL) {
-               SQObjectPtr out;
-               Push(_roottable); Push(error);
-               Call(_errorhandler, 2, _top-2, out);
-               Pop(2);
-       }
-}
-
-void SQVM::CallDebugHook(int type,int forcedline)
-{
-       SQObjectPtr temp_reg;
-       int nparams=5;
-       SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);
-       Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);
-       Call(_debughook,nparams,_top-nparams,temp_reg);
-       Pop(nparams);
-}
-
-bool SQVM::CallNative(SQNativeClosure *nclosure,int nargs,int stackbase,bool tailcall,SQObjectPtr &retval,bool &suspend)
-{
-       if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
-       int nparamscheck = nclosure->_nparamscheck;
-       if(((nparamscheck > 0) && (nparamscheck != nargs))
-               || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {
-               Raise_Error(_SC("wrong number of parameters"));
-               return false;
-               }
-
-       int tcs;
-       if(tcs = nclosure->_typecheck.size()) {
-               for(int 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]));
-                               return false;
-                       }
-       }
-       _nnativecalls++;
-       if ((_top + MIN_STACK_OVERHEAD) > (int)_stack.size()) {
-               _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));
-       }
-       int oldtop = _top;
-       int 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;
-       _stackbase = stackbase;
-       //push free variables
-       int outers = nclosure->_outervalues.size();
-       for (int i = 0; i < outers; i++) {
-               Push(nclosure->_outervalues[i]);
-       }
-       ci->_prevtop = (oldtop - oldstackbase);
-       int ret = (nclosure->_function)(this);
-       _nnativecalls--;
-       suspend = false;
-       if( ret == SQ_SUSPEND_FLAG) suspend = true;
-       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;
-       _top = oldtop;
-       POP_CALLINFO(this);
-       return true;
-}
-
-bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)
-{
-       switch(type(self)){
-       case OT_TABLE:
-               if(_table(self)->Get(key,dest))return true;
-               break;
-       case OT_ARRAY:
-               if(sq_isnumeric(key)){
-                       return _array(self)->Get(tointeger(key),dest);
-               }
-               break;
-       case OT_INSTANCE:
-               if(_instance(self)->Get(key,dest)) return true;
-               break;
-       }
-       if(FallBackGet(self,key,dest,raw)) return true;
-
-       if(fetchroot) {
-               if(_rawval(STK(0)) == _rawval(self) &&
-                       type(STK(0)) == type(self)) {
-                               return _table(_roottable)->Get(key,dest);
-               }
-       }
-       return false;
-}
-
-bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)
-{
-       switch(type(self)){
-       case OT_CLASS: 
-               return _class(self)->Get(key,dest);
-               break;
-       case OT_TABLE:
-       case OT_USERDATA:
-        //delegation
-               if(_delegable(self)->_delegate) {
-                       if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))
-                               return true;    
-                       if(raw)return false;
-                       Push(self);Push(key);
-                       if(CallMetaMethod(_delegable(self),MT_GET,2,dest))
-                               return true;
-               }
-               if(type(self) == OT_TABLE) {
-                       if(raw) return false;
-                       return _table_ddel->Get(key,dest);
-               }
-               return false;
-               break;
-       case OT_ARRAY:
-               if(raw)return false;
-               return _array_ddel->Get(key,dest);
-       case OT_STRING:
-               if(sq_isnumeric(key)){
-                       SQInteger n=tointeger(key);
-                       if(abs(n)<_string(self)->_len){
-                               if(n<0)n=_string(self)->_len-n;
-                               dest=SQInteger(_stringval(self)[n]);
-                               return true;
-                       }
-                       return false;
-               }
-               else {
-                       if(raw)return false;
-                       return _string_ddel->Get(key,dest);
-               }
-               break;
-       case OT_INSTANCE:
-               if(raw)return false;
-               Push(self);Push(key);
-               if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {
-                       return _instance_ddel->Get(key,dest);
-               }
-               return true;
-       case OT_INTEGER:case OT_FLOAT:case OT_BOOL: 
-               if(raw)return false;
-               return _number_ddel->Get(key,dest);
-       case OT_GENERATOR: 
-               if(raw)return false;
-               return _generator_ddel->Get(key,dest);
-       case OT_CLOSURE: case OT_NATIVECLOSURE: 
-               if(raw)return false;
-               return _closure_ddel->Get(key,dest);
-       case OT_THREAD:
-               if(raw)return false;
-               return  _thread_ddel->Get(key,dest);
-       default:return false;
-       }
-       return false;
-}
-
-bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)
-{
-       switch(type(self)){
-       case OT_TABLE:
-               if(_table(self)->Set(key,val))
-                       return true;
-               if(_table(self)->_delegate) {
-                       if(Set(_table(self)->_delegate,key,val,false)) {
-                               return true;
-                       }
-               }
-               //keeps going
-       case OT_USERDATA:
-               if(_delegable(self)->_delegate) {
-                       SQObjectPtr t;
-                       Push(self);Push(key);Push(val);
-                       if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
-               }
-               break;
-       case OT_INSTANCE:{
-               if(_instance(self)->Set(key,val))
-                       return true;
-               SQObjectPtr t;
-               Push(self);Push(key);Push(val);
-               if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
-               }
-               break;
-       case OT_ARRAY:
-               if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }
-               return _array(self)->Set(tointeger(key),val);
-       default:
-               Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));
-               return false;
-       }
-       if(fetchroot) {
-               if(_rawval(STK(0)) == _rawval(self) &&
-                       type(STK(0)) == type(self)) {
-                               return _table(_roottable)->Set(key,val);
-                       }
-       }
-       return false;
-}
-
-bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)
-{
-       SQObjectPtr temp_reg;
-       switch(type(self)){
-       case OT_TABLE:
-               target = _table(self)->Clone();
-               goto cloned_mt;
-       case OT_INSTANCE:
-               target = _instance(self)->Clone(_ss(this));
-cloned_mt:
-               if(_delegable(target)->_delegate){
-                       Push(target);
-                       Push(self);
-                       CallMetaMethod(_delegable(target),MT_CLONED,2,temp_reg);
-               }
-               return true;
-       case OT_ARRAY: 
-               target=_array(self)->Clone();
-               return true;
-       default: return false;
-       }
-}
-
-bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val)
-{
-       if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }
-       switch(type(self)) {
-       case OT_TABLE: {
-               bool rawcall = true;
-               if(_table(self)->_delegate) {
-                       SQObjectPtr res;
-                       if(!_table(self)->Get(key,res)) {
-                               Push(self);Push(key);Push(val);
-                               rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);
-                       }
-               }
-               if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
-               
-               break;}
-       case OT_CLASS: 
-               if(!_class(self)->NewSlot(key,val)) {
-                       if(_class(self)->_locked) {
-                               Raise_Error(_SC("trying to modify a class that has already been instantiated"));
-                               return false;
-                       }
-                       else {
-                               SQObjectPtr oval = PrintObjVal(key);
-                               Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));
-                               return false;
-                       }
-               }
-               break;
-       default:
-               Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));
-               return false;
-               break;
-       }
-       return true;
-}
-
-bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)
-{
-       switch(type(self)) {
-       case OT_TABLE:
-       case OT_INSTANCE:
-       case OT_USERDATA: {
-               SQObjectPtr t;
-               bool handled = false;
-               if(_delegable(self)->_delegate) {
-                       Push(self);Push(key);
-                       handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);
-               }
-
-               if(!handled) {
-                       if(type(self) == OT_TABLE) {
-                               if(_table(self)->Get(key,t)) {
-                                       _table(self)->Remove(key);
-                               }
-                               else {
-                                       Raise_IdxError((SQObject &)key);
-                                       return false;
-                               }
-                       }
-                       else {
-                               Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));
-                               return false;
-                       }
-               }
-               res = t;
-                               }
-               break;
-       default:
-               Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));
-               return false;
-       }
-       return true;
-}
-
-bool SQVM::Call(SQObjectPtr &closure,int nparams,int stackbase,SQObjectPtr &outres)
-{
-#ifdef _DEBUG
-int prevstackbase = _stackbase;
-#endif
-       switch(type(closure)) {
-       case OT_CLOSURE:
-               return Execute(closure, _top - nparams, nparams, stackbase,outres);
-               break;
-       case OT_NATIVECLOSURE:{
-               bool suspend;
-               return CallNative(_nativeclosure(closure), nparams, stackbase, false, outres,suspend);
-               
-                                                 }
-               break;
-       case OT_CLASS:
-               return CreateClassInstance(_class(closure),nparams,stackbase,outres);
-               break;
-       default:
-               return false;
-       }
-#ifdef _DEBUG
-       if(!_suspended) {
-               assert(_stackbase == prevstackbase);
-       }
-#endif
-       return true;
-}
-
-bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,int nparams,SQObjectPtr &outres)
-{
-       SQObjectPtr closure;
-       if(del->GetMetaMethod(mm, closure)) {
-               if(Call(closure, nparams, _top - nparams, outres)) {
-                       Pop(nparams);
-                       return true;
-               }
-       }
-       Pop(nparams);
-       return false;
-}
-
-void SQVM::Remove(int n) {
-       n = (n >= 0)?n + _stackbase - 1:_top + n;
-       for(int i = n; i < _top; i++){
-               _stack[i] = _stack[i+1];
-       }
-       _stack[_top] = _null_;
-       _top--;
-}
-
-
-#ifdef _DEBUG_DUMP
-void SQVM::dumpstack(int stackbase,bool dumpall)
-{
-       int size=dumpall?_stack.size():_top;
-       int n=0;
-       scprintf(_SC("\n>>>>stack dump<<<<\n"));
-       CallInfo &ci=_callsstack.back();
-       scprintf(_SC("IP: %d\n"),ci._ip);
-       scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);
-       scprintf(_SC("prev top: %d\n"),ci._prevtop);
-       for(int i=0;i<size;i++){
-               SQObjectPtr &obj=_stack[i];     
-               if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
-               scprintf(_SC("[%d]:"),n);
-               switch(type(obj)){
-               case OT_FLOAT:                  scprintf(_SC("FLOAT %.3f"),_float(obj));break;
-               case OT_INTEGER:                scprintf(_SC("INTEGER %d"),_integer(obj));break;
-               case OT_BOOL:                   scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;
-               case OT_STRING:                 scprintf(_SC("STRING %s"),_stringval(obj));break;
-               case OT_NULL:                   scprintf(_SC("NULL"));  break;
-               case OT_TABLE:                  scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;
-               case OT_ARRAY:                  scprintf(_SC("ARRAY %p"),_array(obj));break;
-               case OT_CLOSURE:                scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
-               case OT_NATIVECLOSURE:  scprintf(_SC("NATIVECLOSURE"));break;
-               case OT_USERDATA:               scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
-               case OT_GENERATOR:              scprintf(_SC("GENERATOR"));break;
-               case OT_THREAD:                 scprintf(_SC("THREAD [%p]"),_thread(obj));break;
-               case OT_USERPOINTER:    scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
-               case OT_CLASS:                  scprintf(_SC("CLASS %p"),_class(obj));break;
-               case OT_INSTANCE:               scprintf(_SC("INSTANCE %p"),_instance(obj));break;
-               default:
-                       assert(0);
-                       break;
-               };
-               scprintf(_SC("\n"));
-               ++n;
-       }
-}
-
-#endif
+/*\r
+       see copyright notice in squirrel.h\r
+*/\r
+#include "sqpcheader.h"\r
+#include <math.h>\r
+#include <stdlib.h>\r
+#include "sqopcodes.h"\r
+#include "sqfuncproto.h"\r
+#include "sqvm.h"\r
+#include "sqclosure.h"\r
+#include "sqstring.h"\r
+#include "sqtable.h"\r
+#include "squserdata.h"\r
+#include "sqarray.h"\r
+#include "sqclass.h"\r
+\r
+#define TOP() (_stack[_top-1])\r
+\r
+bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)\r
+{\r
+       SQInteger res;\r
+       SQInteger i1 = _integer(o1), i2 = _integer(o2);\r
+       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))\r
+       {\r
+               switch(op) {\r
+                       case BW_AND:    res = i1 & i2; break;\r
+                       case BW_OR:             res = i1 | i2; break;\r
+                       case BW_XOR:    res = i1 ^ i2; break;\r
+                       case BW_SHIFTL: res = i1 << i2; break;\r
+                       case BW_SHIFTR: res = i1 >> i2; break;\r
+                       case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;\r
+                       default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }\r
+               }\r
+       } \r
+       else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}\r
+       trg = res;\r
+       return true;\r
+}\r
+\r
+bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)\r
+{\r
+       if(sq_isnumeric(o1) && sq_isnumeric(o2)) {\r
+                       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {\r
+                               switch(op) {\r
+                               case '+': trg = _integer(o1) + _integer(o2); break;\r
+                               case '-': trg = _integer(o1) - _integer(o2); break;\r
+                               case '/': if(_integer(o2) == 0) { Raise_Error(_SC("division by zero")); return false; }\r
+                                       trg = _integer(o1) / _integer(o2); \r
+                                       break;\r
+                               case '*': trg = _integer(o1) * _integer(o2); break;\r
+                               case '%': trg = _integer(o1) % _integer(o2); break;\r
+                               }\r
+                       }else{\r
+                               switch(op) {\r
+                               case '+': trg = tofloat(o1) + tofloat(o2); break;\r
+                               case '-': trg = tofloat(o1) - tofloat(o2); break;\r
+                               case '/': trg = tofloat(o1) / tofloat(o2); break;\r
+                               case '*': trg = tofloat(o1) * tofloat(o2); break;\r
+                               case '%': trg = SQFloat(fmod((double)tofloat(o1),(double)tofloat(o2))); break;\r
+                               }\r
+                       }       \r
+               } else {\r
+                       if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){\r
+                                       if(!StringCat(o1, o2, trg)) return false;\r
+                       }\r
+                       else if(!ArithMetaMethod(op,o1,o2,trg)) { \r
+                               Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false; \r
+                       }\r
+               }\r
+               return true;\r
+}\r
+\r
+SQVM::SQVM(SQSharedState *ss)\r
+{\r
+       _sharedstate=ss;\r
+       _suspended = SQFalse;\r
+       _suspended_target=-1;\r
+       _suspended_root = SQFalse;\r
+       _suspended_traps=-1;\r
+       _foreignptr=NULL;\r
+       _nnativecalls=0;\r
+       _lasterror = _null_;\r
+       _errorhandler = _null_;\r
+       _debughook = _null_;\r
+       INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);\r
+}\r
+\r
+void SQVM::Finalize()\r
+{\r
+       _roottable = _null_;\r
+       _lasterror = _null_;\r
+       _errorhandler = _null_;\r
+       _debughook = _null_;\r
+       temp_reg = _null_;\r
+       SQInteger size=_stack.size();\r
+       for(SQInteger i=0;i<size;i++)\r
+               _stack[i]=_null_;\r
+}\r
+\r
+SQVM::~SQVM()\r
+{\r
+       Finalize();\r
+       REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
+}\r
+\r
+bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)\r
+{\r
+       SQMetaMethod mm;\r
+       switch(op){\r
+               case _SC('+'): mm=MT_ADD; break;\r
+               case _SC('-'): mm=MT_SUB; break;\r
+               case _SC('/'): mm=MT_DIV; break;\r
+               case _SC('*'): mm=MT_MUL; break;\r
+               case _SC('%'): mm=MT_MODULO; break;\r
+       }\r
+       if(is_delegable(o1) && _delegable(o1)->_delegate) {\r
+               Push(o1);Push(o2);\r
+               return CallMetaMethod(_delegable(o1),mm,2,dest);\r
+       }\r
+       return false;\r
+}\r
+\r
+bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)\r
+{\r
+       \r
+       switch(type(o)) {\r
+       case OT_INTEGER:\r
+               trg = -_integer(o);\r
+               return true;\r
+       case OT_FLOAT:\r
+               trg = -_float(o);\r
+               return true;\r
+       case OT_TABLE:\r
+       case OT_USERDATA:\r
+       case OT_INSTANCE:\r
+               if(_delegable(o)->_delegate) {\r
+                       Push(o);\r
+                       if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {\r
+                               trg = temp_reg;\r
+                               return true;\r
+                       }\r
+               }\r
+               return true;\r
+\r
+       }\r
+       Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));\r
+       return false;\r
+}\r
+\r
+#define _RET_SUCCEED(exp) { result = (exp); return true; } \r
+bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)\r
+{\r
+       if(type(o1)==type(o2)){\r
+               if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);\r
+               SQObjectPtr res;\r
+               switch(type(o1)){\r
+               case OT_STRING:\r
+                       _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));\r
+               case OT_INTEGER:\r
+                       _RET_SUCCEED(_integer(o1)-_integer(o2));\r
+               case OT_FLOAT:\r
+                       _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);\r
+               case OT_TABLE:\r
+               case OT_USERDATA:\r
+               case OT_INSTANCE:\r
+                       Push(o1);Push(o2);\r
+                       if(_delegable(o1)->_delegate)CallMetaMethod(_delegable(o1),MT_CMP,2,res);\r
+                       break;\r
+               }\r
+               if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }\r
+               _RET_SUCCEED(_integer(res));\r
+       }\r
+       else{\r
+               if(sq_isnumeric(o1) && sq_isnumeric(o2)){\r
+                       if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) { \r
+                               if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }\r
+                               else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }\r
+                               _RET_SUCCEED(1);\r
+                       }\r
+                       else{\r
+                               if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }\r
+                               else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }\r
+                               _RET_SUCCEED(1);\r
+                       }\r
+               }\r
+               else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);}\r
+               else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);}\r
+               else { Raise_CompareError(o1,o2); return false; }\r
+               \r
+       }\r
+       assert(0);\r
+       _RET_SUCCEED(0); //cannot happen\r
+}\r
+\r
+bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)\r
+{\r
+       SQInteger r;\r
+       if(ObjCmp(o1,o2,r)) {\r
+               switch(op) {\r
+                       case CMP_G: res = (r > 0)?_true_:_false_; return true;\r
+                       case CMP_GE: res = (r >= 0)?_true_:_false_; return true;\r
+                       case CMP_L: res = (r < 0)?_true_:_false_; return true;\r
+                       case CMP_LE: res = (r <= 0)?_true_:_false_; return true;\r
+                       \r
+               }\r
+               assert(0);\r
+       }\r
+       return false;\r
+}\r
+\r
+void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)\r
+{\r
+       switch(type(o)) {\r
+       case OT_STRING:\r
+               res = o;\r
+               return;\r
+       case OT_FLOAT:\r
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));\r
+               break;\r
+       case OT_INTEGER:\r
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));\r
+               break;\r
+       case OT_BOOL:\r
+               scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));\r
+               break;\r
+       case OT_TABLE:\r
+       case OT_USERDATA:\r
+       case OT_INSTANCE:\r
+               if(_delegable(o)->_delegate) {\r
+                       Push(o);\r
+                       if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) {\r
+                               if(type(res) == OT_STRING)\r
+                                       return;\r
+                               //else keeps going to the default\r
+                       }\r
+               }\r
+       default:\r
+               scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),_rawval(o));\r
+       }\r
+       res = SQString::Create(_ss(this),_spval);\r
+       return;\r
+}\r
+\r
+\r
+bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)\r
+{\r
+       switch(type(obj))\r
+       {\r
+       case OT_STRING:\r
+               switch(type(str)){\r
+               case OT_STRING: {\r
+                       SQInteger l=_string(str)->_len,ol=_string(obj)->_len;\r
+                       SQChar *s=_sp(rsl(l+ol+1));\r
+                       memcpy(s,_stringval(str),rsl(l));memcpy(s+l,_stringval(obj),rsl(ol));s[l+ol]=_SC('\0');\r
+                       break;\r
+               }\r
+               case OT_FLOAT:\r
+                       scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(obj)->_len+1)),_SC("%g%s"),_float(str),_stringval(obj));\r
+                       break;\r
+               case OT_INTEGER:\r
+                       scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(obj)->_len+1)),_SC("%d%s"),_integer(str),_stringval(obj));\r
+                       break;\r
+               default:\r
+                       Raise_Error(_SC("string concatenation between '%s' and '%s'"),GetTypeName(str),GetTypeName(obj));\r
+                       return false;\r
+               }\r
+               dest=SQString::Create(_ss(this),_spval);\r
+               break;\r
+       case OT_FLOAT:\r
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(str)->_len+1)),_SC("%s%g"),_stringval(str),_float(obj));\r
+               dest=SQString::Create(_ss(this),_spval);\r
+               break;\r
+       case OT_INTEGER:\r
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+_string(str)->_len+1)),_SC("%s%d"),_stringval(str),_integer(obj));\r
+               dest=SQString::Create(_ss(this),_spval);\r
+               break;\r
+       default:\r
+               Raise_Error(_SC("string concatenation between '%s' and '%s'"),GetTypeName(str),GetTypeName(obj));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+const SQChar *IdType2Name(SQObjectType type)\r
+{\r
+       switch(_RAW_TYPE(type))\r
+       {\r
+       case _RT_NULL:return _SC("null");\r
+       case _RT_INTEGER:return _SC("integer");\r
+       case _RT_FLOAT:return _SC("float");\r
+       case _RT_BOOL:return _SC("bool");\r
+       case _RT_STRING:return _SC("string");\r
+       case _RT_TABLE:return _SC("table");\r
+       case _RT_ARRAY:return _SC("array");\r
+       case _RT_GENERATOR:return _SC("generator");\r
+       case _RT_CLOSURE:\r
+       case _RT_NATIVECLOSURE:\r
+               return _SC("function");\r
+       case _RT_USERDATA:\r
+       case _RT_USERPOINTER:\r
+               return _SC("userdata");\r
+       case _RT_THREAD: return _SC("thread");\r
+       case _RT_FUNCPROTO: return _SC("function");\r
+       case _RT_CLASS: return _SC("class");\r
+       case _RT_INSTANCE: return _SC("instance");\r
+       case _RT_WEAKREF: return _SC("weakref");\r
+       default:\r
+               return NULL;\r
+       }\r
+}\r
+\r
+const SQChar *GetTypeName(const SQObjectPtr &obj1)\r
+{\r
+       return IdType2Name(type(obj1)); \r
+}\r
+\r
+void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)\r
+{\r
+       if(is_delegable(obj1) && _delegable(obj1)->_delegate) {\r
+               Push(obj1);\r
+               if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))\r
+                       return;\r
+       }\r
+       dest = SQString::Create(_ss(this),GetTypeName(obj1));\r
+}\r
+\r
+bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)\r
+{\r
+       _stack.resize(stacksize);\r
+       _callsstack.reserve(4);\r
+       _stackbase = 0;\r
+       _top = 0;\r
+       if(!friendvm) \r
+               _roottable = SQTable::Create(_ss(this), 0);\r
+       else {\r
+               _roottable = friendvm->_roottable;\r
+               _errorhandler = friendvm->_errorhandler;\r
+               _debughook = friendvm->_debughook;\r
+       }\r
+       \r
+       sq_base_register(this);\r
+       return true;\r
+}\r
+\r
+extern SQInstructionDesc g_InstrDesc[];\r
+\r
+bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall)\r
+{\r
+       SQFunctionProto *func = _funcproto(closure->_function);\r
+       //const SQInteger outerssize = func->_outervalues.size();\r
+\r
+       const SQInteger paramssize = func->_parameters.size();\r
+       const SQInteger oldtop = _top;\r
+       const SQInteger newtop = stackbase + func->_stacksize;\r
+       \r
+       \r
+       if (paramssize != nargs) {\r
+               if(func->_varparams)\r
+               {\r
+                       if (nargs < paramssize) {\r
+                               Raise_Error(_SC("wrong number of parameters"));\r
+                               return false;\r
+                       }\r
+                       for(SQInteger n = 0; n < nargs - paramssize; n++) {\r
+                               _vargsstack.push_back(_stack[stackbase+paramssize+n]);\r
+                               _stack[stackbase+paramssize+n] = _null_;\r
+                       }\r
+               }\r
+               else {\r
+                       Raise_Error(_SC("wrong number of parameters"));\r
+                       return false;\r
+               }\r
+       }\r
+       \r
+       if (!tailcall) {\r
+               PUSH_CALLINFO(this, CallInfo());\r
+               ci->_etraps = 0;\r
+               ci->_prevstkbase = stackbase - _stackbase;\r
+               ci->_target = target;\r
+               ci->_prevtop = _top - _stackbase;\r
+               ci->_ncalls = 1;\r
+               ci->_root = SQFalse;\r
+       }\r
+       else {\r
+               ci->_ncalls++;\r
+       }\r
+       ci->_vargs.size = (nargs - paramssize);\r
+       ci->_vargs.base = _vargsstack.size()-(nargs - paramssize);\r
+       ci->_closure._unVal.pClosure = closure;\r
+       ci->_closure._type = OT_CLOSURE;\r
+       ci->_iv = &func->_instructions;\r
+       ci->_literals = &func->_literals;\r
+       //grows the stack if needed\r
+       if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) {\r
+               _stack.resize(_stack.size() + (func->_stacksize<<1));\r
+       }\r
+               \r
+       _top = newtop;\r
+       _stackbase = stackbase;\r
+       ci->_ip = ci->_iv->_vals;\r
+       return true;\r
+}\r
+\r
+bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)\r
+{\r
+       if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))\r
+               for(SQInteger i=0;i<ci->_ncalls;i++)\r
+                       CallDebugHook(_SC('r'));\r
+                                               \r
+       SQBool broot = ci->_root;\r
+       SQInteger last_top = _top;\r
+       SQInteger target = ci->_target;\r
+       SQInteger oldstackbase = _stackbase;\r
+       _stackbase -= ci->_prevstkbase;\r
+       _top = _stackbase + ci->_prevtop;\r
+       if(ci->_vargs.size) PopVarArgs(ci->_vargs);\r
+       POP_CALLINFO(this);\r
+       if (broot) {\r
+               if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack[oldstackbase+_arg1];\r
+               else retval = _null_;\r
+       }\r
+       else {\r
+               if (_arg0 != MAX_FUNC_STACKSIZE)\r
+                       STK(target) = _stack[oldstackbase+_arg1];\r
+               else\r
+                       STK(target) = _null_;\r
+       }\r
+\r
+       while (last_top >= _top) _stack[last_top--].Null();\r
+       assert(oldstackbase >= _stackbase); \r
+       return broot?true:false;\r
+}\r
+\r
+#define _RET_ON_FAIL(exp) { if(!exp) return false; }\r
+\r
+bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)\r
+{\r
+       _RET_ON_FAIL(ARITH_OP( op , target, a, incr));\r
+       a = target;\r
+       return true;\r
+}\r
+\r
+bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)\r
+{\r
+       SQObjectPtr trg;\r
+       _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));\r
+       target = a;\r
+       a = trg;\r
+       return true;\r
+}\r
+\r
+bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)\r
+{\r
+       SQObjectPtr tmp, tself = self, tkey = key;\r
+       if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }\r
+       _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))\r
+       Set(tself, tkey, target,true);\r
+       if (postfix) target = tmp;\r
+       return true;\r
+}\r
+\r
+#define arg0 (_i_._arg0)\r
+#define arg1 (_i_._arg1)\r
+#define sarg1 (*((SQInteger *)&_i_._arg1))\r
+#define arg2 (_i_._arg2)\r
+#define arg3 (_i_._arg3)\r
+#define sarg3 (*((char *)&_i_._arg3))\r
+\r
+SQRESULT SQVM::Suspend()\r
+{\r
+       if (_suspended)\r
+               return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));\r
+       if (_nnativecalls!=2)\r
+               return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));\r
+       return SQ_SUSPEND_FLAG;\r
+}\r
+\r
+void SQVM::PopVarArgs(VarArgs &vargs)\r
+{\r
+       for(SQInteger n = 0; n< vargs.size; n++)\r
+               _vargsstack.pop_back();\r
+}\r
+\r
+#define _FINISH(stoploop) {finished = stoploop; return true; }\r
+bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr \r
+&o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished)\r
+{\r
+       SQInteger nrefidx;\r
+       switch(type(o1)) {\r
+       case OT_TABLE:\r
+               if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(true);\r
+               o4 = (SQInteger)nrefidx; _FINISH(false);\r
+       case OT_ARRAY:\r
+               if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(true);\r
+               o4 = (SQInteger) nrefidx; _FINISH(false);\r
+       case OT_STRING:\r
+               if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);\r
+               o4 = (SQInteger)nrefidx; _FINISH(false);\r
+       case OT_CLASS:\r
+               if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);\r
+               o4 = (SQInteger)nrefidx; _FINISH(false);\r
+       case OT_USERDATA:\r
+       case OT_INSTANCE:\r
+               if(_delegable(o1)->_delegate) {\r
+                       SQObjectPtr itr;\r
+                       Push(o1);\r
+                       Push(o4);\r
+                       if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){\r
+                               o4 = o2 = itr;\r
+                               if(type(itr) == OT_NULL) _FINISH(true);\r
+                               if(!Get(o1, itr, o3, false,false)) {\r
+                                       Raise_Error(_SC("_nexti returned an invalid idx"));\r
+                                       return false;\r
+                               }\r
+                               _FINISH(false);\r
+                       }\r
+                       Raise_Error(_SC("_nexti failed"));\r
+                       return false;\r
+               }\r
+               break;\r
+       case OT_GENERATOR:\r
+               if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(true);\r
+               if(_generator(o1)->_state == SQGenerator::eSuspended) {\r
+                       SQInteger idx = 0;\r
+                       if(type(o4) == OT_INTEGER) {\r
+                               idx = _integer(o4) + 1;\r
+                       }\r
+                       o2 = idx;\r
+                       o4 = idx;\r
+                       _generator(o1)->Resume(this, arg_2+1);\r
+                       _FINISH(false);\r
+               }\r
+       }\r
+       Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));\r
+       return false; //cannot be hit(just to avoid warnings)\r
+}\r
+\r
+bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)\r
+{\r
+       if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }\r
+       switch(type(o2)) {\r
+       case OT_TABLE:\r
+               if(!_table(o1)->SetDelegate(_table(o2))){\r
+                       Raise_Error(_SC("delegate cycle detected"));\r
+                       return false;\r
+               }\r
+               break;\r
+       case OT_NULL:\r
+               _table(o1)->SetDelegate(NULL);\r
+               break;\r
+       default:\r
+               Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));\r
+               return false;\r
+               break;\r
+       }\r
+       trg = o1;\r
+       return true;\r
+}\r
+#define COND_LITERAL (arg3!=0?(*ci->_literals)[arg1]:STK(arg1))\r
+\r
+#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }\r
+\r
+#define SQ_THROW() { goto exception_trap; }\r
+\r
+bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)\r
+{\r
+       SQInteger nouters;\r
+       SQClosure *closure = SQClosure::Create(_ss(this), func);\r
+       if(nouters = func->_outervalues.size()) {\r
+               closure->_outervalues.reserve(nouters);\r
+               for(SQInteger i = 0; i<nouters; i++) {\r
+                       SQOuterVar &v = func->_outervalues[i];\r
+                       switch(v._type){\r
+                       case otSYMBOL:\r
+                               closure->_outervalues.push_back(_null_);\r
+                               if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))\r
+                               {Raise_IdxError(v._src); return false; }\r
+                               break;\r
+                       case otLOCAL:\r
+                               closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);\r
+                               break;\r
+                       case otOUTER:\r
+                               closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+       target = closure;\r
+       return true;\r
+\r
+}\r
+\r
+bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)\r
+{\r
+       if(ci->_vargs.size == 0) {\r
+               Raise_Error(_SC("the function doesn't have var args"));\r
+               return false;\r
+       }\r
+       if(!sq_isnumeric(index)){\r
+               Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));\r
+               return false;\r
+       }\r
+       SQInteger idx = tointeger(index);\r
+       if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }\r
+       target = _vargsstack[ci->_vargs.base+idx];\r
+       return true;\r
+}\r
+\r
+bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)\r
+{\r
+       SQClass *base = NULL;\r
+       SQObjectPtr attrs;\r
+       if(baseclass != MAX_LITERALS) {\r
+               if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }\r
+               base = _class(_stack._vals[_stackbase + baseclass]);\r
+       }\r
+       if(attributes != MAX_FUNC_STACKSIZE) {\r
+               attrs = _stack._vals[_stackbase+attributes];\r
+       }\r
+       target = SQClass::Create(_ss(this),base);\r
+       _class(target)->_attributes = attrs;\r
+       return true;\r
+}\r
+\r
+\r
+\r
+bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)\r
+{\r
+       if(type(o1) == type(o2)) {\r
+               res = ((_userpointer(o1) == _userpointer(o2)?true:false));\r
+       }\r
+       else {\r
+               if(sq_isnumeric(o1) && sq_isnumeric(o2)) {\r
+                       SQInteger cmpres;\r
+                       if(!ObjCmp(o1, o2,cmpres)) return false;\r
+                       res = (cmpres == 0);\r
+               }\r
+               else {\r
+                       res = false;\r
+               }\r
+       }\r
+       return true;\r
+}\r
+\r
+bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, ExecutionType et)\r
+{\r
+       if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }\r
+       _nnativecalls++;\r
+       AutoDec ad(&_nnativecalls);\r
+       SQInteger traps = 0;\r
+       //temp_reg vars for OP_CALL\r
+       SQInteger ct_target;\r
+       bool ct_tailcall; \r
+\r
+       switch(et) {\r
+               case ET_CALL: \r
+                       if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) { \r
+                               //call the handler if there are no calls in the stack, if not relies on the previous node\r
+                               if(ci == NULL) CallErrorHandler(_lasterror);\r
+                               return false;\r
+                       }\r
+                       ci->_root = SQTrue;\r
+                       break;\r
+               case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;\r
+               case ET_RESUME_VM:\r
+                       traps = _suspended_traps;\r
+                       ci->_root = _suspended_root;\r
+                       _suspended = SQFalse;\r
+                       break;\r
+       }\r
+       \r
+exception_restore:\r
+       //\r
+       {\r
+               for(;;)\r
+               {\r
+                       const SQInstruction &_i_ = *ci->_ip++;\r
+                       //dumpstack(_stackbase);\r
+                       //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);\r
+                       switch(_i_.op)\r
+                       {\r
+                       case _OP_LINE:\r
+                               if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))\r
+                                       CallDebugHook(_SC('l'),arg1);\r
+                               continue;\r
+                       case _OP_LOAD: TARGET = (*ci->_literals)[arg1]; continue;\r
+                       case _OP_DLOAD: TARGET = (*ci->_literals)[arg1]; STK(arg2) = (*ci->_literals)[arg3];continue;\r
+                       case _OP_TAILCALL:\r
+                               temp_reg = STK(arg1);\r
+                               if (type(temp_reg) == OT_CLOSURE){ \r
+                                       ct_tailcall = true;\r
+                                       if(ci->_vargs.size) PopVarArgs(ci->_vargs);\r
+                                       for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);\r
+                                       ct_target = ci->_target;\r
+                                       goto common_call;\r
+                               }\r
+                       case _OP_CALL: {\r
+                                       ct_tailcall = false;\r
+                                       ct_target = arg0;\r
+                                       temp_reg = STK(arg1);\r
+common_call:\r
+                                       SQInteger last_top = _top;\r
+                                       switch (type(temp_reg)) {\r
+                                       case OT_CLOSURE:{\r
+                                               _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_tailcall?_stackbase:_stackbase+arg2, ct_tailcall));\r
+                                               if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {\r
+                                                       SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));\r
+                                                       _GUARD(gen->Yield(this));\r
+                                                       Return(1, ct_target, temp_reg);\r
+                                                       STK(ct_target) = gen;\r
+                                                       while (last_top >= _top) _stack[last_top--].Null();\r
+                                                       continue;\r
+                                               }\r
+                                               if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))\r
+                                                       CallDebugHook(_SC('c'));\r
+                                               }\r
+                                               break;\r
+                                       case OT_NATIVECLOSURE: {\r
+                                               bool suspend;\r
+                                               _GUARD(CallNative(_nativeclosure(temp_reg), arg3, _stackbase+arg2, ct_tailcall, temp_reg,suspend));\r
+                                               if(suspend){\r
+                                                       _suspended = SQTrue;\r
+                                                       _suspended_target = ct_target;\r
+                                                       _suspended_root = ci->_root;\r
+                                                       _suspended_traps = traps;\r
+                                                       outres = temp_reg;\r
+                                                       return true;\r
+                                               }\r
+                                               STK(ct_target) = temp_reg;\r
+                                                                                  }\r
+                                               break;\r
+                                       case OT_CLASS:{\r
+                                               _GUARD(CreateClassInstance(_class(temp_reg),arg3,_stackbase+arg2,STK(ct_target)));\r
+                                               }\r
+                                               break;\r
+                                       case OT_TABLE:\r
+                                       case OT_USERDATA:\r
+                                       case OT_INSTANCE:\r
+                                               {\r
+                                               Push(temp_reg);\r
+                                               for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));\r
+                                               if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){\r
+                                                       STK(ct_target) = temp_reg;\r
+                                                       break;\r
+                                               }\r
+                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));\r
+                                               SQ_THROW();\r
+                                         }\r
+                                       default:\r
+                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));\r
+                                               SQ_THROW();\r
+                                       }\r
+                               }\r
+                                 continue;\r
+                       case _OP_PREPCALL:\r
+                                       if (!Get(STK(arg2), STK(arg1), temp_reg, false,true))\r
+                                       { Raise_IdxError(STK(arg1)); SQ_THROW(); }\r
+                                       goto common_prepcall;\r
+                       case _OP_PREPCALLK:\r
+                                       if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg,false,true)) {\r
+                                               if(type(STK(arg2)) == OT_CLASS) { //hack?\r
+                                                       if(_class_ddel->Get((*ci->_literals)[arg1],temp_reg)) {\r
+                                                               STK(arg3) = STK(arg2);\r
+                                                               TARGET = temp_reg;\r
+                                                               continue;\r
+                                                       }\r
+                                               }\r
+                                               { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();}\r
+                                       }\r
+common_prepcall:\r
+                                       if(type(STK(arg2)) == OT_CLASS) {\r
+                                               STK(arg3) = STK(0); // this\r
+                                       }\r
+                                       else {\r
+                                               STK(arg3) = STK(arg2);\r
+                                       }\r
+                                       TARGET = temp_reg;\r
+                               continue;\r
+                       case _OP_GETK:\r
+                               if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg, false,true)) { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();}\r
+                               TARGET = temp_reg;\r
+                               continue;\r
+                       case _OP_MOVE: TARGET = STK(arg1); continue;\r
+                       case _OP_NEWSLOT:\r
+                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3)));\r
+                               if(arg0 != arg3) TARGET = STK(arg3);\r
+                               continue;\r
+                       case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;\r
+                       case _OP_SET:\r
+                               if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }\r
+                               if (arg0 != arg3) TARGET = STK(arg3);\r
+                               continue;\r
+                       case _OP_GET:\r
+                               if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }\r
+                               TARGET = temp_reg;\r
+                               continue;\r
+                       case _OP_EQ:{\r
+                               bool res;\r
+                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }\r
+                               TARGET = res?_true_:_false_;\r
+                               }continue;\r
+                       case _OP_NE:{ \r
+                               bool res;\r
+                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }\r
+                               TARGET = (!res)?_true_:_false_;\r
+                               } continue;\r
+                       case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;\r
+                       case _OP_BITW:  _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;\r
+                       case _OP_RETURN:\r
+                               if(type((ci)->_generator) == OT_GENERATOR) {\r
+                                       _generator((ci)->_generator)->Kill();\r
+                               }\r
+                               if(Return(arg0, arg1, temp_reg)){\r
+                                       assert(traps==0);\r
+                                       outres = temp_reg;\r
+                                       return true;\r
+                               }\r
+                               continue;\r
+                       case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue;\r
+                       case _OP_LOADROOTTABLE: TARGET = _roottable; continue;\r
+                       case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;\r
+                       case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;\r
+                       case _OP_JMP: ci->_ip += (sarg1); continue;\r
+                       case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;\r
+                       case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;\r
+                       case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue;\r
+                       case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue;\r
+                       case _OP_GETVARGV: \r
+                               if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); } \r
+                               continue;\r
+                       case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;\r
+                       case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;\r
+                       case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL);  continue;\r
+                       case _OP_GETPARENT:\r
+                               switch(type(STK(arg1))) {\r
+                               case OT_TABLE: \r
+                       TARGET = _table(STK(arg1))->_delegate?SQObjectPtr(_table(STK(arg1))->_delegate):_null_;\r
+                                       continue;\r
+                               case OT_CLASS: TARGET = _class(STK(arg1))->_base?_class(STK(arg1))->_base:_null_;\r
+                                       continue;\r
+                               }\r
+                               Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(STK(arg1)));\r
+                               SQ_THROW();\r
+                               continue;\r
+                       case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;\r
+                       case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;\r
+                       case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;\r
+                       case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;\r
+                       case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;\r
+                       case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue;\r
+                       case _OP_CMP:   _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET))  continue;\r
+                       case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue;\r
+                       case _OP_INSTANCEOF: \r
+                               if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE)\r
+                               {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}\r
+                               TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_;\r
+                               continue;\r
+                       case _OP_AND: \r
+                               if(IsFalse(STK(arg2))) {\r
+                                       TARGET = STK(arg2);\r
+                                       ci->_ip += (sarg1);\r
+                               }\r
+                               continue;\r
+                       case _OP_OR:\r
+                               if(!IsFalse(STK(arg2))) {\r
+                                       TARGET = STK(arg2);\r
+                                       ci->_ip += (sarg1);\r
+                               }\r
+                               continue;\r
+                       case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;\r
+                       case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;\r
+                       case _OP_BWNOT:\r
+                               if(type(STK(arg1)) == OT_INTEGER) {\r
+                                       TARGET = SQInteger(~_integer(STK(arg1)));\r
+                                       continue;\r
+                               }\r
+                               Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));\r
+                               SQ_THROW();\r
+                       case _OP_CLOSURE: {\r
+                               SQClosure *c = ci->_closure._unVal.pClosure;\r
+                               SQFunctionProto *fp = c->_function._unVal.pFunctionProto;\r
+                               if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }\r
+                               continue;\r
+                       }\r
+                       case _OP_YIELD:{\r
+                               if(type(ci->_generator) == OT_GENERATOR) {\r
+                                       if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);\r
+                                       _GUARD(_generator(ci->_generator)->Yield(this));\r
+                                       traps -= ci->_etraps;\r
+                                       if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;\r
+                               }\r
+                               else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}\r
+                               if(Return(arg0, arg1, temp_reg)){\r
+                                       assert(traps==0);\r
+                                       outres = temp_reg;\r
+                                       return true;\r
+                               }\r
+                                       \r
+                               }\r
+                               continue;\r
+                       case _OP_RESUME:\r
+                               if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}\r
+                               _GUARD(_generator(STK(arg1))->Resume(this, arg0));\r
+                               traps += ci->_etraps;\r
+                continue;\r
+                       case _OP_FOREACH:{ bool finished;\r
+                               _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,finished));\r
+                               if(finished) ci->_ip += sarg1; }\r
+                               continue;\r
+                       case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue;\r
+                       case _OP_CLONE:\r
+                               if(!Clone(STK(arg1), TARGET))\r
+                               { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();}\r
+                               continue;\r
+                       case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue;\r
+                       case _OP_PUSHTRAP:\r
+                               _etraps.push_back(SQExceptionTrap(_top,_stackbase, &ci->_iv->_vals[(ci->_ip-ci->_iv->_vals)+arg1], arg0)); traps++;\r
+                               ci->_etraps++;\r
+                               continue;\r
+                       case _OP_POPTRAP:{\r
+                               for(SQInteger i=0; i<arg0; i++) {\r
+                                       _etraps.pop_back(); traps--;\r
+                                       ci->_etraps--;\r
+                               }}\r
+                               continue;\r
+                       case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;\r
+                       case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;\r
+                       case _OP_NEWSLOTA:\r
+                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3)));\r
+                               _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));\r
+                               if(arg0 != arg3) TARGET = STK(arg3);\r
+                               continue;\r
+                       }\r
+                       \r
+               }\r
+       }\r
+exception_trap:\r
+       {\r
+               SQObjectPtr currerror = _lasterror;\r
+//             dumpstack(_stackbase);\r
+               SQInteger n = 0;\r
+               SQInteger last_top = _top;\r
+               if(ci) {\r
+                       if(traps) {\r
+                               do {\r
+                                       if(ci->_etraps > 0) {\r
+                                               SQExceptionTrap &et = _etraps.top();\r
+                                               ci->_ip = et._ip;\r
+                                               _top = et._stacksize;\r
+                                               _stackbase = et._stackbase;\r
+                                               _stack[_stackbase+et._extarget] = currerror;\r
+                                               _etraps.pop_back(); traps--; ci->_etraps--;\r
+                                               while(last_top >= _top) _stack[last_top--].Null();\r
+                                               goto exception_restore;\r
+                                       }\r
+                                       //if is a native closure\r
+                                       if(type(ci->_closure) != OT_CLOSURE && n)\r
+                                               break;\r
+                                       if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();\r
+                                       PopVarArgs(ci->_vargs);\r
+                                       POP_CALLINFO(this);\r
+                                       n++;\r
+                               }while(_callsstack.size());\r
+                       }\r
+                       //call the hook\r
+                       CallErrorHandler(currerror);\r
+                       //remove call stack until a C function is found or the cstack is empty\r
+                       if(ci) do{\r
+                               SQBool exitafterthisone = ci->_root;\r
+                               if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();\r
+                               _stackbase -= ci->_prevstkbase;\r
+                               _top = _stackbase + ci->_prevtop;\r
+                               PopVarArgs(ci->_vargs);\r
+                               POP_CALLINFO(this);\r
+                               if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;\r
+                       }while(_callsstack.size());\r
+\r
+                       while(last_top >= _top) _stack[last_top--].Null();\r
+               }\r
+               _lasterror = currerror;\r
+               return false;\r
+       }\r
+       assert(0);\r
+}\r
+\r
+bool SQVM::CreateClassInstance(SQClass *theclass, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval)\r
+{\r
+       SQObjectPtr constr;\r
+       SQObjectPtr inst = theclass->CreateInstance();\r
+       _stack[stackbase] = inst;\r
+       if(theclass->Get(_ss(this)->_constructoridx,constr)) {\r
+               if(!Call(constr,nargs,stackbase,constr))\r
+                       return false;\r
+       }\r
+       retval = inst;\r
+       return true;\r
+}\r
+\r
+void SQVM::CallErrorHandler(SQObjectPtr &error)\r
+{\r
+       if(type(_errorhandler) != OT_NULL) {\r
+               SQObjectPtr out;\r
+               Push(_roottable); Push(error);\r
+               Call(_errorhandler, 2, _top-2, out);\r
+               Pop(2);\r
+       }\r
+}\r
+\r
+void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)\r
+{\r
+       SQObjectPtr temp_reg;\r
+       SQInteger nparams=5;\r
+       SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);\r
+       Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);\r
+       Call(_debughook,nparams,_top-nparams,temp_reg);\r
+       Pop(nparams);\r
+}\r
+\r
+bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,bool tailcall,SQObjectPtr &retval,bool &suspend)\r
+{\r
+       if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }\r
+       SQInteger nparamscheck = nclosure->_nparamscheck;\r
+       if(((nparamscheck > 0) && (nparamscheck != nargs))\r
+               || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {\r
+               Raise_Error(_SC("wrong number of parameters"));\r
+               return false;\r
+               }\r
+\r
+       SQInteger tcs;\r
+       if(tcs = nclosure->_typecheck.size()) {\r
+               for(SQInteger i = 0; i < nargs && i < tcs; i++)\r
+                       if((nclosure->_typecheck[i] != -1) && !(type(_stack[stackbase+i]) & nclosure->_typecheck[i])) {\r
+                Raise_ParamTypeError(i,nclosure->_typecheck[i],type(_stack[stackbase+i]));\r
+                               return false;\r
+                       }\r
+       }\r
+       _nnativecalls++;\r
+       if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) {\r
+               _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));\r
+       }\r
+       SQInteger oldtop = _top;\r
+       SQInteger oldstackbase = _stackbase;\r
+       _top = stackbase + nargs;\r
+       PUSH_CALLINFO(this, CallInfo());\r
+       ci->_etraps = 0;\r
+       ci->_closure._unVal.pNativeClosure = nclosure;\r
+       ci->_closure._type = OT_NATIVECLOSURE;\r
+       ci->_prevstkbase = stackbase - _stackbase;\r
+       ci->_ncalls = 1;\r
+       _stackbase = stackbase;\r
+       //push free variables\r
+       SQInteger outers = nclosure->_outervalues.size();\r
+       for (SQInteger i = 0; i < outers; i++) {\r
+               Push(nclosure->_outervalues[i]);\r
+       }\r
+       ci->_prevtop = (oldtop - oldstackbase);\r
+       SQInteger ret = (nclosure->_function)(this);\r
+       _nnativecalls--;\r
+       suspend = false;\r
+       if( ret == SQ_SUSPEND_FLAG) suspend = true;\r
+       else if (ret < 0) { \r
+               _stackbase = oldstackbase;\r
+               _top = oldtop;\r
+               POP_CALLINFO(this);\r
+               Raise_Error(_lasterror);\r
+               return false;\r
+       }\r
+       \r
+       if (ret != 0){ retval = TOP(); }\r
+       else { retval = _null_; }\r
+       _stackbase = oldstackbase;\r
+       _top = oldtop;\r
+       POP_CALLINFO(this);\r
+       return true;\r
+}\r
+\r
+bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)\r
+{\r
+       switch(type(self)){\r
+       case OT_TABLE:\r
+               if(_table(self)->Get(key,dest))return true;\r
+               break;\r
+       case OT_ARRAY:\r
+               if(sq_isnumeric(key)){\r
+                       return _array(self)->Get(tointeger(key),dest);\r
+               }\r
+               break;\r
+       case OT_INSTANCE:\r
+               if(_instance(self)->Get(key,dest)) return true;\r
+               break;\r
+       }\r
+       if(FallBackGet(self,key,dest,raw)) return true;\r
+\r
+       if(fetchroot) {\r
+               if(_rawval(STK(0)) == _rawval(self) &&\r
+                       type(STK(0)) == type(self)) {\r
+                               return _table(_roottable)->Get(key,dest);\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)\r
+{\r
+       switch(type(self)){\r
+       case OT_CLASS: \r
+               return _class(self)->Get(key,dest);\r
+               break;\r
+       case OT_TABLE:\r
+       case OT_USERDATA:\r
+        //delegation\r
+               if(_delegable(self)->_delegate) {\r
+                       if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))\r
+                               return true;    \r
+                       if(raw)return false;\r
+                       Push(self);Push(key);\r
+                       if(CallMetaMethod(_delegable(self),MT_GET,2,dest))\r
+                               return true;\r
+               }\r
+               if(type(self) == OT_TABLE) {\r
+                       if(raw) return false;\r
+                       return _table_ddel->Get(key,dest);\r
+               }\r
+               return false;\r
+               break;\r
+       case OT_ARRAY:\r
+               if(raw)return false;\r
+               return _array_ddel->Get(key,dest);\r
+       case OT_STRING:\r
+               if(sq_isnumeric(key)){\r
+                       SQInteger n=tointeger(key);\r
+                       if(abs(n)<_string(self)->_len){\r
+                               if(n<0)n=_string(self)->_len-n;\r
+                               dest=SQInteger(_stringval(self)[n]);\r
+                               return true;\r
+                       }\r
+                       return false;\r
+               }\r
+               else {\r
+                       if(raw)return false;\r
+                       return _string_ddel->Get(key,dest);\r
+               }\r
+               break;\r
+       case OT_INSTANCE:\r
+               if(raw)return false;\r
+               Push(self);Push(key);\r
+               if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {\r
+                       return _instance_ddel->Get(key,dest);\r
+               }\r
+               return true;\r
+       case OT_INTEGER:case OT_FLOAT:case OT_BOOL: \r
+               if(raw)return false;\r
+               return _number_ddel->Get(key,dest);\r
+       case OT_GENERATOR: \r
+               if(raw)return false;\r
+               return _generator_ddel->Get(key,dest);\r
+       case OT_CLOSURE: case OT_NATIVECLOSURE: \r
+               if(raw)return false;\r
+               return _closure_ddel->Get(key,dest);\r
+       case OT_THREAD:\r
+               if(raw)return false;\r
+               return  _thread_ddel->Get(key,dest);\r
+       case OT_WEAKREF:\r
+               if(raw)return false;\r
+               return  _weakref_ddel->Get(key,dest);\r
+       default:return false;\r
+       }\r
+       return false;\r
+}\r
+\r
+bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)\r
+{\r
+       switch(type(self)){\r
+       case OT_TABLE:\r
+               if(_table(self)->Set(key,val))\r
+                       return true;\r
+               if(_table(self)->_delegate) {\r
+                       if(Set(_table(self)->_delegate,key,val,false)) {\r
+                               return true;\r
+                       }\r
+               }\r
+               //keeps going\r
+       case OT_USERDATA:\r
+               if(_delegable(self)->_delegate) {\r
+                       SQObjectPtr t;\r
+                       Push(self);Push(key);Push(val);\r
+                       if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;\r
+               }\r
+               break;\r
+       case OT_INSTANCE:{\r
+               if(_instance(self)->Set(key,val))\r
+                       return true;\r
+               SQObjectPtr t;\r
+               Push(self);Push(key);Push(val);\r
+               if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;\r
+               }\r
+               break;\r
+       case OT_ARRAY:\r
+               if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }\r
+               return _array(self)->Set(tointeger(key),val);\r
+       default:\r
+               Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));\r
+               return false;\r
+       }\r
+       if(fetchroot) {\r
+               if(_rawval(STK(0)) == _rawval(self) &&\r
+                       type(STK(0)) == type(self)) {\r
+                               return _table(_roottable)->Set(key,val);\r
+                       }\r
+       }\r
+       return false;\r
+}\r
+\r
+bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)\r
+{\r
+       SQObjectPtr temp_reg;\r
+       switch(type(self)){\r
+       case OT_TABLE:\r
+               target = _table(self)->Clone();\r
+               goto cloned_mt;\r
+       case OT_INSTANCE:\r
+               target = _instance(self)->Clone(_ss(this));\r
+cloned_mt:\r
+               if(_delegable(target)->_delegate){\r
+                       Push(target);\r
+                       Push(self);\r
+                       CallMetaMethod(_delegable(target),MT_CLONED,2,temp_reg);\r
+               }\r
+               return true;\r
+       case OT_ARRAY: \r
+               target=_array(self)->Clone();\r
+               return true;\r
+       default: return false;\r
+       }\r
+}\r
+\r
+bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val)\r
+{\r
+       if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }\r
+       switch(type(self)) {\r
+       case OT_TABLE: {\r
+               bool rawcall = true;\r
+               if(_table(self)->_delegate) {\r
+                       SQObjectPtr res;\r
+                       if(!_table(self)->Get(key,res)) {\r
+                               Push(self);Push(key);Push(val);\r
+                               rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);\r
+                       }\r
+               }\r
+               if(rawcall) _table(self)->NewSlot(key,val); //cannot fail\r
+               \r
+               break;}\r
+       case OT_CLASS: \r
+               if(!_class(self)->NewSlot(key,val)) {\r
+                       if(_class(self)->_locked) {\r
+                               Raise_Error(_SC("trying to modify a class that has already been instantiated"));\r
+                               return false;\r
+                       }\r
+                       else {\r
+                               SQObjectPtr oval = PrintObjVal(key);\r
+                               Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));\r
+                               return false;\r
+                       }\r
+               }\r
+               break;\r
+       default:\r
+               Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));\r
+               return false;\r
+               break;\r
+       }\r
+       return true;\r
+}\r
+\r
+bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)\r
+{\r
+       switch(type(self)) {\r
+       case OT_TABLE:\r
+       case OT_INSTANCE:\r
+       case OT_USERDATA: {\r
+               SQObjectPtr t;\r
+               bool handled = false;\r
+               if(_delegable(self)->_delegate) {\r
+                       Push(self);Push(key);\r
+                       handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);\r
+               }\r
+\r
+               if(!handled) {\r
+                       if(type(self) == OT_TABLE) {\r
+                               if(_table(self)->Get(key,t)) {\r
+                                       _table(self)->Remove(key);\r
+                               }\r
+                               else {\r
+                                       Raise_IdxError((SQObject &)key);\r
+                                       return false;\r
+                               }\r
+                       }\r
+                       else {\r
+                               Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));\r
+                               return false;\r
+                       }\r
+               }\r
+               res = t;\r
+                               }\r
+               break;\r
+       default:\r
+               Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres)\r
+{\r
+#ifdef _DEBUG\r
+SQInteger prevstackbase = _stackbase;\r
+#endif\r
+       switch(type(closure)) {\r
+       case OT_CLOSURE:\r
+               return Execute(closure, _top - nparams, nparams, stackbase,outres);\r
+               break;\r
+       case OT_NATIVECLOSURE:{\r
+               bool suspend;\r
+               return CallNative(_nativeclosure(closure), nparams, stackbase, false, outres,suspend);\r
+               \r
+                                                 }\r
+               break;\r
+       case OT_CLASS:\r
+               return CreateClassInstance(_class(closure),nparams,stackbase,outres);\r
+               break;\r
+       default:\r
+               return false;\r
+       }\r
+#ifdef _DEBUG\r
+       if(!_suspended) {\r
+               assert(_stackbase == prevstackbase);\r
+       }\r
+#endif\r
+       return true;\r
+}\r
+\r
+bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)\r
+{\r
+       SQObjectPtr closure;\r
+       if(del->GetMetaMethod(mm, closure)) {\r
+               if(Call(closure, nparams, _top - nparams, outres)) {\r
+                       Pop(nparams);\r
+                       return true;\r
+               }\r
+       }\r
+       Pop(nparams);\r
+       return false;\r
+}\r
+\r
+void SQVM::Remove(SQInteger n) {\r
+       n = (n >= 0)?n + _stackbase - 1:_top + n;\r
+       for(SQInteger i = n; i < _top; i++){\r
+               _stack[i] = _stack[i+1];\r
+       }\r
+       _stack[_top] = _null_;\r
+       _top--;\r
+}\r
+\r
+\r
+#ifdef _DEBUG_DUMP\r
+void SQVM::dumpstack(SQInteger stackbase,bool dumpall)\r
+{\r
+       SQInteger size=dumpall?_stack.size():_top;\r
+       SQInteger n=0;\r
+       scprintf(_SC("\n>>>>stack dump<<<<\n"));\r
+       CallInfo &ci=_callsstack.back();\r
+       scprintf(_SC("IP: %d\n"),ci._ip);\r
+       scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);\r
+       scprintf(_SC("prev top: %d\n"),ci._prevtop);\r
+       for(SQInteger i=0;i<size;i++){\r
+               SQObjectPtr &obj=_stack[i];     \r
+               if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));\r
+               scprintf(_SC("[%d]:"),n);\r
+               switch(type(obj)){\r
+               case OT_FLOAT:                  scprintf(_SC("FLOAT %.3f"),_float(obj));break;\r
+               case OT_INTEGER:                scprintf(_SC("INTEGER %d"),_integer(obj));break;\r
+               case OT_BOOL:                   scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;\r
+               case OT_STRING:                 scprintf(_SC("STRING %s"),_stringval(obj));break;\r
+               case OT_NULL:                   scprintf(_SC("NULL"));  break;\r
+               case OT_TABLE:                  scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;\r
+               case OT_ARRAY:                  scprintf(_SC("ARRAY %p"),_array(obj));break;\r
+               case OT_CLOSURE:                scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;\r
+               case OT_NATIVECLOSURE:  scprintf(_SC("NATIVECLOSURE"));break;\r
+               case OT_USERDATA:               scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;\r
+               case OT_GENERATOR:              scprintf(_SC("GENERATOR"));break;\r
+               case OT_THREAD:                 scprintf(_SC("THREAD [%p]"),_thread(obj));break;\r
+               case OT_USERPOINTER:    scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;\r
+               case OT_CLASS:                  scprintf(_SC("CLASS %p"),_class(obj));break;\r
+               case OT_INSTANCE:               scprintf(_SC("INSTANCE %p"),_instance(obj));break;\r
+               case OT_WEAKREF:                scprintf(_SC("WEAKERF %p"),_weakref(obj));break;\r
+               default:\r
+                       assert(0);\r
+                       break;\r
+               };\r
+               scprintf(_SC("\n"));\r
+               ++n;\r
+       }\r
+}\r
+\r
+#endif\r
index d46f2a2..00fce00 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQVM_H_
-#define _SQVM_H_
-
-#include "sqopcodes.h"
-#include "sqobject.h"
-#define MAX_NATIVE_CALLS 100
-#define MIN_STACK_OVERHEAD 10
-
-#define SQ_SUSPEND_FLAG -666
-//base lib
-void sq_base_register(HSQUIRRELVM v);
-
-struct SQExceptionTrap{
-       SQExceptionTrap() {}
-       SQExceptionTrap(int ss, int stackbase,SQInstruction *ip, int ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
-       SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et;      }
-       int _stackbase;
-       int _stacksize;
-       SQInstruction *_ip;
-       int _extarget;
-};
-
-
-#define STK(a) _stack._vals[_stackbase+(a)]
-#define TARGET _stack._vals[_stackbase+arg0]
-
-typedef sqvector<SQExceptionTrap> ExceptionsTraps;
-
-struct SQVM : public CHAINABLE_OBJ
-{
-       struct VarArgs {
-               VarArgs() { size = 0; base = 0; }
-               int size;
-               int base;
-       };
-
-       struct CallInfo{
-               //CallInfo() {}
-               //CallInfo(const CallInfo& ci) {  }
-               SQInstructionVec *_iv;
-               SQObjectPtrVec *_literals;
-               SQObject _closure;
-               SQObject _generator;
-               int _etraps;
-               int _prevstkbase;
-               int _prevtop;
-               int _target;
-               SQInstruction *_ip;
-               int _ncalls;
-               SQBool _root;
-               VarArgs _vargs;
-       };
-
-typedef sqvector<CallInfo> CallInfoVec;
-public:
-       enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
-       SQVM(SQSharedState *ss);
-       ~SQVM();
-       bool Init(SQVM *friendvm, int stacksize);
-       bool Execute(SQObjectPtr &func, int target, int nargs, int stackbase, SQObjectPtr &outres, ExecutionType et = ET_CALL);
-       //start a native call return when the NATIVE closure returns(returns true if the vm has been suspended)
-       bool CallNative(SQNativeClosure *nclosure, int nargs, int stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);
-       //start a SQUIRREL call in the same "Execution loop"
-       bool StartCall(SQClosure *closure, int target, int nargs, int stackbase, bool tailcall);
-       bool CreateClassInstance(SQClass *theclass, int nargs, int stackbase, SQObjectPtr &retval);
-       //call a generic closure pure SQUIRREL or NATIVE
-       bool Call(SQObjectPtr &closure, int nparams, int stackbase, SQObjectPtr &outres);
-       SQRESULT Suspend();
-
-       void CallDebugHook(int type,int forcedline=0);
-       void CallErrorHandler(SQObjectPtr &e);
-       bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
-       bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
-       bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
-       bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val);
-       bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
-       bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
-       bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,int &res);
-       bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
-       bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
-       bool IsFalse(SQObjectPtr &o);
-       SQString *PrintObjVal(const SQObject &o);
-
-       void Raise_Error(const SQChar *s, ...);
-       void Raise_Error(SQObjectPtr &desc);
-       void Raise_IdxError(SQObject &o);
-       void Raise_CompareError(const SQObject &o1, const SQObject &o2);
-       void Raise_ParamTypeError(int nparam,int typemask,int type);
-
-       void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
-       bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, int nparams, SQObjectPtr &outres);
-       bool ArithMetaMethod(int op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
-       bool Return(int _arg0, int _arg1, SQObjectPtr &retval);
-       //new stuff
-       inline bool ARITH_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
-       inline bool BW_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
-       inline bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
-       inline bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
-       bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
-       bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
-       bool CLASS_OP(SQObjectPtr &target,int base,int attrs);
-       //return true if the loop is finished
-       bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,int arg_2,bool &finished);
-       bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
-       inline bool LOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
-       inline bool PLOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
-       inline bool DerefInc(int op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
-       void PopVarArgs(VarArgs &vargs);
-#ifdef _DEBUG_DUMP
-       void dumpstack(int stackbase=-1, bool dumpall = false);
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
-       void Mark(SQCollectable **chain);
-#endif
-       void Finalize();
-
-       void Release(){ sq_delete(this,SQVM); } //does nothing
-////////////////////////////////////////////////////////////////////////////
-       //stack functions for the api
-       void Remove(int n);
-
-       inline void Pop() {
-               _stack[--_top] = _null_;
-       }
-
-       inline void Pop(int n) {
-               for(int i = 0; i < n; i++){
-                       _stack[--_top] = _null_;
-               }
-       }
-
-       inline void Push(const SQObjectPtr &o) { _stack[_top++] = o; }
-       inline SQObjectPtr &Top() { return _stack[_top-1]; }
-       inline SQObjectPtr &PopGet() { return _stack[--_top]; }
-       inline SQObjectPtr &GetUp(int n) { return _stack[_top+n]; }
-       inline SQObjectPtr &GetAt(int n) { return _stack[n]; }
-
-       SQObjectPtrVec _stack;
-       SQObjectPtrVec _vargsstack;
-       int _top;
-       int _stackbase;
-       SQObjectPtr _roottable;
-       //SQObjectPtr _thrownerror;
-       SQObjectPtr _lasterror;
-       SQObjectPtr _errorhandler;
-       SQObjectPtr _debughook;
-
-       SQObjectPtr temp_reg;
-       CallInfoVec _callsstack;
-       ExceptionsTraps _etraps;
-       CallInfo *ci;
-       void *_foreignptr;
-       //VMs sharing the same state
-       SQSharedState *_sharedstate;
-       int _nnativecalls;
-       //suspend infos
-       SQBool _suspended;
-       SQBool _suspended_root;
-       int _suspended_target;
-       int _suspended_traps;
-};
-
-struct AutoDec{
-       AutoDec(int *n) { _n = n; }
-       ~AutoDec() { (*_n)--; }
-       int *_n;
-};
-
-SQObjectPtr &stack_get(HSQUIRRELVM v, int idx);
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
-
-#define _ss(_vm_) (_vm_)->_sharedstate
-
-#ifndef NO_GARBAGE_COLLECTOR
-#define _opt_ss(_vm_) (_vm_)->_sharedstate
-#else
-#define _opt_ss(_vm_) NULL
-#endif
-
-#define PUSH_CALLINFO(v,nci){ \
-       v->ci = &v->_callsstack.push_back(nci); \
-}
-
-#define POP_CALLINFO(v){ \
-       v->_callsstack.pop_back(); \
-       if(v->_callsstack.size())       \
-               v->ci = &v->_callsstack.back() ; \
-       else    \
-               v->ci = NULL; \
-}
-#endif //_SQVM_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQVM_H_\r
+#define _SQVM_H_\r
+\r
+#include "sqopcodes.h"\r
+#include "sqobject.h"\r
+#define MAX_NATIVE_CALLS 100\r
+#define MIN_STACK_OVERHEAD 10\r
+\r
+#define SQ_SUSPEND_FLAG -666\r
+//base lib\r
+void sq_base_register(HSQUIRRELVM v);\r
+\r
+struct SQExceptionTrap{\r
+       SQExceptionTrap() {}\r
+       SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}\r
+       SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et;      }\r
+       SQInteger _stackbase;\r
+       SQInteger _stacksize;\r
+       SQInstruction *_ip;\r
+       SQInteger _extarget;\r
+};\r
+\r
+\r
+#define STK(a) _stack._vals[_stackbase+(a)]\r
+#define TARGET _stack._vals[_stackbase+arg0]\r
+\r
+typedef sqvector<SQExceptionTrap> ExceptionsTraps;\r
+\r
+struct SQVM : public CHAINABLE_OBJ\r
+{\r
+       struct VarArgs {\r
+               VarArgs() { size = 0; base = 0; }\r
+               SQInteger size;\r
+               SQInteger base;\r
+       };\r
+\r
+       struct CallInfo{\r
+               CallInfo() { _generator._type = OT_NULL;}\r
+               //CallInfo(const CallInfo& ci) {  }\r
+               SQInstructionVec *_iv;\r
+               SQObjectPtrVec *_literals;\r
+               SQObject _closure;\r
+               SQObject _generator;\r
+               SQInteger _etraps;\r
+               SQInteger _prevstkbase;\r
+               SQInteger _prevtop;\r
+               SQInteger _target;\r
+               SQInstruction *_ip;\r
+               SQInteger _ncalls;\r
+               SQBool _root;\r
+               VarArgs _vargs;\r
+       };\r
+\r
+typedef sqvector<CallInfo> CallInfoVec;\r
+public:\r
+       enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };\r
+       SQVM(SQSharedState *ss);\r
+       ~SQVM();\r
+       bool Init(SQVM *friendvm, SQInteger stacksize);\r
+       bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, ExecutionType et = ET_CALL);\r
+       //start a native call return when the NATIVE closure returns(returns true if the vm has been suspended)\r
+       bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);\r
+       //start a SQUIRREL call in the same "Execution loop"\r
+       bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);\r
+       bool CreateClassInstance(SQClass *theclass, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval);\r
+       //call a generic closure pure SQUIRREL or NATIVE\r
+       bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres);\r
+       SQRESULT Suspend();\r
+\r
+       void CallDebugHook(SQInteger type,SQInteger forcedline=0);\r
+       void CallErrorHandler(SQObjectPtr &e);\r
+       bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);\r
+       bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);\r
+       bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);\r
+       bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val);\r
+       bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);\r
+       bool Clone(const SQObjectPtr &self, SQObjectPtr &target);\r
+       bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);\r
+       bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);\r
+       bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);\r
+       void ToString(const SQObjectPtr &o,SQObjectPtr &res);\r
+       SQString *PrintObjVal(const SQObject &o);\r
+\r
\r
+       void Raise_Error(const SQChar *s, ...);\r
+       void Raise_Error(SQObjectPtr &desc);\r
+       void Raise_IdxError(SQObject &o);\r
+       void Raise_CompareError(const SQObject &o1, const SQObject &o2);\r
+       void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);\r
+\r
+       void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);\r
+       bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);\r
+       bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);\r
+       bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);\r
+       //new stuff\r
+       inline bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
+       inline bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
+       inline bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);\r
+       inline bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);\r
+       bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);\r
+       bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);\r
+       bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);\r
+       //return true if the loop is finished\r
+       bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished);\r
+       bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);\r
+       inline bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
+       inline bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
+       inline bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);\r
+       void PopVarArgs(VarArgs &vargs);\r
+#ifdef _DEBUG_DUMP\r
+       void dumpstack(SQInteger stackbase=-1, bool dumpall = false);\r
+#endif\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       void Mark(SQCollectable **chain);\r
+#endif\r
+       void Finalize();\r
+\r
+       void Release(){ sq_delete(this,SQVM); } //does nothing\r
+////////////////////////////////////////////////////////////////////////////\r
+       //stack functions for the api\r
+       void Remove(SQInteger n);\r
+\r
+       inline bool IsFalse(SQObjectPtr &o)\r
+       {\r
+               if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) )\r
+                       || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       inline void Pop() {\r
+               _stack[--_top] = _null_;\r
+       }\r
+\r
+       inline void Pop(SQInteger n) {\r
+               for(SQInteger i = 0; i < n; i++){\r
+                       _stack[--_top] = _null_;\r
+               }\r
+       }\r
+\r
+       inline void Push(const SQObjectPtr &o) { _stack[_top++] = o; }\r
+       inline SQObjectPtr &Top() { return _stack[_top-1]; }\r
+       inline SQObjectPtr &PopGet() { return _stack[--_top]; }\r
+       inline SQObjectPtr &GetUp(SQInteger n) { return _stack[_top+n]; }\r
+       inline SQObjectPtr &GetAt(SQInteger n) { return _stack[n]; }\r
+\r
+       SQObjectPtrVec _stack;\r
+       SQObjectPtrVec _vargsstack;\r
+       SQInteger _top;\r
+       SQInteger _stackbase;\r
+       SQObjectPtr _roottable;\r
+       //SQObjectPtr _thrownerror;\r
+       SQObjectPtr _lasterror;\r
+       SQObjectPtr _errorhandler;\r
+       SQObjectPtr _debughook;\r
+\r
+       SQObjectPtr temp_reg;\r
+       CallInfoVec _callsstack;\r
+       ExceptionsTraps _etraps;\r
+       CallInfo *ci;\r
+       void *_foreignptr;\r
+       //VMs sharing the same state\r
+       SQSharedState *_sharedstate;\r
+       SQInteger _nnativecalls;\r
+       //suspend infos\r
+       SQBool _suspended;\r
+       SQBool _suspended_root;\r
+       SQInteger _suspended_target;\r
+       SQInteger _suspended_traps;\r
+};\r
+\r
+struct AutoDec{\r
+       AutoDec(SQInteger *n) { _n = n; }\r
+       ~AutoDec() { (*_n)--; }\r
+       SQInteger *_n;\r
+};\r
+\r
+inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}\r
+const SQChar *GetTypeName(const SQObjectPtr &obj1);\r
+const SQChar *IdType2Name(SQObjectType type);\r
+\r
+#define _ss(_vm_) (_vm_)->_sharedstate\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+#define _opt_ss(_vm_) (_vm_)->_sharedstate\r
+#else\r
+#define _opt_ss(_vm_) NULL\r
+#endif\r
+\r
+#define PUSH_CALLINFO(v,nci){ \\r
+       v->ci = &v->_callsstack.push_back(nci); \\r
+}\r
+\r
+#define POP_CALLINFO(v){ \\r
+       v->_callsstack.pop_back(); \\r
+       if(v->_callsstack.size())       \\r
+               v->ci = &v->_callsstack.back() ; \\r
+       else    \\r
+               v->ci = NULL; \\r
+}\r
+#endif //_SQVM_H_\r