* Update squirrel to 2.2.3
authorMathnerd314 <man.is.allan@gmail.com>
Sun, 30 Aug 2009 19:45:19 +0000 (19:45 +0000)
committerMathnerd314 <man.is.allan@gmail.com>
Sun, 30 Aug 2009 19:45:19 +0000 (19:45 +0000)
* Fix some script problems and improve some error messages
* Minor cleanups in camera and sector

SVN-Revision: 5912

24 files changed:
data/levels/world2/airkey.stl
data/scripts/console.nut
src/object/camera.cpp
src/scripting/thread_queue.cpp
src/scripting/time_scheduler.cpp
src/sector.cpp
src/squirrel/COPYRIGHT
src/squirrel/HISTORY
src/squirrel/README
src/squirrel/include/sqstdstring.h
src/squirrel/include/squirrel.h
src/squirrel/sqstdlib/sqstdaux.cpp
src/squirrel/sqstdlib/sqstdstream.cpp
src/squirrel/sqstdlib/sqstdstream.h
src/squirrel/sqstdlib/sqstdstring.cpp
src/squirrel/squirrel/sqapi.cpp
src/squirrel/squirrel/sqbaselib.cpp
src/squirrel/squirrel/sqcompiler.cpp
src/squirrel/squirrel/sqdebug.cpp
src/squirrel/squirrel/sqobject.h
src/squirrel/squirrel/squtils.h
src/squirrel/squirrel/sqvm.cpp
src/squirrel/squirrel/sqvm.h
src/trigger/switch.cpp

index 6d1a2c3..798c9ba 100644 (file)
@@ -307,9 +307,7 @@ end_level();
     (switch
       (script "if(! (\"door_opened\" in this) ) {
        Tux.deactivate();
-       Effect.sixteen_to_nine(0);
-       wait(1);
-       Camera.set_mode(\"manual\");
+       Effect.sixteen_to_nine(1);
        Camera.scroll_to(2652, 2066, 2);
        wait(3);
        blocker1.goto_node(1);
@@ -319,11 +317,10 @@ end_level();
        blocker5.goto_node(1);
        blocker6.goto_node(1);
        wait(2);
-       Camera.scroll_to(2223.9,2265.4);
-       wait(2.5);
-       Camera.set_mode(\"normal\");
+       Camera.scroll_to(2223.9,2265.4,2);
+       Effect.four_to_three(1);
        wait(2);
-       Effect.four_to_three(0);
+       Camera.set_mode(\"normal\");
        Tux.activate();
        this.door_opened <- true;
 }")
index 5ceec2d..16464db 100644 (file)
@@ -27,8 +27,10 @@ function play()
 function worldmapfinish()
 {
        save_state();
-       foreach(levelname, level in state.worlds[state.world].levels) {
-               level.solved = true;
+       foreach(world in state.worlds) {
+               foreach(levelname, level in world.levels) {
+                       level.solved = true;
+               }
        }
        update_worldmap();
 }
index abdfe0c..e6ec192 100644 (file)
@@ -49,9 +49,9 @@ static const float PEEK_ARRIVE_RATIO = 0.1;
 class CameraConfig
 {
 public:
-  // 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby
+  // 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby, 4 = Super Metroid-like
   int ymode;
-  // as above, 4 = super metroid like
+  // as above
   int xmode;
   float kirby_rectsize_x;
   float kirby_rectsize_y;
@@ -326,15 +326,11 @@ Camera::update_scroll_normal(float elapsed_time)
     return;
 
   /****** Vertical Scrolling part ******/
-  int xmode = config.xmode;
   int ymode = config.ymode;
 
   if(player->is_dying() || sector->get_height() == 19*32) {
     ymode = 0;
   }
-  if(player->is_dying())
-    xmode = 0;
-
   if(ymode == 1) {
     cached_translation.y = player_pos.y - SCREEN_HEIGHT * config.target_y;
   }
@@ -441,6 +437,10 @@ Camera::update_scroll_normal(float elapsed_time)
   }
 
   /****** Horizontal scrolling part *******/
+  int xmode = config.xmode;
+
+  if(player->is_dying())
+    xmode = 0;
 
   if(xmode == 1) {
     cached_translation.x = player_pos.x - SCREEN_WIDTH * config.target_x;
index 6ecaef3..2d20e47 100644 (file)
@@ -70,7 +70,7 @@ ThreadQueue::wakeup()
     HSQUIRRELVM scheduled_vm;
     if(sq_gettype(global_vm, -1) == OT_THREAD &&
             SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
-      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue))) {
+      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
         log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
       }
     }
index d28308b..2396d56 100644 (file)
@@ -51,9 +51,9 @@ TimeScheduler::update(float time)
     HSQUIRRELVM scheduled_vm;
     if(sq_gettype(global_vm, -1) == OT_THREAD &&
         SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
-      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue))) {
+      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
         std::ostringstream msg;
-        msg << "Couldn't wakeup scheduled squirrel VM: ";
+        msg << "Error waking VM: ";
         sq_getlasterror(scheduled_vm);
         if(sq_gettype(scheduled_vm, -1) != OT_STRING) {
             msg << "(no info)";
index 2aa60ab..3cb2372 100644 (file)
@@ -521,9 +521,9 @@ Sector::run_script(std::istream& in, const std::string& sourcename)
   sq_setroottable(vm);
 
   try {
-    compile_and_run(vm, in, sourcename);
+    compile_and_run(vm, in, "Sector " + name + " - " + sourcename);
   } catch(std::exception& e) {
-    log_warning << "Couldn't run script: " << e.what() << std::endl;
+    log_warning << "Error running script: " << e.what() << std::endl;
   }
 
   return vm;
@@ -625,7 +625,7 @@ Sector::activate(const Vector& player_pos)
   if(PHYSFS_exists((basedir + "/info").c_str())) {
     try {
       IFileStream in(basedir + "/default.nut");
-      run_script(in, std::string("Sector(") + name + ") - default.nut");
+      run_script(in, "default.nut");
     } catch(std::exception& ) {
       // doesn't exist or erroneous; do nothing
     }
@@ -634,7 +634,7 @@ Sector::activate(const Vector& player_pos)
   // Run init script
   if(init_script != "") {
     std::istringstream in(init_script);
-    run_script(in, std::string("Sector(") + name + ") - init");
+    run_script(in, "init-script");
   }
 }
 
@@ -1400,10 +1400,9 @@ Sector::is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid) const
       Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
       triangle = AATriangle(p1, p2, tile->getData());
       Constraints constraints;
-      return collision::rectangle_aatriangle(&constraints, rect, triangle);
+      if(collision::rectangle_aatriangle(&constraints, rect, triangle) && (!ignoreUnisolid || !(tile->getAttributes() & Tile::UNISOLID))) return false;
     }
-    if((tile->getAttributes() & Tile::SOLID) && !ignoreUnisolid) return false;
-    if((tile->getAttributes() & Tile::SOLID) && !(tile->getAttributes() & Tile::UNISOLID)) return false;
+    if((tile->getAttributes() & Tile::SOLID) && (!ignoreUnisolid || !(tile->getAttributes() & Tile::UNISOLID))) return false;
       }
     }
   }
index 8bd2081..ad983ce 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2008 Alberto Demichelis\r
+Copyright (c) 2003-2009 Alberto Demichelis\r
 \r
 This software is provided 'as-is', without any \r
 express or implied warranty. In no event will the \r
index 7b91808..b6dcc83 100644 (file)
@@ -1,3 +1,17 @@
+***version 2.2.3 stable***\r
+-added sq_getfunctioninfo\r
+-added compile time flag SQUSEDOUBLE to use double precision floats\r
+-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds\r
+-sq_wakeupvm can now resume the vm with an exception\r
+-added sqstd_format\r
+-generators can now be instantiated by calling sq_call() or closure.call()\r
+-fixed a bug in sqstd_printcallstack(thx takayuki_h)\r
+-fixed modulo by zero(thx jup)\r
+-fixed negative enums and constants\r
+-fixed generator crash bug if invoked as tail call (thx Mr.Accident)\r
+-fixed some minor bug\r
+\r
+***2008-09-24          ***\r
 ***version 2.2.2 stable***\r
 -fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident)\r
 -fixed coroutine error propagation\r
index 5b335ae..5bd1cd4 100644 (file)
@@ -1,4 +1,4 @@
-The programming language SQUIRREL 2.2.1 stable\r
+The programming language SQUIRREL 2.2.3 stable\r
 \r
 --------------------------------------------------\r
 The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and\r
index 72f30b4..3c3bce8 100644 (file)
@@ -22,6 +22,8 @@ SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,co
 SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
 SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
 
+SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output);
+
 SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
 
 #ifdef __cplusplus
index 8962eb1..7d2f9a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2003-2008 Alberto Demichelis
+Copyright (c) 2003-2009 Alberto Demichelis
 
 This software is provided 'as-is', without any 
 express or implied warranty. In no event will the 
@@ -62,7 +62,24 @@ typedef unsigned int SQHash; /*should be the same size of a pointer*/
 #endif
 
 
+#ifdef SQUSEDOUBLE
+typedef double SQFloat;
+#else
 typedef float SQFloat;
+#endif
+
+#if defined(SQUSEDOUBLE) && !defined(_SQ64)
+#ifdef _MSC_VER
+typedef __int64 SQRawObjectVal; //must be 64bits
+#else
+typedef long SQRawObjectVal; //must be 64bits
+#endif
+#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
+#else
+typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
+#define SQ_OBJECT_RAWINIT()
+#endif
+
 typedef void* SQUserPointer;
 typedef SQUnsignedInteger SQBool;
 typedef SQInteger SQRESULT;
@@ -140,8 +157,8 @@ typedef char SQChar;
 #define MAX_CHAR 0xFF
 #endif
 
-#define SQUIRREL_VERSION       _SC("Squirrel 2.2.2 stable")
-#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2008 Alberto Demichelis")
+#define SQUIRREL_VERSION       _SC("Squirrel 2.2.3 stable")
+#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2009 Alberto Demichelis")
 #define SQUIRREL_AUTHOR                _SC("Alberto Demichelis")
 
 #define SQ_VMSTATE_IDLE                        0
@@ -221,6 +238,7 @@ typedef union tagSQObjectValue
        struct SQClass *pClass;
        struct SQInstance *pInstance;
        struct SQWeakRef *pWeakRef;
+       SQRawObjectVal raw;
 }SQObjectValue;
 
 
@@ -255,6 +273,13 @@ typedef struct tagSQRegFunction{
        const SQChar *typemask;
 }SQRegFunction;
 
+typedef struct tagSQFunctionInfo {
+       SQUserPointer funcid;
+       const SQChar *name;
+       const SQChar *source;
+}SQFunctionInfo;
+
+
 /*vm*/
 SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
 SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
@@ -265,7 +290,7 @@ 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,SQBool raiseerror);
+SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror);
 SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
 
 /*compiler*/
@@ -316,6 +341,7 @@ SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer ty
 SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
 SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
 SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
+SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi);
 SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
 SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
 SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
index f024713..d53073b 100644 (file)
@@ -9,6 +9,7 @@ void sqstd_printcallstack(HSQUIRRELVM v)
        if(pf) {
                SQStackInfos si;
                SQInteger i;
+               SQBool b;
                SQFloat f;
                const SQChar *s;
                SQInteger level=1; //1 is to skip this function that is level 0
@@ -83,8 +84,8 @@ void sqstd_printcallstack(HSQUIRRELVM v)
                                        pf(v,_SC("[%s] WEAKREF\n"),name);
                                        break;
                                case OT_BOOL:{
-                                       sq_getinteger(v,-1,&i);
-                                       pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
+                                       sq_getbool(v,-1,&b);
+                                       pf(v,_SC("[%s] %s\n"),name,b?_SC("true"):_SC("false"));
                                                         }
                                        break;
                                default: assert(0); break;
index f373f5b..eb3e245 100644 (file)
@@ -277,7 +277,7 @@ void init_streamclass(HSQUIRRELVM v)
        sq_pop(v,1);
 }
 
-SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
+SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
 {
        if(sq_gettype(v,-1) != OT_TABLE)
                return sq_throwerror(v,_SC("table expected"));
index 4dcc000..2763ccb 100644 (file)
@@ -14,5 +14,5 @@ SQInteger _stream_eos(HSQUIRRELVM v);
 SQInteger _stream_flush(HSQUIRRELVM v);
 
 #define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
-SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
+SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
 #endif /*_SQSTD_STREAM_H_*/
index 58e935f..19b30b7 100644 (file)
@@ -65,15 +65,16 @@ static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src,
        return n;
 }
 
-static SQInteger _string_format(HSQUIRRELVM v)
+
+SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
 {
        const SQChar *format;
        SQChar *dest;
        SQChar fmt[MAX_FORMAT_LEN];
-       sq_getstring(v,2,&format);
-       SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar);
+       sq_getstring(v,nformatstringidx,&format);
+       SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
        dest = sq_getscratchpad(v,allocated);
-       SQInteger n = 0,i = 0, nparam = 3, w = 0;
+       SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
        while(format[n] != '\0') {
                if(format[n] != '%') {
                        assert(i < allocated);
@@ -118,7 +119,7 @@ static SQInteger _string_format(HSQUIRRELVM v)
                                return sq_throwerror(v,_SC("invalid format"));
                        }
                        n++;
-                       allocated += addlen;
+                       allocated += addlen + sizeof(SQChar);
                        dest = sq_getscratchpad(v,allocated);
                        switch(valtype) {
                        case 's': i += scsprintf(&dest[i],fmt,ts); break;
@@ -128,7 +129,19 @@ static SQInteger _string_format(HSQUIRRELVM v)
                        nparam ++;
                }
        }
-       sq_pushstring(v,dest,i);
+       *outlen = i;
+       dest[i] = '\0';
+       *output = dest;
+       return SQ_OK;
+}
+
+static SQInteger _string_format(HSQUIRRELVM v)
+{
+       SQChar *dest = NULL;
+       SQInteger length = 0;
+       if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
+               return -1;
+       sq_pushstring(v,dest,length);
        return 1;
 }
 
index 055b4b6..342e0a3 100644 (file)
@@ -973,7 +973,7 @@ SQRESULT sq_suspendvm(HSQUIRRELVM v)
        return v->Suspend();
 }
 
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror)
+SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror)
 {
        SQObjectPtr ret;
        if(!v->_suspended)
@@ -982,8 +982,10 @@ SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseer
                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,raiseerror,SQVM::ET_RESUME_VM)) {
+       if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : 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);
index 821fec9..7a90ee2 100644 (file)
@@ -267,6 +267,9 @@ void sq_base_register(HSQUIRRELVM v)
        sq_pushstring(v,_SC("_intsize_"),-1);
        sq_pushinteger(v,sizeof(SQInteger));
        sq_createslot(v,-3);
+       sq_pushstring(v,_SC("_floatsize_"),-1);
+       sq_pushinteger(v,sizeof(SQFloat));
+       sq_createslot(v,-3);
        sq_pop(v,1);
 }
 
@@ -805,7 +808,7 @@ static SQInteger thread_wakeup(HSQUIRRELVM v)
                if(wakeupret) {
                        sq_move(thread,v,2);
                }
-               if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQFalse))) {
+               if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) {
                        sq_move(v,thread,-1);
                        sq_pop(thread,1); //pop retval
                        if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
index 5c468e1..a6cd2cd 100644 (file)
@@ -1101,6 +1101,22 @@ public:
                        case TK_STRING_LITERAL:
                                val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
                                break;
+                       case '-':
+                               Lex();
+                               switch(_token)
+                               {
+                               case TK_INTEGER:
+                                       val._type = OT_INTEGER;
+                                       val._unVal.nInteger = -_lex._nvalue;
+                               break;
+                               case TK_FLOAT:
+                                       val._type = OT_FLOAT;
+                                       val._unVal.fFloat = -_lex._fvalue;
+                               break;
+                               default:
+                                       Error(_SC("scalar expected : integer,float"));
+                               }
+                               break;
                        default:
                        Error(_SC("scalar expected : integer,float or string"));
                }
index 40e0c9b..14f7f64 100644 (file)
@@ -8,6 +8,23 @@
 #include "sqclosure.h"
 #include "sqstring.h"
 
+SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)
+{
+       SQInteger cssize = v->_callsstacksize;
+       if (cssize > level) {
+               SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
+               if(sq_isclosure(ci._closure)) {
+                       SQClosure *c = _closure(ci._closure);
+                       SQFunctionProto *proto = _funcproto(c->_function);
+                       fi->funcid = proto;
+                       fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
+                       fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
+                       return SQ_OK;
+               }
+       }
+       return sq_throwerror(v,_SC("the object is not a closure"));
+}
+
 SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
 {
        SQInteger cssize = v->_callsstacksize;
index 271bf41..29adc3b 100644 (file)
@@ -117,7 +117,7 @@ struct SQObjectPtr;
 #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
 #define _weakref(obj) ((obj)._unVal.pWeakRef)
 #define _refcounted(obj) ((obj)._unVal.pRefCounted)
-#define _rawval(obj) ((obj)._unVal.pRefCounted)
+#define _rawval(obj) ((obj)._unVal.raw)
 
 #define _stringval(obj) (obj)._unVal.pString->_val
 #define _userdataval(obj) (obj)._unVal.pUserData->_val
@@ -130,23 +130,27 @@ struct SQObjectPtr : public SQObject
 {
        SQObjectPtr()
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_NULL;
                _unVal.pUserPointer=NULL;
        }
        SQObjectPtr(const SQObjectPtr &o)
        {
+               SQ_OBJECT_RAWINIT()
                _type=o._type;
                _unVal=o._unVal;
                __AddRef(_type,_unVal);
        }
        SQObjectPtr(const SQObject &o)
        {
+               SQ_OBJECT_RAWINIT()
                _type=o._type;
                _unVal=o._unVal;
                __AddRef(_type,_unVal);
        }
        SQObjectPtr(SQTable *pTable)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_TABLE;
                _unVal.pTable=pTable;
                assert(_unVal.pTable);
@@ -154,6 +158,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQClass *pClass)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_CLASS;
                _unVal.pClass=pClass;
                assert(_unVal.pClass);
@@ -161,6 +166,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQInstance *pInstance)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_INSTANCE;
                _unVal.pInstance=pInstance;
                assert(_unVal.pInstance);
@@ -168,6 +174,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQArray *pArray)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_ARRAY;
                _unVal.pArray=pArray;
                assert(_unVal.pArray);
@@ -175,6 +182,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQClosure *pClosure)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_CLOSURE;
                _unVal.pClosure=pClosure;
                assert(_unVal.pClosure);
@@ -182,6 +190,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQGenerator *pGenerator)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_GENERATOR;
                _unVal.pGenerator=pGenerator;
                assert(_unVal.pGenerator);
@@ -189,6 +198,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQNativeClosure *pNativeClosure)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_NATIVECLOSURE;
                _unVal.pNativeClosure=pNativeClosure;
                assert(_unVal.pNativeClosure);
@@ -196,6 +206,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQString *pString)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_STRING;
                _unVal.pString=pString;
                assert(_unVal.pString);
@@ -203,6 +214,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQUserData *pUserData)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_USERDATA;
                _unVal.pUserData=pUserData;
                assert(_unVal.pUserData);
@@ -210,6 +222,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQVM *pThread)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_THREAD;
                _unVal.pThread=pThread;
                assert(_unVal.pThread);
@@ -217,6 +230,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQWeakRef *pWeakRef)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_WEAKREF;
                _unVal.pWeakRef=pWeakRef;
                assert(_unVal.pWeakRef);
@@ -224,6 +238,7 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQFunctionProto *pFunctionProto)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_FUNCPROTO;
                _unVal.pFunctionProto=pFunctionProto;
                assert(_unVal.pFunctionProto);
@@ -231,24 +246,25 @@ struct SQObjectPtr : public SQObject
        }
        SQObjectPtr(SQInteger nInteger)
        {
-               _unVal.pUserPointer=NULL;
+               SQ_OBJECT_RAWINIT()
                _type=OT_INTEGER;
                _unVal.nInteger=nInteger;
        }
        SQObjectPtr(SQFloat fFloat)
        {
-               _unVal.pUserPointer=NULL;
+               SQ_OBJECT_RAWINIT()
                _type=OT_FLOAT;
                _unVal.fFloat=fFloat;
        }
        SQObjectPtr(bool bBool)
        {
-               _unVal.pUserPointer=NULL;
+               SQ_OBJECT_RAWINIT()
                _type = OT_BOOL;
                _unVal.nInteger = bBool?1:0;
        }
        SQObjectPtr(SQUserPointer pUserPointer)
        {
+               SQ_OBJECT_RAWINIT()
                _type=OT_USERPOINTER;
                _unVal.pUserPointer=pUserPointer;
        }
index 77ccdb2..b6a436e 100644 (file)
@@ -82,7 +82,7 @@ public:
        {
                _vals[idx].~T();
                if(idx < (_size - 1)) {
-                       memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
+                       memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
                }
                _size--;
        }
index 7cadcaf..9b1827a 100644 (file)
 
 #define TOP() (_stack._vals[_top-1])
 
+#define CLEARSTACK(_last_top) { if((_last_top) >= _top) ClearStack(_last_top); }
+void SQVM::ClearStack(SQInteger last_top)
+{
+       SQObjectType tOldType;
+       SQObjectValue unOldVal;
+       while (last_top >= _top) {
+               SQObjectPtr &o = _stack._vals[last_top--];
+               tOldType = o._type;
+               unOldVal = o._unVal;
+               o._type = OT_NULL;
+               o._unVal.pUserPointer = NULL;
+               __Release(tOldType,unOldVal);
+       }
+}
+
 bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
 {
        SQInteger res;
@@ -49,7 +64,9 @@ bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,
                                        res = i1 / i2; 
                                        break;
                                case '*': res = i1 * i2; break;
-                               case '%': res = i1 % i2; break;
+                               case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; }
+                                       res = i1 % i2; 
+                                       break;
                                default: res = 0xDEADBEEF;
                                }
                                trg = res;
@@ -281,12 +298,10 @@ void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
 bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
 {
        _stack.resize(stacksize);
-       //_callsstack.reserve(4);
        _alloccallsstacksize = 4;
        _callstackdata.resize(_alloccallsstacksize);
        _callsstacksize = 0;
        _callsstack = &_callstackdata[0];
-       //_callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo));
        _stackbase = 0;
        _top = 0;
        if(!friendvm) 
@@ -397,7 +412,7 @@ bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
                }
        }
 
-       while (last_top >= _top) _stack._vals[last_top--].Null();
+       CLEARSTACK(last_top);
        assert(oldstackbase >= _stackbase); 
        return broot?true:false;
 }
@@ -664,20 +679,34 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn
        bool ct_tailcall; 
 
        switch(et) {
-               case ET_CALL: 
-                       if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) { 
+               case ET_CALL: {
+                       SQInteger last_top = _top;
+                       temp_reg = closure;
+                       if(!StartCall(_closure(temp_reg), _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;
                        }
+                       if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
+                               SQFunctionProto *f = _funcproto(_closure(temp_reg)->_function);
+                               SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));
+                               _GUARD(gen->Yield(this));
+                               Return(1, ci->_target, temp_reg);
+                               outres = gen;
+                               CLEARSTACK(last_top);
+                               return true;
+                       }
                        ci->_root = SQTrue;
+                                         }
                        break;
                case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
                case ET_RESUME_VM:
+               case ET_RESUME_THROW_VM:
                        traps = _suspended_traps;
                        ci->_root = _suspended_root;
                        ci->_vargs = _suspend_varargs;
                        _suspended = SQFalse;
+                       if(et  == ET_RESUME_THROW_VM) { SQ_THROW(); }
                        break;
        }
        
@@ -701,7 +730,7 @@ exception_restore:
                        case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
                        case _OP_TAILCALL:
                                temp_reg = STK(arg1);
-                               if (type(temp_reg) == OT_CLOSURE){ 
+                               if (type(temp_reg) == OT_CLOSURE && !_funcproto(_closure(temp_reg)->_function)->_bgenerator){ 
                                        ct_tailcall = true;
                                        if(ci->_vargs.size) PopVarArgs(ci->_vargs);
                                        for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
@@ -726,7 +755,7 @@ common_call:
                                                        _GUARD(gen->Yield(this));
                                                        Return(1, ct_target, clo);
                                                        STK(ct_target) = gen;
-                                                       while (last_top >= _top) _stack._vals[last_top--].Null();
+                                                       CLEARSTACK(last_top);
                                                        continue;
                                                }
                                                }
@@ -986,7 +1015,7 @@ exception_trap:
                                                _stackbase = et._stackbase;
                                                _stack._vals[_stackbase+et._extarget] = currerror;
                                                _etraps.pop_back(); traps--; ci->_etraps--;
-                                               while(last_top >= _top) _stack._vals[last_top--].Null();
+                                               CLEARSTACK(last_top);
                                                goto exception_restore;
                                        }
                                        //if is a native closure
@@ -1014,7 +1043,7 @@ exception_trap:
                                if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
                        } while(_callsstacksize);
 
-                       while(last_top >= _top) _stack._vals[last_top--].Null();
+                       CLEARSTACK(last_top);
                }
                _lasterror = currerror;
                return false;
@@ -1026,8 +1055,6 @@ bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr
 {
        inst = theclass->CreateInstance();
        if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
-               //if(!Call(constr,nargs,stackbase,constr,false))
-               //      return false;
                constructor = _null_;
        }
        return true;
index b9db817..c073fb4 100644 (file)
@@ -53,7 +53,7 @@ struct SQVM : public CHAINABLE_OBJ
        
 typedef sqvector<CallInfo> CallInfoVec;
 public:
-       enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
+       enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_THROW_VM };
        SQVM(SQSharedState *ss);
        ~SQVM();
        bool Init(SQVM *friendvm, SQInteger stacksize);
@@ -108,6 +108,7 @@ public:
        _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
        _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
        void PopVarArgs(VarArgs &vargs);
+       void ClearStack(SQInteger last_top);
 #ifdef _DEBUG_DUMP
        void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
 #endif
index 82b97e1..b32e5ed 100644 (file)
@@ -69,7 +69,9 @@ Switch::update(float )
     case TURN_ON:
       if(sprite->animation_done()) {
     std::istringstream stream(script);
-    Sector::current()->run_script(stream, "Switch");
+    std::ostringstream location;
+    location << "switch" << bbox.p1;
+    Sector::current()->run_script(stream, location.str());
 
     sprite->set_action("on", 1);
     state = ON;